1 //
   2 // Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
   3 // Copyright (c) 2014, Red Hat Inc. All rights reserved.
   4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5 //
   6 // This code is free software; you can redistribute it and/or modify it
   7 // under the terms of the GNU General Public License version 2 only, as
   8 // published by the Free Software Foundation.
   9 //
  10 // This code is distributed in the hope that it will be useful, but WITHOUT
  11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13 // version 2 for more details (a copy is included in the LICENSE file that
  14 // accompanied this code).
  15 //
  16 // You should have received a copy of the GNU General Public License version
  17 // 2 along with this work; if not, write to the Free Software Foundation,
  18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19 //
  20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21 // or visit www.oracle.com if you need additional information or have any
  22 // questions.
  23 //
  24 //
  25 
  26 // AArch64 Architecture Description File
  27 
  28 //----------REGISTER DEFINITION BLOCK------------------------------------------
  29 // This information is used by the matcher and the register allocator to
  30 // describe individual registers and classes of registers within the target
  31 // archtecture.
  32 
  33 register %{
  34 //----------Architecture Description Register Definitions----------------------
  35 // General Registers
  36 // "reg_def"  name ( register save type, C convention save type,
  37 //                   ideal register type, encoding );
  38 // Register Save Types:
  39 //
  40 // NS  = No-Save:       The register allocator assumes that these registers
  41 //                      can be used without saving upon entry to the method, &
  42 //                      that they do not need to be saved at call sites.
  43 //
  44 // SOC = Save-On-Call:  The register allocator assumes that these registers
  45 //                      can be used without saving upon entry to the method,
  46 //                      but that they must be saved at call sites.
  47 //
  48 // SOE = Save-On-Entry: The register allocator assumes that these registers
  49 //                      must be saved before using them upon entry to the
  50 //                      method, but they do not need to be saved at call
  51 //                      sites.
  52 //
  53 // AS  = Always-Save:   The register allocator assumes that these registers
  54 //                      must be saved before using them upon entry to the
  55 //                      method, & that they must be saved at call sites.
  56 //
  57 // Ideal Register Type is used to determine how to save & restore a
  58 // register.  Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
  59 // spilled with LoadP/StoreP.  If the register supports both, use Op_RegI.
  60 //
  61 // The encoding number is the actual bit-pattern placed into the opcodes.
  62 
  63 // We must define the 64 bit int registers in two 32 bit halves, the
  64 // real lower register and a virtual upper half register. upper halves
  65 // are used by the register allocator but are not actually supplied as
  66 // operands to memory ops.
  67 //
  68 // follow the C1 compiler in making registers
  69 //
  70 //   r0-r7,r10-r26 volatile (caller save)
  71 //   r27-r32 system (no save, no allocate)
  72 //   r8-r9 invisible to the allocator (so we can use them as scratch regs)
  73 //
  74 // as regards Java usage. we don't use any callee save registers
  75 // because this makes it difficult to de-optimise a frame (see comment
  76 // in x86 implementation of Deoptimization::unwind_callee_save_values)
  77 //
  78 
  79 // General Registers
  80 
  81 reg_def R0      ( SOC, SOC, Op_RegI,  0, r0->as_VMReg()         );
  82 reg_def R0_H    ( SOC, SOC, Op_RegI,  0, r0->as_VMReg()->next() );
  83 reg_def R1      ( SOC, SOC, Op_RegI,  1, r1->as_VMReg()         );
  84 reg_def R1_H    ( SOC, SOC, Op_RegI,  1, r1->as_VMReg()->next() );
  85 reg_def R2      ( SOC, SOC, Op_RegI,  2, r2->as_VMReg()         );
  86 reg_def R2_H    ( SOC, SOC, Op_RegI,  2, r2->as_VMReg()->next() );
  87 reg_def R3      ( SOC, SOC, Op_RegI,  3, r3->as_VMReg()         );
  88 reg_def R3_H    ( SOC, SOC, Op_RegI,  3, r3->as_VMReg()->next() );
  89 reg_def R4      ( SOC, SOC, Op_RegI,  4, r4->as_VMReg()         );
  90 reg_def R4_H    ( SOC, SOC, Op_RegI,  4, r4->as_VMReg()->next() );
  91 reg_def R5      ( SOC, SOC, Op_RegI,  5, r5->as_VMReg()         );
  92 reg_def R5_H    ( SOC, SOC, Op_RegI,  5, r5->as_VMReg()->next() );
  93 reg_def R6      ( SOC, SOC, Op_RegI,  6, r6->as_VMReg()         );
  94 reg_def R6_H    ( SOC, SOC, Op_RegI,  6, r6->as_VMReg()->next() );
  95 reg_def R7      ( SOC, SOC, Op_RegI,  7, r7->as_VMReg()         );
  96 reg_def R7_H    ( SOC, SOC, Op_RegI,  7, r7->as_VMReg()->next() );
  97 reg_def R10     ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()        );
  98 reg_def R10_H   ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next());
  99 reg_def R11     ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()        );
 100 reg_def R11_H   ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next());
 101 reg_def R12     ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()        );
 102 reg_def R12_H   ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()->next());
 103 reg_def R13     ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()        );
 104 reg_def R13_H   ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()->next());
 105 reg_def R14     ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()        );
 106 reg_def R14_H   ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()->next());
 107 reg_def R15     ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()        );
 108 reg_def R15_H   ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()->next());
 109 reg_def R16     ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()        );
 110 reg_def R16_H   ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next());
 111 reg_def R17     ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()        );
 112 reg_def R17_H   ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next());
 113 reg_def R18     ( SOC, SOC, Op_RegI, 18, r18->as_VMReg()        );
 114 reg_def R18_H   ( SOC, SOC, Op_RegI, 18, r18->as_VMReg()->next());
 115 reg_def R19     ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()        );
 116 reg_def R19_H   ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next());
 117 reg_def R20     ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()        ); // caller esp
 118 reg_def R20_H   ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()->next());
 119 reg_def R21     ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()        );
 120 reg_def R21_H   ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()->next());
 121 reg_def R22     ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()        );
 122 reg_def R22_H   ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()->next());
 123 reg_def R23     ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()        );
 124 reg_def R23_H   ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()->next());
 125 reg_def R24     ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()        );
 126 reg_def R24_H   ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()->next());
 127 reg_def R25     ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()        );
 128 reg_def R25_H   ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()->next());
 129 reg_def R26     ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()        );
 130 reg_def R26_H   ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()->next());
 131 reg_def R27     (  NS, SOE, Op_RegI, 27, r27->as_VMReg()        ); // heapbase
 132 reg_def R27_H   (  NS, SOE, Op_RegI, 27, r27->as_VMReg()->next());
 133 reg_def R28     (  NS, SOE, Op_RegI, 28, r28->as_VMReg()        ); // thread
 134 reg_def R28_H   (  NS, SOE, Op_RegI, 28, r28->as_VMReg()->next());
 135 reg_def R29     (  NS,  NS, Op_RegI, 29, r29->as_VMReg()        ); // fp
 136 reg_def R29_H   (  NS,  NS, Op_RegI, 29, r29->as_VMReg()->next());
 137 reg_def R30     (  NS,  NS, Op_RegI, 30, r30->as_VMReg()        ); // lr
 138 reg_def R30_H   (  NS,  NS, Op_RegI, 30, r30->as_VMReg()->next());
 139 reg_def R31     (  NS,  NS, Op_RegI, 31, r31_sp->as_VMReg()     ); // sp
 140 reg_def R31_H   (  NS,  NS, Op_RegI, 31, r31_sp->as_VMReg()->next());
 141 
 142 // ----------------------------
 143 // Float/Double Registers
 144 // ----------------------------
 145 
 146 // Double Registers
 147 
 148 // The rules of ADL require that double registers be defined in pairs.
 149 // Each pair must be two 32-bit values, but not necessarily a pair of
 150 // single float registers. In each pair, ADLC-assigned register numbers
 151 // must be adjacent, with the lower number even. Finally, when the
 152 // CPU stores such a register pair to memory, the word associated with
 153 // the lower ADLC-assigned number must be stored to the lower address.
 154 
 155 // AArch64 has 32 floating-point registers. Each can store a vector of
 156 // single or double precision floating-point values up to 8 * 32
 157 // floats, 4 * 64 bit floats or 2 * 128 bit floats.  We currently only
 158 // use the first float or double element of the vector.
 159 
 160 // for Java use float registers v0-v15 are always save on call whereas
 161 // the platform ABI treats v8-v15 as callee save). float registers
 162 // v16-v31 are SOC as per the platform spec
 163 
 164   reg_def V0   ( SOC, SOC, Op_RegF,  0, v0->as_VMReg()          );
 165   reg_def V0_H ( SOC, SOC, Op_RegF,  0, v0->as_VMReg()->next()  );
 166   reg_def V0_J ( SOC, SOC, Op_RegF,  0, v0->as_VMReg()->next(2) );
 167   reg_def V0_K ( SOC, SOC, Op_RegF,  0, v0->as_VMReg()->next(3) );
 168 
 169   reg_def V1   ( SOC, SOC, Op_RegF,  1, v1->as_VMReg()          );
 170   reg_def V1_H ( SOC, SOC, Op_RegF,  1, v1->as_VMReg()->next()  );
 171   reg_def V1_J ( SOC, SOC, Op_RegF,  1, v1->as_VMReg()->next(2) );
 172   reg_def V1_K ( SOC, SOC, Op_RegF,  1, v1->as_VMReg()->next(3) );
 173 
 174   reg_def V2   ( SOC, SOC, Op_RegF,  2, v2->as_VMReg()          );
 175   reg_def V2_H ( SOC, SOC, Op_RegF,  2, v2->as_VMReg()->next()  );
 176   reg_def V2_J ( SOC, SOC, Op_RegF,  2, v2->as_VMReg()->next(2) );
 177   reg_def V2_K ( SOC, SOC, Op_RegF,  2, v2->as_VMReg()->next(3) );
 178 
 179   reg_def V3   ( SOC, SOC, Op_RegF,  3, v3->as_VMReg()          );
 180   reg_def V3_H ( SOC, SOC, Op_RegF,  3, v3->as_VMReg()->next()  );
 181   reg_def V3_J ( SOC, SOC, Op_RegF,  3, v3->as_VMReg()->next(2) );
 182   reg_def V3_K ( SOC, SOC, Op_RegF,  3, v3->as_VMReg()->next(3) );
 183 
 184   reg_def V4   ( SOC, SOC, Op_RegF,  4, v4->as_VMReg()          );
 185   reg_def V4_H ( SOC, SOC, Op_RegF,  4, v4->as_VMReg()->next()  );
 186   reg_def V4_J ( SOC, SOC, Op_RegF,  4, v4->as_VMReg()->next(2) );
 187   reg_def V4_K ( SOC, SOC, Op_RegF,  4, v4->as_VMReg()->next(3) );
 188 
 189   reg_def V5   ( SOC, SOC, Op_RegF,  5, v5->as_VMReg()          );
 190   reg_def V5_H ( SOC, SOC, Op_RegF,  5, v5->as_VMReg()->next()  );
 191   reg_def V5_J ( SOC, SOC, Op_RegF,  5, v5->as_VMReg()->next(2) );
 192   reg_def V5_K ( SOC, SOC, Op_RegF,  5, v5->as_VMReg()->next(3) );
 193 
 194   reg_def V6   ( SOC, SOC, Op_RegF,  6, v6->as_VMReg()          );
 195   reg_def V6_H ( SOC, SOC, Op_RegF,  6, v6->as_VMReg()->next()  );
 196   reg_def V6_J ( SOC, SOC, Op_RegF,  6, v6->as_VMReg()->next(2) );
 197   reg_def V6_K ( SOC, SOC, Op_RegF,  6, v6->as_VMReg()->next(3) );
 198 
 199   reg_def V7   ( SOC, SOC, Op_RegF,  7, v7->as_VMReg()          );
 200   reg_def V7_H ( SOC, SOC, Op_RegF,  7, v7->as_VMReg()->next()  );
 201   reg_def V7_J ( SOC, SOC, Op_RegF,  7, v7->as_VMReg()->next(2) );
 202   reg_def V7_K ( SOC, SOC, Op_RegF,  7, v7->as_VMReg()->next(3) );
 203 
 204   reg_def V8   ( SOC, SOC, Op_RegF,  8, v8->as_VMReg()          );
 205   reg_def V8_H ( SOC, SOC, Op_RegF,  8, v8->as_VMReg()->next()  );
 206   reg_def V8_J ( SOC, SOC, Op_RegF,  8, v8->as_VMReg()->next(2) );
 207   reg_def V8_K ( SOC, SOC, Op_RegF,  8, v8->as_VMReg()->next(3) );
 208 
 209   reg_def V9   ( SOC, SOC, Op_RegF,  9, v9->as_VMReg()          );
 210   reg_def V9_H ( SOC, SOC, Op_RegF,  9, v9->as_VMReg()->next()  );
 211   reg_def V9_J ( SOC, SOC, Op_RegF,  9, v9->as_VMReg()->next(2) );
 212   reg_def V9_K ( SOC, SOC, Op_RegF,  9, v9->as_VMReg()->next(3) );
 213 
 214   reg_def V10  ( SOC, SOC, Op_RegF, 10, v10->as_VMReg()         );
 215   reg_def V10_H( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next() );
 216   reg_def V10_J( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(2));
 217   reg_def V10_K( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(3));
 218 
 219   reg_def V11  ( SOC, SOC, Op_RegF, 11, v11->as_VMReg()         );
 220   reg_def V11_H( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next() );
 221   reg_def V11_J( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(2));
 222   reg_def V11_K( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(3));
 223 
 224   reg_def V12  ( SOC, SOC, Op_RegF, 12, v12->as_VMReg()         );
 225   reg_def V12_H( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next() );
 226   reg_def V12_J( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(2));
 227   reg_def V12_K( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(3));
 228 
 229   reg_def V13  ( SOC, SOC, Op_RegF, 13, v13->as_VMReg()         );
 230   reg_def V13_H( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next() );
 231   reg_def V13_J( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(2));
 232   reg_def V13_K( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(3));
 233 
 234   reg_def V14  ( SOC, SOC, Op_RegF, 14, v14->as_VMReg()         );
 235   reg_def V14_H( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next() );
 236   reg_def V14_J( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(2));
 237   reg_def V14_K( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(3));
 238 
 239   reg_def V15  ( SOC, SOC, Op_RegF, 15, v15->as_VMReg()         );
 240   reg_def V15_H( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next() );
 241   reg_def V15_J( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(2));
 242   reg_def V15_K( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(3));
 243 
 244   reg_def V16  ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()         );
 245   reg_def V16_H( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next() );
 246   reg_def V16_J( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(2));
 247   reg_def V16_K( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(3));
 248 
 249   reg_def V17  ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()         );
 250   reg_def V17_H( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next() );
 251   reg_def V17_J( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(2));
 252   reg_def V17_K( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(3));
 253 
 254   reg_def V18  ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()         );
 255   reg_def V18_H( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next() );
 256   reg_def V18_J( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(2));
 257   reg_def V18_K( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(3));
 258 
 259   reg_def V19  ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()         );
 260   reg_def V19_H( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next() );
 261   reg_def V19_J( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(2));
 262   reg_def V19_K( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(3));
 263 
 264   reg_def V20  ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()         );
 265   reg_def V20_H( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next() );
 266   reg_def V20_J( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(2));
 267   reg_def V20_K( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(3));
 268 
 269   reg_def V21  ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()         );
 270   reg_def V21_H( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next() );
 271   reg_def V21_J( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(2));
 272   reg_def V21_K( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(3));
 273 
 274   reg_def V22  ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()         );
 275   reg_def V22_H( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next() );
 276   reg_def V22_J( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(2));
 277   reg_def V22_K( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(3));
 278 
 279   reg_def V23  ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()         );
 280   reg_def V23_H( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next() );
 281   reg_def V23_J( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(2));
 282   reg_def V23_K( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(3));
 283 
 284   reg_def V24  ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()         );
 285   reg_def V24_H( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next() );
 286   reg_def V24_J( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(2));
 287   reg_def V24_K( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(3));
 288 
 289   reg_def V25  ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()         );
 290   reg_def V25_H( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next() );
 291   reg_def V25_J( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(2));
 292   reg_def V25_K( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(3));
 293 
 294   reg_def V26  ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()         );
 295   reg_def V26_H( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next() );
 296   reg_def V26_J( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(2));
 297   reg_def V26_K( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(3));
 298 
 299   reg_def V27  ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()         );
 300   reg_def V27_H( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next() );
 301   reg_def V27_J( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(2));
 302   reg_def V27_K( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(3));
 303 
 304   reg_def V28  ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()         );
 305   reg_def V28_H( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next() );
 306   reg_def V28_J( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(2));
 307   reg_def V28_K( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(3));
 308 
 309   reg_def V29  ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()         );
 310   reg_def V29_H( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next() );
 311   reg_def V29_J( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(2));
 312   reg_def V29_K( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(3));
 313 
 314   reg_def V30  ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()         );
 315   reg_def V30_H( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next() );
 316   reg_def V30_J( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(2));
 317   reg_def V30_K( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(3));
 318 
 319   reg_def V31  ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()         );
 320   reg_def V31_H( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next() );
 321   reg_def V31_J( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(2));
 322   reg_def V31_K( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(3));
 323 
 324 // ----------------------------
 325 // Special Registers
 326 // ----------------------------
 327 
 328 // the AArch64 CSPR status flag register is not directly acessible as
 329 // instruction operand. the FPSR status flag register is a system
 330 // register which can be written/read using MSR/MRS but again does not
 331 // appear as an operand (a code identifying the FSPR occurs as an
 332 // immediate value in the instruction).
 333 
 334 reg_def RFLAGS(SOC, SOC, 0, 32, VMRegImpl::Bad());
 335 
 336 
 337 // Specify priority of register selection within phases of register
 338 // allocation.  Highest priority is first.  A useful heuristic is to
 339 // give registers a low priority when they are required by machine
 340 // instructions, like EAX and EDX on I486, and choose no-save registers
 341 // before save-on-call, & save-on-call before save-on-entry.  Registers
 342 // which participate in fixed calling sequences should come last.
 343 // Registers which are used as pairs must fall on an even boundary.
 344 
 345 alloc_class chunk0(
 346     // volatiles
 347     R10, R10_H,
 348     R11, R11_H,
 349     R12, R12_H,
 350     R13, R13_H,
 351     R14, R14_H,
 352     R15, R15_H,
 353     R16, R16_H,
 354     R17, R17_H,
 355     R18, R18_H,
 356 
 357     // arg registers
 358     R0, R0_H,
 359     R1, R1_H,
 360     R2, R2_H,
 361     R3, R3_H,
 362     R4, R4_H,
 363     R5, R5_H,
 364     R6, R6_H,
 365     R7, R7_H,
 366 
 367     // non-volatiles
 368     R19, R19_H,
 369     R20, R20_H,
 370     R21, R21_H,
 371     R22, R22_H,
 372     R23, R23_H,
 373     R24, R24_H,
 374     R25, R25_H,
 375     R26, R26_H,
 376 
 377     // non-allocatable registers
 378 
 379     R27, R27_H, // heapbase
 380     R28, R28_H, // thread
 381     R29, R29_H, // fp
 382     R30, R30_H, // lr
 383     R31, R31_H, // sp
 384 );
 385 
 386 alloc_class chunk1(
 387 
 388     // no save
 389     V16, V16_H, V16_J, V16_K,
 390     V17, V17_H, V17_J, V17_K,
 391     V18, V18_H, V18_J, V18_K,
 392     V19, V19_H, V19_J, V19_K,
 393     V20, V20_H, V20_J, V20_K,
 394     V21, V21_H, V21_J, V21_K,
 395     V22, V22_H, V22_J, V22_K,
 396     V23, V23_H, V23_J, V23_K,
 397     V24, V24_H, V24_J, V24_K,
 398     V25, V25_H, V25_J, V25_K,
 399     V26, V26_H, V26_J, V26_K,
 400     V27, V27_H, V27_J, V27_K,
 401     V28, V28_H, V28_J, V28_K,
 402     V29, V29_H, V29_J, V29_K,
 403     V30, V30_H, V30_J, V30_K,
 404     V31, V31_H, V31_J, V31_K,
 405 
 406     // arg registers
 407     V0, V0_H, V0_J, V0_K,
 408     V1, V1_H, V1_J, V1_K,
 409     V2, V2_H, V2_J, V2_K,
 410     V3, V3_H, V3_J, V3_K,
 411     V4, V4_H, V4_J, V4_K,
 412     V5, V5_H, V5_J, V5_K,
 413     V6, V6_H, V6_J, V6_K,
 414     V7, V7_H, V7_J, V7_K,
 415 
 416     // non-volatiles
 417     V8, V8_H, V8_J, V8_K,
 418     V9, V9_H, V9_J, V9_K,
 419     V10, V10_H, V10_J, V10_K,
 420     V11, V11_H, V11_J, V11_K,
 421     V12, V12_H, V12_J, V12_K,
 422     V13, V13_H, V13_J, V13_K,
 423     V14, V14_H, V14_J, V14_K,
 424     V15, V15_H, V15_J, V15_K,
 425 );
 426 
 427 alloc_class chunk2(RFLAGS);
 428 
 429 //----------Architecture Description Register Classes--------------------------
 430 // Several register classes are automatically defined based upon information in
 431 // this architecture description.
 432 // 1) reg_class inline_cache_reg           ( /* as def'd in frame section */ )
 433 // 2) reg_class compiler_method_oop_reg    ( /* as def'd in frame section */ )
 434 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ )
 435 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
 436 //
 437 
 438 // Class for all 32 bit integer registers -- excludes SP which will
 439 // never be used as an integer register
 440 reg_class any_reg32(
 441     R0,
 442     R1,
 443     R2,
 444     R3,
 445     R4,
 446     R5,
 447     R6,
 448     R7,
 449     R10,
 450     R11,
 451     R12,
 452     R13,
 453     R14,
 454     R15,
 455     R16,
 456     R17,
 457     R18,
 458     R19,
 459     R20,
 460     R21,
 461     R22,
 462     R23,
 463     R24,
 464     R25,
 465     R26,
 466     R27,
 467     R28,
 468     R29,
 469     R30
 470 );
 471 
 472 // Singleton class for R0 int register
 473 reg_class int_r0_reg(R0);
 474 
 475 // Singleton class for R2 int register
 476 reg_class int_r2_reg(R2);
 477 
 478 // Singleton class for R3 int register
 479 reg_class int_r3_reg(R3);
 480 
 481 // Singleton class for R4 int register
 482 reg_class int_r4_reg(R4);
 483 
 484 // Class for all long integer registers (including RSP)
 485 reg_class any_reg(
 486     R0, R0_H,
 487     R1, R1_H,
 488     R2, R2_H,
 489     R3, R3_H,
 490     R4, R4_H,
 491     R5, R5_H,
 492     R6, R6_H,
 493     R7, R7_H,
 494     R10, R10_H,
 495     R11, R11_H,
 496     R12, R12_H,
 497     R13, R13_H,
 498     R14, R14_H,
 499     R15, R15_H,
 500     R16, R16_H,
 501     R17, R17_H,
 502     R18, R18_H,
 503     R19, R19_H,
 504     R20, R20_H,
 505     R21, R21_H,
 506     R22, R22_H,
 507     R23, R23_H,
 508     R24, R24_H,
 509     R25, R25_H,
 510     R26, R26_H,
 511     R27, R27_H,
 512     R28, R28_H,
 513     R29, R29_H,
 514     R30, R30_H,
 515     R31, R31_H
 516 );
 517 
 518 // Class for all non-special integer registers
 519 reg_class no_special_reg32_no_fp(
 520     R0,
 521     R1,
 522     R2,
 523     R3,
 524     R4,
 525     R5,
 526     R6,
 527     R7,
 528     R10,
 529     R11,
 530     R12,                        // rmethod
 531     R13,
 532     R14,
 533     R15,
 534     R16,
 535     R17,
 536     R18,
 537     R19,
 538     R20,
 539     R21,
 540     R22,
 541     R23,
 542     R24,
 543     R25,
 544     R26
 545  /* R27, */                     // heapbase
 546  /* R28, */                     // thread
 547  /* R29, */                     // fp
 548  /* R30, */                     // lr
 549  /* R31 */                      // sp
 550 );
 551 
 552 reg_class no_special_reg32_with_fp(
 553     R0,
 554     R1,
 555     R2,
 556     R3,
 557     R4,
 558     R5,
 559     R6,
 560     R7,
 561     R10,
 562     R11,
 563     R12,                        // rmethod
 564     R13,
 565     R14,
 566     R15,
 567     R16,
 568     R17,
 569     R18,
 570     R19,
 571     R20,
 572     R21,
 573     R22,
 574     R23,
 575     R24,
 576     R25,
 577     R26
 578  /* R27, */                     // heapbase
 579  /* R28, */                     // thread
 580     R29,                        // fp
 581  /* R30, */                     // lr
 582  /* R31 */                      // sp
 583 );
 584 
 585 reg_class_dynamic no_special_reg32(no_special_reg32_no_fp, no_special_reg32_with_fp, %{ PreserveFramePointer %});
 586 
 587 // Class for all non-special long integer registers
 588 reg_class no_special_reg_no_fp(
 589     R0, R0_H,
 590     R1, R1_H,
 591     R2, R2_H,
 592     R3, R3_H,
 593     R4, R4_H,
 594     R5, R5_H,
 595     R6, R6_H,
 596     R7, R7_H,
 597     R10, R10_H,
 598     R11, R11_H,
 599     R12, R12_H,                 // rmethod
 600     R13, R13_H,
 601     R14, R14_H,
 602     R15, R15_H,
 603     R16, R16_H,
 604     R17, R17_H,
 605     R18, R18_H,
 606     R19, R19_H,
 607     R20, R20_H,
 608     R21, R21_H,
 609     R22, R22_H,
 610     R23, R23_H,
 611     R24, R24_H,
 612     R25, R25_H,
 613     R26, R26_H,
 614  /* R27, R27_H, */              // heapbase
 615  /* R28, R28_H, */              // thread
 616  /* R29, R29_H, */              // fp
 617  /* R30, R30_H, */              // lr
 618  /* R31, R31_H */               // sp
 619 );
 620 
 621 reg_class no_special_reg_with_fp(
 622     R0, R0_H,
 623     R1, R1_H,
 624     R2, R2_H,
 625     R3, R3_H,
 626     R4, R4_H,
 627     R5, R5_H,
 628     R6, R6_H,
 629     R7, R7_H,
 630     R10, R10_H,
 631     R11, R11_H,
 632     R12, R12_H,                 // rmethod
 633     R13, R13_H,
 634     R14, R14_H,
 635     R15, R15_H,
 636     R16, R16_H,
 637     R17, R17_H,
 638     R18, R18_H,
 639     R19, R19_H,
 640     R20, R20_H,
 641     R21, R21_H,
 642     R22, R22_H,
 643     R23, R23_H,
 644     R24, R24_H,
 645     R25, R25_H,
 646     R26, R26_H,
 647  /* R27, R27_H, */              // heapbase
 648  /* R28, R28_H, */              // thread
 649     R29, R29_H,                 // fp
 650  /* R30, R30_H, */              // lr
 651  /* R31, R31_H */               // sp
 652 );
 653 
 654 reg_class_dynamic no_special_reg(no_special_reg_no_fp, no_special_reg_with_fp, %{ PreserveFramePointer %});
 655 
 656 // Class for 64 bit register r0
 657 reg_class r0_reg(
 658     R0, R0_H
 659 );
 660 
 661 // Class for 64 bit register r1
 662 reg_class r1_reg(
 663     R1, R1_H
 664 );
 665 
 666 // Class for 64 bit register r2
 667 reg_class r2_reg(
 668     R2, R2_H
 669 );
 670 
 671 // Class for 64 bit register r3
 672 reg_class r3_reg(
 673     R3, R3_H
 674 );
 675 
 676 // Class for 64 bit register r4
 677 reg_class r4_reg(
 678     R4, R4_H
 679 );
 680 
 681 // Class for 64 bit register r5
 682 reg_class r5_reg(
 683     R5, R5_H
 684 );
 685 
 686 // Class for 64 bit register r10
 687 reg_class r10_reg(
 688     R10, R10_H
 689 );
 690 
 691 // Class for 64 bit register r11
 692 reg_class r11_reg(
 693     R11, R11_H
 694 );
 695 
 696 // Class for method register
 697 reg_class method_reg(
 698     R12, R12_H
 699 );
 700 
 701 // Class for heapbase register
 702 reg_class heapbase_reg(
 703     R27, R27_H
 704 );
 705 
 706 // Class for thread register
 707 reg_class thread_reg(
 708     R28, R28_H
 709 );
 710 
 711 // Class for frame pointer register
 712 reg_class fp_reg(
 713     R29, R29_H
 714 );
 715 
 716 // Class for link register
 717 reg_class lr_reg(
 718     R30, R30_H
 719 );
 720 
 721 // Class for long sp register
 722 reg_class sp_reg(
 723   R31, R31_H
 724 );
 725 
 726 // Class for all pointer registers
 727 reg_class ptr_reg(
 728     R0, R0_H,
 729     R1, R1_H,
 730     R2, R2_H,
 731     R3, R3_H,
 732     R4, R4_H,
 733     R5, R5_H,
 734     R6, R6_H,
 735     R7, R7_H,
 736     R10, R10_H,
 737     R11, R11_H,
 738     R12, R12_H,
 739     R13, R13_H,
 740     R14, R14_H,
 741     R15, R15_H,
 742     R16, R16_H,
 743     R17, R17_H,
 744     R18, R18_H,
 745     R19, R19_H,
 746     R20, R20_H,
 747     R21, R21_H,
 748     R22, R22_H,
 749     R23, R23_H,
 750     R24, R24_H,
 751     R25, R25_H,
 752     R26, R26_H,
 753     R27, R27_H,
 754     R28, R28_H,
 755     R29, R29_H,
 756     R30, R30_H,
 757     R31, R31_H
 758 );
 759 
 760 // Class for all non_special pointer registers
 761 reg_class no_special_ptr_reg(
 762     R0, R0_H,
 763     R1, R1_H,
 764     R2, R2_H,
 765     R3, R3_H,
 766     R4, R4_H,
 767     R5, R5_H,
 768     R6, R6_H,
 769     R7, R7_H,
 770     R10, R10_H,
 771     R11, R11_H,
 772     R12, R12_H,
 773     R13, R13_H,
 774     R14, R14_H,
 775     R15, R15_H,
 776     R16, R16_H,
 777     R17, R17_H,
 778     R18, R18_H,
 779     R19, R19_H,
 780     R20, R20_H,
 781     R21, R21_H,
 782     R22, R22_H,
 783     R23, R23_H,
 784     R24, R24_H,
 785     R25, R25_H,
 786     R26, R26_H,
 787  /* R27, R27_H, */              // heapbase
 788  /* R28, R28_H, */              // thread
 789  /* R29, R29_H, */              // fp
 790  /* R30, R30_H, */              // lr
 791  /* R31, R31_H */               // sp
 792 );
 793 
 794 // Class for all float registers
 795 reg_class float_reg(
 796     V0,
 797     V1,
 798     V2,
 799     V3,
 800     V4,
 801     V5,
 802     V6,
 803     V7,
 804     V8,
 805     V9,
 806     V10,
 807     V11,
 808     V12,
 809     V13,
 810     V14,
 811     V15,
 812     V16,
 813     V17,
 814     V18,
 815     V19,
 816     V20,
 817     V21,
 818     V22,
 819     V23,
 820     V24,
 821     V25,
 822     V26,
 823     V27,
 824     V28,
 825     V29,
 826     V30,
 827     V31
 828 );
 829 
 830 // Double precision float registers have virtual `high halves' that
 831 // are needed by the allocator.
 832 // Class for all double registers
 833 reg_class double_reg(
 834     V0, V0_H,
 835     V1, V1_H,
 836     V2, V2_H,
 837     V3, V3_H,
 838     V4, V4_H,
 839     V5, V5_H,
 840     V6, V6_H,
 841     V7, V7_H,
 842     V8, V8_H,
 843     V9, V9_H,
 844     V10, V10_H,
 845     V11, V11_H,
 846     V12, V12_H,
 847     V13, V13_H,
 848     V14, V14_H,
 849     V15, V15_H,
 850     V16, V16_H,
 851     V17, V17_H,
 852     V18, V18_H,
 853     V19, V19_H,
 854     V20, V20_H,
 855     V21, V21_H,
 856     V22, V22_H,
 857     V23, V23_H,
 858     V24, V24_H,
 859     V25, V25_H,
 860     V26, V26_H,
 861     V27, V27_H,
 862     V28, V28_H,
 863     V29, V29_H,
 864     V30, V30_H,
 865     V31, V31_H
 866 );
 867 
 868 // Class for all 64bit vector registers
 869 reg_class vectord_reg(
 870     V0, V0_H,
 871     V1, V1_H,
 872     V2, V2_H,
 873     V3, V3_H,
 874     V4, V4_H,
 875     V5, V5_H,
 876     V6, V6_H,
 877     V7, V7_H,
 878     V8, V8_H,
 879     V9, V9_H,
 880     V10, V10_H,
 881     V11, V11_H,
 882     V12, V12_H,
 883     V13, V13_H,
 884     V14, V14_H,
 885     V15, V15_H,
 886     V16, V16_H,
 887     V17, V17_H,
 888     V18, V18_H,
 889     V19, V19_H,
 890     V20, V20_H,
 891     V21, V21_H,
 892     V22, V22_H,
 893     V23, V23_H,
 894     V24, V24_H,
 895     V25, V25_H,
 896     V26, V26_H,
 897     V27, V27_H,
 898     V28, V28_H,
 899     V29, V29_H,
 900     V30, V30_H,
 901     V31, V31_H
 902 );
 903 
 904 // Class for all 128bit vector registers
 905 reg_class vectorx_reg(
 906     V0, V0_H, V0_J, V0_K,
 907     V1, V1_H, V1_J, V1_K,
 908     V2, V2_H, V2_J, V2_K,
 909     V3, V3_H, V3_J, V3_K,
 910     V4, V4_H, V4_J, V4_K,
 911     V5, V5_H, V5_J, V5_K,
 912     V6, V6_H, V6_J, V6_K,
 913     V7, V7_H, V7_J, V7_K,
 914     V8, V8_H, V8_J, V8_K,
 915     V9, V9_H, V9_J, V9_K,
 916     V10, V10_H, V10_J, V10_K,
 917     V11, V11_H, V11_J, V11_K,
 918     V12, V12_H, V12_J, V12_K,
 919     V13, V13_H, V13_J, V13_K,
 920     V14, V14_H, V14_J, V14_K,
 921     V15, V15_H, V15_J, V15_K,
 922     V16, V16_H, V16_J, V16_K,
 923     V17, V17_H, V17_J, V17_K,
 924     V18, V18_H, V18_J, V18_K,
 925     V19, V19_H, V19_J, V19_K,
 926     V20, V20_H, V20_J, V20_K,
 927     V21, V21_H, V21_J, V21_K,
 928     V22, V22_H, V22_J, V22_K,
 929     V23, V23_H, V23_J, V23_K,
 930     V24, V24_H, V24_J, V24_K,
 931     V25, V25_H, V25_J, V25_K,
 932     V26, V26_H, V26_J, V26_K,
 933     V27, V27_H, V27_J, V27_K,
 934     V28, V28_H, V28_J, V28_K,
 935     V29, V29_H, V29_J, V29_K,
 936     V30, V30_H, V30_J, V30_K,
 937     V31, V31_H, V31_J, V31_K
 938 );
 939 
 940 // Class for 128 bit register v0
 941 reg_class v0_reg(
 942     V0, V0_H
 943 );
 944 
 945 // Class for 128 bit register v1
 946 reg_class v1_reg(
 947     V1, V1_H
 948 );
 949 
 950 // Class for 128 bit register v2
 951 reg_class v2_reg(
 952     V2, V2_H
 953 );
 954 
 955 // Class for 128 bit register v3
 956 reg_class v3_reg(
 957     V3, V3_H
 958 );
 959 
 960 // Singleton class for condition codes
 961 reg_class int_flags(RFLAGS);
 962 
 963 %}
 964 
 965 //----------DEFINITION BLOCK---------------------------------------------------
 966 // Define name --> value mappings to inform the ADLC of an integer valued name
 967 // Current support includes integer values in the range [0, 0x7FFFFFFF]
 968 // Format:
 969 //        int_def  <name>         ( <int_value>, <expression>);
 970 // Generated Code in ad_<arch>.hpp
 971 //        #define  <name>   (<expression>)
 972 //        // value == <int_value>
 973 // Generated code in ad_<arch>.cpp adlc_verification()
 974 //        assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
 975 //
 976 
 977 // we follow the ppc-aix port in using a simple cost model which ranks
 978 // register operations as cheap, memory ops as more expensive and
 979 // branches as most expensive. the first two have a low as well as a
 980 // normal cost. huge cost appears to be a way of saying don't do
 981 // something
 982 
 983 definitions %{
 984   // The default cost (of a register move instruction).
 985   int_def INSN_COST            (    100,     100);
 986   int_def BRANCH_COST          (    200,     2 * INSN_COST);
 987   int_def CALL_COST            (    200,     2 * INSN_COST);
 988   int_def VOLATILE_REF_COST    (   1000,     10 * INSN_COST);
 989 %}
 990 
 991 
 992 //----------SOURCE BLOCK-------------------------------------------------------
 993 // This is a block of C++ code which provides values, functions, and
 994 // definitions necessary in the rest of the architecture description
 995 
 996 source_hpp %{
 997 
 998 #include "asm/macroAssembler.hpp"
 999 #include "gc/shared/cardTable.hpp"
1000 #include "gc/shared/cardTableBarrierSet.hpp"
1001 #include "gc/shared/collectedHeap.hpp"
1002 #include "opto/addnode.hpp"
1003 
1004 class CallStubImpl {
1005 
1006   //--------------------------------------------------------------
1007   //---<  Used for optimization in Compile::shorten_branches  >---
1008   //--------------------------------------------------------------
1009 
1010  public:
1011   // Size of call trampoline stub.
1012   static uint size_call_trampoline() {
1013     return 0; // no call trampolines on this platform
1014   }
1015 
1016   // number of relocations needed by a call trampoline stub
1017   static uint reloc_call_trampoline() {
1018     return 0; // no call trampolines on this platform
1019   }
1020 };
1021 
1022 class HandlerImpl {
1023 
1024  public:
1025 
1026   static int emit_exception_handler(CodeBuffer &cbuf);
1027   static int emit_deopt_handler(CodeBuffer& cbuf);
1028 
1029   static uint size_exception_handler() {
1030     return MacroAssembler::far_branch_size();
1031   }
1032 
1033   static uint size_deopt_handler() {
1034     // count one adr and one far branch instruction
1035     return 4 * NativeInstruction::instruction_size;
1036   }
1037 };
1038 
1039  bool is_CAS(int opcode, bool maybe_volatile);
1040 
1041   // predicates controlling emit of ldr<x>/ldar<x> and associated dmb
1042 
1043   bool unnecessary_acquire(const Node *barrier);
1044   bool needs_acquiring_load(const Node *load);
1045 
1046   // predicates controlling emit of str<x>/stlr<x> and associated dmbs
1047 
1048   bool unnecessary_release(const Node *barrier);
1049   bool unnecessary_volatile(const Node *barrier);
1050   bool needs_releasing_store(const Node *store);
1051 
1052   // predicate controlling translation of CompareAndSwapX
1053   bool needs_acquiring_load_exclusive(const Node *load);
1054 
1055   // predicate controlling translation of StoreCM
1056   bool unnecessary_storestore(const Node *storecm);
1057 
1058   // predicate controlling addressing modes
1059   bool size_fits_all_mem_uses(AddPNode* addp, int shift);
1060 %}
1061 
1062 source %{
1063 
1064   // Optimizaton of volatile gets and puts
1065   // -------------------------------------
1066   //
1067   // AArch64 has ldar<x> and stlr<x> instructions which we can safely
1068   // use to implement volatile reads and writes. For a volatile read
1069   // we simply need
1070   //
1071   //   ldar<x>
1072   //
1073   // and for a volatile write we need
1074   //
1075   //   stlr<x>
1076   //
1077   // Alternatively, we can implement them by pairing a normal
1078   // load/store with a memory barrier. For a volatile read we need
1079   //
1080   //   ldr<x>
1081   //   dmb ishld
1082   //
1083   // for a volatile write
1084   //
1085   //   dmb ish
1086   //   str<x>
1087   //   dmb ish
1088   //
1089   // We can also use ldaxr and stlxr to implement compare and swap CAS
1090   // sequences. These are normally translated to an instruction
1091   // sequence like the following
1092   //
1093   //   dmb      ish
1094   // retry:
1095   //   ldxr<x>   rval raddr
1096   //   cmp       rval rold
1097   //   b.ne done
1098   //   stlxr<x>  rval, rnew, rold
1099   //   cbnz      rval retry
1100   // done:
1101   //   cset      r0, eq
1102   //   dmb ishld
1103   //
1104   // Note that the exclusive store is already using an stlxr
1105   // instruction. That is required to ensure visibility to other
1106   // threads of the exclusive write (assuming it succeeds) before that
1107   // of any subsequent writes.
1108   //
1109   // The following instruction sequence is an improvement on the above
1110   //
1111   // retry:
1112   //   ldaxr<x>  rval raddr
1113   //   cmp       rval rold
1114   //   b.ne done
1115   //   stlxr<x>  rval, rnew, rold
1116   //   cbnz      rval retry
1117   // done:
1118   //   cset      r0, eq
1119   //
1120   // We don't need the leading dmb ish since the stlxr guarantees
1121   // visibility of prior writes in the case that the swap is
1122   // successful. Crucially we don't have to worry about the case where
1123   // the swap is not successful since no valid program should be
1124   // relying on visibility of prior changes by the attempting thread
1125   // in the case where the CAS fails.
1126   //
1127   // Similarly, we don't need the trailing dmb ishld if we substitute
1128   // an ldaxr instruction since that will provide all the guarantees we
1129   // require regarding observation of changes made by other threads
1130   // before any change to the CAS address observed by the load.
1131   //
1132   // In order to generate the desired instruction sequence we need to
1133   // be able to identify specific 'signature' ideal graph node
1134   // sequences which i) occur as a translation of a volatile reads or
1135   // writes or CAS operations and ii) do not occur through any other
1136   // translation or graph transformation. We can then provide
1137   // alternative aldc matching rules which translate these node
1138   // sequences to the desired machine code sequences. Selection of the
1139   // alternative rules can be implemented by predicates which identify
1140   // the relevant node sequences.
1141   //
1142   // The ideal graph generator translates a volatile read to the node
1143   // sequence
1144   //
1145   //   LoadX[mo_acquire]
1146   //   MemBarAcquire
1147   //
1148   // As a special case when using the compressed oops optimization we
1149   // may also see this variant
1150   //
1151   //   LoadN[mo_acquire]
1152   //   DecodeN
1153   //   MemBarAcquire
1154   //
1155   // A volatile write is translated to the node sequence
1156   //
1157   //   MemBarRelease
1158   //   StoreX[mo_release] {CardMark}-optional
1159   //   MemBarVolatile
1160   //
1161   // n.b. the above node patterns are generated with a strict
1162   // 'signature' configuration of input and output dependencies (see
1163   // the predicates below for exact details). The card mark may be as
1164   // simple as a few extra nodes or, in a few GC configurations, may
1165   // include more complex control flow between the leading and
1166   // trailing memory barriers. However, whatever the card mark
1167   // configuration these signatures are unique to translated volatile
1168   // reads/stores -- they will not appear as a result of any other
1169   // bytecode translation or inlining nor as a consequence of
1170   // optimizing transforms.
1171   //
1172   // We also want to catch inlined unsafe volatile gets and puts and
1173   // be able to implement them using either ldar<x>/stlr<x> or some
1174   // combination of ldr<x>/stlr<x> and dmb instructions.
1175   //
1176   // Inlined unsafe volatiles puts manifest as a minor variant of the
1177   // normal volatile put node sequence containing an extra cpuorder
1178   // membar
1179   //
1180   //   MemBarRelease
1181   //   MemBarCPUOrder
1182   //   StoreX[mo_release] {CardMark}-optional
1183   //   MemBarCPUOrder
1184   //   MemBarVolatile
1185   //
1186   // n.b. as an aside, a cpuorder membar is not itself subject to
1187   // matching and translation by adlc rules.  However, the rule
1188   // predicates need to detect its presence in order to correctly
1189   // select the desired adlc rules.
1190   //
1191   // Inlined unsafe volatile gets manifest as a slightly different
1192   // node sequence to a normal volatile get because of the
1193   // introduction of some CPUOrder memory barriers to bracket the
1194   // Load. However, but the same basic skeleton of a LoadX feeding a
1195   // MemBarAcquire, possibly thorugh an optional DecodeN, is still
1196   // present
1197   //
1198   //   MemBarCPUOrder
1199   //        ||       \\
1200   //   MemBarCPUOrder LoadX[mo_acquire]
1201   //        ||            |
1202   //        ||       {DecodeN} optional
1203   //        ||       /
1204   //     MemBarAcquire
1205   //
1206   // In this case the acquire membar does not directly depend on the
1207   // load. However, we can be sure that the load is generated from an
1208   // inlined unsafe volatile get if we see it dependent on this unique
1209   // sequence of membar nodes. Similarly, given an acquire membar we
1210   // can know that it was added because of an inlined unsafe volatile
1211   // get if it is fed and feeds a cpuorder membar and if its feed
1212   // membar also feeds an acquiring load.
1213   //
1214   // Finally an inlined (Unsafe) CAS operation is translated to the
1215   // following ideal graph
1216   //
1217   //   MemBarRelease
1218   //   MemBarCPUOrder
1219   //   CompareAndSwapX {CardMark}-optional
1220   //   MemBarCPUOrder
1221   //   MemBarAcquire
1222   //
1223   // So, where we can identify these volatile read and write
1224   // signatures we can choose to plant either of the above two code
1225   // sequences. For a volatile read we can simply plant a normal
1226   // ldr<x> and translate the MemBarAcquire to a dmb. However, we can
1227   // also choose to inhibit translation of the MemBarAcquire and
1228   // inhibit planting of the ldr<x>, instead planting an ldar<x>.
1229   //
1230   // When we recognise a volatile store signature we can choose to
1231   // plant at a dmb ish as a translation for the MemBarRelease, a
1232   // normal str<x> and then a dmb ish for the MemBarVolatile.
1233   // Alternatively, we can inhibit translation of the MemBarRelease
1234   // and MemBarVolatile and instead plant a simple stlr<x>
1235   // instruction.
1236   //
1237   // when we recognise a CAS signature we can choose to plant a dmb
1238   // ish as a translation for the MemBarRelease, the conventional
1239   // macro-instruction sequence for the CompareAndSwap node (which
1240   // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire.
1241   // Alternatively, we can elide generation of the dmb instructions
1242   // and plant the alternative CompareAndSwap macro-instruction
1243   // sequence (which uses ldaxr<x>).
1244   //
1245   // Of course, the above only applies when we see these signature
1246   // configurations. We still want to plant dmb instructions in any
1247   // other cases where we may see a MemBarAcquire, MemBarRelease or
1248   // MemBarVolatile. For example, at the end of a constructor which
1249   // writes final/volatile fields we will see a MemBarRelease
1250   // instruction and this needs a 'dmb ish' lest we risk the
1251   // constructed object being visible without making the
1252   // final/volatile field writes visible.
1253   //
1254   // n.b. the translation rules below which rely on detection of the
1255   // volatile signatures and insert ldar<x> or stlr<x> are failsafe.
1256   // If we see anything other than the signature configurations we
1257   // always just translate the loads and stores to ldr<x> and str<x>
1258   // and translate acquire, release and volatile membars to the
1259   // relevant dmb instructions.
1260   //
1261 
1262   // is_CAS(int opcode, bool maybe_volatile)
1263   //
1264   // return true if opcode is one of the possible CompareAndSwapX
1265   // values otherwise false.
1266 
1267   bool is_CAS(int opcode, bool maybe_volatile)
1268   {
1269     switch(opcode) {
1270       // We handle these
1271     case Op_CompareAndSwapI:
1272     case Op_CompareAndSwapL:
1273     case Op_CompareAndSwapP:
1274     case Op_CompareAndSwapN:
1275     case Op_CompareAndSwapB:
1276     case Op_CompareAndSwapS:
1277     case Op_GetAndSetI:
1278     case Op_GetAndSetL:
1279     case Op_GetAndSetP:
1280     case Op_GetAndSetN:
1281     case Op_GetAndAddI:
1282     case Op_GetAndAddL:
1283       return true;
1284     case Op_CompareAndExchangeI:
1285     case Op_CompareAndExchangeN:
1286     case Op_CompareAndExchangeB:
1287     case Op_CompareAndExchangeS:
1288     case Op_CompareAndExchangeL:
1289     case Op_CompareAndExchangeP:
1290     case Op_WeakCompareAndSwapB:
1291     case Op_WeakCompareAndSwapS:
1292     case Op_WeakCompareAndSwapI:
1293     case Op_WeakCompareAndSwapL:
1294     case Op_WeakCompareAndSwapP:
1295     case Op_WeakCompareAndSwapN:
1296       return maybe_volatile;
1297     default:
1298       return false;
1299     }
1300   }
1301 
1302   // helper to determine the maximum number of Phi nodes we may need to
1303   // traverse when searching from a card mark membar for the merge mem
1304   // feeding a trailing membar or vice versa
1305 
1306 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb
1307 
1308 bool unnecessary_acquire(const Node *barrier)
1309 {
1310   assert(barrier->is_MemBar(), "expecting a membar");
1311 
1312   if (UseBarriersForVolatile) {
1313     // we need to plant a dmb
1314     return false;
1315   }
1316 
1317   MemBarNode* mb = barrier->as_MemBar();
1318 
1319   if (mb->trailing_load()) {
1320     return true;
1321   }
1322 
1323   if (mb->trailing_load_store()) {
1324     Node* load_store = mb->in(MemBarNode::Precedent);
1325     assert(load_store->is_LoadStore(), "unexpected graph shape");
1326     return is_CAS(load_store->Opcode(), true);
1327   }
1328 
1329   return false;
1330 }
1331 
1332 bool needs_acquiring_load(const Node *n)
1333 {
1334   assert(n->is_Load(), "expecting a load");
1335   if (UseBarriersForVolatile) {
1336     // we use a normal load and a dmb
1337     return false;
1338   }
1339 
1340   LoadNode *ld = n->as_Load();
1341 
1342   return ld->is_acquire();
1343 }
1344 
1345 bool unnecessary_release(const Node *n)
1346 {
1347   assert((n->is_MemBar() &&
1348           n->Opcode() == Op_MemBarRelease),
1349          "expecting a release membar");
1350 
1351   if (UseBarriersForVolatile) {
1352     // we need to plant a dmb
1353     return false;
1354   }
1355 
1356   MemBarNode *barrier = n->as_MemBar();
1357   if (!barrier->leading()) {
1358     return false;
1359   } else {
1360     Node* trailing = barrier->trailing_membar();
1361     MemBarNode* trailing_mb = trailing->as_MemBar();
1362     assert(trailing_mb->trailing(), "Not a trailing membar?");
1363     assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars");
1364 
1365     Node* mem = trailing_mb->in(MemBarNode::Precedent);
1366     if (mem->is_Store()) {
1367       assert(mem->as_Store()->is_release(), "");
1368       assert(trailing_mb->Opcode() == Op_MemBarVolatile, "");
1369       return true;
1370     } else {
1371       assert(mem->is_LoadStore(), "");
1372       assert(trailing_mb->Opcode() == Op_MemBarAcquire, "");
1373       return is_CAS(mem->Opcode(), true);
1374     }
1375   }
1376   return false;
1377 }
1378 
1379 bool unnecessary_volatile(const Node *n)
1380 {
1381   // assert n->is_MemBar();
1382   if (UseBarriersForVolatile) {
1383     // we need to plant a dmb
1384     return false;
1385   }
1386 
1387   MemBarNode *mbvol = n->as_MemBar();
1388 
1389   bool release = mbvol->trailing_store();
1390   assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), "");
1391 #ifdef ASSERT
1392   if (release) {
1393     Node* leading = mbvol->leading_membar();
1394     assert(leading->Opcode() == Op_MemBarRelease, "");
1395     assert(leading->as_MemBar()->leading_store(), "");
1396     assert(leading->as_MemBar()->trailing_membar() == mbvol, "");
1397   }
1398 #endif
1399 
1400   return release;
1401 }
1402 
1403 // predicates controlling emit of str<x>/stlr<x> and associated dmbs
1404 
1405 bool needs_releasing_store(const Node *n)
1406 {
1407   // assert n->is_Store();
1408   if (UseBarriersForVolatile) {
1409     // we use a normal store and dmb combination
1410     return false;
1411   }
1412 
1413   StoreNode *st = n->as_Store();
1414 
1415   return st->trailing_membar() != NULL;
1416 }
1417 
1418 // predicate controlling translation of CAS
1419 //
1420 // returns true if CAS needs to use an acquiring load otherwise false
1421 
1422 bool needs_acquiring_load_exclusive(const Node *n)
1423 {
1424   assert(is_CAS(n->Opcode(), true), "expecting a compare and swap");
1425   if (UseBarriersForVolatile) {
1426     return false;
1427   }
1428 
1429   LoadStoreNode* ldst = n->as_LoadStore();
1430   if (is_CAS(n->Opcode(), false)) {
1431     assert(ldst->trailing_membar() != NULL, "expected trailing membar");
1432   } else {
1433     return ldst->trailing_membar() != NULL;
1434   }
1435 
1436   // so we can just return true here
1437   return true;
1438 }
1439 
1440 // predicate controlling translation of StoreCM
1441 //
1442 // returns true if a StoreStore must precede the card write otherwise
1443 // false
1444 
1445 bool unnecessary_storestore(const Node *storecm)
1446 {
1447   assert(storecm->Opcode()  == Op_StoreCM, "expecting a StoreCM");
1448 
1449   // we need to generate a dmb ishst between an object put and the
1450   // associated card mark when we are using CMS without conditional
1451   // card marking
1452 
1453   if (UseConcMarkSweepGC && !UseCondCardMark) {
1454     return false;
1455   }
1456 
1457   // a storestore is unnecesary in all other cases
1458 
1459   return true;
1460 }
1461 
1462 
1463 #define __ _masm.
1464 
1465 // advance declarations for helper functions to convert register
1466 // indices to register objects
1467 
1468 // the ad file has to provide implementations of certain methods
1469 // expected by the generic code
1470 //
1471 // REQUIRED FUNCTIONALITY
1472 
1473 //=============================================================================
1474 
1475 // !!!!! Special hack to get all types of calls to specify the byte offset
1476 //       from the start of the call to the point where the return address
1477 //       will point.
1478 
1479 int MachCallStaticJavaNode::ret_addr_offset()
1480 {
1481   // call should be a simple bl
1482   int off = 4;
1483   return off;
1484 }
1485 
1486 int MachCallDynamicJavaNode::ret_addr_offset()
1487 {
1488   return 16; // movz, movk, movk, bl
1489 }
1490 
1491 int MachCallRuntimeNode::ret_addr_offset() {
1492   // for generated stubs the call will be
1493   //   far_call(addr)
1494   // for real runtime callouts it will be six instructions
1495   // see aarch64_enc_java_to_runtime
1496   //   adr(rscratch2, retaddr)
1497   //   lea(rscratch1, RuntimeAddress(addr)
1498   //   stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize)))
1499   //   blrt rscratch1
1500   CodeBlob *cb = CodeCache::find_blob(_entry_point);
1501   if (cb) {
1502     return MacroAssembler::far_branch_size();
1503   } else {
1504     return 6 * NativeInstruction::instruction_size;
1505   }
1506 }
1507 
1508 // Indicate if the safepoint node needs the polling page as an input
1509 
1510 // the shared code plants the oop data at the start of the generated
1511 // code for the safepoint node and that needs ot be at the load
1512 // instruction itself. so we cannot plant a mov of the safepoint poll
1513 // address followed by a load. setting this to true means the mov is
1514 // scheduled as a prior instruction. that's better for scheduling
1515 // anyway.
1516 
1517 bool SafePointNode::needs_polling_address_input()
1518 {
1519   return true;
1520 }
1521 
1522 //=============================================================================
1523 
1524 #ifndef PRODUCT
1525 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1526   st->print("BREAKPOINT");
1527 }
1528 #endif
1529 
1530 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1531   MacroAssembler _masm(&cbuf);
1532   __ brk(0);
1533 }
1534 
1535 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
1536   return MachNode::size(ra_);
1537 }
1538 
1539 //=============================================================================
1540 
1541 #ifndef PRODUCT
1542   void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const {
1543     st->print("nop \t# %d bytes pad for loops and calls", _count);
1544   }
1545 #endif
1546 
1547   void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const {
1548     MacroAssembler _masm(&cbuf);
1549     for (int i = 0; i < _count; i++) {
1550       __ nop();
1551     }
1552   }
1553 
1554   uint MachNopNode::size(PhaseRegAlloc*) const {
1555     return _count * NativeInstruction::instruction_size;
1556   }
1557 
1558 //=============================================================================
1559 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
1560 
1561 int Compile::ConstantTable::calculate_table_base_offset() const {
1562   return 0;  // absolute addressing, no offset
1563 }
1564 
1565 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
1566 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1567   ShouldNotReachHere();
1568 }
1569 
1570 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1571   // Empty encoding
1572 }
1573 
1574 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1575   return 0;
1576 }
1577 
1578 #ifndef PRODUCT
1579 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1580   st->print("-- \t// MachConstantBaseNode (empty encoding)");
1581 }
1582 #endif
1583 
1584 #ifndef PRODUCT
1585 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1586   Compile* C = ra_->C;
1587 
1588   int framesize = C->frame_slots() << LogBytesPerInt;
1589 
1590   if (C->need_stack_bang(framesize))
1591     st->print("# stack bang size=%d\n\t", framesize);
1592 
1593   if (framesize < ((1 << 9) + 2 * wordSize)) {
1594     st->print("sub  sp, sp, #%d\n\t", framesize);
1595     st->print("stp  rfp, lr, [sp, #%d]", framesize - 2 * wordSize);
1596     if (PreserveFramePointer) st->print("\n\tadd  rfp, sp, #%d", framesize - 2 * wordSize);
1597   } else {
1598     st->print("stp  lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize));
1599     if (PreserveFramePointer) st->print("mov  rfp, sp\n\t");
1600     st->print("mov  rscratch1, #%d\n\t", framesize - 2 * wordSize);
1601     st->print("sub  sp, sp, rscratch1");
1602   }
1603 }
1604 #endif
1605 
1606 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1607   Compile* C = ra_->C;
1608   MacroAssembler _masm(&cbuf);
1609 
1610   // n.b. frame size includes space for return pc and rfp
1611   const long framesize = C->frame_size_in_bytes();
1612   assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment");
1613 
1614   // insert a nop at the start of the prolog so we can patch in a
1615   // branch if we need to invalidate the method later
1616   __ nop();
1617 
1618   int bangsize = C->bang_size_in_bytes();
1619   if (C->need_stack_bang(bangsize) && UseStackBanging)
1620     __ generate_stack_overflow_check(bangsize);
1621 
1622   __ build_frame(framesize);
1623 
1624   if (NotifySimulator) {
1625     __ notify(Assembler::method_entry);
1626   }
1627 
1628   if (VerifyStackAtCalls) {
1629     Unimplemented();
1630   }
1631 
1632   C->set_frame_complete(cbuf.insts_size());
1633 
1634   if (C->has_mach_constant_base_node()) {
1635     // NOTE: We set the table base offset here because users might be
1636     // emitted before MachConstantBaseNode.
1637     Compile::ConstantTable& constant_table = C->constant_table();
1638     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
1639   }
1640 }
1641 
1642 uint MachPrologNode::size(PhaseRegAlloc* ra_) const
1643 {
1644   return MachNode::size(ra_); // too many variables; just compute it
1645                               // the hard way
1646 }
1647 
1648 int MachPrologNode::reloc() const
1649 {
1650   return 0;
1651 }
1652 
1653 //=============================================================================
1654 
1655 #ifndef PRODUCT
1656 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1657   Compile* C = ra_->C;
1658   int framesize = C->frame_slots() << LogBytesPerInt;
1659 
1660   st->print("# pop frame %d\n\t",framesize);
1661 
1662   if (framesize == 0) {
1663     st->print("ldp  lr, rfp, [sp],#%d\n\t", (2 * wordSize));
1664   } else if (framesize < ((1 << 9) + 2 * wordSize)) {
1665     st->print("ldp  lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize);
1666     st->print("add  sp, sp, #%d\n\t", framesize);
1667   } else {
1668     st->print("mov  rscratch1, #%d\n\t", framesize - 2 * wordSize);
1669     st->print("add  sp, sp, rscratch1\n\t");
1670     st->print("ldp  lr, rfp, [sp],#%d\n\t", (2 * wordSize));
1671   }
1672 
1673   if (do_polling() && C->is_method_compilation()) {
1674     st->print("# touch polling page\n\t");
1675     st->print("mov  rscratch1, #0x%lx\n\t", p2i(os::get_polling_page()));
1676     st->print("ldr zr, [rscratch1]");
1677   }
1678 }
1679 #endif
1680 
1681 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1682   Compile* C = ra_->C;
1683   MacroAssembler _masm(&cbuf);
1684   int framesize = C->frame_slots() << LogBytesPerInt;
1685 
1686   __ remove_frame(framesize);
1687 
1688   if (NotifySimulator) {
1689     __ notify(Assembler::method_reentry);
1690   }
1691 
1692   if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
1693     __ reserved_stack_check();
1694   }
1695 
1696   if (do_polling() && C->is_method_compilation()) {
1697     __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type);
1698   }
1699 }
1700 
1701 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
1702   // Variable size. Determine dynamically.
1703   return MachNode::size(ra_);
1704 }
1705 
1706 int MachEpilogNode::reloc() const {
1707   // Return number of relocatable values contained in this instruction.
1708   return 1; // 1 for polling page.
1709 }
1710 
1711 const Pipeline * MachEpilogNode::pipeline() const {
1712   return MachNode::pipeline_class();
1713 }
1714 
1715 // This method seems to be obsolete. It is declared in machnode.hpp
1716 // and defined in all *.ad files, but it is never called. Should we
1717 // get rid of it?
1718 int MachEpilogNode::safepoint_offset() const {
1719   assert(do_polling(), "no return for this epilog node");
1720   return 4;
1721 }
1722 
1723 //=============================================================================
1724 
1725 // Figure out which register class each belongs in: rc_int, rc_float or
1726 // rc_stack.
1727 enum RC { rc_bad, rc_int, rc_float, rc_stack };
1728 
1729 static enum RC rc_class(OptoReg::Name reg) {
1730 
1731   if (reg == OptoReg::Bad) {
1732     return rc_bad;
1733   }
1734 
1735   // we have 30 int registers * 2 halves
1736   // (rscratch1 and rscratch2 are omitted)
1737 
1738   if (reg < 60) {
1739     return rc_int;
1740   }
1741 
1742   // we have 32 float register * 2 halves
1743   if (reg < 60 + 128) {
1744     return rc_float;
1745   }
1746 
1747   // Between float regs & stack is the flags regs.
1748   assert(OptoReg::is_stack(reg), "blow up if spilling flags");
1749 
1750   return rc_stack;
1751 }
1752 
1753 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const {
1754   Compile* C = ra_->C;
1755 
1756   // Get registers to move.
1757   OptoReg::Name src_hi = ra_->get_reg_second(in(1));
1758   OptoReg::Name src_lo = ra_->get_reg_first(in(1));
1759   OptoReg::Name dst_hi = ra_->get_reg_second(this);
1760   OptoReg::Name dst_lo = ra_->get_reg_first(this);
1761 
1762   enum RC src_hi_rc = rc_class(src_hi);
1763   enum RC src_lo_rc = rc_class(src_lo);
1764   enum RC dst_hi_rc = rc_class(dst_hi);
1765   enum RC dst_lo_rc = rc_class(dst_lo);
1766 
1767   assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register");
1768 
1769   if (src_hi != OptoReg::Bad) {
1770     assert((src_lo&1)==0 && src_lo+1==src_hi &&
1771            (dst_lo&1)==0 && dst_lo+1==dst_hi,
1772            "expected aligned-adjacent pairs");
1773   }
1774 
1775   if (src_lo == dst_lo && src_hi == dst_hi) {
1776     return 0;            // Self copy, no move.
1777   }
1778 
1779   bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi &&
1780               (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi;
1781   int src_offset = ra_->reg2offset(src_lo);
1782   int dst_offset = ra_->reg2offset(dst_lo);
1783 
1784   if (bottom_type()->isa_vect() != NULL) {
1785     uint ireg = ideal_reg();
1786     assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector");
1787     if (cbuf) {
1788       MacroAssembler _masm(cbuf);
1789       assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity");
1790       if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1791         // stack->stack
1792         assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset");
1793         if (ireg == Op_VecD) {
1794           __ unspill(rscratch1, true, src_offset);
1795           __ spill(rscratch1, true, dst_offset);
1796         } else {
1797           __ spill_copy128(src_offset, dst_offset);
1798         }
1799       } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
1800         __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1801                ireg == Op_VecD ? __ T8B : __ T16B,
1802                as_FloatRegister(Matcher::_regEncode[src_lo]));
1803       } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
1804         __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]),
1805                        ireg == Op_VecD ? __ D : __ Q,
1806                        ra_->reg2offset(dst_lo));
1807       } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) {
1808         __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1809                        ireg == Op_VecD ? __ D : __ Q,
1810                        ra_->reg2offset(src_lo));
1811       } else {
1812         ShouldNotReachHere();
1813       }
1814     }
1815   } else if (cbuf) {
1816     MacroAssembler _masm(cbuf);
1817     switch (src_lo_rc) {
1818     case rc_int:
1819       if (dst_lo_rc == rc_int) {  // gpr --> gpr copy
1820         if (is64) {
1821             __ mov(as_Register(Matcher::_regEncode[dst_lo]),
1822                    as_Register(Matcher::_regEncode[src_lo]));
1823         } else {
1824             MacroAssembler _masm(cbuf);
1825             __ movw(as_Register(Matcher::_regEncode[dst_lo]),
1826                     as_Register(Matcher::_regEncode[src_lo]));
1827         }
1828       } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy
1829         if (is64) {
1830             __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1831                      as_Register(Matcher::_regEncode[src_lo]));
1832         } else {
1833             __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1834                      as_Register(Matcher::_regEncode[src_lo]));
1835         }
1836       } else {                    // gpr --> stack spill
1837         assert(dst_lo_rc == rc_stack, "spill to bad register class");
1838         __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset);
1839       }
1840       break;
1841     case rc_float:
1842       if (dst_lo_rc == rc_int) {  // fpr --> gpr copy
1843         if (is64) {
1844             __ fmovd(as_Register(Matcher::_regEncode[dst_lo]),
1845                      as_FloatRegister(Matcher::_regEncode[src_lo]));
1846         } else {
1847             __ fmovs(as_Register(Matcher::_regEncode[dst_lo]),
1848                      as_FloatRegister(Matcher::_regEncode[src_lo]));
1849         }
1850       } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy
1851           if (cbuf) {
1852             __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1853                      as_FloatRegister(Matcher::_regEncode[src_lo]));
1854         } else {
1855             __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1856                      as_FloatRegister(Matcher::_regEncode[src_lo]));
1857         }
1858       } else {                    // fpr --> stack spill
1859         assert(dst_lo_rc == rc_stack, "spill to bad register class");
1860         __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]),
1861                  is64 ? __ D : __ S, dst_offset);
1862       }
1863       break;
1864     case rc_stack:
1865       if (dst_lo_rc == rc_int) {  // stack --> gpr load
1866         __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset);
1867       } else if (dst_lo_rc == rc_float) { // stack --> fpr load
1868         __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1869                    is64 ? __ D : __ S, src_offset);
1870       } else {                    // stack --> stack copy
1871         assert(dst_lo_rc == rc_stack, "spill to bad register class");
1872         __ unspill(rscratch1, is64, src_offset);
1873         __ spill(rscratch1, is64, dst_offset);
1874       }
1875       break;
1876     default:
1877       assert(false, "bad rc_class for spill");
1878       ShouldNotReachHere();
1879     }
1880   }
1881 
1882   if (st) {
1883     st->print("spill ");
1884     if (src_lo_rc == rc_stack) {
1885       st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo));
1886     } else {
1887       st->print("%s -> ", Matcher::regName[src_lo]);
1888     }
1889     if (dst_lo_rc == rc_stack) {
1890       st->print("[sp, #%d]", ra_->reg2offset(dst_lo));
1891     } else {
1892       st->print("%s", Matcher::regName[dst_lo]);
1893     }
1894     if (bottom_type()->isa_vect() != NULL) {
1895       st->print("\t# vector spill size = %d", ideal_reg()==Op_VecD ? 64:128);
1896     } else {
1897       st->print("\t# spill size = %d", is64 ? 64:32);
1898     }
1899   }
1900 
1901   return 0;
1902 
1903 }
1904 
1905 #ifndef PRODUCT
1906 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1907   if (!ra_)
1908     st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
1909   else
1910     implementation(NULL, ra_, false, st);
1911 }
1912 #endif
1913 
1914 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1915   implementation(&cbuf, ra_, false, NULL);
1916 }
1917 
1918 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1919   return MachNode::size(ra_);
1920 }
1921 
1922 //=============================================================================
1923 
1924 #ifndef PRODUCT
1925 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1926   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1927   int reg = ra_->get_reg_first(this);
1928   st->print("add %s, rsp, #%d]\t# box lock",
1929             Matcher::regName[reg], offset);
1930 }
1931 #endif
1932 
1933 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1934   MacroAssembler _masm(&cbuf);
1935 
1936   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1937   int reg    = ra_->get_encode(this);
1938 
1939   if (Assembler::operand_valid_for_add_sub_immediate(offset)) {
1940     __ add(as_Register(reg), sp, offset);
1941   } else {
1942     ShouldNotReachHere();
1943   }
1944 }
1945 
1946 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
1947   // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
1948   return 4;
1949 }
1950 
1951 //=============================================================================
1952 
1953 #ifndef PRODUCT
1954 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1955 {
1956   st->print_cr("# MachUEPNode");
1957   if (UseCompressedClassPointers) {
1958     st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1959     if (Universe::narrow_klass_shift() != 0) {
1960       st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
1961     }
1962   } else {
1963    st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1964   }
1965   st->print_cr("\tcmp r0, rscratch1\t # Inline cache check");
1966   st->print_cr("\tbne, SharedRuntime::_ic_miss_stub");
1967 }
1968 #endif
1969 
1970 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1971 {
1972   // This is the unverified entry point.
1973   MacroAssembler _masm(&cbuf);
1974 
1975   __ cmp_klass(j_rarg0, rscratch2, rscratch1);
1976   Label skip;
1977   // TODO
1978   // can we avoid this skip and still use a reloc?
1979   __ br(Assembler::EQ, skip);
1980   __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
1981   __ bind(skip);
1982 }
1983 
1984 uint MachUEPNode::size(PhaseRegAlloc* ra_) const
1985 {
1986   return MachNode::size(ra_);
1987 }
1988 
1989 // REQUIRED EMIT CODE
1990 
1991 //=============================================================================
1992 
1993 // Emit exception handler code.
1994 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf)
1995 {
1996   // mov rscratch1 #exception_blob_entry_point
1997   // br rscratch1
1998   // Note that the code buffer's insts_mark is always relative to insts.
1999   // That's why we must use the macroassembler to generate a handler.
2000   MacroAssembler _masm(&cbuf);
2001   address base = __ start_a_stub(size_exception_handler());
2002   if (base == NULL) {
2003     ciEnv::current()->record_failure("CodeCache is full");
2004     return 0;  // CodeBuffer::expand failed
2005   }
2006   int offset = __ offset();
2007   __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point()));
2008   assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
2009   __ end_a_stub();
2010   return offset;
2011 }
2012 
2013 // Emit deopt handler code.
2014 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf)
2015 {
2016   // Note that the code buffer's insts_mark is always relative to insts.
2017   // That's why we must use the macroassembler to generate a handler.
2018   MacroAssembler _masm(&cbuf);
2019   address base = __ start_a_stub(size_deopt_handler());
2020   if (base == NULL) {
2021     ciEnv::current()->record_failure("CodeCache is full");
2022     return 0;  // CodeBuffer::expand failed
2023   }
2024   int offset = __ offset();
2025 
2026   __ adr(lr, __ pc());
2027   __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
2028 
2029   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
2030   __ end_a_stub();
2031   return offset;
2032 }
2033 
2034 // REQUIRED MATCHER CODE
2035 
2036 //=============================================================================
2037 
2038 const bool Matcher::match_rule_supported(int opcode) {
2039 
2040   switch (opcode) {
2041   default:
2042     break;
2043   }
2044 
2045   if (!has_match_rule(opcode)) {
2046     return false;
2047   }
2048 
2049   return true;  // Per default match rules are supported.
2050 }
2051 
2052 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) {
2053 
2054   // TODO
2055   // identify extra cases that we might want to provide match rules for
2056   // e.g. Op_ vector nodes and other intrinsics while guarding with vlen
2057   bool ret_value = match_rule_supported(opcode);
2058   // Add rules here.
2059 
2060   return ret_value;  // Per default match rules are supported.
2061 }
2062 
2063 const bool Matcher::has_predicated_vectors(void) {
2064   return false;
2065 }
2066 
2067 const int Matcher::float_pressure(int default_pressure_threshold) {
2068   return default_pressure_threshold;
2069 }
2070 
2071 int Matcher::regnum_to_fpu_offset(int regnum)
2072 {
2073   Unimplemented();
2074   return 0;
2075 }
2076 
2077 // Is this branch offset short enough that a short branch can be used?
2078 //
2079 // NOTE: If the platform does not provide any short branch variants, then
2080 //       this method should return false for offset 0.
2081 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2082   // The passed offset is relative to address of the branch.
2083 
2084   return (-32768 <= offset && offset < 32768);
2085 }
2086 
2087 const bool Matcher::isSimpleConstant64(jlong value) {
2088   // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
2089   // Probably always true, even if a temp register is required.
2090   return true;
2091 }
2092 
2093 // true just means we have fast l2f conversion
2094 const bool Matcher::convL2FSupported(void) {
2095   return true;
2096 }
2097 
2098 // Vector width in bytes.
2099 const int Matcher::vector_width_in_bytes(BasicType bt) {
2100   int size = MIN2(16,(int)MaxVectorSize);
2101   // Minimum 2 values in vector
2102   if (size < 2*type2aelembytes(bt)) size = 0;
2103   // But never < 4
2104   if (size < 4) size = 0;
2105   return size;
2106 }
2107 
2108 // Limits on vector size (number of elements) loaded into vector.
2109 const int Matcher::max_vector_size(const BasicType bt) {
2110   return vector_width_in_bytes(bt)/type2aelembytes(bt);
2111 }
2112 const int Matcher::min_vector_size(const BasicType bt) {
2113 //  For the moment limit the vector size to 8 bytes
2114     int size = 8 / type2aelembytes(bt);
2115     if (size < 2) size = 2;
2116     return size;
2117 }
2118 
2119 // Vector ideal reg.
2120 const uint Matcher::vector_ideal_reg(int len) {
2121   switch(len) {
2122     case  8: return Op_VecD;
2123     case 16: return Op_VecX;
2124   }
2125   ShouldNotReachHere();
2126   return 0;
2127 }
2128 
2129 const uint Matcher::vector_shift_count_ideal_reg(int size) {
2130   return Op_VecX;
2131 }
2132 
2133 // AES support not yet implemented
2134 const bool Matcher::pass_original_key_for_aes() {
2135   return false;
2136 }
2137 
2138 // x86 supports misaligned vectors store/load.
2139 const bool Matcher::misaligned_vectors_ok() {
2140   return !AlignVector; // can be changed by flag
2141 }
2142 
2143 // false => size gets scaled to BytesPerLong, ok.
2144 const bool Matcher::init_array_count_is_in_bytes = false;
2145 
2146 // Use conditional move (CMOVL)
2147 const int Matcher::long_cmove_cost() {
2148   // long cmoves are no more expensive than int cmoves
2149   return 0;
2150 }
2151 
2152 const int Matcher::float_cmove_cost() {
2153   // float cmoves are no more expensive than int cmoves
2154   return 0;
2155 }
2156 
2157 // Does the CPU require late expand (see block.cpp for description of late expand)?
2158 const bool Matcher::require_postalloc_expand = false;
2159 
2160 // Do we need to mask the count passed to shift instructions or does
2161 // the cpu only look at the lower 5/6 bits anyway?
2162 const bool Matcher::need_masked_shift_count = false;
2163 
2164 // This affects two different things:
2165 //  - how Decode nodes are matched
2166 //  - how ImplicitNullCheck opportunities are recognized
2167 // If true, the matcher will try to remove all Decodes and match them
2168 // (as operands) into nodes. NullChecks are not prepared to deal with
2169 // Decodes by final_graph_reshaping().
2170 // If false, final_graph_reshaping() forces the decode behind the Cmp
2171 // for a NullCheck. The matcher matches the Decode node into a register.
2172 // Implicit_null_check optimization moves the Decode along with the
2173 // memory operation back up before the NullCheck.
2174 bool Matcher::narrow_oop_use_complex_address() {
2175   return Universe::narrow_oop_shift() == 0;
2176 }
2177 
2178 bool Matcher::narrow_klass_use_complex_address() {
2179 // TODO
2180 // decide whether we need to set this to true
2181   return false;
2182 }
2183 
2184 bool Matcher::const_oop_prefer_decode() {
2185   // Prefer ConN+DecodeN over ConP in simple compressed oops mode.
2186   return Universe::narrow_oop_base() == NULL;
2187 }
2188 
2189 bool Matcher::const_klass_prefer_decode() {
2190   // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode.
2191   return Universe::narrow_klass_base() == NULL;
2192 }
2193 
2194 // Is it better to copy float constants, or load them directly from
2195 // memory?  Intel can load a float constant from a direct address,
2196 // requiring no extra registers.  Most RISCs will have to materialize
2197 // an address into a register first, so they would do better to copy
2198 // the constant from stack.
2199 const bool Matcher::rematerialize_float_constants = false;
2200 
2201 // If CPU can load and store mis-aligned doubles directly then no
2202 // fixup is needed.  Else we split the double into 2 integer pieces
2203 // and move it piece-by-piece.  Only happens when passing doubles into
2204 // C code as the Java calling convention forces doubles to be aligned.
2205 const bool Matcher::misaligned_doubles_ok = true;
2206 
2207 // No-op on amd64
2208 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {
2209   Unimplemented();
2210 }
2211 
2212 // Advertise here if the CPU requires explicit rounding operations to
2213 // implement the UseStrictFP mode.
2214 const bool Matcher::strict_fp_requires_explicit_rounding = false;
2215 
2216 // Are floats converted to double when stored to stack during
2217 // deoptimization?
2218 bool Matcher::float_in_double() { return false; }
2219 
2220 // Do ints take an entire long register or just half?
2221 // The relevant question is how the int is callee-saved:
2222 // the whole long is written but de-opt'ing will have to extract
2223 // the relevant 32 bits.
2224 const bool Matcher::int_in_long = true;
2225 
2226 // Return whether or not this register is ever used as an argument.
2227 // This function is used on startup to build the trampoline stubs in
2228 // generateOptoStub.  Registers not mentioned will be killed by the VM
2229 // call in the trampoline, and arguments in those registers not be
2230 // available to the callee.
2231 bool Matcher::can_be_java_arg(int reg)
2232 {
2233   return
2234     reg ==  R0_num || reg == R0_H_num ||
2235     reg ==  R1_num || reg == R1_H_num ||
2236     reg ==  R2_num || reg == R2_H_num ||
2237     reg ==  R3_num || reg == R3_H_num ||
2238     reg ==  R4_num || reg == R4_H_num ||
2239     reg ==  R5_num || reg == R5_H_num ||
2240     reg ==  R6_num || reg == R6_H_num ||
2241     reg ==  R7_num || reg == R7_H_num ||
2242     reg ==  V0_num || reg == V0_H_num ||
2243     reg ==  V1_num || reg == V1_H_num ||
2244     reg ==  V2_num || reg == V2_H_num ||
2245     reg ==  V3_num || reg == V3_H_num ||
2246     reg ==  V4_num || reg == V4_H_num ||
2247     reg ==  V5_num || reg == V5_H_num ||
2248     reg ==  V6_num || reg == V6_H_num ||
2249     reg ==  V7_num || reg == V7_H_num;
2250 }
2251 
2252 bool Matcher::is_spillable_arg(int reg)
2253 {
2254   return can_be_java_arg(reg);
2255 }
2256 
2257 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) {
2258   return false;
2259 }
2260 
2261 RegMask Matcher::divI_proj_mask() {
2262   ShouldNotReachHere();
2263   return RegMask();
2264 }
2265 
2266 // Register for MODI projection of divmodI.
2267 RegMask Matcher::modI_proj_mask() {
2268   ShouldNotReachHere();
2269   return RegMask();
2270 }
2271 
2272 // Register for DIVL projection of divmodL.
2273 RegMask Matcher::divL_proj_mask() {
2274   ShouldNotReachHere();
2275   return RegMask();
2276 }
2277 
2278 // Register for MODL projection of divmodL.
2279 RegMask Matcher::modL_proj_mask() {
2280   ShouldNotReachHere();
2281   return RegMask();
2282 }
2283 
2284 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
2285   return FP_REG_mask();
2286 }
2287 
2288 bool size_fits_all_mem_uses(AddPNode* addp, int shift) {
2289   for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) {
2290     Node* u = addp->fast_out(i);
2291     if (u->is_Mem()) {
2292       int opsize = u->as_Mem()->memory_size();
2293       assert(opsize > 0, "unexpected memory operand size");
2294       if (u->as_Mem()->memory_size() != (1<<shift)) {
2295         return false;
2296       }
2297     }
2298   }
2299   return true;
2300 }
2301 
2302 const bool Matcher::convi2l_type_required = false;
2303 
2304 // Should the Matcher clone shifts on addressing modes, expecting them
2305 // to be subsumed into complex addressing expressions or compute them
2306 // into registers?
2307 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
2308   if (clone_base_plus_offset_address(m, mstack, address_visited)) {
2309     return true;
2310   }
2311 
2312   Node *off = m->in(AddPNode::Offset);
2313   if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() &&
2314       size_fits_all_mem_uses(m, off->in(2)->get_int()) &&
2315       // Are there other uses besides address expressions?
2316       !is_visited(off)) {
2317     address_visited.set(off->_idx); // Flag as address_visited
2318     mstack.push(off->in(2), Visit);
2319     Node *conv = off->in(1);
2320     if (conv->Opcode() == Op_ConvI2L &&
2321         // Are there other uses besides address expressions?
2322         !is_visited(conv)) {
2323       address_visited.set(conv->_idx); // Flag as address_visited
2324       mstack.push(conv->in(1), Pre_Visit);
2325     } else {
2326       mstack.push(conv, Pre_Visit);
2327     }
2328     address_visited.test_set(m->_idx); // Flag as address_visited
2329     mstack.push(m->in(AddPNode::Address), Pre_Visit);
2330     mstack.push(m->in(AddPNode::Base), Pre_Visit);
2331     return true;
2332   } else if (off->Opcode() == Op_ConvI2L &&
2333              // Are there other uses besides address expressions?
2334              !is_visited(off)) {
2335     address_visited.test_set(m->_idx); // Flag as address_visited
2336     address_visited.set(off->_idx); // Flag as address_visited
2337     mstack.push(off->in(1), Pre_Visit);
2338     mstack.push(m->in(AddPNode::Address), Pre_Visit);
2339     mstack.push(m->in(AddPNode::Base), Pre_Visit);
2340     return true;
2341   }
2342   return false;
2343 }
2344 
2345 void Compile::reshape_address(AddPNode* addp) {
2346 }
2347 
2348 // helper for encoding java_to_runtime calls on sim
2349 //
2350 // this is needed to compute the extra arguments required when
2351 // planting a call to the simulator blrt instruction. the TypeFunc
2352 // can be queried to identify the counts for integral, and floating
2353 // arguments and the return type
2354 
2355 static void getCallInfo(const TypeFunc *tf, int &gpcnt, int &fpcnt, int &rtype)
2356 {
2357   int gps = 0;
2358   int fps = 0;
2359   const TypeTuple *domain = tf->domain();
2360   int max = domain->cnt();
2361   for (int i = TypeFunc::Parms; i < max; i++) {
2362     const Type *t = domain->field_at(i);
2363     switch(t->basic_type()) {
2364     case T_FLOAT:
2365     case T_DOUBLE:
2366       fps++;
2367     default:
2368       gps++;
2369     }
2370   }
2371   gpcnt = gps;
2372   fpcnt = fps;
2373   BasicType rt = tf->return_type();
2374   switch (rt) {
2375   case T_VOID:
2376     rtype = MacroAssembler::ret_type_void;
2377     break;
2378   default:
2379     rtype = MacroAssembler::ret_type_integral;
2380     break;
2381   case T_FLOAT:
2382     rtype = MacroAssembler::ret_type_float;
2383     break;
2384   case T_DOUBLE:
2385     rtype = MacroAssembler::ret_type_double;
2386     break;
2387   }
2388 }
2389 
2390 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN)      \
2391   MacroAssembler _masm(&cbuf);                                          \
2392   {                                                                     \
2393     guarantee(INDEX == -1, "mode not permitted for volatile");          \
2394     guarantee(DISP == 0, "mode not permitted for volatile");            \
2395     guarantee(SCALE == 0, "mode not permitted for volatile");           \
2396     __ INSN(REG, as_Register(BASE));                                    \
2397   }
2398 
2399 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr);
2400 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr);
2401 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt,
2402                                   MacroAssembler::SIMD_RegVariant T, const Address &adr);
2403 
2404   // Used for all non-volatile memory accesses.  The use of
2405   // $mem->opcode() to discover whether this pattern uses sign-extended
2406   // offsets is something of a kludge.
2407   static void loadStore(MacroAssembler masm, mem_insn insn,
2408                          Register reg, int opcode,
2409                          Register base, int index, int size, int disp)
2410   {
2411     Address::extend scale;
2412 
2413     // Hooboy, this is fugly.  We need a way to communicate to the
2414     // encoder that the index needs to be sign extended, so we have to
2415     // enumerate all the cases.
2416     switch (opcode) {
2417     case INDINDEXSCALEDI2L:
2418     case INDINDEXSCALEDI2LN:
2419     case INDINDEXI2L:
2420     case INDINDEXI2LN:
2421       scale = Address::sxtw(size);
2422       break;
2423     default:
2424       scale = Address::lsl(size);
2425     }
2426 
2427     if (index == -1) {
2428       (masm.*insn)(reg, Address(base, disp));
2429     } else {
2430       assert(disp == 0, "unsupported address mode: disp = %d", disp);
2431       (masm.*insn)(reg, Address(base, as_Register(index), scale));
2432     }
2433   }
2434 
2435   static void loadStore(MacroAssembler masm, mem_float_insn insn,
2436                          FloatRegister reg, int opcode,
2437                          Register base, int index, int size, int disp)
2438   {
2439     Address::extend scale;
2440 
2441     switch (opcode) {
2442     case INDINDEXSCALEDI2L:
2443     case INDINDEXSCALEDI2LN:
2444       scale = Address::sxtw(size);
2445       break;
2446     default:
2447       scale = Address::lsl(size);
2448     }
2449 
2450      if (index == -1) {
2451       (masm.*insn)(reg, Address(base, disp));
2452     } else {
2453       assert(disp == 0, "unsupported address mode: disp = %d", disp);
2454       (masm.*insn)(reg, Address(base, as_Register(index), scale));
2455     }
2456   }
2457 
2458   static void loadStore(MacroAssembler masm, mem_vector_insn insn,
2459                          FloatRegister reg, MacroAssembler::SIMD_RegVariant T,
2460                          int opcode, Register base, int index, int size, int disp)
2461   {
2462     if (index == -1) {
2463       (masm.*insn)(reg, T, Address(base, disp));
2464     } else {
2465       assert(disp == 0, "unsupported address mode");
2466       (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size)));
2467     }
2468   }
2469 
2470 %}
2471 
2472 
2473 
2474 //----------ENCODING BLOCK-----------------------------------------------------
2475 // This block specifies the encoding classes used by the compiler to
2476 // output byte streams.  Encoding classes are parameterized macros
2477 // used by Machine Instruction Nodes in order to generate the bit
2478 // encoding of the instruction.  Operands specify their base encoding
2479 // interface with the interface keyword.  There are currently
2480 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
2481 // COND_INTER.  REG_INTER causes an operand to generate a function
2482 // which returns its register number when queried.  CONST_INTER causes
2483 // an operand to generate a function which returns the value of the
2484 // constant when queried.  MEMORY_INTER causes an operand to generate
2485 // four functions which return the Base Register, the Index Register,
2486 // the Scale Value, and the Offset Value of the operand when queried.
2487 // COND_INTER causes an operand to generate six functions which return
2488 // the encoding code (ie - encoding bits for the instruction)
2489 // associated with each basic boolean condition for a conditional
2490 // instruction.
2491 //
2492 // Instructions specify two basic values for encoding.  Again, a
2493 // function is available to check if the constant displacement is an
2494 // oop. They use the ins_encode keyword to specify their encoding
2495 // classes (which must be a sequence of enc_class names, and their
2496 // parameters, specified in the encoding block), and they use the
2497 // opcode keyword to specify, in order, their primary, secondary, and
2498 // tertiary opcode.  Only the opcode sections which a particular
2499 // instruction needs for encoding need to be specified.
2500 encode %{
2501   // Build emit functions for each basic byte or larger field in the
2502   // intel encoding scheme (opcode, rm, sib, immediate), and call them
2503   // from C++ code in the enc_class source block.  Emit functions will
2504   // live in the main source block for now.  In future, we can
2505   // generalize this by adding a syntax that specifies the sizes of
2506   // fields in an order, so that the adlc can build the emit functions
2507   // automagically
2508 
2509   // catch all for unimplemented encodings
2510   enc_class enc_unimplemented %{
2511     MacroAssembler _masm(&cbuf);
2512     __ unimplemented("C2 catch all");
2513   %}
2514 
2515   // BEGIN Non-volatile memory access
2516 
2517   enc_class aarch64_enc_ldrsbw(iRegI dst, memory mem) %{
2518     Register dst_reg = as_Register($dst$$reg);
2519     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(),
2520                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2521   %}
2522 
2523   enc_class aarch64_enc_ldrsb(iRegI dst, memory mem) %{
2524     Register dst_reg = as_Register($dst$$reg);
2525     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(),
2526                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2527   %}
2528 
2529   enc_class aarch64_enc_ldrb(iRegI dst, memory mem) %{
2530     Register dst_reg = as_Register($dst$$reg);
2531     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(),
2532                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2533   %}
2534 
2535   enc_class aarch64_enc_ldrb(iRegL dst, memory mem) %{
2536     Register dst_reg = as_Register($dst$$reg);
2537     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(),
2538                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2539   %}
2540 
2541   enc_class aarch64_enc_ldrshw(iRegI dst, memory mem) %{
2542     Register dst_reg = as_Register($dst$$reg);
2543     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(),
2544                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2545   %}
2546 
2547   enc_class aarch64_enc_ldrsh(iRegI dst, memory mem) %{
2548     Register dst_reg = as_Register($dst$$reg);
2549     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(),
2550                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2551   %}
2552 
2553   enc_class aarch64_enc_ldrh(iRegI dst, memory mem) %{
2554     Register dst_reg = as_Register($dst$$reg);
2555     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(),
2556                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2557   %}
2558 
2559   enc_class aarch64_enc_ldrh(iRegL dst, memory mem) %{
2560     Register dst_reg = as_Register($dst$$reg);
2561     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(),
2562                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2563   %}
2564 
2565   enc_class aarch64_enc_ldrw(iRegI dst, memory mem) %{
2566     Register dst_reg = as_Register($dst$$reg);
2567     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(),
2568                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2569   %}
2570 
2571   enc_class aarch64_enc_ldrw(iRegL dst, memory mem) %{
2572     Register dst_reg = as_Register($dst$$reg);
2573     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(),
2574                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2575   %}
2576 
2577   enc_class aarch64_enc_ldrsw(iRegL dst, memory mem) %{
2578     Register dst_reg = as_Register($dst$$reg);
2579     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(),
2580                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2581   %}
2582 
2583   enc_class aarch64_enc_ldr(iRegL dst, memory mem) %{
2584     Register dst_reg = as_Register($dst$$reg);
2585     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(),
2586                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2587   %}
2588 
2589   enc_class aarch64_enc_ldrs(vRegF dst, memory mem) %{
2590     FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2591     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(),
2592                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2593   %}
2594 
2595   enc_class aarch64_enc_ldrd(vRegD dst, memory mem) %{
2596     FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2597     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(),
2598                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2599   %}
2600 
2601   enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{
2602     FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2603     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S,
2604        $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2605   %}
2606 
2607   enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{
2608     FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2609     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D,
2610        $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2611   %}
2612 
2613   enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{
2614     FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2615     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q,
2616        $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2617   %}
2618 
2619   enc_class aarch64_enc_strb(iRegI src, memory mem) %{
2620     Register src_reg = as_Register($src$$reg);
2621     loadStore(MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(),
2622                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2623   %}
2624 
2625   enc_class aarch64_enc_strb0(memory mem) %{
2626     MacroAssembler _masm(&cbuf);
2627     loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(),
2628                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2629   %}
2630 
2631   enc_class aarch64_enc_strb0_ordered(memory mem) %{
2632     MacroAssembler _masm(&cbuf);
2633     __ membar(Assembler::StoreStore);
2634     loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(),
2635                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2636   %}
2637 
2638   enc_class aarch64_enc_strh(iRegI src, memory mem) %{
2639     Register src_reg = as_Register($src$$reg);
2640     loadStore(MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(),
2641                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2642   %}
2643 
2644   enc_class aarch64_enc_strh0(memory mem) %{
2645     MacroAssembler _masm(&cbuf);
2646     loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(),
2647                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2648   %}
2649 
2650   enc_class aarch64_enc_strw(iRegI src, memory mem) %{
2651     Register src_reg = as_Register($src$$reg);
2652     loadStore(MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(),
2653                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2654   %}
2655 
2656   enc_class aarch64_enc_strw0(memory mem) %{
2657     MacroAssembler _masm(&cbuf);
2658     loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(),
2659                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2660   %}
2661 
2662   enc_class aarch64_enc_str(iRegL src, memory mem) %{
2663     Register src_reg = as_Register($src$$reg);
2664     // we sometimes get asked to store the stack pointer into the
2665     // current thread -- we cannot do that directly on AArch64
2666     if (src_reg == r31_sp) {
2667       MacroAssembler _masm(&cbuf);
2668       assert(as_Register($mem$$base) == rthread, "unexpected store for sp");
2669       __ mov(rscratch2, sp);
2670       src_reg = rscratch2;
2671     }
2672     loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(),
2673                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2674   %}
2675 
2676   enc_class aarch64_enc_str0(memory mem) %{
2677     MacroAssembler _masm(&cbuf);
2678     loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(),
2679                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2680   %}
2681 
2682   enc_class aarch64_enc_strs(vRegF src, memory mem) %{
2683     FloatRegister src_reg = as_FloatRegister($src$$reg);
2684     loadStore(MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(),
2685                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2686   %}
2687 
2688   enc_class aarch64_enc_strd(vRegD src, memory mem) %{
2689     FloatRegister src_reg = as_FloatRegister($src$$reg);
2690     loadStore(MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(),
2691                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2692   %}
2693 
2694   enc_class aarch64_enc_strvS(vecD src, memory mem) %{
2695     FloatRegister src_reg = as_FloatRegister($src$$reg);
2696     loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S,
2697        $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2698   %}
2699 
2700   enc_class aarch64_enc_strvD(vecD src, memory mem) %{
2701     FloatRegister src_reg = as_FloatRegister($src$$reg);
2702     loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D,
2703        $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2704   %}
2705 
2706   enc_class aarch64_enc_strvQ(vecX src, memory mem) %{
2707     FloatRegister src_reg = as_FloatRegister($src$$reg);
2708     loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q,
2709        $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
2710   %}
2711 
2712   // END Non-volatile memory access
2713 
2714   // volatile loads and stores
2715 
2716   enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{
2717     MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2718                  rscratch1, stlrb);
2719   %}
2720 
2721   enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{
2722     MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2723                  rscratch1, stlrh);
2724   %}
2725 
2726   enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{
2727     MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2728                  rscratch1, stlrw);
2729   %}
2730 
2731 
2732   enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{
2733     Register dst_reg = as_Register($dst$$reg);
2734     MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2735              rscratch1, ldarb);
2736     __ sxtbw(dst_reg, dst_reg);
2737   %}
2738 
2739   enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{
2740     Register dst_reg = as_Register($dst$$reg);
2741     MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2742              rscratch1, ldarb);
2743     __ sxtb(dst_reg, dst_reg);
2744   %}
2745 
2746   enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{
2747     MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2748              rscratch1, ldarb);
2749   %}
2750 
2751   enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{
2752     MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2753              rscratch1, ldarb);
2754   %}
2755 
2756   enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{
2757     Register dst_reg = as_Register($dst$$reg);
2758     MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2759              rscratch1, ldarh);
2760     __ sxthw(dst_reg, dst_reg);
2761   %}
2762 
2763   enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{
2764     Register dst_reg = as_Register($dst$$reg);
2765     MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2766              rscratch1, ldarh);
2767     __ sxth(dst_reg, dst_reg);
2768   %}
2769 
2770   enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{
2771     MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2772              rscratch1, ldarh);
2773   %}
2774 
2775   enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{
2776     MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2777              rscratch1, ldarh);
2778   %}
2779 
2780   enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{
2781     MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2782              rscratch1, ldarw);
2783   %}
2784 
2785   enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{
2786     MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2787              rscratch1, ldarw);
2788   %}
2789 
2790   enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{
2791     MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2792              rscratch1, ldar);
2793   %}
2794 
2795   enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{
2796     MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2797              rscratch1, ldarw);
2798     __ fmovs(as_FloatRegister($dst$$reg), rscratch1);
2799   %}
2800 
2801   enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{
2802     MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2803              rscratch1, ldar);
2804     __ fmovd(as_FloatRegister($dst$$reg), rscratch1);
2805   %}
2806 
2807   enc_class aarch64_enc_stlr(iRegL src, memory mem) %{
2808     Register src_reg = as_Register($src$$reg);
2809     // we sometimes get asked to store the stack pointer into the
2810     // current thread -- we cannot do that directly on AArch64
2811     if (src_reg == r31_sp) {
2812         MacroAssembler _masm(&cbuf);
2813       assert(as_Register($mem$$base) == rthread, "unexpected store for sp");
2814       __ mov(rscratch2, sp);
2815       src_reg = rscratch2;
2816     }
2817     MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2818                  rscratch1, stlr);
2819   %}
2820 
2821   enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{
2822     {
2823       MacroAssembler _masm(&cbuf);
2824       FloatRegister src_reg = as_FloatRegister($src$$reg);
2825       __ fmovs(rscratch2, src_reg);
2826     }
2827     MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2828                  rscratch1, stlrw);
2829   %}
2830 
2831   enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{
2832     {
2833       MacroAssembler _masm(&cbuf);
2834       FloatRegister src_reg = as_FloatRegister($src$$reg);
2835       __ fmovd(rscratch2, src_reg);
2836     }
2837     MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
2838                  rscratch1, stlr);
2839   %}
2840 
2841   // synchronized read/update encodings
2842 
2843   enc_class aarch64_enc_ldaxr(iRegL dst, memory mem) %{
2844     MacroAssembler _masm(&cbuf);
2845     Register dst_reg = as_Register($dst$$reg);
2846     Register base = as_Register($mem$$base);
2847     int index = $mem$$index;
2848     int scale = $mem$$scale;
2849     int disp = $mem$$disp;
2850     if (index == -1) {
2851        if (disp != 0) {
2852         __ lea(rscratch1, Address(base, disp));
2853         __ ldaxr(dst_reg, rscratch1);
2854       } else {
2855         // TODO
2856         // should we ever get anything other than this case?
2857         __ ldaxr(dst_reg, base);
2858       }
2859     } else {
2860       Register index_reg = as_Register(index);
2861       if (disp == 0) {
2862         __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale)));
2863         __ ldaxr(dst_reg, rscratch1);
2864       } else {
2865         __ lea(rscratch1, Address(base, disp));
2866         __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale)));
2867         __ ldaxr(dst_reg, rscratch1);
2868       }
2869     }
2870   %}
2871 
2872   enc_class aarch64_enc_stlxr(iRegLNoSp src, memory mem) %{
2873     MacroAssembler _masm(&cbuf);
2874     Register src_reg = as_Register($src$$reg);
2875     Register base = as_Register($mem$$base);
2876     int index = $mem$$index;
2877     int scale = $mem$$scale;
2878     int disp = $mem$$disp;
2879     if (index == -1) {
2880        if (disp != 0) {
2881         __ lea(rscratch2, Address(base, disp));
2882         __ stlxr(rscratch1, src_reg, rscratch2);
2883       } else {
2884         // TODO
2885         // should we ever get anything other than this case?
2886         __ stlxr(rscratch1, src_reg, base);
2887       }
2888     } else {
2889       Register index_reg = as_Register(index);
2890       if (disp == 0) {
2891         __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale)));
2892         __ stlxr(rscratch1, src_reg, rscratch2);
2893       } else {
2894         __ lea(rscratch2, Address(base, disp));
2895         __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale)));
2896         __ stlxr(rscratch1, src_reg, rscratch2);
2897       }
2898     }
2899     __ cmpw(rscratch1, zr);
2900   %}
2901 
2902   enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
2903     MacroAssembler _masm(&cbuf);
2904     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2905     __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2906                Assembler::xword, /*acquire*/ false, /*release*/ true,
2907                /*weak*/ false, noreg);
2908   %}
2909 
2910   enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
2911     MacroAssembler _masm(&cbuf);
2912     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2913     __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2914                Assembler::word, /*acquire*/ false, /*release*/ true,
2915                /*weak*/ false, noreg);
2916   %}
2917 
2918   enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
2919     MacroAssembler _masm(&cbuf);
2920     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2921     __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2922                Assembler::halfword, /*acquire*/ false, /*release*/ true,
2923                /*weak*/ false, noreg);
2924   %}
2925 
2926   enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
2927     MacroAssembler _masm(&cbuf);
2928     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2929     __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2930                Assembler::byte, /*acquire*/ false, /*release*/ true,
2931                /*weak*/ false, noreg);
2932   %}
2933 
2934 
2935   // The only difference between aarch64_enc_cmpxchg and
2936   // aarch64_enc_cmpxchg_acq is that we use load-acquire in the
2937   // CompareAndSwap sequence to serve as a barrier on acquiring a
2938   // lock.
2939   enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
2940     MacroAssembler _masm(&cbuf);
2941     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2942     __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2943                Assembler::xword, /*acquire*/ true, /*release*/ true,
2944                /*weak*/ false, noreg);
2945   %}
2946 
2947   enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
2948     MacroAssembler _masm(&cbuf);
2949     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2950     __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2951                Assembler::word, /*acquire*/ true, /*release*/ true,
2952                /*weak*/ false, noreg);
2953   %}
2954 
2955   enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
2956     MacroAssembler _masm(&cbuf);
2957     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2958     __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2959                Assembler::halfword, /*acquire*/ true, /*release*/ true,
2960                /*weak*/ false, noreg);
2961   %}
2962 
2963   enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
2964     MacroAssembler _masm(&cbuf);
2965     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2966     __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2967                Assembler::byte, /*acquire*/ true, /*release*/ true,
2968                /*weak*/ false, noreg);
2969   %}
2970 
2971   // auxiliary used for CompareAndSwapX to set result register
2972   enc_class aarch64_enc_cset_eq(iRegINoSp res) %{
2973     MacroAssembler _masm(&cbuf);
2974     Register res_reg = as_Register($res$$reg);
2975     __ cset(res_reg, Assembler::EQ);
2976   %}
2977 
2978   // prefetch encodings
2979 
2980   enc_class aarch64_enc_prefetchw(memory mem) %{
2981     MacroAssembler _masm(&cbuf);
2982     Register base = as_Register($mem$$base);
2983     int index = $mem$$index;
2984     int scale = $mem$$scale;
2985     int disp = $mem$$disp;
2986     if (index == -1) {
2987       __ prfm(Address(base, disp), PSTL1KEEP);
2988     } else {
2989       Register index_reg = as_Register(index);
2990       if (disp == 0) {
2991         __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP);
2992       } else {
2993         __ lea(rscratch1, Address(base, disp));
2994         __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP);
2995       }
2996     }
2997   %}
2998 
2999   /// mov envcodings
3000 
3001   enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{
3002     MacroAssembler _masm(&cbuf);
3003     u_int32_t con = (u_int32_t)$src$$constant;
3004     Register dst_reg = as_Register($dst$$reg);
3005     if (con == 0) {
3006       __ movw(dst_reg, zr);
3007     } else {
3008       __ movw(dst_reg, con);
3009     }
3010   %}
3011 
3012   enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{
3013     MacroAssembler _masm(&cbuf);
3014     Register dst_reg = as_Register($dst$$reg);
3015     u_int64_t con = (u_int64_t)$src$$constant;
3016     if (con == 0) {
3017       __ mov(dst_reg, zr);
3018     } else {
3019       __ mov(dst_reg, con);
3020     }
3021   %}
3022 
3023   enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{
3024     MacroAssembler _masm(&cbuf);
3025     Register dst_reg = as_Register($dst$$reg);
3026     address con = (address)$src$$constant;
3027     if (con == NULL || con == (address)1) {
3028       ShouldNotReachHere();
3029     } else {
3030       relocInfo::relocType rtype = $src->constant_reloc();
3031       if (rtype == relocInfo::oop_type) {
3032         __ movoop(dst_reg, (jobject)con, /*immediate*/true);
3033       } else if (rtype == relocInfo::metadata_type) {
3034         __ mov_metadata(dst_reg, (Metadata*)con);
3035       } else {
3036         assert(rtype == relocInfo::none, "unexpected reloc type");
3037         if (con < (address)(uintptr_t)os::vm_page_size()) {
3038           __ mov(dst_reg, con);
3039         } else {
3040           unsigned long offset;
3041           __ adrp(dst_reg, con, offset);
3042           __ add(dst_reg, dst_reg, offset);
3043         }
3044       }
3045     }
3046   %}
3047 
3048   enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{
3049     MacroAssembler _masm(&cbuf);
3050     Register dst_reg = as_Register($dst$$reg);
3051     __ mov(dst_reg, zr);
3052   %}
3053 
3054   enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{
3055     MacroAssembler _masm(&cbuf);
3056     Register dst_reg = as_Register($dst$$reg);
3057     __ mov(dst_reg, (u_int64_t)1);
3058   %}
3059 
3060   enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{
3061     MacroAssembler _masm(&cbuf);
3062     address page = (address)$src$$constant;
3063     Register dst_reg = as_Register($dst$$reg);
3064     unsigned long off;
3065     __ adrp(dst_reg, Address(page, relocInfo::poll_type), off);
3066     assert(off == 0, "assumed offset == 0");
3067   %}
3068 
3069   enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{
3070     MacroAssembler _masm(&cbuf);
3071     __ load_byte_map_base($dst$$Register);
3072   %}
3073 
3074   enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{
3075     MacroAssembler _masm(&cbuf);
3076     Register dst_reg = as_Register($dst$$reg);
3077     address con = (address)$src$$constant;
3078     if (con == NULL) {
3079       ShouldNotReachHere();
3080     } else {
3081       relocInfo::relocType rtype = $src->constant_reloc();
3082       assert(rtype == relocInfo::oop_type, "unexpected reloc type");
3083       __ set_narrow_oop(dst_reg, (jobject)con);
3084     }
3085   %}
3086 
3087   enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{
3088     MacroAssembler _masm(&cbuf);
3089     Register dst_reg = as_Register($dst$$reg);
3090     __ mov(dst_reg, zr);
3091   %}
3092 
3093   enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{
3094     MacroAssembler _masm(&cbuf);
3095     Register dst_reg = as_Register($dst$$reg);
3096     address con = (address)$src$$constant;
3097     if (con == NULL) {
3098       ShouldNotReachHere();
3099     } else {
3100       relocInfo::relocType rtype = $src->constant_reloc();
3101       assert(rtype == relocInfo::metadata_type, "unexpected reloc type");
3102       __ set_narrow_klass(dst_reg, (Klass *)con);
3103     }
3104   %}
3105 
3106   // arithmetic encodings
3107 
3108   enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{
3109     MacroAssembler _masm(&cbuf);
3110     Register dst_reg = as_Register($dst$$reg);
3111     Register src_reg = as_Register($src1$$reg);
3112     int32_t con = (int32_t)$src2$$constant;
3113     // add has primary == 0, subtract has primary == 1
3114     if ($primary) { con = -con; }
3115     if (con < 0) {
3116       __ subw(dst_reg, src_reg, -con);
3117     } else {
3118       __ addw(dst_reg, src_reg, con);
3119     }
3120   %}
3121 
3122   enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{
3123     MacroAssembler _masm(&cbuf);
3124     Register dst_reg = as_Register($dst$$reg);
3125     Register src_reg = as_Register($src1$$reg);
3126     int32_t con = (int32_t)$src2$$constant;
3127     // add has primary == 0, subtract has primary == 1
3128     if ($primary) { con = -con; }
3129     if (con < 0) {
3130       __ sub(dst_reg, src_reg, -con);
3131     } else {
3132       __ add(dst_reg, src_reg, con);
3133     }
3134   %}
3135 
3136   enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{
3137     MacroAssembler _masm(&cbuf);
3138    Register dst_reg = as_Register($dst$$reg);
3139    Register src1_reg = as_Register($src1$$reg);
3140    Register src2_reg = as_Register($src2$$reg);
3141     __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1);
3142   %}
3143 
3144   enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{
3145     MacroAssembler _masm(&cbuf);
3146    Register dst_reg = as_Register($dst$$reg);
3147    Register src1_reg = as_Register($src1$$reg);
3148    Register src2_reg = as_Register($src2$$reg);
3149     __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1);
3150   %}
3151 
3152   enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{
3153     MacroAssembler _masm(&cbuf);
3154    Register dst_reg = as_Register($dst$$reg);
3155    Register src1_reg = as_Register($src1$$reg);
3156    Register src2_reg = as_Register($src2$$reg);
3157     __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1);
3158   %}
3159 
3160   enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{
3161     MacroAssembler _masm(&cbuf);
3162    Register dst_reg = as_Register($dst$$reg);
3163    Register src1_reg = as_Register($src1$$reg);
3164    Register src2_reg = as_Register($src2$$reg);
3165     __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1);
3166   %}
3167 
3168   // compare instruction encodings
3169 
3170   enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{
3171     MacroAssembler _masm(&cbuf);
3172     Register reg1 = as_Register($src1$$reg);
3173     Register reg2 = as_Register($src2$$reg);
3174     __ cmpw(reg1, reg2);
3175   %}
3176 
3177   enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{
3178     MacroAssembler _masm(&cbuf);
3179     Register reg = as_Register($src1$$reg);
3180     int32_t val = $src2$$constant;
3181     if (val >= 0) {
3182       __ subsw(zr, reg, val);
3183     } else {
3184       __ addsw(zr, reg, -val);
3185     }
3186   %}
3187 
3188   enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{
3189     MacroAssembler _masm(&cbuf);
3190     Register reg1 = as_Register($src1$$reg);
3191     u_int32_t val = (u_int32_t)$src2$$constant;
3192     __ movw(rscratch1, val);
3193     __ cmpw(reg1, rscratch1);
3194   %}
3195 
3196   enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{
3197     MacroAssembler _masm(&cbuf);
3198     Register reg1 = as_Register($src1$$reg);
3199     Register reg2 = as_Register($src2$$reg);
3200     __ cmp(reg1, reg2);
3201   %}
3202 
3203   enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{
3204     MacroAssembler _masm(&cbuf);
3205     Register reg = as_Register($src1$$reg);
3206     int64_t val = $src2$$constant;
3207     if (val >= 0) {
3208       __ subs(zr, reg, val);
3209     } else if (val != -val) {
3210       __ adds(zr, reg, -val);
3211     } else {
3212     // aargh, Long.MIN_VALUE is a special case
3213       __ orr(rscratch1, zr, (u_int64_t)val);
3214       __ subs(zr, reg, rscratch1);
3215     }
3216   %}
3217 
3218   enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{
3219     MacroAssembler _masm(&cbuf);
3220     Register reg1 = as_Register($src1$$reg);
3221     u_int64_t val = (u_int64_t)$src2$$constant;
3222     __ mov(rscratch1, val);
3223     __ cmp(reg1, rscratch1);
3224   %}
3225 
3226   enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{
3227     MacroAssembler _masm(&cbuf);
3228     Register reg1 = as_Register($src1$$reg);
3229     Register reg2 = as_Register($src2$$reg);
3230     __ cmp(reg1, reg2);
3231   %}
3232 
3233   enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{
3234     MacroAssembler _masm(&cbuf);
3235     Register reg1 = as_Register($src1$$reg);
3236     Register reg2 = as_Register($src2$$reg);
3237     __ cmpw(reg1, reg2);
3238   %}
3239 
3240   enc_class aarch64_enc_testp(iRegP src) %{
3241     MacroAssembler _masm(&cbuf);
3242     Register reg = as_Register($src$$reg);
3243     __ cmp(reg, zr);
3244   %}
3245 
3246   enc_class aarch64_enc_testn(iRegN src) %{
3247     MacroAssembler _masm(&cbuf);
3248     Register reg = as_Register($src$$reg);
3249     __ cmpw(reg, zr);
3250   %}
3251 
3252   enc_class aarch64_enc_b(label lbl) %{
3253     MacroAssembler _masm(&cbuf);
3254     Label *L = $lbl$$label;
3255     __ b(*L);
3256   %}
3257 
3258   enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{
3259     MacroAssembler _masm(&cbuf);
3260     Label *L = $lbl$$label;
3261     __ br ((Assembler::Condition)$cmp$$cmpcode, *L);
3262   %}
3263 
3264   enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{
3265     MacroAssembler _masm(&cbuf);
3266     Label *L = $lbl$$label;
3267     __ br ((Assembler::Condition)$cmp$$cmpcode, *L);
3268   %}
3269 
3270   enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result)
3271   %{
3272      Register sub_reg = as_Register($sub$$reg);
3273      Register super_reg = as_Register($super$$reg);
3274      Register temp_reg = as_Register($temp$$reg);
3275      Register result_reg = as_Register($result$$reg);
3276 
3277      Label miss;
3278      MacroAssembler _masm(&cbuf);
3279      __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg,
3280                                      NULL, &miss,
3281                                      /*set_cond_codes:*/ true);
3282      if ($primary) {
3283        __ mov(result_reg, zr);
3284      }
3285      __ bind(miss);
3286   %}
3287 
3288   enc_class aarch64_enc_java_static_call(method meth) %{
3289     MacroAssembler _masm(&cbuf);
3290 
3291     address addr = (address)$meth$$method;
3292     address call;
3293     if (!_method) {
3294       // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3295       call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf);
3296     } else {
3297       int method_index = resolved_method_index(cbuf);
3298       RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
3299                                                   : static_call_Relocation::spec(method_index);
3300       call = __ trampoline_call(Address(addr, rspec), &cbuf);
3301 
3302       // Emit stub for static call
3303       address stub = CompiledStaticCall::emit_to_interp_stub(cbuf);
3304       if (stub == NULL) {
3305         ciEnv::current()->record_failure("CodeCache is full");
3306         return;
3307       }
3308     }
3309     if (call == NULL) {
3310       ciEnv::current()->record_failure("CodeCache is full");
3311       return;
3312     }
3313   %}
3314 
3315   enc_class aarch64_enc_java_dynamic_call(method meth) %{
3316     MacroAssembler _masm(&cbuf);
3317     int method_index = resolved_method_index(cbuf);
3318     address call = __ ic_call((address)$meth$$method, method_index);
3319     if (call == NULL) {
3320       ciEnv::current()->record_failure("CodeCache is full");
3321       return;
3322     }
3323   %}
3324 
3325   enc_class aarch64_enc_call_epilog() %{
3326     MacroAssembler _masm(&cbuf);
3327     if (VerifyStackAtCalls) {
3328       // Check that stack depth is unchanged: find majik cookie on stack
3329       __ call_Unimplemented();
3330     }
3331   %}
3332 
3333   enc_class aarch64_enc_java_to_runtime(method meth) %{
3334     MacroAssembler _masm(&cbuf);
3335 
3336     // some calls to generated routines (arraycopy code) are scheduled
3337     // by C2 as runtime calls. if so we can call them using a br (they
3338     // will be in a reachable segment) otherwise we have to use a blrt
3339     // which loads the absolute address into a register.
3340     address entry = (address)$meth$$method;
3341     CodeBlob *cb = CodeCache::find_blob(entry);
3342     if (cb) {
3343       address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type));
3344       if (call == NULL) {
3345         ciEnv::current()->record_failure("CodeCache is full");
3346         return;
3347       }
3348     } else {
3349       int gpcnt;
3350       int fpcnt;
3351       int rtype;
3352       getCallInfo(tf(), gpcnt, fpcnt, rtype);
3353       Label retaddr;
3354       __ adr(rscratch2, retaddr);
3355       __ lea(rscratch1, RuntimeAddress(entry));
3356       // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc()
3357       __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize)));
3358       __ blrt(rscratch1, gpcnt, fpcnt, rtype);
3359       __ bind(retaddr);
3360       __ add(sp, sp, 2 * wordSize);
3361     }
3362   %}
3363 
3364   enc_class aarch64_enc_rethrow() %{
3365     MacroAssembler _masm(&cbuf);
3366     __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub()));
3367   %}
3368 
3369   enc_class aarch64_enc_ret() %{
3370     MacroAssembler _masm(&cbuf);
3371     __ ret(lr);
3372   %}
3373 
3374   enc_class aarch64_enc_tail_call(iRegP jump_target) %{
3375     MacroAssembler _masm(&cbuf);
3376     Register target_reg = as_Register($jump_target$$reg);
3377     __ br(target_reg);
3378   %}
3379 
3380   enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{
3381     MacroAssembler _masm(&cbuf);
3382     Register target_reg = as_Register($jump_target$$reg);
3383     // exception oop should be in r0
3384     // ret addr has been popped into lr
3385     // callee expects it in r3
3386     __ mov(r3, lr);
3387     __ br(target_reg);
3388   %}
3389 
3390   enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{
3391     MacroAssembler _masm(&cbuf);
3392     Register oop = as_Register($object$$reg);
3393     Register box = as_Register($box$$reg);
3394     Register disp_hdr = as_Register($tmp$$reg);
3395     Register tmp = as_Register($tmp2$$reg);
3396     Label cont;
3397     Label object_has_monitor;
3398     Label cas_failed;
3399 
3400     assert_different_registers(oop, box, tmp, disp_hdr);
3401 
3402     // Load markOop from object into displaced_header.
3403     __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes()));
3404 
3405     if (UseBiasedLocking && !UseOptoBiasInlining) {
3406       __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont);
3407     }
3408 
3409     // Handle existing monitor
3410     // we can use AArch64's bit test and branch here but
3411     // markoopDesc does not define a bit index just the bit value
3412     // so assert in case the bit pos changes
3413 #   define __monitor_value_log2 1
3414     assert(markOopDesc::monitor_value == (1 << __monitor_value_log2), "incorrect bit position");
3415     __ tbnz(disp_hdr, __monitor_value_log2, object_has_monitor);
3416 #   undef __monitor_value_log2
3417 
3418     // Set displaced_header to be (markOop of object | UNLOCK_VALUE).
3419     __ orr(disp_hdr, disp_hdr, markOopDesc::unlocked_value);
3420 
3421     // Load Compare Value application register.
3422 
3423     // Initialize the box. (Must happen before we update the object mark!)
3424     __ str(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes()));
3425 
3426     // Compare object markOop with mark and if equal exchange scratch1
3427     // with object markOop.
3428     if (UseLSE) {
3429       __ mov(tmp, disp_hdr);
3430       __ casal(Assembler::xword, tmp, box, oop);
3431       __ cmp(tmp, disp_hdr);
3432       __ br(Assembler::EQ, cont);
3433     } else {
3434       Label retry_load;
3435       if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
3436         __ prfm(Address(oop), PSTL1STRM);
3437       __ bind(retry_load);
3438       __ ldaxr(tmp, oop);
3439       __ cmp(tmp, disp_hdr);
3440       __ br(Assembler::NE, cas_failed);
3441       // use stlxr to ensure update is immediately visible
3442       __ stlxr(tmp, box, oop);
3443       __ cbzw(tmp, cont);
3444       __ b(retry_load);
3445     }
3446 
3447     // Formerly:
3448     // __ cmpxchgptr(/*oldv=*/disp_hdr,
3449     //               /*newv=*/box,
3450     //               /*addr=*/oop,
3451     //               /*tmp=*/tmp,
3452     //               cont,
3453     //               /*fail*/NULL);
3454 
3455     assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
3456 
3457     // If the compare-and-exchange succeeded, then we found an unlocked
3458     // object, will have now locked it will continue at label cont
3459 
3460     __ bind(cas_failed);
3461     // We did not see an unlocked object so try the fast recursive case.
3462 
3463     // Check if the owner is self by comparing the value in the
3464     // markOop of object (disp_hdr) with the stack pointer.
3465     __ mov(rscratch1, sp);
3466     __ sub(disp_hdr, disp_hdr, rscratch1);
3467     __ mov(tmp, (address) (~(os::vm_page_size()-1) | markOopDesc::lock_mask_in_place));
3468     // If condition is true we are cont and hence we can store 0 as the
3469     // displaced header in the box, which indicates that it is a recursive lock.
3470     __ ands(tmp/*==0?*/, disp_hdr, tmp);
3471     __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes()));
3472 
3473     // Handle existing monitor.
3474     __ b(cont);
3475 
3476     __ bind(object_has_monitor);
3477     // The object's monitor m is unlocked iff m->owner == NULL,
3478     // otherwise m->owner may contain a thread or a stack address.
3479     //
3480     // Try to CAS m->owner from NULL to current thread.
3481     __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value));
3482     __ mov(disp_hdr, zr);
3483 
3484     if (UseLSE) {
3485       __ mov(rscratch1, disp_hdr);
3486       __ casal(Assembler::xword, rscratch1, rthread, tmp);
3487       __ cmp(rscratch1, disp_hdr);
3488     } else {
3489       Label retry_load, fail;
3490       if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) {
3491         __ prfm(Address(tmp), PSTL1STRM);
3492       }
3493       __ bind(retry_load);
3494       __ ldaxr(rscratch1, tmp);
3495       __ cmp(disp_hdr, rscratch1);
3496       __ br(Assembler::NE, fail);
3497       // use stlxr to ensure update is immediately visible
3498       __ stlxr(rscratch1, rthread, tmp);
3499       __ cbnzw(rscratch1, retry_load);
3500       __ bind(fail);
3501     }
3502 
3503     // Label next;
3504     // __ cmpxchgptr(/*oldv=*/disp_hdr,
3505     //               /*newv=*/rthread,
3506     //               /*addr=*/tmp,
3507     //               /*tmp=*/rscratch1,
3508     //               /*succeed*/next,
3509     //               /*fail*/NULL);
3510     // __ bind(next);
3511 
3512     // store a non-null value into the box.
3513     __ str(box, Address(box, BasicLock::displaced_header_offset_in_bytes()));
3514 
3515     // PPC port checks the following invariants
3516     // #ifdef ASSERT
3517     // bne(flag, cont);
3518     // We have acquired the monitor, check some invariants.
3519     // addw(/*monitor=*/tmp, tmp, -ObjectMonitor::owner_offset_in_bytes());
3520     // Invariant 1: _recursions should be 0.
3521     // assert(ObjectMonitor::recursions_size_in_bytes() == 8, "unexpected size");
3522     // assert_mem8_is_zero(ObjectMonitor::recursions_offset_in_bytes(), tmp,
3523     //                        "monitor->_recursions should be 0", -1);
3524     // Invariant 2: OwnerIsThread shouldn't be 0.
3525     // assert(ObjectMonitor::OwnerIsThread_size_in_bytes() == 4, "unexpected size");
3526     //assert_mem4_isnot_zero(ObjectMonitor::OwnerIsThread_offset_in_bytes(), tmp,
3527     //                           "monitor->OwnerIsThread shouldn't be 0", -1);
3528     // #endif
3529 
3530     __ bind(cont);
3531     // flag == EQ indicates success
3532     // flag == NE indicates failure
3533 
3534   %}
3535 
3536   // TODO
3537   // reimplement this with custom cmpxchgptr code
3538   // which avoids some of the unnecessary branching
3539   enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{
3540     MacroAssembler _masm(&cbuf);
3541     Register oop = as_Register($object$$reg);
3542     Register box = as_Register($box$$reg);
3543     Register disp_hdr = as_Register($tmp$$reg);
3544     Register tmp = as_Register($tmp2$$reg);
3545     Label cont;
3546     Label object_has_monitor;
3547     Label cas_failed;
3548 
3549     assert_different_registers(oop, box, tmp, disp_hdr);
3550 
3551     if (UseBiasedLocking && !UseOptoBiasInlining) {
3552       __ biased_locking_exit(oop, tmp, cont);
3553     }
3554 
3555     // Find the lock address and load the displaced header from the stack.
3556     __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes()));
3557 
3558     // If the displaced header is 0, we have a recursive unlock.
3559     __ cmp(disp_hdr, zr);
3560     __ br(Assembler::EQ, cont);
3561 
3562 
3563     // Handle existing monitor.
3564     __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes()));
3565     __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor);
3566 
3567     // Check if it is still a light weight lock, this is is true if we
3568     // see the stack address of the basicLock in the markOop of the
3569     // object.
3570 
3571       if (UseLSE) {
3572         __ mov(tmp, box);
3573         __ casl(Assembler::xword, tmp, disp_hdr, oop);
3574         __ cmp(tmp, box);
3575       } else {
3576         Label retry_load;
3577         if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
3578           __ prfm(Address(oop), PSTL1STRM);
3579         __ bind(retry_load);
3580         __ ldxr(tmp, oop);
3581         __ cmp(box, tmp);
3582         __ br(Assembler::NE, cas_failed);
3583         // use stlxr to ensure update is immediately visible
3584         __ stlxr(tmp, disp_hdr, oop);
3585         __ cbzw(tmp, cont);
3586         __ b(retry_load);
3587       }
3588 
3589     // __ cmpxchgptr(/*compare_value=*/box,
3590     //               /*exchange_value=*/disp_hdr,
3591     //               /*where=*/oop,
3592     //               /*result=*/tmp,
3593     //               cont,
3594     //               /*cas_failed*/NULL);
3595     assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
3596 
3597     __ bind(cas_failed);
3598 
3599     // Handle existing monitor.
3600     __ b(cont);
3601 
3602     __ bind(object_has_monitor);
3603     __ add(tmp, tmp, -markOopDesc::monitor_value); // monitor
3604     __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes()));
3605     __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes()));
3606     __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner.
3607     __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions
3608     __ cmp(rscratch1, zr);
3609     __ br(Assembler::NE, cont);
3610 
3611     __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes()));
3612     __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes()));
3613     __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0.
3614     __ cmp(rscratch1, zr);
3615     __ cbnz(rscratch1, cont);
3616     // need a release store here
3617     __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes()));
3618     __ stlr(rscratch1, tmp); // rscratch1 is zero
3619 
3620     __ bind(cont);
3621     // flag == EQ indicates success
3622     // flag == NE indicates failure
3623   %}
3624 
3625 %}
3626 
3627 //----------FRAME--------------------------------------------------------------
3628 // Definition of frame structure and management information.
3629 //
3630 //  S T A C K   L A Y O U T    Allocators stack-slot number
3631 //                             |   (to get allocators register number
3632 //  G  Owned by    |        |  v    add OptoReg::stack0())
3633 //  r   CALLER     |        |
3634 //  o     |        +--------+      pad to even-align allocators stack-slot
3635 //  w     V        |  pad0  |        numbers; owned by CALLER
3636 //  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
3637 //  h     ^        |   in   |  5
3638 //        |        |  args  |  4   Holes in incoming args owned by SELF
3639 //  |     |        |        |  3
3640 //  |     |        +--------+
3641 //  V     |        | old out|      Empty on Intel, window on Sparc
3642 //        |    old |preserve|      Must be even aligned.
3643 //        |     SP-+--------+----> Matcher::_old_SP, even aligned
3644 //        |        |   in   |  3   area for Intel ret address
3645 //     Owned by    |preserve|      Empty on Sparc.
3646 //       SELF      +--------+
3647 //        |        |  pad2  |  2   pad to align old SP
3648 //        |        +--------+  1
3649 //        |        | locks  |  0
3650 //        |        +--------+----> OptoReg::stack0(), even aligned
3651 //        |        |  pad1  | 11   pad to align new SP
3652 //        |        +--------+
3653 //        |        |        | 10
3654 //        |        | spills |  9   spills
3655 //        V        |        |  8   (pad0 slot for callee)
3656 //      -----------+--------+----> Matcher::_out_arg_limit, unaligned
3657 //        ^        |  out   |  7
3658 //        |        |  args  |  6   Holes in outgoing args owned by CALLEE
3659 //     Owned by    +--------+
3660 //      CALLEE     | new out|  6   Empty on Intel, window on Sparc
3661 //        |    new |preserve|      Must be even-aligned.
3662 //        |     SP-+--------+----> Matcher::_new_SP, even aligned
3663 //        |        |        |
3664 //
3665 // Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
3666 //         known from SELF's arguments and the Java calling convention.
3667 //         Region 6-7 is determined per call site.
3668 // Note 2: If the calling convention leaves holes in the incoming argument
3669 //         area, those holes are owned by SELF.  Holes in the outgoing area
3670 //         are owned by the CALLEE.  Holes should not be nessecary in the
3671 //         incoming area, as the Java calling convention is completely under
3672 //         the control of the AD file.  Doubles can be sorted and packed to
3673 //         avoid holes.  Holes in the outgoing arguments may be nessecary for
3674 //         varargs C calling conventions.
3675 // Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
3676 //         even aligned with pad0 as needed.
3677 //         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
3678 //           (the latter is true on Intel but is it false on AArch64?)
3679 //         region 6-11 is even aligned; it may be padded out more so that
3680 //         the region from SP to FP meets the minimum stack alignment.
3681 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
3682 //         alignment.  Region 11, pad1, may be dynamically extended so that
3683 //         SP meets the minimum alignment.
3684 
3685 frame %{
3686   // What direction does stack grow in (assumed to be same for C & Java)
3687   stack_direction(TOWARDS_LOW);
3688 
3689   // These three registers define part of the calling convention
3690   // between compiled code and the interpreter.
3691 
3692   // Inline Cache Register or methodOop for I2C.
3693   inline_cache_reg(R12);
3694 
3695   // Method Oop Register when calling interpreter.
3696   interpreter_method_oop_reg(R12);
3697 
3698   // Number of stack slots consumed by locking an object
3699   sync_stack_slots(2);
3700 
3701   // Compiled code's Frame Pointer
3702   frame_pointer(R31);
3703 
3704   // Interpreter stores its frame pointer in a register which is
3705   // stored to the stack by I2CAdaptors.
3706   // I2CAdaptors convert from interpreted java to compiled java.
3707   interpreter_frame_pointer(R29);
3708 
3709   // Stack alignment requirement
3710   stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
3711 
3712   // Number of stack slots between incoming argument block and the start of
3713   // a new frame.  The PROLOG must add this many slots to the stack.  The
3714   // EPILOG must remove this many slots. aarch64 needs two slots for
3715   // return address and fp.
3716   // TODO think this is correct but check
3717   in_preserve_stack_slots(4);
3718 
3719   // Number of outgoing stack slots killed above the out_preserve_stack_slots
3720   // for calls to C.  Supports the var-args backing area for register parms.
3721   varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt);
3722 
3723   // The after-PROLOG location of the return address.  Location of
3724   // return address specifies a type (REG or STACK) and a number
3725   // representing the register number (i.e. - use a register name) or
3726   // stack slot.
3727   // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
3728   // Otherwise, it is above the locks and verification slot and alignment word
3729   // TODO this may well be correct but need to check why that - 2 is there
3730   // ppc port uses 0 but we definitely need to allow for fixed_slots
3731   // which folds in the space used for monitors
3732   return_addr(STACK - 2 +
3733               align_up((Compile::current()->in_preserve_stack_slots() +
3734                         Compile::current()->fixed_slots()),
3735                        stack_alignment_in_slots()));
3736 
3737   // Body of function which returns an integer array locating
3738   // arguments either in registers or in stack slots.  Passed an array
3739   // of ideal registers called "sig" and a "length" count.  Stack-slot
3740   // offsets are based on outgoing arguments, i.e. a CALLER setting up
3741   // arguments for a CALLEE.  Incoming stack arguments are
3742   // automatically biased by the preserve_stack_slots field above.
3743 
3744   calling_convention
3745   %{
3746     // No difference between ingoing/outgoing just pass false
3747     SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
3748   %}
3749 
3750   c_calling_convention
3751   %{
3752     // This is obviously always outgoing
3753     (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length);
3754   %}
3755 
3756   // Location of compiled Java return values.  Same as C for now.
3757   return_value
3758   %{
3759     // TODO do we allow ideal_reg == Op_RegN???
3760     assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL,
3761            "only return normal values");
3762 
3763     static const int lo[Op_RegL + 1] = { // enum name
3764       0,                                 // Op_Node
3765       0,                                 // Op_Set
3766       R0_num,                            // Op_RegN
3767       R0_num,                            // Op_RegI
3768       R0_num,                            // Op_RegP
3769       V0_num,                            // Op_RegF
3770       V0_num,                            // Op_RegD
3771       R0_num                             // Op_RegL
3772     };
3773 
3774     static const int hi[Op_RegL + 1] = { // enum name
3775       0,                                 // Op_Node
3776       0,                                 // Op_Set
3777       OptoReg::Bad,                       // Op_RegN
3778       OptoReg::Bad,                      // Op_RegI
3779       R0_H_num,                          // Op_RegP
3780       OptoReg::Bad,                      // Op_RegF
3781       V0_H_num,                          // Op_RegD
3782       R0_H_num                           // Op_RegL
3783     };
3784 
3785     return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
3786   %}
3787 %}
3788 
3789 //----------ATTRIBUTES---------------------------------------------------------
3790 //----------Operand Attributes-------------------------------------------------
3791 op_attrib op_cost(1);        // Required cost attribute
3792 
3793 //----------Instruction Attributes---------------------------------------------
3794 ins_attrib ins_cost(INSN_COST); // Required cost attribute
3795 ins_attrib ins_size(32);        // Required size attribute (in bits)
3796 ins_attrib ins_short_branch(0); // Required flag: is this instruction
3797                                 // a non-matching short branch variant
3798                                 // of some long branch?
3799 ins_attrib ins_alignment(4);    // Required alignment attribute (must
3800                                 // be a power of 2) specifies the
3801                                 // alignment that some part of the
3802                                 // instruction (not necessarily the
3803                                 // start) requires.  If > 1, a
3804                                 // compute_padding() function must be
3805                                 // provided for the instruction
3806 
3807 //----------OPERANDS-----------------------------------------------------------
3808 // Operand definitions must precede instruction definitions for correct parsing
3809 // in the ADLC because operands constitute user defined types which are used in
3810 // instruction definitions.
3811 
3812 //----------Simple Operands----------------------------------------------------
3813 
3814 // Integer operands 32 bit
3815 // 32 bit immediate
3816 operand immI()
3817 %{
3818   match(ConI);
3819 
3820   op_cost(0);
3821   format %{ %}
3822   interface(CONST_INTER);
3823 %}
3824 
3825 // 32 bit zero
3826 operand immI0()
3827 %{
3828   predicate(n->get_int() == 0);
3829   match(ConI);
3830 
3831   op_cost(0);
3832   format %{ %}
3833   interface(CONST_INTER);
3834 %}
3835 
3836 // 32 bit unit increment
3837 operand immI_1()
3838 %{
3839   predicate(n->get_int() == 1);
3840   match(ConI);
3841 
3842   op_cost(0);
3843   format %{ %}
3844   interface(CONST_INTER);
3845 %}
3846 
3847 // 32 bit unit decrement
3848 operand immI_M1()
3849 %{
3850   predicate(n->get_int() == -1);
3851   match(ConI);
3852 
3853   op_cost(0);
3854   format %{ %}
3855   interface(CONST_INTER);
3856 %}
3857 
3858 // Shift values for add/sub extension shift
3859 operand immIExt()
3860 %{
3861   predicate(0 <= n->get_int() && (n->get_int() <= 4));
3862   match(ConI);
3863 
3864   op_cost(0);
3865   format %{ %}
3866   interface(CONST_INTER);
3867 %}
3868 
3869 operand immI_le_4()
3870 %{
3871   predicate(n->get_int() <= 4);
3872   match(ConI);
3873 
3874   op_cost(0);
3875   format %{ %}
3876   interface(CONST_INTER);
3877 %}
3878 
3879 operand immI_31()
3880 %{
3881   predicate(n->get_int() == 31);
3882   match(ConI);
3883 
3884   op_cost(0);
3885   format %{ %}
3886   interface(CONST_INTER);
3887 %}
3888 
3889 operand immI_8()
3890 %{
3891   predicate(n->get_int() == 8);
3892   match(ConI);
3893 
3894   op_cost(0);
3895   format %{ %}
3896   interface(CONST_INTER);
3897 %}
3898 
3899 operand immI_16()
3900 %{
3901   predicate(n->get_int() == 16);
3902   match(ConI);
3903 
3904   op_cost(0);
3905   format %{ %}
3906   interface(CONST_INTER);
3907 %}
3908 
3909 operand immI_24()
3910 %{
3911   predicate(n->get_int() == 24);
3912   match(ConI);
3913 
3914   op_cost(0);
3915   format %{ %}
3916   interface(CONST_INTER);
3917 %}
3918 
3919 operand immI_32()
3920 %{
3921   predicate(n->get_int() == 32);
3922   match(ConI);
3923 
3924   op_cost(0);
3925   format %{ %}
3926   interface(CONST_INTER);
3927 %}
3928 
3929 operand immI_48()
3930 %{
3931   predicate(n->get_int() == 48);
3932   match(ConI);
3933 
3934   op_cost(0);
3935   format %{ %}
3936   interface(CONST_INTER);
3937 %}
3938 
3939 operand immI_56()
3940 %{
3941   predicate(n->get_int() == 56);
3942   match(ConI);
3943 
3944   op_cost(0);
3945   format %{ %}
3946   interface(CONST_INTER);
3947 %}
3948 
3949 operand immI_63()
3950 %{
3951   predicate(n->get_int() == 63);
3952   match(ConI);
3953 
3954   op_cost(0);
3955   format %{ %}
3956   interface(CONST_INTER);
3957 %}
3958 
3959 operand immI_64()
3960 %{
3961   predicate(n->get_int() == 64);
3962   match(ConI);
3963 
3964   op_cost(0);
3965   format %{ %}
3966   interface(CONST_INTER);
3967 %}
3968 
3969 operand immI_255()
3970 %{
3971   predicate(n->get_int() == 255);
3972   match(ConI);
3973 
3974   op_cost(0);
3975   format %{ %}
3976   interface(CONST_INTER);
3977 %}
3978 
3979 operand immI_65535()
3980 %{
3981   predicate(n->get_int() == 65535);
3982   match(ConI);
3983 
3984   op_cost(0);
3985   format %{ %}
3986   interface(CONST_INTER);
3987 %}
3988 
3989 operand immL_255()
3990 %{
3991   predicate(n->get_long() == 255L);
3992   match(ConL);
3993 
3994   op_cost(0);
3995   format %{ %}
3996   interface(CONST_INTER);
3997 %}
3998 
3999 operand immL_65535()
4000 %{
4001   predicate(n->get_long() == 65535L);
4002   match(ConL);
4003 
4004   op_cost(0);
4005   format %{ %}
4006   interface(CONST_INTER);
4007 %}
4008 
4009 operand immL_4294967295()
4010 %{
4011   predicate(n->get_long() == 4294967295L);
4012   match(ConL);
4013 
4014   op_cost(0);
4015   format %{ %}
4016   interface(CONST_INTER);
4017 %}
4018 
4019 operand immL_bitmask()
4020 %{
4021   predicate(((n->get_long() & 0xc000000000000000l) == 0)
4022             && is_power_of_2(n->get_long() + 1));
4023   match(ConL);
4024 
4025   op_cost(0);
4026   format %{ %}
4027   interface(CONST_INTER);
4028 %}
4029 
4030 operand immI_bitmask()
4031 %{
4032   predicate(((n->get_int() & 0xc0000000) == 0)
4033             && is_power_of_2(n->get_int() + 1));
4034   match(ConI);
4035 
4036   op_cost(0);
4037   format %{ %}
4038   interface(CONST_INTER);
4039 %}
4040 
4041 // Scale values for scaled offset addressing modes (up to long but not quad)
4042 operand immIScale()
4043 %{
4044   predicate(0 <= n->get_int() && (n->get_int() <= 3));
4045   match(ConI);
4046 
4047   op_cost(0);
4048   format %{ %}
4049   interface(CONST_INTER);
4050 %}
4051 
4052 // 26 bit signed offset -- for pc-relative branches
4053 operand immI26()
4054 %{
4055   predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25)));
4056   match(ConI);
4057 
4058   op_cost(0);
4059   format %{ %}
4060   interface(CONST_INTER);
4061 %}
4062 
4063 // 19 bit signed offset -- for pc-relative loads
4064 operand immI19()
4065 %{
4066   predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18)));
4067   match(ConI);
4068 
4069   op_cost(0);
4070   format %{ %}
4071   interface(CONST_INTER);
4072 %}
4073 
4074 // 12 bit unsigned offset -- for base plus immediate loads
4075 operand immIU12()
4076 %{
4077   predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12)));
4078   match(ConI);
4079 
4080   op_cost(0);
4081   format %{ %}
4082   interface(CONST_INTER);
4083 %}
4084 
4085 operand immLU12()
4086 %{
4087   predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12)));
4088   match(ConL);
4089 
4090   op_cost(0);
4091   format %{ %}
4092   interface(CONST_INTER);
4093 %}
4094 
4095 // Offset for scaled or unscaled immediate loads and stores
4096 operand immIOffset()
4097 %{
4098   predicate(Address::offset_ok_for_immed(n->get_int()));
4099   match(ConI);
4100 
4101   op_cost(0);
4102   format %{ %}
4103   interface(CONST_INTER);
4104 %}
4105 
4106 operand immIOffset4()
4107 %{
4108   predicate(Address::offset_ok_for_immed(n->get_int(), 2));
4109   match(ConI);
4110 
4111   op_cost(0);
4112   format %{ %}
4113   interface(CONST_INTER);
4114 %}
4115 
4116 operand immIOffset8()
4117 %{
4118   predicate(Address::offset_ok_for_immed(n->get_int(), 3));
4119   match(ConI);
4120 
4121   op_cost(0);
4122   format %{ %}
4123   interface(CONST_INTER);
4124 %}
4125 
4126 operand immIOffset16()
4127 %{
4128   predicate(Address::offset_ok_for_immed(n->get_int(), 4));
4129   match(ConI);
4130 
4131   op_cost(0);
4132   format %{ %}
4133   interface(CONST_INTER);
4134 %}
4135 
4136 operand immLoffset()
4137 %{
4138   predicate(Address::offset_ok_for_immed(n->get_long()));
4139   match(ConL);
4140 
4141   op_cost(0);
4142   format %{ %}
4143   interface(CONST_INTER);
4144 %}
4145 
4146 operand immLoffset4()
4147 %{
4148   predicate(Address::offset_ok_for_immed(n->get_long(), 2));
4149   match(ConL);
4150 
4151   op_cost(0);
4152   format %{ %}
4153   interface(CONST_INTER);
4154 %}
4155 
4156 operand immLoffset8()
4157 %{
4158   predicate(Address::offset_ok_for_immed(n->get_long(), 3));
4159   match(ConL);
4160 
4161   op_cost(0);
4162   format %{ %}
4163   interface(CONST_INTER);
4164 %}
4165 
4166 operand immLoffset16()
4167 %{
4168   predicate(Address::offset_ok_for_immed(n->get_long(), 4));
4169   match(ConL);
4170 
4171   op_cost(0);
4172   format %{ %}
4173   interface(CONST_INTER);
4174 %}
4175 
4176 // 32 bit integer valid for add sub immediate
4177 operand immIAddSub()
4178 %{
4179   predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int()));
4180   match(ConI);
4181   op_cost(0);
4182   format %{ %}
4183   interface(CONST_INTER);
4184 %}
4185 
4186 // 32 bit unsigned integer valid for logical immediate
4187 // TODO -- check this is right when e.g the mask is 0x80000000
4188 operand immILog()
4189 %{
4190   predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int()));
4191   match(ConI);
4192 
4193   op_cost(0);
4194   format %{ %}
4195   interface(CONST_INTER);
4196 %}
4197 
4198 // Integer operands 64 bit
4199 // 64 bit immediate
4200 operand immL()
4201 %{
4202   match(ConL);
4203 
4204   op_cost(0);
4205   format %{ %}
4206   interface(CONST_INTER);
4207 %}
4208 
4209 // 64 bit zero
4210 operand immL0()
4211 %{
4212   predicate(n->get_long() == 0);
4213   match(ConL);
4214 
4215   op_cost(0);
4216   format %{ %}
4217   interface(CONST_INTER);
4218 %}
4219 
4220 // 64 bit unit increment
4221 operand immL_1()
4222 %{
4223   predicate(n->get_long() == 1);
4224   match(ConL);
4225 
4226   op_cost(0);
4227   format %{ %}
4228   interface(CONST_INTER);
4229 %}
4230 
4231 // 64 bit unit decrement
4232 operand immL_M1()
4233 %{
4234   predicate(n->get_long() == -1);
4235   match(ConL);
4236 
4237   op_cost(0);
4238   format %{ %}
4239   interface(CONST_INTER);
4240 %}
4241 
4242 // 32 bit offset of pc in thread anchor
4243 
4244 operand immL_pc_off()
4245 %{
4246   predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) +
4247                              in_bytes(JavaFrameAnchor::last_Java_pc_offset()));
4248   match(ConL);
4249 
4250   op_cost(0);
4251   format %{ %}
4252   interface(CONST_INTER);
4253 %}
4254 
4255 // 64 bit integer valid for add sub immediate
4256 operand immLAddSub()
4257 %{
4258   predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long()));
4259   match(ConL);
4260   op_cost(0);
4261   format %{ %}
4262   interface(CONST_INTER);
4263 %}
4264 
4265 // 64 bit integer valid for logical immediate
4266 operand immLLog()
4267 %{
4268   predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (unsigned long)n->get_long()));
4269   match(ConL);
4270   op_cost(0);
4271   format %{ %}
4272   interface(CONST_INTER);
4273 %}
4274 
4275 // Long Immediate: low 32-bit mask
4276 operand immL_32bits()
4277 %{
4278   predicate(n->get_long() == 0xFFFFFFFFL);
4279   match(ConL);
4280   op_cost(0);
4281   format %{ %}
4282   interface(CONST_INTER);
4283 %}
4284 
4285 // Pointer operands
4286 // Pointer Immediate
4287 operand immP()
4288 %{
4289   match(ConP);
4290 
4291   op_cost(0);
4292   format %{ %}
4293   interface(CONST_INTER);
4294 %}
4295 
4296 // NULL Pointer Immediate
4297 operand immP0()
4298 %{
4299   predicate(n->get_ptr() == 0);
4300   match(ConP);
4301 
4302   op_cost(0);
4303   format %{ %}
4304   interface(CONST_INTER);
4305 %}
4306 
4307 // Pointer Immediate One
4308 // this is used in object initialization (initial object header)
4309 operand immP_1()
4310 %{
4311   predicate(n->get_ptr() == 1);
4312   match(ConP);
4313 
4314   op_cost(0);
4315   format %{ %}
4316   interface(CONST_INTER);
4317 %}
4318 
4319 // Polling Page Pointer Immediate
4320 operand immPollPage()
4321 %{
4322   predicate((address)n->get_ptr() == os::get_polling_page());
4323   match(ConP);
4324 
4325   op_cost(0);
4326   format %{ %}
4327   interface(CONST_INTER);
4328 %}
4329 
4330 // Card Table Byte Map Base
4331 operand immByteMapBase()
4332 %{
4333   // Get base of card map
4334   predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) &&
4335             (jbyte*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base());
4336   match(ConP);
4337 
4338   op_cost(0);
4339   format %{ %}
4340   interface(CONST_INTER);
4341 %}
4342 
4343 // Pointer Immediate Minus One
4344 // this is used when we want to write the current PC to the thread anchor
4345 operand immP_M1()
4346 %{
4347   predicate(n->get_ptr() == -1);
4348   match(ConP);
4349 
4350   op_cost(0);
4351   format %{ %}
4352   interface(CONST_INTER);
4353 %}
4354 
4355 // Pointer Immediate Minus Two
4356 // this is used when we want to write the current PC to the thread anchor
4357 operand immP_M2()
4358 %{
4359   predicate(n->get_ptr() == -2);
4360   match(ConP);
4361 
4362   op_cost(0);
4363   format %{ %}
4364   interface(CONST_INTER);
4365 %}
4366 
4367 // Float and Double operands
4368 // Double Immediate
4369 operand immD()
4370 %{
4371   match(ConD);
4372   op_cost(0);
4373   format %{ %}
4374   interface(CONST_INTER);
4375 %}
4376 
4377 // Double Immediate: +0.0d
4378 operand immD0()
4379 %{
4380   predicate(jlong_cast(n->getd()) == 0);
4381   match(ConD);
4382 
4383   op_cost(0);
4384   format %{ %}
4385   interface(CONST_INTER);
4386 %}
4387 
4388 // constant 'double +0.0'.
4389 operand immDPacked()
4390 %{
4391   predicate(Assembler::operand_valid_for_float_immediate(n->getd()));
4392   match(ConD);
4393   op_cost(0);
4394   format %{ %}
4395   interface(CONST_INTER);
4396 %}
4397 
4398 // Float Immediate
4399 operand immF()
4400 %{
4401   match(ConF);
4402   op_cost(0);
4403   format %{ %}
4404   interface(CONST_INTER);
4405 %}
4406 
4407 // Float Immediate: +0.0f.
4408 operand immF0()
4409 %{
4410   predicate(jint_cast(n->getf()) == 0);
4411   match(ConF);
4412 
4413   op_cost(0);
4414   format %{ %}
4415   interface(CONST_INTER);
4416 %}
4417 
4418 //
4419 operand immFPacked()
4420 %{
4421   predicate(Assembler::operand_valid_for_float_immediate((double)n->getf()));
4422   match(ConF);
4423   op_cost(0);
4424   format %{ %}
4425   interface(CONST_INTER);
4426 %}
4427 
4428 // Narrow pointer operands
4429 // Narrow Pointer Immediate
4430 operand immN()
4431 %{
4432   match(ConN);
4433 
4434   op_cost(0);
4435   format %{ %}
4436   interface(CONST_INTER);
4437 %}
4438 
4439 // Narrow NULL Pointer Immediate
4440 operand immN0()
4441 %{
4442   predicate(n->get_narrowcon() == 0);
4443   match(ConN);
4444 
4445   op_cost(0);
4446   format %{ %}
4447   interface(CONST_INTER);
4448 %}
4449 
4450 operand immNKlass()
4451 %{
4452   match(ConNKlass);
4453 
4454   op_cost(0);
4455   format %{ %}
4456   interface(CONST_INTER);
4457 %}
4458 
4459 // Integer 32 bit Register Operands
4460 // Integer 32 bitRegister (excludes SP)
4461 operand iRegI()
4462 %{
4463   constraint(ALLOC_IN_RC(any_reg32));
4464   match(RegI);
4465   match(iRegINoSp);
4466   op_cost(0);
4467   format %{ %}
4468   interface(REG_INTER);
4469 %}
4470 
4471 // Integer 32 bit Register not Special
4472 operand iRegINoSp()
4473 %{
4474   constraint(ALLOC_IN_RC(no_special_reg32));
4475   match(RegI);
4476   op_cost(0);
4477   format %{ %}
4478   interface(REG_INTER);
4479 %}
4480 
4481 // Integer 64 bit Register Operands
4482 // Integer 64 bit Register (includes SP)
4483 operand iRegL()
4484 %{
4485   constraint(ALLOC_IN_RC(any_reg));
4486   match(RegL);
4487   match(iRegLNoSp);
4488   op_cost(0);
4489   format %{ %}
4490   interface(REG_INTER);
4491 %}
4492 
4493 // Integer 64 bit Register not Special
4494 operand iRegLNoSp()
4495 %{
4496   constraint(ALLOC_IN_RC(no_special_reg));
4497   match(RegL);
4498   match(iRegL_R0);
4499   format %{ %}
4500   interface(REG_INTER);
4501 %}
4502 
4503 // Pointer Register Operands
4504 // Pointer Register
4505 operand iRegP()
4506 %{
4507   constraint(ALLOC_IN_RC(ptr_reg));
4508   match(RegP);
4509   match(iRegPNoSp);
4510   match(iRegP_R0);
4511   //match(iRegP_R2);
4512   //match(iRegP_R4);
4513   //match(iRegP_R5);
4514   match(thread_RegP);
4515   op_cost(0);
4516   format %{ %}
4517   interface(REG_INTER);
4518 %}
4519 
4520 // Pointer 64 bit Register not Special
4521 operand iRegPNoSp()
4522 %{
4523   constraint(ALLOC_IN_RC(no_special_ptr_reg));
4524   match(RegP);
4525   // match(iRegP);
4526   // match(iRegP_R0);
4527   // match(iRegP_R2);
4528   // match(iRegP_R4);
4529   // match(iRegP_R5);
4530   // match(thread_RegP);
4531   op_cost(0);
4532   format %{ %}
4533   interface(REG_INTER);
4534 %}
4535 
4536 // Pointer 64 bit Register R0 only
4537 operand iRegP_R0()
4538 %{
4539   constraint(ALLOC_IN_RC(r0_reg));
4540   match(RegP);
4541   // match(iRegP);
4542   match(iRegPNoSp);
4543   op_cost(0);
4544   format %{ %}
4545   interface(REG_INTER);
4546 %}
4547 
4548 // Pointer 64 bit Register R1 only
4549 operand iRegP_R1()
4550 %{
4551   constraint(ALLOC_IN_RC(r1_reg));
4552   match(RegP);
4553   // match(iRegP);
4554   match(iRegPNoSp);
4555   op_cost(0);
4556   format %{ %}
4557   interface(REG_INTER);
4558 %}
4559 
4560 // Pointer 64 bit Register R2 only
4561 operand iRegP_R2()
4562 %{
4563   constraint(ALLOC_IN_RC(r2_reg));
4564   match(RegP);
4565   // match(iRegP);
4566   match(iRegPNoSp);
4567   op_cost(0);
4568   format %{ %}
4569   interface(REG_INTER);
4570 %}
4571 
4572 // Pointer 64 bit Register R3 only
4573 operand iRegP_R3()
4574 %{
4575   constraint(ALLOC_IN_RC(r3_reg));
4576   match(RegP);
4577   // match(iRegP);
4578   match(iRegPNoSp);
4579   op_cost(0);
4580   format %{ %}
4581   interface(REG_INTER);
4582 %}
4583 
4584 // Pointer 64 bit Register R4 only
4585 operand iRegP_R4()
4586 %{
4587   constraint(ALLOC_IN_RC(r4_reg));
4588   match(RegP);
4589   // match(iRegP);
4590   match(iRegPNoSp);
4591   op_cost(0);
4592   format %{ %}
4593   interface(REG_INTER);
4594 %}
4595 
4596 // Pointer 64 bit Register R5 only
4597 operand iRegP_R5()
4598 %{
4599   constraint(ALLOC_IN_RC(r5_reg));
4600   match(RegP);
4601   // match(iRegP);
4602   match(iRegPNoSp);
4603   op_cost(0);
4604   format %{ %}
4605   interface(REG_INTER);
4606 %}
4607 
4608 // Pointer 64 bit Register R10 only
4609 operand iRegP_R10()
4610 %{
4611   constraint(ALLOC_IN_RC(r10_reg));
4612   match(RegP);
4613   // match(iRegP);
4614   match(iRegPNoSp);
4615   op_cost(0);
4616   format %{ %}
4617   interface(REG_INTER);
4618 %}
4619 
4620 // Long 64 bit Register R0 only
4621 operand iRegL_R0()
4622 %{
4623   constraint(ALLOC_IN_RC(r0_reg));
4624   match(RegL);
4625   match(iRegLNoSp);
4626   op_cost(0);
4627   format %{ %}
4628   interface(REG_INTER);
4629 %}
4630 
4631 // Long 64 bit Register R2 only
4632 operand iRegL_R2()
4633 %{
4634   constraint(ALLOC_IN_RC(r2_reg));
4635   match(RegL);
4636   match(iRegLNoSp);
4637   op_cost(0);
4638   format %{ %}
4639   interface(REG_INTER);
4640 %}
4641 
4642 // Long 64 bit Register R3 only
4643 operand iRegL_R3()
4644 %{
4645   constraint(ALLOC_IN_RC(r3_reg));
4646   match(RegL);
4647   match(iRegLNoSp);
4648   op_cost(0);
4649   format %{ %}
4650   interface(REG_INTER);
4651 %}
4652 
4653 // Long 64 bit Register R11 only
4654 operand iRegL_R11()
4655 %{
4656   constraint(ALLOC_IN_RC(r11_reg));
4657   match(RegL);
4658   match(iRegLNoSp);
4659   op_cost(0);
4660   format %{ %}
4661   interface(REG_INTER);
4662 %}
4663 
4664 // Pointer 64 bit Register FP only
4665 operand iRegP_FP()
4666 %{
4667   constraint(ALLOC_IN_RC(fp_reg));
4668   match(RegP);
4669   // match(iRegP);
4670   op_cost(0);
4671   format %{ %}
4672   interface(REG_INTER);
4673 %}
4674 
4675 // Register R0 only
4676 operand iRegI_R0()
4677 %{
4678   constraint(ALLOC_IN_RC(int_r0_reg));
4679   match(RegI);
4680   match(iRegINoSp);
4681   op_cost(0);
4682   format %{ %}
4683   interface(REG_INTER);
4684 %}
4685 
4686 // Register R2 only
4687 operand iRegI_R2()
4688 %{
4689   constraint(ALLOC_IN_RC(int_r2_reg));
4690   match(RegI);
4691   match(iRegINoSp);
4692   op_cost(0);
4693   format %{ %}
4694   interface(REG_INTER);
4695 %}
4696 
4697 // Register R3 only
4698 operand iRegI_R3()
4699 %{
4700   constraint(ALLOC_IN_RC(int_r3_reg));
4701   match(RegI);
4702   match(iRegINoSp);
4703   op_cost(0);
4704   format %{ %}
4705   interface(REG_INTER);
4706 %}
4707 
4708 
4709 // Register R4 only
4710 operand iRegI_R4()
4711 %{
4712   constraint(ALLOC_IN_RC(int_r4_reg));
4713   match(RegI);
4714   match(iRegINoSp);
4715   op_cost(0);
4716   format %{ %}
4717   interface(REG_INTER);
4718 %}
4719 
4720 
4721 // Pointer Register Operands
4722 // Narrow Pointer Register
4723 operand iRegN()
4724 %{
4725   constraint(ALLOC_IN_RC(any_reg32));
4726   match(RegN);
4727   match(iRegNNoSp);
4728   op_cost(0);
4729   format %{ %}
4730   interface(REG_INTER);
4731 %}
4732 
4733 operand iRegN_R0()
4734 %{
4735   constraint(ALLOC_IN_RC(r0_reg));
4736   match(iRegN);
4737   op_cost(0);
4738   format %{ %}
4739   interface(REG_INTER);
4740 %}
4741 
4742 operand iRegN_R2()
4743 %{
4744   constraint(ALLOC_IN_RC(r2_reg));
4745   match(iRegN);
4746   op_cost(0);
4747   format %{ %}
4748   interface(REG_INTER);
4749 %}
4750 
4751 operand iRegN_R3()
4752 %{
4753   constraint(ALLOC_IN_RC(r3_reg));
4754   match(iRegN);
4755   op_cost(0);
4756   format %{ %}
4757   interface(REG_INTER);
4758 %}
4759 
4760 // Integer 64 bit Register not Special
4761 operand iRegNNoSp()
4762 %{
4763   constraint(ALLOC_IN_RC(no_special_reg32));
4764   match(RegN);
4765   op_cost(0);
4766   format %{ %}
4767   interface(REG_INTER);
4768 %}
4769 
4770 // heap base register -- used for encoding immN0
4771 
4772 operand iRegIHeapbase()
4773 %{
4774   constraint(ALLOC_IN_RC(heapbase_reg));
4775   match(RegI);
4776   op_cost(0);
4777   format %{ %}
4778   interface(REG_INTER);
4779 %}
4780 
4781 // Float Register
4782 // Float register operands
4783 operand vRegF()
4784 %{
4785   constraint(ALLOC_IN_RC(float_reg));
4786   match(RegF);
4787 
4788   op_cost(0);
4789   format %{ %}
4790   interface(REG_INTER);
4791 %}
4792 
4793 // Double Register
4794 // Double register operands
4795 operand vRegD()
4796 %{
4797   constraint(ALLOC_IN_RC(double_reg));
4798   match(RegD);
4799 
4800   op_cost(0);
4801   format %{ %}
4802   interface(REG_INTER);
4803 %}
4804 
4805 operand vecD()
4806 %{
4807   constraint(ALLOC_IN_RC(vectord_reg));
4808   match(VecD);
4809 
4810   op_cost(0);
4811   format %{ %}
4812   interface(REG_INTER);
4813 %}
4814 
4815 operand vecX()
4816 %{
4817   constraint(ALLOC_IN_RC(vectorx_reg));
4818   match(VecX);
4819 
4820   op_cost(0);
4821   format %{ %}
4822   interface(REG_INTER);
4823 %}
4824 
4825 operand vRegD_V0()
4826 %{
4827   constraint(ALLOC_IN_RC(v0_reg));
4828   match(RegD);
4829   op_cost(0);
4830   format %{ %}
4831   interface(REG_INTER);
4832 %}
4833 
4834 operand vRegD_V1()
4835 %{
4836   constraint(ALLOC_IN_RC(v1_reg));
4837   match(RegD);
4838   op_cost(0);
4839   format %{ %}
4840   interface(REG_INTER);
4841 %}
4842 
4843 operand vRegD_V2()
4844 %{
4845   constraint(ALLOC_IN_RC(v2_reg));
4846   match(RegD);
4847   op_cost(0);
4848   format %{ %}
4849   interface(REG_INTER);
4850 %}
4851 
4852 operand vRegD_V3()
4853 %{
4854   constraint(ALLOC_IN_RC(v3_reg));
4855   match(RegD);
4856   op_cost(0);
4857   format %{ %}
4858   interface(REG_INTER);
4859 %}
4860 
4861 // Flags register, used as output of signed compare instructions
4862 
4863 // note that on AArch64 we also use this register as the output for
4864 // for floating point compare instructions (CmpF CmpD). this ensures
4865 // that ordered inequality tests use GT, GE, LT or LE none of which
4866 // pass through cases where the result is unordered i.e. one or both
4867 // inputs to the compare is a NaN. this means that the ideal code can
4868 // replace e.g. a GT with an LE and not end up capturing the NaN case
4869 // (where the comparison should always fail). EQ and NE tests are
4870 // always generated in ideal code so that unordered folds into the NE
4871 // case, matching the behaviour of AArch64 NE.
4872 //
4873 // This differs from x86 where the outputs of FP compares use a
4874 // special FP flags registers and where compares based on this
4875 // register are distinguished into ordered inequalities (cmpOpUCF) and
4876 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests
4877 // to explicitly handle the unordered case in branches. x86 also has
4878 // to include extra CMoveX rules to accept a cmpOpUCF input.
4879 
4880 operand rFlagsReg()
4881 %{
4882   constraint(ALLOC_IN_RC(int_flags));
4883   match(RegFlags);
4884 
4885   op_cost(0);
4886   format %{ "RFLAGS" %}
4887   interface(REG_INTER);
4888 %}
4889 
4890 // Flags register, used as output of unsigned compare instructions
4891 operand rFlagsRegU()
4892 %{
4893   constraint(ALLOC_IN_RC(int_flags));
4894   match(RegFlags);
4895 
4896   op_cost(0);
4897   format %{ "RFLAGSU" %}
4898   interface(REG_INTER);
4899 %}
4900 
4901 // Special Registers
4902 
4903 // Method Register
4904 operand inline_cache_RegP(iRegP reg)
4905 %{
4906   constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg
4907   match(reg);
4908   match(iRegPNoSp);
4909   op_cost(0);
4910   format %{ %}
4911   interface(REG_INTER);
4912 %}
4913 
4914 operand interpreter_method_oop_RegP(iRegP reg)
4915 %{
4916   constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg
4917   match(reg);
4918   match(iRegPNoSp);
4919   op_cost(0);
4920   format %{ %}
4921   interface(REG_INTER);
4922 %}
4923 
4924 // Thread Register
4925 operand thread_RegP(iRegP reg)
4926 %{
4927   constraint(ALLOC_IN_RC(thread_reg)); // link_reg
4928   match(reg);
4929   op_cost(0);
4930   format %{ %}
4931   interface(REG_INTER);
4932 %}
4933 
4934 operand lr_RegP(iRegP reg)
4935 %{
4936   constraint(ALLOC_IN_RC(lr_reg)); // link_reg
4937   match(reg);
4938   op_cost(0);
4939   format %{ %}
4940   interface(REG_INTER);
4941 %}
4942 
4943 //----------Memory Operands----------------------------------------------------
4944 
4945 operand indirect(iRegP reg)
4946 %{
4947   constraint(ALLOC_IN_RC(ptr_reg));
4948   match(reg);
4949   op_cost(0);
4950   format %{ "[$reg]" %}
4951   interface(MEMORY_INTER) %{
4952     base($reg);
4953     index(0xffffffff);
4954     scale(0x0);
4955     disp(0x0);
4956   %}
4957 %}
4958 
4959 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale)
4960 %{
4961   constraint(ALLOC_IN_RC(ptr_reg));
4962   predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
4963   match(AddP reg (LShiftL (ConvI2L ireg) scale));
4964   op_cost(0);
4965   format %{ "$reg, $ireg sxtw($scale), 0, I2L" %}
4966   interface(MEMORY_INTER) %{
4967     base($reg);
4968     index($ireg);
4969     scale($scale);
4970     disp(0x0);
4971   %}
4972 %}
4973 
4974 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale)
4975 %{
4976   constraint(ALLOC_IN_RC(ptr_reg));
4977   predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
4978   match(AddP reg (LShiftL lreg scale));
4979   op_cost(0);
4980   format %{ "$reg, $lreg lsl($scale)" %}
4981   interface(MEMORY_INTER) %{
4982     base($reg);
4983     index($lreg);
4984     scale($scale);
4985     disp(0x0);
4986   %}
4987 %}
4988 
4989 operand indIndexI2L(iRegP reg, iRegI ireg)
4990 %{
4991   constraint(ALLOC_IN_RC(ptr_reg));
4992   match(AddP reg (ConvI2L ireg));
4993   op_cost(0);
4994   format %{ "$reg, $ireg, 0, I2L" %}
4995   interface(MEMORY_INTER) %{
4996     base($reg);
4997     index($ireg);
4998     scale(0x0);
4999     disp(0x0);
5000   %}
5001 %}
5002 
5003 operand indIndex(iRegP reg, iRegL lreg)
5004 %{
5005   constraint(ALLOC_IN_RC(ptr_reg));
5006   match(AddP reg lreg);
5007   op_cost(0);
5008   format %{ "$reg, $lreg" %}
5009   interface(MEMORY_INTER) %{
5010     base($reg);
5011     index($lreg);
5012     scale(0x0);
5013     disp(0x0);
5014   %}
5015 %}
5016 
5017 operand indOffI(iRegP reg, immIOffset off)
5018 %{
5019   constraint(ALLOC_IN_RC(ptr_reg));
5020   match(AddP reg off);
5021   op_cost(0);
5022   format %{ "[$reg, $off]" %}
5023   interface(MEMORY_INTER) %{
5024     base($reg);
5025     index(0xffffffff);
5026     scale(0x0);
5027     disp($off);
5028   %}
5029 %}
5030 
5031 operand indOffI4(iRegP reg, immIOffset4 off)
5032 %{
5033   constraint(ALLOC_IN_RC(ptr_reg));
5034   match(AddP reg off);
5035   op_cost(0);
5036   format %{ "[$reg, $off]" %}
5037   interface(MEMORY_INTER) %{
5038     base($reg);
5039     index(0xffffffff);
5040     scale(0x0);
5041     disp($off);
5042   %}
5043 %}
5044 
5045 operand indOffI8(iRegP reg, immIOffset8 off)
5046 %{
5047   constraint(ALLOC_IN_RC(ptr_reg));
5048   match(AddP reg off);
5049   op_cost(0);
5050   format %{ "[$reg, $off]" %}
5051   interface(MEMORY_INTER) %{
5052     base($reg);
5053     index(0xffffffff);
5054     scale(0x0);
5055     disp($off);
5056   %}
5057 %}
5058 
5059 operand indOffI16(iRegP reg, immIOffset16 off)
5060 %{
5061   constraint(ALLOC_IN_RC(ptr_reg));
5062   match(AddP reg off);
5063   op_cost(0);
5064   format %{ "[$reg, $off]" %}
5065   interface(MEMORY_INTER) %{
5066     base($reg);
5067     index(0xffffffff);
5068     scale(0x0);
5069     disp($off);
5070   %}
5071 %}
5072 
5073 operand indOffL(iRegP reg, immLoffset off)
5074 %{
5075   constraint(ALLOC_IN_RC(ptr_reg));
5076   match(AddP reg off);
5077   op_cost(0);
5078   format %{ "[$reg, $off]" %}
5079   interface(MEMORY_INTER) %{
5080     base($reg);
5081     index(0xffffffff);
5082     scale(0x0);
5083     disp($off);
5084   %}
5085 %}
5086 
5087 operand indOffL4(iRegP reg, immLoffset4 off)
5088 %{
5089   constraint(ALLOC_IN_RC(ptr_reg));
5090   match(AddP reg off);
5091   op_cost(0);
5092   format %{ "[$reg, $off]" %}
5093   interface(MEMORY_INTER) %{
5094     base($reg);
5095     index(0xffffffff);
5096     scale(0x0);
5097     disp($off);
5098   %}
5099 %}
5100 
5101 operand indOffL8(iRegP reg, immLoffset8 off)
5102 %{
5103   constraint(ALLOC_IN_RC(ptr_reg));
5104   match(AddP reg off);
5105   op_cost(0);
5106   format %{ "[$reg, $off]" %}
5107   interface(MEMORY_INTER) %{
5108     base($reg);
5109     index(0xffffffff);
5110     scale(0x0);
5111     disp($off);
5112   %}
5113 %}
5114 
5115 operand indOffL16(iRegP reg, immLoffset16 off)
5116 %{
5117   constraint(ALLOC_IN_RC(ptr_reg));
5118   match(AddP reg off);
5119   op_cost(0);
5120   format %{ "[$reg, $off]" %}
5121   interface(MEMORY_INTER) %{
5122     base($reg);
5123     index(0xffffffff);
5124     scale(0x0);
5125     disp($off);
5126   %}
5127 %}
5128 
5129 operand indirectN(iRegN reg)
5130 %{
5131   predicate(Universe::narrow_oop_shift() == 0);
5132   constraint(ALLOC_IN_RC(ptr_reg));
5133   match(DecodeN reg);
5134   op_cost(0);
5135   format %{ "[$reg]\t# narrow" %}
5136   interface(MEMORY_INTER) %{
5137     base($reg);
5138     index(0xffffffff);
5139     scale(0x0);
5140     disp(0x0);
5141   %}
5142 %}
5143 
5144 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale)
5145 %{
5146   predicate(Universe::narrow_oop_shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
5147   constraint(ALLOC_IN_RC(ptr_reg));
5148   match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale));
5149   op_cost(0);
5150   format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %}
5151   interface(MEMORY_INTER) %{
5152     base($reg);
5153     index($ireg);
5154     scale($scale);
5155     disp(0x0);
5156   %}
5157 %}
5158 
5159 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale)
5160 %{
5161   predicate(Universe::narrow_oop_shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
5162   constraint(ALLOC_IN_RC(ptr_reg));
5163   match(AddP (DecodeN reg) (LShiftL lreg scale));
5164   op_cost(0);
5165   format %{ "$reg, $lreg lsl($scale)\t# narrow" %}
5166   interface(MEMORY_INTER) %{
5167     base($reg);
5168     index($lreg);
5169     scale($scale);
5170     disp(0x0);
5171   %}
5172 %}
5173 
5174 operand indIndexI2LN(iRegN reg, iRegI ireg)
5175 %{
5176   predicate(Universe::narrow_oop_shift() == 0);
5177   constraint(ALLOC_IN_RC(ptr_reg));
5178   match(AddP (DecodeN reg) (ConvI2L ireg));
5179   op_cost(0);
5180   format %{ "$reg, $ireg, 0, I2L\t# narrow" %}
5181   interface(MEMORY_INTER) %{
5182     base($reg);
5183     index($ireg);
5184     scale(0x0);
5185     disp(0x0);
5186   %}
5187 %}
5188 
5189 operand indIndexN(iRegN reg, iRegL lreg)
5190 %{
5191   predicate(Universe::narrow_oop_shift() == 0);
5192   constraint(ALLOC_IN_RC(ptr_reg));
5193   match(AddP (DecodeN reg) lreg);
5194   op_cost(0);
5195   format %{ "$reg, $lreg\t# narrow" %}
5196   interface(MEMORY_INTER) %{
5197     base($reg);
5198     index($lreg);
5199     scale(0x0);
5200     disp(0x0);
5201   %}
5202 %}
5203 
5204 operand indOffIN(iRegN reg, immIOffset off)
5205 %{
5206   predicate(Universe::narrow_oop_shift() == 0);
5207   constraint(ALLOC_IN_RC(ptr_reg));
5208   match(AddP (DecodeN reg) off);
5209   op_cost(0);
5210   format %{ "[$reg, $off]\t# narrow" %}
5211   interface(MEMORY_INTER) %{
5212     base($reg);
5213     index(0xffffffff);
5214     scale(0x0);
5215     disp($off);
5216   %}
5217 %}
5218 
5219 operand indOffLN(iRegN reg, immLoffset off)
5220 %{
5221   predicate(Universe::narrow_oop_shift() == 0);
5222   constraint(ALLOC_IN_RC(ptr_reg));
5223   match(AddP (DecodeN reg) off);
5224   op_cost(0);
5225   format %{ "[$reg, $off]\t# narrow" %}
5226   interface(MEMORY_INTER) %{
5227     base($reg);
5228     index(0xffffffff);
5229     scale(0x0);
5230     disp($off);
5231   %}
5232 %}
5233 
5234 
5235 
5236 // AArch64 opto stubs need to write to the pc slot in the thread anchor
5237 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off)
5238 %{
5239   constraint(ALLOC_IN_RC(ptr_reg));
5240   match(AddP reg off);
5241   op_cost(0);
5242   format %{ "[$reg, $off]" %}
5243   interface(MEMORY_INTER) %{
5244     base($reg);
5245     index(0xffffffff);
5246     scale(0x0);
5247     disp($off);
5248   %}
5249 %}
5250 
5251 //----------Special Memory Operands--------------------------------------------
5252 // Stack Slot Operand - This operand is used for loading and storing temporary
5253 //                      values on the stack where a match requires a value to
5254 //                      flow through memory.
5255 operand stackSlotP(sRegP reg)
5256 %{
5257   constraint(ALLOC_IN_RC(stack_slots));
5258   op_cost(100);
5259   // No match rule because this operand is only generated in matching
5260   // match(RegP);
5261   format %{ "[$reg]" %}
5262   interface(MEMORY_INTER) %{
5263     base(0x1e);  // RSP
5264     index(0x0);  // No Index
5265     scale(0x0);  // No Scale
5266     disp($reg);  // Stack Offset
5267   %}
5268 %}
5269 
5270 operand stackSlotI(sRegI reg)
5271 %{
5272   constraint(ALLOC_IN_RC(stack_slots));
5273   // No match rule because this operand is only generated in matching
5274   // match(RegI);
5275   format %{ "[$reg]" %}
5276   interface(MEMORY_INTER) %{
5277     base(0x1e);  // RSP
5278     index(0x0);  // No Index
5279     scale(0x0);  // No Scale
5280     disp($reg);  // Stack Offset
5281   %}
5282 %}
5283 
5284 operand stackSlotF(sRegF reg)
5285 %{
5286   constraint(ALLOC_IN_RC(stack_slots));
5287   // No match rule because this operand is only generated in matching
5288   // match(RegF);
5289   format %{ "[$reg]" %}
5290   interface(MEMORY_INTER) %{
5291     base(0x1e);  // RSP
5292     index(0x0);  // No Index
5293     scale(0x0);  // No Scale
5294     disp($reg);  // Stack Offset
5295   %}
5296 %}
5297 
5298 operand stackSlotD(sRegD reg)
5299 %{
5300   constraint(ALLOC_IN_RC(stack_slots));
5301   // No match rule because this operand is only generated in matching
5302   // match(RegD);
5303   format %{ "[$reg]" %}
5304   interface(MEMORY_INTER) %{
5305     base(0x1e);  // RSP
5306     index(0x0);  // No Index
5307     scale(0x0);  // No Scale
5308     disp($reg);  // Stack Offset
5309   %}
5310 %}
5311 
5312 operand stackSlotL(sRegL reg)
5313 %{
5314   constraint(ALLOC_IN_RC(stack_slots));
5315   // No match rule because this operand is only generated in matching
5316   // match(RegL);
5317   format %{ "[$reg]" %}
5318   interface(MEMORY_INTER) %{
5319     base(0x1e);  // RSP
5320     index(0x0);  // No Index
5321     scale(0x0);  // No Scale
5322     disp($reg);  // Stack Offset
5323   %}
5324 %}
5325 
5326 // Operands for expressing Control Flow
5327 // NOTE: Label is a predefined operand which should not be redefined in
5328 //       the AD file. It is generically handled within the ADLC.
5329 
5330 //----------Conditional Branch Operands----------------------------------------
5331 // Comparison Op  - This is the operation of the comparison, and is limited to
5332 //                  the following set of codes:
5333 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
5334 //
5335 // Other attributes of the comparison, such as unsignedness, are specified
5336 // by the comparison instruction that sets a condition code flags register.
5337 // That result is represented by a flags operand whose subtype is appropriate
5338 // to the unsignedness (etc.) of the comparison.
5339 //
5340 // Later, the instruction which matches both the Comparison Op (a Bool) and
5341 // the flags (produced by the Cmp) specifies the coding of the comparison op
5342 // by matching a specific subtype of Bool operand below, such as cmpOpU.
5343 
5344 // used for signed integral comparisons and fp comparisons
5345 
5346 operand cmpOp()
5347 %{
5348   match(Bool);
5349 
5350   format %{ "" %}
5351   interface(COND_INTER) %{
5352     equal(0x0, "eq");
5353     not_equal(0x1, "ne");
5354     less(0xb, "lt");
5355     greater_equal(0xa, "ge");
5356     less_equal(0xd, "le");
5357     greater(0xc, "gt");
5358     overflow(0x6, "vs");
5359     no_overflow(0x7, "vc");
5360   %}
5361 %}
5362 
5363 // used for unsigned integral comparisons
5364 
5365 operand cmpOpU()
5366 %{
5367   match(Bool);
5368 
5369   format %{ "" %}
5370   interface(COND_INTER) %{
5371     equal(0x0, "eq");
5372     not_equal(0x1, "ne");
5373     less(0x3, "lo");
5374     greater_equal(0x2, "hs");
5375     less_equal(0x9, "ls");
5376     greater(0x8, "hi");
5377     overflow(0x6, "vs");
5378     no_overflow(0x7, "vc");
5379   %}
5380 %}
5381 
5382 // used for certain integral comparisons which can be
5383 // converted to cbxx or tbxx instructions
5384 
5385 operand cmpOpEqNe()
5386 %{
5387   match(Bool);
5388   match(CmpOp);
5389   op_cost(0);
5390   predicate(n->as_Bool()->_test._test == BoolTest::ne
5391             || n->as_Bool()->_test._test == BoolTest::eq);
5392 
5393   format %{ "" %}
5394   interface(COND_INTER) %{
5395     equal(0x0, "eq");
5396     not_equal(0x1, "ne");
5397     less(0xb, "lt");
5398     greater_equal(0xa, "ge");
5399     less_equal(0xd, "le");
5400     greater(0xc, "gt");
5401     overflow(0x6, "vs");
5402     no_overflow(0x7, "vc");
5403   %}
5404 %}
5405 
5406 // used for certain integral comparisons which can be
5407 // converted to cbxx or tbxx instructions
5408 
5409 operand cmpOpLtGe()
5410 %{
5411   match(Bool);
5412   match(CmpOp);
5413   op_cost(0);
5414 
5415   predicate(n->as_Bool()->_test._test == BoolTest::lt
5416             || n->as_Bool()->_test._test == BoolTest::ge);
5417 
5418   format %{ "" %}
5419   interface(COND_INTER) %{
5420     equal(0x0, "eq");
5421     not_equal(0x1, "ne");
5422     less(0xb, "lt");
5423     greater_equal(0xa, "ge");
5424     less_equal(0xd, "le");
5425     greater(0xc, "gt");
5426     overflow(0x6, "vs");
5427     no_overflow(0x7, "vc");
5428   %}
5429 %}
5430 
5431 // used for certain unsigned integral comparisons which can be
5432 // converted to cbxx or tbxx instructions
5433 
5434 operand cmpOpUEqNeLtGe()
5435 %{
5436   match(Bool);
5437   match(CmpOp);
5438   op_cost(0);
5439 
5440   predicate(n->as_Bool()->_test._test == BoolTest::eq
5441             || n->as_Bool()->_test._test == BoolTest::ne
5442             || n->as_Bool()->_test._test == BoolTest::lt
5443             || n->as_Bool()->_test._test == BoolTest::ge);
5444 
5445   format %{ "" %}
5446   interface(COND_INTER) %{
5447     equal(0x0, "eq");
5448     not_equal(0x1, "ne");
5449     less(0xb, "lt");
5450     greater_equal(0xa, "ge");
5451     less_equal(0xd, "le");
5452     greater(0xc, "gt");
5453     overflow(0x6, "vs");
5454     no_overflow(0x7, "vc");
5455   %}
5456 %}
5457 
5458 // Special operand allowing long args to int ops to be truncated for free
5459 
5460 operand iRegL2I(iRegL reg) %{
5461 
5462   op_cost(0);
5463 
5464   match(ConvL2I reg);
5465 
5466   format %{ "l2i($reg)" %}
5467 
5468   interface(REG_INTER)
5469 %}
5470 
5471 opclass vmem4(indirect, indIndex, indOffI4, indOffL4);
5472 opclass vmem8(indirect, indIndex, indOffI8, indOffL8);
5473 opclass vmem16(indirect, indIndex, indOffI16, indOffL16);
5474 
5475 //----------OPERAND CLASSES----------------------------------------------------
5476 // Operand Classes are groups of operands that are used as to simplify
5477 // instruction definitions by not requiring the AD writer to specify
5478 // separate instructions for every form of operand when the
5479 // instruction accepts multiple operand types with the same basic
5480 // encoding and format. The classic case of this is memory operands.
5481 
5482 // memory is used to define read/write location for load/store
5483 // instruction defs. we can turn a memory op into an Address
5484 
5485 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI, indOffL,
5486                indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN);
5487 
5488 // iRegIorL2I is used for src inputs in rules for 32 bit int (I)
5489 // operations. it allows the src to be either an iRegI or a (ConvL2I
5490 // iRegL). in the latter case the l2i normally planted for a ConvL2I
5491 // can be elided because the 32-bit instruction will just employ the
5492 // lower 32 bits anyway.
5493 //
5494 // n.b. this does not elide all L2I conversions. if the truncated
5495 // value is consumed by more than one operation then the ConvL2I
5496 // cannot be bundled into the consuming nodes so an l2i gets planted
5497 // (actually a movw $dst $src) and the downstream instructions consume
5498 // the result of the l2i as an iRegI input. That's a shame since the
5499 // movw is actually redundant but its not too costly.
5500 
5501 opclass iRegIorL2I(iRegI, iRegL2I);
5502 
5503 //----------PIPELINE-----------------------------------------------------------
5504 // Rules which define the behavior of the target architectures pipeline.
5505 
5506 // For specific pipelines, eg A53, define the stages of that pipeline
5507 //pipe_desc(ISS, EX1, EX2, WR);
5508 #define ISS S0
5509 #define EX1 S1
5510 #define EX2 S2
5511 #define WR  S3
5512 
5513 // Integer ALU reg operation
5514 pipeline %{
5515 
5516 attributes %{
5517   // ARM instructions are of fixed length
5518   fixed_size_instructions;        // Fixed size instructions TODO does
5519   max_instructions_per_bundle = 2;   // A53 = 2, A57 = 4
5520   // ARM instructions come in 32-bit word units
5521   instruction_unit_size = 4;         // An instruction is 4 bytes long
5522   instruction_fetch_unit_size = 64;  // The processor fetches one line
5523   instruction_fetch_units = 1;       // of 64 bytes
5524 
5525   // List of nop instructions
5526   nops( MachNop );
5527 %}
5528 
5529 // We don't use an actual pipeline model so don't care about resources
5530 // or description. we do use pipeline classes to introduce fixed
5531 // latencies
5532 
5533 //----------RESOURCES----------------------------------------------------------
5534 // Resources are the functional units available to the machine
5535 
5536 resources( INS0, INS1, INS01 = INS0 | INS1,
5537            ALU0, ALU1, ALU = ALU0 | ALU1,
5538            MAC,
5539            DIV,
5540            BRANCH,
5541            LDST,
5542            NEON_FP);
5543 
5544 //----------PIPELINE DESCRIPTION-----------------------------------------------
5545 // Pipeline Description specifies the stages in the machine's pipeline
5546 
5547 // Define the pipeline as a generic 6 stage pipeline
5548 pipe_desc(S0, S1, S2, S3, S4, S5);
5549 
5550 //----------PIPELINE CLASSES---------------------------------------------------
5551 // Pipeline Classes describe the stages in which input and output are
5552 // referenced by the hardware pipeline.
5553 
5554 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2)
5555 %{
5556   single_instruction;
5557   src1   : S1(read);
5558   src2   : S2(read);
5559   dst    : S5(write);
5560   INS01  : ISS;
5561   NEON_FP : S5;
5562 %}
5563 
5564 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2)
5565 %{
5566   single_instruction;
5567   src1   : S1(read);
5568   src2   : S2(read);
5569   dst    : S5(write);
5570   INS01  : ISS;
5571   NEON_FP : S5;
5572 %}
5573 
5574 pipe_class fp_uop_s(vRegF dst, vRegF src)
5575 %{
5576   single_instruction;
5577   src    : S1(read);
5578   dst    : S5(write);
5579   INS01  : ISS;
5580   NEON_FP : S5;
5581 %}
5582 
5583 pipe_class fp_uop_d(vRegD dst, vRegD src)
5584 %{
5585   single_instruction;
5586   src    : S1(read);
5587   dst    : S5(write);
5588   INS01  : ISS;
5589   NEON_FP : S5;
5590 %}
5591 
5592 pipe_class fp_d2f(vRegF dst, vRegD src)
5593 %{
5594   single_instruction;
5595   src    : S1(read);
5596   dst    : S5(write);
5597   INS01  : ISS;
5598   NEON_FP : S5;
5599 %}
5600 
5601 pipe_class fp_f2d(vRegD dst, vRegF src)
5602 %{
5603   single_instruction;
5604   src    : S1(read);
5605   dst    : S5(write);
5606   INS01  : ISS;
5607   NEON_FP : S5;
5608 %}
5609 
5610 pipe_class fp_f2i(iRegINoSp dst, vRegF src)
5611 %{
5612   single_instruction;
5613   src    : S1(read);
5614   dst    : S5(write);
5615   INS01  : ISS;
5616   NEON_FP : S5;
5617 %}
5618 
5619 pipe_class fp_f2l(iRegLNoSp dst, vRegF src)
5620 %{
5621   single_instruction;
5622   src    : S1(read);
5623   dst    : S5(write);
5624   INS01  : ISS;
5625   NEON_FP : S5;
5626 %}
5627 
5628 pipe_class fp_i2f(vRegF dst, iRegIorL2I src)
5629 %{
5630   single_instruction;
5631   src    : S1(read);
5632   dst    : S5(write);
5633   INS01  : ISS;
5634   NEON_FP : S5;
5635 %}
5636 
5637 pipe_class fp_l2f(vRegF dst, iRegL src)
5638 %{
5639   single_instruction;
5640   src    : S1(read);
5641   dst    : S5(write);
5642   INS01  : ISS;
5643   NEON_FP : S5;
5644 %}
5645 
5646 pipe_class fp_d2i(iRegINoSp dst, vRegD src)
5647 %{
5648   single_instruction;
5649   src    : S1(read);
5650   dst    : S5(write);
5651   INS01  : ISS;
5652   NEON_FP : S5;
5653 %}
5654 
5655 pipe_class fp_d2l(iRegLNoSp dst, vRegD src)
5656 %{
5657   single_instruction;
5658   src    : S1(read);
5659   dst    : S5(write);
5660   INS01  : ISS;
5661   NEON_FP : S5;
5662 %}
5663 
5664 pipe_class fp_i2d(vRegD dst, iRegIorL2I src)
5665 %{
5666   single_instruction;
5667   src    : S1(read);
5668   dst    : S5(write);
5669   INS01  : ISS;
5670   NEON_FP : S5;
5671 %}
5672 
5673 pipe_class fp_l2d(vRegD dst, iRegIorL2I src)
5674 %{
5675   single_instruction;
5676   src    : S1(read);
5677   dst    : S5(write);
5678   INS01  : ISS;
5679   NEON_FP : S5;
5680 %}
5681 
5682 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2)
5683 %{
5684   single_instruction;
5685   src1   : S1(read);
5686   src2   : S2(read);
5687   dst    : S5(write);
5688   INS0   : ISS;
5689   NEON_FP : S5;
5690 %}
5691 
5692 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2)
5693 %{
5694   single_instruction;
5695   src1   : S1(read);
5696   src2   : S2(read);
5697   dst    : S5(write);
5698   INS0   : ISS;
5699   NEON_FP : S5;
5700 %}
5701 
5702 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr)
5703 %{
5704   single_instruction;
5705   cr     : S1(read);
5706   src1   : S1(read);
5707   src2   : S1(read);
5708   dst    : S3(write);
5709   INS01  : ISS;
5710   NEON_FP : S3;
5711 %}
5712 
5713 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr)
5714 %{
5715   single_instruction;
5716   cr     : S1(read);
5717   src1   : S1(read);
5718   src2   : S1(read);
5719   dst    : S3(write);
5720   INS01  : ISS;
5721   NEON_FP : S3;
5722 %}
5723 
5724 pipe_class fp_imm_s(vRegF dst)
5725 %{
5726   single_instruction;
5727   dst    : S3(write);
5728   INS01  : ISS;
5729   NEON_FP : S3;
5730 %}
5731 
5732 pipe_class fp_imm_d(vRegD dst)
5733 %{
5734   single_instruction;
5735   dst    : S3(write);
5736   INS01  : ISS;
5737   NEON_FP : S3;
5738 %}
5739 
5740 pipe_class fp_load_constant_s(vRegF dst)
5741 %{
5742   single_instruction;
5743   dst    : S4(write);
5744   INS01  : ISS;
5745   NEON_FP : S4;
5746 %}
5747 
5748 pipe_class fp_load_constant_d(vRegD dst)
5749 %{
5750   single_instruction;
5751   dst    : S4(write);
5752   INS01  : ISS;
5753   NEON_FP : S4;
5754 %}
5755 
5756 pipe_class vmul64(vecD dst, vecD src1, vecD src2)
5757 %{
5758   single_instruction;
5759   dst    : S5(write);
5760   src1   : S1(read);
5761   src2   : S1(read);
5762   INS01  : ISS;
5763   NEON_FP : S5;
5764 %}
5765 
5766 pipe_class vmul128(vecX dst, vecX src1, vecX src2)
5767 %{
5768   single_instruction;
5769   dst    : S5(write);
5770   src1   : S1(read);
5771   src2   : S1(read);
5772   INS0   : ISS;
5773   NEON_FP : S5;
5774 %}
5775 
5776 pipe_class vmla64(vecD dst, vecD src1, vecD src2)
5777 %{
5778   single_instruction;
5779   dst    : S5(write);
5780   src1   : S1(read);
5781   src2   : S1(read);
5782   dst    : S1(read);
5783   INS01  : ISS;
5784   NEON_FP : S5;
5785 %}
5786 
5787 pipe_class vmla128(vecX dst, vecX src1, vecX src2)
5788 %{
5789   single_instruction;
5790   dst    : S5(write);
5791   src1   : S1(read);
5792   src2   : S1(read);
5793   dst    : S1(read);
5794   INS0   : ISS;
5795   NEON_FP : S5;
5796 %}
5797 
5798 pipe_class vdop64(vecD dst, vecD src1, vecD src2)
5799 %{
5800   single_instruction;
5801   dst    : S4(write);
5802   src1   : S2(read);
5803   src2   : S2(read);
5804   INS01  : ISS;
5805   NEON_FP : S4;
5806 %}
5807 
5808 pipe_class vdop128(vecX dst, vecX src1, vecX src2)
5809 %{
5810   single_instruction;
5811   dst    : S4(write);
5812   src1   : S2(read);
5813   src2   : S2(read);
5814   INS0   : ISS;
5815   NEON_FP : S4;
5816 %}
5817 
5818 pipe_class vlogical64(vecD dst, vecD src1, vecD src2)
5819 %{
5820   single_instruction;
5821   dst    : S3(write);
5822   src1   : S2(read);
5823   src2   : S2(read);
5824   INS01  : ISS;
5825   NEON_FP : S3;
5826 %}
5827 
5828 pipe_class vlogical128(vecX dst, vecX src1, vecX src2)
5829 %{
5830   single_instruction;
5831   dst    : S3(write);
5832   src1   : S2(read);
5833   src2   : S2(read);
5834   INS0   : ISS;
5835   NEON_FP : S3;
5836 %}
5837 
5838 pipe_class vshift64(vecD dst, vecD src, vecX shift)
5839 %{
5840   single_instruction;
5841   dst    : S3(write);
5842   src    : S1(read);
5843   shift  : S1(read);
5844   INS01  : ISS;
5845   NEON_FP : S3;
5846 %}
5847 
5848 pipe_class vshift128(vecX dst, vecX src, vecX shift)
5849 %{
5850   single_instruction;
5851   dst    : S3(write);
5852   src    : S1(read);
5853   shift  : S1(read);
5854   INS0   : ISS;
5855   NEON_FP : S3;
5856 %}
5857 
5858 pipe_class vshift64_imm(vecD dst, vecD src, immI shift)
5859 %{
5860   single_instruction;
5861   dst    : S3(write);
5862   src    : S1(read);
5863   INS01  : ISS;
5864   NEON_FP : S3;
5865 %}
5866 
5867 pipe_class vshift128_imm(vecX dst, vecX src, immI shift)
5868 %{
5869   single_instruction;
5870   dst    : S3(write);
5871   src    : S1(read);
5872   INS0   : ISS;
5873   NEON_FP : S3;
5874 %}
5875 
5876 pipe_class vdop_fp64(vecD dst, vecD src1, vecD src2)
5877 %{
5878   single_instruction;
5879   dst    : S5(write);
5880   src1   : S1(read);
5881   src2   : S1(read);
5882   INS01  : ISS;
5883   NEON_FP : S5;
5884 %}
5885 
5886 pipe_class vdop_fp128(vecX dst, vecX src1, vecX src2)
5887 %{
5888   single_instruction;
5889   dst    : S5(write);
5890   src1   : S1(read);
5891   src2   : S1(read);
5892   INS0   : ISS;
5893   NEON_FP : S5;
5894 %}
5895 
5896 pipe_class vmuldiv_fp64(vecD dst, vecD src1, vecD src2)
5897 %{
5898   single_instruction;
5899   dst    : S5(write);
5900   src1   : S1(read);
5901   src2   : S1(read);
5902   INS0   : ISS;
5903   NEON_FP : S5;
5904 %}
5905 
5906 pipe_class vmuldiv_fp128(vecX dst, vecX src1, vecX src2)
5907 %{
5908   single_instruction;
5909   dst    : S5(write);
5910   src1   : S1(read);
5911   src2   : S1(read);
5912   INS0   : ISS;
5913   NEON_FP : S5;
5914 %}
5915 
5916 pipe_class vsqrt_fp128(vecX dst, vecX src)
5917 %{
5918   single_instruction;
5919   dst    : S5(write);
5920   src    : S1(read);
5921   INS0   : ISS;
5922   NEON_FP : S5;
5923 %}
5924 
5925 pipe_class vunop_fp64(vecD dst, vecD src)
5926 %{
5927   single_instruction;
5928   dst    : S5(write);
5929   src    : S1(read);
5930   INS01  : ISS;
5931   NEON_FP : S5;
5932 %}
5933 
5934 pipe_class vunop_fp128(vecX dst, vecX src)
5935 %{
5936   single_instruction;
5937   dst    : S5(write);
5938   src    : S1(read);
5939   INS0   : ISS;
5940   NEON_FP : S5;
5941 %}
5942 
5943 pipe_class vdup_reg_reg64(vecD dst, iRegI src)
5944 %{
5945   single_instruction;
5946   dst    : S3(write);
5947   src    : S1(read);
5948   INS01  : ISS;
5949   NEON_FP : S3;
5950 %}
5951 
5952 pipe_class vdup_reg_reg128(vecX dst, iRegI src)
5953 %{
5954   single_instruction;
5955   dst    : S3(write);
5956   src    : S1(read);
5957   INS01  : ISS;
5958   NEON_FP : S3;
5959 %}
5960 
5961 pipe_class vdup_reg_freg64(vecD dst, vRegF src)
5962 %{
5963   single_instruction;
5964   dst    : S3(write);
5965   src    : S1(read);
5966   INS01  : ISS;
5967   NEON_FP : S3;
5968 %}
5969 
5970 pipe_class vdup_reg_freg128(vecX dst, vRegF src)
5971 %{
5972   single_instruction;
5973   dst    : S3(write);
5974   src    : S1(read);
5975   INS01  : ISS;
5976   NEON_FP : S3;
5977 %}
5978 
5979 pipe_class vdup_reg_dreg128(vecX dst, vRegD src)
5980 %{
5981   single_instruction;
5982   dst    : S3(write);
5983   src    : S1(read);
5984   INS01  : ISS;
5985   NEON_FP : S3;
5986 %}
5987 
5988 pipe_class vmovi_reg_imm64(vecD dst)
5989 %{
5990   single_instruction;
5991   dst    : S3(write);
5992   INS01  : ISS;
5993   NEON_FP : S3;
5994 %}
5995 
5996 pipe_class vmovi_reg_imm128(vecX dst)
5997 %{
5998   single_instruction;
5999   dst    : S3(write);
6000   INS0   : ISS;
6001   NEON_FP : S3;
6002 %}
6003 
6004 pipe_class vload_reg_mem64(vecD dst, vmem8 mem)
6005 %{
6006   single_instruction;
6007   dst    : S5(write);
6008   mem    : ISS(read);
6009   INS01  : ISS;
6010   NEON_FP : S3;
6011 %}
6012 
6013 pipe_class vload_reg_mem128(vecX dst, vmem16 mem)
6014 %{
6015   single_instruction;
6016   dst    : S5(write);
6017   mem    : ISS(read);
6018   INS01  : ISS;
6019   NEON_FP : S3;
6020 %}
6021 
6022 pipe_class vstore_reg_mem64(vecD src, vmem8 mem)
6023 %{
6024   single_instruction;
6025   mem    : ISS(read);
6026   src    : S2(read);
6027   INS01  : ISS;
6028   NEON_FP : S3;
6029 %}
6030 
6031 pipe_class vstore_reg_mem128(vecD src, vmem16 mem)
6032 %{
6033   single_instruction;
6034   mem    : ISS(read);
6035   src    : S2(read);
6036   INS01  : ISS;
6037   NEON_FP : S3;
6038 %}
6039 
6040 //------- Integer ALU operations --------------------------
6041 
6042 // Integer ALU reg-reg operation
6043 // Operands needed in EX1, result generated in EX2
6044 // Eg.  ADD     x0, x1, x2
6045 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6046 %{
6047   single_instruction;
6048   dst    : EX2(write);
6049   src1   : EX1(read);
6050   src2   : EX1(read);
6051   INS01  : ISS; // Dual issue as instruction 0 or 1
6052   ALU    : EX2;
6053 %}
6054 
6055 // Integer ALU reg-reg operation with constant shift
6056 // Shifted register must be available in LATE_ISS instead of EX1
6057 // Eg.  ADD     x0, x1, x2, LSL #2
6058 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift)
6059 %{
6060   single_instruction;
6061   dst    : EX2(write);
6062   src1   : EX1(read);
6063   src2   : ISS(read);
6064   INS01  : ISS;
6065   ALU    : EX2;
6066 %}
6067 
6068 // Integer ALU reg operation with constant shift
6069 // Eg.  LSL     x0, x1, #shift
6070 pipe_class ialu_reg_shift(iRegI dst, iRegI src1)
6071 %{
6072   single_instruction;
6073   dst    : EX2(write);
6074   src1   : ISS(read);
6075   INS01  : ISS;
6076   ALU    : EX2;
6077 %}
6078 
6079 // Integer ALU reg-reg operation with variable shift
6080 // Both operands must be available in LATE_ISS instead of EX1
6081 // Result is available in EX1 instead of EX2
6082 // Eg.  LSLV    x0, x1, x2
6083 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2)
6084 %{
6085   single_instruction;
6086   dst    : EX1(write);
6087   src1   : ISS(read);
6088   src2   : ISS(read);
6089   INS01  : ISS;
6090   ALU    : EX1;
6091 %}
6092 
6093 // Integer ALU reg-reg operation with extract
6094 // As for _vshift above, but result generated in EX2
6095 // Eg.  EXTR    x0, x1, x2, #N
6096 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2)
6097 %{
6098   single_instruction;
6099   dst    : EX2(write);
6100   src1   : ISS(read);
6101   src2   : ISS(read);
6102   INS1   : ISS; // Can only dual issue as Instruction 1
6103   ALU    : EX1;
6104 %}
6105 
6106 // Integer ALU reg operation
6107 // Eg.  NEG     x0, x1
6108 pipe_class ialu_reg(iRegI dst, iRegI src)
6109 %{
6110   single_instruction;
6111   dst    : EX2(write);
6112   src    : EX1(read);
6113   INS01  : ISS;
6114   ALU    : EX2;
6115 %}
6116 
6117 // Integer ALU reg mmediate operation
6118 // Eg.  ADD     x0, x1, #N
6119 pipe_class ialu_reg_imm(iRegI dst, iRegI src1)
6120 %{
6121   single_instruction;
6122   dst    : EX2(write);
6123   src1   : EX1(read);
6124   INS01  : ISS;
6125   ALU    : EX2;
6126 %}
6127 
6128 // Integer ALU immediate operation (no source operands)
6129 // Eg.  MOV     x0, #N
6130 pipe_class ialu_imm(iRegI dst)
6131 %{
6132   single_instruction;
6133   dst    : EX1(write);
6134   INS01  : ISS;
6135   ALU    : EX1;
6136 %}
6137 
6138 //------- Compare operation -------------------------------
6139 
6140 // Compare reg-reg
6141 // Eg.  CMP     x0, x1
6142 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2)
6143 %{
6144   single_instruction;
6145 //  fixed_latency(16);
6146   cr     : EX2(write);
6147   op1    : EX1(read);
6148   op2    : EX1(read);
6149   INS01  : ISS;
6150   ALU    : EX2;
6151 %}
6152 
6153 // Compare reg-reg
6154 // Eg.  CMP     x0, #N
6155 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1)
6156 %{
6157   single_instruction;
6158 //  fixed_latency(16);
6159   cr     : EX2(write);
6160   op1    : EX1(read);
6161   INS01  : ISS;
6162   ALU    : EX2;
6163 %}
6164 
6165 //------- Conditional instructions ------------------------
6166 
6167 // Conditional no operands
6168 // Eg.  CSINC   x0, zr, zr, <cond>
6169 pipe_class icond_none(iRegI dst, rFlagsReg cr)
6170 %{
6171   single_instruction;
6172   cr     : EX1(read);
6173   dst    : EX2(write);
6174   INS01  : ISS;
6175   ALU    : EX2;
6176 %}
6177 
6178 // Conditional 2 operand
6179 // EG.  CSEL    X0, X1, X2, <cond>
6180 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr)
6181 %{
6182   single_instruction;
6183   cr     : EX1(read);
6184   src1   : EX1(read);
6185   src2   : EX1(read);
6186   dst    : EX2(write);
6187   INS01  : ISS;
6188   ALU    : EX2;
6189 %}
6190 
6191 // Conditional 2 operand
6192 // EG.  CSEL    X0, X1, X2, <cond>
6193 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr)
6194 %{
6195   single_instruction;
6196   cr     : EX1(read);
6197   src    : EX1(read);
6198   dst    : EX2(write);
6199   INS01  : ISS;
6200   ALU    : EX2;
6201 %}
6202 
6203 //------- Multiply pipeline operations --------------------
6204 
6205 // Multiply reg-reg
6206 // Eg.  MUL     w0, w1, w2
6207 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6208 %{
6209   single_instruction;
6210   dst    : WR(write);
6211   src1   : ISS(read);
6212   src2   : ISS(read);
6213   INS01  : ISS;
6214   MAC    : WR;
6215 %}
6216 
6217 // Multiply accumulate
6218 // Eg.  MADD    w0, w1, w2, w3
6219 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3)
6220 %{
6221   single_instruction;
6222   dst    : WR(write);
6223   src1   : ISS(read);
6224   src2   : ISS(read);
6225   src3   : ISS(read);
6226   INS01  : ISS;
6227   MAC    : WR;
6228 %}
6229 
6230 // Eg.  MUL     w0, w1, w2
6231 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6232 %{
6233   single_instruction;
6234   fixed_latency(3); // Maximum latency for 64 bit mul
6235   dst    : WR(write);
6236   src1   : ISS(read);
6237   src2   : ISS(read);
6238   INS01  : ISS;
6239   MAC    : WR;
6240 %}
6241 
6242 // Multiply accumulate
6243 // Eg.  MADD    w0, w1, w2, w3
6244 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3)
6245 %{
6246   single_instruction;
6247   fixed_latency(3); // Maximum latency for 64 bit mul
6248   dst    : WR(write);
6249   src1   : ISS(read);
6250   src2   : ISS(read);
6251   src3   : ISS(read);
6252   INS01  : ISS;
6253   MAC    : WR;
6254 %}
6255 
6256 //------- Divide pipeline operations --------------------
6257 
6258 // Eg.  SDIV    w0, w1, w2
6259 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6260 %{
6261   single_instruction;
6262   fixed_latency(8); // Maximum latency for 32 bit divide
6263   dst    : WR(write);
6264   src1   : ISS(read);
6265   src2   : ISS(read);
6266   INS0   : ISS; // Can only dual issue as instruction 0
6267   DIV    : WR;
6268 %}
6269 
6270 // Eg.  SDIV    x0, x1, x2
6271 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6272 %{
6273   single_instruction;
6274   fixed_latency(16); // Maximum latency for 64 bit divide
6275   dst    : WR(write);
6276   src1   : ISS(read);
6277   src2   : ISS(read);
6278   INS0   : ISS; // Can only dual issue as instruction 0
6279   DIV    : WR;
6280 %}
6281 
6282 //------- Load pipeline operations ------------------------
6283 
6284 // Load - prefetch
6285 // Eg.  PFRM    <mem>
6286 pipe_class iload_prefetch(memory mem)
6287 %{
6288   single_instruction;
6289   mem    : ISS(read);
6290   INS01  : ISS;
6291   LDST   : WR;
6292 %}
6293 
6294 // Load - reg, mem
6295 // Eg.  LDR     x0, <mem>
6296 pipe_class iload_reg_mem(iRegI dst, memory mem)
6297 %{
6298   single_instruction;
6299   dst    : WR(write);
6300   mem    : ISS(read);
6301   INS01  : ISS;
6302   LDST   : WR;
6303 %}
6304 
6305 // Load - reg, reg
6306 // Eg.  LDR     x0, [sp, x1]
6307 pipe_class iload_reg_reg(iRegI dst, iRegI src)
6308 %{
6309   single_instruction;
6310   dst    : WR(write);
6311   src    : ISS(read);
6312   INS01  : ISS;
6313   LDST   : WR;
6314 %}
6315 
6316 //------- Store pipeline operations -----------------------
6317 
6318 // Store - zr, mem
6319 // Eg.  STR     zr, <mem>
6320 pipe_class istore_mem(memory mem)
6321 %{
6322   single_instruction;
6323   mem    : ISS(read);
6324   INS01  : ISS;
6325   LDST   : WR;
6326 %}
6327 
6328 // Store - reg, mem
6329 // Eg.  STR     x0, <mem>
6330 pipe_class istore_reg_mem(iRegI src, memory mem)
6331 %{
6332   single_instruction;
6333   mem    : ISS(read);
6334   src    : EX2(read);
6335   INS01  : ISS;
6336   LDST   : WR;
6337 %}
6338 
6339 // Store - reg, reg
6340 // Eg. STR      x0, [sp, x1]
6341 pipe_class istore_reg_reg(iRegI dst, iRegI src)
6342 %{
6343   single_instruction;
6344   dst    : ISS(read);
6345   src    : EX2(read);
6346   INS01  : ISS;
6347   LDST   : WR;
6348 %}
6349 
6350 //------- Store pipeline operations -----------------------
6351 
6352 // Branch
6353 pipe_class pipe_branch()
6354 %{
6355   single_instruction;
6356   INS01  : ISS;
6357   BRANCH : EX1;
6358 %}
6359 
6360 // Conditional branch
6361 pipe_class pipe_branch_cond(rFlagsReg cr)
6362 %{
6363   single_instruction;
6364   cr     : EX1(read);
6365   INS01  : ISS;
6366   BRANCH : EX1;
6367 %}
6368 
6369 // Compare & Branch
6370 // EG.  CBZ/CBNZ
6371 pipe_class pipe_cmp_branch(iRegI op1)
6372 %{
6373   single_instruction;
6374   op1    : EX1(read);
6375   INS01  : ISS;
6376   BRANCH : EX1;
6377 %}
6378 
6379 //------- Synchronisation operations ----------------------
6380 
6381 // Any operation requiring serialization.
6382 // EG.  DMB/Atomic Ops/Load Acquire/Str Release
6383 pipe_class pipe_serial()
6384 %{
6385   single_instruction;
6386   force_serialization;
6387   fixed_latency(16);
6388   INS01  : ISS(2); // Cannot dual issue with any other instruction
6389   LDST   : WR;
6390 %}
6391 
6392 // Generic big/slow expanded idiom - also serialized
6393 pipe_class pipe_slow()
6394 %{
6395   instruction_count(10);
6396   multiple_bundles;
6397   force_serialization;
6398   fixed_latency(16);
6399   INS01  : ISS(2); // Cannot dual issue with any other instruction
6400   LDST   : WR;
6401 %}
6402 
6403 // Empty pipeline class
6404 pipe_class pipe_class_empty()
6405 %{
6406   single_instruction;
6407   fixed_latency(0);
6408 %}
6409 
6410 // Default pipeline class.
6411 pipe_class pipe_class_default()
6412 %{
6413   single_instruction;
6414   fixed_latency(2);
6415 %}
6416 
6417 // Pipeline class for compares.
6418 pipe_class pipe_class_compare()
6419 %{
6420   single_instruction;
6421   fixed_latency(16);
6422 %}
6423 
6424 // Pipeline class for memory operations.
6425 pipe_class pipe_class_memory()
6426 %{
6427   single_instruction;
6428   fixed_latency(16);
6429 %}
6430 
6431 // Pipeline class for call.
6432 pipe_class pipe_class_call()
6433 %{
6434   single_instruction;
6435   fixed_latency(100);
6436 %}
6437 
6438 // Define the class for the Nop node.
6439 define %{
6440    MachNop = pipe_class_empty;
6441 %}
6442 
6443 %}
6444 //----------INSTRUCTIONS-------------------------------------------------------
6445 //
6446 // match      -- States which machine-independent subtree may be replaced
6447 //               by this instruction.
6448 // ins_cost   -- The estimated cost of this instruction is used by instruction
6449 //               selection to identify a minimum cost tree of machine
6450 //               instructions that matches a tree of machine-independent
6451 //               instructions.
6452 // format     -- A string providing the disassembly for this instruction.
6453 //               The value of an instruction's operand may be inserted
6454 //               by referring to it with a '$' prefix.
6455 // opcode     -- Three instruction opcodes may be provided.  These are referred
6456 //               to within an encode class as $primary, $secondary, and $tertiary
6457 //               rrspectively.  The primary opcode is commonly used to
6458 //               indicate the type of machine instruction, while secondary
6459 //               and tertiary are often used for prefix options or addressing
6460 //               modes.
6461 // ins_encode -- A list of encode classes with parameters. The encode class
6462 //               name must have been defined in an 'enc_class' specification
6463 //               in the encode section of the architecture description.
6464 
6465 // ============================================================================
6466 // Memory (Load/Store) Instructions
6467 
6468 // Load Instructions
6469 
6470 // Load Byte (8 bit signed)
6471 instruct loadB(iRegINoSp dst, memory mem)
6472 %{
6473   match(Set dst (LoadB mem));
6474   predicate(!needs_acquiring_load(n));
6475 
6476   ins_cost(4 * INSN_COST);
6477   format %{ "ldrsbw  $dst, $mem\t# byte" %}
6478 
6479   ins_encode(aarch64_enc_ldrsbw(dst, mem));
6480 
6481   ins_pipe(iload_reg_mem);
6482 %}
6483 
6484 // Load Byte (8 bit signed) into long
6485 instruct loadB2L(iRegLNoSp dst, memory mem)
6486 %{
6487   match(Set dst (ConvI2L (LoadB mem)));
6488   predicate(!needs_acquiring_load(n->in(1)));
6489 
6490   ins_cost(4 * INSN_COST);
6491   format %{ "ldrsb  $dst, $mem\t# byte" %}
6492 
6493   ins_encode(aarch64_enc_ldrsb(dst, mem));
6494 
6495   ins_pipe(iload_reg_mem);
6496 %}
6497 
6498 // Load Byte (8 bit unsigned)
6499 instruct loadUB(iRegINoSp dst, memory mem)
6500 %{
6501   match(Set dst (LoadUB mem));
6502   predicate(!needs_acquiring_load(n));
6503 
6504   ins_cost(4 * INSN_COST);
6505   format %{ "ldrbw  $dst, $mem\t# byte" %}
6506 
6507   ins_encode(aarch64_enc_ldrb(dst, mem));
6508 
6509   ins_pipe(iload_reg_mem);
6510 %}
6511 
6512 // Load Byte (8 bit unsigned) into long
6513 instruct loadUB2L(iRegLNoSp dst, memory mem)
6514 %{
6515   match(Set dst (ConvI2L (LoadUB mem)));
6516   predicate(!needs_acquiring_load(n->in(1)));
6517 
6518   ins_cost(4 * INSN_COST);
6519   format %{ "ldrb  $dst, $mem\t# byte" %}
6520 
6521   ins_encode(aarch64_enc_ldrb(dst, mem));
6522 
6523   ins_pipe(iload_reg_mem);
6524 %}
6525 
6526 // Load Short (16 bit signed)
6527 instruct loadS(iRegINoSp dst, memory mem)
6528 %{
6529   match(Set dst (LoadS mem));
6530   predicate(!needs_acquiring_load(n));
6531 
6532   ins_cost(4 * INSN_COST);
6533   format %{ "ldrshw  $dst, $mem\t# short" %}
6534 
6535   ins_encode(aarch64_enc_ldrshw(dst, mem));
6536 
6537   ins_pipe(iload_reg_mem);
6538 %}
6539 
6540 // Load Short (16 bit signed) into long
6541 instruct loadS2L(iRegLNoSp dst, memory mem)
6542 %{
6543   match(Set dst (ConvI2L (LoadS mem)));
6544   predicate(!needs_acquiring_load(n->in(1)));
6545 
6546   ins_cost(4 * INSN_COST);
6547   format %{ "ldrsh  $dst, $mem\t# short" %}
6548 
6549   ins_encode(aarch64_enc_ldrsh(dst, mem));
6550 
6551   ins_pipe(iload_reg_mem);
6552 %}
6553 
6554 // Load Char (16 bit unsigned)
6555 instruct loadUS(iRegINoSp dst, memory mem)
6556 %{
6557   match(Set dst (LoadUS mem));
6558   predicate(!needs_acquiring_load(n));
6559 
6560   ins_cost(4 * INSN_COST);
6561   format %{ "ldrh  $dst, $mem\t# short" %}
6562 
6563   ins_encode(aarch64_enc_ldrh(dst, mem));
6564 
6565   ins_pipe(iload_reg_mem);
6566 %}
6567 
6568 // Load Short/Char (16 bit unsigned) into long
6569 instruct loadUS2L(iRegLNoSp dst, memory mem)
6570 %{
6571   match(Set dst (ConvI2L (LoadUS mem)));
6572   predicate(!needs_acquiring_load(n->in(1)));
6573 
6574   ins_cost(4 * INSN_COST);
6575   format %{ "ldrh  $dst, $mem\t# short" %}
6576 
6577   ins_encode(aarch64_enc_ldrh(dst, mem));
6578 
6579   ins_pipe(iload_reg_mem);
6580 %}
6581 
6582 // Load Integer (32 bit signed)
6583 instruct loadI(iRegINoSp dst, memory mem)
6584 %{
6585   match(Set dst (LoadI mem));
6586   predicate(!needs_acquiring_load(n));
6587 
6588   ins_cost(4 * INSN_COST);
6589   format %{ "ldrw  $dst, $mem\t# int" %}
6590 
6591   ins_encode(aarch64_enc_ldrw(dst, mem));
6592 
6593   ins_pipe(iload_reg_mem);
6594 %}
6595 
6596 // Load Integer (32 bit signed) into long
6597 instruct loadI2L(iRegLNoSp dst, memory mem)
6598 %{
6599   match(Set dst (ConvI2L (LoadI mem)));
6600   predicate(!needs_acquiring_load(n->in(1)));
6601 
6602   ins_cost(4 * INSN_COST);
6603   format %{ "ldrsw  $dst, $mem\t# int" %}
6604 
6605   ins_encode(aarch64_enc_ldrsw(dst, mem));
6606 
6607   ins_pipe(iload_reg_mem);
6608 %}
6609 
6610 // Load Integer (32 bit unsigned) into long
6611 instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask)
6612 %{
6613   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
6614   predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load()));
6615 
6616   ins_cost(4 * INSN_COST);
6617   format %{ "ldrw  $dst, $mem\t# int" %}
6618 
6619   ins_encode(aarch64_enc_ldrw(dst, mem));
6620 
6621   ins_pipe(iload_reg_mem);
6622 %}
6623 
6624 // Load Long (64 bit signed)
6625 instruct loadL(iRegLNoSp dst, memory mem)
6626 %{
6627   match(Set dst (LoadL mem));
6628   predicate(!needs_acquiring_load(n));
6629 
6630   ins_cost(4 * INSN_COST);
6631   format %{ "ldr  $dst, $mem\t# int" %}
6632 
6633   ins_encode(aarch64_enc_ldr(dst, mem));
6634 
6635   ins_pipe(iload_reg_mem);
6636 %}
6637 
6638 // Load Range
6639 instruct loadRange(iRegINoSp dst, memory mem)
6640 %{
6641   match(Set dst (LoadRange mem));
6642 
6643   ins_cost(4 * INSN_COST);
6644   format %{ "ldrw  $dst, $mem\t# range" %}
6645 
6646   ins_encode(aarch64_enc_ldrw(dst, mem));
6647 
6648   ins_pipe(iload_reg_mem);
6649 %}
6650 
6651 // Load Pointer
6652 instruct loadP(iRegPNoSp dst, memory mem)
6653 %{
6654   match(Set dst (LoadP mem));
6655   predicate(!needs_acquiring_load(n));
6656 
6657   ins_cost(4 * INSN_COST);
6658   format %{ "ldr  $dst, $mem\t# ptr" %}
6659 
6660   ins_encode(aarch64_enc_ldr(dst, mem));
6661 
6662   ins_pipe(iload_reg_mem);
6663 %}
6664 
6665 // Load Compressed Pointer
6666 instruct loadN(iRegNNoSp dst, memory mem)
6667 %{
6668   match(Set dst (LoadN mem));
6669   predicate(!needs_acquiring_load(n));
6670 
6671   ins_cost(4 * INSN_COST);
6672   format %{ "ldrw  $dst, $mem\t# compressed ptr" %}
6673 
6674   ins_encode(aarch64_enc_ldrw(dst, mem));
6675 
6676   ins_pipe(iload_reg_mem);
6677 %}
6678 
6679 // Load Klass Pointer
6680 instruct loadKlass(iRegPNoSp dst, memory mem)
6681 %{
6682   match(Set dst (LoadKlass mem));
6683   predicate(!needs_acquiring_load(n));
6684 
6685   ins_cost(4 * INSN_COST);
6686   format %{ "ldr  $dst, $mem\t# class" %}
6687 
6688   ins_encode(aarch64_enc_ldr(dst, mem));
6689 
6690   ins_pipe(iload_reg_mem);
6691 %}
6692 
6693 // Load Narrow Klass Pointer
6694 instruct loadNKlass(iRegNNoSp dst, memory mem)
6695 %{
6696   match(Set dst (LoadNKlass mem));
6697   predicate(!needs_acquiring_load(n));
6698 
6699   ins_cost(4 * INSN_COST);
6700   format %{ "ldrw  $dst, $mem\t# compressed class ptr" %}
6701 
6702   ins_encode(aarch64_enc_ldrw(dst, mem));
6703 
6704   ins_pipe(iload_reg_mem);
6705 %}
6706 
6707 // Load Float
6708 instruct loadF(vRegF dst, memory mem)
6709 %{
6710   match(Set dst (LoadF mem));
6711   predicate(!needs_acquiring_load(n));
6712 
6713   ins_cost(4 * INSN_COST);
6714   format %{ "ldrs  $dst, $mem\t# float" %}
6715 
6716   ins_encode( aarch64_enc_ldrs(dst, mem) );
6717 
6718   ins_pipe(pipe_class_memory);
6719 %}
6720 
6721 // Load Double
6722 instruct loadD(vRegD dst, memory mem)
6723 %{
6724   match(Set dst (LoadD mem));
6725   predicate(!needs_acquiring_load(n));
6726 
6727   ins_cost(4 * INSN_COST);
6728   format %{ "ldrd  $dst, $mem\t# double" %}
6729 
6730   ins_encode( aarch64_enc_ldrd(dst, mem) );
6731 
6732   ins_pipe(pipe_class_memory);
6733 %}
6734 
6735 
6736 // Load Int Constant
6737 instruct loadConI(iRegINoSp dst, immI src)
6738 %{
6739   match(Set dst src);
6740 
6741   ins_cost(INSN_COST);
6742   format %{ "mov $dst, $src\t# int" %}
6743 
6744   ins_encode( aarch64_enc_movw_imm(dst, src) );
6745 
6746   ins_pipe(ialu_imm);
6747 %}
6748 
6749 // Load Long Constant
6750 instruct loadConL(iRegLNoSp dst, immL src)
6751 %{
6752   match(Set dst src);
6753 
6754   ins_cost(INSN_COST);
6755   format %{ "mov $dst, $src\t# long" %}
6756 
6757   ins_encode( aarch64_enc_mov_imm(dst, src) );
6758 
6759   ins_pipe(ialu_imm);
6760 %}
6761 
6762 // Load Pointer Constant
6763 
6764 instruct loadConP(iRegPNoSp dst, immP con)
6765 %{
6766   match(Set dst con);
6767 
6768   ins_cost(INSN_COST * 4);
6769   format %{
6770     "mov  $dst, $con\t# ptr\n\t"
6771   %}
6772 
6773   ins_encode(aarch64_enc_mov_p(dst, con));
6774 
6775   ins_pipe(ialu_imm);
6776 %}
6777 
6778 // Load Null Pointer Constant
6779 
6780 instruct loadConP0(iRegPNoSp dst, immP0 con)
6781 %{
6782   match(Set dst con);
6783 
6784   ins_cost(INSN_COST);
6785   format %{ "mov  $dst, $con\t# NULL ptr" %}
6786 
6787   ins_encode(aarch64_enc_mov_p0(dst, con));
6788 
6789   ins_pipe(ialu_imm);
6790 %}
6791 
6792 // Load Pointer Constant One
6793 
6794 instruct loadConP1(iRegPNoSp dst, immP_1 con)
6795 %{
6796   match(Set dst con);
6797 
6798   ins_cost(INSN_COST);
6799   format %{ "mov  $dst, $con\t# NULL ptr" %}
6800 
6801   ins_encode(aarch64_enc_mov_p1(dst, con));
6802 
6803   ins_pipe(ialu_imm);
6804 %}
6805 
6806 // Load Poll Page Constant
6807 
6808 instruct loadConPollPage(iRegPNoSp dst, immPollPage con)
6809 %{
6810   match(Set dst con);
6811 
6812   ins_cost(INSN_COST);
6813   format %{ "adr  $dst, $con\t# Poll Page Ptr" %}
6814 
6815   ins_encode(aarch64_enc_mov_poll_page(dst, con));
6816 
6817   ins_pipe(ialu_imm);
6818 %}
6819 
6820 // Load Byte Map Base Constant
6821 
6822 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con)
6823 %{
6824   match(Set dst con);
6825 
6826   ins_cost(INSN_COST);
6827   format %{ "adr  $dst, $con\t# Byte Map Base" %}
6828 
6829   ins_encode(aarch64_enc_mov_byte_map_base(dst, con));
6830 
6831   ins_pipe(ialu_imm);
6832 %}
6833 
6834 // Load Narrow Pointer Constant
6835 
6836 instruct loadConN(iRegNNoSp dst, immN con)
6837 %{
6838   match(Set dst con);
6839 
6840   ins_cost(INSN_COST * 4);
6841   format %{ "mov  $dst, $con\t# compressed ptr" %}
6842 
6843   ins_encode(aarch64_enc_mov_n(dst, con));
6844 
6845   ins_pipe(ialu_imm);
6846 %}
6847 
6848 // Load Narrow Null Pointer Constant
6849 
6850 instruct loadConN0(iRegNNoSp dst, immN0 con)
6851 %{
6852   match(Set dst con);
6853 
6854   ins_cost(INSN_COST);
6855   format %{ "mov  $dst, $con\t# compressed NULL ptr" %}
6856 
6857   ins_encode(aarch64_enc_mov_n0(dst, con));
6858 
6859   ins_pipe(ialu_imm);
6860 %}
6861 
6862 // Load Narrow Klass Constant
6863 
6864 instruct loadConNKlass(iRegNNoSp dst, immNKlass con)
6865 %{
6866   match(Set dst con);
6867 
6868   ins_cost(INSN_COST);
6869   format %{ "mov  $dst, $con\t# compressed klass ptr" %}
6870 
6871   ins_encode(aarch64_enc_mov_nk(dst, con));
6872 
6873   ins_pipe(ialu_imm);
6874 %}
6875 
6876 // Load Packed Float Constant
6877 
6878 instruct loadConF_packed(vRegF dst, immFPacked con) %{
6879   match(Set dst con);
6880   ins_cost(INSN_COST * 4);
6881   format %{ "fmovs  $dst, $con"%}
6882   ins_encode %{
6883     __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant);
6884   %}
6885 
6886   ins_pipe(fp_imm_s);
6887 %}
6888 
6889 // Load Float Constant
6890 
6891 instruct loadConF(vRegF dst, immF con) %{
6892   match(Set dst con);
6893 
6894   ins_cost(INSN_COST * 4);
6895 
6896   format %{
6897     "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t"
6898   %}
6899 
6900   ins_encode %{
6901     __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con));
6902   %}
6903 
6904   ins_pipe(fp_load_constant_s);
6905 %}
6906 
6907 // Load Packed Double Constant
6908 
6909 instruct loadConD_packed(vRegD dst, immDPacked con) %{
6910   match(Set dst con);
6911   ins_cost(INSN_COST);
6912   format %{ "fmovd  $dst, $con"%}
6913   ins_encode %{
6914     __ fmovd(as_FloatRegister($dst$$reg), $con$$constant);
6915   %}
6916 
6917   ins_pipe(fp_imm_d);
6918 %}
6919 
6920 // Load Double Constant
6921 
6922 instruct loadConD(vRegD dst, immD con) %{
6923   match(Set dst con);
6924 
6925   ins_cost(INSN_COST * 5);
6926   format %{
6927     "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t"
6928   %}
6929 
6930   ins_encode %{
6931     __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con));
6932   %}
6933 
6934   ins_pipe(fp_load_constant_d);
6935 %}
6936 
6937 // Store Instructions
6938 
6939 // Store CMS card-mark Immediate
6940 instruct storeimmCM0(immI0 zero, memory mem)
6941 %{
6942   match(Set mem (StoreCM mem zero));
6943   predicate(unnecessary_storestore(n));
6944 
6945   ins_cost(INSN_COST);
6946   format %{ "storestore (elided)\n\t"
6947             "strb zr, $mem\t# byte" %}
6948 
6949   ins_encode(aarch64_enc_strb0(mem));
6950 
6951   ins_pipe(istore_mem);
6952 %}
6953 
6954 // Store CMS card-mark Immediate with intervening StoreStore
6955 // needed when using CMS with no conditional card marking
6956 instruct storeimmCM0_ordered(immI0 zero, memory mem)
6957 %{
6958   match(Set mem (StoreCM mem zero));
6959 
6960   ins_cost(INSN_COST * 2);
6961   format %{ "storestore\n\t"
6962             "dmb ishst"
6963             "\n\tstrb zr, $mem\t# byte" %}
6964 
6965   ins_encode(aarch64_enc_strb0_ordered(mem));
6966 
6967   ins_pipe(istore_mem);
6968 %}
6969 
6970 // Store Byte
6971 instruct storeB(iRegIorL2I src, memory mem)
6972 %{
6973   match(Set mem (StoreB mem src));
6974   predicate(!needs_releasing_store(n));
6975 
6976   ins_cost(INSN_COST);
6977   format %{ "strb  $src, $mem\t# byte" %}
6978 
6979   ins_encode(aarch64_enc_strb(src, mem));
6980 
6981   ins_pipe(istore_reg_mem);
6982 %}
6983 
6984 
6985 instruct storeimmB0(immI0 zero, memory mem)
6986 %{
6987   match(Set mem (StoreB mem zero));
6988   predicate(!needs_releasing_store(n));
6989 
6990   ins_cost(INSN_COST);
6991   format %{ "strb rscractch2, $mem\t# byte" %}
6992 
6993   ins_encode(aarch64_enc_strb0(mem));
6994 
6995   ins_pipe(istore_mem);
6996 %}
6997 
6998 // Store Char/Short
6999 instruct storeC(iRegIorL2I src, memory mem)
7000 %{
7001   match(Set mem (StoreC mem src));
7002   predicate(!needs_releasing_store(n));
7003 
7004   ins_cost(INSN_COST);
7005   format %{ "strh  $src, $mem\t# short" %}
7006 
7007   ins_encode(aarch64_enc_strh(src, mem));
7008 
7009   ins_pipe(istore_reg_mem);
7010 %}
7011 
7012 instruct storeimmC0(immI0 zero, memory mem)
7013 %{
7014   match(Set mem (StoreC mem zero));
7015   predicate(!needs_releasing_store(n));
7016 
7017   ins_cost(INSN_COST);
7018   format %{ "strh  zr, $mem\t# short" %}
7019 
7020   ins_encode(aarch64_enc_strh0(mem));
7021 
7022   ins_pipe(istore_mem);
7023 %}
7024 
7025 // Store Integer
7026 
7027 instruct storeI(iRegIorL2I src, memory mem)
7028 %{
7029   match(Set mem(StoreI mem src));
7030   predicate(!needs_releasing_store(n));
7031 
7032   ins_cost(INSN_COST);
7033   format %{ "strw  $src, $mem\t# int" %}
7034 
7035   ins_encode(aarch64_enc_strw(src, mem));
7036 
7037   ins_pipe(istore_reg_mem);
7038 %}
7039 
7040 instruct storeimmI0(immI0 zero, memory mem)
7041 %{
7042   match(Set mem(StoreI mem zero));
7043   predicate(!needs_releasing_store(n));
7044 
7045   ins_cost(INSN_COST);
7046   format %{ "strw  zr, $mem\t# int" %}
7047 
7048   ins_encode(aarch64_enc_strw0(mem));
7049 
7050   ins_pipe(istore_mem);
7051 %}
7052 
7053 // Store Long (64 bit signed)
7054 instruct storeL(iRegL src, memory mem)
7055 %{
7056   match(Set mem (StoreL mem src));
7057   predicate(!needs_releasing_store(n));
7058 
7059   ins_cost(INSN_COST);
7060   format %{ "str  $src, $mem\t# int" %}
7061 
7062   ins_encode(aarch64_enc_str(src, mem));
7063 
7064   ins_pipe(istore_reg_mem);
7065 %}
7066 
7067 // Store Long (64 bit signed)
7068 instruct storeimmL0(immL0 zero, memory mem)
7069 %{
7070   match(Set mem (StoreL mem zero));
7071   predicate(!needs_releasing_store(n));
7072 
7073   ins_cost(INSN_COST);
7074   format %{ "str  zr, $mem\t# int" %}
7075 
7076   ins_encode(aarch64_enc_str0(mem));
7077 
7078   ins_pipe(istore_mem);
7079 %}
7080 
7081 // Store Pointer
7082 instruct storeP(iRegP src, memory mem)
7083 %{
7084   match(Set mem (StoreP mem src));
7085   predicate(!needs_releasing_store(n));
7086 
7087   ins_cost(INSN_COST);
7088   format %{ "str  $src, $mem\t# ptr" %}
7089 
7090   ins_encode(aarch64_enc_str(src, mem));
7091 
7092   ins_pipe(istore_reg_mem);
7093 %}
7094 
7095 // Store Pointer
7096 instruct storeimmP0(immP0 zero, memory mem)
7097 %{
7098   match(Set mem (StoreP mem zero));
7099   predicate(!needs_releasing_store(n));
7100 
7101   ins_cost(INSN_COST);
7102   format %{ "str zr, $mem\t# ptr" %}
7103 
7104   ins_encode(aarch64_enc_str0(mem));
7105 
7106   ins_pipe(istore_mem);
7107 %}
7108 
7109 // Store Compressed Pointer
7110 instruct storeN(iRegN src, memory mem)
7111 %{
7112   match(Set mem (StoreN mem src));
7113   predicate(!needs_releasing_store(n));
7114 
7115   ins_cost(INSN_COST);
7116   format %{ "strw  $src, $mem\t# compressed ptr" %}
7117 
7118   ins_encode(aarch64_enc_strw(src, mem));
7119 
7120   ins_pipe(istore_reg_mem);
7121 %}
7122 
7123 instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory mem)
7124 %{
7125   match(Set mem (StoreN mem zero));
7126   predicate(Universe::narrow_oop_base() == NULL &&
7127             Universe::narrow_klass_base() == NULL &&
7128             (!needs_releasing_store(n)));
7129 
7130   ins_cost(INSN_COST);
7131   format %{ "strw  rheapbase, $mem\t# compressed ptr (rheapbase==0)" %}
7132 
7133   ins_encode(aarch64_enc_strw(heapbase, mem));
7134 
7135   ins_pipe(istore_reg_mem);
7136 %}
7137 
7138 // Store Float
7139 instruct storeF(vRegF src, memory mem)
7140 %{
7141   match(Set mem (StoreF mem src));
7142   predicate(!needs_releasing_store(n));
7143 
7144   ins_cost(INSN_COST);
7145   format %{ "strs  $src, $mem\t# float" %}
7146 
7147   ins_encode( aarch64_enc_strs(src, mem) );
7148 
7149   ins_pipe(pipe_class_memory);
7150 %}
7151 
7152 // TODO
7153 // implement storeImmF0 and storeFImmPacked
7154 
7155 // Store Double
7156 instruct storeD(vRegD src, memory mem)
7157 %{
7158   match(Set mem (StoreD mem src));
7159   predicate(!needs_releasing_store(n));
7160 
7161   ins_cost(INSN_COST);
7162   format %{ "strd  $src, $mem\t# double" %}
7163 
7164   ins_encode( aarch64_enc_strd(src, mem) );
7165 
7166   ins_pipe(pipe_class_memory);
7167 %}
7168 
7169 // Store Compressed Klass Pointer
7170 instruct storeNKlass(iRegN src, memory mem)
7171 %{
7172   predicate(!needs_releasing_store(n));
7173   match(Set mem (StoreNKlass mem src));
7174 
7175   ins_cost(INSN_COST);
7176   format %{ "strw  $src, $mem\t# compressed klass ptr" %}
7177 
7178   ins_encode(aarch64_enc_strw(src, mem));
7179 
7180   ins_pipe(istore_reg_mem);
7181 %}
7182 
7183 // TODO
7184 // implement storeImmD0 and storeDImmPacked
7185 
7186 // prefetch instructions
7187 // Must be safe to execute with invalid address (cannot fault).
7188 
7189 instruct prefetchalloc( memory mem ) %{
7190   match(PrefetchAllocation mem);
7191 
7192   ins_cost(INSN_COST);
7193   format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %}
7194 
7195   ins_encode( aarch64_enc_prefetchw(mem) );
7196 
7197   ins_pipe(iload_prefetch);
7198 %}
7199 
7200 //  ---------------- volatile loads and stores ----------------
7201 
7202 // Load Byte (8 bit signed)
7203 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7204 %{
7205   match(Set dst (LoadB mem));
7206 
7207   ins_cost(VOLATILE_REF_COST);
7208   format %{ "ldarsb  $dst, $mem\t# byte" %}
7209 
7210   ins_encode(aarch64_enc_ldarsb(dst, mem));
7211 
7212   ins_pipe(pipe_serial);
7213 %}
7214 
7215 // Load Byte (8 bit signed) into long
7216 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7217 %{
7218   match(Set dst (ConvI2L (LoadB mem)));
7219 
7220   ins_cost(VOLATILE_REF_COST);
7221   format %{ "ldarsb  $dst, $mem\t# byte" %}
7222 
7223   ins_encode(aarch64_enc_ldarsb(dst, mem));
7224 
7225   ins_pipe(pipe_serial);
7226 %}
7227 
7228 // Load Byte (8 bit unsigned)
7229 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7230 %{
7231   match(Set dst (LoadUB mem));
7232 
7233   ins_cost(VOLATILE_REF_COST);
7234   format %{ "ldarb  $dst, $mem\t# byte" %}
7235 
7236   ins_encode(aarch64_enc_ldarb(dst, mem));
7237 
7238   ins_pipe(pipe_serial);
7239 %}
7240 
7241 // Load Byte (8 bit unsigned) into long
7242 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7243 %{
7244   match(Set dst (ConvI2L (LoadUB mem)));
7245 
7246   ins_cost(VOLATILE_REF_COST);
7247   format %{ "ldarb  $dst, $mem\t# byte" %}
7248 
7249   ins_encode(aarch64_enc_ldarb(dst, mem));
7250 
7251   ins_pipe(pipe_serial);
7252 %}
7253 
7254 // Load Short (16 bit signed)
7255 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7256 %{
7257   match(Set dst (LoadS mem));
7258 
7259   ins_cost(VOLATILE_REF_COST);
7260   format %{ "ldarshw  $dst, $mem\t# short" %}
7261 
7262   ins_encode(aarch64_enc_ldarshw(dst, mem));
7263 
7264   ins_pipe(pipe_serial);
7265 %}
7266 
7267 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7268 %{
7269   match(Set dst (LoadUS mem));
7270 
7271   ins_cost(VOLATILE_REF_COST);
7272   format %{ "ldarhw  $dst, $mem\t# short" %}
7273 
7274   ins_encode(aarch64_enc_ldarhw(dst, mem));
7275 
7276   ins_pipe(pipe_serial);
7277 %}
7278 
7279 // Load Short/Char (16 bit unsigned) into long
7280 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7281 %{
7282   match(Set dst (ConvI2L (LoadUS mem)));
7283 
7284   ins_cost(VOLATILE_REF_COST);
7285   format %{ "ldarh  $dst, $mem\t# short" %}
7286 
7287   ins_encode(aarch64_enc_ldarh(dst, mem));
7288 
7289   ins_pipe(pipe_serial);
7290 %}
7291 
7292 // Load Short/Char (16 bit signed) into long
7293 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7294 %{
7295   match(Set dst (ConvI2L (LoadS mem)));
7296 
7297   ins_cost(VOLATILE_REF_COST);
7298   format %{ "ldarh  $dst, $mem\t# short" %}
7299 
7300   ins_encode(aarch64_enc_ldarsh(dst, mem));
7301 
7302   ins_pipe(pipe_serial);
7303 %}
7304 
7305 // Load Integer (32 bit signed)
7306 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7307 %{
7308   match(Set dst (LoadI mem));
7309 
7310   ins_cost(VOLATILE_REF_COST);
7311   format %{ "ldarw  $dst, $mem\t# int" %}
7312 
7313   ins_encode(aarch64_enc_ldarw(dst, mem));
7314 
7315   ins_pipe(pipe_serial);
7316 %}
7317 
7318 // Load Integer (32 bit unsigned) into long
7319 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask)
7320 %{
7321   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
7322 
7323   ins_cost(VOLATILE_REF_COST);
7324   format %{ "ldarw  $dst, $mem\t# int" %}
7325 
7326   ins_encode(aarch64_enc_ldarw(dst, mem));
7327 
7328   ins_pipe(pipe_serial);
7329 %}
7330 
7331 // Load Long (64 bit signed)
7332 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7333 %{
7334   match(Set dst (LoadL mem));
7335 
7336   ins_cost(VOLATILE_REF_COST);
7337   format %{ "ldar  $dst, $mem\t# int" %}
7338 
7339   ins_encode(aarch64_enc_ldar(dst, mem));
7340 
7341   ins_pipe(pipe_serial);
7342 %}
7343 
7344 // Load Pointer
7345 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem)
7346 %{
7347   match(Set dst (LoadP mem));
7348 
7349   ins_cost(VOLATILE_REF_COST);
7350   format %{ "ldar  $dst, $mem\t# ptr" %}
7351 
7352   ins_encode(aarch64_enc_ldar(dst, mem));
7353 
7354   ins_pipe(pipe_serial);
7355 %}
7356 
7357 // Load Compressed Pointer
7358 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem)
7359 %{
7360   match(Set dst (LoadN mem));
7361 
7362   ins_cost(VOLATILE_REF_COST);
7363   format %{ "ldarw  $dst, $mem\t# compressed ptr" %}
7364 
7365   ins_encode(aarch64_enc_ldarw(dst, mem));
7366 
7367   ins_pipe(pipe_serial);
7368 %}
7369 
7370 // Load Float
7371 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem)
7372 %{
7373   match(Set dst (LoadF mem));
7374 
7375   ins_cost(VOLATILE_REF_COST);
7376   format %{ "ldars  $dst, $mem\t# float" %}
7377 
7378   ins_encode( aarch64_enc_fldars(dst, mem) );
7379 
7380   ins_pipe(pipe_serial);
7381 %}
7382 
7383 // Load Double
7384 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem)
7385 %{
7386   match(Set dst (LoadD mem));
7387 
7388   ins_cost(VOLATILE_REF_COST);
7389   format %{ "ldard  $dst, $mem\t# double" %}
7390 
7391   ins_encode( aarch64_enc_fldard(dst, mem) );
7392 
7393   ins_pipe(pipe_serial);
7394 %}
7395 
7396 // Store Byte
7397 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
7398 %{
7399   match(Set mem (StoreB mem src));
7400 
7401   ins_cost(VOLATILE_REF_COST);
7402   format %{ "stlrb  $src, $mem\t# byte" %}
7403 
7404   ins_encode(aarch64_enc_stlrb(src, mem));
7405 
7406   ins_pipe(pipe_class_memory);
7407 %}
7408 
7409 // Store Char/Short
7410 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
7411 %{
7412   match(Set mem (StoreC mem src));
7413 
7414   ins_cost(VOLATILE_REF_COST);
7415   format %{ "stlrh  $src, $mem\t# short" %}
7416 
7417   ins_encode(aarch64_enc_stlrh(src, mem));
7418 
7419   ins_pipe(pipe_class_memory);
7420 %}
7421 
7422 // Store Integer
7423 
7424 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
7425 %{
7426   match(Set mem(StoreI mem src));
7427 
7428   ins_cost(VOLATILE_REF_COST);
7429   format %{ "stlrw  $src, $mem\t# int" %}
7430 
7431   ins_encode(aarch64_enc_stlrw(src, mem));
7432 
7433   ins_pipe(pipe_class_memory);
7434 %}
7435 
7436 // Store Long (64 bit signed)
7437 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem)
7438 %{
7439   match(Set mem (StoreL mem src));
7440 
7441   ins_cost(VOLATILE_REF_COST);
7442   format %{ "stlr  $src, $mem\t# int" %}
7443 
7444   ins_encode(aarch64_enc_stlr(src, mem));
7445 
7446   ins_pipe(pipe_class_memory);
7447 %}
7448 
7449 // Store Pointer
7450 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem)
7451 %{
7452   match(Set mem (StoreP mem src));
7453 
7454   ins_cost(VOLATILE_REF_COST);
7455   format %{ "stlr  $src, $mem\t# ptr" %}
7456 
7457   ins_encode(aarch64_enc_stlr(src, mem));
7458 
7459   ins_pipe(pipe_class_memory);
7460 %}
7461 
7462 // Store Compressed Pointer
7463 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem)
7464 %{
7465   match(Set mem (StoreN mem src));
7466 
7467   ins_cost(VOLATILE_REF_COST);
7468   format %{ "stlrw  $src, $mem\t# compressed ptr" %}
7469 
7470   ins_encode(aarch64_enc_stlrw(src, mem));
7471 
7472   ins_pipe(pipe_class_memory);
7473 %}
7474 
7475 // Store Float
7476 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem)
7477 %{
7478   match(Set mem (StoreF mem src));
7479 
7480   ins_cost(VOLATILE_REF_COST);
7481   format %{ "stlrs  $src, $mem\t# float" %}
7482 
7483   ins_encode( aarch64_enc_fstlrs(src, mem) );
7484 
7485   ins_pipe(pipe_class_memory);
7486 %}
7487 
7488 // TODO
7489 // implement storeImmF0 and storeFImmPacked
7490 
7491 // Store Double
7492 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem)
7493 %{
7494   match(Set mem (StoreD mem src));
7495 
7496   ins_cost(VOLATILE_REF_COST);
7497   format %{ "stlrd  $src, $mem\t# double" %}
7498 
7499   ins_encode( aarch64_enc_fstlrd(src, mem) );
7500 
7501   ins_pipe(pipe_class_memory);
7502 %}
7503 
7504 //  ---------------- end of volatile loads and stores ----------------
7505 
7506 // ============================================================================
7507 // BSWAP Instructions
7508 
7509 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{
7510   match(Set dst (ReverseBytesI src));
7511 
7512   ins_cost(INSN_COST);
7513   format %{ "revw  $dst, $src" %}
7514 
7515   ins_encode %{
7516     __ revw(as_Register($dst$$reg), as_Register($src$$reg));
7517   %}
7518 
7519   ins_pipe(ialu_reg);
7520 %}
7521 
7522 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{
7523   match(Set dst (ReverseBytesL src));
7524 
7525   ins_cost(INSN_COST);
7526   format %{ "rev  $dst, $src" %}
7527 
7528   ins_encode %{
7529     __ rev(as_Register($dst$$reg), as_Register($src$$reg));
7530   %}
7531 
7532   ins_pipe(ialu_reg);
7533 %}
7534 
7535 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{
7536   match(Set dst (ReverseBytesUS src));
7537 
7538   ins_cost(INSN_COST);
7539   format %{ "rev16w  $dst, $src" %}
7540 
7541   ins_encode %{
7542     __ rev16w(as_Register($dst$$reg), as_Register($src$$reg));
7543   %}
7544 
7545   ins_pipe(ialu_reg);
7546 %}
7547 
7548 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{
7549   match(Set dst (ReverseBytesS src));
7550 
7551   ins_cost(INSN_COST);
7552   format %{ "rev16w  $dst, $src\n\t"
7553             "sbfmw $dst, $dst, #0, #15" %}
7554 
7555   ins_encode %{
7556     __ rev16w(as_Register($dst$$reg), as_Register($src$$reg));
7557     __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U);
7558   %}
7559 
7560   ins_pipe(ialu_reg);
7561 %}
7562 
7563 // ============================================================================
7564 // Zero Count Instructions
7565 
7566 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{
7567   match(Set dst (CountLeadingZerosI src));
7568 
7569   ins_cost(INSN_COST);
7570   format %{ "clzw  $dst, $src" %}
7571   ins_encode %{
7572     __ clzw(as_Register($dst$$reg), as_Register($src$$reg));
7573   %}
7574 
7575   ins_pipe(ialu_reg);
7576 %}
7577 
7578 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{
7579   match(Set dst (CountLeadingZerosL src));
7580 
7581   ins_cost(INSN_COST);
7582   format %{ "clz   $dst, $src" %}
7583   ins_encode %{
7584     __ clz(as_Register($dst$$reg), as_Register($src$$reg));
7585   %}
7586 
7587   ins_pipe(ialu_reg);
7588 %}
7589 
7590 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{
7591   match(Set dst (CountTrailingZerosI src));
7592 
7593   ins_cost(INSN_COST * 2);
7594   format %{ "rbitw  $dst, $src\n\t"
7595             "clzw   $dst, $dst" %}
7596   ins_encode %{
7597     __ rbitw(as_Register($dst$$reg), as_Register($src$$reg));
7598     __ clzw(as_Register($dst$$reg), as_Register($dst$$reg));
7599   %}
7600 
7601   ins_pipe(ialu_reg);
7602 %}
7603 
7604 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{
7605   match(Set dst (CountTrailingZerosL src));
7606 
7607   ins_cost(INSN_COST * 2);
7608   format %{ "rbit   $dst, $src\n\t"
7609             "clz    $dst, $dst" %}
7610   ins_encode %{
7611     __ rbit(as_Register($dst$$reg), as_Register($src$$reg));
7612     __ clz(as_Register($dst$$reg), as_Register($dst$$reg));
7613   %}
7614 
7615   ins_pipe(ialu_reg);
7616 %}
7617 
7618 //---------- Population Count Instructions -------------------------------------
7619 //
7620 
7621 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{
7622   predicate(UsePopCountInstruction);
7623   match(Set dst (PopCountI src));
7624   effect(TEMP tmp);
7625   ins_cost(INSN_COST * 13);
7626 
7627   format %{ "movw   $src, $src\n\t"
7628             "mov    $tmp, $src\t# vector (1D)\n\t"
7629             "cnt    $tmp, $tmp\t# vector (8B)\n\t"
7630             "addv   $tmp, $tmp\t# vector (8B)\n\t"
7631             "mov    $dst, $tmp\t# vector (1D)" %}
7632   ins_encode %{
7633     __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0
7634     __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register);
7635     __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7636     __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7637     __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0);
7638   %}
7639 
7640   ins_pipe(pipe_class_default);
7641 %}
7642 
7643 instruct popCountI_mem(iRegINoSp dst, memory mem, vRegF tmp) %{
7644   predicate(UsePopCountInstruction);
7645   match(Set dst (PopCountI (LoadI mem)));
7646   effect(TEMP tmp);
7647   ins_cost(INSN_COST * 13);
7648 
7649   format %{ "ldrs   $tmp, $mem\n\t"
7650             "cnt    $tmp, $tmp\t# vector (8B)\n\t"
7651             "addv   $tmp, $tmp\t# vector (8B)\n\t"
7652             "mov    $dst, $tmp\t# vector (1D)" %}
7653   ins_encode %{
7654     FloatRegister tmp_reg = as_FloatRegister($tmp$$reg);
7655     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(),
7656                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
7657     __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7658     __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7659     __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0);
7660   %}
7661 
7662   ins_pipe(pipe_class_default);
7663 %}
7664 
7665 // Note: Long.bitCount(long) returns an int.
7666 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{
7667   predicate(UsePopCountInstruction);
7668   match(Set dst (PopCountL src));
7669   effect(TEMP tmp);
7670   ins_cost(INSN_COST * 13);
7671 
7672   format %{ "mov    $tmp, $src\t# vector (1D)\n\t"
7673             "cnt    $tmp, $tmp\t# vector (8B)\n\t"
7674             "addv   $tmp, $tmp\t# vector (8B)\n\t"
7675             "mov    $dst, $tmp\t# vector (1D)" %}
7676   ins_encode %{
7677     __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register);
7678     __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7679     __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7680     __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0);
7681   %}
7682 
7683   ins_pipe(pipe_class_default);
7684 %}
7685 
7686 instruct popCountL_mem(iRegINoSp dst, memory mem, vRegD tmp) %{
7687   predicate(UsePopCountInstruction);
7688   match(Set dst (PopCountL (LoadL mem)));
7689   effect(TEMP tmp);
7690   ins_cost(INSN_COST * 13);
7691 
7692   format %{ "ldrd   $tmp, $mem\n\t"
7693             "cnt    $tmp, $tmp\t# vector (8B)\n\t"
7694             "addv   $tmp, $tmp\t# vector (8B)\n\t"
7695             "mov    $dst, $tmp\t# vector (1D)" %}
7696   ins_encode %{
7697     FloatRegister tmp_reg = as_FloatRegister($tmp$$reg);
7698     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(),
7699                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
7700     __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7701     __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7702     __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0);
7703   %}
7704 
7705   ins_pipe(pipe_class_default);
7706 %}
7707 
7708 // ============================================================================
7709 // MemBar Instruction
7710 
7711 instruct load_fence() %{
7712   match(LoadFence);
7713   ins_cost(VOLATILE_REF_COST);
7714 
7715   format %{ "load_fence" %}
7716 
7717   ins_encode %{
7718     __ membar(Assembler::LoadLoad|Assembler::LoadStore);
7719   %}
7720   ins_pipe(pipe_serial);
7721 %}
7722 
7723 instruct unnecessary_membar_acquire() %{
7724   predicate(unnecessary_acquire(n));
7725   match(MemBarAcquire);
7726   ins_cost(0);
7727 
7728   format %{ "membar_acquire (elided)" %}
7729 
7730   ins_encode %{
7731     __ block_comment("membar_acquire (elided)");
7732   %}
7733 
7734   ins_pipe(pipe_class_empty);
7735 %}
7736 
7737 instruct membar_acquire() %{
7738   match(MemBarAcquire);
7739   ins_cost(VOLATILE_REF_COST);
7740 
7741   format %{ "membar_acquire\n\t"
7742             "dmb ish" %}
7743 
7744   ins_encode %{
7745     __ block_comment("membar_acquire");
7746     __ membar(Assembler::LoadLoad|Assembler::LoadStore);
7747   %}
7748 
7749   ins_pipe(pipe_serial);
7750 %}
7751 
7752 
7753 instruct membar_acquire_lock() %{
7754   match(MemBarAcquireLock);
7755   ins_cost(VOLATILE_REF_COST);
7756 
7757   format %{ "membar_acquire_lock (elided)" %}
7758 
7759   ins_encode %{
7760     __ block_comment("membar_acquire_lock (elided)");
7761   %}
7762 
7763   ins_pipe(pipe_serial);
7764 %}
7765 
7766 instruct store_fence() %{
7767   match(StoreFence);
7768   ins_cost(VOLATILE_REF_COST);
7769 
7770   format %{ "store_fence" %}
7771 
7772   ins_encode %{
7773     __ membar(Assembler::LoadStore|Assembler::StoreStore);
7774   %}
7775   ins_pipe(pipe_serial);
7776 %}
7777 
7778 instruct unnecessary_membar_release() %{
7779   predicate(unnecessary_release(n));
7780   match(MemBarRelease);
7781   ins_cost(0);
7782 
7783   format %{ "membar_release (elided)" %}
7784 
7785   ins_encode %{
7786     __ block_comment("membar_release (elided)");
7787   %}
7788   ins_pipe(pipe_serial);
7789 %}
7790 
7791 instruct membar_release() %{
7792   match(MemBarRelease);
7793   ins_cost(VOLATILE_REF_COST);
7794 
7795   format %{ "membar_release\n\t"
7796             "dmb ish" %}
7797 
7798   ins_encode %{
7799     __ block_comment("membar_release");
7800     __ membar(Assembler::LoadStore|Assembler::StoreStore);
7801   %}
7802   ins_pipe(pipe_serial);
7803 %}
7804 
7805 instruct membar_storestore() %{
7806   match(MemBarStoreStore);
7807   ins_cost(VOLATILE_REF_COST);
7808 
7809   format %{ "MEMBAR-store-store" %}
7810 
7811   ins_encode %{
7812     __ membar(Assembler::StoreStore);
7813   %}
7814   ins_pipe(pipe_serial);
7815 %}
7816 
7817 instruct membar_release_lock() %{
7818   match(MemBarReleaseLock);
7819   ins_cost(VOLATILE_REF_COST);
7820 
7821   format %{ "membar_release_lock (elided)" %}
7822 
7823   ins_encode %{
7824     __ block_comment("membar_release_lock (elided)");
7825   %}
7826 
7827   ins_pipe(pipe_serial);
7828 %}
7829 
7830 instruct unnecessary_membar_volatile() %{
7831   predicate(unnecessary_volatile(n));
7832   match(MemBarVolatile);
7833   ins_cost(0);
7834 
7835   format %{ "membar_volatile (elided)" %}
7836 
7837   ins_encode %{
7838     __ block_comment("membar_volatile (elided)");
7839   %}
7840 
7841   ins_pipe(pipe_serial);
7842 %}
7843 
7844 instruct membar_volatile() %{
7845   match(MemBarVolatile);
7846   ins_cost(VOLATILE_REF_COST*100);
7847 
7848   format %{ "membar_volatile\n\t"
7849              "dmb ish"%}
7850 
7851   ins_encode %{
7852     __ block_comment("membar_volatile");
7853     __ membar(Assembler::StoreLoad);
7854   %}
7855 
7856   ins_pipe(pipe_serial);
7857 %}
7858 
7859 // ============================================================================
7860 // Cast/Convert Instructions
7861 
7862 instruct castX2P(iRegPNoSp dst, iRegL src) %{
7863   match(Set dst (CastX2P src));
7864 
7865   ins_cost(INSN_COST);
7866   format %{ "mov $dst, $src\t# long -> ptr" %}
7867 
7868   ins_encode %{
7869     if ($dst$$reg != $src$$reg) {
7870       __ mov(as_Register($dst$$reg), as_Register($src$$reg));
7871     }
7872   %}
7873 
7874   ins_pipe(ialu_reg);
7875 %}
7876 
7877 instruct castP2X(iRegLNoSp dst, iRegP src) %{
7878   match(Set dst (CastP2X src));
7879 
7880   ins_cost(INSN_COST);
7881   format %{ "mov $dst, $src\t# ptr -> long" %}
7882 
7883   ins_encode %{
7884     if ($dst$$reg != $src$$reg) {
7885       __ mov(as_Register($dst$$reg), as_Register($src$$reg));
7886     }
7887   %}
7888 
7889   ins_pipe(ialu_reg);
7890 %}
7891 
7892 // Convert oop into int for vectors alignment masking
7893 instruct convP2I(iRegINoSp dst, iRegP src) %{
7894   match(Set dst (ConvL2I (CastP2X src)));
7895 
7896   ins_cost(INSN_COST);
7897   format %{ "movw $dst, $src\t# ptr -> int" %}
7898   ins_encode %{
7899     __ movw($dst$$Register, $src$$Register);
7900   %}
7901 
7902   ins_pipe(ialu_reg);
7903 %}
7904 
7905 // Convert compressed oop into int for vectors alignment masking
7906 // in case of 32bit oops (heap < 4Gb).
7907 instruct convN2I(iRegINoSp dst, iRegN src)
7908 %{
7909   predicate(Universe::narrow_oop_shift() == 0);
7910   match(Set dst (ConvL2I (CastP2X (DecodeN src))));
7911 
7912   ins_cost(INSN_COST);
7913   format %{ "mov dst, $src\t# compressed ptr -> int" %}
7914   ins_encode %{
7915     __ movw($dst$$Register, $src$$Register);
7916   %}
7917 
7918   ins_pipe(ialu_reg);
7919 %}
7920 
7921 
7922 // Convert oop pointer into compressed form
7923 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{
7924   predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
7925   match(Set dst (EncodeP src));
7926   effect(KILL cr);
7927   ins_cost(INSN_COST * 3);
7928   format %{ "encode_heap_oop $dst, $src" %}
7929   ins_encode %{
7930     Register s = $src$$Register;
7931     Register d = $dst$$Register;
7932     __ encode_heap_oop(d, s);
7933   %}
7934   ins_pipe(ialu_reg);
7935 %}
7936 
7937 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{
7938   predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
7939   match(Set dst (EncodeP src));
7940   ins_cost(INSN_COST * 3);
7941   format %{ "encode_heap_oop_not_null $dst, $src" %}
7942   ins_encode %{
7943     __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
7944   %}
7945   ins_pipe(ialu_reg);
7946 %}
7947 
7948 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{
7949   predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
7950             n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
7951   match(Set dst (DecodeN src));
7952   ins_cost(INSN_COST * 3);
7953   format %{ "decode_heap_oop $dst, $src" %}
7954   ins_encode %{
7955     Register s = $src$$Register;
7956     Register d = $dst$$Register;
7957     __ decode_heap_oop(d, s);
7958   %}
7959   ins_pipe(ialu_reg);
7960 %}
7961 
7962 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{
7963   predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
7964             n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
7965   match(Set dst (DecodeN src));
7966   ins_cost(INSN_COST * 3);
7967   format %{ "decode_heap_oop_not_null $dst, $src" %}
7968   ins_encode %{
7969     Register s = $src$$Register;
7970     Register d = $dst$$Register;
7971     __ decode_heap_oop_not_null(d, s);
7972   %}
7973   ins_pipe(ialu_reg);
7974 %}
7975 
7976 // n.b. AArch64 implementations of encode_klass_not_null and
7977 // decode_klass_not_null do not modify the flags register so, unlike
7978 // Intel, we don't kill CR as a side effect here
7979 
7980 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{
7981   match(Set dst (EncodePKlass src));
7982 
7983   ins_cost(INSN_COST * 3);
7984   format %{ "encode_klass_not_null $dst,$src" %}
7985 
7986   ins_encode %{
7987     Register src_reg = as_Register($src$$reg);
7988     Register dst_reg = as_Register($dst$$reg);
7989     __ encode_klass_not_null(dst_reg, src_reg);
7990   %}
7991 
7992    ins_pipe(ialu_reg);
7993 %}
7994 
7995 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{
7996   match(Set dst (DecodeNKlass src));
7997 
7998   ins_cost(INSN_COST * 3);
7999   format %{ "decode_klass_not_null $dst,$src" %}
8000 
8001   ins_encode %{
8002     Register src_reg = as_Register($src$$reg);
8003     Register dst_reg = as_Register($dst$$reg);
8004     if (dst_reg != src_reg) {
8005       __ decode_klass_not_null(dst_reg, src_reg);
8006     } else {
8007       __ decode_klass_not_null(dst_reg);
8008     }
8009   %}
8010 
8011    ins_pipe(ialu_reg);
8012 %}
8013 
8014 instruct checkCastPP(iRegPNoSp dst)
8015 %{
8016   match(Set dst (CheckCastPP dst));
8017 
8018   size(0);
8019   format %{ "# checkcastPP of $dst" %}
8020   ins_encode(/* empty encoding */);
8021   ins_pipe(pipe_class_empty);
8022 %}
8023 
8024 instruct castPP(iRegPNoSp dst)
8025 %{
8026   match(Set dst (CastPP dst));
8027 
8028   size(0);
8029   format %{ "# castPP of $dst" %}
8030   ins_encode(/* empty encoding */);
8031   ins_pipe(pipe_class_empty);
8032 %}
8033 
8034 instruct castII(iRegI dst)
8035 %{
8036   match(Set dst (CastII dst));
8037 
8038   size(0);
8039   format %{ "# castII of $dst" %}
8040   ins_encode(/* empty encoding */);
8041   ins_cost(0);
8042   ins_pipe(pipe_class_empty);
8043 %}
8044 
8045 // ============================================================================
8046 // Atomic operation instructions
8047 //
8048 // Intel and SPARC both implement Ideal Node LoadPLocked and
8049 // Store{PIL}Conditional instructions using a normal load for the
8050 // LoadPLocked and a CAS for the Store{PIL}Conditional.
8051 //
8052 // The ideal code appears only to use LoadPLocked/StorePLocked as a
8053 // pair to lock object allocations from Eden space when not using
8054 // TLABs.
8055 //
8056 // There does not appear to be a Load{IL}Locked Ideal Node and the
8057 // Ideal code appears to use Store{IL}Conditional as an alias for CAS
8058 // and to use StoreIConditional only for 32-bit and StoreLConditional
8059 // only for 64-bit.
8060 //
8061 // We implement LoadPLocked and StorePLocked instructions using,
8062 // respectively the AArch64 hw load-exclusive and store-conditional
8063 // instructions. Whereas we must implement each of
8064 // Store{IL}Conditional using a CAS which employs a pair of
8065 // instructions comprising a load-exclusive followed by a
8066 // store-conditional.
8067 
8068 
8069 // Locked-load (linked load) of the current heap-top
8070 // used when updating the eden heap top
8071 // implemented using ldaxr on AArch64
8072 
8073 instruct loadPLocked(iRegPNoSp dst, indirect mem)
8074 %{
8075   match(Set dst (LoadPLocked mem));
8076 
8077   ins_cost(VOLATILE_REF_COST);
8078 
8079   format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %}
8080 
8081   ins_encode(aarch64_enc_ldaxr(dst, mem));
8082 
8083   ins_pipe(pipe_serial);
8084 %}
8085 
8086 // Conditional-store of the updated heap-top.
8087 // Used during allocation of the shared heap.
8088 // Sets flag (EQ) on success.
8089 // implemented using stlxr on AArch64.
8090 
8091 instruct storePConditional(memory heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr)
8092 %{
8093   match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
8094 
8095   ins_cost(VOLATILE_REF_COST);
8096 
8097  // TODO
8098  // do we need to do a store-conditional release or can we just use a
8099  // plain store-conditional?
8100 
8101   format %{
8102     "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release"
8103     "cmpw rscratch1, zr\t# EQ on successful write"
8104   %}
8105 
8106   ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr));
8107 
8108   ins_pipe(pipe_serial);
8109 %}
8110 
8111 
8112 // storeLConditional is used by PhaseMacroExpand::expand_lock_node
8113 // when attempting to rebias a lock towards the current thread.  We
8114 // must use the acquire form of cmpxchg in order to guarantee acquire
8115 // semantics in this case.
8116 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr)
8117 %{
8118   match(Set cr (StoreLConditional mem (Binary oldval newval)));
8119 
8120   ins_cost(VOLATILE_REF_COST);
8121 
8122   format %{
8123     "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval"
8124     "cmpw rscratch1, zr\t# EQ on successful write"
8125   %}
8126 
8127   ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval));
8128 
8129   ins_pipe(pipe_slow);
8130 %}
8131 
8132 // storeIConditional also has acquire semantics, for no better reason
8133 // than matching storeLConditional.  At the time of writing this
8134 // comment storeIConditional was not used anywhere by AArch64.
8135 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr)
8136 %{
8137   match(Set cr (StoreIConditional mem (Binary oldval newval)));
8138 
8139   ins_cost(VOLATILE_REF_COST);
8140 
8141   format %{
8142     "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval"
8143     "cmpw rscratch1, zr\t# EQ on successful write"
8144   %}
8145 
8146   ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval));
8147 
8148   ins_pipe(pipe_slow);
8149 %}
8150 
8151 // standard CompareAndSwapX when we are using barriers
8152 // these have higher priority than the rules selected by a predicate
8153 
8154 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher
8155 // can't match them
8156 
8157 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8158 
8159   match(Set res (CompareAndSwapB mem (Binary oldval newval)));
8160   ins_cost(2 * VOLATILE_REF_COST);
8161 
8162   effect(KILL cr);
8163 
8164   format %{
8165     "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8166     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8167   %}
8168 
8169   ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval),
8170             aarch64_enc_cset_eq(res));
8171 
8172   ins_pipe(pipe_slow);
8173 %}
8174 
8175 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8176 
8177   match(Set res (CompareAndSwapS mem (Binary oldval newval)));
8178   ins_cost(2 * VOLATILE_REF_COST);
8179 
8180   effect(KILL cr);
8181 
8182   format %{
8183     "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8184     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8185   %}
8186 
8187   ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval),
8188             aarch64_enc_cset_eq(res));
8189 
8190   ins_pipe(pipe_slow);
8191 %}
8192 
8193 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8194 
8195   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
8196   ins_cost(2 * VOLATILE_REF_COST);
8197 
8198   effect(KILL cr);
8199 
8200  format %{
8201     "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8202     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8203  %}
8204 
8205  ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval),
8206             aarch64_enc_cset_eq(res));
8207 
8208   ins_pipe(pipe_slow);
8209 %}
8210 
8211 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{
8212 
8213   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
8214   ins_cost(2 * VOLATILE_REF_COST);
8215 
8216   effect(KILL cr);
8217 
8218  format %{
8219     "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
8220     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8221  %}
8222 
8223  ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
8224             aarch64_enc_cset_eq(res));
8225 
8226   ins_pipe(pipe_slow);
8227 %}
8228 
8229 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8230 
8231   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
8232   ins_cost(2 * VOLATILE_REF_COST);
8233 
8234   effect(KILL cr);
8235 
8236  format %{
8237     "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
8238     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8239  %}
8240 
8241  ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
8242             aarch64_enc_cset_eq(res));
8243 
8244   ins_pipe(pipe_slow);
8245 %}
8246 
8247 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
8248 
8249   match(Set res (CompareAndSwapN mem (Binary oldval newval)));
8250   ins_cost(2 * VOLATILE_REF_COST);
8251 
8252   effect(KILL cr);
8253 
8254  format %{
8255     "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
8256     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8257  %}
8258 
8259  ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval),
8260             aarch64_enc_cset_eq(res));
8261 
8262   ins_pipe(pipe_slow);
8263 %}
8264 
8265 // alternative CompareAndSwapX when we are eliding barriers
8266 
8267 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8268 
8269   predicate(needs_acquiring_load_exclusive(n));
8270   match(Set res (CompareAndSwapB mem (Binary oldval newval)));
8271   ins_cost(VOLATILE_REF_COST);
8272 
8273   effect(KILL cr);
8274 
8275   format %{
8276     "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8277     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8278   %}
8279 
8280   ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval),
8281             aarch64_enc_cset_eq(res));
8282 
8283   ins_pipe(pipe_slow);
8284 %}
8285 
8286 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8287 
8288   predicate(needs_acquiring_load_exclusive(n));
8289   match(Set res (CompareAndSwapS mem (Binary oldval newval)));
8290   ins_cost(VOLATILE_REF_COST);
8291 
8292   effect(KILL cr);
8293 
8294   format %{
8295     "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8296     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8297   %}
8298 
8299   ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval),
8300             aarch64_enc_cset_eq(res));
8301 
8302   ins_pipe(pipe_slow);
8303 %}
8304 
8305 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8306 
8307   predicate(needs_acquiring_load_exclusive(n));
8308   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
8309   ins_cost(VOLATILE_REF_COST);
8310 
8311   effect(KILL cr);
8312 
8313  format %{
8314     "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8315     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8316  %}
8317 
8318  ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
8319             aarch64_enc_cset_eq(res));
8320 
8321   ins_pipe(pipe_slow);
8322 %}
8323 
8324 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{
8325 
8326   predicate(needs_acquiring_load_exclusive(n));
8327   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
8328   ins_cost(VOLATILE_REF_COST);
8329 
8330   effect(KILL cr);
8331 
8332  format %{
8333     "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
8334     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8335  %}
8336 
8337  ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
8338             aarch64_enc_cset_eq(res));
8339 
8340   ins_pipe(pipe_slow);
8341 %}
8342 
8343 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8344 
8345   predicate(needs_acquiring_load_exclusive(n));
8346   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
8347   ins_cost(VOLATILE_REF_COST);
8348 
8349   effect(KILL cr);
8350 
8351  format %{
8352     "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
8353     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8354  %}
8355 
8356  ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
8357             aarch64_enc_cset_eq(res));
8358 
8359   ins_pipe(pipe_slow);
8360 %}
8361 
8362 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
8363 
8364   predicate(needs_acquiring_load_exclusive(n));
8365   match(Set res (CompareAndSwapN mem (Binary oldval newval)));
8366   ins_cost(VOLATILE_REF_COST);
8367 
8368   effect(KILL cr);
8369 
8370  format %{
8371     "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
8372     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8373  %}
8374 
8375  ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
8376             aarch64_enc_cset_eq(res));
8377 
8378   ins_pipe(pipe_slow);
8379 %}
8380 
8381 
8382 // ---------------------------------------------------------------------
8383 
8384 
8385 // BEGIN This section of the file is automatically generated. Do not edit --------------
8386 
8387 // Sundry CAS operations.  Note that release is always true,
8388 // regardless of the memory ordering of the CAS.  This is because we
8389 // need the volatile case to be sequentially consistent but there is
8390 // no trailing StoreLoad barrier emitted by C2.  Unfortunately we
8391 // can't check the type of memory ordering here, so we always emit a
8392 // STLXR.
8393 
8394 // This section is generated from aarch64_ad_cas.m4
8395 
8396 
8397 
8398 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8399   match(Set res (CompareAndExchangeB mem (Binary oldval newval)));
8400   ins_cost(2 * VOLATILE_REF_COST);
8401   effect(TEMP_DEF res, KILL cr);
8402   format %{
8403     "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
8404   %}
8405   ins_encode %{
8406     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8407                Assembler::byte, /*acquire*/ false, /*release*/ true,
8408                /*weak*/ false, $res$$Register);
8409     __ sxtbw($res$$Register, $res$$Register);
8410   %}
8411   ins_pipe(pipe_slow);
8412 %}
8413 
8414 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8415   match(Set res (CompareAndExchangeS mem (Binary oldval newval)));
8416   ins_cost(2 * VOLATILE_REF_COST);
8417   effect(TEMP_DEF res, KILL cr);
8418   format %{
8419     "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
8420   %}
8421   ins_encode %{
8422     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8423                Assembler::halfword, /*acquire*/ false, /*release*/ true,
8424                /*weak*/ false, $res$$Register);
8425     __ sxthw($res$$Register, $res$$Register);
8426   %}
8427   ins_pipe(pipe_slow);
8428 %}
8429 
8430 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8431   match(Set res (CompareAndExchangeI mem (Binary oldval newval)));
8432   ins_cost(2 * VOLATILE_REF_COST);
8433   effect(TEMP_DEF res, KILL cr);
8434   format %{
8435     "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
8436   %}
8437   ins_encode %{
8438     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8439                Assembler::word, /*acquire*/ false, /*release*/ true,
8440                /*weak*/ false, $res$$Register);
8441   %}
8442   ins_pipe(pipe_slow);
8443 %}
8444 
8445 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
8446   match(Set res (CompareAndExchangeL mem (Binary oldval newval)));
8447   ins_cost(2 * VOLATILE_REF_COST);
8448   effect(TEMP_DEF res, KILL cr);
8449   format %{
8450     "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
8451   %}
8452   ins_encode %{
8453     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8454                Assembler::xword, /*acquire*/ false, /*release*/ true,
8455                /*weak*/ false, $res$$Register);
8456   %}
8457   ins_pipe(pipe_slow);
8458 %}
8459 
8460 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
8461   match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
8462   ins_cost(2 * VOLATILE_REF_COST);
8463   effect(TEMP_DEF res, KILL cr);
8464   format %{
8465     "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
8466   %}
8467   ins_encode %{
8468     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8469                Assembler::word, /*acquire*/ false, /*release*/ true,
8470                /*weak*/ false, $res$$Register);
8471   %}
8472   ins_pipe(pipe_slow);
8473 %}
8474 
8475 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8476   match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
8477   ins_cost(2 * VOLATILE_REF_COST);
8478   effect(TEMP_DEF res, KILL cr);
8479   format %{
8480     "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
8481   %}
8482   ins_encode %{
8483     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8484                Assembler::xword, /*acquire*/ false, /*release*/ true,
8485                /*weak*/ false, $res$$Register);
8486   %}
8487   ins_pipe(pipe_slow);
8488 %}
8489 
8490 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8491   predicate(needs_acquiring_load_exclusive(n));
8492   match(Set res (CompareAndExchangeB mem (Binary oldval newval)));
8493   ins_cost(VOLATILE_REF_COST);
8494   effect(TEMP_DEF res, KILL cr);
8495   format %{
8496     "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
8497   %}
8498   ins_encode %{
8499     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8500                Assembler::byte, /*acquire*/ true, /*release*/ true,
8501                /*weak*/ false, $res$$Register);
8502     __ sxtbw($res$$Register, $res$$Register);
8503   %}
8504   ins_pipe(pipe_slow);
8505 %}
8506 
8507 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8508   predicate(needs_acquiring_load_exclusive(n));
8509   match(Set res (CompareAndExchangeS mem (Binary oldval newval)));
8510   ins_cost(VOLATILE_REF_COST);
8511   effect(TEMP_DEF res, KILL cr);
8512   format %{
8513     "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
8514   %}
8515   ins_encode %{
8516     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8517                Assembler::halfword, /*acquire*/ true, /*release*/ true,
8518                /*weak*/ false, $res$$Register);
8519     __ sxthw($res$$Register, $res$$Register);
8520   %}
8521   ins_pipe(pipe_slow);
8522 %}
8523 
8524 
8525 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8526   predicate(needs_acquiring_load_exclusive(n));
8527   match(Set res (CompareAndExchangeI mem (Binary oldval newval)));
8528   ins_cost(VOLATILE_REF_COST);
8529   effect(TEMP_DEF res, KILL cr);
8530   format %{
8531     "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
8532   %}
8533   ins_encode %{
8534     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8535                Assembler::word, /*acquire*/ true, /*release*/ true,
8536                /*weak*/ false, $res$$Register);
8537   %}
8538   ins_pipe(pipe_slow);
8539 %}
8540 
8541 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
8542   predicate(needs_acquiring_load_exclusive(n));
8543   match(Set res (CompareAndExchangeL mem (Binary oldval newval)));
8544   ins_cost(VOLATILE_REF_COST);
8545   effect(TEMP_DEF res, KILL cr);
8546   format %{
8547     "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
8548   %}
8549   ins_encode %{
8550     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8551                Assembler::xword, /*acquire*/ true, /*release*/ true,
8552                /*weak*/ false, $res$$Register);
8553   %}
8554   ins_pipe(pipe_slow);
8555 %}
8556 
8557 
8558 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
8559   predicate(needs_acquiring_load_exclusive(n));
8560   match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
8561   ins_cost(VOLATILE_REF_COST);
8562   effect(TEMP_DEF res, KILL cr);
8563   format %{
8564     "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
8565   %}
8566   ins_encode %{
8567     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8568                Assembler::word, /*acquire*/ true, /*release*/ true,
8569                /*weak*/ false, $res$$Register);
8570   %}
8571   ins_pipe(pipe_slow);
8572 %}
8573 
8574 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8575   predicate(needs_acquiring_load_exclusive(n));
8576   match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
8577   ins_cost(VOLATILE_REF_COST);
8578   effect(TEMP_DEF res, KILL cr);
8579   format %{
8580     "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
8581   %}
8582   ins_encode %{
8583     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8584                Assembler::xword, /*acquire*/ true, /*release*/ true,
8585                /*weak*/ false, $res$$Register);
8586   %}
8587   ins_pipe(pipe_slow);
8588 %}
8589 
8590 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8591   match(Set res (WeakCompareAndSwapB mem (Binary oldval newval)));
8592   ins_cost(2 * VOLATILE_REF_COST);
8593   effect(KILL cr);
8594   format %{
8595     "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
8596     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8597   %}
8598   ins_encode %{
8599     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8600                Assembler::byte, /*acquire*/ false, /*release*/ true,
8601                /*weak*/ true, noreg);
8602     __ csetw($res$$Register, Assembler::EQ);
8603   %}
8604   ins_pipe(pipe_slow);
8605 %}
8606 
8607 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8608   match(Set res (WeakCompareAndSwapS mem (Binary oldval newval)));
8609   ins_cost(2 * VOLATILE_REF_COST);
8610   effect(KILL cr);
8611   format %{
8612     "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
8613     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8614   %}
8615   ins_encode %{
8616     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8617                Assembler::halfword, /*acquire*/ false, /*release*/ true,
8618                /*weak*/ true, noreg);
8619     __ csetw($res$$Register, Assembler::EQ);
8620   %}
8621   ins_pipe(pipe_slow);
8622 %}
8623 
8624 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8625   match(Set res (WeakCompareAndSwapI mem (Binary oldval newval)));
8626   ins_cost(2 * VOLATILE_REF_COST);
8627   effect(KILL cr);
8628   format %{
8629     "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
8630     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8631   %}
8632   ins_encode %{
8633     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8634                Assembler::word, /*acquire*/ false, /*release*/ true,
8635                /*weak*/ true, noreg);
8636     __ csetw($res$$Register, Assembler::EQ);
8637   %}
8638   ins_pipe(pipe_slow);
8639 %}
8640 
8641 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
8642   match(Set res (WeakCompareAndSwapL mem (Binary oldval newval)));
8643   ins_cost(2 * VOLATILE_REF_COST);
8644   effect(KILL cr);
8645   format %{
8646     "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
8647     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8648   %}
8649   ins_encode %{
8650     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8651                Assembler::xword, /*acquire*/ false, /*release*/ true,
8652                /*weak*/ true, noreg);
8653     __ csetw($res$$Register, Assembler::EQ);
8654   %}
8655   ins_pipe(pipe_slow);
8656 %}
8657 
8658 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
8659   match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
8660   ins_cost(2 * VOLATILE_REF_COST);
8661   effect(KILL cr);
8662   format %{
8663     "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
8664     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8665   %}
8666   ins_encode %{
8667     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8668                Assembler::word, /*acquire*/ false, /*release*/ true,
8669                /*weak*/ true, noreg);
8670     __ csetw($res$$Register, Assembler::EQ);
8671   %}
8672   ins_pipe(pipe_slow);
8673 %}
8674 
8675 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8676   match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
8677   ins_cost(2 * VOLATILE_REF_COST);
8678   effect(KILL cr);
8679   format %{
8680     "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
8681     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8682   %}
8683   ins_encode %{
8684     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8685                Assembler::xword, /*acquire*/ false, /*release*/ true,
8686                /*weak*/ true, noreg);
8687     __ csetw($res$$Register, Assembler::EQ);
8688   %}
8689   ins_pipe(pipe_slow);
8690 %}
8691 
8692 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8693   predicate(needs_acquiring_load_exclusive(n));
8694   match(Set res (WeakCompareAndSwapB mem (Binary oldval newval)));
8695   ins_cost(VOLATILE_REF_COST);
8696   effect(KILL cr);
8697   format %{
8698     "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
8699     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8700   %}
8701   ins_encode %{
8702     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8703                Assembler::byte, /*acquire*/ true, /*release*/ true,
8704                /*weak*/ true, noreg);
8705     __ csetw($res$$Register, Assembler::EQ);
8706   %}
8707   ins_pipe(pipe_slow);
8708 %}
8709 
8710 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8711   predicate(needs_acquiring_load_exclusive(n));
8712   match(Set res (WeakCompareAndSwapS mem (Binary oldval newval)));
8713   ins_cost(VOLATILE_REF_COST);
8714   effect(KILL cr);
8715   format %{
8716     "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
8717     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8718   %}
8719   ins_encode %{
8720     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8721                Assembler::halfword, /*acquire*/ true, /*release*/ true,
8722                /*weak*/ true, noreg);
8723     __ csetw($res$$Register, Assembler::EQ);
8724   %}
8725   ins_pipe(pipe_slow);
8726 %}
8727 
8728 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8729   predicate(needs_acquiring_load_exclusive(n));
8730   match(Set res (WeakCompareAndSwapI mem (Binary oldval newval)));
8731   ins_cost(VOLATILE_REF_COST);
8732   effect(KILL cr);
8733   format %{
8734     "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
8735     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8736   %}
8737   ins_encode %{
8738     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8739                Assembler::word, /*acquire*/ true, /*release*/ true,
8740                /*weak*/ true, noreg);
8741     __ csetw($res$$Register, Assembler::EQ);
8742   %}
8743   ins_pipe(pipe_slow);
8744 %}
8745 
8746 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
8747   predicate(needs_acquiring_load_exclusive(n));
8748   match(Set res (WeakCompareAndSwapL mem (Binary oldval newval)));
8749   ins_cost(VOLATILE_REF_COST);
8750   effect(KILL cr);
8751   format %{
8752     "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
8753     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8754   %}
8755   ins_encode %{
8756     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8757                Assembler::xword, /*acquire*/ true, /*release*/ true,
8758                /*weak*/ true, noreg);
8759     __ csetw($res$$Register, Assembler::EQ);
8760   %}
8761   ins_pipe(pipe_slow);
8762 %}
8763 
8764 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
8765   predicate(needs_acquiring_load_exclusive(n));
8766   match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
8767   ins_cost(VOLATILE_REF_COST);
8768   effect(KILL cr);
8769   format %{
8770     "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
8771     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8772   %}
8773   ins_encode %{
8774     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8775                Assembler::word, /*acquire*/ true, /*release*/ true,
8776                /*weak*/ true, noreg);
8777     __ csetw($res$$Register, Assembler::EQ);
8778   %}
8779   ins_pipe(pipe_slow);
8780 %}
8781 
8782 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8783   predicate(needs_acquiring_load_exclusive(n));
8784   match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
8785   ins_cost(VOLATILE_REF_COST);
8786   effect(KILL cr);
8787   format %{
8788     "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
8789     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8790   %}
8791   ins_encode %{
8792     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8793                Assembler::xword, /*acquire*/ true, /*release*/ true,
8794                /*weak*/ true, noreg);
8795     __ csetw($res$$Register, Assembler::EQ);
8796   %}
8797   ins_pipe(pipe_slow);
8798 %}
8799 
8800 // END This section of the file is automatically generated. Do not edit --------------
8801 // ---------------------------------------------------------------------
8802 
8803 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{
8804   match(Set prev (GetAndSetI mem newv));
8805   ins_cost(2 * VOLATILE_REF_COST);
8806   format %{ "atomic_xchgw  $prev, $newv, [$mem]" %}
8807   ins_encode %{
8808     __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base));
8809   %}
8810   ins_pipe(pipe_serial);
8811 %}
8812 
8813 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{
8814   match(Set prev (GetAndSetL mem newv));
8815   ins_cost(2 * VOLATILE_REF_COST);
8816   format %{ "atomic_xchg  $prev, $newv, [$mem]" %}
8817   ins_encode %{
8818     __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
8819   %}
8820   ins_pipe(pipe_serial);
8821 %}
8822 
8823 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{
8824   match(Set prev (GetAndSetN mem newv));
8825   ins_cost(2 * VOLATILE_REF_COST);
8826   format %{ "atomic_xchgw $prev, $newv, [$mem]" %}
8827   ins_encode %{
8828     __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base));
8829   %}
8830   ins_pipe(pipe_serial);
8831 %}
8832 
8833 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{
8834   match(Set prev (GetAndSetP mem newv));
8835   ins_cost(2 * VOLATILE_REF_COST);
8836   format %{ "atomic_xchg  $prev, $newv, [$mem]" %}
8837   ins_encode %{
8838     __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
8839   %}
8840   ins_pipe(pipe_serial);
8841 %}
8842 
8843 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{
8844   predicate(needs_acquiring_load_exclusive(n));
8845   match(Set prev (GetAndSetI mem newv));
8846   ins_cost(VOLATILE_REF_COST);
8847   format %{ "atomic_xchgw_acq  $prev, $newv, [$mem]" %}
8848   ins_encode %{
8849     __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base));
8850   %}
8851   ins_pipe(pipe_serial);
8852 %}
8853 
8854 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{
8855   predicate(needs_acquiring_load_exclusive(n));
8856   match(Set prev (GetAndSetL mem newv));
8857   ins_cost(VOLATILE_REF_COST);
8858   format %{ "atomic_xchg_acq  $prev, $newv, [$mem]" %}
8859   ins_encode %{
8860     __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base));
8861   %}
8862   ins_pipe(pipe_serial);
8863 %}
8864 
8865 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{
8866   predicate(needs_acquiring_load_exclusive(n));
8867   match(Set prev (GetAndSetN mem newv));
8868   ins_cost(VOLATILE_REF_COST);
8869   format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %}
8870   ins_encode %{
8871     __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base));
8872   %}
8873   ins_pipe(pipe_serial);
8874 %}
8875 
8876 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{
8877   predicate(needs_acquiring_load_exclusive(n));
8878   match(Set prev (GetAndSetP mem newv));
8879   ins_cost(VOLATILE_REF_COST);
8880   format %{ "atomic_xchg_acq  $prev, $newv, [$mem]" %}
8881   ins_encode %{
8882     __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base));
8883   %}
8884   ins_pipe(pipe_serial);
8885 %}
8886 
8887 
8888 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{
8889   match(Set newval (GetAndAddL mem incr));
8890   ins_cost(2 * VOLATILE_REF_COST + 1);
8891   format %{ "get_and_addL $newval, [$mem], $incr" %}
8892   ins_encode %{
8893     __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base));
8894   %}
8895   ins_pipe(pipe_serial);
8896 %}
8897 
8898 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{
8899   predicate(n->as_LoadStore()->result_not_used());
8900   match(Set dummy (GetAndAddL mem incr));
8901   ins_cost(2 * VOLATILE_REF_COST);
8902   format %{ "get_and_addL [$mem], $incr" %}
8903   ins_encode %{
8904     __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base));
8905   %}
8906   ins_pipe(pipe_serial);
8907 %}
8908 
8909 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{
8910   match(Set newval (GetAndAddL mem incr));
8911   ins_cost(2 * VOLATILE_REF_COST + 1);
8912   format %{ "get_and_addL $newval, [$mem], $incr" %}
8913   ins_encode %{
8914     __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base));
8915   %}
8916   ins_pipe(pipe_serial);
8917 %}
8918 
8919 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{
8920   predicate(n->as_LoadStore()->result_not_used());
8921   match(Set dummy (GetAndAddL mem incr));
8922   ins_cost(2 * VOLATILE_REF_COST);
8923   format %{ "get_and_addL [$mem], $incr" %}
8924   ins_encode %{
8925     __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base));
8926   %}
8927   ins_pipe(pipe_serial);
8928 %}
8929 
8930 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{
8931   match(Set newval (GetAndAddI mem incr));
8932   ins_cost(2 * VOLATILE_REF_COST + 1);
8933   format %{ "get_and_addI $newval, [$mem], $incr" %}
8934   ins_encode %{
8935     __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base));
8936   %}
8937   ins_pipe(pipe_serial);
8938 %}
8939 
8940 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{
8941   predicate(n->as_LoadStore()->result_not_used());
8942   match(Set dummy (GetAndAddI mem incr));
8943   ins_cost(2 * VOLATILE_REF_COST);
8944   format %{ "get_and_addI [$mem], $incr" %}
8945   ins_encode %{
8946     __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base));
8947   %}
8948   ins_pipe(pipe_serial);
8949 %}
8950 
8951 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{
8952   match(Set newval (GetAndAddI mem incr));
8953   ins_cost(2 * VOLATILE_REF_COST + 1);
8954   format %{ "get_and_addI $newval, [$mem], $incr" %}
8955   ins_encode %{
8956     __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base));
8957   %}
8958   ins_pipe(pipe_serial);
8959 %}
8960 
8961 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{
8962   predicate(n->as_LoadStore()->result_not_used());
8963   match(Set dummy (GetAndAddI mem incr));
8964   ins_cost(2 * VOLATILE_REF_COST);
8965   format %{ "get_and_addI [$mem], $incr" %}
8966   ins_encode %{
8967     __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base));
8968   %}
8969   ins_pipe(pipe_serial);
8970 %}
8971 
8972 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{
8973   predicate(needs_acquiring_load_exclusive(n));
8974   match(Set newval (GetAndAddL mem incr));
8975   ins_cost(VOLATILE_REF_COST + 1);
8976   format %{ "get_and_addL_acq $newval, [$mem], $incr" %}
8977   ins_encode %{
8978     __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base));
8979   %}
8980   ins_pipe(pipe_serial);
8981 %}
8982 
8983 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{
8984   predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
8985   match(Set dummy (GetAndAddL mem incr));
8986   ins_cost(VOLATILE_REF_COST);
8987   format %{ "get_and_addL_acq [$mem], $incr" %}
8988   ins_encode %{
8989     __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base));
8990   %}
8991   ins_pipe(pipe_serial);
8992 %}
8993 
8994 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{
8995   predicate(needs_acquiring_load_exclusive(n));
8996   match(Set newval (GetAndAddL mem incr));
8997   ins_cost(VOLATILE_REF_COST + 1);
8998   format %{ "get_and_addL_acq $newval, [$mem], $incr" %}
8999   ins_encode %{
9000     __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base));
9001   %}
9002   ins_pipe(pipe_serial);
9003 %}
9004 
9005 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{
9006   predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
9007   match(Set dummy (GetAndAddL mem incr));
9008   ins_cost(VOLATILE_REF_COST);
9009   format %{ "get_and_addL_acq [$mem], $incr" %}
9010   ins_encode %{
9011     __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base));
9012   %}
9013   ins_pipe(pipe_serial);
9014 %}
9015 
9016 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{
9017   predicate(needs_acquiring_load_exclusive(n));
9018   match(Set newval (GetAndAddI mem incr));
9019   ins_cost(VOLATILE_REF_COST + 1);
9020   format %{ "get_and_addI_acq $newval, [$mem], $incr" %}
9021   ins_encode %{
9022     __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base));
9023   %}
9024   ins_pipe(pipe_serial);
9025 %}
9026 
9027 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{
9028   predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
9029   match(Set dummy (GetAndAddI mem incr));
9030   ins_cost(VOLATILE_REF_COST);
9031   format %{ "get_and_addI_acq [$mem], $incr" %}
9032   ins_encode %{
9033     __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base));
9034   %}
9035   ins_pipe(pipe_serial);
9036 %}
9037 
9038 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{
9039   predicate(needs_acquiring_load_exclusive(n));
9040   match(Set newval (GetAndAddI mem incr));
9041   ins_cost(VOLATILE_REF_COST + 1);
9042   format %{ "get_and_addI_acq $newval, [$mem], $incr" %}
9043   ins_encode %{
9044     __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base));
9045   %}
9046   ins_pipe(pipe_serial);
9047 %}
9048 
9049 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{
9050   predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
9051   match(Set dummy (GetAndAddI mem incr));
9052   ins_cost(VOLATILE_REF_COST);
9053   format %{ "get_and_addI_acq [$mem], $incr" %}
9054   ins_encode %{
9055     __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base));
9056   %}
9057   ins_pipe(pipe_serial);
9058 %}
9059 
9060 // Manifest a CmpL result in an integer register.
9061 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0)
9062 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags)
9063 %{
9064   match(Set dst (CmpL3 src1 src2));
9065   effect(KILL flags);
9066 
9067   ins_cost(INSN_COST * 6);
9068   format %{
9069       "cmp $src1, $src2"
9070       "csetw $dst, ne"
9071       "cnegw $dst, lt"
9072   %}
9073   // format %{ "CmpL3 $dst, $src1, $src2" %}
9074   ins_encode %{
9075     __ cmp($src1$$Register, $src2$$Register);
9076     __ csetw($dst$$Register, Assembler::NE);
9077     __ cnegw($dst$$Register, $dst$$Register, Assembler::LT);
9078   %}
9079 
9080   ins_pipe(pipe_class_default);
9081 %}
9082 
9083 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags)
9084 %{
9085   match(Set dst (CmpL3 src1 src2));
9086   effect(KILL flags);
9087 
9088   ins_cost(INSN_COST * 6);
9089   format %{
9090       "cmp $src1, $src2"
9091       "csetw $dst, ne"
9092       "cnegw $dst, lt"
9093   %}
9094   ins_encode %{
9095     int32_t con = (int32_t)$src2$$constant;
9096      if (con < 0) {
9097       __ adds(zr, $src1$$Register, -con);
9098     } else {
9099       __ subs(zr, $src1$$Register, con);
9100     }
9101     __ csetw($dst$$Register, Assembler::NE);
9102     __ cnegw($dst$$Register, $dst$$Register, Assembler::LT);
9103   %}
9104 
9105   ins_pipe(pipe_class_default);
9106 %}
9107 
9108 // ============================================================================
9109 // Conditional Move Instructions
9110 
9111 // n.b. we have identical rules for both a signed compare op (cmpOp)
9112 // and an unsigned compare op (cmpOpU). it would be nice if we could
9113 // define an op class which merged both inputs and use it to type the
9114 // argument to a single rule. unfortunatelyt his fails because the
9115 // opclass does not live up to the COND_INTER interface of its
9116 // component operands. When the generic code tries to negate the
9117 // operand it ends up running the generci Machoper::negate method
9118 // which throws a ShouldNotHappen. So, we have to provide two flavours
9119 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh).
9120 
9121 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9122   match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2)));
9123 
9124   ins_cost(INSN_COST * 2);
9125   format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int"  %}
9126 
9127   ins_encode %{
9128     __ cselw(as_Register($dst$$reg),
9129              as_Register($src2$$reg),
9130              as_Register($src1$$reg),
9131              (Assembler::Condition)$cmp$$cmpcode);
9132   %}
9133 
9134   ins_pipe(icond_reg_reg);
9135 %}
9136 
9137 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9138   match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2)));
9139 
9140   ins_cost(INSN_COST * 2);
9141   format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int"  %}
9142 
9143   ins_encode %{
9144     __ cselw(as_Register($dst$$reg),
9145              as_Register($src2$$reg),
9146              as_Register($src1$$reg),
9147              (Assembler::Condition)$cmp$$cmpcode);
9148   %}
9149 
9150   ins_pipe(icond_reg_reg);
9151 %}
9152 
9153 // special cases where one arg is zero
9154 
9155 // n.b. this is selected in preference to the rule above because it
9156 // avoids loading constant 0 into a source register
9157 
9158 // TODO
9159 // we ought only to be able to cull one of these variants as the ideal
9160 // transforms ought always to order the zero consistently (to left/right?)
9161 
9162 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{
9163   match(Set dst (CMoveI (Binary cmp cr) (Binary zero src)));
9164 
9165   ins_cost(INSN_COST * 2);
9166   format %{ "cselw $dst, $src, zr $cmp\t# signed, int"  %}
9167 
9168   ins_encode %{
9169     __ cselw(as_Register($dst$$reg),
9170              as_Register($src$$reg),
9171              zr,
9172              (Assembler::Condition)$cmp$$cmpcode);
9173   %}
9174 
9175   ins_pipe(icond_reg);
9176 %}
9177 
9178 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{
9179   match(Set dst (CMoveI (Binary cmp cr) (Binary zero src)));
9180 
9181   ins_cost(INSN_COST * 2);
9182   format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int"  %}
9183 
9184   ins_encode %{
9185     __ cselw(as_Register($dst$$reg),
9186              as_Register($src$$reg),
9187              zr,
9188              (Assembler::Condition)$cmp$$cmpcode);
9189   %}
9190 
9191   ins_pipe(icond_reg);
9192 %}
9193 
9194 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{
9195   match(Set dst (CMoveI (Binary cmp cr) (Binary src zero)));
9196 
9197   ins_cost(INSN_COST * 2);
9198   format %{ "cselw $dst, zr, $src $cmp\t# signed, int"  %}
9199 
9200   ins_encode %{
9201     __ cselw(as_Register($dst$$reg),
9202              zr,
9203              as_Register($src$$reg),
9204              (Assembler::Condition)$cmp$$cmpcode);
9205   %}
9206 
9207   ins_pipe(icond_reg);
9208 %}
9209 
9210 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{
9211   match(Set dst (CMoveI (Binary cmp cr) (Binary src zero)));
9212 
9213   ins_cost(INSN_COST * 2);
9214   format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int"  %}
9215 
9216   ins_encode %{
9217     __ cselw(as_Register($dst$$reg),
9218              zr,
9219              as_Register($src$$reg),
9220              (Assembler::Condition)$cmp$$cmpcode);
9221   %}
9222 
9223   ins_pipe(icond_reg);
9224 %}
9225 
9226 // special case for creating a boolean 0 or 1
9227 
9228 // n.b. this is selected in preference to the rule above because it
9229 // avoids loading constants 0 and 1 into a source register
9230 
9231 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{
9232   match(Set dst (CMoveI (Binary cmp cr) (Binary one zero)));
9233 
9234   ins_cost(INSN_COST * 2);
9235   format %{ "csincw $dst, zr, zr $cmp\t# signed, int"  %}
9236 
9237   ins_encode %{
9238     // equivalently
9239     // cset(as_Register($dst$$reg),
9240     //      negate_condition((Assembler::Condition)$cmp$$cmpcode));
9241     __ csincw(as_Register($dst$$reg),
9242              zr,
9243              zr,
9244              (Assembler::Condition)$cmp$$cmpcode);
9245   %}
9246 
9247   ins_pipe(icond_none);
9248 %}
9249 
9250 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{
9251   match(Set dst (CMoveI (Binary cmp cr) (Binary one zero)));
9252 
9253   ins_cost(INSN_COST * 2);
9254   format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int"  %}
9255 
9256   ins_encode %{
9257     // equivalently
9258     // cset(as_Register($dst$$reg),
9259     //      negate_condition((Assembler::Condition)$cmp$$cmpcode));
9260     __ csincw(as_Register($dst$$reg),
9261              zr,
9262              zr,
9263              (Assembler::Condition)$cmp$$cmpcode);
9264   %}
9265 
9266   ins_pipe(icond_none);
9267 %}
9268 
9269 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{
9270   match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2)));
9271 
9272   ins_cost(INSN_COST * 2);
9273   format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long"  %}
9274 
9275   ins_encode %{
9276     __ csel(as_Register($dst$$reg),
9277             as_Register($src2$$reg),
9278             as_Register($src1$$reg),
9279             (Assembler::Condition)$cmp$$cmpcode);
9280   %}
9281 
9282   ins_pipe(icond_reg_reg);
9283 %}
9284 
9285 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{
9286   match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2)));
9287 
9288   ins_cost(INSN_COST * 2);
9289   format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long"  %}
9290 
9291   ins_encode %{
9292     __ csel(as_Register($dst$$reg),
9293             as_Register($src2$$reg),
9294             as_Register($src1$$reg),
9295             (Assembler::Condition)$cmp$$cmpcode);
9296   %}
9297 
9298   ins_pipe(icond_reg_reg);
9299 %}
9300 
9301 // special cases where one arg is zero
9302 
9303 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{
9304   match(Set dst (CMoveL (Binary cmp cr) (Binary src zero)));
9305 
9306   ins_cost(INSN_COST * 2);
9307   format %{ "csel $dst, zr, $src $cmp\t# signed, long"  %}
9308 
9309   ins_encode %{
9310     __ csel(as_Register($dst$$reg),
9311             zr,
9312             as_Register($src$$reg),
9313             (Assembler::Condition)$cmp$$cmpcode);
9314   %}
9315 
9316   ins_pipe(icond_reg);
9317 %}
9318 
9319 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{
9320   match(Set dst (CMoveL (Binary cmp cr) (Binary src zero)));
9321 
9322   ins_cost(INSN_COST * 2);
9323   format %{ "csel $dst, zr, $src $cmp\t# unsigned, long"  %}
9324 
9325   ins_encode %{
9326     __ csel(as_Register($dst$$reg),
9327             zr,
9328             as_Register($src$$reg),
9329             (Assembler::Condition)$cmp$$cmpcode);
9330   %}
9331 
9332   ins_pipe(icond_reg);
9333 %}
9334 
9335 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{
9336   match(Set dst (CMoveL (Binary cmp cr) (Binary zero src)));
9337 
9338   ins_cost(INSN_COST * 2);
9339   format %{ "csel $dst, $src, zr $cmp\t# signed, long"  %}
9340 
9341   ins_encode %{
9342     __ csel(as_Register($dst$$reg),
9343             as_Register($src$$reg),
9344             zr,
9345             (Assembler::Condition)$cmp$$cmpcode);
9346   %}
9347 
9348   ins_pipe(icond_reg);
9349 %}
9350 
9351 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{
9352   match(Set dst (CMoveL (Binary cmp cr) (Binary zero src)));
9353 
9354   ins_cost(INSN_COST * 2);
9355   format %{ "csel $dst, $src, zr $cmp\t# unsigned, long"  %}
9356 
9357   ins_encode %{
9358     __ csel(as_Register($dst$$reg),
9359             as_Register($src$$reg),
9360             zr,
9361             (Assembler::Condition)$cmp$$cmpcode);
9362   %}
9363 
9364   ins_pipe(icond_reg);
9365 %}
9366 
9367 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{
9368   match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2)));
9369 
9370   ins_cost(INSN_COST * 2);
9371   format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr"  %}
9372 
9373   ins_encode %{
9374     __ csel(as_Register($dst$$reg),
9375             as_Register($src2$$reg),
9376             as_Register($src1$$reg),
9377             (Assembler::Condition)$cmp$$cmpcode);
9378   %}
9379 
9380   ins_pipe(icond_reg_reg);
9381 %}
9382 
9383 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{
9384   match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2)));
9385 
9386   ins_cost(INSN_COST * 2);
9387   format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr"  %}
9388 
9389   ins_encode %{
9390     __ csel(as_Register($dst$$reg),
9391             as_Register($src2$$reg),
9392             as_Register($src1$$reg),
9393             (Assembler::Condition)$cmp$$cmpcode);
9394   %}
9395 
9396   ins_pipe(icond_reg_reg);
9397 %}
9398 
9399 // special cases where one arg is zero
9400 
9401 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{
9402   match(Set dst (CMoveP (Binary cmp cr) (Binary src zero)));
9403 
9404   ins_cost(INSN_COST * 2);
9405   format %{ "csel $dst, zr, $src $cmp\t# signed, ptr"  %}
9406 
9407   ins_encode %{
9408     __ csel(as_Register($dst$$reg),
9409             zr,
9410             as_Register($src$$reg),
9411             (Assembler::Condition)$cmp$$cmpcode);
9412   %}
9413 
9414   ins_pipe(icond_reg);
9415 %}
9416 
9417 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{
9418   match(Set dst (CMoveP (Binary cmp cr) (Binary src zero)));
9419 
9420   ins_cost(INSN_COST * 2);
9421   format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr"  %}
9422 
9423   ins_encode %{
9424     __ csel(as_Register($dst$$reg),
9425             zr,
9426             as_Register($src$$reg),
9427             (Assembler::Condition)$cmp$$cmpcode);
9428   %}
9429 
9430   ins_pipe(icond_reg);
9431 %}
9432 
9433 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{
9434   match(Set dst (CMoveP (Binary cmp cr) (Binary zero src)));
9435 
9436   ins_cost(INSN_COST * 2);
9437   format %{ "csel $dst, $src, zr $cmp\t# signed, ptr"  %}
9438 
9439   ins_encode %{
9440     __ csel(as_Register($dst$$reg),
9441             as_Register($src$$reg),
9442             zr,
9443             (Assembler::Condition)$cmp$$cmpcode);
9444   %}
9445 
9446   ins_pipe(icond_reg);
9447 %}
9448 
9449 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{
9450   match(Set dst (CMoveP (Binary cmp cr) (Binary zero src)));
9451 
9452   ins_cost(INSN_COST * 2);
9453   format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr"  %}
9454 
9455   ins_encode %{
9456     __ csel(as_Register($dst$$reg),
9457             as_Register($src$$reg),
9458             zr,
9459             (Assembler::Condition)$cmp$$cmpcode);
9460   %}
9461 
9462   ins_pipe(icond_reg);
9463 %}
9464 
9465 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{
9466   match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2)));
9467 
9468   ins_cost(INSN_COST * 2);
9469   format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr"  %}
9470 
9471   ins_encode %{
9472     __ cselw(as_Register($dst$$reg),
9473              as_Register($src2$$reg),
9474              as_Register($src1$$reg),
9475              (Assembler::Condition)$cmp$$cmpcode);
9476   %}
9477 
9478   ins_pipe(icond_reg_reg);
9479 %}
9480 
9481 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{
9482   match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2)));
9483 
9484   ins_cost(INSN_COST * 2);
9485   format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr"  %}
9486 
9487   ins_encode %{
9488     __ cselw(as_Register($dst$$reg),
9489              as_Register($src2$$reg),
9490              as_Register($src1$$reg),
9491              (Assembler::Condition)$cmp$$cmpcode);
9492   %}
9493 
9494   ins_pipe(icond_reg_reg);
9495 %}
9496 
9497 // special cases where one arg is zero
9498 
9499 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{
9500   match(Set dst (CMoveN (Binary cmp cr) (Binary src zero)));
9501 
9502   ins_cost(INSN_COST * 2);
9503   format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr"  %}
9504 
9505   ins_encode %{
9506     __ cselw(as_Register($dst$$reg),
9507              zr,
9508              as_Register($src$$reg),
9509              (Assembler::Condition)$cmp$$cmpcode);
9510   %}
9511 
9512   ins_pipe(icond_reg);
9513 %}
9514 
9515 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{
9516   match(Set dst (CMoveN (Binary cmp cr) (Binary src zero)));
9517 
9518   ins_cost(INSN_COST * 2);
9519   format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr"  %}
9520 
9521   ins_encode %{
9522     __ cselw(as_Register($dst$$reg),
9523              zr,
9524              as_Register($src$$reg),
9525              (Assembler::Condition)$cmp$$cmpcode);
9526   %}
9527 
9528   ins_pipe(icond_reg);
9529 %}
9530 
9531 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{
9532   match(Set dst (CMoveN (Binary cmp cr) (Binary zero src)));
9533 
9534   ins_cost(INSN_COST * 2);
9535   format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr"  %}
9536 
9537   ins_encode %{
9538     __ cselw(as_Register($dst$$reg),
9539              as_Register($src$$reg),
9540              zr,
9541              (Assembler::Condition)$cmp$$cmpcode);
9542   %}
9543 
9544   ins_pipe(icond_reg);
9545 %}
9546 
9547 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{
9548   match(Set dst (CMoveN (Binary cmp cr) (Binary zero src)));
9549 
9550   ins_cost(INSN_COST * 2);
9551   format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr"  %}
9552 
9553   ins_encode %{
9554     __ cselw(as_Register($dst$$reg),
9555              as_Register($src$$reg),
9556              zr,
9557              (Assembler::Condition)$cmp$$cmpcode);
9558   %}
9559 
9560   ins_pipe(icond_reg);
9561 %}
9562 
9563 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1,  vRegF src2)
9564 %{
9565   match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2)));
9566 
9567   ins_cost(INSN_COST * 3);
9568 
9569   format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %}
9570   ins_encode %{
9571     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
9572     __ fcsels(as_FloatRegister($dst$$reg),
9573               as_FloatRegister($src2$$reg),
9574               as_FloatRegister($src1$$reg),
9575               cond);
9576   %}
9577 
9578   ins_pipe(fp_cond_reg_reg_s);
9579 %}
9580 
9581 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1,  vRegF src2)
9582 %{
9583   match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2)));
9584 
9585   ins_cost(INSN_COST * 3);
9586 
9587   format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %}
9588   ins_encode %{
9589     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
9590     __ fcsels(as_FloatRegister($dst$$reg),
9591               as_FloatRegister($src2$$reg),
9592               as_FloatRegister($src1$$reg),
9593               cond);
9594   %}
9595 
9596   ins_pipe(fp_cond_reg_reg_s);
9597 %}
9598 
9599 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1,  vRegD src2)
9600 %{
9601   match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2)));
9602 
9603   ins_cost(INSN_COST * 3);
9604 
9605   format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %}
9606   ins_encode %{
9607     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
9608     __ fcseld(as_FloatRegister($dst$$reg),
9609               as_FloatRegister($src2$$reg),
9610               as_FloatRegister($src1$$reg),
9611               cond);
9612   %}
9613 
9614   ins_pipe(fp_cond_reg_reg_d);
9615 %}
9616 
9617 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1,  vRegD src2)
9618 %{
9619   match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2)));
9620 
9621   ins_cost(INSN_COST * 3);
9622 
9623   format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %}
9624   ins_encode %{
9625     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
9626     __ fcseld(as_FloatRegister($dst$$reg),
9627               as_FloatRegister($src2$$reg),
9628               as_FloatRegister($src1$$reg),
9629               cond);
9630   %}
9631 
9632   ins_pipe(fp_cond_reg_reg_d);
9633 %}
9634 
9635 // ============================================================================
9636 // Arithmetic Instructions
9637 //
9638 
9639 // Integer Addition
9640 
9641 // TODO
9642 // these currently employ operations which do not set CR and hence are
9643 // not flagged as killing CR but we would like to isolate the cases
9644 // where we want to set flags from those where we don't. need to work
9645 // out how to do that.
9646 
9647 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9648   match(Set dst (AddI src1 src2));
9649 
9650   ins_cost(INSN_COST);
9651   format %{ "addw  $dst, $src1, $src2" %}
9652 
9653   ins_encode %{
9654     __ addw(as_Register($dst$$reg),
9655             as_Register($src1$$reg),
9656             as_Register($src2$$reg));
9657   %}
9658 
9659   ins_pipe(ialu_reg_reg);
9660 %}
9661 
9662 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{
9663   match(Set dst (AddI src1 src2));
9664 
9665   ins_cost(INSN_COST);
9666   format %{ "addw $dst, $src1, $src2" %}
9667 
9668   // use opcode to indicate that this is an add not a sub
9669   opcode(0x0);
9670 
9671   ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2));
9672 
9673   ins_pipe(ialu_reg_imm);
9674 %}
9675 
9676 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{
9677   match(Set dst (AddI (ConvL2I src1) src2));
9678 
9679   ins_cost(INSN_COST);
9680   format %{ "addw $dst, $src1, $src2" %}
9681 
9682   // use opcode to indicate that this is an add not a sub
9683   opcode(0x0);
9684 
9685   ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2));
9686 
9687   ins_pipe(ialu_reg_imm);
9688 %}
9689 
9690 // Pointer Addition
9691 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{
9692   match(Set dst (AddP src1 src2));
9693 
9694   ins_cost(INSN_COST);
9695   format %{ "add $dst, $src1, $src2\t# ptr" %}
9696 
9697   ins_encode %{
9698     __ add(as_Register($dst$$reg),
9699            as_Register($src1$$reg),
9700            as_Register($src2$$reg));
9701   %}
9702 
9703   ins_pipe(ialu_reg_reg);
9704 %}
9705 
9706 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{
9707   match(Set dst (AddP src1 (ConvI2L src2)));
9708 
9709   ins_cost(1.9 * INSN_COST);
9710   format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %}
9711 
9712   ins_encode %{
9713     __ add(as_Register($dst$$reg),
9714            as_Register($src1$$reg),
9715            as_Register($src2$$reg), ext::sxtw);
9716   %}
9717 
9718   ins_pipe(ialu_reg_reg);
9719 %}
9720 
9721 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{
9722   match(Set dst (AddP src1 (LShiftL src2 scale)));
9723 
9724   ins_cost(1.9 * INSN_COST);
9725   format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %}
9726 
9727   ins_encode %{
9728     __ lea(as_Register($dst$$reg),
9729            Address(as_Register($src1$$reg), as_Register($src2$$reg),
9730                    Address::lsl($scale$$constant)));
9731   %}
9732 
9733   ins_pipe(ialu_reg_reg_shift);
9734 %}
9735 
9736 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{
9737   match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale)));
9738 
9739   ins_cost(1.9 * INSN_COST);
9740   format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %}
9741 
9742   ins_encode %{
9743     __ lea(as_Register($dst$$reg),
9744            Address(as_Register($src1$$reg), as_Register($src2$$reg),
9745                    Address::sxtw($scale$$constant)));
9746   %}
9747 
9748   ins_pipe(ialu_reg_reg_shift);
9749 %}
9750 
9751 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{
9752   match(Set dst (LShiftL (ConvI2L src) scale));
9753 
9754   ins_cost(INSN_COST);
9755   format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %}
9756 
9757   ins_encode %{
9758     __ sbfiz(as_Register($dst$$reg),
9759           as_Register($src$$reg),
9760           $scale$$constant & 63, MIN(32, (-$scale$$constant) & 63));
9761   %}
9762 
9763   ins_pipe(ialu_reg_shift);
9764 %}
9765 
9766 // Pointer Immediate Addition
9767 // n.b. this needs to be more expensive than using an indirect memory
9768 // operand
9769 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{
9770   match(Set dst (AddP src1 src2));
9771 
9772   ins_cost(INSN_COST);
9773   format %{ "add $dst, $src1, $src2\t# ptr" %}
9774 
9775   // use opcode to indicate that this is an add not a sub
9776   opcode(0x0);
9777 
9778   ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) );
9779 
9780   ins_pipe(ialu_reg_imm);
9781 %}
9782 
9783 // Long Addition
9784 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
9785 
9786   match(Set dst (AddL src1 src2));
9787 
9788   ins_cost(INSN_COST);
9789   format %{ "add  $dst, $src1, $src2" %}
9790 
9791   ins_encode %{
9792     __ add(as_Register($dst$$reg),
9793            as_Register($src1$$reg),
9794            as_Register($src2$$reg));
9795   %}
9796 
9797   ins_pipe(ialu_reg_reg);
9798 %}
9799 
9800 // No constant pool entries requiredLong Immediate Addition.
9801 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{
9802   match(Set dst (AddL src1 src2));
9803 
9804   ins_cost(INSN_COST);
9805   format %{ "add $dst, $src1, $src2" %}
9806 
9807   // use opcode to indicate that this is an add not a sub
9808   opcode(0x0);
9809 
9810   ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) );
9811 
9812   ins_pipe(ialu_reg_imm);
9813 %}
9814 
9815 // Integer Subtraction
9816 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9817   match(Set dst (SubI src1 src2));
9818 
9819   ins_cost(INSN_COST);
9820   format %{ "subw  $dst, $src1, $src2" %}
9821 
9822   ins_encode %{
9823     __ subw(as_Register($dst$$reg),
9824             as_Register($src1$$reg),
9825             as_Register($src2$$reg));
9826   %}
9827 
9828   ins_pipe(ialu_reg_reg);
9829 %}
9830 
9831 // Immediate Subtraction
9832 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{
9833   match(Set dst (SubI src1 src2));
9834 
9835   ins_cost(INSN_COST);
9836   format %{ "subw $dst, $src1, $src2" %}
9837 
9838   // use opcode to indicate that this is a sub not an add
9839   opcode(0x1);
9840 
9841   ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2));
9842 
9843   ins_pipe(ialu_reg_imm);
9844 %}
9845 
9846 // Long Subtraction
9847 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
9848 
9849   match(Set dst (SubL src1 src2));
9850 
9851   ins_cost(INSN_COST);
9852   format %{ "sub  $dst, $src1, $src2" %}
9853 
9854   ins_encode %{
9855     __ sub(as_Register($dst$$reg),
9856            as_Register($src1$$reg),
9857            as_Register($src2$$reg));
9858   %}
9859 
9860   ins_pipe(ialu_reg_reg);
9861 %}
9862 
9863 // No constant pool entries requiredLong Immediate Subtraction.
9864 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{
9865   match(Set dst (SubL src1 src2));
9866 
9867   ins_cost(INSN_COST);
9868   format %{ "sub$dst, $src1, $src2" %}
9869 
9870   // use opcode to indicate that this is a sub not an add
9871   opcode(0x1);
9872 
9873   ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) );
9874 
9875   ins_pipe(ialu_reg_imm);
9876 %}
9877 
9878 // Integer Negation (special case for sub)
9879 
9880 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{
9881   match(Set dst (SubI zero src));
9882 
9883   ins_cost(INSN_COST);
9884   format %{ "negw $dst, $src\t# int" %}
9885 
9886   ins_encode %{
9887     __ negw(as_Register($dst$$reg),
9888             as_Register($src$$reg));
9889   %}
9890 
9891   ins_pipe(ialu_reg);
9892 %}
9893 
9894 // Long Negation
9895 
9896 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{
9897   match(Set dst (SubL zero src));
9898 
9899   ins_cost(INSN_COST);
9900   format %{ "neg $dst, $src\t# long" %}
9901 
9902   ins_encode %{
9903     __ neg(as_Register($dst$$reg),
9904            as_Register($src$$reg));
9905   %}
9906 
9907   ins_pipe(ialu_reg);
9908 %}
9909 
9910 // Integer Multiply
9911 
9912 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9913   match(Set dst (MulI src1 src2));
9914 
9915   ins_cost(INSN_COST * 3);
9916   format %{ "mulw  $dst, $src1, $src2" %}
9917 
9918   ins_encode %{
9919     __ mulw(as_Register($dst$$reg),
9920             as_Register($src1$$reg),
9921             as_Register($src2$$reg));
9922   %}
9923 
9924   ins_pipe(imul_reg_reg);
9925 %}
9926 
9927 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9928   match(Set dst (MulL (ConvI2L src1) (ConvI2L src2)));
9929 
9930   ins_cost(INSN_COST * 3);
9931   format %{ "smull  $dst, $src1, $src2" %}
9932 
9933   ins_encode %{
9934     __ smull(as_Register($dst$$reg),
9935              as_Register($src1$$reg),
9936              as_Register($src2$$reg));
9937   %}
9938 
9939   ins_pipe(imul_reg_reg);
9940 %}
9941 
9942 // Long Multiply
9943 
9944 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
9945   match(Set dst (MulL src1 src2));
9946 
9947   ins_cost(INSN_COST * 5);
9948   format %{ "mul  $dst, $src1, $src2" %}
9949 
9950   ins_encode %{
9951     __ mul(as_Register($dst$$reg),
9952            as_Register($src1$$reg),
9953            as_Register($src2$$reg));
9954   %}
9955 
9956   ins_pipe(lmul_reg_reg);
9957 %}
9958 
9959 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr)
9960 %{
9961   match(Set dst (MulHiL src1 src2));
9962 
9963   ins_cost(INSN_COST * 7);
9964   format %{ "smulh   $dst, $src1, $src2, \t# mulhi" %}
9965 
9966   ins_encode %{
9967     __ smulh(as_Register($dst$$reg),
9968              as_Register($src1$$reg),
9969              as_Register($src2$$reg));
9970   %}
9971 
9972   ins_pipe(lmul_reg_reg);
9973 %}
9974 
9975 // Combined Integer Multiply & Add/Sub
9976 
9977 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{
9978   match(Set dst (AddI src3 (MulI src1 src2)));
9979 
9980   ins_cost(INSN_COST * 3);
9981   format %{ "madd  $dst, $src1, $src2, $src3" %}
9982 
9983   ins_encode %{
9984     __ maddw(as_Register($dst$$reg),
9985              as_Register($src1$$reg),
9986              as_Register($src2$$reg),
9987              as_Register($src3$$reg));
9988   %}
9989 
9990   ins_pipe(imac_reg_reg);
9991 %}
9992 
9993 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{
9994   match(Set dst (SubI src3 (MulI src1 src2)));
9995 
9996   ins_cost(INSN_COST * 3);
9997   format %{ "msub  $dst, $src1, $src2, $src3" %}
9998 
9999   ins_encode %{
10000     __ msubw(as_Register($dst$$reg),
10001              as_Register($src1$$reg),
10002              as_Register($src2$$reg),
10003              as_Register($src3$$reg));
10004   %}
10005 
10006   ins_pipe(imac_reg_reg);
10007 %}
10008 
10009 // Combined Integer Multiply & Neg
10010 
10011 instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{
10012   match(Set dst (MulI (SubI zero src1) src2));
10013   match(Set dst (MulI src1 (SubI zero src2)));
10014 
10015   ins_cost(INSN_COST * 3);
10016   format %{ "mneg  $dst, $src1, $src2" %}
10017 
10018   ins_encode %{
10019     __ mnegw(as_Register($dst$$reg),
10020              as_Register($src1$$reg),
10021              as_Register($src2$$reg));
10022   %}
10023 
10024   ins_pipe(imac_reg_reg);
10025 %}
10026 
10027 // Combined Long Multiply & Add/Sub
10028 
10029 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{
10030   match(Set dst (AddL src3 (MulL src1 src2)));
10031 
10032   ins_cost(INSN_COST * 5);
10033   format %{ "madd  $dst, $src1, $src2, $src3" %}
10034 
10035   ins_encode %{
10036     __ madd(as_Register($dst$$reg),
10037             as_Register($src1$$reg),
10038             as_Register($src2$$reg),
10039             as_Register($src3$$reg));
10040   %}
10041 
10042   ins_pipe(lmac_reg_reg);
10043 %}
10044 
10045 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{
10046   match(Set dst (SubL src3 (MulL src1 src2)));
10047 
10048   ins_cost(INSN_COST * 5);
10049   format %{ "msub  $dst, $src1, $src2, $src3" %}
10050 
10051   ins_encode %{
10052     __ msub(as_Register($dst$$reg),
10053             as_Register($src1$$reg),
10054             as_Register($src2$$reg),
10055             as_Register($src3$$reg));
10056   %}
10057 
10058   ins_pipe(lmac_reg_reg);
10059 %}
10060 
10061 // Combined Long Multiply & Neg
10062 
10063 instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{
10064   match(Set dst (MulL (SubL zero src1) src2));
10065   match(Set dst (MulL src1 (SubL zero src2)));
10066 
10067   ins_cost(INSN_COST * 5);
10068   format %{ "mneg  $dst, $src1, $src2" %}
10069 
10070   ins_encode %{
10071     __ mneg(as_Register($dst$$reg),
10072             as_Register($src1$$reg),
10073             as_Register($src2$$reg));
10074   %}
10075 
10076   ins_pipe(lmac_reg_reg);
10077 %}
10078 
10079 // Integer Divide
10080 
10081 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10082   match(Set dst (DivI src1 src2));
10083 
10084   ins_cost(INSN_COST * 19);
10085   format %{ "sdivw  $dst, $src1, $src2" %}
10086 
10087   ins_encode(aarch64_enc_divw(dst, src1, src2));
10088   ins_pipe(idiv_reg_reg);
10089 %}
10090 
10091 instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{
10092   match(Set dst (URShiftI (RShiftI src1 div1) div2));
10093   ins_cost(INSN_COST);
10094   format %{ "lsrw $dst, $src1, $div1" %}
10095   ins_encode %{
10096     __ lsrw(as_Register($dst$$reg), as_Register($src1$$reg), 31);
10097   %}
10098   ins_pipe(ialu_reg_shift);
10099 %}
10100 
10101 instruct div2Round(iRegINoSp dst, iRegIorL2I src, immI_31 div1, immI_31 div2) %{
10102   match(Set dst (AddI src (URShiftI (RShiftI src div1) div2)));
10103   ins_cost(INSN_COST);
10104   format %{ "addw $dst, $src, LSR $div1" %}
10105 
10106   ins_encode %{
10107     __ addw(as_Register($dst$$reg),
10108               as_Register($src$$reg),
10109               as_Register($src$$reg),
10110               Assembler::LSR, 31);
10111   %}
10112   ins_pipe(ialu_reg);
10113 %}
10114 
10115 // Long Divide
10116 
10117 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10118   match(Set dst (DivL src1 src2));
10119 
10120   ins_cost(INSN_COST * 35);
10121   format %{ "sdiv   $dst, $src1, $src2" %}
10122 
10123   ins_encode(aarch64_enc_div(dst, src1, src2));
10124   ins_pipe(ldiv_reg_reg);
10125 %}
10126 
10127 instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{
10128   match(Set dst (URShiftL (RShiftL src1 div1) div2));
10129   ins_cost(INSN_COST);
10130   format %{ "lsr $dst, $src1, $div1" %}
10131   ins_encode %{
10132     __ lsr(as_Register($dst$$reg), as_Register($src1$$reg), 63);
10133   %}
10134   ins_pipe(ialu_reg_shift);
10135 %}
10136 
10137 instruct div2RoundL(iRegLNoSp dst, iRegL src, immI_63 div1, immI_63 div2) %{
10138   match(Set dst (AddL src (URShiftL (RShiftL src div1) div2)));
10139   ins_cost(INSN_COST);
10140   format %{ "add $dst, $src, $div1" %}
10141 
10142   ins_encode %{
10143     __ add(as_Register($dst$$reg),
10144               as_Register($src$$reg),
10145               as_Register($src$$reg),
10146               Assembler::LSR, 63);
10147   %}
10148   ins_pipe(ialu_reg);
10149 %}
10150 
10151 // Integer Remainder
10152 
10153 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10154   match(Set dst (ModI src1 src2));
10155 
10156   ins_cost(INSN_COST * 22);
10157   format %{ "sdivw  rscratch1, $src1, $src2\n\t"
10158             "msubw($dst, rscratch1, $src2, $src1" %}
10159 
10160   ins_encode(aarch64_enc_modw(dst, src1, src2));
10161   ins_pipe(idiv_reg_reg);
10162 %}
10163 
10164 // Long Remainder
10165 
10166 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10167   match(Set dst (ModL src1 src2));
10168 
10169   ins_cost(INSN_COST * 38);
10170   format %{ "sdiv   rscratch1, $src1, $src2\n"
10171             "msub($dst, rscratch1, $src2, $src1" %}
10172 
10173   ins_encode(aarch64_enc_mod(dst, src1, src2));
10174   ins_pipe(ldiv_reg_reg);
10175 %}
10176 
10177 // Integer Shifts
10178 
10179 // Shift Left Register
10180 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10181   match(Set dst (LShiftI src1 src2));
10182 
10183   ins_cost(INSN_COST * 2);
10184   format %{ "lslvw  $dst, $src1, $src2" %}
10185 
10186   ins_encode %{
10187     __ lslvw(as_Register($dst$$reg),
10188              as_Register($src1$$reg),
10189              as_Register($src2$$reg));
10190   %}
10191 
10192   ins_pipe(ialu_reg_reg_vshift);
10193 %}
10194 
10195 // Shift Left Immediate
10196 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
10197   match(Set dst (LShiftI src1 src2));
10198 
10199   ins_cost(INSN_COST);
10200   format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %}
10201 
10202   ins_encode %{
10203     __ lslw(as_Register($dst$$reg),
10204             as_Register($src1$$reg),
10205             $src2$$constant & 0x1f);
10206   %}
10207 
10208   ins_pipe(ialu_reg_shift);
10209 %}
10210 
10211 // Shift Right Logical Register
10212 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10213   match(Set dst (URShiftI src1 src2));
10214 
10215   ins_cost(INSN_COST * 2);
10216   format %{ "lsrvw  $dst, $src1, $src2" %}
10217 
10218   ins_encode %{
10219     __ lsrvw(as_Register($dst$$reg),
10220              as_Register($src1$$reg),
10221              as_Register($src2$$reg));
10222   %}
10223 
10224   ins_pipe(ialu_reg_reg_vshift);
10225 %}
10226 
10227 // Shift Right Logical Immediate
10228 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
10229   match(Set dst (URShiftI src1 src2));
10230 
10231   ins_cost(INSN_COST);
10232   format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %}
10233 
10234   ins_encode %{
10235     __ lsrw(as_Register($dst$$reg),
10236             as_Register($src1$$reg),
10237             $src2$$constant & 0x1f);
10238   %}
10239 
10240   ins_pipe(ialu_reg_shift);
10241 %}
10242 
10243 // Shift Right Arithmetic Register
10244 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10245   match(Set dst (RShiftI src1 src2));
10246 
10247   ins_cost(INSN_COST * 2);
10248   format %{ "asrvw  $dst, $src1, $src2" %}
10249 
10250   ins_encode %{
10251     __ asrvw(as_Register($dst$$reg),
10252              as_Register($src1$$reg),
10253              as_Register($src2$$reg));
10254   %}
10255 
10256   ins_pipe(ialu_reg_reg_vshift);
10257 %}
10258 
10259 // Shift Right Arithmetic Immediate
10260 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
10261   match(Set dst (RShiftI src1 src2));
10262 
10263   ins_cost(INSN_COST);
10264   format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %}
10265 
10266   ins_encode %{
10267     __ asrw(as_Register($dst$$reg),
10268             as_Register($src1$$reg),
10269             $src2$$constant & 0x1f);
10270   %}
10271 
10272   ins_pipe(ialu_reg_shift);
10273 %}
10274 
10275 // Combined Int Mask and Right Shift (using UBFM)
10276 // TODO
10277 
10278 // Long Shifts
10279 
10280 // Shift Left Register
10281 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
10282   match(Set dst (LShiftL src1 src2));
10283 
10284   ins_cost(INSN_COST * 2);
10285   format %{ "lslv  $dst, $src1, $src2" %}
10286 
10287   ins_encode %{
10288     __ lslv(as_Register($dst$$reg),
10289             as_Register($src1$$reg),
10290             as_Register($src2$$reg));
10291   %}
10292 
10293   ins_pipe(ialu_reg_reg_vshift);
10294 %}
10295 
10296 // Shift Left Immediate
10297 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
10298   match(Set dst (LShiftL src1 src2));
10299 
10300   ins_cost(INSN_COST);
10301   format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %}
10302 
10303   ins_encode %{
10304     __ lsl(as_Register($dst$$reg),
10305             as_Register($src1$$reg),
10306             $src2$$constant & 0x3f);
10307   %}
10308 
10309   ins_pipe(ialu_reg_shift);
10310 %}
10311 
10312 // Shift Right Logical Register
10313 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
10314   match(Set dst (URShiftL src1 src2));
10315 
10316   ins_cost(INSN_COST * 2);
10317   format %{ "lsrv  $dst, $src1, $src2" %}
10318 
10319   ins_encode %{
10320     __ lsrv(as_Register($dst$$reg),
10321             as_Register($src1$$reg),
10322             as_Register($src2$$reg));
10323   %}
10324 
10325   ins_pipe(ialu_reg_reg_vshift);
10326 %}
10327 
10328 // Shift Right Logical Immediate
10329 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
10330   match(Set dst (URShiftL src1 src2));
10331 
10332   ins_cost(INSN_COST);
10333   format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %}
10334 
10335   ins_encode %{
10336     __ lsr(as_Register($dst$$reg),
10337            as_Register($src1$$reg),
10338            $src2$$constant & 0x3f);
10339   %}
10340 
10341   ins_pipe(ialu_reg_shift);
10342 %}
10343 
10344 // A special-case pattern for card table stores.
10345 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{
10346   match(Set dst (URShiftL (CastP2X src1) src2));
10347 
10348   ins_cost(INSN_COST);
10349   format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %}
10350 
10351   ins_encode %{
10352     __ lsr(as_Register($dst$$reg),
10353            as_Register($src1$$reg),
10354            $src2$$constant & 0x3f);
10355   %}
10356 
10357   ins_pipe(ialu_reg_shift);
10358 %}
10359 
10360 // Shift Right Arithmetic Register
10361 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
10362   match(Set dst (RShiftL src1 src2));
10363 
10364   ins_cost(INSN_COST * 2);
10365   format %{ "asrv  $dst, $src1, $src2" %}
10366 
10367   ins_encode %{
10368     __ asrv(as_Register($dst$$reg),
10369             as_Register($src1$$reg),
10370             as_Register($src2$$reg));
10371   %}
10372 
10373   ins_pipe(ialu_reg_reg_vshift);
10374 %}
10375 
10376 // Shift Right Arithmetic Immediate
10377 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
10378   match(Set dst (RShiftL src1 src2));
10379 
10380   ins_cost(INSN_COST);
10381   format %{ "asr $dst, $src1, ($src2 & 0x3f)" %}
10382 
10383   ins_encode %{
10384     __ asr(as_Register($dst$$reg),
10385            as_Register($src1$$reg),
10386            $src2$$constant & 0x3f);
10387   %}
10388 
10389   ins_pipe(ialu_reg_shift);
10390 %}
10391 
10392 // BEGIN This section of the file is automatically generated. Do not edit --------------
10393 
10394 instruct regL_not_reg(iRegLNoSp dst,
10395                          iRegL src1, immL_M1 m1,
10396                          rFlagsReg cr) %{
10397   match(Set dst (XorL src1 m1));
10398   ins_cost(INSN_COST);
10399   format %{ "eon  $dst, $src1, zr" %}
10400 
10401   ins_encode %{
10402     __ eon(as_Register($dst$$reg),
10403               as_Register($src1$$reg),
10404               zr,
10405               Assembler::LSL, 0);
10406   %}
10407 
10408   ins_pipe(ialu_reg);
10409 %}
10410 instruct regI_not_reg(iRegINoSp dst,
10411                          iRegIorL2I src1, immI_M1 m1,
10412                          rFlagsReg cr) %{
10413   match(Set dst (XorI src1 m1));
10414   ins_cost(INSN_COST);
10415   format %{ "eonw  $dst, $src1, zr" %}
10416 
10417   ins_encode %{
10418     __ eonw(as_Register($dst$$reg),
10419               as_Register($src1$$reg),
10420               zr,
10421               Assembler::LSL, 0);
10422   %}
10423 
10424   ins_pipe(ialu_reg);
10425 %}
10426 
10427 instruct AndI_reg_not_reg(iRegINoSp dst,
10428                          iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1,
10429                          rFlagsReg cr) %{
10430   match(Set dst (AndI src1 (XorI src2 m1)));
10431   ins_cost(INSN_COST);
10432   format %{ "bicw  $dst, $src1, $src2" %}
10433 
10434   ins_encode %{
10435     __ bicw(as_Register($dst$$reg),
10436               as_Register($src1$$reg),
10437               as_Register($src2$$reg),
10438               Assembler::LSL, 0);
10439   %}
10440 
10441   ins_pipe(ialu_reg_reg);
10442 %}
10443 
10444 instruct AndL_reg_not_reg(iRegLNoSp dst,
10445                          iRegL src1, iRegL src2, immL_M1 m1,
10446                          rFlagsReg cr) %{
10447   match(Set dst (AndL src1 (XorL src2 m1)));
10448   ins_cost(INSN_COST);
10449   format %{ "bic  $dst, $src1, $src2" %}
10450 
10451   ins_encode %{
10452     __ bic(as_Register($dst$$reg),
10453               as_Register($src1$$reg),
10454               as_Register($src2$$reg),
10455               Assembler::LSL, 0);
10456   %}
10457 
10458   ins_pipe(ialu_reg_reg);
10459 %}
10460 
10461 instruct OrI_reg_not_reg(iRegINoSp dst,
10462                          iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1,
10463                          rFlagsReg cr) %{
10464   match(Set dst (OrI src1 (XorI src2 m1)));
10465   ins_cost(INSN_COST);
10466   format %{ "ornw  $dst, $src1, $src2" %}
10467 
10468   ins_encode %{
10469     __ ornw(as_Register($dst$$reg),
10470               as_Register($src1$$reg),
10471               as_Register($src2$$reg),
10472               Assembler::LSL, 0);
10473   %}
10474 
10475   ins_pipe(ialu_reg_reg);
10476 %}
10477 
10478 instruct OrL_reg_not_reg(iRegLNoSp dst,
10479                          iRegL src1, iRegL src2, immL_M1 m1,
10480                          rFlagsReg cr) %{
10481   match(Set dst (OrL src1 (XorL src2 m1)));
10482   ins_cost(INSN_COST);
10483   format %{ "orn  $dst, $src1, $src2" %}
10484 
10485   ins_encode %{
10486     __ orn(as_Register($dst$$reg),
10487               as_Register($src1$$reg),
10488               as_Register($src2$$reg),
10489               Assembler::LSL, 0);
10490   %}
10491 
10492   ins_pipe(ialu_reg_reg);
10493 %}
10494 
10495 instruct XorI_reg_not_reg(iRegINoSp dst,
10496                          iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1,
10497                          rFlagsReg cr) %{
10498   match(Set dst (XorI m1 (XorI src2 src1)));
10499   ins_cost(INSN_COST);
10500   format %{ "eonw  $dst, $src1, $src2" %}
10501 
10502   ins_encode %{
10503     __ eonw(as_Register($dst$$reg),
10504               as_Register($src1$$reg),
10505               as_Register($src2$$reg),
10506               Assembler::LSL, 0);
10507   %}
10508 
10509   ins_pipe(ialu_reg_reg);
10510 %}
10511 
10512 instruct XorL_reg_not_reg(iRegLNoSp dst,
10513                          iRegL src1, iRegL src2, immL_M1 m1,
10514                          rFlagsReg cr) %{
10515   match(Set dst (XorL m1 (XorL src2 src1)));
10516   ins_cost(INSN_COST);
10517   format %{ "eon  $dst, $src1, $src2" %}
10518 
10519   ins_encode %{
10520     __ eon(as_Register($dst$$reg),
10521               as_Register($src1$$reg),
10522               as_Register($src2$$reg),
10523               Assembler::LSL, 0);
10524   %}
10525 
10526   ins_pipe(ialu_reg_reg);
10527 %}
10528 
10529 instruct AndI_reg_URShift_not_reg(iRegINoSp dst,
10530                          iRegIorL2I src1, iRegIorL2I src2,
10531                          immI src3, immI_M1 src4, rFlagsReg cr) %{
10532   match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4)));
10533   ins_cost(1.9 * INSN_COST);
10534   format %{ "bicw  $dst, $src1, $src2, LSR $src3" %}
10535 
10536   ins_encode %{
10537     __ bicw(as_Register($dst$$reg),
10538               as_Register($src1$$reg),
10539               as_Register($src2$$reg),
10540               Assembler::LSR,
10541               $src3$$constant & 0x1f);
10542   %}
10543 
10544   ins_pipe(ialu_reg_reg_shift);
10545 %}
10546 
10547 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst,
10548                          iRegL src1, iRegL src2,
10549                          immI src3, immL_M1 src4, rFlagsReg cr) %{
10550   match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4)));
10551   ins_cost(1.9 * INSN_COST);
10552   format %{ "bic  $dst, $src1, $src2, LSR $src3" %}
10553 
10554   ins_encode %{
10555     __ bic(as_Register($dst$$reg),
10556               as_Register($src1$$reg),
10557               as_Register($src2$$reg),
10558               Assembler::LSR,
10559               $src3$$constant & 0x3f);
10560   %}
10561 
10562   ins_pipe(ialu_reg_reg_shift);
10563 %}
10564 
10565 instruct AndI_reg_RShift_not_reg(iRegINoSp dst,
10566                          iRegIorL2I src1, iRegIorL2I src2,
10567                          immI src3, immI_M1 src4, rFlagsReg cr) %{
10568   match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4)));
10569   ins_cost(1.9 * INSN_COST);
10570   format %{ "bicw  $dst, $src1, $src2, ASR $src3" %}
10571 
10572   ins_encode %{
10573     __ bicw(as_Register($dst$$reg),
10574               as_Register($src1$$reg),
10575               as_Register($src2$$reg),
10576               Assembler::ASR,
10577               $src3$$constant & 0x1f);
10578   %}
10579 
10580   ins_pipe(ialu_reg_reg_shift);
10581 %}
10582 
10583 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst,
10584                          iRegL src1, iRegL src2,
10585                          immI src3, immL_M1 src4, rFlagsReg cr) %{
10586   match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4)));
10587   ins_cost(1.9 * INSN_COST);
10588   format %{ "bic  $dst, $src1, $src2, ASR $src3" %}
10589 
10590   ins_encode %{
10591     __ bic(as_Register($dst$$reg),
10592               as_Register($src1$$reg),
10593               as_Register($src2$$reg),
10594               Assembler::ASR,
10595               $src3$$constant & 0x3f);
10596   %}
10597 
10598   ins_pipe(ialu_reg_reg_shift);
10599 %}
10600 
10601 instruct AndI_reg_LShift_not_reg(iRegINoSp dst,
10602                          iRegIorL2I src1, iRegIorL2I src2,
10603                          immI src3, immI_M1 src4, rFlagsReg cr) %{
10604   match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4)));
10605   ins_cost(1.9 * INSN_COST);
10606   format %{ "bicw  $dst, $src1, $src2, LSL $src3" %}
10607 
10608   ins_encode %{
10609     __ bicw(as_Register($dst$$reg),
10610               as_Register($src1$$reg),
10611               as_Register($src2$$reg),
10612               Assembler::LSL,
10613               $src3$$constant & 0x1f);
10614   %}
10615 
10616   ins_pipe(ialu_reg_reg_shift);
10617 %}
10618 
10619 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst,
10620                          iRegL src1, iRegL src2,
10621                          immI src3, immL_M1 src4, rFlagsReg cr) %{
10622   match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4)));
10623   ins_cost(1.9 * INSN_COST);
10624   format %{ "bic  $dst, $src1, $src2, LSL $src3" %}
10625 
10626   ins_encode %{
10627     __ bic(as_Register($dst$$reg),
10628               as_Register($src1$$reg),
10629               as_Register($src2$$reg),
10630               Assembler::LSL,
10631               $src3$$constant & 0x3f);
10632   %}
10633 
10634   ins_pipe(ialu_reg_reg_shift);
10635 %}
10636 
10637 instruct XorI_reg_URShift_not_reg(iRegINoSp dst,
10638                          iRegIorL2I src1, iRegIorL2I src2,
10639                          immI src3, immI_M1 src4, rFlagsReg cr) %{
10640   match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1)));
10641   ins_cost(1.9 * INSN_COST);
10642   format %{ "eonw  $dst, $src1, $src2, LSR $src3" %}
10643 
10644   ins_encode %{
10645     __ eonw(as_Register($dst$$reg),
10646               as_Register($src1$$reg),
10647               as_Register($src2$$reg),
10648               Assembler::LSR,
10649               $src3$$constant & 0x1f);
10650   %}
10651 
10652   ins_pipe(ialu_reg_reg_shift);
10653 %}
10654 
10655 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst,
10656                          iRegL src1, iRegL src2,
10657                          immI src3, immL_M1 src4, rFlagsReg cr) %{
10658   match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1)));
10659   ins_cost(1.9 * INSN_COST);
10660   format %{ "eon  $dst, $src1, $src2, LSR $src3" %}
10661 
10662   ins_encode %{
10663     __ eon(as_Register($dst$$reg),
10664               as_Register($src1$$reg),
10665               as_Register($src2$$reg),
10666               Assembler::LSR,
10667               $src3$$constant & 0x3f);
10668   %}
10669 
10670   ins_pipe(ialu_reg_reg_shift);
10671 %}
10672 
10673 instruct XorI_reg_RShift_not_reg(iRegINoSp dst,
10674                          iRegIorL2I src1, iRegIorL2I src2,
10675                          immI src3, immI_M1 src4, rFlagsReg cr) %{
10676   match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1)));
10677   ins_cost(1.9 * INSN_COST);
10678   format %{ "eonw  $dst, $src1, $src2, ASR $src3" %}
10679 
10680   ins_encode %{
10681     __ eonw(as_Register($dst$$reg),
10682               as_Register($src1$$reg),
10683               as_Register($src2$$reg),
10684               Assembler::ASR,
10685               $src3$$constant & 0x1f);
10686   %}
10687 
10688   ins_pipe(ialu_reg_reg_shift);
10689 %}
10690 
10691 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst,
10692                          iRegL src1, iRegL src2,
10693                          immI src3, immL_M1 src4, rFlagsReg cr) %{
10694   match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1)));
10695   ins_cost(1.9 * INSN_COST);
10696   format %{ "eon  $dst, $src1, $src2, ASR $src3" %}
10697 
10698   ins_encode %{
10699     __ eon(as_Register($dst$$reg),
10700               as_Register($src1$$reg),
10701               as_Register($src2$$reg),
10702               Assembler::ASR,
10703               $src3$$constant & 0x3f);
10704   %}
10705 
10706   ins_pipe(ialu_reg_reg_shift);
10707 %}
10708 
10709 instruct XorI_reg_LShift_not_reg(iRegINoSp dst,
10710                          iRegIorL2I src1, iRegIorL2I src2,
10711                          immI src3, immI_M1 src4, rFlagsReg cr) %{
10712   match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1)));
10713   ins_cost(1.9 * INSN_COST);
10714   format %{ "eonw  $dst, $src1, $src2, LSL $src3" %}
10715 
10716   ins_encode %{
10717     __ eonw(as_Register($dst$$reg),
10718               as_Register($src1$$reg),
10719               as_Register($src2$$reg),
10720               Assembler::LSL,
10721               $src3$$constant & 0x1f);
10722   %}
10723 
10724   ins_pipe(ialu_reg_reg_shift);
10725 %}
10726 
10727 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst,
10728                          iRegL src1, iRegL src2,
10729                          immI src3, immL_M1 src4, rFlagsReg cr) %{
10730   match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1)));
10731   ins_cost(1.9 * INSN_COST);
10732   format %{ "eon  $dst, $src1, $src2, LSL $src3" %}
10733 
10734   ins_encode %{
10735     __ eon(as_Register($dst$$reg),
10736               as_Register($src1$$reg),
10737               as_Register($src2$$reg),
10738               Assembler::LSL,
10739               $src3$$constant & 0x3f);
10740   %}
10741 
10742   ins_pipe(ialu_reg_reg_shift);
10743 %}
10744 
10745 instruct OrI_reg_URShift_not_reg(iRegINoSp dst,
10746                          iRegIorL2I src1, iRegIorL2I src2,
10747                          immI src3, immI_M1 src4, rFlagsReg cr) %{
10748   match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4)));
10749   ins_cost(1.9 * INSN_COST);
10750   format %{ "ornw  $dst, $src1, $src2, LSR $src3" %}
10751 
10752   ins_encode %{
10753     __ ornw(as_Register($dst$$reg),
10754               as_Register($src1$$reg),
10755               as_Register($src2$$reg),
10756               Assembler::LSR,
10757               $src3$$constant & 0x1f);
10758   %}
10759 
10760   ins_pipe(ialu_reg_reg_shift);
10761 %}
10762 
10763 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst,
10764                          iRegL src1, iRegL src2,
10765                          immI src3, immL_M1 src4, rFlagsReg cr) %{
10766   match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4)));
10767   ins_cost(1.9 * INSN_COST);
10768   format %{ "orn  $dst, $src1, $src2, LSR $src3" %}
10769 
10770   ins_encode %{
10771     __ orn(as_Register($dst$$reg),
10772               as_Register($src1$$reg),
10773               as_Register($src2$$reg),
10774               Assembler::LSR,
10775               $src3$$constant & 0x3f);
10776   %}
10777 
10778   ins_pipe(ialu_reg_reg_shift);
10779 %}
10780 
10781 instruct OrI_reg_RShift_not_reg(iRegINoSp dst,
10782                          iRegIorL2I src1, iRegIorL2I src2,
10783                          immI src3, immI_M1 src4, rFlagsReg cr) %{
10784   match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4)));
10785   ins_cost(1.9 * INSN_COST);
10786   format %{ "ornw  $dst, $src1, $src2, ASR $src3" %}
10787 
10788   ins_encode %{
10789     __ ornw(as_Register($dst$$reg),
10790               as_Register($src1$$reg),
10791               as_Register($src2$$reg),
10792               Assembler::ASR,
10793               $src3$$constant & 0x1f);
10794   %}
10795 
10796   ins_pipe(ialu_reg_reg_shift);
10797 %}
10798 
10799 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst,
10800                          iRegL src1, iRegL src2,
10801                          immI src3, immL_M1 src4, rFlagsReg cr) %{
10802   match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4)));
10803   ins_cost(1.9 * INSN_COST);
10804   format %{ "orn  $dst, $src1, $src2, ASR $src3" %}
10805 
10806   ins_encode %{
10807     __ orn(as_Register($dst$$reg),
10808               as_Register($src1$$reg),
10809               as_Register($src2$$reg),
10810               Assembler::ASR,
10811               $src3$$constant & 0x3f);
10812   %}
10813 
10814   ins_pipe(ialu_reg_reg_shift);
10815 %}
10816 
10817 instruct OrI_reg_LShift_not_reg(iRegINoSp dst,
10818                          iRegIorL2I src1, iRegIorL2I src2,
10819                          immI src3, immI_M1 src4, rFlagsReg cr) %{
10820   match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4)));
10821   ins_cost(1.9 * INSN_COST);
10822   format %{ "ornw  $dst, $src1, $src2, LSL $src3" %}
10823 
10824   ins_encode %{
10825     __ ornw(as_Register($dst$$reg),
10826               as_Register($src1$$reg),
10827               as_Register($src2$$reg),
10828               Assembler::LSL,
10829               $src3$$constant & 0x1f);
10830   %}
10831 
10832   ins_pipe(ialu_reg_reg_shift);
10833 %}
10834 
10835 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst,
10836                          iRegL src1, iRegL src2,
10837                          immI src3, immL_M1 src4, rFlagsReg cr) %{
10838   match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4)));
10839   ins_cost(1.9 * INSN_COST);
10840   format %{ "orn  $dst, $src1, $src2, LSL $src3" %}
10841 
10842   ins_encode %{
10843     __ orn(as_Register($dst$$reg),
10844               as_Register($src1$$reg),
10845               as_Register($src2$$reg),
10846               Assembler::LSL,
10847               $src3$$constant & 0x3f);
10848   %}
10849 
10850   ins_pipe(ialu_reg_reg_shift);
10851 %}
10852 
10853 instruct AndI_reg_URShift_reg(iRegINoSp dst,
10854                          iRegIorL2I src1, iRegIorL2I src2,
10855                          immI src3, rFlagsReg cr) %{
10856   match(Set dst (AndI src1 (URShiftI src2 src3)));
10857 
10858   ins_cost(1.9 * INSN_COST);
10859   format %{ "andw  $dst, $src1, $src2, LSR $src3" %}
10860 
10861   ins_encode %{
10862     __ andw(as_Register($dst$$reg),
10863               as_Register($src1$$reg),
10864               as_Register($src2$$reg),
10865               Assembler::LSR,
10866               $src3$$constant & 0x1f);
10867   %}
10868 
10869   ins_pipe(ialu_reg_reg_shift);
10870 %}
10871 
10872 instruct AndL_reg_URShift_reg(iRegLNoSp dst,
10873                          iRegL src1, iRegL src2,
10874                          immI src3, rFlagsReg cr) %{
10875   match(Set dst (AndL src1 (URShiftL src2 src3)));
10876 
10877   ins_cost(1.9 * INSN_COST);
10878   format %{ "andr  $dst, $src1, $src2, LSR $src3" %}
10879 
10880   ins_encode %{
10881     __ andr(as_Register($dst$$reg),
10882               as_Register($src1$$reg),
10883               as_Register($src2$$reg),
10884               Assembler::LSR,
10885               $src3$$constant & 0x3f);
10886   %}
10887 
10888   ins_pipe(ialu_reg_reg_shift);
10889 %}
10890 
10891 instruct AndI_reg_RShift_reg(iRegINoSp dst,
10892                          iRegIorL2I src1, iRegIorL2I src2,
10893                          immI src3, rFlagsReg cr) %{
10894   match(Set dst (AndI src1 (RShiftI src2 src3)));
10895 
10896   ins_cost(1.9 * INSN_COST);
10897   format %{ "andw  $dst, $src1, $src2, ASR $src3" %}
10898 
10899   ins_encode %{
10900     __ andw(as_Register($dst$$reg),
10901               as_Register($src1$$reg),
10902               as_Register($src2$$reg),
10903               Assembler::ASR,
10904               $src3$$constant & 0x1f);
10905   %}
10906 
10907   ins_pipe(ialu_reg_reg_shift);
10908 %}
10909 
10910 instruct AndL_reg_RShift_reg(iRegLNoSp dst,
10911                          iRegL src1, iRegL src2,
10912                          immI src3, rFlagsReg cr) %{
10913   match(Set dst (AndL src1 (RShiftL src2 src3)));
10914 
10915   ins_cost(1.9 * INSN_COST);
10916   format %{ "andr  $dst, $src1, $src2, ASR $src3" %}
10917 
10918   ins_encode %{
10919     __ andr(as_Register($dst$$reg),
10920               as_Register($src1$$reg),
10921               as_Register($src2$$reg),
10922               Assembler::ASR,
10923               $src3$$constant & 0x3f);
10924   %}
10925 
10926   ins_pipe(ialu_reg_reg_shift);
10927 %}
10928 
10929 instruct AndI_reg_LShift_reg(iRegINoSp dst,
10930                          iRegIorL2I src1, iRegIorL2I src2,
10931                          immI src3, rFlagsReg cr) %{
10932   match(Set dst (AndI src1 (LShiftI src2 src3)));
10933 
10934   ins_cost(1.9 * INSN_COST);
10935   format %{ "andw  $dst, $src1, $src2, LSL $src3" %}
10936 
10937   ins_encode %{
10938     __ andw(as_Register($dst$$reg),
10939               as_Register($src1$$reg),
10940               as_Register($src2$$reg),
10941               Assembler::LSL,
10942               $src3$$constant & 0x1f);
10943   %}
10944 
10945   ins_pipe(ialu_reg_reg_shift);
10946 %}
10947 
10948 instruct AndL_reg_LShift_reg(iRegLNoSp dst,
10949                          iRegL src1, iRegL src2,
10950                          immI src3, rFlagsReg cr) %{
10951   match(Set dst (AndL src1 (LShiftL src2 src3)));
10952 
10953   ins_cost(1.9 * INSN_COST);
10954   format %{ "andr  $dst, $src1, $src2, LSL $src3" %}
10955 
10956   ins_encode %{
10957     __ andr(as_Register($dst$$reg),
10958               as_Register($src1$$reg),
10959               as_Register($src2$$reg),
10960               Assembler::LSL,
10961               $src3$$constant & 0x3f);
10962   %}
10963 
10964   ins_pipe(ialu_reg_reg_shift);
10965 %}
10966 
10967 instruct XorI_reg_URShift_reg(iRegINoSp dst,
10968                          iRegIorL2I src1, iRegIorL2I src2,
10969                          immI src3, rFlagsReg cr) %{
10970   match(Set dst (XorI src1 (URShiftI src2 src3)));
10971 
10972   ins_cost(1.9 * INSN_COST);
10973   format %{ "eorw  $dst, $src1, $src2, LSR $src3" %}
10974 
10975   ins_encode %{
10976     __ eorw(as_Register($dst$$reg),
10977               as_Register($src1$$reg),
10978               as_Register($src2$$reg),
10979               Assembler::LSR,
10980               $src3$$constant & 0x1f);
10981   %}
10982 
10983   ins_pipe(ialu_reg_reg_shift);
10984 %}
10985 
10986 instruct XorL_reg_URShift_reg(iRegLNoSp dst,
10987                          iRegL src1, iRegL src2,
10988                          immI src3, rFlagsReg cr) %{
10989   match(Set dst (XorL src1 (URShiftL src2 src3)));
10990 
10991   ins_cost(1.9 * INSN_COST);
10992   format %{ "eor  $dst, $src1, $src2, LSR $src3" %}
10993 
10994   ins_encode %{
10995     __ eor(as_Register($dst$$reg),
10996               as_Register($src1$$reg),
10997               as_Register($src2$$reg),
10998               Assembler::LSR,
10999               $src3$$constant & 0x3f);
11000   %}
11001 
11002   ins_pipe(ialu_reg_reg_shift);
11003 %}
11004 
11005 instruct XorI_reg_RShift_reg(iRegINoSp dst,
11006                          iRegIorL2I src1, iRegIorL2I src2,
11007                          immI src3, rFlagsReg cr) %{
11008   match(Set dst (XorI src1 (RShiftI src2 src3)));
11009 
11010   ins_cost(1.9 * INSN_COST);
11011   format %{ "eorw  $dst, $src1, $src2, ASR $src3" %}
11012 
11013   ins_encode %{
11014     __ eorw(as_Register($dst$$reg),
11015               as_Register($src1$$reg),
11016               as_Register($src2$$reg),
11017               Assembler::ASR,
11018               $src3$$constant & 0x1f);
11019   %}
11020 
11021   ins_pipe(ialu_reg_reg_shift);
11022 %}
11023 
11024 instruct XorL_reg_RShift_reg(iRegLNoSp dst,
11025                          iRegL src1, iRegL src2,
11026                          immI src3, rFlagsReg cr) %{
11027   match(Set dst (XorL src1 (RShiftL src2 src3)));
11028 
11029   ins_cost(1.9 * INSN_COST);
11030   format %{ "eor  $dst, $src1, $src2, ASR $src3" %}
11031 
11032   ins_encode %{
11033     __ eor(as_Register($dst$$reg),
11034               as_Register($src1$$reg),
11035               as_Register($src2$$reg),
11036               Assembler::ASR,
11037               $src3$$constant & 0x3f);
11038   %}
11039 
11040   ins_pipe(ialu_reg_reg_shift);
11041 %}
11042 
11043 instruct XorI_reg_LShift_reg(iRegINoSp dst,
11044                          iRegIorL2I src1, iRegIorL2I src2,
11045                          immI src3, rFlagsReg cr) %{
11046   match(Set dst (XorI src1 (LShiftI src2 src3)));
11047 
11048   ins_cost(1.9 * INSN_COST);
11049   format %{ "eorw  $dst, $src1, $src2, LSL $src3" %}
11050 
11051   ins_encode %{
11052     __ eorw(as_Register($dst$$reg),
11053               as_Register($src1$$reg),
11054               as_Register($src2$$reg),
11055               Assembler::LSL,
11056               $src3$$constant & 0x1f);
11057   %}
11058 
11059   ins_pipe(ialu_reg_reg_shift);
11060 %}
11061 
11062 instruct XorL_reg_LShift_reg(iRegLNoSp dst,
11063                          iRegL src1, iRegL src2,
11064                          immI src3, rFlagsReg cr) %{
11065   match(Set dst (XorL src1 (LShiftL src2 src3)));
11066 
11067   ins_cost(1.9 * INSN_COST);
11068   format %{ "eor  $dst, $src1, $src2, LSL $src3" %}
11069 
11070   ins_encode %{
11071     __ eor(as_Register($dst$$reg),
11072               as_Register($src1$$reg),
11073               as_Register($src2$$reg),
11074               Assembler::LSL,
11075               $src3$$constant & 0x3f);
11076   %}
11077 
11078   ins_pipe(ialu_reg_reg_shift);
11079 %}
11080 
11081 instruct OrI_reg_URShift_reg(iRegINoSp dst,
11082                          iRegIorL2I src1, iRegIorL2I src2,
11083                          immI src3, rFlagsReg cr) %{
11084   match(Set dst (OrI src1 (URShiftI src2 src3)));
11085 
11086   ins_cost(1.9 * INSN_COST);
11087   format %{ "orrw  $dst, $src1, $src2, LSR $src3" %}
11088 
11089   ins_encode %{
11090     __ orrw(as_Register($dst$$reg),
11091               as_Register($src1$$reg),
11092               as_Register($src2$$reg),
11093               Assembler::LSR,
11094               $src3$$constant & 0x1f);
11095   %}
11096 
11097   ins_pipe(ialu_reg_reg_shift);
11098 %}
11099 
11100 instruct OrL_reg_URShift_reg(iRegLNoSp dst,
11101                          iRegL src1, iRegL src2,
11102                          immI src3, rFlagsReg cr) %{
11103   match(Set dst (OrL src1 (URShiftL src2 src3)));
11104 
11105   ins_cost(1.9 * INSN_COST);
11106   format %{ "orr  $dst, $src1, $src2, LSR $src3" %}
11107 
11108   ins_encode %{
11109     __ orr(as_Register($dst$$reg),
11110               as_Register($src1$$reg),
11111               as_Register($src2$$reg),
11112               Assembler::LSR,
11113               $src3$$constant & 0x3f);
11114   %}
11115 
11116   ins_pipe(ialu_reg_reg_shift);
11117 %}
11118 
11119 instruct OrI_reg_RShift_reg(iRegINoSp dst,
11120                          iRegIorL2I src1, iRegIorL2I src2,
11121                          immI src3, rFlagsReg cr) %{
11122   match(Set dst (OrI src1 (RShiftI src2 src3)));
11123 
11124   ins_cost(1.9 * INSN_COST);
11125   format %{ "orrw  $dst, $src1, $src2, ASR $src3" %}
11126 
11127   ins_encode %{
11128     __ orrw(as_Register($dst$$reg),
11129               as_Register($src1$$reg),
11130               as_Register($src2$$reg),
11131               Assembler::ASR,
11132               $src3$$constant & 0x1f);
11133   %}
11134 
11135   ins_pipe(ialu_reg_reg_shift);
11136 %}
11137 
11138 instruct OrL_reg_RShift_reg(iRegLNoSp dst,
11139                          iRegL src1, iRegL src2,
11140                          immI src3, rFlagsReg cr) %{
11141   match(Set dst (OrL src1 (RShiftL src2 src3)));
11142 
11143   ins_cost(1.9 * INSN_COST);
11144   format %{ "orr  $dst, $src1, $src2, ASR $src3" %}
11145 
11146   ins_encode %{
11147     __ orr(as_Register($dst$$reg),
11148               as_Register($src1$$reg),
11149               as_Register($src2$$reg),
11150               Assembler::ASR,
11151               $src3$$constant & 0x3f);
11152   %}
11153 
11154   ins_pipe(ialu_reg_reg_shift);
11155 %}
11156 
11157 instruct OrI_reg_LShift_reg(iRegINoSp dst,
11158                          iRegIorL2I src1, iRegIorL2I src2,
11159                          immI src3, rFlagsReg cr) %{
11160   match(Set dst (OrI src1 (LShiftI src2 src3)));
11161 
11162   ins_cost(1.9 * INSN_COST);
11163   format %{ "orrw  $dst, $src1, $src2, LSL $src3" %}
11164 
11165   ins_encode %{
11166     __ orrw(as_Register($dst$$reg),
11167               as_Register($src1$$reg),
11168               as_Register($src2$$reg),
11169               Assembler::LSL,
11170               $src3$$constant & 0x1f);
11171   %}
11172 
11173   ins_pipe(ialu_reg_reg_shift);
11174 %}
11175 
11176 instruct OrL_reg_LShift_reg(iRegLNoSp dst,
11177                          iRegL src1, iRegL src2,
11178                          immI src3, rFlagsReg cr) %{
11179   match(Set dst (OrL src1 (LShiftL src2 src3)));
11180 
11181   ins_cost(1.9 * INSN_COST);
11182   format %{ "orr  $dst, $src1, $src2, LSL $src3" %}
11183 
11184   ins_encode %{
11185     __ orr(as_Register($dst$$reg),
11186               as_Register($src1$$reg),
11187               as_Register($src2$$reg),
11188               Assembler::LSL,
11189               $src3$$constant & 0x3f);
11190   %}
11191 
11192   ins_pipe(ialu_reg_reg_shift);
11193 %}
11194 
11195 instruct AddI_reg_URShift_reg(iRegINoSp dst,
11196                          iRegIorL2I src1, iRegIorL2I src2,
11197                          immI src3, rFlagsReg cr) %{
11198   match(Set dst (AddI src1 (URShiftI src2 src3)));
11199 
11200   ins_cost(1.9 * INSN_COST);
11201   format %{ "addw  $dst, $src1, $src2, LSR $src3" %}
11202 
11203   ins_encode %{
11204     __ addw(as_Register($dst$$reg),
11205               as_Register($src1$$reg),
11206               as_Register($src2$$reg),
11207               Assembler::LSR,
11208               $src3$$constant & 0x1f);
11209   %}
11210 
11211   ins_pipe(ialu_reg_reg_shift);
11212 %}
11213 
11214 instruct AddL_reg_URShift_reg(iRegLNoSp dst,
11215                          iRegL src1, iRegL src2,
11216                          immI src3, rFlagsReg cr) %{
11217   match(Set dst (AddL src1 (URShiftL src2 src3)));
11218 
11219   ins_cost(1.9 * INSN_COST);
11220   format %{ "add  $dst, $src1, $src2, LSR $src3" %}
11221 
11222   ins_encode %{
11223     __ add(as_Register($dst$$reg),
11224               as_Register($src1$$reg),
11225               as_Register($src2$$reg),
11226               Assembler::LSR,
11227               $src3$$constant & 0x3f);
11228   %}
11229 
11230   ins_pipe(ialu_reg_reg_shift);
11231 %}
11232 
11233 instruct AddI_reg_RShift_reg(iRegINoSp dst,
11234                          iRegIorL2I src1, iRegIorL2I src2,
11235                          immI src3, rFlagsReg cr) %{
11236   match(Set dst (AddI src1 (RShiftI src2 src3)));
11237 
11238   ins_cost(1.9 * INSN_COST);
11239   format %{ "addw  $dst, $src1, $src2, ASR $src3" %}
11240 
11241   ins_encode %{
11242     __ addw(as_Register($dst$$reg),
11243               as_Register($src1$$reg),
11244               as_Register($src2$$reg),
11245               Assembler::ASR,
11246               $src3$$constant & 0x1f);
11247   %}
11248 
11249   ins_pipe(ialu_reg_reg_shift);
11250 %}
11251 
11252 instruct AddL_reg_RShift_reg(iRegLNoSp dst,
11253                          iRegL src1, iRegL src2,
11254                          immI src3, rFlagsReg cr) %{
11255   match(Set dst (AddL src1 (RShiftL src2 src3)));
11256 
11257   ins_cost(1.9 * INSN_COST);
11258   format %{ "add  $dst, $src1, $src2, ASR $src3" %}
11259 
11260   ins_encode %{
11261     __ add(as_Register($dst$$reg),
11262               as_Register($src1$$reg),
11263               as_Register($src2$$reg),
11264               Assembler::ASR,
11265               $src3$$constant & 0x3f);
11266   %}
11267 
11268   ins_pipe(ialu_reg_reg_shift);
11269 %}
11270 
11271 instruct AddI_reg_LShift_reg(iRegINoSp dst,
11272                          iRegIorL2I src1, iRegIorL2I src2,
11273                          immI src3, rFlagsReg cr) %{
11274   match(Set dst (AddI src1 (LShiftI src2 src3)));
11275 
11276   ins_cost(1.9 * INSN_COST);
11277   format %{ "addw  $dst, $src1, $src2, LSL $src3" %}
11278 
11279   ins_encode %{
11280     __ addw(as_Register($dst$$reg),
11281               as_Register($src1$$reg),
11282               as_Register($src2$$reg),
11283               Assembler::LSL,
11284               $src3$$constant & 0x1f);
11285   %}
11286 
11287   ins_pipe(ialu_reg_reg_shift);
11288 %}
11289 
11290 instruct AddL_reg_LShift_reg(iRegLNoSp dst,
11291                          iRegL src1, iRegL src2,
11292                          immI src3, rFlagsReg cr) %{
11293   match(Set dst (AddL src1 (LShiftL src2 src3)));
11294 
11295   ins_cost(1.9 * INSN_COST);
11296   format %{ "add  $dst, $src1, $src2, LSL $src3" %}
11297 
11298   ins_encode %{
11299     __ add(as_Register($dst$$reg),
11300               as_Register($src1$$reg),
11301               as_Register($src2$$reg),
11302               Assembler::LSL,
11303               $src3$$constant & 0x3f);
11304   %}
11305 
11306   ins_pipe(ialu_reg_reg_shift);
11307 %}
11308 
11309 instruct SubI_reg_URShift_reg(iRegINoSp dst,
11310                          iRegIorL2I src1, iRegIorL2I src2,
11311                          immI src3, rFlagsReg cr) %{
11312   match(Set dst (SubI src1 (URShiftI src2 src3)));
11313 
11314   ins_cost(1.9 * INSN_COST);
11315   format %{ "subw  $dst, $src1, $src2, LSR $src3" %}
11316 
11317   ins_encode %{
11318     __ subw(as_Register($dst$$reg),
11319               as_Register($src1$$reg),
11320               as_Register($src2$$reg),
11321               Assembler::LSR,
11322               $src3$$constant & 0x1f);
11323   %}
11324 
11325   ins_pipe(ialu_reg_reg_shift);
11326 %}
11327 
11328 instruct SubL_reg_URShift_reg(iRegLNoSp dst,
11329                          iRegL src1, iRegL src2,
11330                          immI src3, rFlagsReg cr) %{
11331   match(Set dst (SubL src1 (URShiftL src2 src3)));
11332 
11333   ins_cost(1.9 * INSN_COST);
11334   format %{ "sub  $dst, $src1, $src2, LSR $src3" %}
11335 
11336   ins_encode %{
11337     __ sub(as_Register($dst$$reg),
11338               as_Register($src1$$reg),
11339               as_Register($src2$$reg),
11340               Assembler::LSR,
11341               $src3$$constant & 0x3f);
11342   %}
11343 
11344   ins_pipe(ialu_reg_reg_shift);
11345 %}
11346 
11347 instruct SubI_reg_RShift_reg(iRegINoSp dst,
11348                          iRegIorL2I src1, iRegIorL2I src2,
11349                          immI src3, rFlagsReg cr) %{
11350   match(Set dst (SubI src1 (RShiftI src2 src3)));
11351 
11352   ins_cost(1.9 * INSN_COST);
11353   format %{ "subw  $dst, $src1, $src2, ASR $src3" %}
11354 
11355   ins_encode %{
11356     __ subw(as_Register($dst$$reg),
11357               as_Register($src1$$reg),
11358               as_Register($src2$$reg),
11359               Assembler::ASR,
11360               $src3$$constant & 0x1f);
11361   %}
11362 
11363   ins_pipe(ialu_reg_reg_shift);
11364 %}
11365 
11366 instruct SubL_reg_RShift_reg(iRegLNoSp dst,
11367                          iRegL src1, iRegL src2,
11368                          immI src3, rFlagsReg cr) %{
11369   match(Set dst (SubL src1 (RShiftL src2 src3)));
11370 
11371   ins_cost(1.9 * INSN_COST);
11372   format %{ "sub  $dst, $src1, $src2, ASR $src3" %}
11373 
11374   ins_encode %{
11375     __ sub(as_Register($dst$$reg),
11376               as_Register($src1$$reg),
11377               as_Register($src2$$reg),
11378               Assembler::ASR,
11379               $src3$$constant & 0x3f);
11380   %}
11381 
11382   ins_pipe(ialu_reg_reg_shift);
11383 %}
11384 
11385 instruct SubI_reg_LShift_reg(iRegINoSp dst,
11386                          iRegIorL2I src1, iRegIorL2I src2,
11387                          immI src3, rFlagsReg cr) %{
11388   match(Set dst (SubI src1 (LShiftI src2 src3)));
11389 
11390   ins_cost(1.9 * INSN_COST);
11391   format %{ "subw  $dst, $src1, $src2, LSL $src3" %}
11392 
11393   ins_encode %{
11394     __ subw(as_Register($dst$$reg),
11395               as_Register($src1$$reg),
11396               as_Register($src2$$reg),
11397               Assembler::LSL,
11398               $src3$$constant & 0x1f);
11399   %}
11400 
11401   ins_pipe(ialu_reg_reg_shift);
11402 %}
11403 
11404 instruct SubL_reg_LShift_reg(iRegLNoSp dst,
11405                          iRegL src1, iRegL src2,
11406                          immI src3, rFlagsReg cr) %{
11407   match(Set dst (SubL src1 (LShiftL src2 src3)));
11408 
11409   ins_cost(1.9 * INSN_COST);
11410   format %{ "sub  $dst, $src1, $src2, LSL $src3" %}
11411 
11412   ins_encode %{
11413     __ sub(as_Register($dst$$reg),
11414               as_Register($src1$$reg),
11415               as_Register($src2$$reg),
11416               Assembler::LSL,
11417               $src3$$constant & 0x3f);
11418   %}
11419 
11420   ins_pipe(ialu_reg_reg_shift);
11421 %}
11422 
11423 
11424 
11425 // Shift Left followed by Shift Right.
11426 // This idiom is used by the compiler for the i2b bytecode etc.
11427 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count)
11428 %{
11429   match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count));
11430   // Make sure we are not going to exceed what sbfm can do.
11431   predicate((unsigned int)n->in(2)->get_int() <= 63
11432             && (unsigned int)n->in(1)->in(2)->get_int() <= 63);
11433 
11434   ins_cost(INSN_COST * 2);
11435   format %{ "sbfm  $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %}
11436   ins_encode %{
11437     int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant;
11438     int s = 63 - lshift;
11439     int r = (rshift - lshift) & 63;
11440     __ sbfm(as_Register($dst$$reg),
11441             as_Register($src$$reg),
11442             r, s);
11443   %}
11444 
11445   ins_pipe(ialu_reg_shift);
11446 %}
11447 
11448 // Shift Left followed by Shift Right.
11449 // This idiom is used by the compiler for the i2b bytecode etc.
11450 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count)
11451 %{
11452   match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count));
11453   // Make sure we are not going to exceed what sbfmw can do.
11454   predicate((unsigned int)n->in(2)->get_int() <= 31
11455             && (unsigned int)n->in(1)->in(2)->get_int() <= 31);
11456 
11457   ins_cost(INSN_COST * 2);
11458   format %{ "sbfmw  $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %}
11459   ins_encode %{
11460     int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant;
11461     int s = 31 - lshift;
11462     int r = (rshift - lshift) & 31;
11463     __ sbfmw(as_Register($dst$$reg),
11464             as_Register($src$$reg),
11465             r, s);
11466   %}
11467 
11468   ins_pipe(ialu_reg_shift);
11469 %}
11470 
11471 // Shift Left followed by Shift Right.
11472 // This idiom is used by the compiler for the i2b bytecode etc.
11473 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count)
11474 %{
11475   match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count));
11476   // Make sure we are not going to exceed what ubfm can do.
11477   predicate((unsigned int)n->in(2)->get_int() <= 63
11478             && (unsigned int)n->in(1)->in(2)->get_int() <= 63);
11479 
11480   ins_cost(INSN_COST * 2);
11481   format %{ "ubfm  $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %}
11482   ins_encode %{
11483     int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant;
11484     int s = 63 - lshift;
11485     int r = (rshift - lshift) & 63;
11486     __ ubfm(as_Register($dst$$reg),
11487             as_Register($src$$reg),
11488             r, s);
11489   %}
11490 
11491   ins_pipe(ialu_reg_shift);
11492 %}
11493 
11494 // Shift Left followed by Shift Right.
11495 // This idiom is used by the compiler for the i2b bytecode etc.
11496 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count)
11497 %{
11498   match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count));
11499   // Make sure we are not going to exceed what ubfmw can do.
11500   predicate((unsigned int)n->in(2)->get_int() <= 31
11501             && (unsigned int)n->in(1)->in(2)->get_int() <= 31);
11502 
11503   ins_cost(INSN_COST * 2);
11504   format %{ "ubfmw  $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %}
11505   ins_encode %{
11506     int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant;
11507     int s = 31 - lshift;
11508     int r = (rshift - lshift) & 31;
11509     __ ubfmw(as_Register($dst$$reg),
11510             as_Register($src$$reg),
11511             r, s);
11512   %}
11513 
11514   ins_pipe(ialu_reg_shift);
11515 %}
11516 // Bitfield extract with shift & mask
11517 
11518 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
11519 %{
11520   match(Set dst (AndI (URShiftI src rshift) mask));
11521 
11522   ins_cost(INSN_COST);
11523   format %{ "ubfxw $dst, $src, $rshift, $mask" %}
11524   ins_encode %{
11525     int rshift = $rshift$$constant;
11526     long mask = $mask$$constant;
11527     int width = exact_log2(mask+1);
11528     __ ubfxw(as_Register($dst$$reg),
11529             as_Register($src$$reg), rshift, width);
11530   %}
11531   ins_pipe(ialu_reg_shift);
11532 %}
11533 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask)
11534 %{
11535   match(Set dst (AndL (URShiftL src rshift) mask));
11536 
11537   ins_cost(INSN_COST);
11538   format %{ "ubfx $dst, $src, $rshift, $mask" %}
11539   ins_encode %{
11540     int rshift = $rshift$$constant;
11541     long mask = $mask$$constant;
11542     int width = exact_log2(mask+1);
11543     __ ubfx(as_Register($dst$$reg),
11544             as_Register($src$$reg), rshift, width);
11545   %}
11546   ins_pipe(ialu_reg_shift);
11547 %}
11548 
11549 // We can use ubfx when extending an And with a mask when we know mask
11550 // is positive.  We know that because immI_bitmask guarantees it.
11551 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
11552 %{
11553   match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask)));
11554 
11555   ins_cost(INSN_COST * 2);
11556   format %{ "ubfx $dst, $src, $rshift, $mask" %}
11557   ins_encode %{
11558     int rshift = $rshift$$constant;
11559     long mask = $mask$$constant;
11560     int width = exact_log2(mask+1);
11561     __ ubfx(as_Register($dst$$reg),
11562             as_Register($src$$reg), rshift, width);
11563   %}
11564   ins_pipe(ialu_reg_shift);
11565 %}
11566 
11567 // We can use ubfiz when masking by a positive number and then left shifting the result.
11568 // We know that the mask is positive because immI_bitmask guarantees it.
11569 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
11570 %{
11571   match(Set dst (LShiftI (AndI src mask) lshift));
11572   predicate((unsigned int)n->in(2)->get_int() <= 31 &&
11573     (exact_log2(n->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= (31+1));
11574 
11575   ins_cost(INSN_COST);
11576   format %{ "ubfizw $dst, $src, $lshift, $mask" %}
11577   ins_encode %{
11578     int lshift = $lshift$$constant;
11579     long mask = $mask$$constant;
11580     int width = exact_log2(mask+1);
11581     __ ubfizw(as_Register($dst$$reg),
11582           as_Register($src$$reg), lshift, width);
11583   %}
11584   ins_pipe(ialu_reg_shift);
11585 %}
11586 // We can use ubfiz when masking by a positive number and then left shifting the result.
11587 // We know that the mask is positive because immL_bitmask guarantees it.
11588 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask)
11589 %{
11590   match(Set dst (LShiftL (AndL src mask) lshift));
11591   predicate((unsigned int)n->in(2)->get_int() <= 63 &&
11592     (exact_log2_long(n->in(1)->in(2)->get_long()+1) + (unsigned int)n->in(2)->get_int()) <= (63+1));
11593 
11594   ins_cost(INSN_COST);
11595   format %{ "ubfiz $dst, $src, $lshift, $mask" %}
11596   ins_encode %{
11597     int lshift = $lshift$$constant;
11598     long mask = $mask$$constant;
11599     int width = exact_log2(mask+1);
11600     __ ubfiz(as_Register($dst$$reg),
11601           as_Register($src$$reg), lshift, width);
11602   %}
11603   ins_pipe(ialu_reg_shift);
11604 %}
11605 
11606 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz
11607 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
11608 %{
11609   match(Set dst (LShiftL (ConvI2L(AndI src mask)) lshift));
11610   predicate((unsigned int)n->in(2)->get_int() <= 31 &&
11611     (exact_log2((unsigned int)n->in(1)->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= 32);
11612 
11613   ins_cost(INSN_COST);
11614   format %{ "ubfiz $dst, $src, $lshift, $mask" %}
11615   ins_encode %{
11616     int lshift = $lshift$$constant;
11617     long mask = $mask$$constant;
11618     int width = exact_log2(mask+1);
11619     __ ubfiz(as_Register($dst$$reg),
11620              as_Register($src$$reg), lshift, width);
11621   %}
11622   ins_pipe(ialu_reg_shift);
11623 %}
11624 
11625 // Rotations
11626 
11627 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr)
11628 %{
11629   match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift)));
11630   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63));
11631 
11632   ins_cost(INSN_COST);
11633   format %{ "extr $dst, $src1, $src2, #$rshift" %}
11634 
11635   ins_encode %{
11636     __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
11637             $rshift$$constant & 63);
11638   %}
11639   ins_pipe(ialu_reg_reg_extr);
11640 %}
11641 
11642 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr)
11643 %{
11644   match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift)));
11645   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31));
11646 
11647   ins_cost(INSN_COST);
11648   format %{ "extr $dst, $src1, $src2, #$rshift" %}
11649 
11650   ins_encode %{
11651     __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
11652             $rshift$$constant & 31);
11653   %}
11654   ins_pipe(ialu_reg_reg_extr);
11655 %}
11656 
11657 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr)
11658 %{
11659   match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift)));
11660   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63));
11661 
11662   ins_cost(INSN_COST);
11663   format %{ "extr $dst, $src1, $src2, #$rshift" %}
11664 
11665   ins_encode %{
11666     __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
11667             $rshift$$constant & 63);
11668   %}
11669   ins_pipe(ialu_reg_reg_extr);
11670 %}
11671 
11672 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr)
11673 %{
11674   match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift)));
11675   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31));
11676 
11677   ins_cost(INSN_COST);
11678   format %{ "extr $dst, $src1, $src2, #$rshift" %}
11679 
11680   ins_encode %{
11681     __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
11682             $rshift$$constant & 31);
11683   %}
11684   ins_pipe(ialu_reg_reg_extr);
11685 %}
11686 
11687 
11688 // rol expander
11689 
11690 instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr)
11691 %{
11692   effect(DEF dst, USE src, USE shift);
11693 
11694   format %{ "rol    $dst, $src, $shift" %}
11695   ins_cost(INSN_COST * 3);
11696   ins_encode %{
11697     __ subw(rscratch1, zr, as_Register($shift$$reg));
11698     __ rorv(as_Register($dst$$reg), as_Register($src$$reg),
11699             rscratch1);
11700     %}
11701   ins_pipe(ialu_reg_reg_vshift);
11702 %}
11703 
11704 // rol expander
11705 
11706 instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr)
11707 %{
11708   effect(DEF dst, USE src, USE shift);
11709 
11710   format %{ "rol    $dst, $src, $shift" %}
11711   ins_cost(INSN_COST * 3);
11712   ins_encode %{
11713     __ subw(rscratch1, zr, as_Register($shift$$reg));
11714     __ rorvw(as_Register($dst$$reg), as_Register($src$$reg),
11715             rscratch1);
11716     %}
11717   ins_pipe(ialu_reg_reg_vshift);
11718 %}
11719 
11720 instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr)
11721 %{
11722   match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift))));
11723 
11724   expand %{
11725     rolL_rReg(dst, src, shift, cr);
11726   %}
11727 %}
11728 
11729 instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr)
11730 %{
11731   match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift))));
11732 
11733   expand %{
11734     rolL_rReg(dst, src, shift, cr);
11735   %}
11736 %}
11737 
11738 instruct rolI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr)
11739 %{
11740   match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift))));
11741 
11742   expand %{
11743     rolI_rReg(dst, src, shift, cr);
11744   %}
11745 %}
11746 
11747 instruct rolI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr)
11748 %{
11749   match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift))));
11750 
11751   expand %{
11752     rolI_rReg(dst, src, shift, cr);
11753   %}
11754 %}
11755 
11756 // ror expander
11757 
11758 instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr)
11759 %{
11760   effect(DEF dst, USE src, USE shift);
11761 
11762   format %{ "ror    $dst, $src, $shift" %}
11763   ins_cost(INSN_COST);
11764   ins_encode %{
11765     __ rorv(as_Register($dst$$reg), as_Register($src$$reg),
11766             as_Register($shift$$reg));
11767     %}
11768   ins_pipe(ialu_reg_reg_vshift);
11769 %}
11770 
11771 // ror expander
11772 
11773 instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr)
11774 %{
11775   effect(DEF dst, USE src, USE shift);
11776 
11777   format %{ "ror    $dst, $src, $shift" %}
11778   ins_cost(INSN_COST);
11779   ins_encode %{
11780     __ rorvw(as_Register($dst$$reg), as_Register($src$$reg),
11781             as_Register($shift$$reg));
11782     %}
11783   ins_pipe(ialu_reg_reg_vshift);
11784 %}
11785 
11786 instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr)
11787 %{
11788   match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift))));
11789 
11790   expand %{
11791     rorL_rReg(dst, src, shift, cr);
11792   %}
11793 %}
11794 
11795 instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr)
11796 %{
11797   match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift))));
11798 
11799   expand %{
11800     rorL_rReg(dst, src, shift, cr);
11801   %}
11802 %}
11803 
11804 instruct rorI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr)
11805 %{
11806   match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift))));
11807 
11808   expand %{
11809     rorI_rReg(dst, src, shift, cr);
11810   %}
11811 %}
11812 
11813 instruct rorI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr)
11814 %{
11815   match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift))));
11816 
11817   expand %{
11818     rorI_rReg(dst, src, shift, cr);
11819   %}
11820 %}
11821 
11822 // Add/subtract (extended)
11823 
11824 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr)
11825 %{
11826   match(Set dst (AddL src1 (ConvI2L src2)));
11827   ins_cost(INSN_COST);
11828   format %{ "add  $dst, $src1, $src2, sxtw" %}
11829 
11830    ins_encode %{
11831      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11832             as_Register($src2$$reg), ext::sxtw);
11833    %}
11834   ins_pipe(ialu_reg_reg);
11835 %};
11836 
11837 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr)
11838 %{
11839   match(Set dst (SubL src1 (ConvI2L src2)));
11840   ins_cost(INSN_COST);
11841   format %{ "sub  $dst, $src1, $src2, sxtw" %}
11842 
11843    ins_encode %{
11844      __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
11845             as_Register($src2$$reg), ext::sxtw);
11846    %}
11847   ins_pipe(ialu_reg_reg);
11848 %};
11849 
11850 
11851 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr)
11852 %{
11853   match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift)));
11854   ins_cost(INSN_COST);
11855   format %{ "add  $dst, $src1, $src2, sxth" %}
11856 
11857    ins_encode %{
11858      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11859             as_Register($src2$$reg), ext::sxth);
11860    %}
11861   ins_pipe(ialu_reg_reg);
11862 %}
11863 
11864 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr)
11865 %{
11866   match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift)));
11867   ins_cost(INSN_COST);
11868   format %{ "add  $dst, $src1, $src2, sxtb" %}
11869 
11870    ins_encode %{
11871      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11872             as_Register($src2$$reg), ext::sxtb);
11873    %}
11874   ins_pipe(ialu_reg_reg);
11875 %}
11876 
11877 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr)
11878 %{
11879   match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift)));
11880   ins_cost(INSN_COST);
11881   format %{ "add  $dst, $src1, $src2, uxtb" %}
11882 
11883    ins_encode %{
11884      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11885             as_Register($src2$$reg), ext::uxtb);
11886    %}
11887   ins_pipe(ialu_reg_reg);
11888 %}
11889 
11890 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr)
11891 %{
11892   match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
11893   ins_cost(INSN_COST);
11894   format %{ "add  $dst, $src1, $src2, sxth" %}
11895 
11896    ins_encode %{
11897      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11898             as_Register($src2$$reg), ext::sxth);
11899    %}
11900   ins_pipe(ialu_reg_reg);
11901 %}
11902 
11903 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr)
11904 %{
11905   match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
11906   ins_cost(INSN_COST);
11907   format %{ "add  $dst, $src1, $src2, sxtw" %}
11908 
11909    ins_encode %{
11910      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11911             as_Register($src2$$reg), ext::sxtw);
11912    %}
11913   ins_pipe(ialu_reg_reg);
11914 %}
11915 
11916 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr)
11917 %{
11918   match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
11919   ins_cost(INSN_COST);
11920   format %{ "add  $dst, $src1, $src2, sxtb" %}
11921 
11922    ins_encode %{
11923      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11924             as_Register($src2$$reg), ext::sxtb);
11925    %}
11926   ins_pipe(ialu_reg_reg);
11927 %}
11928 
11929 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr)
11930 %{
11931   match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift)));
11932   ins_cost(INSN_COST);
11933   format %{ "add  $dst, $src1, $src2, uxtb" %}
11934 
11935    ins_encode %{
11936      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11937             as_Register($src2$$reg), ext::uxtb);
11938    %}
11939   ins_pipe(ialu_reg_reg);
11940 %}
11941 
11942 
11943 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr)
11944 %{
11945   match(Set dst (AddI src1 (AndI src2 mask)));
11946   ins_cost(INSN_COST);
11947   format %{ "addw  $dst, $src1, $src2, uxtb" %}
11948 
11949    ins_encode %{
11950      __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
11951             as_Register($src2$$reg), ext::uxtb);
11952    %}
11953   ins_pipe(ialu_reg_reg);
11954 %}
11955 
11956 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr)
11957 %{
11958   match(Set dst (AddI src1 (AndI src2 mask)));
11959   ins_cost(INSN_COST);
11960   format %{ "addw  $dst, $src1, $src2, uxth" %}
11961 
11962    ins_encode %{
11963      __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
11964             as_Register($src2$$reg), ext::uxth);
11965    %}
11966   ins_pipe(ialu_reg_reg);
11967 %}
11968 
11969 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr)
11970 %{
11971   match(Set dst (AddL src1 (AndL src2 mask)));
11972   ins_cost(INSN_COST);
11973   format %{ "add  $dst, $src1, $src2, uxtb" %}
11974 
11975    ins_encode %{
11976      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11977             as_Register($src2$$reg), ext::uxtb);
11978    %}
11979   ins_pipe(ialu_reg_reg);
11980 %}
11981 
11982 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr)
11983 %{
11984   match(Set dst (AddL src1 (AndL src2 mask)));
11985   ins_cost(INSN_COST);
11986   format %{ "add  $dst, $src1, $src2, uxth" %}
11987 
11988    ins_encode %{
11989      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
11990             as_Register($src2$$reg), ext::uxth);
11991    %}
11992   ins_pipe(ialu_reg_reg);
11993 %}
11994 
11995 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr)
11996 %{
11997   match(Set dst (AddL src1 (AndL src2 mask)));
11998   ins_cost(INSN_COST);
11999   format %{ "add  $dst, $src1, $src2, uxtw" %}
12000 
12001    ins_encode %{
12002      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12003             as_Register($src2$$reg), ext::uxtw);
12004    %}
12005   ins_pipe(ialu_reg_reg);
12006 %}
12007 
12008 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr)
12009 %{
12010   match(Set dst (SubI src1 (AndI src2 mask)));
12011   ins_cost(INSN_COST);
12012   format %{ "subw  $dst, $src1, $src2, uxtb" %}
12013 
12014    ins_encode %{
12015      __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
12016             as_Register($src2$$reg), ext::uxtb);
12017    %}
12018   ins_pipe(ialu_reg_reg);
12019 %}
12020 
12021 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr)
12022 %{
12023   match(Set dst (SubI src1 (AndI src2 mask)));
12024   ins_cost(INSN_COST);
12025   format %{ "subw  $dst, $src1, $src2, uxth" %}
12026 
12027    ins_encode %{
12028      __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
12029             as_Register($src2$$reg), ext::uxth);
12030    %}
12031   ins_pipe(ialu_reg_reg);
12032 %}
12033 
12034 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr)
12035 %{
12036   match(Set dst (SubL src1 (AndL src2 mask)));
12037   ins_cost(INSN_COST);
12038   format %{ "sub  $dst, $src1, $src2, uxtb" %}
12039 
12040    ins_encode %{
12041      __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12042             as_Register($src2$$reg), ext::uxtb);
12043    %}
12044   ins_pipe(ialu_reg_reg);
12045 %}
12046 
12047 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr)
12048 %{
12049   match(Set dst (SubL src1 (AndL src2 mask)));
12050   ins_cost(INSN_COST);
12051   format %{ "sub  $dst, $src1, $src2, uxth" %}
12052 
12053    ins_encode %{
12054      __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12055             as_Register($src2$$reg), ext::uxth);
12056    %}
12057   ins_pipe(ialu_reg_reg);
12058 %}
12059 
12060 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr)
12061 %{
12062   match(Set dst (SubL src1 (AndL src2 mask)));
12063   ins_cost(INSN_COST);
12064   format %{ "sub  $dst, $src1, $src2, uxtw" %}
12065 
12066    ins_encode %{
12067      __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12068             as_Register($src2$$reg), ext::uxtw);
12069    %}
12070   ins_pipe(ialu_reg_reg);
12071 %}
12072 
12073 
12074 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr)
12075 %{
12076   match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
12077   ins_cost(1.9 * INSN_COST);
12078   format %{ "add  $dst, $src1, $src2, sxtb #lshift2" %}
12079 
12080    ins_encode %{
12081      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12082             as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
12083    %}
12084   ins_pipe(ialu_reg_reg_shift);
12085 %}
12086 
12087 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr)
12088 %{
12089   match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
12090   ins_cost(1.9 * INSN_COST);
12091   format %{ "add  $dst, $src1, $src2, sxth #lshift2" %}
12092 
12093    ins_encode %{
12094      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12095             as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
12096    %}
12097   ins_pipe(ialu_reg_reg_shift);
12098 %}
12099 
12100 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr)
12101 %{
12102   match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
12103   ins_cost(1.9 * INSN_COST);
12104   format %{ "add  $dst, $src1, $src2, sxtw #lshift2" %}
12105 
12106    ins_encode %{
12107      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12108             as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant));
12109    %}
12110   ins_pipe(ialu_reg_reg_shift);
12111 %}
12112 
12113 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr)
12114 %{
12115   match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
12116   ins_cost(1.9 * INSN_COST);
12117   format %{ "sub  $dst, $src1, $src2, sxtb #lshift2" %}
12118 
12119    ins_encode %{
12120      __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12121             as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
12122    %}
12123   ins_pipe(ialu_reg_reg_shift);
12124 %}
12125 
12126 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr)
12127 %{
12128   match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
12129   ins_cost(1.9 * INSN_COST);
12130   format %{ "sub  $dst, $src1, $src2, sxth #lshift2" %}
12131 
12132    ins_encode %{
12133      __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12134             as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
12135    %}
12136   ins_pipe(ialu_reg_reg_shift);
12137 %}
12138 
12139 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr)
12140 %{
12141   match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
12142   ins_cost(1.9 * INSN_COST);
12143   format %{ "sub  $dst, $src1, $src2, sxtw #lshift2" %}
12144 
12145    ins_encode %{
12146      __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12147             as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant));
12148    %}
12149   ins_pipe(ialu_reg_reg_shift);
12150 %}
12151 
12152 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr)
12153 %{
12154   match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
12155   ins_cost(1.9 * INSN_COST);
12156   format %{ "addw  $dst, $src1, $src2, sxtb #lshift2" %}
12157 
12158    ins_encode %{
12159      __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
12160             as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
12161    %}
12162   ins_pipe(ialu_reg_reg_shift);
12163 %}
12164 
12165 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr)
12166 %{
12167   match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
12168   ins_cost(1.9 * INSN_COST);
12169   format %{ "addw  $dst, $src1, $src2, sxth #lshift2" %}
12170 
12171    ins_encode %{
12172      __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
12173             as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
12174    %}
12175   ins_pipe(ialu_reg_reg_shift);
12176 %}
12177 
12178 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr)
12179 %{
12180   match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
12181   ins_cost(1.9 * INSN_COST);
12182   format %{ "subw  $dst, $src1, $src2, sxtb #lshift2" %}
12183 
12184    ins_encode %{
12185      __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
12186             as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
12187    %}
12188   ins_pipe(ialu_reg_reg_shift);
12189 %}
12190 
12191 instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr)
12192 %{
12193   match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
12194   ins_cost(1.9 * INSN_COST);
12195   format %{ "subw  $dst, $src1, $src2, sxth #lshift2" %}
12196 
12197    ins_encode %{
12198      __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
12199             as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
12200    %}
12201   ins_pipe(ialu_reg_reg_shift);
12202 %}
12203 
12204 
12205 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr)
12206 %{
12207   match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift)));
12208   ins_cost(1.9 * INSN_COST);
12209   format %{ "add  $dst, $src1, $src2, sxtw #lshift" %}
12210 
12211    ins_encode %{
12212      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12213             as_Register($src2$$reg), ext::sxtw, ($lshift$$constant));
12214    %}
12215   ins_pipe(ialu_reg_reg_shift);
12216 %};
12217 
12218 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr)
12219 %{
12220   match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift)));
12221   ins_cost(1.9 * INSN_COST);
12222   format %{ "sub  $dst, $src1, $src2, sxtw #lshift" %}
12223 
12224    ins_encode %{
12225      __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12226             as_Register($src2$$reg), ext::sxtw, ($lshift$$constant));
12227    %}
12228   ins_pipe(ialu_reg_reg_shift);
12229 %};
12230 
12231 
12232 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr)
12233 %{
12234   match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
12235   ins_cost(1.9 * INSN_COST);
12236   format %{ "add  $dst, $src1, $src2, uxtb #lshift" %}
12237 
12238    ins_encode %{
12239      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12240             as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
12241    %}
12242   ins_pipe(ialu_reg_reg_shift);
12243 %}
12244 
12245 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr)
12246 %{
12247   match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
12248   ins_cost(1.9 * INSN_COST);
12249   format %{ "add  $dst, $src1, $src2, uxth #lshift" %}
12250 
12251    ins_encode %{
12252      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12253             as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
12254    %}
12255   ins_pipe(ialu_reg_reg_shift);
12256 %}
12257 
12258 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr)
12259 %{
12260   match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
12261   ins_cost(1.9 * INSN_COST);
12262   format %{ "add  $dst, $src1, $src2, uxtw #lshift" %}
12263 
12264    ins_encode %{
12265      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12266             as_Register($src2$$reg), ext::uxtw, ($lshift$$constant));
12267    %}
12268   ins_pipe(ialu_reg_reg_shift);
12269 %}
12270 
12271 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr)
12272 %{
12273   match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
12274   ins_cost(1.9 * INSN_COST);
12275   format %{ "sub  $dst, $src1, $src2, uxtb #lshift" %}
12276 
12277    ins_encode %{
12278      __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12279             as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
12280    %}
12281   ins_pipe(ialu_reg_reg_shift);
12282 %}
12283 
12284 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr)
12285 %{
12286   match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
12287   ins_cost(1.9 * INSN_COST);
12288   format %{ "sub  $dst, $src1, $src2, uxth #lshift" %}
12289 
12290    ins_encode %{
12291      __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12292             as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
12293    %}
12294   ins_pipe(ialu_reg_reg_shift);
12295 %}
12296 
12297 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr)
12298 %{
12299   match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
12300   ins_cost(1.9 * INSN_COST);
12301   format %{ "sub  $dst, $src1, $src2, uxtw #lshift" %}
12302 
12303    ins_encode %{
12304      __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12305             as_Register($src2$$reg), ext::uxtw, ($lshift$$constant));
12306    %}
12307   ins_pipe(ialu_reg_reg_shift);
12308 %}
12309 
12310 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr)
12311 %{
12312   match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift)));
12313   ins_cost(1.9 * INSN_COST);
12314   format %{ "addw  $dst, $src1, $src2, uxtb #lshift" %}
12315 
12316    ins_encode %{
12317      __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
12318             as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
12319    %}
12320   ins_pipe(ialu_reg_reg_shift);
12321 %}
12322 
12323 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr)
12324 %{
12325   match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift)));
12326   ins_cost(1.9 * INSN_COST);
12327   format %{ "addw  $dst, $src1, $src2, uxth #lshift" %}
12328 
12329    ins_encode %{
12330      __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
12331             as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
12332    %}
12333   ins_pipe(ialu_reg_reg_shift);
12334 %}
12335 
12336 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr)
12337 %{
12338   match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift)));
12339   ins_cost(1.9 * INSN_COST);
12340   format %{ "subw  $dst, $src1, $src2, uxtb #lshift" %}
12341 
12342    ins_encode %{
12343      __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
12344             as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
12345    %}
12346   ins_pipe(ialu_reg_reg_shift);
12347 %}
12348 
12349 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr)
12350 %{
12351   match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift)));
12352   ins_cost(1.9 * INSN_COST);
12353   format %{ "subw  $dst, $src1, $src2, uxth #lshift" %}
12354 
12355    ins_encode %{
12356      __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
12357             as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
12358    %}
12359   ins_pipe(ialu_reg_reg_shift);
12360 %}
12361 // END This section of the file is automatically generated. Do not edit --------------
12362 
12363 // ============================================================================
12364 // Floating Point Arithmetic Instructions
12365 
12366 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
12367   match(Set dst (AddF src1 src2));
12368 
12369   ins_cost(INSN_COST * 5);
12370   format %{ "fadds   $dst, $src1, $src2" %}
12371 
12372   ins_encode %{
12373     __ fadds(as_FloatRegister($dst$$reg),
12374              as_FloatRegister($src1$$reg),
12375              as_FloatRegister($src2$$reg));
12376   %}
12377 
12378   ins_pipe(fp_dop_reg_reg_s);
12379 %}
12380 
12381 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
12382   match(Set dst (AddD src1 src2));
12383 
12384   ins_cost(INSN_COST * 5);
12385   format %{ "faddd   $dst, $src1, $src2" %}
12386 
12387   ins_encode %{
12388     __ faddd(as_FloatRegister($dst$$reg),
12389              as_FloatRegister($src1$$reg),
12390              as_FloatRegister($src2$$reg));
12391   %}
12392 
12393   ins_pipe(fp_dop_reg_reg_d);
12394 %}
12395 
12396 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
12397   match(Set dst (SubF src1 src2));
12398 
12399   ins_cost(INSN_COST * 5);
12400   format %{ "fsubs   $dst, $src1, $src2" %}
12401 
12402   ins_encode %{
12403     __ fsubs(as_FloatRegister($dst$$reg),
12404              as_FloatRegister($src1$$reg),
12405              as_FloatRegister($src2$$reg));
12406   %}
12407 
12408   ins_pipe(fp_dop_reg_reg_s);
12409 %}
12410 
12411 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
12412   match(Set dst (SubD src1 src2));
12413 
12414   ins_cost(INSN_COST * 5);
12415   format %{ "fsubd   $dst, $src1, $src2" %}
12416 
12417   ins_encode %{
12418     __ fsubd(as_FloatRegister($dst$$reg),
12419              as_FloatRegister($src1$$reg),
12420              as_FloatRegister($src2$$reg));
12421   %}
12422 
12423   ins_pipe(fp_dop_reg_reg_d);
12424 %}
12425 
12426 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
12427   match(Set dst (MulF src1 src2));
12428 
12429   ins_cost(INSN_COST * 6);
12430   format %{ "fmuls   $dst, $src1, $src2" %}
12431 
12432   ins_encode %{
12433     __ fmuls(as_FloatRegister($dst$$reg),
12434              as_FloatRegister($src1$$reg),
12435              as_FloatRegister($src2$$reg));
12436   %}
12437 
12438   ins_pipe(fp_dop_reg_reg_s);
12439 %}
12440 
12441 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
12442   match(Set dst (MulD src1 src2));
12443 
12444   ins_cost(INSN_COST * 6);
12445   format %{ "fmuld   $dst, $src1, $src2" %}
12446 
12447   ins_encode %{
12448     __ fmuld(as_FloatRegister($dst$$reg),
12449              as_FloatRegister($src1$$reg),
12450              as_FloatRegister($src2$$reg));
12451   %}
12452 
12453   ins_pipe(fp_dop_reg_reg_d);
12454 %}
12455 
12456 // src1 * src2 + src3
12457 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
12458   predicate(UseFMA);
12459   match(Set dst (FmaF src3 (Binary src1 src2)));
12460 
12461   format %{ "fmadds   $dst, $src1, $src2, $src3" %}
12462 
12463   ins_encode %{
12464     __ fmadds(as_FloatRegister($dst$$reg),
12465              as_FloatRegister($src1$$reg),
12466              as_FloatRegister($src2$$reg),
12467              as_FloatRegister($src3$$reg));
12468   %}
12469 
12470   ins_pipe(pipe_class_default);
12471 %}
12472 
12473 // src1 * src2 + src3
12474 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{
12475   predicate(UseFMA);
12476   match(Set dst (FmaD src3 (Binary src1 src2)));
12477 
12478   format %{ "fmaddd   $dst, $src1, $src2, $src3" %}
12479 
12480   ins_encode %{
12481     __ fmaddd(as_FloatRegister($dst$$reg),
12482              as_FloatRegister($src1$$reg),
12483              as_FloatRegister($src2$$reg),
12484              as_FloatRegister($src3$$reg));
12485   %}
12486 
12487   ins_pipe(pipe_class_default);
12488 %}
12489 
12490 // -src1 * src2 + src3
12491 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
12492   predicate(UseFMA);
12493   match(Set dst (FmaF src3 (Binary (NegF src1) src2)));
12494   match(Set dst (FmaF src3 (Binary src1 (NegF src2))));
12495 
12496   format %{ "fmsubs   $dst, $src1, $src2, $src3" %}
12497 
12498   ins_encode %{
12499     __ fmsubs(as_FloatRegister($dst$$reg),
12500               as_FloatRegister($src1$$reg),
12501               as_FloatRegister($src2$$reg),
12502               as_FloatRegister($src3$$reg));
12503   %}
12504 
12505   ins_pipe(pipe_class_default);
12506 %}
12507 
12508 // -src1 * src2 + src3
12509 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{
12510   predicate(UseFMA);
12511   match(Set dst (FmaD src3 (Binary (NegD src1) src2)));
12512   match(Set dst (FmaD src3 (Binary src1 (NegD src2))));
12513 
12514   format %{ "fmsubd   $dst, $src1, $src2, $src3" %}
12515 
12516   ins_encode %{
12517     __ fmsubd(as_FloatRegister($dst$$reg),
12518               as_FloatRegister($src1$$reg),
12519               as_FloatRegister($src2$$reg),
12520               as_FloatRegister($src3$$reg));
12521   %}
12522 
12523   ins_pipe(pipe_class_default);
12524 %}
12525 
12526 // -src1 * src2 - src3
12527 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
12528   predicate(UseFMA);
12529   match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2)));
12530   match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2))));
12531 
12532   format %{ "fnmadds  $dst, $src1, $src2, $src3" %}
12533 
12534   ins_encode %{
12535     __ fnmadds(as_FloatRegister($dst$$reg),
12536                as_FloatRegister($src1$$reg),
12537                as_FloatRegister($src2$$reg),
12538                as_FloatRegister($src3$$reg));
12539   %}
12540 
12541   ins_pipe(pipe_class_default);
12542 %}
12543 
12544 // -src1 * src2 - src3
12545 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{
12546   predicate(UseFMA);
12547   match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2)));
12548   match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2))));
12549 
12550   format %{ "fnmaddd   $dst, $src1, $src2, $src3" %}
12551 
12552   ins_encode %{
12553     __ fnmaddd(as_FloatRegister($dst$$reg),
12554                as_FloatRegister($src1$$reg),
12555                as_FloatRegister($src2$$reg),
12556                as_FloatRegister($src3$$reg));
12557   %}
12558 
12559   ins_pipe(pipe_class_default);
12560 %}
12561 
12562 // src1 * src2 - src3
12563 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{
12564   predicate(UseFMA);
12565   match(Set dst (FmaF (NegF src3) (Binary src1 src2)));
12566 
12567   format %{ "fnmsubs  $dst, $src1, $src2, $src3" %}
12568 
12569   ins_encode %{
12570     __ fnmsubs(as_FloatRegister($dst$$reg),
12571                as_FloatRegister($src1$$reg),
12572                as_FloatRegister($src2$$reg),
12573                as_FloatRegister($src3$$reg));
12574   %}
12575 
12576   ins_pipe(pipe_class_default);
12577 %}
12578 
12579 // src1 * src2 - src3
12580 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{
12581   predicate(UseFMA);
12582   match(Set dst (FmaD (NegD src3) (Binary src1 src2)));
12583 
12584   format %{ "fnmsubd   $dst, $src1, $src2, $src3" %}
12585 
12586   ins_encode %{
12587   // n.b. insn name should be fnmsubd
12588     __ fnmsub(as_FloatRegister($dst$$reg),
12589               as_FloatRegister($src1$$reg),
12590               as_FloatRegister($src2$$reg),
12591               as_FloatRegister($src3$$reg));
12592   %}
12593 
12594   ins_pipe(pipe_class_default);
12595 %}
12596 
12597 
12598 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
12599   match(Set dst (DivF src1  src2));
12600 
12601   ins_cost(INSN_COST * 18);
12602   format %{ "fdivs   $dst, $src1, $src2" %}
12603 
12604   ins_encode %{
12605     __ fdivs(as_FloatRegister($dst$$reg),
12606              as_FloatRegister($src1$$reg),
12607              as_FloatRegister($src2$$reg));
12608   %}
12609 
12610   ins_pipe(fp_div_s);
12611 %}
12612 
12613 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
12614   match(Set dst (DivD src1  src2));
12615 
12616   ins_cost(INSN_COST * 32);
12617   format %{ "fdivd   $dst, $src1, $src2" %}
12618 
12619   ins_encode %{
12620     __ fdivd(as_FloatRegister($dst$$reg),
12621              as_FloatRegister($src1$$reg),
12622              as_FloatRegister($src2$$reg));
12623   %}
12624 
12625   ins_pipe(fp_div_d);
12626 %}
12627 
12628 instruct negF_reg_reg(vRegF dst, vRegF src) %{
12629   match(Set dst (NegF src));
12630 
12631   ins_cost(INSN_COST * 3);
12632   format %{ "fneg   $dst, $src" %}
12633 
12634   ins_encode %{
12635     __ fnegs(as_FloatRegister($dst$$reg),
12636              as_FloatRegister($src$$reg));
12637   %}
12638 
12639   ins_pipe(fp_uop_s);
12640 %}
12641 
12642 instruct negD_reg_reg(vRegD dst, vRegD src) %{
12643   match(Set dst (NegD src));
12644 
12645   ins_cost(INSN_COST * 3);
12646   format %{ "fnegd   $dst, $src" %}
12647 
12648   ins_encode %{
12649     __ fnegd(as_FloatRegister($dst$$reg),
12650              as_FloatRegister($src$$reg));
12651   %}
12652 
12653   ins_pipe(fp_uop_d);
12654 %}
12655 
12656 instruct absF_reg(vRegF dst, vRegF src) %{
12657   match(Set dst (AbsF src));
12658 
12659   ins_cost(INSN_COST * 3);
12660   format %{ "fabss   $dst, $src" %}
12661   ins_encode %{
12662     __ fabss(as_FloatRegister($dst$$reg),
12663              as_FloatRegister($src$$reg));
12664   %}
12665 
12666   ins_pipe(fp_uop_s);
12667 %}
12668 
12669 instruct absD_reg(vRegD dst, vRegD src) %{
12670   match(Set dst (AbsD src));
12671 
12672   ins_cost(INSN_COST * 3);
12673   format %{ "fabsd   $dst, $src" %}
12674   ins_encode %{
12675     __ fabsd(as_FloatRegister($dst$$reg),
12676              as_FloatRegister($src$$reg));
12677   %}
12678 
12679   ins_pipe(fp_uop_d);
12680 %}
12681 
12682 instruct sqrtD_reg(vRegD dst, vRegD src) %{
12683   match(Set dst (SqrtD src));
12684 
12685   ins_cost(INSN_COST * 50);
12686   format %{ "fsqrtd  $dst, $src" %}
12687   ins_encode %{
12688     __ fsqrtd(as_FloatRegister($dst$$reg),
12689              as_FloatRegister($src$$reg));
12690   %}
12691 
12692   ins_pipe(fp_div_s);
12693 %}
12694 
12695 instruct sqrtF_reg(vRegF dst, vRegF src) %{
12696   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
12697 
12698   ins_cost(INSN_COST * 50);
12699   format %{ "fsqrts  $dst, $src" %}
12700   ins_encode %{
12701     __ fsqrts(as_FloatRegister($dst$$reg),
12702              as_FloatRegister($src$$reg));
12703   %}
12704 
12705   ins_pipe(fp_div_d);
12706 %}
12707 
12708 // ============================================================================
12709 // Logical Instructions
12710 
12711 // Integer Logical Instructions
12712 
12713 // And Instructions
12714 
12715 
12716 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{
12717   match(Set dst (AndI src1 src2));
12718 
12719   format %{ "andw  $dst, $src1, $src2\t# int" %}
12720 
12721   ins_cost(INSN_COST);
12722   ins_encode %{
12723     __ andw(as_Register($dst$$reg),
12724             as_Register($src1$$reg),
12725             as_Register($src2$$reg));
12726   %}
12727 
12728   ins_pipe(ialu_reg_reg);
12729 %}
12730 
12731 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{
12732   match(Set dst (AndI src1 src2));
12733 
12734   format %{ "andsw  $dst, $src1, $src2\t# int" %}
12735 
12736   ins_cost(INSN_COST);
12737   ins_encode %{
12738     __ andw(as_Register($dst$$reg),
12739             as_Register($src1$$reg),
12740             (unsigned long)($src2$$constant));
12741   %}
12742 
12743   ins_pipe(ialu_reg_imm);
12744 %}
12745 
12746 // Or Instructions
12747 
12748 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
12749   match(Set dst (OrI src1 src2));
12750 
12751   format %{ "orrw  $dst, $src1, $src2\t# int" %}
12752 
12753   ins_cost(INSN_COST);
12754   ins_encode %{
12755     __ orrw(as_Register($dst$$reg),
12756             as_Register($src1$$reg),
12757             as_Register($src2$$reg));
12758   %}
12759 
12760   ins_pipe(ialu_reg_reg);
12761 %}
12762 
12763 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{
12764   match(Set dst (OrI src1 src2));
12765 
12766   format %{ "orrw  $dst, $src1, $src2\t# int" %}
12767 
12768   ins_cost(INSN_COST);
12769   ins_encode %{
12770     __ orrw(as_Register($dst$$reg),
12771             as_Register($src1$$reg),
12772             (unsigned long)($src2$$constant));
12773   %}
12774 
12775   ins_pipe(ialu_reg_imm);
12776 %}
12777 
12778 // Xor Instructions
12779 
12780 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
12781   match(Set dst (XorI src1 src2));
12782 
12783   format %{ "eorw  $dst, $src1, $src2\t# int" %}
12784 
12785   ins_cost(INSN_COST);
12786   ins_encode %{
12787     __ eorw(as_Register($dst$$reg),
12788             as_Register($src1$$reg),
12789             as_Register($src2$$reg));
12790   %}
12791 
12792   ins_pipe(ialu_reg_reg);
12793 %}
12794 
12795 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{
12796   match(Set dst (XorI src1 src2));
12797 
12798   format %{ "eorw  $dst, $src1, $src2\t# int" %}
12799 
12800   ins_cost(INSN_COST);
12801   ins_encode %{
12802     __ eorw(as_Register($dst$$reg),
12803             as_Register($src1$$reg),
12804             (unsigned long)($src2$$constant));
12805   %}
12806 
12807   ins_pipe(ialu_reg_imm);
12808 %}
12809 
12810 // Long Logical Instructions
12811 // TODO
12812 
12813 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{
12814   match(Set dst (AndL src1 src2));
12815 
12816   format %{ "and  $dst, $src1, $src2\t# int" %}
12817 
12818   ins_cost(INSN_COST);
12819   ins_encode %{
12820     __ andr(as_Register($dst$$reg),
12821             as_Register($src1$$reg),
12822             as_Register($src2$$reg));
12823   %}
12824 
12825   ins_pipe(ialu_reg_reg);
12826 %}
12827 
12828 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{
12829   match(Set dst (AndL src1 src2));
12830 
12831   format %{ "and  $dst, $src1, $src2\t# int" %}
12832 
12833   ins_cost(INSN_COST);
12834   ins_encode %{
12835     __ andr(as_Register($dst$$reg),
12836             as_Register($src1$$reg),
12837             (unsigned long)($src2$$constant));
12838   %}
12839 
12840   ins_pipe(ialu_reg_imm);
12841 %}
12842 
12843 // Or Instructions
12844 
12845 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
12846   match(Set dst (OrL src1 src2));
12847 
12848   format %{ "orr  $dst, $src1, $src2\t# int" %}
12849 
12850   ins_cost(INSN_COST);
12851   ins_encode %{
12852     __ orr(as_Register($dst$$reg),
12853            as_Register($src1$$reg),
12854            as_Register($src2$$reg));
12855   %}
12856 
12857   ins_pipe(ialu_reg_reg);
12858 %}
12859 
12860 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{
12861   match(Set dst (OrL src1 src2));
12862 
12863   format %{ "orr  $dst, $src1, $src2\t# int" %}
12864 
12865   ins_cost(INSN_COST);
12866   ins_encode %{
12867     __ orr(as_Register($dst$$reg),
12868            as_Register($src1$$reg),
12869            (unsigned long)($src2$$constant));
12870   %}
12871 
12872   ins_pipe(ialu_reg_imm);
12873 %}
12874 
12875 // Xor Instructions
12876 
12877 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
12878   match(Set dst (XorL src1 src2));
12879 
12880   format %{ "eor  $dst, $src1, $src2\t# int" %}
12881 
12882   ins_cost(INSN_COST);
12883   ins_encode %{
12884     __ eor(as_Register($dst$$reg),
12885            as_Register($src1$$reg),
12886            as_Register($src2$$reg));
12887   %}
12888 
12889   ins_pipe(ialu_reg_reg);
12890 %}
12891 
12892 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{
12893   match(Set dst (XorL src1 src2));
12894 
12895   ins_cost(INSN_COST);
12896   format %{ "eor  $dst, $src1, $src2\t# int" %}
12897 
12898   ins_encode %{
12899     __ eor(as_Register($dst$$reg),
12900            as_Register($src1$$reg),
12901            (unsigned long)($src2$$constant));
12902   %}
12903 
12904   ins_pipe(ialu_reg_imm);
12905 %}
12906 
12907 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src)
12908 %{
12909   match(Set dst (ConvI2L src));
12910 
12911   ins_cost(INSN_COST);
12912   format %{ "sxtw  $dst, $src\t# i2l" %}
12913   ins_encode %{
12914     __ sbfm($dst$$Register, $src$$Register, 0, 31);
12915   %}
12916   ins_pipe(ialu_reg_shift);
12917 %}
12918 
12919 // this pattern occurs in bigmath arithmetic
12920 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask)
12921 %{
12922   match(Set dst (AndL (ConvI2L src) mask));
12923 
12924   ins_cost(INSN_COST);
12925   format %{ "ubfm  $dst, $src, 0, 31\t# ui2l" %}
12926   ins_encode %{
12927     __ ubfm($dst$$Register, $src$$Register, 0, 31);
12928   %}
12929 
12930   ins_pipe(ialu_reg_shift);
12931 %}
12932 
12933 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{
12934   match(Set dst (ConvL2I src));
12935 
12936   ins_cost(INSN_COST);
12937   format %{ "movw  $dst, $src \t// l2i" %}
12938 
12939   ins_encode %{
12940     __ movw(as_Register($dst$$reg), as_Register($src$$reg));
12941   %}
12942 
12943   ins_pipe(ialu_reg);
12944 %}
12945 
12946 instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr)
12947 %{
12948   match(Set dst (Conv2B src));
12949   effect(KILL cr);
12950 
12951   format %{
12952     "cmpw $src, zr\n\t"
12953     "cset $dst, ne"
12954   %}
12955 
12956   ins_encode %{
12957     __ cmpw(as_Register($src$$reg), zr);
12958     __ cset(as_Register($dst$$reg), Assembler::NE);
12959   %}
12960 
12961   ins_pipe(ialu_reg);
12962 %}
12963 
12964 instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr)
12965 %{
12966   match(Set dst (Conv2B src));
12967   effect(KILL cr);
12968 
12969   format %{
12970     "cmp  $src, zr\n\t"
12971     "cset $dst, ne"
12972   %}
12973 
12974   ins_encode %{
12975     __ cmp(as_Register($src$$reg), zr);
12976     __ cset(as_Register($dst$$reg), Assembler::NE);
12977   %}
12978 
12979   ins_pipe(ialu_reg);
12980 %}
12981 
12982 instruct convD2F_reg(vRegF dst, vRegD src) %{
12983   match(Set dst (ConvD2F src));
12984 
12985   ins_cost(INSN_COST * 5);
12986   format %{ "fcvtd  $dst, $src \t// d2f" %}
12987 
12988   ins_encode %{
12989     __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg));
12990   %}
12991 
12992   ins_pipe(fp_d2f);
12993 %}
12994 
12995 instruct convF2D_reg(vRegD dst, vRegF src) %{
12996   match(Set dst (ConvF2D src));
12997 
12998   ins_cost(INSN_COST * 5);
12999   format %{ "fcvts  $dst, $src \t// f2d" %}
13000 
13001   ins_encode %{
13002     __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg));
13003   %}
13004 
13005   ins_pipe(fp_f2d);
13006 %}
13007 
13008 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{
13009   match(Set dst (ConvF2I src));
13010 
13011   ins_cost(INSN_COST * 5);
13012   format %{ "fcvtzsw  $dst, $src \t// f2i" %}
13013 
13014   ins_encode %{
13015     __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg));
13016   %}
13017 
13018   ins_pipe(fp_f2i);
13019 %}
13020 
13021 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{
13022   match(Set dst (ConvF2L src));
13023 
13024   ins_cost(INSN_COST * 5);
13025   format %{ "fcvtzs  $dst, $src \t// f2l" %}
13026 
13027   ins_encode %{
13028     __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg));
13029   %}
13030 
13031   ins_pipe(fp_f2l);
13032 %}
13033 
13034 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{
13035   match(Set dst (ConvI2F src));
13036 
13037   ins_cost(INSN_COST * 5);
13038   format %{ "scvtfws  $dst, $src \t// i2f" %}
13039 
13040   ins_encode %{
13041     __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg));
13042   %}
13043 
13044   ins_pipe(fp_i2f);
13045 %}
13046 
13047 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{
13048   match(Set dst (ConvL2F src));
13049 
13050   ins_cost(INSN_COST * 5);
13051   format %{ "scvtfs  $dst, $src \t// l2f" %}
13052 
13053   ins_encode %{
13054     __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg));
13055   %}
13056 
13057   ins_pipe(fp_l2f);
13058 %}
13059 
13060 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{
13061   match(Set dst (ConvD2I src));
13062 
13063   ins_cost(INSN_COST * 5);
13064   format %{ "fcvtzdw  $dst, $src \t// d2i" %}
13065 
13066   ins_encode %{
13067     __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg));
13068   %}
13069 
13070   ins_pipe(fp_d2i);
13071 %}
13072 
13073 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{
13074   match(Set dst (ConvD2L src));
13075 
13076   ins_cost(INSN_COST * 5);
13077   format %{ "fcvtzd  $dst, $src \t// d2l" %}
13078 
13079   ins_encode %{
13080     __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg));
13081   %}
13082 
13083   ins_pipe(fp_d2l);
13084 %}
13085 
13086 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{
13087   match(Set dst (ConvI2D src));
13088 
13089   ins_cost(INSN_COST * 5);
13090   format %{ "scvtfwd  $dst, $src \t// i2d" %}
13091 
13092   ins_encode %{
13093     __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg));
13094   %}
13095 
13096   ins_pipe(fp_i2d);
13097 %}
13098 
13099 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{
13100   match(Set dst (ConvL2D src));
13101 
13102   ins_cost(INSN_COST * 5);
13103   format %{ "scvtfd  $dst, $src \t// l2d" %}
13104 
13105   ins_encode %{
13106     __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg));
13107   %}
13108 
13109   ins_pipe(fp_l2d);
13110 %}
13111 
13112 // stack <-> reg and reg <-> reg shuffles with no conversion
13113 
13114 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{
13115 
13116   match(Set dst (MoveF2I src));
13117 
13118   effect(DEF dst, USE src);
13119 
13120   ins_cost(4 * INSN_COST);
13121 
13122   format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %}
13123 
13124   ins_encode %{
13125     __ ldrw($dst$$Register, Address(sp, $src$$disp));
13126   %}
13127 
13128   ins_pipe(iload_reg_reg);
13129 
13130 %}
13131 
13132 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{
13133 
13134   match(Set dst (MoveI2F src));
13135 
13136   effect(DEF dst, USE src);
13137 
13138   ins_cost(4 * INSN_COST);
13139 
13140   format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %}
13141 
13142   ins_encode %{
13143     __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp));
13144   %}
13145 
13146   ins_pipe(pipe_class_memory);
13147 
13148 %}
13149 
13150 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{
13151 
13152   match(Set dst (MoveD2L src));
13153 
13154   effect(DEF dst, USE src);
13155 
13156   ins_cost(4 * INSN_COST);
13157 
13158   format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %}
13159 
13160   ins_encode %{
13161     __ ldr($dst$$Register, Address(sp, $src$$disp));
13162   %}
13163 
13164   ins_pipe(iload_reg_reg);
13165 
13166 %}
13167 
13168 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{
13169 
13170   match(Set dst (MoveL2D src));
13171 
13172   effect(DEF dst, USE src);
13173 
13174   ins_cost(4 * INSN_COST);
13175 
13176   format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %}
13177 
13178   ins_encode %{
13179     __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp));
13180   %}
13181 
13182   ins_pipe(pipe_class_memory);
13183 
13184 %}
13185 
13186 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{
13187 
13188   match(Set dst (MoveF2I src));
13189 
13190   effect(DEF dst, USE src);
13191 
13192   ins_cost(INSN_COST);
13193 
13194   format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %}
13195 
13196   ins_encode %{
13197     __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp));
13198   %}
13199 
13200   ins_pipe(pipe_class_memory);
13201 
13202 %}
13203 
13204 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{
13205 
13206   match(Set dst (MoveI2F src));
13207 
13208   effect(DEF dst, USE src);
13209 
13210   ins_cost(INSN_COST);
13211 
13212   format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %}
13213 
13214   ins_encode %{
13215     __ strw($src$$Register, Address(sp, $dst$$disp));
13216   %}
13217 
13218   ins_pipe(istore_reg_reg);
13219 
13220 %}
13221 
13222 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{
13223 
13224   match(Set dst (MoveD2L src));
13225 
13226   effect(DEF dst, USE src);
13227 
13228   ins_cost(INSN_COST);
13229 
13230   format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %}
13231 
13232   ins_encode %{
13233     __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp));
13234   %}
13235 
13236   ins_pipe(pipe_class_memory);
13237 
13238 %}
13239 
13240 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{
13241 
13242   match(Set dst (MoveL2D src));
13243 
13244   effect(DEF dst, USE src);
13245 
13246   ins_cost(INSN_COST);
13247 
13248   format %{ "str $src, $dst\t# MoveL2D_reg_stack" %}
13249 
13250   ins_encode %{
13251     __ str($src$$Register, Address(sp, $dst$$disp));
13252   %}
13253 
13254   ins_pipe(istore_reg_reg);
13255 
13256 %}
13257 
13258 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{
13259 
13260   match(Set dst (MoveF2I src));
13261 
13262   effect(DEF dst, USE src);
13263 
13264   ins_cost(INSN_COST);
13265 
13266   format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %}
13267 
13268   ins_encode %{
13269     __ fmovs($dst$$Register, as_FloatRegister($src$$reg));
13270   %}
13271 
13272   ins_pipe(fp_f2i);
13273 
13274 %}
13275 
13276 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{
13277 
13278   match(Set dst (MoveI2F src));
13279 
13280   effect(DEF dst, USE src);
13281 
13282   ins_cost(INSN_COST);
13283 
13284   format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %}
13285 
13286   ins_encode %{
13287     __ fmovs(as_FloatRegister($dst$$reg), $src$$Register);
13288   %}
13289 
13290   ins_pipe(fp_i2f);
13291 
13292 %}
13293 
13294 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{
13295 
13296   match(Set dst (MoveD2L src));
13297 
13298   effect(DEF dst, USE src);
13299 
13300   ins_cost(INSN_COST);
13301 
13302   format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %}
13303 
13304   ins_encode %{
13305     __ fmovd($dst$$Register, as_FloatRegister($src$$reg));
13306   %}
13307 
13308   ins_pipe(fp_d2l);
13309 
13310 %}
13311 
13312 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{
13313 
13314   match(Set dst (MoveL2D src));
13315 
13316   effect(DEF dst, USE src);
13317 
13318   ins_cost(INSN_COST);
13319 
13320   format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %}
13321 
13322   ins_encode %{
13323     __ fmovd(as_FloatRegister($dst$$reg), $src$$Register);
13324   %}
13325 
13326   ins_pipe(fp_l2d);
13327 
13328 %}
13329 
13330 // ============================================================================
13331 // clearing of an array
13332 
13333 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr)
13334 %{
13335   match(Set dummy (ClearArray cnt base));
13336   effect(USE_KILL cnt, USE_KILL base);
13337 
13338   ins_cost(4 * INSN_COST);
13339   format %{ "ClearArray $cnt, $base" %}
13340 
13341   ins_encode %{
13342     __ zero_words($base$$Register, $cnt$$Register);
13343   %}
13344 
13345   ins_pipe(pipe_class_memory);
13346 %}
13347 
13348 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr)
13349 %{
13350   predicate((u_int64_t)n->in(2)->get_long()
13351             < (u_int64_t)(BlockZeroingLowLimit >> LogBytesPerWord));
13352   match(Set dummy (ClearArray cnt base));
13353   effect(USE_KILL base);
13354 
13355   ins_cost(4 * INSN_COST);
13356   format %{ "ClearArray $cnt, $base" %}
13357 
13358   ins_encode %{
13359     __ zero_words($base$$Register, (u_int64_t)$cnt$$constant);
13360   %}
13361 
13362   ins_pipe(pipe_class_memory);
13363 %}
13364 
13365 // ============================================================================
13366 // Overflow Math Instructions
13367 
13368 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
13369 %{
13370   match(Set cr (OverflowAddI op1 op2));
13371 
13372   format %{ "cmnw  $op1, $op2\t# overflow check int" %}
13373   ins_cost(INSN_COST);
13374   ins_encode %{
13375     __ cmnw($op1$$Register, $op2$$Register);
13376   %}
13377 
13378   ins_pipe(icmp_reg_reg);
13379 %}
13380 
13381 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2)
13382 %{
13383   match(Set cr (OverflowAddI op1 op2));
13384 
13385   format %{ "cmnw  $op1, $op2\t# overflow check int" %}
13386   ins_cost(INSN_COST);
13387   ins_encode %{
13388     __ cmnw($op1$$Register, $op2$$constant);
13389   %}
13390 
13391   ins_pipe(icmp_reg_imm);
13392 %}
13393 
13394 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
13395 %{
13396   match(Set cr (OverflowAddL op1 op2));
13397 
13398   format %{ "cmn   $op1, $op2\t# overflow check long" %}
13399   ins_cost(INSN_COST);
13400   ins_encode %{
13401     __ cmn($op1$$Register, $op2$$Register);
13402   %}
13403 
13404   ins_pipe(icmp_reg_reg);
13405 %}
13406 
13407 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2)
13408 %{
13409   match(Set cr (OverflowAddL op1 op2));
13410 
13411   format %{ "cmn   $op1, $op2\t# overflow check long" %}
13412   ins_cost(INSN_COST);
13413   ins_encode %{
13414     __ cmn($op1$$Register, $op2$$constant);
13415   %}
13416 
13417   ins_pipe(icmp_reg_imm);
13418 %}
13419 
13420 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
13421 %{
13422   match(Set cr (OverflowSubI op1 op2));
13423 
13424   format %{ "cmpw  $op1, $op2\t# overflow check int" %}
13425   ins_cost(INSN_COST);
13426   ins_encode %{
13427     __ cmpw($op1$$Register, $op2$$Register);
13428   %}
13429 
13430   ins_pipe(icmp_reg_reg);
13431 %}
13432 
13433 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2)
13434 %{
13435   match(Set cr (OverflowSubI op1 op2));
13436 
13437   format %{ "cmpw  $op1, $op2\t# overflow check int" %}
13438   ins_cost(INSN_COST);
13439   ins_encode %{
13440     __ cmpw($op1$$Register, $op2$$constant);
13441   %}
13442 
13443   ins_pipe(icmp_reg_imm);
13444 %}
13445 
13446 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
13447 %{
13448   match(Set cr (OverflowSubL op1 op2));
13449 
13450   format %{ "cmp   $op1, $op2\t# overflow check long" %}
13451   ins_cost(INSN_COST);
13452   ins_encode %{
13453     __ cmp($op1$$Register, $op2$$Register);
13454   %}
13455 
13456   ins_pipe(icmp_reg_reg);
13457 %}
13458 
13459 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2)
13460 %{
13461   match(Set cr (OverflowSubL op1 op2));
13462 
13463   format %{ "cmp   $op1, $op2\t# overflow check long" %}
13464   ins_cost(INSN_COST);
13465   ins_encode %{
13466     __ subs(zr, $op1$$Register, $op2$$constant);
13467   %}
13468 
13469   ins_pipe(icmp_reg_imm);
13470 %}
13471 
13472 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1)
13473 %{
13474   match(Set cr (OverflowSubI zero op1));
13475 
13476   format %{ "cmpw  zr, $op1\t# overflow check int" %}
13477   ins_cost(INSN_COST);
13478   ins_encode %{
13479     __ cmpw(zr, $op1$$Register);
13480   %}
13481 
13482   ins_pipe(icmp_reg_imm);
13483 %}
13484 
13485 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1)
13486 %{
13487   match(Set cr (OverflowSubL zero op1));
13488 
13489   format %{ "cmp   zr, $op1\t# overflow check long" %}
13490   ins_cost(INSN_COST);
13491   ins_encode %{
13492     __ cmp(zr, $op1$$Register);
13493   %}
13494 
13495   ins_pipe(icmp_reg_imm);
13496 %}
13497 
13498 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
13499 %{
13500   match(Set cr (OverflowMulI op1 op2));
13501 
13502   format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t"
13503             "cmp   rscratch1, rscratch1, sxtw\n\t"
13504             "movw  rscratch1, #0x80000000\n\t"
13505             "cselw rscratch1, rscratch1, zr, NE\n\t"
13506             "cmpw  rscratch1, #1" %}
13507   ins_cost(5 * INSN_COST);
13508   ins_encode %{
13509     __ smull(rscratch1, $op1$$Register, $op2$$Register);
13510     __ subs(zr, rscratch1, rscratch1, ext::sxtw);      // NE => overflow
13511     __ movw(rscratch1, 0x80000000);                    // Develop 0 (EQ),
13512     __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE)
13513     __ cmpw(rscratch1, 1);                             // 0x80000000 - 1 => VS
13514   %}
13515 
13516   ins_pipe(pipe_slow);
13517 %}
13518 
13519 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr)
13520 %{
13521   match(If cmp (OverflowMulI op1 op2));
13522   predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow
13523             || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow);
13524   effect(USE labl, KILL cr);
13525 
13526   format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t"
13527             "cmp   rscratch1, rscratch1, sxtw\n\t"
13528             "b$cmp   $labl" %}
13529   ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST
13530   ins_encode %{
13531     Label* L = $labl$$label;
13532     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13533     __ smull(rscratch1, $op1$$Register, $op2$$Register);
13534     __ subs(zr, rscratch1, rscratch1, ext::sxtw);      // NE => overflow
13535     __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L);
13536   %}
13537 
13538   ins_pipe(pipe_serial);
13539 %}
13540 
13541 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2)
13542 %{
13543   match(Set cr (OverflowMulL op1 op2));
13544 
13545   format %{ "mul   rscratch1, $op1, $op2\t#overflow check long\n\t"
13546             "smulh rscratch2, $op1, $op2\n\t"
13547             "cmp   rscratch2, rscratch1, ASR #63\n\t"
13548             "movw  rscratch1, #0x80000000\n\t"
13549             "cselw rscratch1, rscratch1, zr, NE\n\t"
13550             "cmpw  rscratch1, #1" %}
13551   ins_cost(6 * INSN_COST);
13552   ins_encode %{
13553     __ mul(rscratch1, $op1$$Register, $op2$$Register);   // Result bits 0..63
13554     __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
13555     __ cmp(rscratch2, rscratch1, Assembler::ASR, 63);    // Top is pure sign ext
13556     __ movw(rscratch1, 0x80000000);                    // Develop 0 (EQ),
13557     __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE)
13558     __ cmpw(rscratch1, 1);                             // 0x80000000 - 1 => VS
13559   %}
13560 
13561   ins_pipe(pipe_slow);
13562 %}
13563 
13564 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr)
13565 %{
13566   match(If cmp (OverflowMulL op1 op2));
13567   predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow
13568             || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow);
13569   effect(USE labl, KILL cr);
13570 
13571   format %{ "mul   rscratch1, $op1, $op2\t#overflow check long\n\t"
13572             "smulh rscratch2, $op1, $op2\n\t"
13573             "cmp   rscratch2, rscratch1, ASR #63\n\t"
13574             "b$cmp $labl" %}
13575   ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST
13576   ins_encode %{
13577     Label* L = $labl$$label;
13578     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13579     __ mul(rscratch1, $op1$$Register, $op2$$Register);   // Result bits 0..63
13580     __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
13581     __ cmp(rscratch2, rscratch1, Assembler::ASR, 63);    // Top is pure sign ext
13582     __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L);
13583   %}
13584 
13585   ins_pipe(pipe_serial);
13586 %}
13587 
13588 // ============================================================================
13589 // Compare Instructions
13590 
13591 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2)
13592 %{
13593   match(Set cr (CmpI op1 op2));
13594 
13595   effect(DEF cr, USE op1, USE op2);
13596 
13597   ins_cost(INSN_COST);
13598   format %{ "cmpw  $op1, $op2" %}
13599 
13600   ins_encode(aarch64_enc_cmpw(op1, op2));
13601 
13602   ins_pipe(icmp_reg_reg);
13603 %}
13604 
13605 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero)
13606 %{
13607   match(Set cr (CmpI op1 zero));
13608 
13609   effect(DEF cr, USE op1);
13610 
13611   ins_cost(INSN_COST);
13612   format %{ "cmpw $op1, 0" %}
13613 
13614   ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero));
13615 
13616   ins_pipe(icmp_reg_imm);
13617 %}
13618 
13619 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2)
13620 %{
13621   match(Set cr (CmpI op1 op2));
13622 
13623   effect(DEF cr, USE op1);
13624 
13625   ins_cost(INSN_COST);
13626   format %{ "cmpw  $op1, $op2" %}
13627 
13628   ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2));
13629 
13630   ins_pipe(icmp_reg_imm);
13631 %}
13632 
13633 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2)
13634 %{
13635   match(Set cr (CmpI op1 op2));
13636 
13637   effect(DEF cr, USE op1);
13638 
13639   ins_cost(INSN_COST * 2);
13640   format %{ "cmpw  $op1, $op2" %}
13641 
13642   ins_encode(aarch64_enc_cmpw_imm(op1, op2));
13643 
13644   ins_pipe(icmp_reg_imm);
13645 %}
13646 
13647 // Unsigned compare Instructions; really, same as signed compare
13648 // except it should only be used to feed an If or a CMovI which takes a
13649 // cmpOpU.
13650 
13651 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2)
13652 %{
13653   match(Set cr (CmpU op1 op2));
13654 
13655   effect(DEF cr, USE op1, USE op2);
13656 
13657   ins_cost(INSN_COST);
13658   format %{ "cmpw  $op1, $op2\t# unsigned" %}
13659 
13660   ins_encode(aarch64_enc_cmpw(op1, op2));
13661 
13662   ins_pipe(icmp_reg_reg);
13663 %}
13664 
13665 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero)
13666 %{
13667   match(Set cr (CmpU op1 zero));
13668 
13669   effect(DEF cr, USE op1);
13670 
13671   ins_cost(INSN_COST);
13672   format %{ "cmpw $op1, #0\t# unsigned" %}
13673 
13674   ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero));
13675 
13676   ins_pipe(icmp_reg_imm);
13677 %}
13678 
13679 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2)
13680 %{
13681   match(Set cr (CmpU op1 op2));
13682 
13683   effect(DEF cr, USE op1);
13684 
13685   ins_cost(INSN_COST);
13686   format %{ "cmpw  $op1, $op2\t# unsigned" %}
13687 
13688   ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2));
13689 
13690   ins_pipe(icmp_reg_imm);
13691 %}
13692 
13693 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2)
13694 %{
13695   match(Set cr (CmpU op1 op2));
13696 
13697   effect(DEF cr, USE op1);
13698 
13699   ins_cost(INSN_COST * 2);
13700   format %{ "cmpw  $op1, $op2\t# unsigned" %}
13701 
13702   ins_encode(aarch64_enc_cmpw_imm(op1, op2));
13703 
13704   ins_pipe(icmp_reg_imm);
13705 %}
13706 
13707 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
13708 %{
13709   match(Set cr (CmpL op1 op2));
13710 
13711   effect(DEF cr, USE op1, USE op2);
13712 
13713   ins_cost(INSN_COST);
13714   format %{ "cmp  $op1, $op2" %}
13715 
13716   ins_encode(aarch64_enc_cmp(op1, op2));
13717 
13718   ins_pipe(icmp_reg_reg);
13719 %}
13720 
13721 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero)
13722 %{
13723   match(Set cr (CmpL op1 zero));
13724 
13725   effect(DEF cr, USE op1);
13726 
13727   ins_cost(INSN_COST);
13728   format %{ "tst  $op1" %}
13729 
13730   ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero));
13731 
13732   ins_pipe(icmp_reg_imm);
13733 %}
13734 
13735 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2)
13736 %{
13737   match(Set cr (CmpL op1 op2));
13738 
13739   effect(DEF cr, USE op1);
13740 
13741   ins_cost(INSN_COST);
13742   format %{ "cmp  $op1, $op2" %}
13743 
13744   ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2));
13745 
13746   ins_pipe(icmp_reg_imm);
13747 %}
13748 
13749 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2)
13750 %{
13751   match(Set cr (CmpL op1 op2));
13752 
13753   effect(DEF cr, USE op1);
13754 
13755   ins_cost(INSN_COST * 2);
13756   format %{ "cmp  $op1, $op2" %}
13757 
13758   ins_encode(aarch64_enc_cmp_imm(op1, op2));
13759 
13760   ins_pipe(icmp_reg_imm);
13761 %}
13762 
13763 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2)
13764 %{
13765   match(Set cr (CmpUL op1 op2));
13766 
13767   effect(DEF cr, USE op1, USE op2);
13768 
13769   ins_cost(INSN_COST);
13770   format %{ "cmp  $op1, $op2" %}
13771 
13772   ins_encode(aarch64_enc_cmp(op1, op2));
13773 
13774   ins_pipe(icmp_reg_reg);
13775 %}
13776 
13777 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero)
13778 %{
13779   match(Set cr (CmpUL op1 zero));
13780 
13781   effect(DEF cr, USE op1);
13782 
13783   ins_cost(INSN_COST);
13784   format %{ "tst  $op1" %}
13785 
13786   ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero));
13787 
13788   ins_pipe(icmp_reg_imm);
13789 %}
13790 
13791 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2)
13792 %{
13793   match(Set cr (CmpUL op1 op2));
13794 
13795   effect(DEF cr, USE op1);
13796 
13797   ins_cost(INSN_COST);
13798   format %{ "cmp  $op1, $op2" %}
13799 
13800   ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2));
13801 
13802   ins_pipe(icmp_reg_imm);
13803 %}
13804 
13805 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2)
13806 %{
13807   match(Set cr (CmpUL op1 op2));
13808 
13809   effect(DEF cr, USE op1);
13810 
13811   ins_cost(INSN_COST * 2);
13812   format %{ "cmp  $op1, $op2" %}
13813 
13814   ins_encode(aarch64_enc_cmp_imm(op1, op2));
13815 
13816   ins_pipe(icmp_reg_imm);
13817 %}
13818 
13819 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2)
13820 %{
13821   match(Set cr (CmpP op1 op2));
13822 
13823   effect(DEF cr, USE op1, USE op2);
13824 
13825   ins_cost(INSN_COST);
13826   format %{ "cmp  $op1, $op2\t // ptr" %}
13827 
13828   ins_encode(aarch64_enc_cmpp(op1, op2));
13829 
13830   ins_pipe(icmp_reg_reg);
13831 %}
13832 
13833 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2)
13834 %{
13835   match(Set cr (CmpN op1 op2));
13836 
13837   effect(DEF cr, USE op1, USE op2);
13838 
13839   ins_cost(INSN_COST);
13840   format %{ "cmp  $op1, $op2\t // compressed ptr" %}
13841 
13842   ins_encode(aarch64_enc_cmpn(op1, op2));
13843 
13844   ins_pipe(icmp_reg_reg);
13845 %}
13846 
13847 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero)
13848 %{
13849   match(Set cr (CmpP op1 zero));
13850 
13851   effect(DEF cr, USE op1, USE zero);
13852 
13853   ins_cost(INSN_COST);
13854   format %{ "cmp  $op1, 0\t // ptr" %}
13855 
13856   ins_encode(aarch64_enc_testp(op1));
13857 
13858   ins_pipe(icmp_reg_imm);
13859 %}
13860 
13861 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero)
13862 %{
13863   match(Set cr (CmpN op1 zero));
13864 
13865   effect(DEF cr, USE op1, USE zero);
13866 
13867   ins_cost(INSN_COST);
13868   format %{ "cmp  $op1, 0\t // compressed ptr" %}
13869 
13870   ins_encode(aarch64_enc_testn(op1));
13871 
13872   ins_pipe(icmp_reg_imm);
13873 %}
13874 
13875 // FP comparisons
13876 //
13877 // n.b. CmpF/CmpD set a normal flags reg which then gets compared
13878 // using normal cmpOp. See declaration of rFlagsReg for details.
13879 
13880 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2)
13881 %{
13882   match(Set cr (CmpF src1 src2));
13883 
13884   ins_cost(3 * INSN_COST);
13885   format %{ "fcmps $src1, $src2" %}
13886 
13887   ins_encode %{
13888     __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
13889   %}
13890 
13891   ins_pipe(pipe_class_compare);
13892 %}
13893 
13894 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2)
13895 %{
13896   match(Set cr (CmpF src1 src2));
13897 
13898   ins_cost(3 * INSN_COST);
13899   format %{ "fcmps $src1, 0.0" %}
13900 
13901   ins_encode %{
13902     __ fcmps(as_FloatRegister($src1$$reg), 0.0D);
13903   %}
13904 
13905   ins_pipe(pipe_class_compare);
13906 %}
13907 // FROM HERE
13908 
13909 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2)
13910 %{
13911   match(Set cr (CmpD src1 src2));
13912 
13913   ins_cost(3 * INSN_COST);
13914   format %{ "fcmpd $src1, $src2" %}
13915 
13916   ins_encode %{
13917     __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
13918   %}
13919 
13920   ins_pipe(pipe_class_compare);
13921 %}
13922 
13923 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2)
13924 %{
13925   match(Set cr (CmpD src1 src2));
13926 
13927   ins_cost(3 * INSN_COST);
13928   format %{ "fcmpd $src1, 0.0" %}
13929 
13930   ins_encode %{
13931     __ fcmpd(as_FloatRegister($src1$$reg), 0.0D);
13932   %}
13933 
13934   ins_pipe(pipe_class_compare);
13935 %}
13936 
13937 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr)
13938 %{
13939   match(Set dst (CmpF3 src1 src2));
13940   effect(KILL cr);
13941 
13942   ins_cost(5 * INSN_COST);
13943   format %{ "fcmps $src1, $src2\n\t"
13944             "csinvw($dst, zr, zr, eq\n\t"
13945             "csnegw($dst, $dst, $dst, lt)"
13946   %}
13947 
13948   ins_encode %{
13949     Label done;
13950     FloatRegister s1 = as_FloatRegister($src1$$reg);
13951     FloatRegister s2 = as_FloatRegister($src2$$reg);
13952     Register d = as_Register($dst$$reg);
13953     __ fcmps(s1, s2);
13954     // installs 0 if EQ else -1
13955     __ csinvw(d, zr, zr, Assembler::EQ);
13956     // keeps -1 if less or unordered else installs 1
13957     __ csnegw(d, d, d, Assembler::LT);
13958     __ bind(done);
13959   %}
13960 
13961   ins_pipe(pipe_class_default);
13962 
13963 %}
13964 
13965 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr)
13966 %{
13967   match(Set dst (CmpD3 src1 src2));
13968   effect(KILL cr);
13969 
13970   ins_cost(5 * INSN_COST);
13971   format %{ "fcmpd $src1, $src2\n\t"
13972             "csinvw($dst, zr, zr, eq\n\t"
13973             "csnegw($dst, $dst, $dst, lt)"
13974   %}
13975 
13976   ins_encode %{
13977     Label done;
13978     FloatRegister s1 = as_FloatRegister($src1$$reg);
13979     FloatRegister s2 = as_FloatRegister($src2$$reg);
13980     Register d = as_Register($dst$$reg);
13981     __ fcmpd(s1, s2);
13982     // installs 0 if EQ else -1
13983     __ csinvw(d, zr, zr, Assembler::EQ);
13984     // keeps -1 if less or unordered else installs 1
13985     __ csnegw(d, d, d, Assembler::LT);
13986     __ bind(done);
13987   %}
13988   ins_pipe(pipe_class_default);
13989 
13990 %}
13991 
13992 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr)
13993 %{
13994   match(Set dst (CmpF3 src1 zero));
13995   effect(KILL cr);
13996 
13997   ins_cost(5 * INSN_COST);
13998   format %{ "fcmps $src1, 0.0\n\t"
13999             "csinvw($dst, zr, zr, eq\n\t"
14000             "csnegw($dst, $dst, $dst, lt)"
14001   %}
14002 
14003   ins_encode %{
14004     Label done;
14005     FloatRegister s1 = as_FloatRegister($src1$$reg);
14006     Register d = as_Register($dst$$reg);
14007     __ fcmps(s1, 0.0D);
14008     // installs 0 if EQ else -1
14009     __ csinvw(d, zr, zr, Assembler::EQ);
14010     // keeps -1 if less or unordered else installs 1
14011     __ csnegw(d, d, d, Assembler::LT);
14012     __ bind(done);
14013   %}
14014 
14015   ins_pipe(pipe_class_default);
14016 
14017 %}
14018 
14019 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr)
14020 %{
14021   match(Set dst (CmpD3 src1 zero));
14022   effect(KILL cr);
14023 
14024   ins_cost(5 * INSN_COST);
14025   format %{ "fcmpd $src1, 0.0\n\t"
14026             "csinvw($dst, zr, zr, eq\n\t"
14027             "csnegw($dst, $dst, $dst, lt)"
14028   %}
14029 
14030   ins_encode %{
14031     Label done;
14032     FloatRegister s1 = as_FloatRegister($src1$$reg);
14033     Register d = as_Register($dst$$reg);
14034     __ fcmpd(s1, 0.0D);
14035     // installs 0 if EQ else -1
14036     __ csinvw(d, zr, zr, Assembler::EQ);
14037     // keeps -1 if less or unordered else installs 1
14038     __ csnegw(d, d, d, Assembler::LT);
14039     __ bind(done);
14040   %}
14041   ins_pipe(pipe_class_default);
14042 
14043 %}
14044 
14045 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr)
14046 %{
14047   match(Set dst (CmpLTMask p q));
14048   effect(KILL cr);
14049 
14050   ins_cost(3 * INSN_COST);
14051 
14052   format %{ "cmpw $p, $q\t# cmpLTMask\n\t"
14053             "csetw $dst, lt\n\t"
14054             "subw $dst, zr, $dst"
14055   %}
14056 
14057   ins_encode %{
14058     __ cmpw(as_Register($p$$reg), as_Register($q$$reg));
14059     __ csetw(as_Register($dst$$reg), Assembler::LT);
14060     __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg));
14061   %}
14062 
14063   ins_pipe(ialu_reg_reg);
14064 %}
14065 
14066 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr)
14067 %{
14068   match(Set dst (CmpLTMask src zero));
14069   effect(KILL cr);
14070 
14071   ins_cost(INSN_COST);
14072 
14073   format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %}
14074 
14075   ins_encode %{
14076     __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31);
14077   %}
14078 
14079   ins_pipe(ialu_reg_shift);
14080 %}
14081 
14082 // ============================================================================
14083 // Max and Min
14084 
14085 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr)
14086 %{
14087   match(Set dst (MinI src1 src2));
14088 
14089   effect(DEF dst, USE src1, USE src2, KILL cr);
14090   size(8);
14091 
14092   ins_cost(INSN_COST * 3);
14093   format %{
14094     "cmpw $src1 $src2\t signed int\n\t"
14095     "cselw $dst, $src1, $src2 lt\t"
14096   %}
14097 
14098   ins_encode %{
14099     __ cmpw(as_Register($src1$$reg),
14100             as_Register($src2$$reg));
14101     __ cselw(as_Register($dst$$reg),
14102              as_Register($src1$$reg),
14103              as_Register($src2$$reg),
14104              Assembler::LT);
14105   %}
14106 
14107   ins_pipe(ialu_reg_reg);
14108 %}
14109 // FROM HERE
14110 
14111 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr)
14112 %{
14113   match(Set dst (MaxI src1 src2));
14114 
14115   effect(DEF dst, USE src1, USE src2, KILL cr);
14116   size(8);
14117 
14118   ins_cost(INSN_COST * 3);
14119   format %{
14120     "cmpw $src1 $src2\t signed int\n\t"
14121     "cselw $dst, $src1, $src2 gt\t"
14122   %}
14123 
14124   ins_encode %{
14125     __ cmpw(as_Register($src1$$reg),
14126             as_Register($src2$$reg));
14127     __ cselw(as_Register($dst$$reg),
14128              as_Register($src1$$reg),
14129              as_Register($src2$$reg),
14130              Assembler::GT);
14131   %}
14132 
14133   ins_pipe(ialu_reg_reg);
14134 %}
14135 
14136 // ============================================================================
14137 // Branch Instructions
14138 
14139 // Direct Branch.
14140 instruct branch(label lbl)
14141 %{
14142   match(Goto);
14143 
14144   effect(USE lbl);
14145 
14146   ins_cost(BRANCH_COST);
14147   format %{ "b  $lbl" %}
14148 
14149   ins_encode(aarch64_enc_b(lbl));
14150 
14151   ins_pipe(pipe_branch);
14152 %}
14153 
14154 // Conditional Near Branch
14155 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl)
14156 %{
14157   // Same match rule as `branchConFar'.
14158   match(If cmp cr);
14159 
14160   effect(USE lbl);
14161 
14162   ins_cost(BRANCH_COST);
14163   // If set to 1 this indicates that the current instruction is a
14164   // short variant of a long branch. This avoids using this
14165   // instruction in first-pass matching. It will then only be used in
14166   // the `Shorten_branches' pass.
14167   // ins_short_branch(1);
14168   format %{ "b$cmp  $lbl" %}
14169 
14170   ins_encode(aarch64_enc_br_con(cmp, lbl));
14171 
14172   ins_pipe(pipe_branch_cond);
14173 %}
14174 
14175 // Conditional Near Branch Unsigned
14176 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl)
14177 %{
14178   // Same match rule as `branchConFar'.
14179   match(If cmp cr);
14180 
14181   effect(USE lbl);
14182 
14183   ins_cost(BRANCH_COST);
14184   // If set to 1 this indicates that the current instruction is a
14185   // short variant of a long branch. This avoids using this
14186   // instruction in first-pass matching. It will then only be used in
14187   // the `Shorten_branches' pass.
14188   // ins_short_branch(1);
14189   format %{ "b$cmp  $lbl\t# unsigned" %}
14190 
14191   ins_encode(aarch64_enc_br_conU(cmp, lbl));
14192 
14193   ins_pipe(pipe_branch_cond);
14194 %}
14195 
14196 // Make use of CBZ and CBNZ.  These instructions, as well as being
14197 // shorter than (cmp; branch), have the additional benefit of not
14198 // killing the flags.
14199 
14200 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{
14201   match(If cmp (CmpI op1 op2));
14202   effect(USE labl);
14203 
14204   ins_cost(BRANCH_COST);
14205   format %{ "cbw$cmp   $op1, $labl" %}
14206   ins_encode %{
14207     Label* L = $labl$$label;
14208     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14209     if (cond == Assembler::EQ)
14210       __ cbzw($op1$$Register, *L);
14211     else
14212       __ cbnzw($op1$$Register, *L);
14213   %}
14214   ins_pipe(pipe_cmp_branch);
14215 %}
14216 
14217 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{
14218   match(If cmp (CmpL op1 op2));
14219   effect(USE labl);
14220 
14221   ins_cost(BRANCH_COST);
14222   format %{ "cb$cmp   $op1, $labl" %}
14223   ins_encode %{
14224     Label* L = $labl$$label;
14225     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14226     if (cond == Assembler::EQ)
14227       __ cbz($op1$$Register, *L);
14228     else
14229       __ cbnz($op1$$Register, *L);
14230   %}
14231   ins_pipe(pipe_cmp_branch);
14232 %}
14233 
14234 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{
14235   match(If cmp (CmpP op1 op2));
14236   effect(USE labl);
14237 
14238   ins_cost(BRANCH_COST);
14239   format %{ "cb$cmp   $op1, $labl" %}
14240   ins_encode %{
14241     Label* L = $labl$$label;
14242     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14243     if (cond == Assembler::EQ)
14244       __ cbz($op1$$Register, *L);
14245     else
14246       __ cbnz($op1$$Register, *L);
14247   %}
14248   ins_pipe(pipe_cmp_branch);
14249 %}
14250 
14251 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{
14252   match(If cmp (CmpN op1 op2));
14253   effect(USE labl);
14254 
14255   ins_cost(BRANCH_COST);
14256   format %{ "cbw$cmp   $op1, $labl" %}
14257   ins_encode %{
14258     Label* L = $labl$$label;
14259     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14260     if (cond == Assembler::EQ)
14261       __ cbzw($op1$$Register, *L);
14262     else
14263       __ cbnzw($op1$$Register, *L);
14264   %}
14265   ins_pipe(pipe_cmp_branch);
14266 %}
14267 
14268 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{
14269   match(If cmp (CmpP (DecodeN oop) zero));
14270   effect(USE labl);
14271 
14272   ins_cost(BRANCH_COST);
14273   format %{ "cb$cmp   $oop, $labl" %}
14274   ins_encode %{
14275     Label* L = $labl$$label;
14276     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14277     if (cond == Assembler::EQ)
14278       __ cbzw($oop$$Register, *L);
14279     else
14280       __ cbnzw($oop$$Register, *L);
14281   %}
14282   ins_pipe(pipe_cmp_branch);
14283 %}
14284 
14285 instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{
14286   match(If cmp (CmpU op1 op2));
14287   effect(USE labl);
14288 
14289   ins_cost(BRANCH_COST);
14290   format %{ "cbw$cmp   $op1, $labl" %}
14291   ins_encode %{
14292     Label* L = $labl$$label;
14293     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14294     if (cond == Assembler::EQ || cond == Assembler::LS)
14295       __ cbzw($op1$$Register, *L);
14296     else
14297       __ cbnzw($op1$$Register, *L);
14298   %}
14299   ins_pipe(pipe_cmp_branch);
14300 %}
14301 
14302 instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{
14303   match(If cmp (CmpUL op1 op2));
14304   effect(USE labl);
14305 
14306   ins_cost(BRANCH_COST);
14307   format %{ "cb$cmp   $op1, $labl" %}
14308   ins_encode %{
14309     Label* L = $labl$$label;
14310     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14311     if (cond == Assembler::EQ || cond == Assembler::LS)
14312       __ cbz($op1$$Register, *L);
14313     else
14314       __ cbnz($op1$$Register, *L);
14315   %}
14316   ins_pipe(pipe_cmp_branch);
14317 %}
14318 
14319 // Test bit and Branch
14320 
14321 // Patterns for short (< 32KiB) variants
14322 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{
14323   match(If cmp (CmpL op1 op2));
14324   effect(USE labl);
14325 
14326   ins_cost(BRANCH_COST);
14327   format %{ "cb$cmp   $op1, $labl # long" %}
14328   ins_encode %{
14329     Label* L = $labl$$label;
14330     Assembler::Condition cond =
14331       ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
14332     __ tbr(cond, $op1$$Register, 63, *L);
14333   %}
14334   ins_pipe(pipe_cmp_branch);
14335   ins_short_branch(1);
14336 %}
14337 
14338 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{
14339   match(If cmp (CmpI op1 op2));
14340   effect(USE labl);
14341 
14342   ins_cost(BRANCH_COST);
14343   format %{ "cb$cmp   $op1, $labl # int" %}
14344   ins_encode %{
14345     Label* L = $labl$$label;
14346     Assembler::Condition cond =
14347       ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
14348     __ tbr(cond, $op1$$Register, 31, *L);
14349   %}
14350   ins_pipe(pipe_cmp_branch);
14351   ins_short_branch(1);
14352 %}
14353 
14354 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{
14355   match(If cmp (CmpL (AndL op1 op2) op3));
14356   predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long()));
14357   effect(USE labl);
14358 
14359   ins_cost(BRANCH_COST);
14360   format %{ "tb$cmp   $op1, $op2, $labl" %}
14361   ins_encode %{
14362     Label* L = $labl$$label;
14363     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14364     int bit = exact_log2($op2$$constant);
14365     __ tbr(cond, $op1$$Register, bit, *L);
14366   %}
14367   ins_pipe(pipe_cmp_branch);
14368   ins_short_branch(1);
14369 %}
14370 
14371 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{
14372   match(If cmp (CmpI (AndI op1 op2) op3));
14373   predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int()));
14374   effect(USE labl);
14375 
14376   ins_cost(BRANCH_COST);
14377   format %{ "tb$cmp   $op1, $op2, $labl" %}
14378   ins_encode %{
14379     Label* L = $labl$$label;
14380     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14381     int bit = exact_log2($op2$$constant);
14382     __ tbr(cond, $op1$$Register, bit, *L);
14383   %}
14384   ins_pipe(pipe_cmp_branch);
14385   ins_short_branch(1);
14386 %}
14387 
14388 // And far variants
14389 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{
14390   match(If cmp (CmpL op1 op2));
14391   effect(USE labl);
14392 
14393   ins_cost(BRANCH_COST);
14394   format %{ "cb$cmp   $op1, $labl # long" %}
14395   ins_encode %{
14396     Label* L = $labl$$label;
14397     Assembler::Condition cond =
14398       ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
14399     __ tbr(cond, $op1$$Register, 63, *L, /*far*/true);
14400   %}
14401   ins_pipe(pipe_cmp_branch);
14402 %}
14403 
14404 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{
14405   match(If cmp (CmpI op1 op2));
14406   effect(USE labl);
14407 
14408   ins_cost(BRANCH_COST);
14409   format %{ "cb$cmp   $op1, $labl # int" %}
14410   ins_encode %{
14411     Label* L = $labl$$label;
14412     Assembler::Condition cond =
14413       ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
14414     __ tbr(cond, $op1$$Register, 31, *L, /*far*/true);
14415   %}
14416   ins_pipe(pipe_cmp_branch);
14417 %}
14418 
14419 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{
14420   match(If cmp (CmpL (AndL op1 op2) op3));
14421   predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long()));
14422   effect(USE labl);
14423 
14424   ins_cost(BRANCH_COST);
14425   format %{ "tb$cmp   $op1, $op2, $labl" %}
14426   ins_encode %{
14427     Label* L = $labl$$label;
14428     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14429     int bit = exact_log2($op2$$constant);
14430     __ tbr(cond, $op1$$Register, bit, *L, /*far*/true);
14431   %}
14432   ins_pipe(pipe_cmp_branch);
14433 %}
14434 
14435 instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{
14436   match(If cmp (CmpI (AndI op1 op2) op3));
14437   predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int()));
14438   effect(USE labl);
14439 
14440   ins_cost(BRANCH_COST);
14441   format %{ "tb$cmp   $op1, $op2, $labl" %}
14442   ins_encode %{
14443     Label* L = $labl$$label;
14444     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14445     int bit = exact_log2($op2$$constant);
14446     __ tbr(cond, $op1$$Register, bit, *L, /*far*/true);
14447   %}
14448   ins_pipe(pipe_cmp_branch);
14449 %}
14450 
14451 // Test bits
14452 
14453 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{
14454   match(Set cr (CmpL (AndL op1 op2) op3));
14455   predicate(Assembler::operand_valid_for_logical_immediate
14456             (/*is_32*/false, n->in(1)->in(2)->get_long()));
14457 
14458   ins_cost(INSN_COST);
14459   format %{ "tst $op1, $op2 # long" %}
14460   ins_encode %{
14461     __ tst($op1$$Register, $op2$$constant);
14462   %}
14463   ins_pipe(ialu_reg_reg);
14464 %}
14465 
14466 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{
14467   match(Set cr (CmpI (AndI op1 op2) op3));
14468   predicate(Assembler::operand_valid_for_logical_immediate
14469             (/*is_32*/true, n->in(1)->in(2)->get_int()));
14470 
14471   ins_cost(INSN_COST);
14472   format %{ "tst $op1, $op2 # int" %}
14473   ins_encode %{
14474     __ tstw($op1$$Register, $op2$$constant);
14475   %}
14476   ins_pipe(ialu_reg_reg);
14477 %}
14478 
14479 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{
14480   match(Set cr (CmpL (AndL op1 op2) op3));
14481 
14482   ins_cost(INSN_COST);
14483   format %{ "tst $op1, $op2 # long" %}
14484   ins_encode %{
14485     __ tst($op1$$Register, $op2$$Register);
14486   %}
14487   ins_pipe(ialu_reg_reg);
14488 %}
14489 
14490 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{
14491   match(Set cr (CmpI (AndI op1 op2) op3));
14492 
14493   ins_cost(INSN_COST);
14494   format %{ "tstw $op1, $op2 # int" %}
14495   ins_encode %{
14496     __ tstw($op1$$Register, $op2$$Register);
14497   %}
14498   ins_pipe(ialu_reg_reg);
14499 %}
14500 
14501 
14502 // Conditional Far Branch
14503 // Conditional Far Branch Unsigned
14504 // TODO: fixme
14505 
14506 // counted loop end branch near
14507 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl)
14508 %{
14509   match(CountedLoopEnd cmp cr);
14510 
14511   effect(USE lbl);
14512 
14513   ins_cost(BRANCH_COST);
14514   // short variant.
14515   // ins_short_branch(1);
14516   format %{ "b$cmp $lbl \t// counted loop end" %}
14517 
14518   ins_encode(aarch64_enc_br_con(cmp, lbl));
14519 
14520   ins_pipe(pipe_branch);
14521 %}
14522 
14523 // counted loop end branch near Unsigned
14524 instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl)
14525 %{
14526   match(CountedLoopEnd cmp cr);
14527 
14528   effect(USE lbl);
14529 
14530   ins_cost(BRANCH_COST);
14531   // short variant.
14532   // ins_short_branch(1);
14533   format %{ "b$cmp $lbl \t// counted loop end unsigned" %}
14534 
14535   ins_encode(aarch64_enc_br_conU(cmp, lbl));
14536 
14537   ins_pipe(pipe_branch);
14538 %}
14539 
14540 // counted loop end branch far
14541 // counted loop end branch far unsigned
14542 // TODO: fixme
14543 
14544 // ============================================================================
14545 // inlined locking and unlocking
14546 
14547 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2)
14548 %{
14549   match(Set cr (FastLock object box));
14550   effect(TEMP tmp, TEMP tmp2);
14551 
14552   // TODO
14553   // identify correct cost
14554   ins_cost(5 * INSN_COST);
14555   format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %}
14556 
14557   ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2));
14558 
14559   ins_pipe(pipe_serial);
14560 %}
14561 
14562 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2)
14563 %{
14564   match(Set cr (FastUnlock object box));
14565   effect(TEMP tmp, TEMP tmp2);
14566 
14567   ins_cost(5 * INSN_COST);
14568   format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %}
14569 
14570   ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2));
14571 
14572   ins_pipe(pipe_serial);
14573 %}
14574 
14575 
14576 // ============================================================================
14577 // Safepoint Instructions
14578 
14579 // TODO
14580 // provide a near and far version of this code
14581 
14582 instruct safePoint(iRegP poll)
14583 %{
14584   match(SafePoint poll);
14585 
14586   format %{
14587     "ldrw zr, [$poll]\t# Safepoint: poll for GC"
14588   %}
14589   ins_encode %{
14590     __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type);
14591   %}
14592   ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem);
14593 %}
14594 
14595 
14596 // ============================================================================
14597 // Procedure Call/Return Instructions
14598 
14599 // Call Java Static Instruction
14600 
14601 instruct CallStaticJavaDirect(method meth)
14602 %{
14603   match(CallStaticJava);
14604 
14605   effect(USE meth);
14606 
14607   ins_cost(CALL_COST);
14608 
14609   format %{ "call,static $meth \t// ==> " %}
14610 
14611   ins_encode( aarch64_enc_java_static_call(meth),
14612               aarch64_enc_call_epilog );
14613 
14614   ins_pipe(pipe_class_call);
14615 %}
14616 
14617 // TO HERE
14618 
14619 // Call Java Dynamic Instruction
14620 instruct CallDynamicJavaDirect(method meth)
14621 %{
14622   match(CallDynamicJava);
14623 
14624   effect(USE meth);
14625 
14626   ins_cost(CALL_COST);
14627 
14628   format %{ "CALL,dynamic $meth \t// ==> " %}
14629 
14630   ins_encode( aarch64_enc_java_dynamic_call(meth),
14631                aarch64_enc_call_epilog );
14632 
14633   ins_pipe(pipe_class_call);
14634 %}
14635 
14636 // Call Runtime Instruction
14637 
14638 instruct CallRuntimeDirect(method meth)
14639 %{
14640   match(CallRuntime);
14641 
14642   effect(USE meth);
14643 
14644   ins_cost(CALL_COST);
14645 
14646   format %{ "CALL, runtime $meth" %}
14647 
14648   ins_encode( aarch64_enc_java_to_runtime(meth) );
14649 
14650   ins_pipe(pipe_class_call);
14651 %}
14652 
14653 // Call Runtime Instruction
14654 
14655 instruct CallLeafDirect(method meth)
14656 %{
14657   match(CallLeaf);
14658 
14659   effect(USE meth);
14660 
14661   ins_cost(CALL_COST);
14662 
14663   format %{ "CALL, runtime leaf $meth" %}
14664 
14665   ins_encode( aarch64_enc_java_to_runtime(meth) );
14666 
14667   ins_pipe(pipe_class_call);
14668 %}
14669 
14670 // Call Runtime Instruction
14671 
14672 instruct CallLeafNoFPDirect(method meth)
14673 %{
14674   match(CallLeafNoFP);
14675 
14676   effect(USE meth);
14677 
14678   ins_cost(CALL_COST);
14679 
14680   format %{ "CALL, runtime leaf nofp $meth" %}
14681 
14682   ins_encode( aarch64_enc_java_to_runtime(meth) );
14683 
14684   ins_pipe(pipe_class_call);
14685 %}
14686 
14687 // Tail Call; Jump from runtime stub to Java code.
14688 // Also known as an 'interprocedural jump'.
14689 // Target of jump will eventually return to caller.
14690 // TailJump below removes the return address.
14691 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop)
14692 %{
14693   match(TailCall jump_target method_oop);
14694 
14695   ins_cost(CALL_COST);
14696 
14697   format %{ "br $jump_target\t# $method_oop holds method oop" %}
14698 
14699   ins_encode(aarch64_enc_tail_call(jump_target));
14700 
14701   ins_pipe(pipe_class_call);
14702 %}
14703 
14704 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop)
14705 %{
14706   match(TailJump jump_target ex_oop);
14707 
14708   ins_cost(CALL_COST);
14709 
14710   format %{ "br $jump_target\t# $ex_oop holds exception oop" %}
14711 
14712   ins_encode(aarch64_enc_tail_jmp(jump_target));
14713 
14714   ins_pipe(pipe_class_call);
14715 %}
14716 
14717 // Create exception oop: created by stack-crawling runtime code.
14718 // Created exception is now available to this handler, and is setup
14719 // just prior to jumping to this handler. No code emitted.
14720 // TODO check
14721 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1
14722 instruct CreateException(iRegP_R0 ex_oop)
14723 %{
14724   match(Set ex_oop (CreateEx));
14725 
14726   format %{ " -- \t// exception oop; no code emitted" %}
14727 
14728   size(0);
14729 
14730   ins_encode( /*empty*/ );
14731 
14732   ins_pipe(pipe_class_empty);
14733 %}
14734 
14735 // Rethrow exception: The exception oop will come in the first
14736 // argument position. Then JUMP (not call) to the rethrow stub code.
14737 instruct RethrowException() %{
14738   match(Rethrow);
14739   ins_cost(CALL_COST);
14740 
14741   format %{ "b rethrow_stub" %}
14742 
14743   ins_encode( aarch64_enc_rethrow() );
14744 
14745   ins_pipe(pipe_class_call);
14746 %}
14747 
14748 
14749 // Return Instruction
14750 // epilog node loads ret address into lr as part of frame pop
14751 instruct Ret()
14752 %{
14753   match(Return);
14754 
14755   format %{ "ret\t// return register" %}
14756 
14757   ins_encode( aarch64_enc_ret() );
14758 
14759   ins_pipe(pipe_branch);
14760 %}
14761 
14762 // Die now.
14763 instruct ShouldNotReachHere() %{
14764   match(Halt);
14765 
14766   ins_cost(CALL_COST);
14767   format %{ "ShouldNotReachHere" %}
14768 
14769   ins_encode %{
14770     // +1 so NativeInstruction::is_sigill_zombie_not_entrant() doesn't
14771     // return true
14772     __ dpcs1(0xdead + 1);
14773   %}
14774 
14775   ins_pipe(pipe_class_default);
14776 %}
14777 
14778 // ============================================================================
14779 // Partial Subtype Check
14780 //
14781 // superklass array for an instance of the superklass.  Set a hidden
14782 // internal cache on a hit (cache is checked with exposed code in
14783 // gen_subtype_check()).  Return NZ for a miss or zero for a hit.  The
14784 // encoding ALSO sets flags.
14785 
14786 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr)
14787 %{
14788   match(Set result (PartialSubtypeCheck sub super));
14789   effect(KILL cr, KILL temp);
14790 
14791   ins_cost(1100);  // slightly larger than the next version
14792   format %{ "partialSubtypeCheck $result, $sub, $super" %}
14793 
14794   ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result));
14795 
14796   opcode(0x1); // Force zero of result reg on hit
14797 
14798   ins_pipe(pipe_class_memory);
14799 %}
14800 
14801 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr)
14802 %{
14803   match(Set cr (CmpP (PartialSubtypeCheck sub super) zero));
14804   effect(KILL temp, KILL result);
14805 
14806   ins_cost(1100);  // slightly larger than the next version
14807   format %{ "partialSubtypeCheck $result, $sub, $super == 0" %}
14808 
14809   ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result));
14810 
14811   opcode(0x0); // Don't zero result reg on hit
14812 
14813   ins_pipe(pipe_class_memory);
14814 %}
14815 
14816 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
14817                         iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr)
14818 %{
14819   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
14820   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
14821   effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
14822 
14823   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1" %}
14824   ins_encode %{
14825     // Count is in 8-bit bytes; non-Compact chars are 16 bits.
14826     __ string_compare($str1$$Register, $str2$$Register,
14827                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
14828                       $tmp1$$Register, $tmp2$$Register,
14829                       fnoreg, fnoreg, fnoreg, StrIntrinsicNode::UU);
14830   %}
14831   ins_pipe(pipe_class_memory);
14832 %}
14833 
14834 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
14835                         iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr)
14836 %{
14837   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
14838   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
14839   effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
14840 
14841   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1" %}
14842   ins_encode %{
14843     __ string_compare($str1$$Register, $str2$$Register,
14844                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
14845                       $tmp1$$Register, $tmp2$$Register,
14846                       fnoreg, fnoreg, fnoreg, StrIntrinsicNode::LL);
14847   %}
14848   ins_pipe(pipe_class_memory);
14849 %}
14850 
14851 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
14852                         iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
14853                         vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr)
14854 %{
14855   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
14856   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
14857   effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3,
14858          USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
14859 
14860   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %}
14861   ins_encode %{
14862     __ string_compare($str1$$Register, $str2$$Register,
14863                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
14864                       $tmp1$$Register, $tmp2$$Register,
14865                       $vtmp1$$FloatRegister, $vtmp2$$FloatRegister,
14866                       $vtmp3$$FloatRegister, StrIntrinsicNode::UL);
14867   %}
14868   ins_pipe(pipe_class_memory);
14869 %}
14870 
14871 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
14872                         iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
14873                         vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr)
14874 %{
14875   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
14876   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
14877   effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3,
14878          USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
14879 
14880   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %}
14881   ins_encode %{
14882     __ string_compare($str1$$Register, $str2$$Register,
14883                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
14884                       $tmp1$$Register, $tmp2$$Register,
14885                       $vtmp1$$FloatRegister, $vtmp2$$FloatRegister,
14886                       $vtmp3$$FloatRegister,StrIntrinsicNode::LU);
14887   %}
14888   ins_pipe(pipe_class_memory);
14889 %}
14890 
14891 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
14892        iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3,
14893        iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr)
14894 %{
14895   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
14896   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
14897   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
14898          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr);
14899   format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %}
14900 
14901   ins_encode %{
14902     __ string_indexof($str1$$Register, $str2$$Register,
14903                       $cnt1$$Register, $cnt2$$Register,
14904                       $tmp1$$Register, $tmp2$$Register,
14905                       $tmp3$$Register, $tmp4$$Register,
14906                       $tmp5$$Register, $tmp6$$Register,
14907                       -1, $result$$Register, StrIntrinsicNode::UU);
14908   %}
14909   ins_pipe(pipe_class_memory);
14910 %}
14911 
14912 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
14913        iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3,
14914        iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr)
14915 %{
14916   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
14917   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
14918   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
14919          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr);
14920   format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %}
14921 
14922   ins_encode %{
14923     __ string_indexof($str1$$Register, $str2$$Register,
14924                       $cnt1$$Register, $cnt2$$Register,
14925                       $tmp1$$Register, $tmp2$$Register,
14926                       $tmp3$$Register, $tmp4$$Register,
14927                       $tmp5$$Register, $tmp6$$Register,
14928                       -1, $result$$Register, StrIntrinsicNode::LL);
14929   %}
14930   ins_pipe(pipe_class_memory);
14931 %}
14932 
14933 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
14934        iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3,
14935        iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr)
14936 %{
14937   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
14938   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
14939   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
14940          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr);
14941   format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %}
14942 
14943   ins_encode %{
14944     __ string_indexof($str1$$Register, $str2$$Register,
14945                       $cnt1$$Register, $cnt2$$Register,
14946                       $tmp1$$Register, $tmp2$$Register,
14947                       $tmp3$$Register, $tmp4$$Register,
14948                       $tmp5$$Register, $tmp6$$Register,
14949                       -1, $result$$Register, StrIntrinsicNode::UL);
14950   %}
14951   ins_pipe(pipe_class_memory);
14952 %}
14953 
14954 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
14955                  immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
14956                  iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
14957 %{
14958   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
14959   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
14960   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
14961          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
14962   format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %}
14963 
14964   ins_encode %{
14965     int icnt2 = (int)$int_cnt2$$constant;
14966     __ string_indexof($str1$$Register, $str2$$Register,
14967                       $cnt1$$Register, zr,
14968                       $tmp1$$Register, $tmp2$$Register,
14969                       $tmp3$$Register, $tmp4$$Register, zr, zr,
14970                       icnt2, $result$$Register, StrIntrinsicNode::UU);
14971   %}
14972   ins_pipe(pipe_class_memory);
14973 %}
14974 
14975 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
14976                  immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
14977                  iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
14978 %{
14979   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
14980   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
14981   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
14982          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
14983   format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %}
14984 
14985   ins_encode %{
14986     int icnt2 = (int)$int_cnt2$$constant;
14987     __ string_indexof($str1$$Register, $str2$$Register,
14988                       $cnt1$$Register, zr,
14989                       $tmp1$$Register, $tmp2$$Register,
14990                       $tmp3$$Register, $tmp4$$Register, zr, zr,
14991                       icnt2, $result$$Register, StrIntrinsicNode::LL);
14992   %}
14993   ins_pipe(pipe_class_memory);
14994 %}
14995 
14996 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
14997                  immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
14998                  iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
14999 %{
15000   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
15001   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
15002   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
15003          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
15004   format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %}
15005 
15006   ins_encode %{
15007     int icnt2 = (int)$int_cnt2$$constant;
15008     __ string_indexof($str1$$Register, $str2$$Register,
15009                       $cnt1$$Register, zr,
15010                       $tmp1$$Register, $tmp2$$Register,
15011                       $tmp3$$Register, $tmp4$$Register, zr, zr,
15012                       icnt2, $result$$Register, StrIntrinsicNode::UL);
15013   %}
15014   ins_pipe(pipe_class_memory);
15015 %}
15016 
15017 instruct string_indexofU_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch,
15018                               iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
15019                               iRegINoSp tmp3, rFlagsReg cr)
15020 %{
15021   match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
15022   effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch,
15023          TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
15024 
15025   format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result" %}
15026 
15027   ins_encode %{
15028     __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register,
15029                            $result$$Register, $tmp1$$Register, $tmp2$$Register,
15030                            $tmp3$$Register);
15031   %}
15032   ins_pipe(pipe_class_memory);
15033 %}
15034 
15035 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt,
15036                         iRegI_R0 result, rFlagsReg cr)
15037 %{
15038   predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
15039   match(Set result (StrEquals (Binary str1 str2) cnt));
15040   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr);
15041 
15042   format %{ "String Equals $str1,$str2,$cnt -> $result" %}
15043   ins_encode %{
15044     // Count is in 8-bit bytes; non-Compact chars are 16 bits.
15045     __ string_equals($str1$$Register, $str2$$Register,
15046                      $result$$Register, $cnt$$Register, 1);
15047   %}
15048   ins_pipe(pipe_class_memory);
15049 %}
15050 
15051 instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt,
15052                         iRegI_R0 result, rFlagsReg cr)
15053 %{
15054   predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU);
15055   match(Set result (StrEquals (Binary str1 str2) cnt));
15056   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr);
15057 
15058   format %{ "String Equals $str1,$str2,$cnt -> $result" %}
15059   ins_encode %{
15060     // Count is in 8-bit bytes; non-Compact chars are 16 bits.
15061     __ string_equals($str1$$Register, $str2$$Register,
15062                      $result$$Register, $cnt$$Register, 2);
15063   %}
15064   ins_pipe(pipe_class_memory);
15065 %}
15066 
15067 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
15068                        iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3,
15069                        iRegP_R10 tmp, rFlagsReg cr)
15070 %{
15071   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
15072   match(Set result (AryEq ary1 ary2));
15073   effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
15074 
15075   format %{ "Array Equals $ary1,ary2 -> $result    // KILL $tmp" %}
15076   ins_encode %{
15077     __ arrays_equals($ary1$$Register, $ary2$$Register,
15078                      $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
15079                      $result$$Register, $tmp$$Register, 1);
15080     %}
15081   ins_pipe(pipe_class_memory);
15082 %}
15083 
15084 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
15085                        iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3,
15086                        iRegP_R10 tmp, rFlagsReg cr)
15087 %{
15088   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
15089   match(Set result (AryEq ary1 ary2));
15090   effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
15091 
15092   format %{ "Array Equals $ary1,ary2 -> $result    // KILL $tmp" %}
15093   ins_encode %{
15094     __ arrays_equals($ary1$$Register, $ary2$$Register,
15095                      $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
15096                      $result$$Register, $tmp$$Register, 2);
15097   %}
15098   ins_pipe(pipe_class_memory);
15099 %}
15100 
15101 instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr)
15102 %{
15103   match(Set result (HasNegatives ary1 len));
15104   effect(USE_KILL ary1, USE_KILL len, KILL cr);
15105   format %{ "has negatives byte[] $ary1,$len -> $result" %}
15106   ins_encode %{
15107     __ has_negatives($ary1$$Register, $len$$Register, $result$$Register);
15108   %}
15109   ins_pipe( pipe_slow );
15110 %}
15111 
15112 // fast char[] to byte[] compression
15113 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len,
15114                          vRegD_V0 tmp1, vRegD_V1 tmp2,
15115                          vRegD_V2 tmp3, vRegD_V3 tmp4,
15116                          iRegI_R0 result, rFlagsReg cr)
15117 %{
15118   match(Set result (StrCompressedCopy src (Binary dst len)));
15119   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr);
15120 
15121   format %{ "String Compress $src,$dst -> $result    // KILL R1, R2, R3, R4" %}
15122   ins_encode %{
15123     __ char_array_compress($src$$Register, $dst$$Register, $len$$Register,
15124                            $tmp1$$FloatRegister, $tmp2$$FloatRegister,
15125                            $tmp3$$FloatRegister, $tmp4$$FloatRegister,
15126                            $result$$Register);
15127   %}
15128   ins_pipe( pipe_slow );
15129 %}
15130 
15131 // fast byte[] to char[] inflation
15132 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len,
15133                         vRegD_V0 tmp1, vRegD_V1 tmp2, vRegD_V2 tmp3, iRegP_R3 tmp4, rFlagsReg cr)
15134 %{
15135   match(Set dummy (StrInflatedCopy src (Binary dst len)));
15136   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr);
15137 
15138   format %{ "String Inflate $src,$dst    // KILL $tmp1, $tmp2" %}
15139   ins_encode %{
15140     __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register,
15141                           $tmp1$$FloatRegister, $tmp2$$FloatRegister, $tmp3$$FloatRegister, $tmp4$$Register);
15142   %}
15143   ins_pipe(pipe_class_memory);
15144 %}
15145 
15146 // encode char[] to byte[] in ISO_8859_1
15147 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len,
15148                           vRegD_V0 Vtmp1, vRegD_V1 Vtmp2,
15149                           vRegD_V2 Vtmp3, vRegD_V3 Vtmp4,
15150                           iRegI_R0 result, rFlagsReg cr)
15151 %{
15152   match(Set result (EncodeISOArray src (Binary dst len)));
15153   effect(USE_KILL src, USE_KILL dst, USE_KILL len,
15154          KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr);
15155 
15156   format %{ "Encode array $src,$dst,$len -> $result" %}
15157   ins_encode %{
15158     __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register,
15159          $result$$Register, $Vtmp1$$FloatRegister,  $Vtmp2$$FloatRegister,
15160          $Vtmp3$$FloatRegister,  $Vtmp4$$FloatRegister);
15161   %}
15162   ins_pipe( pipe_class_memory );
15163 %}
15164 
15165 // ============================================================================
15166 // This name is KNOWN by the ADLC and cannot be changed.
15167 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
15168 // for this guy.
15169 instruct tlsLoadP(thread_RegP dst)
15170 %{
15171   match(Set dst (ThreadLocal));
15172 
15173   ins_cost(0);
15174 
15175   format %{ " -- \t// $dst=Thread::current(), empty" %}
15176 
15177   size(0);
15178 
15179   ins_encode( /*empty*/ );
15180 
15181   ins_pipe(pipe_class_empty);
15182 %}
15183 
15184 // ====================VECTOR INSTRUCTIONS=====================================
15185 
15186 // Load vector (32 bits)
15187 instruct loadV4(vecD dst, vmem4 mem)
15188 %{
15189   predicate(n->as_LoadVector()->memory_size() == 4);
15190   match(Set dst (LoadVector mem));
15191   ins_cost(4 * INSN_COST);
15192   format %{ "ldrs   $dst,$mem\t# vector (32 bits)" %}
15193   ins_encode( aarch64_enc_ldrvS(dst, mem) );
15194   ins_pipe(vload_reg_mem64);
15195 %}
15196 
15197 // Load vector (64 bits)
15198 instruct loadV8(vecD dst, vmem8 mem)
15199 %{
15200   predicate(n->as_LoadVector()->memory_size() == 8);
15201   match(Set dst (LoadVector mem));
15202   ins_cost(4 * INSN_COST);
15203   format %{ "ldrd   $dst,$mem\t# vector (64 bits)" %}
15204   ins_encode( aarch64_enc_ldrvD(dst, mem) );
15205   ins_pipe(vload_reg_mem64);
15206 %}
15207 
15208 // Load Vector (128 bits)
15209 instruct loadV16(vecX dst, vmem16 mem)
15210 %{
15211   predicate(n->as_LoadVector()->memory_size() == 16);
15212   match(Set dst (LoadVector mem));
15213   ins_cost(4 * INSN_COST);
15214   format %{ "ldrq   $dst,$mem\t# vector (128 bits)" %}
15215   ins_encode( aarch64_enc_ldrvQ(dst, mem) );
15216   ins_pipe(vload_reg_mem128);
15217 %}
15218 
15219 // Store Vector (32 bits)
15220 instruct storeV4(vecD src, vmem4 mem)
15221 %{
15222   predicate(n->as_StoreVector()->memory_size() == 4);
15223   match(Set mem (StoreVector mem src));
15224   ins_cost(4 * INSN_COST);
15225   format %{ "strs   $mem,$src\t# vector (32 bits)" %}
15226   ins_encode( aarch64_enc_strvS(src, mem) );
15227   ins_pipe(vstore_reg_mem64);
15228 %}
15229 
15230 // Store Vector (64 bits)
15231 instruct storeV8(vecD src, vmem8 mem)
15232 %{
15233   predicate(n->as_StoreVector()->memory_size() == 8);
15234   match(Set mem (StoreVector mem src));
15235   ins_cost(4 * INSN_COST);
15236   format %{ "strd   $mem,$src\t# vector (64 bits)" %}
15237   ins_encode( aarch64_enc_strvD(src, mem) );
15238   ins_pipe(vstore_reg_mem64);
15239 %}
15240 
15241 // Store Vector (128 bits)
15242 instruct storeV16(vecX src, vmem16 mem)
15243 %{
15244   predicate(n->as_StoreVector()->memory_size() == 16);
15245   match(Set mem (StoreVector mem src));
15246   ins_cost(4 * INSN_COST);
15247   format %{ "strq   $mem,$src\t# vector (128 bits)" %}
15248   ins_encode( aarch64_enc_strvQ(src, mem) );
15249   ins_pipe(vstore_reg_mem128);
15250 %}
15251 
15252 instruct replicate8B(vecD dst, iRegIorL2I src)
15253 %{
15254   predicate(n->as_Vector()->length() == 4 ||
15255             n->as_Vector()->length() == 8);
15256   match(Set dst (ReplicateB src));
15257   ins_cost(INSN_COST);
15258   format %{ "dup  $dst, $src\t# vector (8B)" %}
15259   ins_encode %{
15260     __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg));
15261   %}
15262   ins_pipe(vdup_reg_reg64);
15263 %}
15264 
15265 instruct replicate16B(vecX dst, iRegIorL2I src)
15266 %{
15267   predicate(n->as_Vector()->length() == 16);
15268   match(Set dst (ReplicateB src));
15269   ins_cost(INSN_COST);
15270   format %{ "dup  $dst, $src\t# vector (16B)" %}
15271   ins_encode %{
15272     __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($src$$reg));
15273   %}
15274   ins_pipe(vdup_reg_reg128);
15275 %}
15276 
15277 instruct replicate8B_imm(vecD dst, immI con)
15278 %{
15279   predicate(n->as_Vector()->length() == 4 ||
15280             n->as_Vector()->length() == 8);
15281   match(Set dst (ReplicateB con));
15282   ins_cost(INSN_COST);
15283   format %{ "movi  $dst, $con\t# vector(8B)" %}
15284   ins_encode %{
15285     __ mov(as_FloatRegister($dst$$reg), __ T8B, $con$$constant & 0xff);
15286   %}
15287   ins_pipe(vmovi_reg_imm64);
15288 %}
15289 
15290 instruct replicate16B_imm(vecX dst, immI con)
15291 %{
15292   predicate(n->as_Vector()->length() == 16);
15293   match(Set dst (ReplicateB con));
15294   ins_cost(INSN_COST);
15295   format %{ "movi  $dst, $con\t# vector(16B)" %}
15296   ins_encode %{
15297     __ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant & 0xff);
15298   %}
15299   ins_pipe(vmovi_reg_imm128);
15300 %}
15301 
15302 instruct replicate4S(vecD dst, iRegIorL2I src)
15303 %{
15304   predicate(n->as_Vector()->length() == 2 ||
15305             n->as_Vector()->length() == 4);
15306   match(Set dst (ReplicateS src));
15307   ins_cost(INSN_COST);
15308   format %{ "dup  $dst, $src\t# vector (4S)" %}
15309   ins_encode %{
15310     __ dup(as_FloatRegister($dst$$reg), __ T4H, as_Register($src$$reg));
15311   %}
15312   ins_pipe(vdup_reg_reg64);
15313 %}
15314 
15315 instruct replicate8S(vecX dst, iRegIorL2I src)
15316 %{
15317   predicate(n->as_Vector()->length() == 8);
15318   match(Set dst (ReplicateS src));
15319   ins_cost(INSN_COST);
15320   format %{ "dup  $dst, $src\t# vector (8S)" %}
15321   ins_encode %{
15322     __ dup(as_FloatRegister($dst$$reg), __ T8H, as_Register($src$$reg));
15323   %}
15324   ins_pipe(vdup_reg_reg128);
15325 %}
15326 
15327 instruct replicate4S_imm(vecD dst, immI con)
15328 %{
15329   predicate(n->as_Vector()->length() == 2 ||
15330             n->as_Vector()->length() == 4);
15331   match(Set dst (ReplicateS con));
15332   ins_cost(INSN_COST);
15333   format %{ "movi  $dst, $con\t# vector(4H)" %}
15334   ins_encode %{
15335     __ mov(as_FloatRegister($dst$$reg), __ T4H, $con$$constant & 0xffff);
15336   %}
15337   ins_pipe(vmovi_reg_imm64);
15338 %}
15339 
15340 instruct replicate8S_imm(vecX dst, immI con)
15341 %{
15342   predicate(n->as_Vector()->length() == 8);
15343   match(Set dst (ReplicateS con));
15344   ins_cost(INSN_COST);
15345   format %{ "movi  $dst, $con\t# vector(8H)" %}
15346   ins_encode %{
15347     __ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant & 0xffff);
15348   %}
15349   ins_pipe(vmovi_reg_imm128);
15350 %}
15351 
15352 instruct replicate2I(vecD dst, iRegIorL2I src)
15353 %{
15354   predicate(n->as_Vector()->length() == 2);
15355   match(Set dst (ReplicateI src));
15356   ins_cost(INSN_COST);
15357   format %{ "dup  $dst, $src\t# vector (2I)" %}
15358   ins_encode %{
15359     __ dup(as_FloatRegister($dst$$reg), __ T2S, as_Register($src$$reg));
15360   %}
15361   ins_pipe(vdup_reg_reg64);
15362 %}
15363 
15364 instruct replicate4I(vecX dst, iRegIorL2I src)
15365 %{
15366   predicate(n->as_Vector()->length() == 4);
15367   match(Set dst (ReplicateI src));
15368   ins_cost(INSN_COST);
15369   format %{ "dup  $dst, $src\t# vector (4I)" %}
15370   ins_encode %{
15371     __ dup(as_FloatRegister($dst$$reg), __ T4S, as_Register($src$$reg));
15372   %}
15373   ins_pipe(vdup_reg_reg128);
15374 %}
15375 
15376 instruct replicate2I_imm(vecD dst, immI con)
15377 %{
15378   predicate(n->as_Vector()->length() == 2);
15379   match(Set dst (ReplicateI con));
15380   ins_cost(INSN_COST);
15381   format %{ "movi  $dst, $con\t# vector(2I)" %}
15382   ins_encode %{
15383     __ mov(as_FloatRegister($dst$$reg), __ T2S, $con$$constant);
15384   %}
15385   ins_pipe(vmovi_reg_imm64);
15386 %}
15387 
15388 instruct replicate4I_imm(vecX dst, immI con)
15389 %{
15390   predicate(n->as_Vector()->length() == 4);
15391   match(Set dst (ReplicateI con));
15392   ins_cost(INSN_COST);
15393   format %{ "movi  $dst, $con\t# vector(4I)" %}
15394   ins_encode %{
15395     __ mov(as_FloatRegister($dst$$reg), __ T4S, $con$$constant);
15396   %}
15397   ins_pipe(vmovi_reg_imm128);
15398 %}
15399 
15400 instruct replicate2L(vecX dst, iRegL src)
15401 %{
15402   predicate(n->as_Vector()->length() == 2);
15403   match(Set dst (ReplicateL src));
15404   ins_cost(INSN_COST);
15405   format %{ "dup  $dst, $src\t# vector (2L)" %}
15406   ins_encode %{
15407     __ dup(as_FloatRegister($dst$$reg), __ T2D, as_Register($src$$reg));
15408   %}
15409   ins_pipe(vdup_reg_reg128);
15410 %}
15411 
15412 instruct replicate2L_zero(vecX dst, immI0 zero)
15413 %{
15414   predicate(n->as_Vector()->length() == 2);
15415   match(Set dst (ReplicateI zero));
15416   ins_cost(INSN_COST);
15417   format %{ "movi  $dst, $zero\t# vector(4I)" %}
15418   ins_encode %{
15419     __ eor(as_FloatRegister($dst$$reg), __ T16B,
15420            as_FloatRegister($dst$$reg),
15421            as_FloatRegister($dst$$reg));
15422   %}
15423   ins_pipe(vmovi_reg_imm128);
15424 %}
15425 
15426 instruct replicate2F(vecD dst, vRegF src)
15427 %{
15428   predicate(n->as_Vector()->length() == 2);
15429   match(Set dst (ReplicateF src));
15430   ins_cost(INSN_COST);
15431   format %{ "dup  $dst, $src\t# vector (2F)" %}
15432   ins_encode %{
15433     __ dup(as_FloatRegister($dst$$reg), __ T2S,
15434            as_FloatRegister($src$$reg));
15435   %}
15436   ins_pipe(vdup_reg_freg64);
15437 %}
15438 
15439 instruct replicate4F(vecX dst, vRegF src)
15440 %{
15441   predicate(n->as_Vector()->length() == 4);
15442   match(Set dst (ReplicateF src));
15443   ins_cost(INSN_COST);
15444   format %{ "dup  $dst, $src\t# vector (4F)" %}
15445   ins_encode %{
15446     __ dup(as_FloatRegister($dst$$reg), __ T4S,
15447            as_FloatRegister($src$$reg));
15448   %}
15449   ins_pipe(vdup_reg_freg128);
15450 %}
15451 
15452 instruct replicate2D(vecX dst, vRegD src)
15453 %{
15454   predicate(n->as_Vector()->length() == 2);
15455   match(Set dst (ReplicateD src));
15456   ins_cost(INSN_COST);
15457   format %{ "dup  $dst, $src\t# vector (2D)" %}
15458   ins_encode %{
15459     __ dup(as_FloatRegister($dst$$reg), __ T2D,
15460            as_FloatRegister($src$$reg));
15461   %}
15462   ins_pipe(vdup_reg_dreg128);
15463 %}
15464 
15465 // ====================REDUCTION ARITHMETIC====================================
15466 
15467 instruct reduce_add2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp, iRegINoSp tmp2)
15468 %{
15469   match(Set dst (AddReductionVI src1 src2));
15470   ins_cost(INSN_COST);
15471   effect(TEMP tmp, TEMP tmp2);
15472   format %{ "umov  $tmp, $src2, S, 0\n\t"
15473             "umov  $tmp2, $src2, S, 1\n\t"
15474             "addw  $dst, $src1, $tmp\n\t"
15475             "addw  $dst, $dst, $tmp2\t add reduction2i"
15476   %}
15477   ins_encode %{
15478     __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0);
15479     __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ S, 1);
15480     __ addw($dst$$Register, $src1$$Register, $tmp$$Register);
15481     __ addw($dst$$Register, $dst$$Register, $tmp2$$Register);
15482   %}
15483   ins_pipe(pipe_class_default);
15484 %}
15485 
15486 instruct reduce_add4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2)
15487 %{
15488   match(Set dst (AddReductionVI src1 src2));
15489   ins_cost(INSN_COST);
15490   effect(TEMP tmp, TEMP tmp2);
15491   format %{ "addv  $tmp, T4S, $src2\n\t"
15492             "umov  $tmp2, $tmp, S, 0\n\t"
15493             "addw  $dst, $tmp2, $src1\t add reduction4i"
15494   %}
15495   ins_encode %{
15496     __ addv(as_FloatRegister($tmp$$reg), __ T4S,
15497             as_FloatRegister($src2$$reg));
15498     __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0);
15499     __ addw($dst$$Register, $tmp2$$Register, $src1$$Register);
15500   %}
15501   ins_pipe(pipe_class_default);
15502 %}
15503 
15504 instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp)
15505 %{
15506   match(Set dst (MulReductionVI src1 src2));
15507   ins_cost(INSN_COST);
15508   effect(TEMP tmp, TEMP dst);
15509   format %{ "umov  $tmp, $src2, S, 0\n\t"
15510             "mul   $dst, $tmp, $src1\n\t"
15511             "umov  $tmp, $src2, S, 1\n\t"
15512             "mul   $dst, $tmp, $dst\t mul reduction2i\n\t"
15513   %}
15514   ins_encode %{
15515     __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0);
15516     __ mul($dst$$Register, $tmp$$Register, $src1$$Register);
15517     __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 1);
15518     __ mul($dst$$Register, $tmp$$Register, $dst$$Register);
15519   %}
15520   ins_pipe(pipe_class_default);
15521 %}
15522 
15523 instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2)
15524 %{
15525   match(Set dst (MulReductionVI src1 src2));
15526   ins_cost(INSN_COST);
15527   effect(TEMP tmp, TEMP tmp2, TEMP dst);
15528   format %{ "ins   $tmp, $src2, 0, 1\n\t"
15529             "mul   $tmp, $tmp, $src2\n\t"
15530             "umov  $tmp2, $tmp, S, 0\n\t"
15531             "mul   $dst, $tmp2, $src1\n\t"
15532             "umov  $tmp2, $tmp, S, 1\n\t"
15533             "mul   $dst, $tmp2, $dst\t mul reduction4i\n\t"
15534   %}
15535   ins_encode %{
15536     __ ins(as_FloatRegister($tmp$$reg), __ D,
15537            as_FloatRegister($src2$$reg), 0, 1);
15538     __ mulv(as_FloatRegister($tmp$$reg), __ T2S,
15539            as_FloatRegister($tmp$$reg), as_FloatRegister($src2$$reg));
15540     __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0);
15541     __ mul($dst$$Register, $tmp2$$Register, $src1$$Register);
15542     __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 1);
15543     __ mul($dst$$Register, $tmp2$$Register, $dst$$Register);
15544   %}
15545   ins_pipe(pipe_class_default);
15546 %}
15547 
15548 instruct reduce_add2F(vRegF dst, vRegF src1, vecD src2, vecD tmp)
15549 %{
15550   match(Set dst (AddReductionVF src1 src2));
15551   ins_cost(INSN_COST);
15552   effect(TEMP tmp, TEMP dst);
15553   format %{ "fadds $dst, $src1, $src2\n\t"
15554             "ins   $tmp, S, $src2, 0, 1\n\t"
15555             "fadds $dst, $dst, $tmp\t add reduction2f"
15556   %}
15557   ins_encode %{
15558     __ fadds(as_FloatRegister($dst$$reg),
15559              as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
15560     __ ins(as_FloatRegister($tmp$$reg), __ S,
15561            as_FloatRegister($src2$$reg), 0, 1);
15562     __ fadds(as_FloatRegister($dst$$reg),
15563              as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
15564   %}
15565   ins_pipe(pipe_class_default);
15566 %}
15567 
15568 instruct reduce_add4F(vRegF dst, vRegF src1, vecX src2, vecX tmp)
15569 %{
15570   match(Set dst (AddReductionVF src1 src2));
15571   ins_cost(INSN_COST);
15572   effect(TEMP tmp, TEMP dst);
15573   format %{ "fadds $dst, $src1, $src2\n\t"
15574             "ins   $tmp, S, $src2, 0, 1\n\t"
15575             "fadds $dst, $dst, $tmp\n\t"
15576             "ins   $tmp, S, $src2, 0, 2\n\t"
15577             "fadds $dst, $dst, $tmp\n\t"
15578             "ins   $tmp, S, $src2, 0, 3\n\t"
15579             "fadds $dst, $dst, $tmp\t add reduction4f"
15580   %}
15581   ins_encode %{
15582     __ fadds(as_FloatRegister($dst$$reg),
15583              as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
15584     __ ins(as_FloatRegister($tmp$$reg), __ S,
15585            as_FloatRegister($src2$$reg), 0, 1);
15586     __ fadds(as_FloatRegister($dst$$reg),
15587              as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
15588     __ ins(as_FloatRegister($tmp$$reg), __ S,
15589            as_FloatRegister($src2$$reg), 0, 2);
15590     __ fadds(as_FloatRegister($dst$$reg),
15591              as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
15592     __ ins(as_FloatRegister($tmp$$reg), __ S,
15593            as_FloatRegister($src2$$reg), 0, 3);
15594     __ fadds(as_FloatRegister($dst$$reg),
15595              as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
15596   %}
15597   ins_pipe(pipe_class_default);
15598 %}
15599 
15600 instruct reduce_mul2F(vRegF dst, vRegF src1, vecD src2, vecD tmp)
15601 %{
15602   match(Set dst (MulReductionVF src1 src2));
15603   ins_cost(INSN_COST);
15604   effect(TEMP tmp, TEMP dst);
15605   format %{ "fmuls $dst, $src1, $src2\n\t"
15606             "ins   $tmp, S, $src2, 0, 1\n\t"
15607             "fmuls $dst, $dst, $tmp\t add reduction4f"
15608   %}
15609   ins_encode %{
15610     __ fmuls(as_FloatRegister($dst$$reg),
15611              as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
15612     __ ins(as_FloatRegister($tmp$$reg), __ S,
15613            as_FloatRegister($src2$$reg), 0, 1);
15614     __ fmuls(as_FloatRegister($dst$$reg),
15615              as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
15616   %}
15617   ins_pipe(pipe_class_default);
15618 %}
15619 
15620 instruct reduce_mul4F(vRegF dst, vRegF src1, vecX src2, vecX tmp)
15621 %{
15622   match(Set dst (MulReductionVF src1 src2));
15623   ins_cost(INSN_COST);
15624   effect(TEMP tmp, TEMP dst);
15625   format %{ "fmuls $dst, $src1, $src2\n\t"
15626             "ins   $tmp, S, $src2, 0, 1\n\t"
15627             "fmuls $dst, $dst, $tmp\n\t"
15628             "ins   $tmp, S, $src2, 0, 2\n\t"
15629             "fmuls $dst, $dst, $tmp\n\t"
15630             "ins   $tmp, S, $src2, 0, 3\n\t"
15631             "fmuls $dst, $dst, $tmp\t add reduction4f"
15632   %}
15633   ins_encode %{
15634     __ fmuls(as_FloatRegister($dst$$reg),
15635              as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
15636     __ ins(as_FloatRegister($tmp$$reg), __ S,
15637            as_FloatRegister($src2$$reg), 0, 1);
15638     __ fmuls(as_FloatRegister($dst$$reg),
15639              as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
15640     __ ins(as_FloatRegister($tmp$$reg), __ S,
15641            as_FloatRegister($src2$$reg), 0, 2);
15642     __ fmuls(as_FloatRegister($dst$$reg),
15643              as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
15644     __ ins(as_FloatRegister($tmp$$reg), __ S,
15645            as_FloatRegister($src2$$reg), 0, 3);
15646     __ fmuls(as_FloatRegister($dst$$reg),
15647              as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
15648   %}
15649   ins_pipe(pipe_class_default);
15650 %}
15651 
15652 instruct reduce_add2D(vRegD dst, vRegD src1, vecX src2, vecX tmp)
15653 %{
15654   match(Set dst (AddReductionVD src1 src2));
15655   ins_cost(INSN_COST);
15656   effect(TEMP tmp, TEMP dst);
15657   format %{ "faddd $dst, $src1, $src2\n\t"
15658             "ins   $tmp, D, $src2, 0, 1\n\t"
15659             "faddd $dst, $dst, $tmp\t add reduction2d"
15660   %}
15661   ins_encode %{
15662     __ faddd(as_FloatRegister($dst$$reg),
15663              as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
15664     __ ins(as_FloatRegister($tmp$$reg), __ D,
15665            as_FloatRegister($src2$$reg), 0, 1);
15666     __ faddd(as_FloatRegister($dst$$reg),
15667              as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
15668   %}
15669   ins_pipe(pipe_class_default);
15670 %}
15671 
15672 instruct reduce_mul2D(vRegD dst, vRegD src1, vecX src2, vecX tmp)
15673 %{
15674   match(Set dst (MulReductionVD src1 src2));
15675   ins_cost(INSN_COST);
15676   effect(TEMP tmp, TEMP dst);
15677   format %{ "fmuld $dst, $src1, $src2\n\t"
15678             "ins   $tmp, D, $src2, 0, 1\n\t"
15679             "fmuld $dst, $dst, $tmp\t add reduction2d"
15680   %}
15681   ins_encode %{
15682     __ fmuld(as_FloatRegister($dst$$reg),
15683              as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
15684     __ ins(as_FloatRegister($tmp$$reg), __ D,
15685            as_FloatRegister($src2$$reg), 0, 1);
15686     __ fmuld(as_FloatRegister($dst$$reg),
15687              as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
15688   %}
15689   ins_pipe(pipe_class_default);
15690 %}
15691 
15692 // ====================VECTOR ARITHMETIC=======================================
15693 
15694 // --------------------------------- ADD --------------------------------------
15695 
15696 instruct vadd8B(vecD dst, vecD src1, vecD src2)
15697 %{
15698   predicate(n->as_Vector()->length() == 4 ||
15699             n->as_Vector()->length() == 8);
15700   match(Set dst (AddVB src1 src2));
15701   ins_cost(INSN_COST);
15702   format %{ "addv  $dst,$src1,$src2\t# vector (8B)" %}
15703   ins_encode %{
15704     __ addv(as_FloatRegister($dst$$reg), __ T8B,
15705             as_FloatRegister($src1$$reg),
15706             as_FloatRegister($src2$$reg));
15707   %}
15708   ins_pipe(vdop64);
15709 %}
15710 
15711 instruct vadd16B(vecX dst, vecX src1, vecX src2)
15712 %{
15713   predicate(n->as_Vector()->length() == 16);
15714   match(Set dst (AddVB src1 src2));
15715   ins_cost(INSN_COST);
15716   format %{ "addv  $dst,$src1,$src2\t# vector (16B)" %}
15717   ins_encode %{
15718     __ addv(as_FloatRegister($dst$$reg), __ T16B,
15719             as_FloatRegister($src1$$reg),
15720             as_FloatRegister($src2$$reg));
15721   %}
15722   ins_pipe(vdop128);
15723 %}
15724 
15725 instruct vadd4S(vecD dst, vecD src1, vecD src2)
15726 %{
15727   predicate(n->as_Vector()->length() == 2 ||
15728             n->as_Vector()->length() == 4);
15729   match(Set dst (AddVS src1 src2));
15730   ins_cost(INSN_COST);
15731   format %{ "addv  $dst,$src1,$src2\t# vector (4H)" %}
15732   ins_encode %{
15733     __ addv(as_FloatRegister($dst$$reg), __ T4H,
15734             as_FloatRegister($src1$$reg),
15735             as_FloatRegister($src2$$reg));
15736   %}
15737   ins_pipe(vdop64);
15738 %}
15739 
15740 instruct vadd8S(vecX dst, vecX src1, vecX src2)
15741 %{
15742   predicate(n->as_Vector()->length() == 8);
15743   match(Set dst (AddVS src1 src2));
15744   ins_cost(INSN_COST);
15745   format %{ "addv  $dst,$src1,$src2\t# vector (8H)" %}
15746   ins_encode %{
15747     __ addv(as_FloatRegister($dst$$reg), __ T8H,
15748             as_FloatRegister($src1$$reg),
15749             as_FloatRegister($src2$$reg));
15750   %}
15751   ins_pipe(vdop128);
15752 %}
15753 
15754 instruct vadd2I(vecD dst, vecD src1, vecD src2)
15755 %{
15756   predicate(n->as_Vector()->length() == 2);
15757   match(Set dst (AddVI src1 src2));
15758   ins_cost(INSN_COST);
15759   format %{ "addv  $dst,$src1,$src2\t# vector (2S)" %}
15760   ins_encode %{
15761     __ addv(as_FloatRegister($dst$$reg), __ T2S,
15762             as_FloatRegister($src1$$reg),
15763             as_FloatRegister($src2$$reg));
15764   %}
15765   ins_pipe(vdop64);
15766 %}
15767 
15768 instruct vadd4I(vecX dst, vecX src1, vecX src2)
15769 %{
15770   predicate(n->as_Vector()->length() == 4);
15771   match(Set dst (AddVI src1 src2));
15772   ins_cost(INSN_COST);
15773   format %{ "addv  $dst,$src1,$src2\t# vector (4S)" %}
15774   ins_encode %{
15775     __ addv(as_FloatRegister($dst$$reg), __ T4S,
15776             as_FloatRegister($src1$$reg),
15777             as_FloatRegister($src2$$reg));
15778   %}
15779   ins_pipe(vdop128);
15780 %}
15781 
15782 instruct vadd2L(vecX dst, vecX src1, vecX src2)
15783 %{
15784   predicate(n->as_Vector()->length() == 2);
15785   match(Set dst (AddVL src1 src2));
15786   ins_cost(INSN_COST);
15787   format %{ "addv  $dst,$src1,$src2\t# vector (2L)" %}
15788   ins_encode %{
15789     __ addv(as_FloatRegister($dst$$reg), __ T2D,
15790             as_FloatRegister($src1$$reg),
15791             as_FloatRegister($src2$$reg));
15792   %}
15793   ins_pipe(vdop128);
15794 %}
15795 
15796 instruct vadd2F(vecD dst, vecD src1, vecD src2)
15797 %{
15798   predicate(n->as_Vector()->length() == 2);
15799   match(Set dst (AddVF src1 src2));
15800   ins_cost(INSN_COST);
15801   format %{ "fadd  $dst,$src1,$src2\t# vector (2S)" %}
15802   ins_encode %{
15803     __ fadd(as_FloatRegister($dst$$reg), __ T2S,
15804             as_FloatRegister($src1$$reg),
15805             as_FloatRegister($src2$$reg));
15806   %}
15807   ins_pipe(vdop_fp64);
15808 %}
15809 
15810 instruct vadd4F(vecX dst, vecX src1, vecX src2)
15811 %{
15812   predicate(n->as_Vector()->length() == 4);
15813   match(Set dst (AddVF src1 src2));
15814   ins_cost(INSN_COST);
15815   format %{ "fadd  $dst,$src1,$src2\t# vector (4S)" %}
15816   ins_encode %{
15817     __ fadd(as_FloatRegister($dst$$reg), __ T4S,
15818             as_FloatRegister($src1$$reg),
15819             as_FloatRegister($src2$$reg));
15820   %}
15821   ins_pipe(vdop_fp128);
15822 %}
15823 
15824 instruct vadd2D(vecX dst, vecX src1, vecX src2)
15825 %{
15826   match(Set dst (AddVD src1 src2));
15827   ins_cost(INSN_COST);
15828   format %{ "fadd  $dst,$src1,$src2\t# vector (2D)" %}
15829   ins_encode %{
15830     __ fadd(as_FloatRegister($dst$$reg), __ T2D,
15831             as_FloatRegister($src1$$reg),
15832             as_FloatRegister($src2$$reg));
15833   %}
15834   ins_pipe(vdop_fp128);
15835 %}
15836 
15837 // --------------------------------- SUB --------------------------------------
15838 
15839 instruct vsub8B(vecD dst, vecD src1, vecD src2)
15840 %{
15841   predicate(n->as_Vector()->length() == 4 ||
15842             n->as_Vector()->length() == 8);
15843   match(Set dst (SubVB src1 src2));
15844   ins_cost(INSN_COST);
15845   format %{ "subv  $dst,$src1,$src2\t# vector (8B)" %}
15846   ins_encode %{
15847     __ subv(as_FloatRegister($dst$$reg), __ T8B,
15848             as_FloatRegister($src1$$reg),
15849             as_FloatRegister($src2$$reg));
15850   %}
15851   ins_pipe(vdop64);
15852 %}
15853 
15854 instruct vsub16B(vecX dst, vecX src1, vecX src2)
15855 %{
15856   predicate(n->as_Vector()->length() == 16);
15857   match(Set dst (SubVB src1 src2));
15858   ins_cost(INSN_COST);
15859   format %{ "subv  $dst,$src1,$src2\t# vector (16B)" %}
15860   ins_encode %{
15861     __ subv(as_FloatRegister($dst$$reg), __ T16B,
15862             as_FloatRegister($src1$$reg),
15863             as_FloatRegister($src2$$reg));
15864   %}
15865   ins_pipe(vdop128);
15866 %}
15867 
15868 instruct vsub4S(vecD dst, vecD src1, vecD src2)
15869 %{
15870   predicate(n->as_Vector()->length() == 2 ||
15871             n->as_Vector()->length() == 4);
15872   match(Set dst (SubVS src1 src2));
15873   ins_cost(INSN_COST);
15874   format %{ "subv  $dst,$src1,$src2\t# vector (4H)" %}
15875   ins_encode %{
15876     __ subv(as_FloatRegister($dst$$reg), __ T4H,
15877             as_FloatRegister($src1$$reg),
15878             as_FloatRegister($src2$$reg));
15879   %}
15880   ins_pipe(vdop64);
15881 %}
15882 
15883 instruct vsub8S(vecX dst, vecX src1, vecX src2)
15884 %{
15885   predicate(n->as_Vector()->length() == 8);
15886   match(Set dst (SubVS src1 src2));
15887   ins_cost(INSN_COST);
15888   format %{ "subv  $dst,$src1,$src2\t# vector (8H)" %}
15889   ins_encode %{
15890     __ subv(as_FloatRegister($dst$$reg), __ T8H,
15891             as_FloatRegister($src1$$reg),
15892             as_FloatRegister($src2$$reg));
15893   %}
15894   ins_pipe(vdop128);
15895 %}
15896 
15897 instruct vsub2I(vecD dst, vecD src1, vecD src2)
15898 %{
15899   predicate(n->as_Vector()->length() == 2);
15900   match(Set dst (SubVI src1 src2));
15901   ins_cost(INSN_COST);
15902   format %{ "subv  $dst,$src1,$src2\t# vector (2S)" %}
15903   ins_encode %{
15904     __ subv(as_FloatRegister($dst$$reg), __ T2S,
15905             as_FloatRegister($src1$$reg),
15906             as_FloatRegister($src2$$reg));
15907   %}
15908   ins_pipe(vdop64);
15909 %}
15910 
15911 instruct vsub4I(vecX dst, vecX src1, vecX src2)
15912 %{
15913   predicate(n->as_Vector()->length() == 4);
15914   match(Set dst (SubVI src1 src2));
15915   ins_cost(INSN_COST);
15916   format %{ "subv  $dst,$src1,$src2\t# vector (4S)" %}
15917   ins_encode %{
15918     __ subv(as_FloatRegister($dst$$reg), __ T4S,
15919             as_FloatRegister($src1$$reg),
15920             as_FloatRegister($src2$$reg));
15921   %}
15922   ins_pipe(vdop128);
15923 %}
15924 
15925 instruct vsub2L(vecX dst, vecX src1, vecX src2)
15926 %{
15927   predicate(n->as_Vector()->length() == 2);
15928   match(Set dst (SubVL src1 src2));
15929   ins_cost(INSN_COST);
15930   format %{ "subv  $dst,$src1,$src2\t# vector (2L)" %}
15931   ins_encode %{
15932     __ subv(as_FloatRegister($dst$$reg), __ T2D,
15933             as_FloatRegister($src1$$reg),
15934             as_FloatRegister($src2$$reg));
15935   %}
15936   ins_pipe(vdop128);
15937 %}
15938 
15939 instruct vsub2F(vecD dst, vecD src1, vecD src2)
15940 %{
15941   predicate(n->as_Vector()->length() == 2);
15942   match(Set dst (SubVF src1 src2));
15943   ins_cost(INSN_COST);
15944   format %{ "fsub  $dst,$src1,$src2\t# vector (2S)" %}
15945   ins_encode %{
15946     __ fsub(as_FloatRegister($dst$$reg), __ T2S,
15947             as_FloatRegister($src1$$reg),
15948             as_FloatRegister($src2$$reg));
15949   %}
15950   ins_pipe(vdop_fp64);
15951 %}
15952 
15953 instruct vsub4F(vecX dst, vecX src1, vecX src2)
15954 %{
15955   predicate(n->as_Vector()->length() == 4);
15956   match(Set dst (SubVF src1 src2));
15957   ins_cost(INSN_COST);
15958   format %{ "fsub  $dst,$src1,$src2\t# vector (4S)" %}
15959   ins_encode %{
15960     __ fsub(as_FloatRegister($dst$$reg), __ T4S,
15961             as_FloatRegister($src1$$reg),
15962             as_FloatRegister($src2$$reg));
15963   %}
15964   ins_pipe(vdop_fp128);
15965 %}
15966 
15967 instruct vsub2D(vecX dst, vecX src1, vecX src2)
15968 %{
15969   predicate(n->as_Vector()->length() == 2);
15970   match(Set dst (SubVD src1 src2));
15971   ins_cost(INSN_COST);
15972   format %{ "fsub  $dst,$src1,$src2\t# vector (2D)" %}
15973   ins_encode %{
15974     __ fsub(as_FloatRegister($dst$$reg), __ T2D,
15975             as_FloatRegister($src1$$reg),
15976             as_FloatRegister($src2$$reg));
15977   %}
15978   ins_pipe(vdop_fp128);
15979 %}
15980 
15981 // --------------------------------- MUL --------------------------------------
15982 
15983 instruct vmul4S(vecD dst, vecD src1, vecD src2)
15984 %{
15985   predicate(n->as_Vector()->length() == 2 ||
15986             n->as_Vector()->length() == 4);
15987   match(Set dst (MulVS src1 src2));
15988   ins_cost(INSN_COST);
15989   format %{ "mulv  $dst,$src1,$src2\t# vector (4H)" %}
15990   ins_encode %{
15991     __ mulv(as_FloatRegister($dst$$reg), __ T4H,
15992             as_FloatRegister($src1$$reg),
15993             as_FloatRegister($src2$$reg));
15994   %}
15995   ins_pipe(vmul64);
15996 %}
15997 
15998 instruct vmul8S(vecX dst, vecX src1, vecX src2)
15999 %{
16000   predicate(n->as_Vector()->length() == 8);
16001   match(Set dst (MulVS src1 src2));
16002   ins_cost(INSN_COST);
16003   format %{ "mulv  $dst,$src1,$src2\t# vector (8H)" %}
16004   ins_encode %{
16005     __ mulv(as_FloatRegister($dst$$reg), __ T8H,
16006             as_FloatRegister($src1$$reg),
16007             as_FloatRegister($src2$$reg));
16008   %}
16009   ins_pipe(vmul128);
16010 %}
16011 
16012 instruct vmul2I(vecD dst, vecD src1, vecD src2)
16013 %{
16014   predicate(n->as_Vector()->length() == 2);
16015   match(Set dst (MulVI src1 src2));
16016   ins_cost(INSN_COST);
16017   format %{ "mulv  $dst,$src1,$src2\t# vector (2S)" %}
16018   ins_encode %{
16019     __ mulv(as_FloatRegister($dst$$reg), __ T2S,
16020             as_FloatRegister($src1$$reg),
16021             as_FloatRegister($src2$$reg));
16022   %}
16023   ins_pipe(vmul64);
16024 %}
16025 
16026 instruct vmul4I(vecX dst, vecX src1, vecX src2)
16027 %{
16028   predicate(n->as_Vector()->length() == 4);
16029   match(Set dst (MulVI src1 src2));
16030   ins_cost(INSN_COST);
16031   format %{ "mulv  $dst,$src1,$src2\t# vector (4S)" %}
16032   ins_encode %{
16033     __ mulv(as_FloatRegister($dst$$reg), __ T4S,
16034             as_FloatRegister($src1$$reg),
16035             as_FloatRegister($src2$$reg));
16036   %}
16037   ins_pipe(vmul128);
16038 %}
16039 
16040 instruct vmul2F(vecD dst, vecD src1, vecD src2)
16041 %{
16042   predicate(n->as_Vector()->length() == 2);
16043   match(Set dst (MulVF src1 src2));
16044   ins_cost(INSN_COST);
16045   format %{ "fmul  $dst,$src1,$src2\t# vector (2S)" %}
16046   ins_encode %{
16047     __ fmul(as_FloatRegister($dst$$reg), __ T2S,
16048             as_FloatRegister($src1$$reg),
16049             as_FloatRegister($src2$$reg));
16050   %}
16051   ins_pipe(vmuldiv_fp64);
16052 %}
16053 
16054 instruct vmul4F(vecX dst, vecX src1, vecX src2)
16055 %{
16056   predicate(n->as_Vector()->length() == 4);
16057   match(Set dst (MulVF src1 src2));
16058   ins_cost(INSN_COST);
16059   format %{ "fmul  $dst,$src1,$src2\t# vector (4S)" %}
16060   ins_encode %{
16061     __ fmul(as_FloatRegister($dst$$reg), __ T4S,
16062             as_FloatRegister($src1$$reg),
16063             as_FloatRegister($src2$$reg));
16064   %}
16065   ins_pipe(vmuldiv_fp128);
16066 %}
16067 
16068 instruct vmul2D(vecX dst, vecX src1, vecX src2)
16069 %{
16070   predicate(n->as_Vector()->length() == 2);
16071   match(Set dst (MulVD src1 src2));
16072   ins_cost(INSN_COST);
16073   format %{ "fmul  $dst,$src1,$src2\t# vector (2D)" %}
16074   ins_encode %{
16075     __ fmul(as_FloatRegister($dst$$reg), __ T2D,
16076             as_FloatRegister($src1$$reg),
16077             as_FloatRegister($src2$$reg));
16078   %}
16079   ins_pipe(vmuldiv_fp128);
16080 %}
16081 
16082 // --------------------------------- MLA --------------------------------------
16083 
16084 instruct vmla4S(vecD dst, vecD src1, vecD src2)
16085 %{
16086   predicate(n->as_Vector()->length() == 2 ||
16087             n->as_Vector()->length() == 4);
16088   match(Set dst (AddVS dst (MulVS src1 src2)));
16089   ins_cost(INSN_COST);
16090   format %{ "mlav  $dst,$src1,$src2\t# vector (4H)" %}
16091   ins_encode %{
16092     __ mlav(as_FloatRegister($dst$$reg), __ T4H,
16093             as_FloatRegister($src1$$reg),
16094             as_FloatRegister($src2$$reg));
16095   %}
16096   ins_pipe(vmla64);
16097 %}
16098 
16099 instruct vmla8S(vecX dst, vecX src1, vecX src2)
16100 %{
16101   predicate(n->as_Vector()->length() == 8);
16102   match(Set dst (AddVS dst (MulVS src1 src2)));
16103   ins_cost(INSN_COST);
16104   format %{ "mlav  $dst,$src1,$src2\t# vector (8H)" %}
16105   ins_encode %{
16106     __ mlav(as_FloatRegister($dst$$reg), __ T8H,
16107             as_FloatRegister($src1$$reg),
16108             as_FloatRegister($src2$$reg));
16109   %}
16110   ins_pipe(vmla128);
16111 %}
16112 
16113 instruct vmla2I(vecD dst, vecD src1, vecD src2)
16114 %{
16115   predicate(n->as_Vector()->length() == 2);
16116   match(Set dst (AddVI dst (MulVI src1 src2)));
16117   ins_cost(INSN_COST);
16118   format %{ "mlav  $dst,$src1,$src2\t# vector (2S)" %}
16119   ins_encode %{
16120     __ mlav(as_FloatRegister($dst$$reg), __ T2S,
16121             as_FloatRegister($src1$$reg),
16122             as_FloatRegister($src2$$reg));
16123   %}
16124   ins_pipe(vmla64);
16125 %}
16126 
16127 instruct vmla4I(vecX dst, vecX src1, vecX src2)
16128 %{
16129   predicate(n->as_Vector()->length() == 4);
16130   match(Set dst (AddVI dst (MulVI src1 src2)));
16131   ins_cost(INSN_COST);
16132   format %{ "mlav  $dst,$src1,$src2\t# vector (4S)" %}
16133   ins_encode %{
16134     __ mlav(as_FloatRegister($dst$$reg), __ T4S,
16135             as_FloatRegister($src1$$reg),
16136             as_FloatRegister($src2$$reg));
16137   %}
16138   ins_pipe(vmla128);
16139 %}
16140 
16141 // dst + src1 * src2
16142 instruct vmla2F(vecD dst, vecD src1, vecD src2) %{
16143   predicate(UseFMA && n->as_Vector()->length() == 2);
16144   match(Set dst (FmaVF  dst (Binary src1 src2)));
16145   format %{ "fmla  $dst,$src1,$src2\t# vector (2S)" %}
16146   ins_cost(INSN_COST);
16147   ins_encode %{
16148     __ fmla(as_FloatRegister($dst$$reg), __ T2S,
16149             as_FloatRegister($src1$$reg),
16150             as_FloatRegister($src2$$reg));
16151   %}
16152   ins_pipe(vmuldiv_fp64);
16153 %}
16154 
16155 // dst + src1 * src2
16156 instruct vmla4F(vecX dst, vecX src1, vecX src2) %{
16157   predicate(UseFMA && n->as_Vector()->length() == 4);
16158   match(Set dst (FmaVF  dst (Binary src1 src2)));
16159   format %{ "fmla  $dst,$src1,$src2\t# vector (4S)" %}
16160   ins_cost(INSN_COST);
16161   ins_encode %{
16162     __ fmla(as_FloatRegister($dst$$reg), __ T4S,
16163             as_FloatRegister($src1$$reg),
16164             as_FloatRegister($src2$$reg));
16165   %}
16166   ins_pipe(vmuldiv_fp128);
16167 %}
16168 
16169 // dst + src1 * src2
16170 instruct vmla2D(vecX dst, vecX src1, vecX src2) %{
16171   predicate(UseFMA && n->as_Vector()->length() == 2);
16172   match(Set dst (FmaVD  dst (Binary src1 src2)));
16173   format %{ "fmla  $dst,$src1,$src2\t# vector (2D)" %}
16174   ins_cost(INSN_COST);
16175   ins_encode %{
16176     __ fmla(as_FloatRegister($dst$$reg), __ T2D,
16177             as_FloatRegister($src1$$reg),
16178             as_FloatRegister($src2$$reg));
16179   %}
16180   ins_pipe(vmuldiv_fp128);
16181 %}
16182 
16183 // --------------------------------- MLS --------------------------------------
16184 
16185 instruct vmls4S(vecD dst, vecD src1, vecD src2)
16186 %{
16187   predicate(n->as_Vector()->length() == 2 ||
16188             n->as_Vector()->length() == 4);
16189   match(Set dst (SubVS dst (MulVS src1 src2)));
16190   ins_cost(INSN_COST);
16191   format %{ "mlsv  $dst,$src1,$src2\t# vector (4H)" %}
16192   ins_encode %{
16193     __ mlsv(as_FloatRegister($dst$$reg), __ T4H,
16194             as_FloatRegister($src1$$reg),
16195             as_FloatRegister($src2$$reg));
16196   %}
16197   ins_pipe(vmla64);
16198 %}
16199 
16200 instruct vmls8S(vecX dst, vecX src1, vecX src2)
16201 %{
16202   predicate(n->as_Vector()->length() == 8);
16203   match(Set dst (SubVS dst (MulVS src1 src2)));
16204   ins_cost(INSN_COST);
16205   format %{ "mlsv  $dst,$src1,$src2\t# vector (8H)" %}
16206   ins_encode %{
16207     __ mlsv(as_FloatRegister($dst$$reg), __ T8H,
16208             as_FloatRegister($src1$$reg),
16209             as_FloatRegister($src2$$reg));
16210   %}
16211   ins_pipe(vmla128);
16212 %}
16213 
16214 instruct vmls2I(vecD dst, vecD src1, vecD src2)
16215 %{
16216   predicate(n->as_Vector()->length() == 2);
16217   match(Set dst (SubVI dst (MulVI src1 src2)));
16218   ins_cost(INSN_COST);
16219   format %{ "mlsv  $dst,$src1,$src2\t# vector (2S)" %}
16220   ins_encode %{
16221     __ mlsv(as_FloatRegister($dst$$reg), __ T2S,
16222             as_FloatRegister($src1$$reg),
16223             as_FloatRegister($src2$$reg));
16224   %}
16225   ins_pipe(vmla64);
16226 %}
16227 
16228 instruct vmls4I(vecX dst, vecX src1, vecX src2)
16229 %{
16230   predicate(n->as_Vector()->length() == 4);
16231   match(Set dst (SubVI dst (MulVI src1 src2)));
16232   ins_cost(INSN_COST);
16233   format %{ "mlsv  $dst,$src1,$src2\t# vector (4S)" %}
16234   ins_encode %{
16235     __ mlsv(as_FloatRegister($dst$$reg), __ T4S,
16236             as_FloatRegister($src1$$reg),
16237             as_FloatRegister($src2$$reg));
16238   %}
16239   ins_pipe(vmla128);
16240 %}
16241 
16242 // dst - src1 * src2
16243 instruct vmls2F(vecD dst, vecD src1, vecD src2) %{
16244   predicate(UseFMA && n->as_Vector()->length() == 2);
16245   match(Set dst (FmaVF  dst (Binary (NegVF src1) src2)));
16246   match(Set dst (FmaVF  dst (Binary src1 (NegVF src2))));
16247   format %{ "fmls  $dst,$src1,$src2\t# vector (2S)" %}
16248   ins_cost(INSN_COST);
16249   ins_encode %{
16250     __ fmls(as_FloatRegister($dst$$reg), __ T2S,
16251             as_FloatRegister($src1$$reg),
16252             as_FloatRegister($src2$$reg));
16253   %}
16254   ins_pipe(vmuldiv_fp64);
16255 %}
16256 
16257 // dst - src1 * src2
16258 instruct vmls4F(vecX dst, vecX src1, vecX src2) %{
16259   predicate(UseFMA && n->as_Vector()->length() == 4);
16260   match(Set dst (FmaVF  dst (Binary (NegVF src1) src2)));
16261   match(Set dst (FmaVF  dst (Binary src1 (NegVF src2))));
16262   format %{ "fmls  $dst,$src1,$src2\t# vector (4S)" %}
16263   ins_cost(INSN_COST);
16264   ins_encode %{
16265     __ fmls(as_FloatRegister($dst$$reg), __ T4S,
16266             as_FloatRegister($src1$$reg),
16267             as_FloatRegister($src2$$reg));
16268   %}
16269   ins_pipe(vmuldiv_fp128);
16270 %}
16271 
16272 // dst - src1 * src2
16273 instruct vmls2D(vecX dst, vecX src1, vecX src2) %{
16274   predicate(UseFMA && n->as_Vector()->length() == 2);
16275   match(Set dst (FmaVD  dst (Binary (NegVD src1) src2)));
16276   match(Set dst (FmaVD  dst (Binary src1 (NegVD src2))));
16277   format %{ "fmls  $dst,$src1,$src2\t# vector (2D)" %}
16278   ins_cost(INSN_COST);
16279   ins_encode %{
16280     __ fmls(as_FloatRegister($dst$$reg), __ T2D,
16281             as_FloatRegister($src1$$reg),
16282             as_FloatRegister($src2$$reg));
16283   %}
16284   ins_pipe(vmuldiv_fp128);
16285 %}
16286 
16287 // --------------------------------- DIV --------------------------------------
16288 
16289 instruct vdiv2F(vecD dst, vecD src1, vecD src2)
16290 %{
16291   predicate(n->as_Vector()->length() == 2);
16292   match(Set dst (DivVF src1 src2));
16293   ins_cost(INSN_COST);
16294   format %{ "fdiv  $dst,$src1,$src2\t# vector (2S)" %}
16295   ins_encode %{
16296     __ fdiv(as_FloatRegister($dst$$reg), __ T2S,
16297             as_FloatRegister($src1$$reg),
16298             as_FloatRegister($src2$$reg));
16299   %}
16300   ins_pipe(vmuldiv_fp64);
16301 %}
16302 
16303 instruct vdiv4F(vecX dst, vecX src1, vecX src2)
16304 %{
16305   predicate(n->as_Vector()->length() == 4);
16306   match(Set dst (DivVF src1 src2));
16307   ins_cost(INSN_COST);
16308   format %{ "fdiv  $dst,$src1,$src2\t# vector (4S)" %}
16309   ins_encode %{
16310     __ fdiv(as_FloatRegister($dst$$reg), __ T4S,
16311             as_FloatRegister($src1$$reg),
16312             as_FloatRegister($src2$$reg));
16313   %}
16314   ins_pipe(vmuldiv_fp128);
16315 %}
16316 
16317 instruct vdiv2D(vecX dst, vecX src1, vecX src2)
16318 %{
16319   predicate(n->as_Vector()->length() == 2);
16320   match(Set dst (DivVD src1 src2));
16321   ins_cost(INSN_COST);
16322   format %{ "fdiv  $dst,$src1,$src2\t# vector (2D)" %}
16323   ins_encode %{
16324     __ fdiv(as_FloatRegister($dst$$reg), __ T2D,
16325             as_FloatRegister($src1$$reg),
16326             as_FloatRegister($src2$$reg));
16327   %}
16328   ins_pipe(vmuldiv_fp128);
16329 %}
16330 
16331 // --------------------------------- SQRT -------------------------------------
16332 
16333 instruct vsqrt2D(vecX dst, vecX src)
16334 %{
16335   predicate(n->as_Vector()->length() == 2);
16336   match(Set dst (SqrtVD src));
16337   format %{ "fsqrt  $dst, $src\t# vector (2D)" %}
16338   ins_encode %{
16339     __ fsqrt(as_FloatRegister($dst$$reg), __ T2D,
16340              as_FloatRegister($src$$reg));
16341   %}
16342   ins_pipe(vsqrt_fp128);
16343 %}
16344 
16345 // --------------------------------- ABS --------------------------------------
16346 
16347 instruct vabs2F(vecD dst, vecD src)
16348 %{
16349   predicate(n->as_Vector()->length() == 2);
16350   match(Set dst (AbsVF src));
16351   ins_cost(INSN_COST * 3);
16352   format %{ "fabs  $dst,$src\t# vector (2S)" %}
16353   ins_encode %{
16354     __ fabs(as_FloatRegister($dst$$reg), __ T2S,
16355             as_FloatRegister($src$$reg));
16356   %}
16357   ins_pipe(vunop_fp64);
16358 %}
16359 
16360 instruct vabs4F(vecX dst, vecX src)
16361 %{
16362   predicate(n->as_Vector()->length() == 4);
16363   match(Set dst (AbsVF src));
16364   ins_cost(INSN_COST * 3);
16365   format %{ "fabs  $dst,$src\t# vector (4S)" %}
16366   ins_encode %{
16367     __ fabs(as_FloatRegister($dst$$reg), __ T4S,
16368             as_FloatRegister($src$$reg));
16369   %}
16370   ins_pipe(vunop_fp128);
16371 %}
16372 
16373 instruct vabs2D(vecX dst, vecX src)
16374 %{
16375   predicate(n->as_Vector()->length() == 2);
16376   match(Set dst (AbsVD src));
16377   ins_cost(INSN_COST * 3);
16378   format %{ "fabs  $dst,$src\t# vector (2D)" %}
16379   ins_encode %{
16380     __ fabs(as_FloatRegister($dst$$reg), __ T2D,
16381             as_FloatRegister($src$$reg));
16382   %}
16383   ins_pipe(vunop_fp128);
16384 %}
16385 
16386 // --------------------------------- NEG --------------------------------------
16387 
16388 instruct vneg2F(vecD dst, vecD src)
16389 %{
16390   predicate(n->as_Vector()->length() == 2);
16391   match(Set dst (NegVF src));
16392   ins_cost(INSN_COST * 3);
16393   format %{ "fneg  $dst,$src\t# vector (2S)" %}
16394   ins_encode %{
16395     __ fneg(as_FloatRegister($dst$$reg), __ T2S,
16396             as_FloatRegister($src$$reg));
16397   %}
16398   ins_pipe(vunop_fp64);
16399 %}
16400 
16401 instruct vneg4F(vecX dst, vecX src)
16402 %{
16403   predicate(n->as_Vector()->length() == 4);
16404   match(Set dst (NegVF src));
16405   ins_cost(INSN_COST * 3);
16406   format %{ "fneg  $dst,$src\t# vector (4S)" %}
16407   ins_encode %{
16408     __ fneg(as_FloatRegister($dst$$reg), __ T4S,
16409             as_FloatRegister($src$$reg));
16410   %}
16411   ins_pipe(vunop_fp128);
16412 %}
16413 
16414 instruct vneg2D(vecX dst, vecX src)
16415 %{
16416   predicate(n->as_Vector()->length() == 2);
16417   match(Set dst (NegVD src));
16418   ins_cost(INSN_COST * 3);
16419   format %{ "fneg  $dst,$src\t# vector (2D)" %}
16420   ins_encode %{
16421     __ fneg(as_FloatRegister($dst$$reg), __ T2D,
16422             as_FloatRegister($src$$reg));
16423   %}
16424   ins_pipe(vunop_fp128);
16425 %}
16426 
16427 // --------------------------------- AND --------------------------------------
16428 
16429 instruct vand8B(vecD dst, vecD src1, vecD src2)
16430 %{
16431   predicate(n->as_Vector()->length_in_bytes() == 4 ||
16432             n->as_Vector()->length_in_bytes() == 8);
16433   match(Set dst (AndV src1 src2));
16434   ins_cost(INSN_COST);
16435   format %{ "and  $dst,$src1,$src2\t# vector (8B)" %}
16436   ins_encode %{
16437     __ andr(as_FloatRegister($dst$$reg), __ T8B,
16438             as_FloatRegister($src1$$reg),
16439             as_FloatRegister($src2$$reg));
16440   %}
16441   ins_pipe(vlogical64);
16442 %}
16443 
16444 instruct vand16B(vecX dst, vecX src1, vecX src2)
16445 %{
16446   predicate(n->as_Vector()->length_in_bytes() == 16);
16447   match(Set dst (AndV src1 src2));
16448   ins_cost(INSN_COST);
16449   format %{ "and  $dst,$src1,$src2\t# vector (16B)" %}
16450   ins_encode %{
16451     __ andr(as_FloatRegister($dst$$reg), __ T16B,
16452             as_FloatRegister($src1$$reg),
16453             as_FloatRegister($src2$$reg));
16454   %}
16455   ins_pipe(vlogical128);
16456 %}
16457 
16458 // --------------------------------- OR ---------------------------------------
16459 
16460 instruct vor8B(vecD dst, vecD src1, vecD src2)
16461 %{
16462   predicate(n->as_Vector()->length_in_bytes() == 4 ||
16463             n->as_Vector()->length_in_bytes() == 8);
16464   match(Set dst (OrV src1 src2));
16465   ins_cost(INSN_COST);
16466   format %{ "and  $dst,$src1,$src2\t# vector (8B)" %}
16467   ins_encode %{
16468     __ orr(as_FloatRegister($dst$$reg), __ T8B,
16469             as_FloatRegister($src1$$reg),
16470             as_FloatRegister($src2$$reg));
16471   %}
16472   ins_pipe(vlogical64);
16473 %}
16474 
16475 instruct vor16B(vecX dst, vecX src1, vecX src2)
16476 %{
16477   predicate(n->as_Vector()->length_in_bytes() == 16);
16478   match(Set dst (OrV src1 src2));
16479   ins_cost(INSN_COST);
16480   format %{ "orr  $dst,$src1,$src2\t# vector (16B)" %}
16481   ins_encode %{
16482     __ orr(as_FloatRegister($dst$$reg), __ T16B,
16483             as_FloatRegister($src1$$reg),
16484             as_FloatRegister($src2$$reg));
16485   %}
16486   ins_pipe(vlogical128);
16487 %}
16488 
16489 // --------------------------------- XOR --------------------------------------
16490 
16491 instruct vxor8B(vecD dst, vecD src1, vecD src2)
16492 %{
16493   predicate(n->as_Vector()->length_in_bytes() == 4 ||
16494             n->as_Vector()->length_in_bytes() == 8);
16495   match(Set dst (XorV src1 src2));
16496   ins_cost(INSN_COST);
16497   format %{ "xor  $dst,$src1,$src2\t# vector (8B)" %}
16498   ins_encode %{
16499     __ eor(as_FloatRegister($dst$$reg), __ T8B,
16500             as_FloatRegister($src1$$reg),
16501             as_FloatRegister($src2$$reg));
16502   %}
16503   ins_pipe(vlogical64);
16504 %}
16505 
16506 instruct vxor16B(vecX dst, vecX src1, vecX src2)
16507 %{
16508   predicate(n->as_Vector()->length_in_bytes() == 16);
16509   match(Set dst (XorV src1 src2));
16510   ins_cost(INSN_COST);
16511   format %{ "xor  $dst,$src1,$src2\t# vector (16B)" %}
16512   ins_encode %{
16513     __ eor(as_FloatRegister($dst$$reg), __ T16B,
16514             as_FloatRegister($src1$$reg),
16515             as_FloatRegister($src2$$reg));
16516   %}
16517   ins_pipe(vlogical128);
16518 %}
16519 
16520 // ------------------------------ Shift ---------------------------------------
16521 
16522 instruct vshiftcntL(vecX dst, iRegIorL2I cnt) %{
16523   match(Set dst (LShiftCntV cnt));
16524   format %{ "dup  $dst, $cnt\t# shift count (vecX)" %}
16525   ins_encode %{
16526     __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg));
16527   %}
16528   ins_pipe(vdup_reg_reg128);
16529 %}
16530 
16531 // Right shifts on aarch64 SIMD are implemented as left shift by -ve amount
16532 instruct vshiftcntR(vecX dst, iRegIorL2I cnt) %{
16533   match(Set dst (RShiftCntV cnt));
16534   format %{ "dup  $dst, $cnt\t# shift count (vecX)\n\tneg  $dst, $dst\t T16B" %}
16535   ins_encode %{
16536     __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg));
16537     __ negr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($dst$$reg));
16538   %}
16539   ins_pipe(vdup_reg_reg128);
16540 %}
16541 
16542 instruct vsll8B(vecD dst, vecD src, vecX shift) %{
16543   predicate(n->as_Vector()->length() == 4 ||
16544             n->as_Vector()->length() == 8);
16545   match(Set dst (LShiftVB src shift));
16546   match(Set dst (RShiftVB src shift));
16547   ins_cost(INSN_COST);
16548   format %{ "sshl  $dst,$src,$shift\t# vector (8B)" %}
16549   ins_encode %{
16550     __ sshl(as_FloatRegister($dst$$reg), __ T8B,
16551             as_FloatRegister($src$$reg),
16552             as_FloatRegister($shift$$reg));
16553   %}
16554   ins_pipe(vshift64);
16555 %}
16556 
16557 instruct vsll16B(vecX dst, vecX src, vecX shift) %{
16558   predicate(n->as_Vector()->length() == 16);
16559   match(Set dst (LShiftVB src shift));
16560   match(Set dst (RShiftVB src shift));
16561   ins_cost(INSN_COST);
16562   format %{ "sshl  $dst,$src,$shift\t# vector (16B)" %}
16563   ins_encode %{
16564     __ sshl(as_FloatRegister($dst$$reg), __ T16B,
16565             as_FloatRegister($src$$reg),
16566             as_FloatRegister($shift$$reg));
16567   %}
16568   ins_pipe(vshift128);
16569 %}
16570 
16571 instruct vsrl8B(vecD dst, vecD src, vecX shift) %{
16572   predicate(n->as_Vector()->length() == 4 ||
16573             n->as_Vector()->length() == 8);
16574   match(Set dst (URShiftVB src shift));
16575   ins_cost(INSN_COST);
16576   format %{ "ushl  $dst,$src,$shift\t# vector (8B)" %}
16577   ins_encode %{
16578     __ ushl(as_FloatRegister($dst$$reg), __ T8B,
16579             as_FloatRegister($src$$reg),
16580             as_FloatRegister($shift$$reg));
16581   %}
16582   ins_pipe(vshift64);
16583 %}
16584 
16585 instruct vsrl16B(vecX dst, vecX src, vecX shift) %{
16586   predicate(n->as_Vector()->length() == 16);
16587   match(Set dst (URShiftVB src shift));
16588   ins_cost(INSN_COST);
16589   format %{ "ushl  $dst,$src,$shift\t# vector (16B)" %}
16590   ins_encode %{
16591     __ ushl(as_FloatRegister($dst$$reg), __ T16B,
16592             as_FloatRegister($src$$reg),
16593             as_FloatRegister($shift$$reg));
16594   %}
16595   ins_pipe(vshift128);
16596 %}
16597 
16598 instruct vsll8B_imm(vecD dst, vecD src, immI shift) %{
16599   predicate(n->as_Vector()->length() == 4 ||
16600             n->as_Vector()->length() == 8);
16601   match(Set dst (LShiftVB src shift));
16602   ins_cost(INSN_COST);
16603   format %{ "shl    $dst, $src, $shift\t# vector (8B)" %}
16604   ins_encode %{
16605     int sh = (int)$shift$$constant;
16606     if (sh >= 8) {
16607       __ eor(as_FloatRegister($dst$$reg), __ T8B,
16608              as_FloatRegister($src$$reg),
16609              as_FloatRegister($src$$reg));
16610     } else {
16611       __ shl(as_FloatRegister($dst$$reg), __ T8B,
16612              as_FloatRegister($src$$reg), sh);
16613     }
16614   %}
16615   ins_pipe(vshift64_imm);
16616 %}
16617 
16618 instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{
16619   predicate(n->as_Vector()->length() == 16);
16620   match(Set dst (LShiftVB src shift));
16621   ins_cost(INSN_COST);
16622   format %{ "shl    $dst, $src, $shift\t# vector (16B)" %}
16623   ins_encode %{
16624     int sh = (int)$shift$$constant;
16625     if (sh >= 8) {
16626       __ eor(as_FloatRegister($dst$$reg), __ T16B,
16627              as_FloatRegister($src$$reg),
16628              as_FloatRegister($src$$reg));
16629     } else {
16630       __ shl(as_FloatRegister($dst$$reg), __ T16B,
16631              as_FloatRegister($src$$reg), sh);
16632     }
16633   %}
16634   ins_pipe(vshift128_imm);
16635 %}
16636 
16637 instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{
16638   predicate(n->as_Vector()->length() == 4 ||
16639             n->as_Vector()->length() == 8);
16640   match(Set dst (RShiftVB src shift));
16641   ins_cost(INSN_COST);
16642   format %{ "sshr    $dst, $src, $shift\t# vector (8B)" %}
16643   ins_encode %{
16644     int sh = (int)$shift$$constant;
16645     if (sh >= 8) sh = 7;
16646     __ sshr(as_FloatRegister($dst$$reg), __ T8B,
16647            as_FloatRegister($src$$reg), sh);
16648   %}
16649   ins_pipe(vshift64_imm);
16650 %}
16651 
16652 instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{
16653   predicate(n->as_Vector()->length() == 16);
16654   match(Set dst (RShiftVB src shift));
16655   ins_cost(INSN_COST);
16656   format %{ "sshr    $dst, $src, $shift\t# vector (16B)" %}
16657   ins_encode %{
16658     int sh = (int)$shift$$constant;
16659     if (sh >= 8) sh = 7;
16660     __ sshr(as_FloatRegister($dst$$reg), __ T16B,
16661            as_FloatRegister($src$$reg), sh);
16662   %}
16663   ins_pipe(vshift128_imm);
16664 %}
16665 
16666 instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{
16667   predicate(n->as_Vector()->length() == 4 ||
16668             n->as_Vector()->length() == 8);
16669   match(Set dst (URShiftVB src shift));
16670   ins_cost(INSN_COST);
16671   format %{ "ushr    $dst, $src, $shift\t# vector (8B)" %}
16672   ins_encode %{
16673     int sh = (int)$shift$$constant;
16674     if (sh >= 8) {
16675       __ eor(as_FloatRegister($dst$$reg), __ T8B,
16676              as_FloatRegister($src$$reg),
16677              as_FloatRegister($src$$reg));
16678     } else {
16679       __ ushr(as_FloatRegister($dst$$reg), __ T8B,
16680              as_FloatRegister($src$$reg), sh);
16681     }
16682   %}
16683   ins_pipe(vshift64_imm);
16684 %}
16685 
16686 instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{
16687   predicate(n->as_Vector()->length() == 16);
16688   match(Set dst (URShiftVB src shift));
16689   ins_cost(INSN_COST);
16690   format %{ "ushr    $dst, $src, $shift\t# vector (16B)" %}
16691   ins_encode %{
16692     int sh = (int)$shift$$constant;
16693     if (sh >= 8) {
16694       __ eor(as_FloatRegister($dst$$reg), __ T16B,
16695              as_FloatRegister($src$$reg),
16696              as_FloatRegister($src$$reg));
16697     } else {
16698       __ ushr(as_FloatRegister($dst$$reg), __ T16B,
16699              as_FloatRegister($src$$reg), sh);
16700     }
16701   %}
16702   ins_pipe(vshift128_imm);
16703 %}
16704 
16705 instruct vsll4S(vecD dst, vecD src, vecX shift) %{
16706   predicate(n->as_Vector()->length() == 2 ||
16707             n->as_Vector()->length() == 4);
16708   match(Set dst (LShiftVS src shift));
16709   match(Set dst (RShiftVS src shift));
16710   ins_cost(INSN_COST);
16711   format %{ "sshl  $dst,$src,$shift\t# vector (4H)" %}
16712   ins_encode %{
16713     __ sshl(as_FloatRegister($dst$$reg), __ T4H,
16714             as_FloatRegister($src$$reg),
16715             as_FloatRegister($shift$$reg));
16716   %}
16717   ins_pipe(vshift64);
16718 %}
16719 
16720 instruct vsll8S(vecX dst, vecX src, vecX shift) %{
16721   predicate(n->as_Vector()->length() == 8);
16722   match(Set dst (LShiftVS src shift));
16723   match(Set dst (RShiftVS src shift));
16724   ins_cost(INSN_COST);
16725   format %{ "sshl  $dst,$src,$shift\t# vector (8H)" %}
16726   ins_encode %{
16727     __ sshl(as_FloatRegister($dst$$reg), __ T8H,
16728             as_FloatRegister($src$$reg),
16729             as_FloatRegister($shift$$reg));
16730   %}
16731   ins_pipe(vshift128);
16732 %}
16733 
16734 instruct vsrl4S(vecD dst, vecD src, vecX shift) %{
16735   predicate(n->as_Vector()->length() == 2 ||
16736             n->as_Vector()->length() == 4);
16737   match(Set dst (URShiftVS src shift));
16738   ins_cost(INSN_COST);
16739   format %{ "ushl  $dst,$src,$shift\t# vector (4H)" %}
16740   ins_encode %{
16741     __ ushl(as_FloatRegister($dst$$reg), __ T4H,
16742             as_FloatRegister($src$$reg),
16743             as_FloatRegister($shift$$reg));
16744   %}
16745   ins_pipe(vshift64);
16746 %}
16747 
16748 instruct vsrl8S(vecX dst, vecX src, vecX shift) %{
16749   predicate(n->as_Vector()->length() == 8);
16750   match(Set dst (URShiftVS src shift));
16751   ins_cost(INSN_COST);
16752   format %{ "ushl  $dst,$src,$shift\t# vector (8H)" %}
16753   ins_encode %{
16754     __ ushl(as_FloatRegister($dst$$reg), __ T8H,
16755             as_FloatRegister($src$$reg),
16756             as_FloatRegister($shift$$reg));
16757   %}
16758   ins_pipe(vshift128);
16759 %}
16760 
16761 instruct vsll4S_imm(vecD dst, vecD src, immI shift) %{
16762   predicate(n->as_Vector()->length() == 2 ||
16763             n->as_Vector()->length() == 4);
16764   match(Set dst (LShiftVS src shift));
16765   ins_cost(INSN_COST);
16766   format %{ "shl    $dst, $src, $shift\t# vector (4H)" %}
16767   ins_encode %{
16768     int sh = (int)$shift$$constant;
16769     if (sh >= 16) {
16770       __ eor(as_FloatRegister($dst$$reg), __ T8B,
16771              as_FloatRegister($src$$reg),
16772              as_FloatRegister($src$$reg));
16773     } else {
16774       __ shl(as_FloatRegister($dst$$reg), __ T4H,
16775              as_FloatRegister($src$$reg), sh);
16776     }
16777   %}
16778   ins_pipe(vshift64_imm);
16779 %}
16780 
16781 instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{
16782   predicate(n->as_Vector()->length() == 8);
16783   match(Set dst (LShiftVS src shift));
16784   ins_cost(INSN_COST);
16785   format %{ "shl    $dst, $src, $shift\t# vector (8H)" %}
16786   ins_encode %{
16787     int sh = (int)$shift$$constant;
16788     if (sh >= 16) {
16789       __ eor(as_FloatRegister($dst$$reg), __ T16B,
16790              as_FloatRegister($src$$reg),
16791              as_FloatRegister($src$$reg));
16792     } else {
16793       __ shl(as_FloatRegister($dst$$reg), __ T8H,
16794              as_FloatRegister($src$$reg), sh);
16795     }
16796   %}
16797   ins_pipe(vshift128_imm);
16798 %}
16799 
16800 instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{
16801   predicate(n->as_Vector()->length() == 2 ||
16802             n->as_Vector()->length() == 4);
16803   match(Set dst (RShiftVS src shift));
16804   ins_cost(INSN_COST);
16805   format %{ "sshr    $dst, $src, $shift\t# vector (4H)" %}
16806   ins_encode %{
16807     int sh = (int)$shift$$constant;
16808     if (sh >= 16) sh = 15;
16809     __ sshr(as_FloatRegister($dst$$reg), __ T4H,
16810            as_FloatRegister($src$$reg), sh);
16811   %}
16812   ins_pipe(vshift64_imm);
16813 %}
16814 
16815 instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{
16816   predicate(n->as_Vector()->length() == 8);
16817   match(Set dst (RShiftVS src shift));
16818   ins_cost(INSN_COST);
16819   format %{ "sshr    $dst, $src, $shift\t# vector (8H)" %}
16820   ins_encode %{
16821     int sh = (int)$shift$$constant;
16822     if (sh >= 16) sh = 15;
16823     __ sshr(as_FloatRegister($dst$$reg), __ T8H,
16824            as_FloatRegister($src$$reg), sh);
16825   %}
16826   ins_pipe(vshift128_imm);
16827 %}
16828 
16829 instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{
16830   predicate(n->as_Vector()->length() == 2 ||
16831             n->as_Vector()->length() == 4);
16832   match(Set dst (URShiftVS src shift));
16833   ins_cost(INSN_COST);
16834   format %{ "ushr    $dst, $src, $shift\t# vector (4H)" %}
16835   ins_encode %{
16836     int sh = (int)$shift$$constant;
16837     if (sh >= 16) {
16838       __ eor(as_FloatRegister($dst$$reg), __ T8B,
16839              as_FloatRegister($src$$reg),
16840              as_FloatRegister($src$$reg));
16841     } else {
16842       __ ushr(as_FloatRegister($dst$$reg), __ T4H,
16843              as_FloatRegister($src$$reg), sh);
16844     }
16845   %}
16846   ins_pipe(vshift64_imm);
16847 %}
16848 
16849 instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{
16850   predicate(n->as_Vector()->length() == 8);
16851   match(Set dst (URShiftVS src shift));
16852   ins_cost(INSN_COST);
16853   format %{ "ushr    $dst, $src, $shift\t# vector (8H)" %}
16854   ins_encode %{
16855     int sh = (int)$shift$$constant;
16856     if (sh >= 16) {
16857       __ eor(as_FloatRegister($dst$$reg), __ T16B,
16858              as_FloatRegister($src$$reg),
16859              as_FloatRegister($src$$reg));
16860     } else {
16861       __ ushr(as_FloatRegister($dst$$reg), __ T8H,
16862              as_FloatRegister($src$$reg), sh);
16863     }
16864   %}
16865   ins_pipe(vshift128_imm);
16866 %}
16867 
16868 instruct vsll2I(vecD dst, vecD src, vecX shift) %{
16869   predicate(n->as_Vector()->length() == 2);
16870   match(Set dst (LShiftVI src shift));
16871   match(Set dst (RShiftVI src shift));
16872   ins_cost(INSN_COST);
16873   format %{ "sshl  $dst,$src,$shift\t# vector (2S)" %}
16874   ins_encode %{
16875     __ sshl(as_FloatRegister($dst$$reg), __ T2S,
16876             as_FloatRegister($src$$reg),
16877             as_FloatRegister($shift$$reg));
16878   %}
16879   ins_pipe(vshift64);
16880 %}
16881 
16882 instruct vsll4I(vecX dst, vecX src, vecX shift) %{
16883   predicate(n->as_Vector()->length() == 4);
16884   match(Set dst (LShiftVI src shift));
16885   match(Set dst (RShiftVI src shift));
16886   ins_cost(INSN_COST);
16887   format %{ "sshl  $dst,$src,$shift\t# vector (4S)" %}
16888   ins_encode %{
16889     __ sshl(as_FloatRegister($dst$$reg), __ T4S,
16890             as_FloatRegister($src$$reg),
16891             as_FloatRegister($shift$$reg));
16892   %}
16893   ins_pipe(vshift128);
16894 %}
16895 
16896 instruct vsrl2I(vecD dst, vecD src, vecX shift) %{
16897   predicate(n->as_Vector()->length() == 2);
16898   match(Set dst (URShiftVI src shift));
16899   ins_cost(INSN_COST);
16900   format %{ "ushl  $dst,$src,$shift\t# vector (2S)" %}
16901   ins_encode %{
16902     __ ushl(as_FloatRegister($dst$$reg), __ T2S,
16903             as_FloatRegister($src$$reg),
16904             as_FloatRegister($shift$$reg));
16905   %}
16906   ins_pipe(vshift64);
16907 %}
16908 
16909 instruct vsrl4I(vecX dst, vecX src, vecX shift) %{
16910   predicate(n->as_Vector()->length() == 4);
16911   match(Set dst (URShiftVI src shift));
16912   ins_cost(INSN_COST);
16913   format %{ "ushl  $dst,$src,$shift\t# vector (4S)" %}
16914   ins_encode %{
16915     __ ushl(as_FloatRegister($dst$$reg), __ T4S,
16916             as_FloatRegister($src$$reg),
16917             as_FloatRegister($shift$$reg));
16918   %}
16919   ins_pipe(vshift128);
16920 %}
16921 
16922 instruct vsll2I_imm(vecD dst, vecD src, immI shift) %{
16923   predicate(n->as_Vector()->length() == 2);
16924   match(Set dst (LShiftVI src shift));
16925   ins_cost(INSN_COST);
16926   format %{ "shl    $dst, $src, $shift\t# vector (2S)" %}
16927   ins_encode %{
16928     __ shl(as_FloatRegister($dst$$reg), __ T2S,
16929            as_FloatRegister($src$$reg),
16930            (int)$shift$$constant);
16931   %}
16932   ins_pipe(vshift64_imm);
16933 %}
16934 
16935 instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{
16936   predicate(n->as_Vector()->length() == 4);
16937   match(Set dst (LShiftVI src shift));
16938   ins_cost(INSN_COST);
16939   format %{ "shl    $dst, $src, $shift\t# vector (4S)" %}
16940   ins_encode %{
16941     __ shl(as_FloatRegister($dst$$reg), __ T4S,
16942            as_FloatRegister($src$$reg),
16943            (int)$shift$$constant);
16944   %}
16945   ins_pipe(vshift128_imm);
16946 %}
16947 
16948 instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{
16949   predicate(n->as_Vector()->length() == 2);
16950   match(Set dst (RShiftVI src shift));
16951   ins_cost(INSN_COST);
16952   format %{ "sshr    $dst, $src, $shift\t# vector (2S)" %}
16953   ins_encode %{
16954     __ sshr(as_FloatRegister($dst$$reg), __ T2S,
16955             as_FloatRegister($src$$reg),
16956             (int)$shift$$constant);
16957   %}
16958   ins_pipe(vshift64_imm);
16959 %}
16960 
16961 instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{
16962   predicate(n->as_Vector()->length() == 4);
16963   match(Set dst (RShiftVI src shift));
16964   ins_cost(INSN_COST);
16965   format %{ "sshr    $dst, $src, $shift\t# vector (4S)" %}
16966   ins_encode %{
16967     __ sshr(as_FloatRegister($dst$$reg), __ T4S,
16968             as_FloatRegister($src$$reg),
16969             (int)$shift$$constant);
16970   %}
16971   ins_pipe(vshift128_imm);
16972 %}
16973 
16974 instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{
16975   predicate(n->as_Vector()->length() == 2);
16976   match(Set dst (URShiftVI src shift));
16977   ins_cost(INSN_COST);
16978   format %{ "ushr    $dst, $src, $shift\t# vector (2S)" %}
16979   ins_encode %{
16980     __ ushr(as_FloatRegister($dst$$reg), __ T2S,
16981             as_FloatRegister($src$$reg),
16982             (int)$shift$$constant);
16983   %}
16984   ins_pipe(vshift64_imm);
16985 %}
16986 
16987 instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{
16988   predicate(n->as_Vector()->length() == 4);
16989   match(Set dst (URShiftVI src shift));
16990   ins_cost(INSN_COST);
16991   format %{ "ushr    $dst, $src, $shift\t# vector (4S)" %}
16992   ins_encode %{
16993     __ ushr(as_FloatRegister($dst$$reg), __ T4S,
16994             as_FloatRegister($src$$reg),
16995             (int)$shift$$constant);
16996   %}
16997   ins_pipe(vshift128_imm);
16998 %}
16999 
17000 instruct vsll2L(vecX dst, vecX src, vecX shift) %{
17001   predicate(n->as_Vector()->length() == 2);
17002   match(Set dst (LShiftVL src shift));
17003   match(Set dst (RShiftVL src shift));
17004   ins_cost(INSN_COST);
17005   format %{ "sshl  $dst,$src,$shift\t# vector (2D)" %}
17006   ins_encode %{
17007     __ sshl(as_FloatRegister($dst$$reg), __ T2D,
17008             as_FloatRegister($src$$reg),
17009             as_FloatRegister($shift$$reg));
17010   %}
17011   ins_pipe(vshift128);
17012 %}
17013 
17014 instruct vsrl2L(vecX dst, vecX src, vecX shift) %{
17015   predicate(n->as_Vector()->length() == 2);
17016   match(Set dst (URShiftVL src shift));
17017   ins_cost(INSN_COST);
17018   format %{ "ushl  $dst,$src,$shift\t# vector (2D)" %}
17019   ins_encode %{
17020     __ ushl(as_FloatRegister($dst$$reg), __ T2D,
17021             as_FloatRegister($src$$reg),
17022             as_FloatRegister($shift$$reg));
17023   %}
17024   ins_pipe(vshift128);
17025 %}
17026 
17027 instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{
17028   predicate(n->as_Vector()->length() == 2);
17029   match(Set dst (LShiftVL src shift));
17030   ins_cost(INSN_COST);
17031   format %{ "shl    $dst, $src, $shift\t# vector (2D)" %}
17032   ins_encode %{
17033     __ shl(as_FloatRegister($dst$$reg), __ T2D,
17034            as_FloatRegister($src$$reg),
17035            (int)$shift$$constant);
17036   %}
17037   ins_pipe(vshift128_imm);
17038 %}
17039 
17040 instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{
17041   predicate(n->as_Vector()->length() == 2);
17042   match(Set dst (RShiftVL src shift));
17043   ins_cost(INSN_COST);
17044   format %{ "sshr    $dst, $src, $shift\t# vector (2D)" %}
17045   ins_encode %{
17046     __ sshr(as_FloatRegister($dst$$reg), __ T2D,
17047             as_FloatRegister($src$$reg),
17048             (int)$shift$$constant);
17049   %}
17050   ins_pipe(vshift128_imm);
17051 %}
17052 
17053 instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{
17054   predicate(n->as_Vector()->length() == 2);
17055   match(Set dst (URShiftVL src shift));
17056   ins_cost(INSN_COST);
17057   format %{ "ushr    $dst, $src, $shift\t# vector (2D)" %}
17058   ins_encode %{
17059     __ ushr(as_FloatRegister($dst$$reg), __ T2D,
17060             as_FloatRegister($src$$reg),
17061             (int)$shift$$constant);
17062   %}
17063   ins_pipe(vshift128_imm);
17064 %}
17065 
17066 //----------PEEPHOLE RULES-----------------------------------------------------
17067 // These must follow all instruction definitions as they use the names
17068 // defined in the instructions definitions.
17069 //
17070 // peepmatch ( root_instr_name [preceding_instruction]* );
17071 //
17072 // peepconstraint %{
17073 // (instruction_number.operand_name relational_op instruction_number.operand_name
17074 //  [, ...] );
17075 // // instruction numbers are zero-based using left to right order in peepmatch
17076 //
17077 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
17078 // // provide an instruction_number.operand_name for each operand that appears
17079 // // in the replacement instruction's match rule
17080 //
17081 // ---------VM FLAGS---------------------------------------------------------
17082 //
17083 // All peephole optimizations can be turned off using -XX:-OptoPeephole
17084 //
17085 // Each peephole rule is given an identifying number starting with zero and
17086 // increasing by one in the order seen by the parser.  An individual peephole
17087 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
17088 // on the command-line.
17089 //
17090 // ---------CURRENT LIMITATIONS----------------------------------------------
17091 //
17092 // Only match adjacent instructions in same basic block
17093 // Only equality constraints
17094 // Only constraints between operands, not (0.dest_reg == RAX_enc)
17095 // Only one replacement instruction
17096 //
17097 // ---------EXAMPLE----------------------------------------------------------
17098 //
17099 // // pertinent parts of existing instructions in architecture description
17100 // instruct movI(iRegINoSp dst, iRegI src)
17101 // %{
17102 //   match(Set dst (CopyI src));
17103 // %}
17104 //
17105 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr)
17106 // %{
17107 //   match(Set dst (AddI dst src));
17108 //   effect(KILL cr);
17109 // %}
17110 //
17111 // // Change (inc mov) to lea
17112 // peephole %{
17113 //   // increment preceeded by register-register move
17114 //   peepmatch ( incI_iReg movI );
17115 //   // require that the destination register of the increment
17116 //   // match the destination register of the move
17117 //   peepconstraint ( 0.dst == 1.dst );
17118 //   // construct a replacement instruction that sets
17119 //   // the destination to ( move's source register + one )
17120 //   peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) );
17121 // %}
17122 //
17123 
17124 // Implementation no longer uses movX instructions since
17125 // machine-independent system no longer uses CopyX nodes.
17126 //
17127 // peephole
17128 // %{
17129 //   peepmatch (incI_iReg movI);
17130 //   peepconstraint (0.dst == 1.dst);
17131 //   peepreplace (leaI_iReg_immI(0.dst 1.src 0.src));
17132 // %}
17133 
17134 // peephole
17135 // %{
17136 //   peepmatch (decI_iReg movI);
17137 //   peepconstraint (0.dst == 1.dst);
17138 //   peepreplace (leaI_iReg_immI(0.dst 1.src 0.src));
17139 // %}
17140 
17141 // peephole
17142 // %{
17143 //   peepmatch (addI_iReg_imm movI);
17144 //   peepconstraint (0.dst == 1.dst);
17145 //   peepreplace (leaI_iReg_immI(0.dst 1.src 0.src));
17146 // %}
17147 
17148 // peephole
17149 // %{
17150 //   peepmatch (incL_iReg movL);
17151 //   peepconstraint (0.dst == 1.dst);
17152 //   peepreplace (leaL_iReg_immL(0.dst 1.src 0.src));
17153 // %}
17154 
17155 // peephole
17156 // %{
17157 //   peepmatch (decL_iReg movL);
17158 //   peepconstraint (0.dst == 1.dst);
17159 //   peepreplace (leaL_iReg_immL(0.dst 1.src 0.src));
17160 // %}
17161 
17162 // peephole
17163 // %{
17164 //   peepmatch (addL_iReg_imm movL);
17165 //   peepconstraint (0.dst == 1.dst);
17166 //   peepreplace (leaL_iReg_immL(0.dst 1.src 0.src));
17167 // %}
17168 
17169 // peephole
17170 // %{
17171 //   peepmatch (addP_iReg_imm movP);
17172 //   peepconstraint (0.dst == 1.dst);
17173 //   peepreplace (leaP_iReg_imm(0.dst 1.src 0.src));
17174 // %}
17175 
17176 // // Change load of spilled value to only a spill
17177 // instruct storeI(memory mem, iRegI src)
17178 // %{
17179 //   match(Set mem (StoreI mem src));
17180 // %}
17181 //
17182 // instruct loadI(iRegINoSp dst, memory mem)
17183 // %{
17184 //   match(Set dst (LoadI mem));
17185 // %}
17186 //
17187 
17188 //----------SMARTSPILL RULES---------------------------------------------------
17189 // These must follow all instruction definitions as they use the names
17190 // defined in the instructions definitions.
17191 
17192 // Local Variables:
17193 // mode: c++
17194 // End: