1 //
   2 // Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
   3 // Copyright (c) 2015-2018, Azul Systems, 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 // AARCH32 Architecture Description File
  26 
  27 //----------REGISTER DEFINITION BLOCK------------------------------------------
  28 // This information is used by the matcher and the register allocator to
  29 // describe individual registers and classes of registers within the target
  30 // archtecture.
  31 register %{
  32 //----------Architecture Description Register Definitions----------------------
  33 // General Registers
  34 // "reg_def"  name ( register save type, C convention save type,
  35 //                   ideal register type, encoding, vm name );
  36 // Register Save Types:
  37 //
  38 // NS  = No-Save:       The register allocator assumes that these registers
  39 //                      can be used without saving upon entry to the method, &
  40 //                      that they do not need to be saved at call sites.
  41 //
  42 // SOC = Save-On-Call:  The register allocator assumes that these registers
  43 //                      can be used without saving upon entry to the method,
  44 //                      but that they must be saved at call sites.
  45 //
  46 // SOE = Save-On-Entry: The register allocator assumes that these registers
  47 //                      must be saved before using them upon entry to the
  48 //                      method, but they do not need to be saved at call
  49 //                      sites.
  50 //
  51 // AS  = Always-Save:   The register allocator assumes that these registers
  52 //                      must be saved before using them upon entry to the
  53 //                      method, & that they must be saved at call sites.
  54 //
  55 // Ideal Register Type is used to determine how to save & restore a
  56 // register.  Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
  57 // spilled with LoadP/StoreP.  If the register supports both, use Op_RegI.
  58 //
  59 // The encoding number is the actual bit-pattern placed into the opcodes.
  60 
  61 
  62 // ----------------------------
  63 // Integer/Long Registers
  64 // ----------------------------
  65 
  66 reg_def R_R0 (SOC, SOC, Op_RegI,  0,  R(0)->as_VMReg());
  67 reg_def R_R1 (SOC, SOC, Op_RegI,  1,  R(1)->as_VMReg());
  68 reg_def R_R2 (SOC, SOC, Op_RegI,  2,  R(2)->as_VMReg());
  69 reg_def R_R3 (SOC, SOC, Op_RegI,  3,  R(3)->as_VMReg());
  70 reg_def R_R4 (SOC, SOE, Op_RegI,  4,  R(4)->as_VMReg());
  71 reg_def R_R5 (SOC, SOE, Op_RegI,  5,  R(5)->as_VMReg());
  72 reg_def R_R6 (SOC, SOE, Op_RegI,  6,  R(6)->as_VMReg());
  73 reg_def R_R7 (SOC, SOE, Op_RegI,  7,  R(7)->as_VMReg());
  74 reg_def R_R8 (SOC, SOE, Op_RegI,  8,  R(8)->as_VMReg());
  75 reg_def R_R9 (SOC, SOE, Op_RegI,  9,  R(9)->as_VMReg());
  76 reg_def R_R10(NS,  SOE, Op_RegI, 10, R(10)->as_VMReg());
  77 reg_def R_R11(NS,  SOE, Op_RegI, 11, R(11)->as_VMReg());
  78 reg_def R_R12(SOC, SOC, Op_RegI, 12, R(12)->as_VMReg());
  79 reg_def R_R13(NS,  NS,  Op_RegI, 13, R(13)->as_VMReg());
  80 reg_def R_R14(SOC, SOC, Op_RegI, 14, R(14)->as_VMReg());
  81 reg_def R_R15(NS,  NS,  Op_RegI, 15, R(15)->as_VMReg());
  82 
  83 // ----------------------------
  84 // Float/Double Registers
  85 // ----------------------------
  86 
  87 // Float Registers
  88 
  89 reg_def R_S0 ( SOC, SOC, Op_RegF,  0, f0->as_VMReg());
  90 reg_def R_S1 ( SOC, SOC, Op_RegF,  1, f1->as_VMReg());
  91 reg_def R_S2 ( SOC, SOC, Op_RegF,  2, f2->as_VMReg());
  92 reg_def R_S3 ( SOC, SOC, Op_RegF,  3, f3->as_VMReg());
  93 reg_def R_S4 ( SOC, SOC, Op_RegF,  4, f4->as_VMReg());
  94 reg_def R_S5 ( SOC, SOC, Op_RegF,  5, f5->as_VMReg());
  95 reg_def R_S6 ( SOC, SOC, Op_RegF,  6, f6->as_VMReg());
  96 reg_def R_S7 ( SOC, SOC, Op_RegF,  7, f7->as_VMReg());
  97 reg_def R_S8 ( SOC, SOC, Op_RegF,  8, f8->as_VMReg());
  98 reg_def R_S9 ( SOC, SOC, Op_RegF,  9, f9->as_VMReg());
  99 reg_def R_S10( SOC, SOC, Op_RegF, 10,f10->as_VMReg());
 100 reg_def R_S11( SOC, SOC, Op_RegF, 11,f11->as_VMReg());
 101 reg_def R_S12( SOC, SOC, Op_RegF, 12,f12->as_VMReg());
 102 reg_def R_S13( SOC, SOC, Op_RegF, 13,f13->as_VMReg());
 103 reg_def R_S14( SOC, SOC, Op_RegF, 14,f14->as_VMReg());
 104 reg_def R_S15( SOC, SOC, Op_RegF, 15,f15->as_VMReg());
 105 reg_def R_S16( SOC, SOE, Op_RegF, 16,f16->as_VMReg());
 106 reg_def R_S17( SOC, SOE, Op_RegF, 17,f17->as_VMReg());
 107 reg_def R_S18( SOC, SOE, Op_RegF, 18,f18->as_VMReg());
 108 reg_def R_S19( SOC, SOE, Op_RegF, 19,f19->as_VMReg());
 109 reg_def R_S20( SOC, SOE, Op_RegF, 20,f20->as_VMReg());
 110 reg_def R_S21( SOC, SOE, Op_RegF, 21,f21->as_VMReg());
 111 reg_def R_S22( SOC, SOE, Op_RegF, 22,f22->as_VMReg());
 112 reg_def R_S23( SOC, SOE, Op_RegF, 23,f23->as_VMReg());
 113 reg_def R_S24( SOC, SOE, Op_RegF, 24,f24->as_VMReg());
 114 reg_def R_S25( SOC, SOE, Op_RegF, 25,f25->as_VMReg());
 115 reg_def R_S26( SOC, SOE, Op_RegF, 26,f26->as_VMReg());
 116 reg_def R_S27( SOC, SOE, Op_RegF, 27,f27->as_VMReg());
 117 reg_def R_S28( SOC, SOE, Op_RegF, 28,f28->as_VMReg());
 118 reg_def R_S29( SOC, SOE, Op_RegF, 29,f29->as_VMReg());
 119 reg_def R_S30( SOC, SOE, Op_RegF, 30,f30->as_VMReg());
 120 reg_def R_S31( SOC, SOE, Op_RegF, 31,f31->as_VMReg());
 121 
 122 // Double Registers
 123 // The rules of ADL require that double registers be defined in pairs.
 124 // Each pair must be two 32-bit values, but not necessarily a pair of
 125 // single float registers.  In each pair, ADLC-assigned register numbers
 126 // must be adjacent, with the lower number even.  Finally, when the
 127 // CPU stores such a register pair to memory, the word associated with
 128 // the lower ADLC-assigned number must be stored to the lower address.
 129 
 130 // TODO, the problem is that AArch32 port has same same numeric value for
 131 // d16->as_VMReg and f1->as_VMReg which breaks reverse mapping from
 132 // VMReg to OptoReg
 133 // reg_def R_D16 (SOC, SOC, Op_RegD, 32, d16->as_VMReg());
 134 // reg_def R_D16x(SOC, SOC, Op_RegD,255, d16->as_VMReg()->next());
 135 // reg_def R_D17 (SOC, SOC, Op_RegD, 34, d17->as_VMReg());
 136 // reg_def R_D17x(SOC, SOC, Op_RegD,255, d17->as_VMReg()->next());
 137 // reg_def R_D18 (SOC, SOC, Op_RegD, 36, d18->as_VMReg());
 138 // reg_def R_D18x(SOC, SOC, Op_RegD,255, d18->as_VMReg()->next());
 139 // reg_def R_D19 (SOC, SOC, Op_RegD, 38, d19->as_VMReg());
 140 // reg_def R_D19x(SOC, SOC, Op_RegD,255, d19->as_VMReg()->next());
 141 // reg_def R_D20 (SOC, SOC, Op_RegD, 40, d20->as_VMReg());
 142 // reg_def R_D20x(SOC, SOC, Op_RegD,255, d20->as_VMReg()->next());
 143 // reg_def R_D21 (SOC, SOC, Op_RegD, 42, d21->as_VMReg());
 144 // reg_def R_D21x(SOC, SOC, Op_RegD,255, d21->as_VMReg()->next());
 145 // reg_def R_D22 (SOC, SOC, Op_RegD, 44, d22->as_VMReg());
 146 // reg_def R_D22x(SOC, SOC, Op_RegD,255, d22->as_VMReg()->next());
 147 // reg_def R_D23 (SOC, SOC, Op_RegD, 46, d23->as_VMReg());
 148 // reg_def R_D23x(SOC, SOC, Op_RegD,255, d23->as_VMReg()->next());
 149 // reg_def R_D24 (SOC, SOC, Op_RegD, 48, d24->as_VMReg());
 150 // reg_def R_D24x(SOC, SOC, Op_RegD,255, d24->as_VMReg()->next());
 151 // reg_def R_D25 (SOC, SOC, Op_RegD, 50, d25->as_VMReg());
 152 // reg_def R_D25x(SOC, SOC, Op_RegD,255, d25->as_VMReg()->next());
 153 // reg_def R_D26 (SOC, SOC, Op_RegD, 52, d26->as_VMReg());
 154 // reg_def R_D26x(SOC, SOC, Op_RegD,255, d26->as_VMReg()->next());
 155 // reg_def R_D27 (SOC, SOC, Op_RegD, 54, d27->as_VMReg());
 156 // reg_def R_D27x(SOC, SOC, Op_RegD,255, d27->as_VMReg()->next());
 157 // reg_def R_D28 (SOC, SOC, Op_RegD, 56, d28->as_VMReg());
 158 // reg_def R_D28x(SOC, SOC, Op_RegD,255, d28->as_VMReg()->next());
 159 // reg_def R_D29 (SOC, SOC, Op_RegD, 58, d29->as_VMReg());
 160 // reg_def R_D29x(SOC, SOC, Op_RegD,255, d29->as_VMReg()->next());
 161 // reg_def R_D30 (SOC, SOC, Op_RegD, 60, d30->as_VMReg());
 162 // reg_def R_D30x(SOC, SOC, Op_RegD,255, d30->as_VMReg()->next());
 163 // reg_def R_D31 (SOC, SOC, Op_RegD, 62, d31->as_VMReg());
 164 // reg_def R_D31x(SOC, SOC, Op_RegD,255, d31->as_VMReg()->next());
 165 
 166 // ----------------------------
 167 // Special Registers
 168 // Condition Codes Flag Registers
 169 reg_def APSR (SOC, SOC,  Op_RegFlags, 0, VMRegImpl::Bad());
 170 reg_def FPSCR(SOC, SOC,  Op_RegFlags, 0, VMRegImpl::Bad());
 171 
 172 // ----------------------------
 173 // Specify the enum values for the registers.  These enums are only used by the
 174 // OptoReg "class". We can convert these enum values at will to VMReg when needed
 175 // for visibility to the rest of the vm. The order of this enum influences the
 176 // register allocator so having the freedom to set this order and not be stuck
 177 // with the order that is natural for the rest of the vm is worth it.
 178 
 179 // registers in that order so that R11/R12 is an aligned pair that can be used for longs
 180 alloc_class chunk0(
 181                    R_R4, R_R5, R_R6, R_R7, R_R8, R_R9, R_R11, R_R12, R_R10, R_R13, R_R14, R_R15, R_R0, R_R1, R_R2, R_R3);
 182 
 183 // Note that a register is not allocatable unless it is also mentioned
 184 // in a widely-used reg_class below.
 185 
 186 alloc_class chunk1(
 187                    R_S16, R_S17, R_S18, R_S19, R_S20, R_S21, R_S22, R_S23,
 188                    R_S24, R_S25, R_S26, R_S27, R_S28, R_S29, R_S30, R_S31,
 189                    R_S0,  R_S1,  R_S2,  R_S3,  R_S4,  R_S5,  R_S6,  R_S7,
 190                    R_S8,  R_S9,  R_S10, R_S11, R_S12, R_S13, R_S14, R_S15
 191                    // ,
 192                    // R_D16, R_D16x,R_D17, R_D17x,R_D18, R_D18x,R_D19, R_D19x,
 193                    // R_D20, R_D20x,R_D21, R_D21x,R_D22, R_D22x,R_D23, R_D23x,
 194                    // R_D24, R_D24x,R_D25, R_D25x,R_D26, R_D26x,R_D27, R_D27x,
 195                    // R_D28, R_D28x,R_D29, R_D29x,R_D30, R_D30x,R_D31, R_D31x
 196 );
 197 
 198 alloc_class chunk2(APSR, FPSCR);
 199 
 200 //----------Architecture Description Register Classes--------------------------
 201 // Several register classes are automatically defined based upon information in
 202 // this architecture description.
 203 // 1) reg_class inline_cache_reg           ( as defined in frame section )
 204 // 2) reg_class interpreter_method_oop_reg ( as defined in frame section )
 205 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
 206 //
 207 
 208 // ----------------------------
 209 // Integer Register Classes
 210 // ----------------------------
 211 // Exclusions from i_reg:
 212 // sp (R13), PC (R15)
 213 // R10: reserved by HotSpot to the TLS register (invariant within Java)
 214 reg_class int_reg(R_R0, R_R1, R_R2, R_R3, R_R4, R_R5, R_R6, R_R7, R_R8, R_R9, R_R11, R_R12, R_R14);
 215 
 216 reg_class R0_regI(R_R0);
 217 reg_class R1_regI(R_R1);
 218 reg_class R2_regI(R_R2);
 219 reg_class R3_regI(R_R3);
 220 reg_class R9_regI(R_R9);
 221 reg_class R12_regI(R_R12);
 222 
 223 // ----------------------------
 224 // Pointer Register Classes
 225 // ----------------------------
 226 reg_class ptr_reg(R_R0, R_R1, R_R2, R_R3, R_R4, R_R5, R_R6, R_R7, R_R8, R_R9, R_R11, R_R12, R_R14);
 227 // Special class for storeP instructions, which can store SP or RPC to TLS.
 228 // It is also used for memory addressing, allowing direct TLS addressing.
 229 reg_class sp_ptr_reg(R_R0, R_R1, R_R2, R_R3, R_R4, R_R5, R_R6, R_R7, R_R9, R_R11, R_R12, R_R14, R_R8, R_R10 /* TLS*/, R_R13 /* SP*/);
 230 
 231 #define R_Ricklass R_R12
 232 #define R_Rmethod  R_R8
 233 #define R_Rthread  R_R10
 234 #define R_Rexception_obj R_R0
 235 
 236 // Other special pointer regs
 237 reg_class R0_regP(R_R0);
 238 reg_class R1_regP(R_R1);
 239 reg_class R2_regP(R_R2);
 240 reg_class R4_regP(R_R4);
 241 reg_class Rexception_regP(R_Rexception_obj);
 242 reg_class Ricklass_regP(R_Ricklass);
 243 reg_class Rmethod_regP(R_Rmethod);
 244 reg_class Rthread_regP(R_Rthread);
 245 reg_class IP_regP(R_R12);
 246 reg_class LR_regP(R_R14);
 247 
 248 reg_class FP_regP(R_R11);
 249 
 250 // ----------------------------
 251 // Long Register Classes
 252 // ----------------------------
 253 reg_class long_reg (             R_R0,R_R1, R_R2,R_R3, R_R4,R_R5, R_R6,R_R7, R_R8,R_R9, R_R11,R_R12);
 254 // for ldrexd, strexd: first reg of pair must be even
 255 reg_class long_reg_align (       R_R0,R_R1, R_R2,R_R3, R_R4,R_R5, R_R6,R_R7, R_R8,R_R9);
 256 
 257 reg_class R0R1_regL(R_R0,R_R1);
 258 reg_class R2R3_regL(R_R2,R_R3);
 259 
 260 // ----------------------------
 261 // Special Class for Condition Code Flags Register
 262 reg_class int_flags(APSR);
 263 reg_class float_flags(FPSCR);
 264 
 265 
 266 // ----------------------------
 267 // Float Point Register Classes
 268 // ----------------------------
 269 // Skip f14/f15, they are reserved for mem-mem copies
 270 reg_class sflt_reg(R_S0, R_S1, R_S2, R_S3, R_S4, R_S5, R_S6, R_S7, R_S8, R_S9, R_S10, R_S11, R_S12, R_S13,
 271                    R_S16, R_S17, R_S18, R_S19, R_S20, R_S21, R_S22, R_S23, R_S24, R_S25, R_S26, R_S27, R_S28, R_S29, R_S30, R_S31);
 272 
 273 // Paired floating point registers--they show up in the same order as the floats,
 274 // but they are used with the "Op_RegD" type, and always occur in even/odd pairs.
 275 reg_class dflt_reg(R_S0,R_S1, R_S2,R_S3, R_S4,R_S5, R_S6,R_S7, R_S8,R_S9, R_S10,R_S11, R_S12,R_S13,
 276                    R_S16,R_S17, R_S18,R_S19, R_S20,R_S21, R_S22,R_S23, R_S24,R_S25, R_S26,R_S27, R_S28,R_S29, R_S30,R_S31
 277                    // ,
 278                    // R_D16,R_D16x, R_D17,R_D17x, R_D18,R_D18x, R_D19,R_D19x, R_D20,R_D20x, R_D21,R_D21x, R_D22,R_D22x,
 279                    // R_D23,R_D23x, R_D24,R_D24x, R_D25,R_D25x, R_D26,R_D26x, R_D27,R_D27x, R_D28,R_D28x, R_D29,R_D29x,
 280                    // R_D30,R_D30x, R_D31,R_D31x
 281   );
 282 
 283 reg_class dflt_low_reg(R_S0,R_S1, R_S2,R_S3, R_S4,R_S5, R_S6,R_S7, R_S8,R_S9, R_S10,R_S11, R_S12,R_S13,
 284                        R_S16,R_S17, R_S18,R_S19, R_S20,R_S21, R_S22,R_S23, R_S24,R_S25, R_S26,R_S27, R_S28,R_S29, R_S30,R_S31);
 285 
 286 
 287 reg_class actual_dflt_reg %{
 288   if (/*VM_Version::features() & FT_VFPV3D32*/0) { // TODO verify and enable
 289     return DFLT_REG_mask();
 290   } else {
 291     return DFLT_LOW_REG_mask();
 292   }
 293 %}
 294 
 295 reg_class f0_regF(R_S0);
 296 reg_class D0_regD(R_S0,R_S1);
 297 reg_class D1_regD(R_S2,R_S3);
 298 reg_class D2_regD(R_S4,R_S5);
 299 reg_class D3_regD(R_S6,R_S7);
 300 reg_class D4_regD(R_S8,R_S9);
 301 reg_class D5_regD(R_S10,R_S11);
 302 reg_class D6_regD(R_S12,R_S13);
 303 reg_class D7_regD(R_S14,R_S15);
 304 reg_class D0D1_regD(R_S0,R_S1,R_S2,R_S3);
 305 reg_class D2D3_regD(R_S4,R_S5,R_S6,R_S7);
 306 
 307 // reg_class D16_regD(R_D16,R_D16x);
 308 // reg_class D17_regD(R_D17,R_D17x);
 309 // reg_class D18_regD(R_D18,R_D18x);
 310 // reg_class D19_regD(R_D19,R_D19x);
 311 // reg_class D20_regD(R_D20,R_D20x);
 312 // reg_class D21_regD(R_D21,R_D21x);
 313 // reg_class D22_regD(R_D22,R_D22x);
 314 // reg_class D23_regD(R_D23,R_D23x);
 315 // reg_class D24_regD(R_D24,R_D24x);
 316 // reg_class D25_regD(R_D25,R_D25x);
 317 // reg_class D26_regD(R_D26,R_D26x);
 318 // reg_class D27_regD(R_D27,R_D27x);
 319 // reg_class D28_regD(R_D28,R_D28x);
 320 // reg_class D29_regD(R_D29,R_D29x);
 321 // reg_class D30_regD(R_D30,R_D30x);
 322 // reg_class D31_regD(R_D31,R_D31x);
 323 
 324 reg_class vectorx_reg(R_S0,R_S1,R_S2,R_S3, R_S4,R_S5,R_S6,R_S7,
 325                       R_S8,R_S9,R_S10,R_S11, /* skip f14/f15 */
 326                       R_S16,R_S17,R_S18,R_S19, R_S20,R_S21,R_S22,R_S23,
 327                       R_S24,R_S25,R_S26,R_S27, R_S28,R_S29,R_S30,R_S31
 328                       // ,
 329                       // R_D16,R_D16x,R_D17,R_D17x, R_D18,R_D18x,R_D19,R_D19x,
 330                       // R_D20,R_D20x,R_D21,R_D21x, R_D22,R_D22x,R_D23,R_D23x,
 331                       // R_D24,R_D24x,R_D25,R_D25x, R_D26,R_D26x,R_D27,R_D27x,
 332                       // R_D28,R_D28x,R_D29,R_D29x, R_D30,R_D30x,R_D31,R_D31x
 333   );
 334 
 335 %}
 336 
 337 source_hpp %{
 338 // FIXME
 339 const MachRegisterNumbers R_mem_copy_lo_num = R_S14_num;
 340 const MachRegisterNumbers R_mem_copy_hi_num = R_S15_num;
 341 const FloatRegister Rmemcopy = f14;
 342 const MachRegisterNumbers R_hf_ret_lo_num = R_S0_num;
 343 const MachRegisterNumbers R_hf_ret_hi_num = R_S1_num;
 344 
 345 const MachRegisterNumbers R_Ricklass_num = R_R12_num;
 346 const MachRegisterNumbers R_Rmethod_num  = R_R8_num;
 347 
 348 #define LDR_DOUBLE "FLDD"
 349 #define LDR_FLOAT  "FLDS"
 350 #define STR_DOUBLE "FSTD"
 351 #define STR_FLOAT  "FSTS"
 352 #define LDR_64     "LDRD"
 353 #define STR_64     "STRD"
 354 #define LDR_32     "LDR"
 355 #define STR_32     "STR"
 356 #define MOV_DOUBLE "FCPYD"
 357 #define MOV_FLOAT  "FCPYS"
 358 #define FMSR       "FMSR"
 359 #define FMRS       "FMRS"
 360 #define LDREX      "ldrex "
 361 #define STREX      "strex "
 362 
 363 static inline bool is_memoryD(int offset) {
 364   return offset < 1024 && offset > -1024;
 365 }
 366 
 367 static inline bool is_memoryfp(int offset) {
 368   return offset < 1024 && offset > -1024;
 369 }
 370 
 371 static inline bool is_memoryI(int offset) {
 372   return offset < 4096 && offset > -4096;
 373 }
 374 
 375 static inline bool is_memoryP(int offset) {
 376   return offset < 4096 && offset > -4096;
 377 }
 378 
 379 static inline bool is_memoryHD(int offset) {
 380   return offset < 256 && offset > -256;
 381 }
 382 
 383 static inline bool is_aimm(int imm) {
 384   return Assembler::is_valid_for_imm12(imm);
 385 }
 386 
 387 static inline bool is_limmI(jint imm) {
 388   return Assembler::is_valid_for_imm12(imm);
 389 }
 390 
 391 static inline bool is_limmI_low(jint imm, int n) {
 392   int imml = imm & right_n_bits(n);
 393   return is_limmI(imml) || is_limmI(imm);
 394 }
 395 
 396 static inline int limmI_low(jint imm, int n) {
 397   int imml = imm & right_n_bits(n);
 398   return is_limmI(imml) ? imml : imm;
 399 }
 400 
 401 %}
 402 
 403 source %{
 404 
 405 // Given a register encoding, produce a Integer Register object
 406 static Register reg_to_register_object(int register_encoding) {
 407   assert(r0->encoding() == R_R0_enc && r15->encoding() == R_R15_enc, "right coding");
 408   return as_Register(register_encoding);
 409 }
 410 
 411 // Given a register encoding, produce a Float Register object
 412 static FloatRegister reg_to_FloatRegister_object(int register_encoding) {
 413   assert(f0->encoding() == R_S0_enc && f31->encoding() == R_S31_enc, "right coding");
 414   // [d16,d31] share FloatRegister encoding with [f1,f31] since it numericall equals to ARM insn parameter encoding
 415   // in contrary OptoReg encoding for d16+ is different
 416   return as_FloatRegister((register_encoding&0x1f)|(register_encoding>>5));
 417 }
 418 
 419 void Compile::pd_compiler2_init() {
 420   // Umimplemented
 421 }
 422 
 423 OptoRegPair c2::return_value(int ideal_reg) {
 424   assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
 425   static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, R_R0_num,     R_R0_num,     R_hf_ret_lo_num,  R_hf_ret_lo_num, R_R0_num };
 426   static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad,     R_hf_ret_hi_num, R_R1_num };
 427 #ifndef HARD_FLOAT_CC
 428   assert(hasFPU(), "non-VFP java ABI is not supported");
 429 #endif
 430   return OptoRegPair( hi[ideal_reg], lo[ideal_reg]);
 431 }
 432 
 433 #ifndef HARD_FLOAT_CC
 434 OptoRegPair c2::c_return_value(int ideal_reg) {
 435   assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
 436   static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, R_R0_num,     R_R0_num,     R_R0_num,     R_R0_num, R_R0_num };
 437   static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_R1_num, R_R1_num };
 438   return OptoRegPair( hi[ideal_reg], lo[ideal_reg]);
 439 }
 440 #endif
 441 
 442 // !!!!! Special hack to get all type of calls to specify the byte offset
 443 //       from the start of the call to the point where the return address
 444 //       will point.
 445 
 446 static uint call_static_enc_size(const MachCallNode *n, ciMethod *_method, bool _method_handle_invoke) {
 447   int call_sz = (_method == NULL) ?
 448     (maybe_far_call(n) ? 3 : 1) :
 449     (far_branches() ? NativeCall::instruction_size / NativeInstruction::arm_insn_sz : 1);
 450   return (call_sz + (_method_handle_invoke ? 2 : 0)) *
 451     NativeInstruction::arm_insn_sz;
 452 }
 453 
 454 static uint call_dynamic_enc_size() {
 455   return 2 * NativeInstruction::arm_insn_sz +
 456     (far_branches() ? NativeCall::instruction_size : NativeInstruction::arm_insn_sz);
 457 }
 458 
 459 static uint call_runtime_enc_size(const MachCallNode *n) {
 460   // bl or movw; movt; blx
 461   bool far = maybe_far_call(n);
 462   return (far ? 3 : 1) * NativeInstruction::arm_insn_sz;
 463 }
 464 
 465 int MachCallStaticJavaNode::ret_addr_offset() {
 466   return call_static_enc_size(this, _method, _method_handle_invoke) -
 467     (_method_handle_invoke ? 1 : 0) * NativeInstruction::arm_insn_sz;
 468 }
 469 
 470 int MachCallDynamicJavaNode::ret_addr_offset() {
 471   return call_dynamic_enc_size();
 472 }
 473 
 474 int MachCallRuntimeNode::ret_addr_offset() {
 475   return call_runtime_enc_size(this);
 476 }
 477 %}
 478 
 479 // The intptr_t operand types, defined by textual substitution.
 480 // (Cf. opto/type.hpp.  This lets us avoid many, many other ifdefs.)
 481 #define immX      immI
 482 #define immXRot   immIRot
 483 #define iRegX     iRegI
 484 #define aimmX     aimmI
 485 #define limmX     limmI
 486 #define immX10x2  immI10x2
 487 #define LShiftX   LShiftI
 488 #define shimmX    immU5
 489 
 490 // Compatibility interface
 491 #define aimmP     immPRot
 492 #define immIMov   immIRot
 493 
 494 #define store_RegL     iRegL
 495 #define store_RegLd    iRegLd
 496 #define store_RegI     iRegI
 497 #define store_ptr_RegP iRegP
 498 
 499 //----------ATTRIBUTES---------------------------------------------------------
 500 //----------Operand Attributes-------------------------------------------------
 501 op_attrib op_cost(1);          // Required cost attribute
 502 
 503 //----------OPERANDS-----------------------------------------------------------
 504 // Operand definitions must precede instruction definitions for correct parsing
 505 // in the ADLC because operands constitute user defined types which are used in
 506 // instruction definitions.
 507 
 508 //----------Simple Operands----------------------------------------------------
 509 // Immediate Operands
 510 
 511 operand immIRot() %{
 512   predicate(Assembler::is_valid_for_imm12(n->get_int()));
 513   match(ConI);
 514 
 515   op_cost(0);
 516   // formats are generated automatically for constants and base registers
 517   format %{ %}
 518   interface(CONST_INTER);
 519 %}
 520 
 521 operand immIRotn() %{
 522   predicate(n->get_int() != 0 && Assembler::is_valid_for_imm12(~n->get_int()));
 523   match(ConI);
 524 
 525   op_cost(0);
 526   // formats are generated automatically for constants and base registers
 527   format %{ %}
 528   interface(CONST_INTER);
 529 %}
 530 
 531 operand immIRotneg() %{
 532   // if Assembler::is_valid_for_imm12() is true for this constant, it is
 533   // a immIRot and an optimal instruction combination exists to handle the
 534   // constant as an immIRot
 535   predicate(!Assembler::is_valid_for_imm12(n->get_int()) && Assembler::is_valid_for_imm12(-n->get_int()));
 536   match(ConI);
 537 
 538   op_cost(0);
 539   // formats are generated automatically for constants and base registers
 540   format %{ %}
 541   interface(CONST_INTER);
 542 %}
 543 
 544 // Non-negative integer immediate that is encodable using the rotation scheme,
 545 // and that when expanded fits in 31 bits.
 546 operand immU31Rot() %{
 547   predicate((0 <= n->get_int()) && Assembler::is_valid_for_imm12(n->get_int()));
 548   match(ConI);
 549 
 550   op_cost(0);
 551   // formats are generated automatically for constants and base registers
 552   format %{ %}
 553   interface(CONST_INTER);
 554 %}
 555 
 556 operand immPRot() %{
 557   predicate(n->get_ptr() == 0 || (Assembler::is_valid_for_imm12(n->get_ptr()) && ((ConPNode*)n)->type()->reloc() == relocInfo::none));
 558 
 559   match(ConP);
 560 
 561   op_cost(0);
 562   // formats are generated automatically for constants and base registers
 563   format %{ %}
 564   interface(CONST_INTER);
 565 %}
 566 
 567 operand immLlowRot() %{
 568   predicate(n->get_long() >> 32 == 0 && Assembler::is_valid_for_imm12((int)n->get_long()));
 569   match(ConL);
 570   op_cost(0);
 571 
 572   format %{ %}
 573   interface(CONST_INTER);
 574 %}
 575 
 576 operand immLRot2() %{
 577   predicate(Assembler::is_valid_for_imm12((int)(n->get_long() >> 32)) &&
 578             Assembler::is_valid_for_imm12((int)(n->get_long())));
 579   match(ConL);
 580   op_cost(0);
 581 
 582   format %{ %}
 583   interface(CONST_INTER);
 584 %}
 585 
 586 // Integer Immediate: 12-bit - for addressing mode
 587 operand immI12() %{
 588   predicate((-4096 < n->get_int()) && (n->get_int() < 4096));
 589   match(ConI);
 590   op_cost(0);
 591 
 592   format %{ %}
 593   interface(CONST_INTER);
 594 %}
 595 
 596 // Integer Immediate: 10-bit disp and disp+4 - for addressing float pair
 597 operand immI10x2() %{
 598   predicate((-1024 < n->get_int()) && (n->get_int() < 1024 - 4));
 599   match(ConI);
 600   op_cost(0);
 601 
 602   format %{ %}
 603   interface(CONST_INTER);
 604 %}
 605 
 606 // Integer Immediate: 12-bit disp and disp+4 - for addressing word pair
 607 operand immI12x2() %{
 608   predicate((-4096 < n->get_int()) && (n->get_int() < 4096 - 4));
 609   match(ConI);
 610   op_cost(0);
 611 
 612   format %{ %}
 613   interface(CONST_INTER);
 614 %}
 615 
 616 //----------DEFINITION BLOCK---------------------------------------------------
 617 // Define name --> value mappings to inform the ADLC of an integer valued name
 618 // Current support includes integer values in the range [0, 0x7FFFFFFF]
 619 // Format:
 620 //        int_def  <name>         ( <int_value>, <expression>);
 621 // Generated Code in ad_<arch>.hpp
 622 //        #define  <name>   (<expression>)
 623 //        // value == <int_value>
 624 // Generated code in ad_<arch>.cpp adlc_verification()
 625 //        assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
 626 //
 627 definitions %{
 628 // The default cost (of an ALU instruction).
 629   int_def DEFAULT_COST      (    100,     100);
 630   int_def HUGE_COST         (1000000, 1000000);
 631 
 632 // Memory refs are twice as expensive as run-of-the-mill.
 633   int_def MEMORY_REF_COST   (    200, DEFAULT_COST * 2);
 634 
 635 // Branches are even more expensive.
 636   int_def BRANCH_COST       (    300, DEFAULT_COST * 3);
 637   int_def CALL_COST         (    300, DEFAULT_COST * 3);
 638 %}
 639 
 640 
 641 //----------SOURCE BLOCK-------------------------------------------------------
 642 // This is a block of C++ code which provides values, functions, and
 643 // definitions necessary in the rest of the architecture description
 644 source_hpp %{
 645 // Header information of the source block.
 646 // Method declarations/definitions which are used outside
 647 // the ad-scope can conveniently be defined here.
 648 //
 649 // To keep related declarations/definitions/uses close together,
 650 // we switch between source %{ }% and source_hpp %{ }% freely as needed.
 651 
 652 #ifdef PRODUCT
 653 #define BLOCK_COMMENT(str) /* nothing */
 654 #define STOP(error) __ stop(error)
 655 #else
 656 #define BLOCK_COMMENT(str) __ block_comment(str)
 657 #define STOP(error) __ block_comment(error); stop(error)
 658 #endif
 659 
 660 #define BIND(label) __ bind(label); BLOCK_COMMENT(#label ":")
 661 
 662 // Does destination need to be loaded in a register then passed to a
 663 // branch instruction?
 664 extern bool maybe_far_call(const CallNode *n);
 665 extern bool maybe_far_call(const MachCallNode *n);
 666 static inline bool cache_reachable() {
 667   return MacroAssembler::_cache_fully_reachable();
 668 }
 669 static inline bool far_branches() {
 670   return MacroAssembler::far_branches();
 671 }
 672 
 673 extern bool PrintOptoAssembly;
 674 
 675 class c2 {
 676 public:
 677   static OptoRegPair return_value(int ideal_reg);
 678 #ifndef HARD_FLOAT_CC
 679   static OptoRegPair c_return_value(int ideal_reg);
 680 #endif
 681 };
 682 
 683 class CallStubImpl {
 684 
 685   //--------------------------------------------------------------
 686   //---<  Used for optimization in Compile::Shorten_branches  >---
 687   //--------------------------------------------------------------
 688 
 689  public:
 690   // Size of call trampoline stub.
 691   static uint size_call_trampoline() {
 692     return 0; // no call trampolines on this platform
 693   }
 694 
 695   // number of relocations needed by a call trampoline stub
 696   static uint reloc_call_trampoline() {
 697     return 0; // no call trampolines on this platform
 698   }
 699 };
 700 
 701 class HandlerImpl {
 702 
 703  public:
 704 
 705   static int emit_exception_handler(CodeBuffer &cbuf);
 706   static int emit_deopt_handler(CodeBuffer& cbuf);
 707 
 708   static uint size_exception_handler() {
 709     return ( 3 * 4 );
 710   }
 711 
 712 
 713   static uint size_deopt_handler() {
 714     return ( 9 * 4 );
 715   }
 716 
 717 };
 718 
 719 %}
 720 
 721 source %{
 722 #define __ _masm.
 723 
 724 static FloatRegister reg_to_FloatRegister_object(int register_encoding);
 725 static Register reg_to_register_object(int register_encoding);
 726 
 727 
 728 // ****************************************************************************
 729 
 730 // REQUIRED FUNCTIONALITY
 731 
 732 // Indicate if the safepoint node needs the polling page as an input.
 733 // Since ARM does not have absolute addressing, it does.
 734 bool SafePointNode::needs_polling_address_input() {
 735   return true;
 736 }
 737 
 738 // emit an interrupt that is caught by the debugger (for debugging compiler)
 739 void emit_break(CodeBuffer &cbuf) {
 740   MacroAssembler _masm(&cbuf);
 741   __ bkpt(0);
 742 }
 743 
 744 #ifndef PRODUCT
 745 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream *st ) const {
 746   st->print("TA");
 747 }
 748 #endif
 749 
 750 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 751   emit_break(cbuf);
 752 }
 753 
 754 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
 755   return MachNode::size(ra_);
 756 }
 757 
 758 
 759 void emit_nop(CodeBuffer &cbuf) {
 760   MacroAssembler _masm(&cbuf);
 761   __ nop();
 762 }
 763 
 764 
 765 void emit_call_reloc(CodeBuffer &cbuf, const MachCallNode *n, MachOper *m, RelocationHolder const& rspec) {
 766   int ret_addr_offset0 = n->as_MachCall()->ret_addr_offset();
 767   int call_site_offset = cbuf.insts()->mark_off();
 768   MacroAssembler _masm(&cbuf);
 769   __ set_inst_mark(); // needed in emit_to_interp_stub() to locate the call
 770   address target = (address)m->method();
 771   assert(n->as_MachCall()->entry_point() == target, "sanity");
 772   assert(maybe_far_call(n) == !__ reachable_from_cache(target), "sanity");
 773   assert(cache_reachable() == __ cache_fully_reachable(), "sanity");
 774 
 775   assert(target != NULL, "need real address");
 776 
 777   if (rspec.type() == relocInfo::runtime_call_type ||
 778     rspec.type() == relocInfo::none) {
 779     __ call(target, rspec);
 780   } else {
 781     __ trampoline_call(Address(target, rspec), NULL);
 782   }
 783   int ret_addr_offset = __ offset();
 784   assert(ret_addr_offset - call_site_offset == ret_addr_offset0, "fix ret_addr_offset()");
 785 }
 786 
 787 //=============================================================================
 788 // REQUIRED FUNCTIONALITY for encoding
 789 void emit_lo(CodeBuffer &cbuf, int val) {  }
 790 void emit_hi(CodeBuffer &cbuf, int val) {  }
 791 
 792 
 793 //=============================================================================
 794 const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask();
 795 
 796 int Compile::ConstantTable::calculate_table_base_offset() const {
 797   int offset = -(size() / 2);
 798   // vldr_f32, vldr_f64: 8-bit  offset multiplied by 4: +/- 1024
 799   // ldr, ldrb : 12-bit offset:                 +/- 4096
 800   if (!Assembler::is_simm10(offset)) {
 801     offset = Assembler::min_simm10();
 802   }
 803   return offset;
 804 }
 805 
 806 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
 807 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
 808   ShouldNotReachHere();
 809 }
 810 
 811 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
 812   Compile* C = ra_->C;
 813   Compile::ConstantTable& constant_table = C->constant_table();
 814   MacroAssembler _masm(&cbuf);
 815 
 816   Register r = as_Register(ra_->get_encode(this));
 817   CodeSection* consts_section = __ code()->consts();
 818   int consts_size = consts_section->align_at_start(consts_section->size());
 819   assert(constant_table.size() == consts_size, "must be: %d == %d", constant_table.size(), consts_size);
 820 
 821   // Materialize the constant table base.
 822   address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
 823   RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
 824   __ mov_address(r, baseaddr, rspec);
 825 }
 826 
 827 uint MachConstantBaseNode::size(PhaseRegAlloc*) const {
 828   return 8;
 829 }
 830 
 831 #ifndef PRODUCT
 832 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
 833   char reg[128];
 834   ra_->dump_register(this, reg);
 835   st->print("MOV_SLOW    &constanttable,%s\t! constant table base", reg);
 836 }
 837 #endif
 838 
 839 #ifndef PRODUCT
 840 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
 841   Compile* C = ra_->C;
 842 
 843   for (int i = 0; i < OptoPrologueNops; i++) {
 844     st->print_cr("NOP"); st->print("\t");
 845   }
 846 
 847   size_t framesize = C->frame_size_in_bytes();
 848   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
 849   int bangsize = C->bang_size_in_bytes();
 850   // Remove two words for return addr and rbp,
 851   framesize -= 2*wordSize;
 852   bangsize -= 2*wordSize;
 853 
 854   // Calls to C2R adapters often do not accept exceptional returns.
 855   // We require that their callers must bang for them.  But be careful, because
 856   // some VM calls (such as call site linkage) can use several kilobytes of
 857   // stack.  But the stack safety zone should account for that.
 858   // See bugs 4446381, 4468289, 4497237.
 859   if (C->need_stack_bang(bangsize)) {
 860     st->print_cr("! stack bang (%d bytes)", bangsize); st->print("\t");
 861   }
 862   st->print_cr("PUSH   R_FP|R_LR_LR"); st->print("\t");
 863   if (framesize != 0) {
 864     st->print   ("SUB    R_SP, R_SP, " SIZE_FORMAT,framesize);
 865   }
 866 }
 867 #endif
 868 
 869 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 870   Compile* C = ra_->C;
 871   MacroAssembler _masm(&cbuf);
 872 
 873   // insert a nop at the start of the prolog so we can patch in a
 874   // branch if we need to invalidate the method later
 875   __ nop();
 876 
 877   size_t framesize = C->frame_size_in_bytes();
 878   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
 879   int bangsize = C->bang_size_in_bytes();
 880   // Remove two words for return addr and fp,
 881   framesize -= 2*wordSize;
 882   bangsize -= 2*wordSize;
 883 
 884   // Calls to C2R adapters often do not accept exceptional returns.
 885   // We require that their callers must bang for them.  But be careful, because
 886   // some VM calls (such as call site linkage) can use several kilobytes of
 887   // stack.  But the stack safety zone should account for that.
 888   // See bugs 4446381, 4468289, 4497237.
 889   if (C->need_stack_bang(bangsize)) {
 890     __ arm_stack_overflow_check(bangsize, r12);
 891   }
 892 
 893   __ push(RegSet::of(rfp, lr), sp);
 894   if (framesize != 0) {
 895     __ sub(sp, sp, framesize);
 896   }
 897 
 898   // offset from scratch buffer is not valid
 899   if (strcmp(cbuf.name(), "Compile::Fill_buffer") == 0) {
 900     C->set_frame_complete( __ offset() );
 901   }
 902 
 903   if (C->has_mach_constant_base_node()) {
 904     // NOTE: We set the table base offset here because users might be
 905     // emitted before MachConstantBaseNode.
 906     Compile::ConstantTable& constant_table = C->constant_table();
 907     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
 908   }
 909 }
 910 
 911 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
 912   return MachNode::size(ra_);
 913 }
 914 
 915 int MachPrologNode::reloc() const {
 916   return 10; // a large enough number
 917 }
 918 
 919 //=============================================================================
 920 #ifndef PRODUCT
 921 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
 922   Compile* C = ra_->C;
 923 
 924   size_t framesize = C->frame_size_in_bytes();
 925   framesize -= 2*wordSize;
 926 
 927   if (framesize != 0) {
 928     st->print("ADD    R_SP, R_SP, " SIZE_FORMAT "\n\t",framesize);
 929   }
 930   st->print("POP    R_FP|R_LR_LR");
 931 
 932   if (do_polling() && ra_->C->is_method_compilation()) {
 933     st->print("\n\t");
 934     st->print("MOV    r12, #PollAddr\t! Load Polling address\n\t");
 935     st->print("LDR    r12,[r12]\t!Poll for Safepointing");
 936   }
 937 }
 938 #endif
 939 
 940 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 941   MacroAssembler _masm(&cbuf);
 942   Compile* C = ra_->C;
 943 
 944   size_t framesize = C->frame_size_in_bytes();
 945   framesize -= 2*wordSize;
 946   if (framesize != 0) {
 947     __ add(sp, sp, framesize);
 948   }
 949   __ pop(RegSet::of(rfp, lr), sp);
 950 
 951   if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
 952     __ reserved_stack_check();
 953   }
 954 
 955   // If this does safepoint polling, then do it here
 956   if (do_polling() && ra_->C->is_method_compilation()) {
 957     // mov here is usually one or two instruction
 958     __ mov_address(r12, (address)os::get_polling_page(), RelocationHolder::none);
 959     __ relocate(relocInfo::poll_return_type);
 960     __ ldr(r12, Address(r12));
 961   }
 962 }
 963 
 964 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
 965   return MachNode::size(ra_);
 966 }
 967 
 968 int MachEpilogNode::reloc() const {
 969   return 16; // a large enough number
 970 }
 971 
 972 const Pipeline * MachEpilogNode::pipeline() const {
 973   return MachNode::pipeline_class();
 974 }
 975 
 976 int MachEpilogNode::safepoint_offset() const {
 977   assert( do_polling(), "no return for this epilog node");
 978   //  return MacroAssembler::size_of_sethi(os::get_polling_page());
 979   Unimplemented();
 980   return 0;
 981 }
 982 
 983 //=============================================================================
 984 
 985 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
 986 enum RC { rc_bad, rc_int, rc_float, rc_stack };
 987 static enum RC rc_class( OptoReg::Name reg ) {
 988   if (!OptoReg::is_valid(reg)) return rc_bad;
 989   if (OptoReg::is_stack(reg)) return rc_stack;
 990   VMReg r = OptoReg::as_VMReg(reg);
 991   if (r->is_Register()) return rc_int;
 992   assert(r->is_FloatRegister(), "must be");
 993   return rc_float;
 994 }
 995 
 996 static inline bool is_iRegLd_memhd(OptoReg::Name src_first, OptoReg::Name src_second, int offset) {
 997   int rlo = Matcher::_regEncode[src_first];
 998   int rhi = Matcher::_regEncode[src_second];
 999   // if (!((rlo&1)==0 && (rlo+1 == rhi))) {
1000   //   tty->print_cr("CAUGHT BAD LDRD/STRD");
1001   // }
1002   return (rlo&1)==0 && (rlo+1 == rhi) && is_memoryHD(offset);
1003 }
1004 
1005 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
1006                                         PhaseRegAlloc *ra_,
1007                                         bool do_size,
1008                                         outputStream* st ) const {
1009   // Get registers to move
1010   OptoReg::Name src_second = ra_->get_reg_second(in(1));
1011   OptoReg::Name src_first = ra_->get_reg_first(in(1));
1012   OptoReg::Name dst_second = ra_->get_reg_second(this );
1013   OptoReg::Name dst_first = ra_->get_reg_first(this );
1014 
1015   enum RC src_second_rc = rc_class(src_second);
1016   enum RC src_first_rc = rc_class(src_first);
1017   enum RC dst_second_rc = rc_class(dst_second);
1018   enum RC dst_first_rc = rc_class(dst_first);
1019 
1020   assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
1021 
1022   // Generate spill code!
1023   int size = 0;
1024 
1025   if (src_first == dst_first && src_second == dst_second)
1026     return size;            // Self copy, no move
1027 
1028 #ifdef TODO
1029   if (bottom_type()->isa_vect() != NULL) {
1030   }
1031 #endif
1032 
1033   // Shared code does not expect instruction set capability based bailouts here.
1034   // Handle offset unreachable bailout with minimal change in shared code.
1035   // Bailout only for real instruction emit.
1036   // This requires a single comment change in shared code. ( see output.cpp "Normal" instruction case )
1037 
1038   MacroAssembler _masm(cbuf);
1039 
1040   // --------------------------------------
1041   // Check for mem-mem move.  Load into unused float registers and fall into
1042   // the float-store case.
1043   if (src_first_rc == rc_stack && dst_first_rc == rc_stack) {
1044     int offset = ra_->reg2offset(src_first);
1045     if (cbuf && !is_memoryfp(offset)) {
1046       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
1047       return 0;
1048     } else {
1049       if (src_second_rc != rc_bad) {
1050         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
1051         src_first     = OptoReg::Name(R_mem_copy_lo_num);
1052         src_second    = OptoReg::Name(R_mem_copy_hi_num);
1053         src_first_rc  = rc_float;
1054         src_second_rc = rc_float;
1055         if (cbuf) {
1056           __ vldr_f64(Rmemcopy, Address(sp, offset));
1057         } else if (!do_size) {
1058           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
1059         }
1060       } else {
1061         src_first     = OptoReg::Name(R_mem_copy_lo_num);
1062         src_first_rc  = rc_float;
1063         if (cbuf) {
1064           __ vldr_f32(Rmemcopy, Address(sp, offset));
1065         } else if (!do_size) {
1066           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
1067         }
1068       }
1069       size += 4;
1070     }
1071   }
1072 
1073   if (src_second_rc == rc_stack && dst_second_rc == rc_stack) {
1074     Unimplemented();
1075   }
1076 
1077   // --------------------------------------
1078   // Check for integer reg-reg copy
1079   if (src_first_rc == rc_int && dst_first_rc == rc_int) {
1080     // Else normal reg-reg copy
1081     assert( src_second != dst_first, "smashed second before evacuating it" );
1082     if (cbuf) {
1083       __ mov(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
1084 #ifndef PRODUCT
1085     } else if (!do_size) {
1086       st->print("MOV    R_%s, R_%s\t# spill",
1087                 Matcher::regName[dst_first],
1088                 Matcher::regName[src_first]);
1089 #endif
1090     }
1091     size += 4;
1092   }
1093 
1094   // Check for integer store
1095   if (src_first_rc == rc_int && dst_first_rc == rc_stack) {
1096     int offset = ra_->reg2offset(dst_first);
1097     if (cbuf && !is_memoryI(offset)) {
1098       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
1099       return 0;
1100     } else {
1101       if (src_second_rc != rc_bad && is_iRegLd_memhd(src_first, src_second, offset)) {
1102         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
1103         if (cbuf) {
1104           __ strd(reg_to_register_object(Matcher::_regEncode[src_first]), Address(sp, offset));
1105 #ifndef PRODUCT
1106         } else if (!do_size) {
1107           if (size != 0) st->print("\n\t");
1108           st->print(STR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
1109 #endif
1110         }
1111         return size + 4;
1112       } else {
1113         if (cbuf) {
1114           __ str(reg_to_register_object(Matcher::_regEncode[src_first]), Address(sp, offset));
1115 #ifndef PRODUCT
1116         } else if (!do_size) {
1117           if (size != 0) st->print("\n\t");
1118           st->print(STR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
1119 #endif
1120         }
1121       }
1122     }
1123     size += 4;
1124   }
1125 
1126   // Check for integer load
1127   if (dst_first_rc == rc_int && src_first_rc == rc_stack) {
1128     int offset = ra_->reg2offset(src_first);
1129     if (cbuf && !is_memoryI(offset)) {
1130       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
1131       return 0;
1132     } else {
1133       if (src_second_rc != rc_bad && is_iRegLd_memhd(dst_first, dst_second, offset)) {
1134         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
1135         if (cbuf) {
1136           __ ldrd(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(sp, offset));
1137 #ifndef PRODUCT
1138         } else if (!do_size) {
1139           if (size != 0) st->print("\n\t");
1140           st->print(LDR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
1141 #endif
1142         }
1143         return size + 4;
1144       } else {
1145         if (cbuf) {
1146           __ ldr(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(sp, offset));
1147 #ifndef PRODUCT
1148         } else if (!do_size) {
1149           if (size != 0) st->print("\n\t");
1150           st->print(LDR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
1151 #endif
1152         }
1153       }
1154     }
1155     size += 4;
1156   }
1157 
1158   // Check for float reg-reg copy
1159   if (src_first_rc == rc_float && dst_first_rc == rc_float) {
1160     if (src_second_rc != rc_bad) {
1161       assert((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
1162       if (cbuf) {
1163       __ vmov_f64(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
1164 #ifndef PRODUCT
1165       } else if (!do_size) {
1166         st->print(MOV_DOUBLE "    R_%s, R_%s\t# spill",
1167                   Matcher::regName[dst_first],
1168                   Matcher::regName[src_first]);
1169 #endif
1170       }
1171       return 4;
1172     }
1173     if (cbuf) {
1174       __ vmov_f32(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
1175 #ifndef PRODUCT
1176     } else if (!do_size) {
1177       st->print(MOV_FLOAT "    R_%s, R_%s\t# spill",
1178                 Matcher::regName[dst_first],
1179                 Matcher::regName[src_first]);
1180 #endif
1181     }
1182     size = 4;
1183   }
1184 
1185   // Check for float store
1186   if (src_first_rc == rc_float && dst_first_rc == rc_stack) {
1187     int offset = ra_->reg2offset(dst_first);
1188     if (cbuf && !is_memoryfp(offset)) {
1189       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
1190       return 0;
1191     } else {
1192       // Further check for aligned-adjacent pair, so we can use a double store
1193       if (src_second_rc != rc_bad) {
1194         assert((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers and stack slots must be aligned/contiguous");
1195         if (cbuf) {
1196           __ vstr_f64(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(sp, offset));
1197 #ifndef PRODUCT
1198         } else if (!do_size) {
1199           if (size != 0) st->print("\n\t");
1200           st->print(STR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
1201 #endif
1202         }
1203         return size + 4;
1204       } else {
1205         if (cbuf) {
1206           __ vstr_f32(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(sp, offset));
1207 #ifndef PRODUCT
1208         } else if (!do_size) {
1209           if (size != 0) st->print("\n\t");
1210           st->print(STR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
1211 #endif
1212         }
1213       }
1214     }
1215     size += 4;
1216   }
1217 
1218   // Check for float load
1219   if (dst_first_rc == rc_float && src_first_rc == rc_stack) {
1220     int offset = ra_->reg2offset(src_first);
1221     if (cbuf && !is_memoryfp(offset)) {
1222       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
1223       return 0;
1224     } else {
1225       // Further check for aligned-adjacent pair, so we can use a double store
1226       if (src_second_rc != rc_bad) {
1227         assert((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers and stack slots must be aligned/contiguous");
1228         if (cbuf) {
1229           __ vldr_f64(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(sp, offset));
1230 #ifndef PRODUCT
1231         } else if (!do_size) {
1232           if (size != 0) st->print("\n\t");
1233           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
1234 #endif
1235         }
1236         return size + 4;
1237       } else {
1238         if (cbuf) {
1239           __ vldr_f32(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(sp, offset));
1240 #ifndef PRODUCT
1241         } else if (!do_size) {
1242           if (size != 0) st->print("\n\t");
1243           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
1244 #endif
1245         }
1246       }
1247     }
1248     size += 4;
1249   }
1250 
1251   // check for int reg -> float reg move
1252   if (src_first_rc == rc_int && dst_first_rc == rc_float) {
1253     // Further check for aligned-adjacent pair, so we can use a single instruction
1254     if (src_second_rc != rc_bad) {
1255       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
1256       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
1257       assert(src_second_rc == rc_int && dst_second_rc == rc_float, "unsupported");
1258       if (cbuf) {
1259         __ vmov_f64(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]), reg_to_register_object(Matcher::_regEncode[src_second]));
1260 #ifndef PRODUCT
1261       } else if (!do_size) {
1262         if (size != 0) st->print("\n\t");
1263         st->print("FMDRR   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first), OptoReg::regname(src_second));
1264 #endif
1265       }
1266       return size + 4;
1267     } else {
1268       if (cbuf) {
1269         __ vmov_f32(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
1270 #ifndef PRODUCT
1271       } else if (!do_size) {
1272         if (size != 0) st->print("\n\t");
1273         st->print(FMSR "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
1274 #endif
1275       }
1276       size += 4;
1277     }
1278   }
1279 
1280   // check for float reg -> int reg move
1281   if (src_first_rc == rc_float && dst_first_rc == rc_int) {
1282     // Further check for aligned-adjacent pair, so we can use a single instruction
1283     if (src_second_rc != rc_bad) {
1284       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
1285       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
1286       assert(src_second_rc == rc_float && dst_second_rc == rc_int, "unsupported");
1287       if (cbuf) {
1288         __ vmov_f64(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[dst_second]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
1289 #ifndef PRODUCT
1290       } else if (!do_size) {
1291         if (size != 0) st->print("\n\t");
1292         st->print("FMRRD   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(dst_second), OptoReg::regname(src_first));
1293 #endif
1294       }
1295       return size + 4;
1296     } else {
1297       if (cbuf) {
1298         __ vmov_f32(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
1299 #ifndef PRODUCT
1300       } else if (!do_size) {
1301         if (size != 0) st->print("\n\t");
1302         st->print(FMRS "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
1303 #endif
1304       }
1305       size += 4;
1306     }
1307   }
1308 
1309   // --------------------------------------------------------------------
1310   // Check for hi bits still needing moving.  Only happens for misaligned
1311   // arguments to native calls.
1312   if (src_second == dst_second)
1313     return size;               // Self copy; no move
1314   assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" );
1315 
1316   // Check for integer reg-reg copy.  Hi bits are stuck up in the top
1317   // 32-bits of a 64-bit register, but are needed in low bits of another
1318   // register (else it's a hi-bits-to-hi-bits copy which should have
1319   // happened already as part of a 64-bit move)
1320   if (src_second_rc == rc_int && dst_second_rc == rc_int) {
1321     if (cbuf) {
1322       __ mov(reg_to_register_object(Matcher::_regEncode[dst_second]), reg_to_register_object(Matcher::_regEncode[src_second]));
1323 #ifndef PRODUCT
1324     } else if (!do_size) {
1325       if (size != 0) st->print("\n\t");
1326       st->print("MOV    R_%s, R_%s\t# spill high",
1327                 Matcher::regName[dst_second],
1328                 Matcher::regName[src_second]);
1329 #endif
1330     }
1331     return size+4;
1332   }
1333 
1334   // Check for high word integer store
1335   if (src_second_rc == rc_int && dst_second_rc == rc_stack) {
1336     int offset = ra_->reg2offset(dst_second);
1337 
1338     if (cbuf && !is_memoryP(offset)) {
1339       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
1340       return 0;
1341     } else {
1342       if (cbuf) {
1343         __ str(reg_to_register_object(Matcher::_regEncode[src_second]), Address(sp, offset));
1344 #ifndef PRODUCT
1345       } else if (!do_size) {
1346         if (size != 0) st->print("\n\t");
1347         st->print("STR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_second), offset);
1348 #endif
1349       }
1350     }
1351     return size + 4;
1352   }
1353 
1354   // Check for high word integer load
1355   if (dst_second_rc == rc_int && src_second_rc == rc_stack) {
1356     int offset = ra_->reg2offset(src_second);
1357     if (cbuf && !is_memoryP(offset)) {
1358       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
1359       return 0;
1360     } else {
1361       if (cbuf) {
1362         __ ldr(reg_to_register_object(Matcher::_regEncode[dst_second]), Address(sp, offset));
1363 #ifndef PRODUCT
1364       } else if (!do_size) {
1365         if (size != 0) st->print("\n\t");
1366         st->print("LDR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_second), offset);
1367 #endif
1368       }
1369     }
1370     return size + 4;
1371   }
1372 
1373   Unimplemented();
1374   return 0; // Mute compiler
1375 }
1376 
1377 #ifndef PRODUCT
1378 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
1379   implementation( NULL, ra_, false, st );
1380 }
1381 #endif
1382 
1383 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1384   implementation( &cbuf, ra_, false, NULL );
1385 }
1386 
1387 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1388   return implementation( NULL, ra_, true, NULL );
1389 }
1390 
1391 //=============================================================================
1392 #ifndef PRODUCT
1393 void MachNopNode::format( PhaseRegAlloc *, outputStream *st ) const {
1394   st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
1395 }
1396 #endif
1397 
1398 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
1399   MacroAssembler _masm(&cbuf);
1400   for(int i = 0; i < _count; i += 1) {
1401     __ nop();
1402   }
1403 }
1404 
1405 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
1406   return 4 * _count;
1407 }
1408 
1409 
1410 //=============================================================================
1411 #ifndef PRODUCT
1412 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
1413   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1414   int reg = ra_->get_reg_first(this);
1415   st->print("ADD    %s,R_SP+#%d",Matcher::regName[reg], offset);
1416 }
1417 #endif
1418 
1419 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1420   MacroAssembler _masm(&cbuf);
1421   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1422   int reg = ra_->get_encode(this);
1423   Register dst = reg_to_register_object(reg);
1424 
1425   if (is_aimm(offset)) {
1426     __ add(dst, sp, offset);
1427   } else {
1428     __ mov(dst, offset);
1429     __ add(dst, sp, dst);
1430   }
1431 }
1432 
1433 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
1434   // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_)
1435   assert(ra_ == ra_->C->regalloc(), "sanity");
1436   return ra_->C->scratch_emit_size(this);
1437 }
1438 
1439 //=============================================================================
1440 #ifndef PRODUCT
1441 #define R_RTEMP "R_R12"
1442 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
1443   st->print_cr("\nUEP:");
1444   if (UseCompressedClassPointers) {
1445     st->print_cr("\tLDR_w " R_RTEMP ",[R_R0 + oopDesc::klass_offset_in_bytes]\t! Inline cache check");
1446     st->print_cr("\tdecode_klass " R_RTEMP);
1447   } else {
1448     st->print_cr("\tLDR   " R_RTEMP ",[R_R0 + oopDesc::klass_offset_in_bytes]\t! Inline cache check");
1449   }
1450   st->print_cr("\tCMP   " R_RTEMP ",R_R12" );
1451   st->print   ("\tB.NE  SharedRuntime::handle_ic_miss_stub");
1452 }
1453 #endif
1454 
1455 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1456   MacroAssembler _masm(&cbuf);
1457   Register iCache  = reg_to_register_object(Matcher::inline_cache_reg_encode());
1458   assert(iCache == rscratch2/*Ricklass*/, "should be");
1459   Register receiver = r0;
1460 
1461   __ load_klass(r9, receiver);
1462   __ cmp(r9, iCache);
1463   // r9 seems temporary here
1464   __ jump(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type, r9, Assembler::NE);
1465 }
1466 
1467 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
1468   return MachNode::size(ra_);
1469 }
1470 
1471 
1472 // REQUIRED EMIT CODE
1473 
1474 //=============================================================================
1475 
1476 // Emit exception handler code.
1477 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) {
1478   MacroAssembler _masm(&cbuf);
1479 
1480   address base = __ start_a_stub(size_exception_handler());
1481   if (base == NULL) {
1482     ciEnv::current()->record_failure("CodeCache is full");
1483     return 0;  // CodeBuffer::expand failed
1484   }
1485 
1486   int offset = __ offset();
1487 
1488   // OK to trash LR, because exception blob will kill it
1489   __ jump(OptoRuntime::exception_blob()->entry_point(), relocInfo::runtime_call_type, lr);
1490 
1491   assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
1492 
1493   __ end_a_stub();
1494 
1495   return offset;
1496 }
1497 
1498 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
1499   // Can't use any of the current frame's registers as we may have deopted
1500   // at a poll and everything can be live.
1501   MacroAssembler _masm(&cbuf);
1502 
1503   address base = __ start_a_stub(size_deopt_handler());
1504   if (base == NULL) {
1505     ciEnv::current()->record_failure("CodeCache is full");
1506     return 0;  // CodeBuffer::expand failed
1507   }
1508 
1509   int offset = __ offset();
1510   address deopt_pc = __ pc();
1511 
1512   __ sub(sp, sp, wordSize); // make room for saved PC
1513   __ push(lr); // save LR that may be live when we get here
1514   __ mov_relative_address(lr, deopt_pc);
1515   __ str(lr, Address(sp, wordSize)); // save deopt PC
1516   __ pop(lr); // restore LR
1517   // rscratch1 seems killed  at deopt_blob
1518   __ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, rscratch1);
1519 
1520   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
1521 
1522   __ end_a_stub();
1523   return offset;
1524 }
1525 
1526 // REQUIRED MATCHER CODE
1527 
1528 //=============================================================================
1529 
1530 const bool Matcher::match_rule_supported(int opcode) {
1531   if (!has_match_rule(opcode))
1532     return false;
1533 
1534   switch (opcode) {
1535   case Op_PopCountI:
1536   case Op_PopCountL:
1537     if (!UsePopCountInstruction)
1538       return false;
1539     break;
1540   case Op_LShiftCntV:
1541   case Op_RShiftCntV:
1542   case Op_AddVB:
1543   case Op_AddVS:
1544   case Op_AddVI:
1545   case Op_AddVL:
1546   case Op_SubVB:
1547   case Op_SubVS:
1548   case Op_SubVI:
1549   case Op_SubVL:
1550   case Op_MulVS:
1551   case Op_MulVI:
1552   case Op_LShiftVB:
1553   case Op_LShiftVS:
1554   case Op_LShiftVI:
1555   case Op_LShiftVL:
1556   case Op_RShiftVB:
1557   case Op_RShiftVS:
1558   case Op_RShiftVI:
1559   case Op_RShiftVL:
1560   case Op_URShiftVB:
1561   case Op_URShiftVS:
1562   case Op_URShiftVI:
1563   case Op_URShiftVL:
1564   case Op_AndV:
1565   case Op_OrV:
1566   case Op_XorV:
1567     return VM_Version::features() & FT_AdvSIMD;
1568   case Op_LoadVector:
1569   case Op_StoreVector:
1570   case Op_AddVF:
1571   case Op_SubVF:
1572   case Op_MulVF:
1573     return VM_Version::features() & (FT_VFPV2 | FT_AdvSIMD);
1574   case Op_AddVD:
1575   case Op_SubVD:
1576   case Op_MulVD:
1577   case Op_DivVF:
1578   case Op_DivVD:
1579     return VM_Version::features() & FT_VFPV2;
1580   }
1581 
1582   return true;  // Per default match rules are supported.
1583 }
1584 
1585 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) {
1586 
1587   // TODO
1588   // identify extra cases that we might want to provide match rules for
1589   // e.g. Op_ vector nodes and other intrinsics while guarding with vlen
1590   bool ret_value = match_rule_supported(opcode);
1591   // Add rules here.
1592 
1593   return ret_value;  // Per default match rules are supported.
1594 }
1595 
1596 const bool Matcher::has_predicated_vectors(void) {
1597   return false;
1598 }
1599 
1600 const int Matcher::float_pressure(int default_pressure_threshold) {
1601   return default_pressure_threshold;
1602 }
1603 
1604 int Matcher::regnum_to_fpu_offset(int regnum) {
1605   return regnum - 32; // The FP registers are in the second chunk
1606 }
1607 
1608 // Vector width in bytes
1609 const int Matcher::vector_width_in_bytes(BasicType bt) {
1610   return MaxVectorSize;
1611 }
1612 
1613 // Vector ideal reg corresponding to specified size in bytes
1614 const uint Matcher::vector_ideal_reg(int size) {
1615   assert(MaxVectorSize >= size, "");
1616   switch(size) {
1617     case  8: return Op_VecD;
1618     case 16: return Op_VecX;
1619   }
1620   ShouldNotReachHere();
1621   return 0;
1622 }
1623 
1624 const uint Matcher::vector_shift_count_ideal_reg(int size) {
1625   return vector_ideal_reg(size);
1626 }
1627 
1628 // Limits on vector size (number of elements) loaded into vector.
1629 const int Matcher::max_vector_size(const BasicType bt) {
1630   assert(is_java_primitive(bt), "only primitive type vectors");
1631   return vector_width_in_bytes(bt)/type2aelembytes(bt);
1632 }
1633 
1634 const int Matcher::min_vector_size(const BasicType bt) {
1635   assert(is_java_primitive(bt), "only primitive type vectors");
1636   return 8/type2aelembytes(bt);
1637 }
1638 
1639 // ARM doesn't support misaligned vectors store/load.
1640 const bool Matcher::misaligned_vectors_ok() {
1641   return false;
1642 }
1643 
1644 // ARM doesn't support AES intrinsics
1645 const bool Matcher::pass_original_key_for_aes() {
1646   return false;
1647 }
1648 
1649 const bool Matcher::convL2FSupported(void) {
1650   return false; // TODO why not?
1651 }
1652 
1653 // Is this branch offset short enough that a short branch can be used?
1654 //
1655 // NOTE: If the platform does not provide any short branch variants, then
1656 //       this method should return false for offset 0.
1657 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
1658   // The passed offset is relative to address of the branch.
1659   // On ARM a branch displacement is calculated relative to address
1660   // of the branch + 8.
1661   //
1662   // offset -= 8;
1663   // return (Assembler::is_simm24(offset));
1664   return false;
1665 }
1666 
1667 const bool Matcher::isSimpleConstant64(jlong value) {
1668   // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
1669   return false;
1670 }
1671 
1672 // No scaling for the parameter the ClearArray node.
1673 const bool Matcher::init_array_count_is_in_bytes = true;
1674 
1675 // Needs 2 CMOV's for longs.
1676 const int Matcher::long_cmove_cost() { return 2; }
1677 
1678 // CMOVF/CMOVD are expensive on ARM.
1679 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
1680 
1681 // Does the CPU require late expand (see block.cpp for description of late expand)?
1682 const bool Matcher::require_postalloc_expand = false;
1683 
1684 // Do we need to mask the count passed to shift instructions or does
1685 // the cpu only look at the lower 5/6 bits anyway?
1686 // FIXME: does this handle vector shifts as well?
1687 const bool Matcher::need_masked_shift_count = true;
1688 
1689 const bool Matcher::convi2l_type_required = true;
1690 
1691 // Should the Matcher clone shifts on addressing modes, expecting them
1692 // to be subsumed into complex addressing expressions or compute them
1693 // into registers?
1694 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
1695   return clone_base_plus_offset_address(m, mstack, address_visited);
1696 }
1697 
1698 void Compile::reshape_address(AddPNode* addp) {
1699 }
1700 
1701 bool Matcher::narrow_oop_use_complex_address() {
1702   ShouldNotCallThis();
1703   return false;
1704 }
1705 
1706 bool Matcher::narrow_klass_use_complex_address() {
1707   ShouldNotCallThis();
1708   return false;
1709 }
1710 
1711 bool Matcher::const_oop_prefer_decode() {
1712   ShouldNotCallThis();
1713   return true;
1714 }
1715 
1716 bool Matcher::const_klass_prefer_decode() {
1717   ShouldNotCallThis();
1718   return true;
1719 }
1720 
1721 // Is it better to copy float constants, or load them directly from memory?
1722 // Intel can load a float constant from a direct address, requiring no
1723 // extra registers.  Most RISCs will have to materialize an address into a
1724 // register first, so they would do better to copy the constant from stack.
1725 const bool Matcher::rematerialize_float_constants = false;
1726 
1727 // If CPU can load and store mis-aligned doubles directly then no fixup is
1728 // needed.  Else we split the double into 2 integer pieces and move it
1729 // piece-by-piece.  Only happens when passing doubles into C code as the
1730 // Java calling convention forces doubles to be aligned.
1731 const bool Matcher::misaligned_doubles_ok = false;
1732 
1733 // No-op on ARM.
1734 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {
1735 }
1736 
1737 // Advertise here if the CPU requires explicit rounding operations
1738 // to implement the UseStrictFP mode.
1739 const bool Matcher::strict_fp_requires_explicit_rounding = false;
1740 
1741 // Are floats converted to double when stored to stack during deoptimization?
1742 // ARM does not handle callee-save floats.
1743 bool Matcher::float_in_double() {
1744   return false;
1745 }
1746 
1747 // Do ints take an entire long register or just half?
1748 // Note that we if-def off of _LP64.
1749 // The relevant question is how the int is callee-saved.  In _LP64
1750 // the whole long is written but de-opt'ing will have to extract
1751 // the relevant 32 bits, in not-_LP64 only the low 32 bits is written.
1752 const bool Matcher::int_in_long = false;
1753 
1754 // Return whether or not this register is ever used as an argument.  This
1755 // function is used on startup to build the trampoline stubs in generateOptoStub.
1756 // Registers not mentioned will be killed by the VM call in the trampoline, and
1757 // arguments in those registers not be available to the callee.
1758 bool Matcher::can_be_java_arg( int reg ) {
1759   if (reg == R_R0_num ||
1760       reg == R_R1_num ||
1761       reg == R_R2_num ||
1762       reg == R_R3_num) return true;
1763 
1764   if (reg >= R_S0_num &&
1765       reg <= R_S15_num) return true;
1766   return false;
1767 }
1768 
1769 bool Matcher::is_spillable_arg( int reg ) {
1770   return can_be_java_arg(reg);
1771 }
1772 
1773 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
1774   return false;
1775 }
1776 
1777 // Register for DIVI projection of divmodI
1778 RegMask Matcher::divI_proj_mask() {
1779   ShouldNotReachHere();
1780   return RegMask();
1781 }
1782 
1783 // Register for MODI projection of divmodI
1784 RegMask Matcher::modI_proj_mask() {
1785   ShouldNotReachHere();
1786   return RegMask();
1787 }
1788 
1789 // Register for DIVL projection of divmodL
1790 RegMask Matcher::divL_proj_mask() {
1791   ShouldNotReachHere();
1792   return RegMask();
1793 }
1794 
1795 // Register for MODL projection of divmodL
1796 RegMask Matcher::modL_proj_mask() {
1797   ShouldNotReachHere();
1798   return RegMask();
1799 }
1800 
1801 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
1802   return FP_REGP_mask();
1803 }
1804 
1805 bool maybe_far_call(const CallNode *n) {
1806   return !MacroAssembler::_reachable_from_cache(n->as_Call()->entry_point());
1807 }
1808 
1809 bool maybe_far_call(const MachCallNode *n) {
1810   return !MacroAssembler::_reachable_from_cache(n->as_MachCall()->entry_point());
1811 }
1812 
1813 %}
1814 
1815 //----------ENCODING BLOCK-----------------------------------------------------
1816 // This block specifies the encoding classes used by the compiler to output
1817 // byte streams.  Encoding classes are parameterized macros used by
1818 // Machine Instruction Nodes in order to generate the bit encoding of the
1819 // instruction.  Operands specify their base encoding interface with the
1820 // interface keyword.  There are currently supported four interfaces,
1821 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
1822 // operand to generate a function which returns its register number when
1823 // queried.   CONST_INTER causes an operand to generate a function which
1824 // returns the value of the constant when queried.  MEMORY_INTER causes an
1825 // operand to generate four functions which return the Base Register, the
1826 // Index Register, the Scale Value, and the Offset Value of the operand when
1827 // queried.  COND_INTER causes an operand to generate six functions which
1828 // return the encoding code (ie - encoding bits for the instruction)
1829 // associated with each basic boolean condition for a conditional instruction.
1830 //
1831 // Instructions specify two basic values for encoding.  Again, a function
1832 // is available to check if the constant displacement is an oop. They use the
1833 // ins_encode keyword to specify their encoding classes (which must be
1834 // a sequence of enc_class names, and their parameters, specified in
1835 // the encoding block), and they use the
1836 // opcode keyword to specify, in order, their primary, secondary, and
1837 // tertiary opcode.  Only the opcode sections which a particular instruction
1838 // needs for encoding need to be specified.
1839 encode %{
1840   enc_class call_epilog %{
1841     // nothing
1842   %}
1843 
1844   enc_class Java_To_Runtime (method meth) %{
1845     // CALL directly to the runtime
1846     emit_call_reloc(cbuf, as_MachCall(), $meth, runtime_call_Relocation::spec());
1847   %}
1848 
1849   enc_class Java_Static_Call (method meth) %{
1850     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
1851     // who we intended to call.
1852 
1853     if ( !_method) {
1854       emit_call_reloc(cbuf, as_MachCall(), $meth, runtime_call_Relocation::spec());
1855     } else {
1856       int method_index = resolved_method_index(cbuf);
1857       RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
1858                                                   : static_call_Relocation::spec(method_index);
1859       emit_call_reloc(cbuf, as_MachCall(), $meth, rspec);
1860 
1861       // Emit stubs for static call.
1862       address stub = CompiledStaticCall::emit_to_interp_stub(cbuf);
1863       if (stub == NULL) {
1864         ciEnv::current()->record_failure("CodeCache is full");
1865         return;
1866       }
1867     }
1868   %}
1869 
1870   enc_class save_last_PC %{
1871     // preserve mark
1872     address mark = cbuf.insts()->mark();
1873     debug_only(int off0 = cbuf.insts_size());
1874     MacroAssembler _masm(&cbuf);
1875     int ret_addr_offset = as_MachCall()->ret_addr_offset();
1876     __ adr(lr, mark + ret_addr_offset);
1877     __ str(lr, Address(Rthread, JavaThread::last_Java_pc_offset()));
1878     debug_only(int off1 = cbuf.insts_size());
1879     assert(off1 - off0 == 2 * Assembler::InstructionSize, "correct size prediction");
1880     // restore mark
1881     cbuf.insts()->set_mark(mark);
1882   %}
1883 
1884   enc_class preserve_SP %{
1885     // preserve mark
1886     address mark = cbuf.insts()->mark();
1887     debug_only(int off0 = cbuf.insts_size());
1888     MacroAssembler _masm(&cbuf);
1889     // FP is preserved across all calls, even compiled calls.
1890     // Use it to preserve SP in places where the callee might change the SP.
1891     __ mov(Rmh_SP_save, sp);
1892     debug_only(int off1 = cbuf.insts_size());
1893     assert(off1 - off0 == 4, "correct size prediction");
1894     // restore mark
1895     cbuf.insts()->set_mark(mark);
1896   %}
1897 
1898   enc_class restore_SP %{
1899     MacroAssembler _masm(&cbuf);
1900     __ mov(sp, Rmh_SP_save);
1901   %}
1902 
1903   enc_class Java_Dynamic_Call (method meth) %{
1904     MacroAssembler _masm(&cbuf);
1905     Register R12_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode());
1906     assert(R12_ic_reg == rscratch2/*Ricklass*/, "should be");
1907     __ set_inst_mark();
1908     __ movw_i(R12_ic_reg, ((unsigned int)Universe::non_oop_word()) & 0xffff);
1909     __ movt_i(R12_ic_reg, ((unsigned int)Universe::non_oop_word()) >> 16);
1910     address  virtual_call_oop_addr = __ inst_mark();
1911     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
1912     // who we intended to call.
1913     int method_index = resolved_method_index(cbuf);
1914     emit_call_reloc(cbuf, as_MachCall(), $meth, virtual_call_Relocation::spec(virtual_call_oop_addr, method_index));
1915   %}
1916 
1917   enc_class LdReplImmI(immI src, regD dst, iRegI tmp, int cnt, int wth) %{
1918     // FIXME: load from constant table?
1919     // Load a constant replicated "count" times with width "width"
1920     int count = $cnt$$constant;
1921     int width = $wth$$constant;
1922     assert(count*width == 4, "sanity");
1923     int val = $src$$constant;
1924     if (width < 4) {
1925       int bit_width = width * 8;
1926       val &= (((int)1) << bit_width) - 1; // mask off sign bits
1927       for (int i = 0; i < count - 1; i++) {
1928         val |= (val << bit_width);
1929       }
1930     }
1931     MacroAssembler _masm(&cbuf);
1932 
1933     if (val == -1) {
1934       __ mvn_i($tmp$$Register, 0);
1935     } else if (val == 0) {
1936       __ mov_i($tmp$$Register, 0);
1937     } else {
1938       __ movw_i($tmp$$Register, val & 0xffff);
1939       __ movt_i($tmp$$Register, (unsigned int)val >> 16);
1940     }
1941     __ vmov_f64($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
1942   %}
1943 
1944   enc_class LdReplImmF(immF src, regD dst, iRegI tmp) %{
1945     // Replicate float con 2 times and pack into vector (8 bytes) in regD.
1946     float fval = $src$$constant;
1947     int val = *((int*)&fval);
1948     MacroAssembler _masm(&cbuf);
1949 
1950     if (val == -1) {
1951       __ mvn_i($tmp$$Register, 0);
1952     } else if (val == 0) {
1953       __ mov_i($tmp$$Register, 0);
1954     } else {
1955       __ movw_i($tmp$$Register, val & 0xffff);
1956       __ movt_i($tmp$$Register, (unsigned int)val >> 16);
1957     }
1958     __ vmov_f64($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
1959   %}
1960 
1961   enc_class enc_String_Compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result,
1962                                iRegI tmp1, iRegI tmp2, Q0_regD ftmp1, Q1_regD ftmp2,
1963                                int bytes_per_char1, int bytes_per_char2) %{
1964     MacroAssembler _masm(&cbuf);
1965 
1966     Register       str1 = $str1$$Register;
1967     Register       str2 = $str2$$Register;
1968     Register       cnt1 = $cnt1$$Register;
1969     Register       cnt2 = $cnt2$$Register;
1970     Register       tmp1 = $tmp1$$Register;
1971     Register       tmp2 = $tmp2$$Register;
1972     FloatRegister ftmp1 = $ftmp1$$FloatRegister;
1973     FloatRegister ftmp2 = $ftmp2$$FloatRegister;
1974     Register     result = $result$$Register;
1975     int bytes_per_char1 = $bytes_per_char1;
1976     int bytes_per_char2 = $bytes_per_char2;
1977 
1978     typedef void (Assembler::*ldfp)(Register, const Address &, Assembler::Condition);
1979     typedef void (Assembler::*usubp)(Register, Register, Register, Assembler::Condition);
1980     ldfp ldf_16 = &Assembler::ldrh;
1981     ldfp ldf_8  = &Assembler::ldrb;
1982 
1983     // slow path: single char load
1984     int cnt_per_char = bytes_per_char1==2 && bytes_per_char2==2 ? 2 : 1;
1985     ldfp lds1 = bytes_per_char1 == 2 ? ldf_16 : ldf_8;
1986     ldfp lds2 = bytes_per_char2 == 2 ? ldf_16 : ldf_8;
1987     usubp usub = bytes_per_char1 == 1 ? (usubp)&Assembler::usub8 : (usubp)&Assembler::usub16;
1988 
1989     assert_different_registers(str1, str2, cnt1, cnt2, tmp1, tmp2, result);
1990 
1991     Label Llength_diff, Ldone, Lshort_loop;
1992 
1993     BLOCK_COMMENT("string_compare {");
1994 
1995     // for UU we count bytes (saves 1 insn) for others count in chars
1996     if (cnt_per_char == 1 && bytes_per_char1 == 2)
1997       __ lsr(cnt1, cnt1, 1);
1998     if (cnt_per_char == 1 && bytes_per_char2 == 2)
1999       __ lsr(cnt2, cnt2, 1);
2000 
2001     // Compute the minimum of the string lengths and save the difference.
2002     __ subs(tmp1, cnt1, cnt2);
2003     __ mov(cnt2, cnt1, Assembler::LE); // min
2004 
2005     // Check if the strings start at the same location.
2006     __ cmp(str1, str2);
2007     __ b(Llength_diff, Assembler::EQ);
2008 
2009     // without NEON only for UU and LL fast path is available
2010     if ((VM_Version::features() & FT_AdvSIMD) || bytes_per_char1 == bytes_per_char2) {
2011       Label Lshort_string, Lnext_word, Ldifference;
2012 
2013       // A very short string
2014       __ cmp(cnt2, 8+4);
2015       __ b(Lshort_string, Assembler::LT);
2016 
2017       // Compare words
2018       {
2019         const int bits_per_char = bytes_per_char1==1 && bytes_per_char2==1 ? 8 : 16;
2020         // Check first few chars to avoid excessive processing
2021         if (bytes_per_char1 == 1 && bytes_per_char2 == 1) {
2022           Label Lfull_speed;
2023           __ ldr(tmp2, __ post(str1, wordSize));
2024           __ ldr(result, __ post(str2, wordSize));
2025           (_masm.*usub)(result, tmp2, result, Assembler::AL);
2026           __ tst(result, result);
2027           __ b(Lfull_speed, Assembler::EQ);
2028 
2029           __ rbit(cnt1, result);
2030           __ clz(cnt1, cnt1);
2031           __ bic(cnt1, cnt1, bits_per_char-1);
2032           __ lsr(result, result, cnt1);
2033           __ lsr(tmp2, tmp2, cnt1);
2034           __ ubfx(result, result, 0, bits_per_char);
2035           __ ubfx(tmp2, tmp2, 0, bits_per_char);
2036           __ cmp(result, tmp2);
2037           __ sub(result, result, 1<<bits_per_char, Assembler::HI);
2038           __ b(Ldone);
2039 
2040           __ bind(Lfull_speed);
2041         } else {
2042           (_masm.*lds1)(result, __ post(str1, bytes_per_char1), Assembler::AL);
2043           (_masm.*lds2)(cnt1, __ post(str2, bytes_per_char2), Assembler::AL);
2044           __ subs(result, result, cnt1);
2045           __ b(Ldone, Assembler::NE);
2046           (_masm.*lds1)(result, __ post(str1, bytes_per_char1), Assembler::AL);
2047           (_masm.*lds2)(cnt1, __ post(str2, bytes_per_char2), Assembler::AL);
2048           __ subs(result, result, cnt1);
2049           __ b(Ldone, Assembler::NE);
2050         }
2051 
2052         if (VM_Version::features() & FT_AdvSIMD) {
2053 #define LD(expand_needed,reg,str)        \
2054           if (!(expand_needed))                                  \
2055             __ vld1_64((reg), __ post(str, 8), Assembler::ALIGN_STD);     \
2056           else { \
2057             __ vld1_32((reg), 0, __ post(str, 4), false);         \
2058             __ vmovl_8u((reg), (reg)); /* kills reg+1 */        \
2059           }
2060           const int cnt_per_LD  = bytes_per_char1==bytes_per_char2 ? 8 : 4;
2061           const bool expand_needed1 = bytes_per_char1==1 && bytes_per_char2==2;
2062           const bool expand_needed2 = bytes_per_char1==2 && bytes_per_char2==1;
2063 
2064           __ sub(cnt2, cnt2, 2*cnt_per_char*(16/bits_per_char) + cnt_per_LD); // 4 chars processed above for LL, 2 for the rest of encodings
2065           __ bind(Lnext_word);
2066           LD(expand_needed1,ftmp1,str1);
2067           LD(expand_needed2,ftmp2,str2);
2068           if (bits_per_char == 8)
2069             __ vsub_64_8(ftmp2, ftmp1, ftmp2);
2070           else
2071             __ vsub_64_16(ftmp2, ftmp1, ftmp2);
2072           __ vmov_f64(result, cnt1, ftmp2);
2073           __ orrs(tmp2, result, cnt1);
2074           __ b(Ldifference, Assembler::NE);
2075           __ subs(cnt2, cnt2, cnt_per_LD);
2076           __ b(Lnext_word, Assembler::HS);
2077 
2078           // check the tail
2079           __ adds(cnt2, cnt2, cnt_per_LD);
2080           __ b(Llength_diff, Assembler::EQ);
2081           __ b(Lshort_loop);
2082 
2083           __ bind(Ldifference);
2084           __ vmov_f64(tmp2, cnt2, ftmp1);
2085           __ tst(result, result);
2086           __ mov(result, cnt1, Assembler::EQ);
2087           __ mov(tmp2, cnt2, Assembler::EQ);
2088         } else {
2089           __ sub(cnt2, cnt2, 2*cnt_per_char*(16/bits_per_char)+4); // Skip 4 or 2 chars processed above. The last word is a special case
2090 
2091           // Move both string pointers to the last word of their
2092           // strings, negate the remaining count.
2093           __ lea(str1, Address(str1, cnt2));
2094           __ lea(str2, Address(str2, cnt2));
2095           __ neg(cnt2, cnt2);
2096 
2097           // Loop, loading words and comparing them into tmp2.
2098           __ bind(Lnext_word);
2099           __ ldr(tmp2, Address(str1, cnt2));
2100           __ ldr(result, Address(str2, cnt2));
2101           __ teq(result, tmp2);
2102           __ b(Ldifference, Assembler::NE);
2103           __ adds(cnt2, cnt2, wordSize); // cnt is per-byte for both UU and LL
2104           __ b(Lnext_word, Assembler::LT);
2105 
2106           // Last word.  In the case where length == 2 we compare the
2107           // same word twice, but that's still faster than another
2108           // conditional branch.
2109 
2110           __ ldr(tmp2, Address(str1));
2111           __ ldr(result, Address(str2));
2112           __ teq(result, tmp2);
2113           __ b(Llength_diff, Assembler::EQ);
2114 
2115           // Find the first different characters in the words and
2116           // compute their difference.
2117           __ bind(Ldifference);
2118           (_masm.*usub)(result, tmp2, result, Assembler::AL);
2119         }
2120 
2121         // now result is a-b and tmp2 is a
2122         if (bits_per_char == 8) {
2123           __ rbit(cnt1, result);
2124           __ clz(cnt1, cnt1);
2125           __ bic(cnt1, cnt1, bits_per_char-1);
2126           __ lsr(result, result, cnt1);
2127           __ lsr(tmp2, tmp2, cnt1);
2128           __ ubfx(result, result, 0, bits_per_char);
2129           __ ubfx(tmp2, tmp2, 0, bits_per_char);
2130         } else {
2131           __ lsls(cnt1, result, 16);
2132           __ uxth(result, result, ror(16), Assembler::EQ);
2133           __ uxth(result, result, ror(), Assembler::NE);
2134           __ uxth(tmp2, tmp2, ror(16), Assembler::EQ);
2135           __ uxth(tmp2, tmp2, ror(), Assembler::NE);
2136         }
2137         __ cmp(result, tmp2);
2138         __ sub(result, result, 1<<bits_per_char, Assembler::HI);
2139 
2140         __ b(Ldone);
2141       }
2142 
2143       __ bind(Lshort_string);
2144     }
2145 
2146     // Is the minimum length zero?
2147     __ cbz(cnt2, Llength_diff);
2148 
2149     __ bind(Lshort_loop);
2150     (_masm.*lds1)(result, __ post(str1, bytes_per_char1), Assembler::AL);
2151     (_masm.*lds2)(cnt1, __ post(str2, bytes_per_char2), Assembler::AL);
2152     __ subs(result, result, cnt1);
2153     __ b(Ldone, Assembler::NE);
2154     __ subs(cnt2, cnt2, cnt_per_char);
2155     __ b(Lshort_loop, Assembler::NE);
2156 
2157     // Strings are equal up to min length.  Return the length difference.
2158     __ bind(Llength_diff);
2159     __ asr(result, tmp1, cnt_per_char-1); // input in bytes, result in chars, nice convention
2160 
2161     // That's it
2162     __ bind(Ldone);
2163 
2164     BLOCK_COMMENT("} string_compare");
2165   %}
2166 
2167   enc_class enc_Array_Equals(R0RegP ary1, R1RegP ary2, iRegI cnt, iRegI tmp2, iRegI result, int elemSize, bool isArray) %{
2168     Label Ldone, Lloop, Lset_result, Lshort_array, Lnext_word, Lshort_array_cont, Lone_byte;
2169     MacroAssembler _masm(&cbuf);
2170 
2171     Register   ary1 = $ary1$$Register;
2172     Register   ary2 = $ary2$$Register;
2173     Register   cnt =  $cnt$$Register;
2174     Register   tmp2 = $tmp2$$Register;
2175     Register result = $result$$Register;
2176     int elemSize    = $elemSize$$constant;
2177     bool isArray    = $isArray$$constant;
2178 
2179     assert_different_registers(ary1, ary2, cnt, tmp2, result);
2180 
2181     if (isArray) {
2182       int length_offset  = arrayOopDesc::length_offset_in_bytes();
2183       int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
2184 
2185       BLOCK_COMMENT(elemSize == 2 ? "char_array_equalsUU {" : "char_array_equalsLL {");
2186 
2187       // return true if the same array
2188       __ cmpoop(ary1, ary2);
2189       __ b(Lset_result, Assembler::EQ); // equal
2190 
2191       __ ands(result, ary1, ary1);
2192       __ b(Ldone, Assembler::EQ);    // not equal
2193 
2194       __ ands(result, ary2, ary2);
2195       __ b(Ldone, Assembler::EQ);    // not equal
2196 
2197       //load the lengths of arrays
2198       __ ldr(cnt, Address(ary1, length_offset));
2199       __ ldr(tmp2, Address(ary2, length_offset));
2200 
2201       // return false if the two arrays are not equal length
2202       __ teq(cnt, tmp2);
2203       __ b(Lset_result, Assembler::NE);    // not equal
2204 
2205       __ tst(cnt, cnt);
2206       __ b(Lset_result, Assembler::EQ);    // zero-length arrays are equal
2207 
2208       // load array addresses
2209       __ add(ary1, ary1, base_offset);
2210       __ add(ary2, ary2, base_offset);
2211     } else {
2212     // Check if the strings start at the same location.
2213       BLOCK_COMMENT(elemSize == 2 ? "string_equalsUU {" : "string_equalsLL {");
2214 
2215       __ cmp(ary1, ary2);
2216       __ b(Lset_result, Assembler::EQ);
2217     }
2218 
2219     __ cmp(cnt, 4*(2/elemSize));
2220     __ b(Lshort_array, Assembler::LT);
2221 
2222     {
2223       // Move both string pointers to the last word of their
2224       // strings, negate the remaining count, and convert it to bytes if needed.
2225       if (isArray && elemSize == 2)
2226           __ lsl(cnt, cnt, 1);
2227       __ sub(cnt, cnt, wordSize); // The last word is a special case
2228 
2229       __ lea(ary1, Address(ary1, cnt));
2230       __ lea(ary2, Address(ary2, cnt));
2231       __ neg(cnt, cnt);
2232 
2233       // Loop, loading words and comparing them.
2234       __ bind(Lnext_word);
2235       __ ldr(result, Address(ary1, cnt));
2236       __ ldr(tmp2, Address(ary2, cnt));
2237       __ cmp(result, tmp2);
2238       __ b(Lset_result, Assembler::NE);
2239       __ adds(cnt, cnt, wordSize);
2240       __ b(Lnext_word, Assembler::LT);
2241 
2242       // Last word.  In the case where length < 4 we compare the
2243       // same bytes twice, but that's still faster than another
2244       // conditional branch.
2245       __ ldr(result, Address(ary1));
2246       __ ldr(tmp2, Address(ary2));
2247       __ cmp(result, tmp2);
2248       __ b(Lset_result);
2249     }
2250 
2251     __ bind(Lshort_array); {
2252       if (!isArray) {
2253         __ tst(cnt, cnt);
2254         __ b(Lset_result, Assembler::EQ);
2255       }
2256 
2257       if (elemSize == 1) {
2258         __ subs(cnt, cnt, 1);
2259         __ b(Lone_byte, Assembler::EQ);
2260       }
2261       __ bind(Lshort_array_cont);
2262 
2263       __ ldrh(result, __ post(ary1, 2));
2264       __ ldrh(tmp2, __ post(ary2, 2));
2265       __ cmp(result, tmp2);
2266       __ b(Lset_result, Assembler::NE);
2267       __ subs(cnt, cnt, isArray ? 2/elemSize : 2);
2268       __ b(Lshort_array_cont, Assembler::GT);
2269     }
2270 
2271     if (elemSize == 1) {
2272       __ cmn(cnt, 1);
2273       __ b(Lset_result, Assembler::EQ);
2274 
2275       __ bind(Lone_byte); {
2276         __ ldrb(result, Address(ary1));
2277         __ ldrb(tmp2, Address(ary2));
2278         __ cmp(result, tmp2);
2279       }
2280     }
2281 
2282     __ bind(Lset_result);
2283     __ mov(result, 1, Assembler::EQ);
2284     __ mov(result, 0, Assembler::NE);
2285 
2286     __ bind(Ldone);
2287 
2288     if (isArray)
2289       BLOCK_COMMENT(elemSize == 2 ? "} char_array_equalsUU" : "} char_array_equalsLL");
2290     else
2291       BLOCK_COMMENT(elemSize == 2? "} string_equalsUU" : "} string_equalsLL");
2292 
2293     %}
2294 
2295   enc_class enc_Char_Array_Compress(R2RegP src, R1RegP dst, R3RegI len, R9RegI tmp1,
2296                                     Q0_regD tmp2, Q1_regD tmp3, R12RegI tmp4,
2297                                     R0RegI result, flagsReg ccr) %{
2298     Label Ldone, Lloop1, Lset_result;
2299     MacroAssembler _masm(&cbuf);
2300 
2301     Register      src    = $src$$Register;
2302     Register      dst    = $dst$$Register;
2303     Register      len    = $len$$Register;
2304     Register      tmp1   = $tmp1$$Register;
2305     Register      result = $result$$Register;
2306     // tmp2, tmp3 and tmp4 are consumed by NEON stub
2307 
2308     BLOCK_COMMENT("char_array_compress {");
2309 
2310     __ movs(result, len);
2311     __ b(Ldone, Assembler::EQ);
2312 
2313     if (VM_Version::features() & FT_AdvSIMD) {
2314       Label Lloop2;
2315       __ cmp(len, 2+8+16); // neon stub consumes minimum 24 chars
2316       __ b(Lloop1, Assembler::LO);
2317 
2318       // check first 2 chars in hope they quickly give information about encoding
2319       __ ldrh(tmp1, __ post(src, 2));
2320       __ strb(tmp1, __ post(dst, 1));
2321       __ lsrs(tmp1, tmp1, 8);
2322       __ ldrh(tmp1, __ post(src, 2), Assembler::EQ);
2323       __ strb(tmp1, __ post(dst, 1), Assembler::EQ);
2324       __ lsrs(tmp1, tmp1, 8, Assembler::EQ);
2325       __ b(Lset_result, Assembler::NE);
2326       __ sub(len, len, 2);
2327 
2328       __ call(StubRoutines::aarch32::string_compress_neon());
2329       __ b(Ldone, Assembler::EQ);
2330     }
2331 
2332     // nothing better we could do with Aarch32 basic instruction set
2333     __ bind(Lloop1); {
2334       __ ldrh(tmp1, __ post(src, 2));
2335       __ strb(tmp1, __ post(dst, 1));
2336       __ rsbs(tmp1, tmp1, 0x100); // GT good, LE bad
2337       __ subs(len, len, 1, Assembler::GT);
2338       __ b(Lloop1, Assembler::GT);
2339     }
2340 
2341     __ cmp(len, 0);
2342     __ bind(Lset_result);
2343     __ mov(result, 0, Assembler::NE);
2344 
2345     __ bind(Ldone);
2346     BLOCK_COMMENT("} char_array_compress");
2347     %}
2348 
2349   enc_class enc_Byte_Array_Inflate(R0RegP src, R1RegP dst, R2RegI len,
2350                                    iRegI tmp1, Q0_regD tmp2, flagsReg ccr) %{
2351     Label Ldone, Lloop1, Lone_char;
2352     MacroAssembler _masm(&cbuf);
2353 
2354     Register      src = $src$$Register;
2355     Register      dst = $dst$$Register;
2356     Register      len = $len$$Register;
2357     Register     tmp1 = $tmp1$$Register;
2358     // tmp2 is consumed by NEON stub
2359 
2360     BLOCK_COMMENT("byte_array_inflate {");
2361 
2362     __ cbz(len, Ldone);
2363     if (VM_Version::features() & FT_AdvSIMD) {
2364       Label Lskip_simd;
2365 
2366       __ cmp(len, 16);
2367       __ b(Lskip_simd, Assembler::LO);
2368       __ call(StubRoutines::aarch32::string_inflate_neon());
2369       __ b(Ldone, Assembler::EQ);
2370       __ bind(Lskip_simd);
2371     }
2372 
2373     // nothing better we could do with Aarch32 basic instruction set
2374     __ subs(len, len, 1);
2375     __ b(Lone_char, Assembler::EQ);
2376     __ bind(Lloop1); {
2377       __ ldrb(tmp1, __ post(src, 1));
2378       __ strh(tmp1, __ post(dst, 2));
2379       __ ldrb(tmp1, __ post(src, 1));
2380       __ strh(tmp1, __ post(dst, 2));
2381       __ subs(len, len, 2);
2382       __ b(Lloop1, Assembler::HI);
2383     }
2384     __ b(Ldone, Assembler::LO);
2385 
2386     __ bind(Lone_char);
2387     __ ldrb(tmp1, __ post(src, 1));
2388     __ strh(tmp1, __ post(dst, 2));
2389 
2390     __ bind(Ldone);
2391     BLOCK_COMMENT("} byte_array_inflate");
2392   %}
2393 
2394 %}
2395 
2396 //----------FRAME--------------------------------------------------------------
2397 // Definition of frame structure and management information.
2398 //
2399 //  S T A C K   L A Y O U T    Allocators stack-slot number
2400 //                             |   (to get allocators register number
2401 //  G  Owned by    |        |  v    add VMRegImpl::stack0)
2402 //  r   CALLER     |        |
2403 //  o     |        +--------+      pad to even-align allocators stack-slot
2404 //  w     V        |  pad0  |        numbers; owned by CALLER
2405 //  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
2406 //  h     ^        |   in   |  5
2407 //        |        |  args  |  4   Holes in incoming args owned by SELF
2408 //  |     |        |        |  3
2409 //  |     |        +--------+
2410 //  V     |        | old out|      Empty on Intel, window on Sparc
2411 //        |    old |preserve|      Must be even aligned.
2412 //        |     SP-+--------+----> Matcher::_old_SP, 8 (or 16 in LP64)-byte aligned
2413 //        |        |   in   |  3   area for Intel ret address
2414 //     Owned by    |preserve|      Empty on Sparc.
2415 //       SELF      +--------+
2416 //        |        |  pad2  |  2   pad to align old SP
2417 //        |        +--------+  1
2418 //        |        | locks  |  0
2419 //        |        +--------+----> VMRegImpl::stack0, 8 (or 16 in LP64)-byte aligned
2420 //        |        |  pad1  | 11   pad to align new SP
2421 //        |        +--------+
2422 //        |        |        | 10
2423 //        |        | spills |  9   spills
2424 //        V        |        |  8   (pad0 slot for callee)
2425 //      -----------+--------+----> Matcher::_out_arg_limit, unaligned
2426 //        ^        |  out   |  7
2427 //        |        |  args  |  6   Holes in outgoing args owned by CALLEE
2428 //     Owned by    +--------+
2429 //      CALLEE     | new out|  6   Empty on Intel, window on Sparc
2430 //        |    new |preserve|      Must be even-aligned.
2431 //        |     SP-+--------+----> Matcher::_new_SP, even aligned
2432 //        |        |        |
2433 //
2434 // Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
2435 //         known from SELF's arguments and the Java calling convention.
2436 //         Region 6-7 is determined per call site.
2437 // Note 2: If the calling convention leaves holes in the incoming argument
2438 //         area, those holes are owned by SELF.  Holes in the outgoing area
2439 //         are owned by the CALLEE.  Holes should not be nessecary in the
2440 //         incoming area, as the Java calling convention is completely under
2441 //         the control of the AD file.  Doubles can be sorted and packed to
2442 //         avoid holes.  Holes in the outgoing arguments may be nessecary for
2443 //         varargs C calling conventions.
2444 // Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
2445 //         even aligned with pad0 as needed.
2446 //         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
2447 //         region 6-11 is even aligned; it may be padded out more so that
2448 //         the region from SP to FP meets the minimum stack alignment.
2449 
2450 frame %{
2451   // What direction does stack grow in (assumed to be same for native & Java)
2452   stack_direction(TOWARDS_LOW);
2453 
2454   // These two registers define part of the calling convention
2455   // between compiled code and the interpreter.
2456   inline_cache_reg(R_Ricklass);          // Inline Cache Register or Method* for I2C
2457   interpreter_method_oop_reg(R_Rmethod); // Method Oop Register when calling interpreter
2458 
2459   // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
2460   cisc_spilling_operand_name(indOffset);
2461 
2462   // Number of stack slots consumed by a Monitor enter
2463   sync_stack_slots(1 * VMRegImpl::slots_per_word);
2464 
2465   // Compiled code's Frame Pointer
2466   frame_pointer(R_R13);
2467 
2468   // Stack alignment requirement
2469   stack_alignment(StackAlignmentInBytes);
2470   //  LP64: Alignment size in bytes (128-bit -> 16 bytes)
2471   // !LP64: Alignment size in bytes (64-bit  ->  8 bytes)
2472 
2473   // Number of stack slots between incoming argument block and the start of
2474   // a new frame.  The PROLOG must add this many slots to the stack.  The
2475   // EPILOG must remove this many slots.
2476   // FP + LR
2477   in_preserve_stack_slots(2 * VMRegImpl::slots_per_word);
2478 
2479   // Number of outgoing stack slots killed above the out_preserve_stack_slots
2480   // for calls to C.  Supports the var-args backing area for register parms.
2481   // ADLC doesn't support parsing expressions, so I folded the math by hand.
2482   varargs_C_out_slots_killed( 0);
2483 
2484   // The after-PROLOG location of the return address.  Location of
2485   // return address specifies a type (REG or STACK) and a number
2486   // representing the register number (i.e. - use a register name) or
2487   // stack slot.
2488   // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
2489   // Otherwise, it is above the locks and verification slot and alignment word
2490   return_addr(STACK - 1*VMRegImpl::slots_per_word +
2491               align_up((Compile::current()->in_preserve_stack_slots() +
2492                         Compile::current()->fixed_slots()),
2493                        stack_alignment_in_slots()));
2494 
2495   // Body of function which returns an OptoRegs array locating
2496   // arguments either in registers or in stack slots for calling
2497   // java
2498   calling_convention %{
2499     (void) SharedRuntime::java_calling_convention(sig_bt, regs, length, is_outgoing);
2500 
2501   %}
2502 
2503   // Body of function which returns an OptoRegs array locating
2504   // arguments either in registers or in stack slots for callin
2505   // C.
2506   c_calling_convention %{
2507     // This is obviously always outgoing
2508     (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
2509   %}
2510 
2511   // Location of compiled Java return values.
2512   return_value %{
2513     return c2::return_value(ideal_reg);
2514   %}
2515 
2516   // Location of C return values.
2517   c_return_value %{
2518 #ifndef HARD_FLOAT_CC
2519     return c2::c_return_value(ideal_reg);
2520 #else
2521     return c2::return_value(ideal_reg);
2522 #endif
2523   %}
2524 
2525 %}
2526 
2527 //----------ATTRIBUTES---------------------------------------------------------
2528 //----------Instruction Attributes---------------------------------------------
2529 ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute
2530 ins_attrib ins_size(32);           // Required size attribute (in bits)
2531 ins_attrib ins_short_branch(0);    // Required flag: is this instruction a
2532                                    // non-matching short branch variant of some
2533                                                             // long branch?
2534 
2535 //----------OPERANDS-----------------------------------------------------------
2536 // Operand definitions must precede instruction definitions for correct parsing
2537 // in the ADLC because operands constitute user defined types which are used in
2538 // instruction definitions.
2539 
2540 //----------Simple Operands----------------------------------------------------
2541 // Immediate Operands
2542 // Integer Immediate: 32-bit
2543 operand immI() %{
2544   match(ConI);
2545 
2546   op_cost(0);
2547   // formats are generated automatically for constants and base registers
2548   format %{ %}
2549   interface(CONST_INTER);
2550 %}
2551 
2552 // Integer Immediate: 8-bit unsigned - for VMOV
2553 operand immU8() %{
2554   predicate(0 <= n->get_int() && (n->get_int() <= 255));
2555   match(ConI);
2556   op_cost(0);
2557 
2558   format %{ %}
2559   interface(CONST_INTER);
2560 %}
2561 
2562 // Integer Immediate: 16-bit
2563 operand immI16() %{
2564   predicate((n->get_int() >> 16) == 0 && (VM_Version::features() & FT_ARMV6T2));
2565   match(ConI);
2566   op_cost(0);
2567 
2568   format %{ %}
2569   interface(CONST_INTER);
2570 %}
2571 
2572 // Integer Immediate: offset for half and double word loads and stores
2573 operand immIHD() %{
2574   predicate(is_memoryHD(n->get_int()));
2575   match(ConI);
2576   op_cost(0);
2577   format %{ %}
2578   interface(CONST_INTER);
2579 %}
2580 
2581 // Integer Immediate: offset for fp loads and stores
2582 operand immIFP() %{
2583   predicate(is_memoryfp(n->get_int()) && ((n->get_int() & 3) == 0));
2584   match(ConI);
2585   op_cost(0);
2586 
2587   format %{ %}
2588   interface(CONST_INTER);
2589 %}
2590 
2591 // Valid scale values for addressing modes and shifts
2592 operand immU5() %{
2593   predicate(0 <= n->get_int() && (n->get_int() <= 31));
2594   match(ConI);
2595   op_cost(0);
2596 
2597   format %{ %}
2598   interface(CONST_INTER);
2599 %}
2600 
2601 // Integer Immediate: 6-bit
2602 operand immU6Big() %{
2603   predicate(n->get_int() >= 32 && n->get_int() <= 63);
2604   match(ConI);
2605   op_cost(0);
2606   format %{ %}
2607   interface(CONST_INTER);
2608 %}
2609 
2610 // Integer Immediate: 0-bit
2611 operand immI0() %{
2612   predicate(n->get_int() == 0);
2613   match(ConI);
2614   op_cost(0);
2615 
2616   format %{ %}
2617   interface(CONST_INTER);
2618 %}
2619 
2620 // Integer Immediate: the value 1
2621 operand immI_1() %{
2622   predicate(n->get_int() == 1);
2623   match(ConI);
2624   op_cost(0);
2625 
2626   format %{ %}
2627   interface(CONST_INTER);
2628 %}
2629 
2630 // Integer Immediate: the value 2
2631 operand immI_2() %{
2632   predicate(n->get_int() == 2);
2633   match(ConI);
2634   op_cost(0);
2635 
2636   format %{ %}
2637   interface(CONST_INTER);
2638 %}
2639 
2640 // Integer Immediate: the value 3
2641 operand immI_3() %{
2642   predicate(n->get_int() == 3);
2643   match(ConI);
2644   op_cost(0);
2645 
2646   format %{ %}
2647   interface(CONST_INTER);
2648 %}
2649 
2650 // Integer Immediate: the value 4
2651 operand immI_4() %{
2652   predicate(n->get_int() == 4);
2653   match(ConI);
2654   op_cost(0);
2655 
2656   format %{ %}
2657   interface(CONST_INTER);
2658 %}
2659 
2660 // Integer Immediate: the value 8
2661 operand immI_8() %{
2662   predicate(n->get_int() == 8);
2663   match(ConI);
2664   op_cost(0);
2665 
2666   format %{ %}
2667   interface(CONST_INTER);
2668 %}
2669 
2670 // Int Immediate non-negative
2671 operand immU31()
2672 %{
2673   predicate(n->get_int() >= 0);
2674   match(ConI);
2675 
2676   op_cost(0);
2677   format %{ %}
2678   interface(CONST_INTER);
2679 %}
2680 
2681 // Integer Immediate: the values 32-63
2682 operand immI_32_63() %{
2683   predicate(n->get_int() >= 32 && n->get_int() <= 63);
2684   match(ConI);
2685   op_cost(0);
2686 
2687   format %{ %}
2688   interface(CONST_INTER);
2689 %}
2690 
2691 // Immediates for special shifts (sign extend)
2692 
2693 // Integer Immediate: the value 16
2694 operand immI_16() %{
2695   predicate(n->get_int() == 16);
2696   match(ConI);
2697   op_cost(0);
2698 
2699   format %{ %}
2700   interface(CONST_INTER);
2701 %}
2702 
2703 // Integer Immediate: the value 24
2704 operand immI_24() %{
2705   predicate(n->get_int() == 24);
2706   match(ConI);
2707   op_cost(0);
2708 
2709   format %{ %}
2710   interface(CONST_INTER);
2711 %}
2712 
2713 // Integer Immediate: the value 255
2714 operand immI_255() %{
2715   predicate( n->get_int() == 255 );
2716   match(ConI);
2717   op_cost(0);
2718 
2719   format %{ %}
2720   interface(CONST_INTER);
2721 %}
2722 
2723 // Integer Immediate: the value 65535
2724 operand immI_65535() %{
2725   predicate(n->get_int() == 65535);
2726   match(ConI);
2727   op_cost(0);
2728 
2729   format %{ %}
2730   interface(CONST_INTER);
2731 %}
2732 
2733 // Integer Immediates for arithmetic instructions
2734 
2735 operand aimmI() %{
2736   predicate(is_aimm(n->get_int()));
2737   match(ConI);
2738   op_cost(0);
2739 
2740   format %{ %}
2741   interface(CONST_INTER);
2742 %}
2743 
2744 operand aimmIneg() %{
2745   predicate(is_aimm(-n->get_int()));
2746   match(ConI);
2747   op_cost(0);
2748 
2749   format %{ %}
2750   interface(CONST_INTER);
2751 %}
2752 
2753 operand aimmU31() %{
2754   predicate((0 <= n->get_int()) && is_aimm(n->get_int()));
2755   match(ConI);
2756   op_cost(0);
2757 
2758   format %{ %}
2759   interface(CONST_INTER);
2760 %}
2761 
2762 // Integer Immediates for logical instructions
2763 
2764 operand limmI() %{
2765   predicate(is_limmI(n->get_int()));
2766   match(ConI);
2767   op_cost(0);
2768 
2769   format %{ %}
2770   interface(CONST_INTER);
2771 %}
2772 
2773 operand limmIlow8() %{
2774   predicate(is_limmI_low(n->get_int(), 8));
2775   match(ConI);
2776   op_cost(0);
2777 
2778   format %{ %}
2779   interface(CONST_INTER);
2780 %}
2781 
2782 operand limmU31() %{
2783   predicate(0 <= n->get_int() && is_limmI(n->get_int()));
2784   match(ConI);
2785   op_cost(0);
2786 
2787   format %{ %}
2788   interface(CONST_INTER);
2789 %}
2790 
2791 operand limmIn() %{
2792   predicate(is_limmI(~n->get_int()));
2793   match(ConI);
2794   op_cost(0);
2795 
2796   format %{ %}
2797   interface(CONST_INTER);
2798 %}
2799 
2800 // Long Immediate: the value FF
2801 operand immL_FF() %{
2802   predicate( n->get_long() == 0xFFL );
2803   match(ConL);
2804   op_cost(0);
2805 
2806   format %{ %}
2807   interface(CONST_INTER);
2808 %}
2809 
2810 // Long Immediate: the value FFFF
2811 operand immL_FFFF() %{
2812   predicate( n->get_long() == 0xFFFFL );
2813   match(ConL);
2814   op_cost(0);
2815 
2816   format %{ %}
2817   interface(CONST_INTER);
2818 %}
2819 
2820 // Pointer Immediate: 32 or 64-bit
2821 operand immP() %{
2822   match(ConP);
2823 
2824   op_cost(5);
2825   // formats are generated automatically for constants and base registers
2826   format %{ %}
2827   interface(CONST_INTER);
2828 %}
2829 
2830 operand immP0() %{
2831   predicate(n->get_ptr() == 0);
2832   match(ConP);
2833   op_cost(0);
2834 
2835   format %{ %}
2836   interface(CONST_INTER);
2837 %}
2838 
2839 operand immP_poll() %{
2840   predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
2841   match(ConP);
2842 
2843   // formats are generated automatically for constants and base registers
2844   format %{ %}
2845   interface(CONST_INTER);
2846 %}
2847 
2848 // Pointer Immediate
2849 operand immN()
2850 %{
2851   match(ConN);
2852 
2853   op_cost(10);
2854   format %{ %}
2855   interface(CONST_INTER);
2856 %}
2857 
2858 operand immNKlass()
2859 %{
2860   match(ConNKlass);
2861 
2862   op_cost(10);
2863   format %{ %}
2864   interface(CONST_INTER);
2865 %}
2866 
2867 // NULL Pointer Immediate
2868 operand immN0()
2869 %{
2870   predicate(n->get_narrowcon() == 0);
2871   match(ConN);
2872 
2873   op_cost(0);
2874   format %{ %}
2875   interface(CONST_INTER);
2876 %}
2877 
2878 operand immL() %{
2879   match(ConL);
2880   op_cost(40);
2881   // formats are generated automatically for constants and base registers
2882   format %{ %}
2883   interface(CONST_INTER);
2884 %}
2885 
2886 operand immL0() %{
2887   predicate(n->get_long() == 0L);
2888   match(ConL);
2889   op_cost(0);
2890   // formats are generated automatically for constants and base registers
2891   format %{ %}
2892   interface(CONST_INTER);
2893 %}
2894 
2895 // Long Immediate: 16-bit
2896 operand immL16() %{
2897   predicate(n->get_long() >= 0 && n->get_long() < (1<<16)  && (VM_Version::features() & FT_ARMV6T2));
2898   match(ConL);
2899   op_cost(0);
2900 
2901   format %{ %}
2902   interface(CONST_INTER);
2903 %}
2904 
2905 // Long Immediate: low 32-bit mask
2906 operand immL_32bits() %{
2907   predicate(n->get_long() == 0xFFFFFFFFL);
2908   match(ConL);
2909   op_cost(0);
2910 
2911   format %{ %}
2912   interface(CONST_INTER);
2913 %}
2914 
2915 // Double Immediate
2916 operand immD() %{
2917   match(ConD);
2918 
2919   op_cost(40);
2920   format %{ %}
2921   interface(CONST_INTER);
2922 %}
2923 
2924 // Double Immediate: +0.0d.
2925 operand immD0() %{
2926   predicate(jlong_cast(n->getd()) == 0);
2927 
2928   match(ConD);
2929   op_cost(0);
2930   format %{ %}
2931   interface(CONST_INTER);
2932 %}
2933 
2934 operand imm8D() %{
2935   predicate(Assembler::operand_valid_for_double_immediate(n->getd()));
2936   match(ConD);
2937 
2938   op_cost(0);
2939   format %{ %}
2940   interface(CONST_INTER);
2941 %}
2942 
2943 // Float Immediate
2944 operand immF() %{
2945   match(ConF);
2946 
2947   op_cost(20);
2948   format %{ %}
2949   interface(CONST_INTER);
2950 %}
2951 
2952 // Float Immediate: +0.0f
2953 operand immF0() %{
2954   predicate(jint_cast(n->getf()) == 0);
2955   match(ConF);
2956 
2957   op_cost(0);
2958   format %{ %}
2959   interface(CONST_INTER);
2960 %}
2961 
2962 // Float Immediate: encoded as 8 bits
2963 operand imm8F() %{
2964   predicate(Assembler::operand_valid_for_float_immediate(n->getf()));
2965   match(ConF);
2966 
2967   op_cost(0);
2968   format %{ %}
2969   interface(CONST_INTER);
2970 %}
2971 
2972 // Integer Register Operands
2973 // Integer Register
2974 operand iRegI() %{
2975   constraint(ALLOC_IN_RC(int_reg));
2976   match(RegI);
2977   match(R0RegI);
2978   match(R1RegI);
2979   match(R2RegI);
2980   match(R3RegI);
2981   match(R12RegI);
2982 
2983   format %{ %}
2984   interface(REG_INTER);
2985 %}
2986 
2987 // Pointer Register
2988 operand iRegP() %{
2989   constraint(ALLOC_IN_RC(ptr_reg));
2990   match(RegP);
2991   match(R0RegP);
2992   match(R1RegP);
2993   match(R2RegP);
2994   match(RExceptionRegP);
2995   match(RmethodRegP); // R8
2996   match(R9RegP);
2997   match(RthreadRegP); // R10, TODO Oracle FIXME: move to sp_ptr_RegP?
2998   match(R12RegP);
2999   match(LRRegP);
3000 
3001   match(sp_ptr_RegP);
3002   match(store_ptr_RegP);
3003 
3004   format %{ %}
3005   interface(REG_INTER);
3006 %}
3007 
3008 // GPRs + Rmethod + Rthread + SP
3009 operand sp_ptr_RegP() %{
3010   constraint(ALLOC_IN_RC(sp_ptr_reg));
3011   match(RegP);
3012   match(iRegP);
3013   match(SPRegP); // FIXME: check cost
3014 
3015   format %{ %}
3016   interface(REG_INTER);
3017 %}
3018 
3019 operand R0RegP() %{
3020   constraint(ALLOC_IN_RC(R0_regP));
3021   match(iRegP);
3022 
3023   format %{ %}
3024   interface(REG_INTER);
3025 %}
3026 
3027 operand R1RegP() %{
3028   constraint(ALLOC_IN_RC(R1_regP));
3029   match(iRegP);
3030 
3031   format %{ %}
3032   interface(REG_INTER);
3033 %}
3034 
3035 operand R2RegP() %{
3036   constraint(ALLOC_IN_RC(R2_regP));
3037   match(iRegP);
3038 
3039   format %{ %}
3040   interface(REG_INTER);
3041 %}
3042 
3043 operand RExceptionRegP() %{
3044   constraint(ALLOC_IN_RC(Rexception_regP));
3045   match(iRegP);
3046 
3047   format %{ %}
3048   interface(REG_INTER);
3049 %}
3050 
3051 operand RthreadRegP() %{
3052   constraint(ALLOC_IN_RC(Rthread_regP));
3053   match(iRegP);
3054 
3055   format %{ %}
3056   interface(REG_INTER);
3057 %}
3058 
3059 operand RmethodRegP() %{
3060   constraint(ALLOC_IN_RC(Rmethod_regP));
3061   match(iRegP);
3062 
3063   format %{ %}
3064   interface(REG_INTER);
3065 %}
3066 
3067 operand IPRegP() %{
3068   constraint(ALLOC_IN_RC(IP_regP));
3069   match(iRegP);
3070 
3071   format %{ %}
3072   interface(REG_INTER);
3073 %}
3074 
3075 operand LRRegP() %{
3076   constraint(ALLOC_IN_RC(LR_regP));
3077   match(iRegP);
3078 
3079   format %{ %}
3080   interface(REG_INTER);
3081 %}
3082 
3083 operand R0RegI() %{
3084   constraint(ALLOC_IN_RC(R0_regI));
3085   match(iRegI);
3086 
3087   format %{ %}
3088   interface(REG_INTER);
3089 %}
3090 
3091 operand R1RegI() %{
3092   constraint(ALLOC_IN_RC(R1_regI));
3093   match(iRegI);
3094 
3095   format %{ %}
3096   interface(REG_INTER);
3097 %}
3098 
3099 operand R2RegI() %{
3100   constraint(ALLOC_IN_RC(R2_regI));
3101   match(iRegI);
3102 
3103   format %{ %}
3104   interface(REG_INTER);
3105 %}
3106 
3107 operand R3RegI() %{
3108   constraint(ALLOC_IN_RC(R3_regI));
3109   match(iRegI);
3110 
3111   format %{ %}
3112   interface(REG_INTER);
3113 %}
3114 
3115 operand R9RegI() %{
3116   constraint(ALLOC_IN_RC(R9_regI));
3117   match(iRegI);
3118 
3119   format %{ %}
3120   interface(REG_INTER);
3121 %}
3122 
3123 operand R12RegI() %{
3124   constraint(ALLOC_IN_RC(R12_regI));
3125   match(iRegI);
3126 
3127   format %{ %}
3128   interface(REG_INTER);
3129 %}
3130 
3131 // Long Register
3132 operand iRegL() %{
3133   constraint(ALLOC_IN_RC(long_reg));
3134   match(RegL);
3135   match(R0R1RegL);
3136   match(R2R3RegL);
3137 
3138   format %{ %}
3139   interface(REG_INTER);
3140 %}
3141 
3142 operand iRegLd() %{
3143   constraint(ALLOC_IN_RC(long_reg_align));
3144   match(iRegL); // FIXME: allows unaligned R11/R12?
3145 
3146   format %{ %}
3147   interface(REG_INTER);
3148 %}
3149 
3150 // first long arg, or return value
3151 operand R0R1RegL() %{
3152   constraint(ALLOC_IN_RC(R0R1_regL));
3153   match(iRegL);
3154 
3155   format %{ %}
3156   interface(REG_INTER);
3157 %}
3158 
3159 operand R2R3RegL() %{
3160   constraint(ALLOC_IN_RC(R2R3_regL));
3161   match(iRegL);
3162 
3163   format %{ %}
3164   interface(REG_INTER);
3165 %}
3166 
3167 // Condition Code Flag Register
3168 operand flagsReg() %{
3169   constraint(ALLOC_IN_RC(int_flags));
3170   match(RegFlags);
3171 
3172   format %{ "apsr" %}
3173   interface(REG_INTER);
3174 %}
3175 
3176 // Result of compare to 0 (TST)
3177 operand flagsReg_EQNELTGE() %{
3178   constraint(ALLOC_IN_RC(int_flags));
3179   match(RegFlags);
3180 
3181   format %{ "apsr_EQNELTGE" %}
3182   interface(REG_INTER);
3183 %}
3184 
3185 // Condition Code Register, unsigned comparisons.
3186 operand flagsRegU() %{
3187   constraint(ALLOC_IN_RC(int_flags));
3188   match(RegFlags);
3189 #ifdef TODO
3190   match(RegFlagsP);
3191 #endif
3192 
3193   format %{ "apsr_U" %}
3194   interface(REG_INTER);
3195 %}
3196 
3197 // Condition Code Register, pointer comparisons.
3198 operand flagsRegP() %{
3199   constraint(ALLOC_IN_RC(int_flags));
3200   match(RegFlags);
3201 
3202   format %{ "apsr_P" %}
3203   interface(REG_INTER);
3204 %}
3205 
3206 // Condition Code Register, long comparisons.
3207 operand flagsRegL_LTGE() %{
3208   constraint(ALLOC_IN_RC(int_flags));
3209   match(RegFlags);
3210 
3211   format %{ "apsr_L_LTGE" %}
3212   interface(REG_INTER);
3213 %}
3214 
3215 operand flagsRegUL() %{
3216   constraint(ALLOC_IN_RC(int_flags));
3217   match(RegFlags);
3218 
3219   format %{ "apsr_UL" %}
3220   interface(REG_INTER);
3221 %}
3222 
3223 operand flagsRegL_EQNE() %{
3224   constraint(ALLOC_IN_RC(int_flags));
3225   match(RegFlags);
3226 
3227   format %{ "apsr_L_EQNE" %}
3228   interface(REG_INTER);
3229 %}
3230 
3231 operand flagsRegL_LEGT() %{
3232   constraint(ALLOC_IN_RC(int_flags));
3233   match(RegFlags);
3234 
3235   format %{ "apsr_L_LEGT" %}
3236   interface(REG_INTER);
3237 %}
3238 
3239 // Condition Code Register, floating comparisons, unordered same as "less".
3240 operand flagsRegF() %{
3241   constraint(ALLOC_IN_RC(float_flags));
3242   match(RegFlags);
3243 
3244   format %{ "fpscr_F" %}
3245   interface(REG_INTER);
3246 %}
3247 
3248 // Vectors
3249 operand vecD() %{
3250   constraint(ALLOC_IN_RC(actual_dflt_reg));
3251   match(VecD);
3252 
3253   format %{ %}
3254   interface(REG_INTER);
3255 %}
3256 
3257 operand vecX() %{
3258   constraint(ALLOC_IN_RC(vectorx_reg));
3259   match(VecX);
3260 
3261   format %{ %}
3262   interface(REG_INTER);
3263 %}
3264 
3265 operand regD() %{
3266   constraint(ALLOC_IN_RC(actual_dflt_reg));
3267   match(RegD);
3268   match(regD_low);
3269 
3270   format %{ %}
3271   interface(REG_INTER);
3272 %}
3273 
3274 operand Q0_regD() %{
3275   constraint(ALLOC_IN_RC(D0D1_regD));
3276   match(RegD);
3277   match(regD_low);
3278 
3279   format %{ %}
3280   interface(REG_INTER);
3281 %}
3282 
3283 operand Q1_regD() %{
3284   constraint(ALLOC_IN_RC(D2D3_regD));
3285   match(RegD);
3286   match(regD_low);
3287 
3288   format %{ %}
3289   interface(REG_INTER);
3290 %}
3291 
3292 operand regF() %{
3293   constraint(ALLOC_IN_RC(sflt_reg));
3294   match(RegF);
3295 
3296   format %{ %}
3297   interface(REG_INTER);
3298 %}
3299 
3300 operand regD_low() %{
3301   constraint(ALLOC_IN_RC(dflt_low_reg));
3302   match(RegD);
3303 
3304   format %{ %}
3305   interface(REG_INTER);
3306 %}
3307 
3308 // Special Registers
3309 
3310 // Method Register
3311 operand inline_cache_regP(iRegP reg) %{
3312   constraint(ALLOC_IN_RC(Ricklass_regP));
3313   match(reg);
3314   format %{ %}
3315   interface(REG_INTER);
3316 %}
3317 
3318 operand interpreter_method_oop_regP(iRegP reg) %{
3319   constraint(ALLOC_IN_RC(Rmethod_regP));
3320   match(reg);
3321   format %{ %}
3322   interface(REG_INTER);
3323 %}
3324 
3325 
3326 //----------Complex Operands---------------------------------------------------
3327 // Indirect Memory Reference
3328 operand indirect(sp_ptr_RegP reg) %{
3329   constraint(ALLOC_IN_RC(sp_ptr_reg));
3330   match(reg);
3331 
3332   op_cost(100);
3333   format %{ "[$reg]" %}
3334   interface(MEMORY_INTER) %{
3335     base($reg);
3336     index(0xf); // PC => no index
3337     scale(0x0);
3338     disp(0x0);
3339   %}
3340 %}
3341 
3342 // Indirect with Offset in ]-4096, 4096[
3343 operand indOffset12(sp_ptr_RegP reg, immI12 offset) %{
3344   constraint(ALLOC_IN_RC(sp_ptr_reg));
3345   match(AddP reg offset);
3346 
3347   op_cost(100);
3348   format %{ "[$reg + $offset]" %}
3349   interface(MEMORY_INTER) %{
3350     base($reg);
3351     index(0xf); // PC => no index
3352     scale(0x0);
3353     disp($offset);
3354   %}
3355 %}
3356 
3357 // Indirect with offset for float load/store
3358 operand indOffsetFP(sp_ptr_RegP reg, immIFP offset) %{
3359   constraint(ALLOC_IN_RC(sp_ptr_reg));
3360   match(AddP reg offset);
3361 
3362   op_cost(100);
3363   format %{ "[$reg + $offset]" %}
3364   interface(MEMORY_INTER) %{
3365     base($reg);
3366     index(0xf); // PC => no index
3367     scale(0x0);
3368     disp($offset);
3369   %}
3370 %}
3371 
3372 // Indirect with Offset for half and double words
3373 operand indOffsetHD(sp_ptr_RegP reg, immIHD offset) %{
3374   constraint(ALLOC_IN_RC(sp_ptr_reg));
3375   match(AddP reg offset);
3376 
3377   op_cost(100);
3378   format %{ "[$reg + $offset]" %}
3379   interface(MEMORY_INTER) %{
3380     base($reg);
3381     index(0xf); // PC => no index
3382     scale(0x0);
3383     disp($offset);
3384   %}
3385 %}
3386 
3387 // Indirect with Offset and Offset+4 in ]-1024, 1024[
3388 operand indOffsetFPx2(sp_ptr_RegP reg, immX10x2 offset) %{
3389   constraint(ALLOC_IN_RC(sp_ptr_reg));
3390   match(AddP reg offset);
3391 
3392   op_cost(100);
3393   format %{ "[$reg + $offset]" %}
3394   interface(MEMORY_INTER) %{
3395     base($reg);
3396     index(0xf); // PC => no index
3397     scale(0x0);
3398     disp($offset);
3399   %}
3400 %}
3401 
3402 // Indirect with Offset and Offset+4 in ]-4096, 4096[
3403 operand indOffset12x2(sp_ptr_RegP reg, immI12x2 offset) %{
3404   constraint(ALLOC_IN_RC(sp_ptr_reg));
3405   match(AddP reg offset);
3406 
3407   op_cost(100);
3408   format %{ "[$reg + $offset]" %}
3409   interface(MEMORY_INTER) %{
3410     base($reg);
3411     index(0xf); // PC => no index
3412     scale(0x0);
3413     disp($offset);
3414   %}
3415 %}
3416 
3417 // Indirect with Register Index
3418 operand indIndex(iRegP addr, iRegX index) %{
3419   constraint(ALLOC_IN_RC(ptr_reg));
3420   match(AddP addr index);
3421 
3422   op_cost(100);
3423   format %{ "[$addr + $index]" %}
3424   interface(MEMORY_INTER) %{
3425     base($addr);
3426     index($index);
3427     scale(0x0);
3428     disp(0x0);
3429   %}
3430 %}
3431 
3432 // Indirect Memory Times Scale Plus Index Register
3433 operand indIndexScale(iRegP addr, iRegX index, immU5 scale) %{
3434   constraint(ALLOC_IN_RC(ptr_reg));
3435   match(AddP addr (LShiftX index scale));
3436 
3437   op_cost(100);
3438   format %{"[$addr + $index << $scale]" %}
3439   interface(MEMORY_INTER) %{
3440     base($addr);
3441     index($index);
3442     scale($scale);
3443     disp(0x0);
3444   %}
3445 %}
3446 
3447 // Operands for expressing Control Flow
3448 // NOTE:  Label is a predefined operand which should not be redefined in
3449 //        the AD file.  It is generically handled within the ADLC.
3450 
3451 //----------Conditional Branch Operands----------------------------------------
3452 // Comparison Op  - This is the operation of the comparison, and is limited to
3453 //                  the following set of codes:
3454 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
3455 //
3456 // Other attributes of the comparison, such as unsignedness, are specified
3457 // by the comparison instruction that sets a condition code flags register.
3458 // That result is represented by a flags operand whose subtype is appropriate
3459 // to the unsignedness (etc.) of the comparison.
3460 //
3461 // Later, the instruction which matches both the Comparison Op (a Bool) and
3462 // the flags (produced by the Cmp) specifies the coding of the comparison op
3463 // by matching a specific subtype of Bool operand below, such as cmpOpU.
3464 
3465 operand cmpOp() %{
3466   match(Bool);
3467 
3468   format %{ "" %}
3469   interface(COND_INTER) %{
3470     equal(0x0);
3471     not_equal(0x1);
3472     less(0xb);
3473     greater_equal(0xa);
3474     less_equal(0xd);
3475     greater(0xc);
3476     overflow(0x0); // unsupported/unimplemented
3477     no_overflow(0x0); // unsupported/unimplemented
3478   %}
3479 %}
3480 
3481 // integer comparison with 0, signed
3482 operand cmpOp0() %{
3483   match(Bool);
3484 
3485   format %{ "" %}
3486   interface(COND_INTER) %{
3487     equal(0x0);
3488     not_equal(0x1);
3489     less(0x4);
3490     greater_equal(0x5);
3491     less_equal(0xd); // unsupported
3492     greater(0xc); // unsupported
3493     overflow(0x0); // unsupported/unimplemented
3494     no_overflow(0x0); // unsupported/unimplemented
3495   %}
3496 %}
3497 
3498 // Comparison Op, unsigned
3499 operand cmpOpU() %{
3500   match(Bool);
3501 
3502   format %{ "u" %}
3503   interface(COND_INTER) %{
3504     equal(0x0);
3505     not_equal(0x1);
3506     less(0x3);
3507     greater_equal(0x2);
3508     less_equal(0x9);
3509     greater(0x8);
3510     overflow(0x0); // unsupported/unimplemented
3511     no_overflow(0x0); // unsupported/unimplemented
3512   %}
3513 %}
3514 
3515 // Comparison Op, pointer (same as unsigned)
3516 operand cmpOpP() %{
3517   match(Bool);
3518 
3519   format %{ "p" %}
3520   interface(COND_INTER) %{
3521     equal(0x0);
3522     not_equal(0x1);
3523     less(0x3);
3524     greater_equal(0x2);
3525     less_equal(0x9);
3526     greater(0x8);
3527     overflow(0x0); // unsupported/unimplemented
3528     no_overflow(0x0); // unsupported/unimplemented
3529   %}
3530 %}
3531 
3532 operand cmpOpL() %{
3533   match(Bool);
3534 
3535   format %{ "L" %}
3536   interface(COND_INTER) %{
3537     equal(0x0);
3538     not_equal(0x1);
3539     less(0xb);
3540     greater_equal(0xa);
3541     less_equal(0xd);
3542     greater(0xc);
3543     overflow(0x0); // unsupported/unimplemented
3544     no_overflow(0x0); // unsupported/unimplemented
3545   %}
3546 %}
3547 
3548 operand cmpOpL_commute() %{
3549   match(Bool);
3550 
3551   format %{ "L" %}
3552   interface(COND_INTER) %{
3553     equal(0x0);
3554     not_equal(0x1);
3555     less(0xc);
3556     greater_equal(0xd);
3557     less_equal(0xa);
3558     greater(0xb);
3559     overflow(0x0); // unsupported/unimplemented
3560     no_overflow(0x0); // unsupported/unimplemented
3561   %}
3562 %}
3563 
3564 //----------OPERAND CLASSES----------------------------------------------------
3565 // Operand Classes are groups of operands that are used to simplify
3566 // instruction definitions by not requiring the AD writer to specify separate
3567 // instructions for every form of operand when the instruction accepts
3568 // multiple operand types with the same basic encoding and format.  The classic
3569 // case of this is memory operands.
3570 opclass memoryI ( indirect, indOffset12, indIndex, indIndexScale );
3571 opclass memoryP ( indirect, indOffset12, indIndex, indIndexScale );
3572 opclass memoryF ( indirect, indOffsetFP );
3573 opclass memoryF2 ( indirect, indOffsetFPx2 );
3574 opclass memoryD ( indirect, indOffsetFP );
3575 opclass memoryfp( indirect, indOffsetFP );
3576 opclass memoryB ( indirect, indIndex, indOffsetHD );
3577 opclass memoryS ( indirect, indIndex, indOffsetHD );
3578 opclass memoryL ( indirect, indIndex, indOffsetHD );
3579 
3580 opclass memoryScaledI(indIndexScale);
3581 opclass memoryScaledP(indIndexScale);
3582 
3583 // when ldrex/strex is used:
3584 opclass memoryex ( indirect );
3585 opclass indIndexMemory( indIndex );
3586 opclass memorylong ( indirect, indOffset12x2 );
3587 opclass memoryvld ( indirect /* , write back mode not implemented */ );
3588 
3589 //----------PIPELINE-----------------------------------------------------------
3590 pipeline %{
3591 
3592 //----------ATTRIBUTES---------------------------------------------------------
3593 attributes %{
3594   fixed_size_instructions;           // Fixed size instructions
3595   max_instructions_per_bundle = 4;   // Up to 4 instructions per bundle
3596   instruction_unit_size = 4;         // An instruction is 4 bytes long
3597   instruction_fetch_unit_size = 16;  // The processor fetches one line
3598   instruction_fetch_units = 1;       // of 16 bytes
3599 
3600   // List of nop instructions
3601   nops( Nop_A0, Nop_A1, Nop_MS, Nop_FA, Nop_BR );
3602 %}
3603 
3604 //----------RESOURCES----------------------------------------------------------
3605 // Resources are the functional units available to the machine
3606 resources(A0, A1, MS, BR, FA, FM, IDIV, FDIV, IALU = A0 | A1);
3607 
3608 //----------PIPELINE DESCRIPTION-----------------------------------------------
3609 // Pipeline Description specifies the stages in the machine's pipeline
3610 
3611 pipe_desc(A, P, F, B, I, J, S, R, E, C, M, W, X, T, D);
3612 
3613 //----------PIPELINE CLASSES---------------------------------------------------
3614 // Pipeline Classes describe the stages in which input and output are
3615 // referenced by the hardware pipeline.
3616 
3617 // Integer ALU reg-reg operation
3618 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
3619     single_instruction;
3620     dst   : E(write);
3621     src1  : R(read);
3622     src2  : R(read);
3623     IALU  : R;
3624 %}
3625 
3626 // Integer ALU reg-reg long operation
3627 pipe_class ialu_reg_reg_2(iRegL dst, iRegL src1, iRegL src2) %{
3628     instruction_count(2);
3629     dst   : E(write);
3630     src1  : R(read);
3631     src2  : R(read);
3632     IALU  : R;
3633     IALU  : R;
3634 %}
3635 
3636 // Integer ALU reg-reg long dependent operation
3637 pipe_class ialu_reg_reg_2_dep(iRegL dst, iRegL src1, iRegL src2, flagsReg cr) %{
3638     instruction_count(1); multiple_bundles;
3639     dst   : E(write);
3640     src1  : R(read);
3641     src2  : R(read);
3642     cr    : E(write);
3643     IALU  : R(2);
3644 %}
3645 
3646 // Integer ALU reg-imm operaion
3647 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) %{
3648     single_instruction;
3649     dst   : E(write);
3650     src1  : R(read);
3651     IALU  : R;
3652 %}
3653 
3654 // Integer ALU reg-reg operation with condition code
3655 pipe_class ialu_cc_reg_reg(iRegI dst, iRegI src1, iRegI src2, flagsReg cr) %{
3656     single_instruction;
3657     dst   : E(write);
3658     cr    : E(write);
3659     src1  : R(read);
3660     src2  : R(read);
3661     IALU  : R;
3662 %}
3663 
3664 // Integer ALU zero-reg operation
3665 pipe_class ialu_zero_reg(iRegI dst, immI0 zero, iRegI src2) %{
3666     single_instruction;
3667     dst   : E(write);
3668     src2  : R(read);
3669     IALU  : R;
3670 %}
3671 
3672 // Integer ALU zero-reg operation with condition code only
3673 pipe_class ialu_cconly_zero_reg(flagsReg cr, iRegI src) %{
3674     single_instruction;
3675     cr    : E(write);
3676     src   : R(read);
3677     IALU  : R;
3678 %}
3679 
3680 // Integer ALU reg-reg operation with condition code only
3681 pipe_class ialu_cconly_reg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
3682     single_instruction;
3683     cr    : E(write);
3684     src1  : R(read);
3685     src2  : R(read);
3686     IALU  : R;
3687 %}
3688 
3689 // Integer ALU reg-imm operation with condition code only
3690 pipe_class ialu_cconly_reg_imm(flagsReg cr, iRegI src1) %{
3691     single_instruction;
3692     cr    : E(write);
3693     src1  : R(read);
3694     IALU  : R;
3695 %}
3696 
3697 // Integer ALU reg-reg-zero operation with condition code only
3698 pipe_class ialu_cconly_reg_reg_zero(flagsReg cr, iRegI src1, iRegI src2, immI0 zero) %{
3699     single_instruction;
3700     cr    : E(write);
3701     src1  : R(read);
3702     src2  : R(read);
3703     IALU  : R;
3704 %}
3705 
3706 // Integer ALU reg-imm-zero operation with condition code only
3707 pipe_class ialu_cconly_reg_imm_zero(flagsReg cr, iRegI src1, immI0 zero) %{
3708     single_instruction;
3709     cr    : E(write);
3710     src1  : R(read);
3711     IALU  : R;
3712 %}
3713 
3714 // Integer ALU reg-reg operation with condition code, src1 modified
3715 pipe_class ialu_cc_rwreg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
3716     single_instruction;
3717     cr    : E(write);
3718     src1  : E(write);
3719     src1  : R(read);
3720     src2  : R(read);
3721     IALU  : R;
3722 %}
3723 
3724 pipe_class cmpL_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg cr ) %{
3725     multiple_bundles;
3726     dst   : E(write)+4;
3727     cr    : E(write);
3728     src1  : R(read);
3729     src2  : R(read);
3730     IALU  : R(3);
3731     BR    : R(2);
3732 %}
3733 
3734 // Integer ALU operation
3735 pipe_class ialu_none(iRegI dst) %{
3736     single_instruction;
3737     dst   : E(write);
3738     IALU  : R;
3739 %}
3740 
3741 // Integer ALU reg operation
3742 pipe_class ialu_reg(iRegI dst, iRegI src) %{
3743     single_instruction; may_have_no_code;
3744     dst   : E(write);
3745     src   : R(read);
3746     IALU  : R;
3747 %}
3748 
3749 // Integer ALU reg conditional operation
3750 // This instruction has a 1 cycle stall, and cannot execute
3751 // in the same cycle as the instruction setting the condition
3752 // code. We kludge this by pretending to read the condition code
3753 // 1 cycle earlier, and by marking the functional units as busy
3754 // for 2 cycles with the result available 1 cycle later than
3755 // is really the case.
3756 pipe_class ialu_reg_flags( iRegI op2_out, iRegI op2_in, iRegI op1, flagsReg cr ) %{
3757     single_instruction;
3758     op2_out : C(write);
3759     op1     : R(read);
3760     cr      : R(read);       // This is really E, with a 1 cycle stall
3761     BR      : R(2);
3762     MS      : R(2);
3763 %}
3764 
3765 // Integer ALU reg operation
3766 pipe_class ialu_move_reg_L_to_I(iRegI dst, iRegL src) %{
3767     single_instruction; may_have_no_code;
3768     dst   : E(write);
3769     src   : R(read);
3770     IALU  : R;
3771 %}
3772 pipe_class ialu_move_reg_I_to_L(iRegL dst, iRegI src) %{
3773     single_instruction; may_have_no_code;
3774     dst   : E(write);
3775     src   : R(read);
3776     IALU  : R;
3777 %}
3778 
3779 // Two integer ALU reg operations
3780 pipe_class ialu_reg_2(iRegL dst, iRegL src) %{
3781     instruction_count(2);
3782     dst   : E(write);
3783     src   : R(read);
3784     A0    : R;
3785     A1    : R;
3786 %}
3787 
3788 // Two integer ALU reg operations
3789 pipe_class ialu_move_reg_L_to_L(iRegL dst, iRegL src) %{
3790     instruction_count(2); may_have_no_code;
3791     dst   : E(write);
3792     src   : R(read);
3793     A0    : R;
3794     A1    : R;
3795 %}
3796 
3797 // Integer ALU imm operation
3798 pipe_class ialu_imm(iRegI dst) %{
3799     single_instruction;
3800     dst   : E(write);
3801     IALU  : R;
3802 %}
3803 
3804 pipe_class ialu_imm_n(iRegI dst) %{
3805     single_instruction;
3806     dst   : E(write);
3807     IALU  : R;
3808 %}
3809 
3810 // Integer ALU reg-reg with carry operation
3811 pipe_class ialu_reg_reg_cy(iRegI dst, iRegI src1, iRegI src2, iRegI cy) %{
3812     single_instruction;
3813     dst   : E(write);
3814     src1  : R(read);
3815     src2  : R(read);
3816     IALU  : R;
3817 %}
3818 
3819 // Integer ALU cc operation
3820 pipe_class ialu_cc(iRegI dst, flagsReg cc) %{
3821     single_instruction;
3822     dst   : E(write);
3823     cc    : R(read);
3824     IALU  : R;
3825 %}
3826 
3827 // Integer ALU cc / second IALU operation
3828 pipe_class ialu_reg_ialu( iRegI dst, iRegI src ) %{
3829     instruction_count(1); multiple_bundles;
3830     dst   : E(write)+1;
3831     src   : R(read);
3832     IALU  : R;
3833 %}
3834 
3835 // Integer ALU cc / second IALU operation
3836 pipe_class ialu_reg_reg_ialu( iRegI dst, iRegI p, iRegI q ) %{
3837     instruction_count(1); multiple_bundles;
3838     dst   : E(write)+1;
3839     p     : R(read);
3840     q     : R(read);
3841     IALU  : R;
3842 %}
3843 
3844 // Integer ALU hi-lo-reg operation
3845 pipe_class ialu_hi_lo_reg(iRegI dst, immI src) %{
3846     instruction_count(1); multiple_bundles;
3847     dst   : E(write)+1;
3848     IALU  : R(2);
3849 %}
3850 
3851 // Long Constant
3852 pipe_class loadConL( iRegL dst, immL src ) %{
3853     instruction_count(2); multiple_bundles;
3854     dst   : E(write)+1;
3855     IALU  : R(2);
3856     IALU  : R(2);
3857 %}
3858 
3859 // Pointer Constant
3860 pipe_class loadConP( iRegP dst, immP src ) %{
3861     instruction_count(0); multiple_bundles;
3862     fixed_latency(6);
3863 %}
3864 
3865 // Polling Address
3866 pipe_class loadConP_poll( iRegP dst, immP_poll src ) %{
3867     dst   : E(write);
3868     IALU  : R;
3869 %}
3870 
3871 // Long Constant small
3872 pipe_class loadConLlo( iRegL dst, immL src ) %{
3873     instruction_count(2);
3874     dst   : E(write);
3875     IALU  : R;
3876     IALU  : R;
3877 %}
3878 
3879 // [PHH] This is wrong for 64-bit.  See LdImmF/D.
3880 pipe_class loadConFD(regF dst, immF src, iRegP tmp) %{
3881     instruction_count(1); multiple_bundles;
3882     src   : R(read);
3883     dst   : M(write)+1;
3884     IALU  : R;
3885     MS    : E;
3886 %}
3887 
3888 // Integer ALU nop operation
3889 pipe_class ialu_nop() %{
3890     single_instruction;
3891     IALU  : R;
3892 %}
3893 
3894 // Integer ALU nop operation
3895 pipe_class ialu_nop_A0() %{
3896     single_instruction;
3897     A0    : R;
3898 %}
3899 
3900 // Integer ALU nop operation
3901 pipe_class ialu_nop_A1() %{
3902     single_instruction;
3903     A1    : R;
3904 %}
3905 
3906 // Integer Multiply reg-reg operation
3907 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
3908     single_instruction;
3909     dst   : E(write);
3910     src1  : R(read);
3911     src2  : R(read);
3912     MS    : R(5);
3913 %}
3914 
3915 pipe_class mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
3916     single_instruction;
3917     dst   : E(write)+4;
3918     src1  : R(read);
3919     src2  : R(read);
3920     MS    : R(6);
3921 %}
3922 
3923 // Integer Divide reg-reg
3924 pipe_class sdiv_reg_reg_IDIV(iRegI dst, iRegI src1, iRegI src2, iRegI temp, flagsReg cr) %{
3925     single_instruction;
3926     dst   : E(write);
3927     temp  : E(write);
3928     src1  : R(read);
3929     src2  : R(read);
3930     temp  : R(read);
3931     MS    : R(10);
3932 %}
3933 
3934 pipe_class sdiv_reg_reg_SW(iRegI dst, iRegI src1, iRegI src2, iRegI temp1, iRegI temp2, flagsReg cr) %{
3935     instruction_count(1); multiple_bundles;
3936     dst   : E(write);
3937     temp1 : E(write);
3938     temp2 : E(write);
3939     src1  : R(read);
3940     src2  : R(read);
3941     temp1 : R(read);
3942     temp2 : R(read);
3943     MS    : R(38);
3944 %}
3945 
3946 // Long Divide
3947 pipe_class divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
3948     dst  : E(write)+71;
3949     src1 : R(read);
3950     src2 : R(read)+1;
3951     MS   : R(70);
3952 %}
3953 
3954 // Floating Point Add Float
3955 pipe_class faddF_reg_reg(regF dst, regF src1, regF src2) %{
3956     single_instruction;
3957     dst   : X(write);
3958     src1  : E(read);
3959     src2  : E(read);
3960     FA    : R;
3961 %}
3962 
3963 // Floating Point Add Double
3964 pipe_class faddD_reg_reg(regD dst, regD src1, regD src2) %{
3965     single_instruction;
3966     dst   : X(write);
3967     src1  : E(read);
3968     src2  : E(read);
3969     FA    : R;
3970 %}
3971 
3972 // Floating Point Conditional Move based on integer flags
3973 pipe_class int_conditional_float_move (cmpOp cmp, flagsReg cr, regF dst, regF src) %{
3974     single_instruction;
3975     dst   : X(write);
3976     src   : E(read);
3977     cr    : R(read);
3978     FA    : R(2);
3979     BR    : R(2);
3980 %}
3981 
3982 // Floating Point Conditional Move based on integer flags
3983 pipe_class int_conditional_double_move (cmpOp cmp, flagsReg cr, regD dst, regD src) %{
3984     single_instruction;
3985     dst   : X(write);
3986     src   : E(read);
3987     cr    : R(read);
3988     FA    : R(2);
3989     BR    : R(2);
3990 %}
3991 
3992 // Floating Point Multiply Float
3993 pipe_class fmulF_reg_reg(regF dst, regF src1, regF src2) %{
3994     single_instruction;
3995     dst   : X(write);
3996     src1  : E(read);
3997     src2  : E(read);
3998     FM    : R;
3999 %}
4000 
4001 // Floating Point Multiply Double
4002 pipe_class fmulD_reg_reg(regD dst, regD src1, regD src2) %{
4003     single_instruction;
4004     dst   : X(write);
4005     src1  : E(read);
4006     src2  : E(read);
4007     FM    : R;
4008 %}
4009 
4010 // Floating Point Divide Float
4011 pipe_class fdivF_reg_reg(regF dst, regF src1, regF src2) %{
4012     single_instruction;
4013     dst   : X(write);
4014     src1  : E(read);
4015     src2  : E(read);
4016     FM    : R;
4017     FDIV  : C(14);
4018 %}
4019 
4020 // Floating Point Divide Double
4021 pipe_class fdivD_reg_reg(regD dst, regD src1, regD src2) %{
4022     single_instruction;
4023     dst   : X(write);
4024     src1  : E(read);
4025     src2  : E(read);
4026     FM    : R;
4027     FDIV  : C(17);
4028 %}
4029 
4030 // Floating Point Move/Negate/Abs Float
4031 pipe_class faddF_reg(regF dst, regF src) %{
4032     single_instruction;
4033     dst   : W(write);
4034     src   : E(read);
4035     FA    : R(1);
4036 %}
4037 
4038 // Floating Point Move/Negate/Abs Double
4039 pipe_class faddD_reg(regD dst, regD src) %{
4040     single_instruction;
4041     dst   : W(write);
4042     src   : E(read);
4043     FA    : R;
4044 %}
4045 
4046 // Floating Point Convert F->D
4047 pipe_class fcvtF2D(regD dst, regF src) %{
4048     single_instruction;
4049     dst   : X(write);
4050     src   : E(read);
4051     FA    : R;
4052 %}
4053 
4054 // Floating Point Convert I->D
4055 pipe_class fcvtI2D(regD dst, regF src) %{
4056     single_instruction;
4057     dst   : X(write);
4058     src   : E(read);
4059     FA    : R;
4060 %}
4061 
4062 // Floating Point Convert LHi->D
4063 pipe_class fcvtLHi2D(regD dst, regD src) %{
4064     single_instruction;
4065     dst   : X(write);
4066     src   : E(read);
4067     FA    : R;
4068 %}
4069 
4070 // Floating Point Convert L->D
4071 pipe_class fcvtL2D(regD dst, iRegL src) %{
4072     single_instruction;
4073     dst   : X(write);
4074     src   : E(read);
4075     FA    : R;
4076 %}
4077 
4078 // Floating Point Convert L->F
4079 pipe_class fcvtL2F(regF dst, iRegL src) %{
4080     single_instruction;
4081     dst   : X(write);
4082     src   : E(read);
4083     FA    : R;
4084 %}
4085 
4086 // Floating Point Convert D->F
4087 pipe_class fcvtD2F(regD dst, regF src) %{
4088     single_instruction;
4089     dst   : X(write);
4090     src   : E(read);
4091     FA    : R;
4092 %}
4093 
4094 // Floating Point Convert I->L
4095 pipe_class fcvtI2L(regD dst, regF src) %{
4096     single_instruction;
4097     dst   : X(write);
4098     src   : E(read);
4099     FA    : R;
4100 %}
4101 
4102 // Floating Point Convert D->F
4103 pipe_class fcvtD2I(iRegI dst, regD src, flagsReg cr) %{
4104     instruction_count(1); multiple_bundles;
4105     dst   : X(write)+6;
4106     src   : E(read);
4107     FA    : R;
4108 %}
4109 
4110 // Floating Point Convert D->L
4111 pipe_class fcvtD2L(regD dst, regD src, flagsReg cr) %{
4112     instruction_count(1); multiple_bundles;
4113     dst   : X(write)+6;
4114     src   : E(read);
4115     FA    : R;
4116 %}
4117 
4118 // Floating Point Convert F->I
4119 pipe_class fcvtF2I(regF dst, regF src, flagsReg cr) %{
4120     instruction_count(1); multiple_bundles;
4121     dst   : X(write)+6;
4122     src   : E(read);
4123     FA    : R;
4124 %}
4125 
4126 // Floating Point Convert F->L
4127 pipe_class fcvtF2L(regD dst, regF src, flagsReg cr) %{
4128     instruction_count(1); multiple_bundles;
4129     dst   : X(write)+6;
4130     src   : E(read);
4131     FA    : R;
4132 %}
4133 
4134 // Floating Point Convert I->F
4135 pipe_class fcvtI2F(regF dst, regF src) %{
4136     single_instruction;
4137     dst   : X(write);
4138     src   : E(read);
4139     FA    : R;
4140 %}
4141 
4142 // Floating Point Compare
4143 pipe_class faddF_fcc_reg_reg_zero(flagsRegF cr, regF src1, regF src2, immI0 zero) %{
4144     single_instruction;
4145     cr    : X(write);
4146     src1  : E(read);
4147     src2  : E(read);
4148     FA    : R;
4149 %}
4150 
4151 // Floating Point Compare
4152 pipe_class faddD_fcc_reg_reg_zero(flagsRegF cr, regD src1, regD src2, immI0 zero) %{
4153     single_instruction;
4154     cr    : X(write);
4155     src1  : E(read);
4156     src2  : E(read);
4157     FA    : R;
4158 %}
4159 
4160 // Floating Add Nop
4161 pipe_class fadd_nop() %{
4162     single_instruction;
4163     FA  : R;
4164 %}
4165 
4166 // Integer Store to Memory
4167 pipe_class istore_mem_reg(memoryI mem, iRegI src) %{
4168     single_instruction;
4169     mem   : R(read);
4170     src   : C(read);
4171     MS    : R;
4172 %}
4173 
4174 // Integer Store to Memory
4175 pipe_class istore_mem_spORreg(memoryI mem, sp_ptr_RegP src) %{
4176     single_instruction;
4177     mem   : R(read);
4178     src   : C(read);
4179     MS    : R;
4180 %}
4181 
4182 // Float Store
4183 pipe_class fstoreF_mem_reg(memoryF mem, RegF src) %{
4184     single_instruction;
4185     mem : R(read);
4186     src : C(read);
4187     MS  : R;
4188 %}
4189 
4190 // Float Store
4191 pipe_class fstoreF_mem_zero(memoryF mem, immF0 src) %{
4192     single_instruction;
4193     mem : R(read);
4194     MS  : R;
4195 %}
4196 
4197 // Double Store
4198 pipe_class fstoreD_mem_reg(memoryD mem, RegD src) %{
4199     instruction_count(1);
4200     mem : R(read);
4201     src : C(read);
4202     MS  : R;
4203 %}
4204 
4205 // Double Store
4206 pipe_class fstoreD_mem_zero(memoryD mem, immD0 src) %{
4207     single_instruction;
4208     mem : R(read);
4209     MS  : R;
4210 %}
4211 
4212 // Integer Load (when sign bit propagation not needed)
4213 pipe_class iload_mem(iRegI dst, memoryI mem) %{
4214     single_instruction;
4215     mem : R(read);
4216     dst : C(write);
4217     MS  : R;
4218 %}
4219 
4220 // Integer Load (when sign bit propagation or masking is needed)
4221 pipe_class iload_mask_mem(iRegI dst, memoryI mem) %{
4222     single_instruction;
4223     mem : R(read);
4224     dst : M(write);
4225     MS  : R;
4226 %}
4227 
4228 // Float Load
4229 pipe_class floadF_mem(regF dst, memoryF mem) %{
4230     single_instruction;
4231     mem : R(read);
4232     dst : M(write);
4233     MS  : R;
4234 %}
4235 
4236 // Float Load
4237 pipe_class floadD_mem(regD dst, memoryD mem) %{
4238     instruction_count(1); multiple_bundles; // Again, unaligned argument is only multiple case
4239     mem : R(read);
4240     dst : M(write);
4241     MS  : R;
4242 %}
4243 
4244 // Memory Nop
4245 pipe_class mem_nop() %{
4246     single_instruction;
4247     MS  : R;
4248 %}
4249 
4250 pipe_class sethi(iRegP dst, immI src) %{
4251     single_instruction;
4252     dst  : E(write);
4253     IALU : R;
4254 %}
4255 
4256 pipe_class loadPollP(iRegP poll) %{
4257     single_instruction;
4258     poll : R(read);
4259     MS   : R;
4260 %}
4261 
4262 pipe_class br(Universe br, label labl) %{
4263     single_instruction_with_delay_slot;
4264     BR  : R;
4265 %}
4266 
4267 pipe_class br_cc(Universe br, cmpOp cmp, flagsReg cr, label labl) %{
4268     single_instruction_with_delay_slot;
4269     cr    : E(read);
4270     BR    : R;
4271 %}
4272 
4273 pipe_class br_reg(Universe br, cmpOp cmp, iRegI op1, label labl) %{
4274     single_instruction_with_delay_slot;
4275     op1 : E(read);
4276     BR  : R;
4277     MS  : R;
4278 %}
4279 
4280 pipe_class br_nop() %{
4281     single_instruction;
4282     BR  : R;
4283 %}
4284 
4285 pipe_class simple_call(method meth) %{
4286     instruction_count(2); multiple_bundles; force_serialization;
4287     fixed_latency(100);
4288     BR  : R(1);
4289     MS  : R(1);
4290     A0  : R(1);
4291 %}
4292 
4293 pipe_class compiled_call(method meth) %{
4294     instruction_count(1); multiple_bundles; force_serialization;
4295     fixed_latency(100);
4296     MS  : R(1);
4297 %}
4298 
4299 pipe_class call(method meth) %{
4300     instruction_count(0); multiple_bundles; force_serialization;
4301     fixed_latency(100);
4302 %}
4303 
4304 pipe_class tail_call(Universe ignore, label labl) %{
4305     single_instruction; has_delay_slot;
4306     fixed_latency(100);
4307     BR  : R(1);
4308     MS  : R(1);
4309 %}
4310 
4311 pipe_class ret(Universe ignore) %{
4312     single_instruction; has_delay_slot;
4313     BR  : R(1);
4314     MS  : R(1);
4315 %}
4316 
4317 // The real do-nothing guy
4318 pipe_class empty( ) %{
4319     instruction_count(0);
4320 %}
4321 
4322 pipe_class long_memory_op() %{
4323     instruction_count(0); multiple_bundles; force_serialization;
4324     fixed_latency(25);
4325     MS  : R(1);
4326 %}
4327 
4328 // Check-cast
4329 pipe_class partial_subtype_check_pipe(Universe ignore, iRegP array, iRegP match ) %{
4330     array : R(read);
4331     match  : R(read);
4332     IALU   : R(2);
4333     BR     : R(2);
4334     MS     : R;
4335 %}
4336 
4337 // Convert FPU flags into +1,0,-1
4338 pipe_class floating_cmp( iRegI dst, regF src1, regF src2 ) %{
4339     src1  : E(read);
4340     src2  : E(read);
4341     dst   : E(write);
4342     FA    : R;
4343     MS    : R(2);
4344     BR    : R(2);
4345 %}
4346 
4347 // Compare for p < q, and conditionally add y
4348 pipe_class cadd_cmpltmask( iRegI p, iRegI q, iRegI y ) %{
4349     p     : E(read);
4350     q     : E(read);
4351     y     : E(read);
4352     IALU  : R(3)
4353 %}
4354 
4355 // Perform a compare, then move conditionally in a branch delay slot.
4356 pipe_class min_max( iRegI src2, iRegI srcdst ) %{
4357     src2   : E(read);
4358     srcdst : E(read);
4359     IALU   : R;
4360     BR     : R;
4361 %}
4362 
4363 // Define the class for the Nop node
4364 define %{
4365    MachNop = ialu_nop;
4366 %}
4367 
4368 %}
4369 
4370 //----------INSTRUCTIONS-------------------------------------------------------
4371 
4372 //------------Special Nop instructions for bundling - no match rules-----------
4373 // Nop using the A0 functional unit
4374 instruct Nop_A0() %{
4375   ins_pipe(ialu_nop_A0);
4376 %}
4377 
4378 // Nop using the A1 functional unit
4379 instruct Nop_A1( ) %{
4380   ins_pipe(ialu_nop_A1);
4381 %}
4382 
4383 // Nop using the memory functional unit
4384 instruct Nop_MS( ) %{
4385   ins_pipe(mem_nop);
4386 %}
4387 
4388 // Nop using the floating add functional unit
4389 instruct Nop_FA( ) %{
4390   ins_pipe(fadd_nop);
4391 %}
4392 
4393 // Nop using the branch functional unit
4394 instruct Nop_BR( ) %{
4395   ins_pipe(br_nop);
4396 %}
4397 
4398 //----------Load/Store/Move Instructions---------------------------------------
4399 //----------Load Instructions--------------------------------------------------
4400 // Load Byte (8bit signed)
4401 instruct loadB(iRegI dst, memoryB mem) %{
4402   match(Set dst (LoadB mem));
4403   ins_cost(MEMORY_REF_COST);
4404 
4405   size(4);
4406   format %{ "LDRSB   $dst,$mem\t! byte -> int" %}
4407   ins_encode %{
4408     __ ldrsb($dst$$Register, $mem$$Address);
4409   %}
4410   ins_pipe(iload_mask_mem);
4411 %}
4412 
4413 // Load Byte (8bit signed) into a Long Register
4414 instruct loadB2L(iRegL dst, memoryB mem) %{
4415   match(Set dst (ConvI2L (LoadB mem)));
4416   ins_cost(MEMORY_REF_COST);
4417 
4418   size(8);
4419   format %{ "LDRSB $dst.lo,$mem\t! byte -> long\n\t"
4420             "ASR   $dst.hi,$dst.lo,31" %}
4421   ins_encode %{
4422     __ ldrsb($dst$$Register, $mem$$Address);
4423     __ mov($dst$$Register->successor(), $dst$$Register, asr(31));
4424   %}
4425   ins_pipe(iload_mask_mem);
4426 %}
4427 
4428 // Load Unsigned Byte (8bit UNsigned) into an int reg
4429 instruct loadUB(iRegI dst, memoryB mem) %{
4430   match(Set dst (LoadUB mem));
4431   ins_cost(MEMORY_REF_COST);
4432 
4433   size(4);
4434   format %{ "LDRB   $dst,$mem\t! ubyte -> int" %}
4435   ins_encode %{
4436     __ ldrb($dst$$Register, $mem$$Address);
4437   %}
4438   ins_pipe(iload_mem);
4439 %}
4440 
4441 // Load Unsigned Byte (8bit UNsigned) into a Long Register
4442 instruct loadUB2L(iRegL dst, memoryB mem) %{
4443   match(Set dst (ConvI2L (LoadUB mem)));
4444   ins_cost(MEMORY_REF_COST);
4445 
4446   size(8);
4447   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
4448             "MOV   $dst.hi,0" %}
4449   ins_encode %{
4450     __ ldrb($dst$$Register, $mem$$Address);
4451     __ mov($dst$$Register->successor(), 0);
4452   %}
4453   ins_pipe(iload_mem);
4454 %}
4455 
4456 // Load Unsigned Byte (8 bit UNsigned) with immediate mask into Long Register
4457 instruct loadUB2L_limmI(iRegL dst, memoryB mem, limmIlow8 mask) %{
4458   match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
4459 
4460   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
4461   size(12);
4462   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
4463             "MOV   $dst.hi,0\n\t"
4464             "AND  $dst.lo,$dst.lo,$mask" %}
4465   ins_encode %{
4466     __ ldrb($dst$$Register, $mem$$Address);
4467     __ mov($dst$$Register->successor(), 0);
4468     __ andr($dst$$Register, $dst$$Register, limmI_low($mask$$constant, 8));
4469   %}
4470   ins_pipe(iload_mem);
4471 %}
4472 
4473 // Load Short (16bit signed)
4474 
4475 instruct loadS(iRegI dst, memoryS mem) %{
4476   match(Set dst (LoadS mem));
4477   ins_cost(MEMORY_REF_COST);
4478 
4479   size(4);
4480   format %{ "LDRSH   $dst,$mem\t! short" %}
4481   ins_encode %{
4482     __ ldrsh($dst$$Register, $mem$$Address);
4483   %}
4484   ins_pipe(iload_mask_mem);
4485 %}
4486 
4487 // Load Short (16 bit signed) to Byte (8 bit signed)
4488 instruct loadS2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
4489   match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
4490   ins_cost(MEMORY_REF_COST);
4491 
4492   size(4);
4493 
4494   format %{ "LDRSB   $dst,$mem\t! short -> byte" %}
4495   ins_encode %{
4496     // High 32 bits are harmlessly set on Aarch64
4497     __ ldrsb($dst$$Register, $mem$$Address);
4498   %}
4499   ins_pipe(iload_mask_mem);
4500 %}
4501 
4502 // Load Short (16bit signed) into a Long Register
4503 instruct loadS2L(iRegL dst, memoryS mem) %{
4504   match(Set dst (ConvI2L (LoadS mem)));
4505   ins_cost(MEMORY_REF_COST);
4506 
4507   size(8);
4508   format %{ "LDRSH $dst.lo,$mem\t! short -> long\n\t"
4509             "ASR   $dst.hi,$dst.lo,31" %}
4510   ins_encode %{
4511     __ ldrsh($dst$$Register, $mem$$Address);
4512     __ mov($dst$$Register->successor(), $dst$$Register, asr(31));
4513   %}
4514   ins_pipe(iload_mask_mem);
4515 %}
4516 
4517 // Load Unsigned Short/Char (16bit UNsigned)
4518 
4519 
4520 instruct loadUS(iRegI dst, memoryS mem) %{
4521   match(Set dst (LoadUS mem));
4522   ins_cost(MEMORY_REF_COST);
4523 
4524   size(4);
4525   format %{ "LDRH   $dst,$mem\t! ushort/char" %}
4526   ins_encode %{
4527     __ ldrh($dst$$Register, $mem$$Address);
4528   %}
4529   ins_pipe(iload_mem);
4530 %}
4531 
4532 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
4533 instruct loadUS2B(iRegI dst, memoryB mem, immI_24 twentyfour) %{
4534   match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
4535   ins_cost(MEMORY_REF_COST);
4536 
4537   size(4);
4538   format %{ "LDRSB   $dst,$mem\t! ushort -> byte" %}
4539   ins_encode %{
4540     __ ldrsb($dst$$Register, $mem$$Address);
4541   %}
4542   ins_pipe(iload_mask_mem);
4543 %}
4544 
4545 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register
4546 instruct loadUS2L(iRegL dst, memoryS mem) %{
4547   match(Set dst (ConvI2L (LoadUS mem)));
4548   ins_cost(MEMORY_REF_COST);
4549 
4550   size(8);
4551   format %{ "LDRH  $dst.lo,$mem\t! short -> long\n\t"
4552             "MOV   $dst.hi, 0" %}
4553   ins_encode %{
4554     __ ldrh($dst$$Register, $mem$$Address);
4555     __ mov($dst$$Register->successor(), 0);
4556   %}
4557   ins_pipe(iload_mem);
4558 %}
4559 
4560 // Load Unsigned Short/Char (16bit UNsigned) with mask 0xFF into a Long Register
4561 instruct loadUS2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
4562   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
4563   ins_cost(MEMORY_REF_COST);
4564 
4565   size(8);
4566   format %{ "LDRB  $dst.lo,$mem\t! \n\t"
4567             "MOV   $dst.hi, 0" %}
4568   ins_encode %{
4569     __ ldrb($dst$$Register, $mem$$Address);
4570     __ mov($dst$$Register->successor(), 0);
4571   %}
4572   ins_pipe(iload_mem);
4573 %}
4574 
4575 // Load Unsigned Short/Char (16bit UNsigned) with a immediate mask into a Long Register
4576 instruct loadUS2L_limmI(iRegL dst, memoryS mem, limmI mask) %{
4577   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
4578   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
4579 
4580   size(12);
4581   format %{ "LDRH   $dst,$mem\t! ushort/char & mask -> long\n\t"
4582             "MOV    $dst.hi, 0\n\t"
4583             "AND    $dst,$dst,$mask" %}
4584   ins_encode %{
4585     __ ldrh($dst$$Register, $mem$$Address);
4586     __ mov($dst$$Register->successor(), 0);
4587     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
4588   %}
4589   ins_pipe(iload_mem);
4590 %}
4591 
4592 // Load Integer
4593 
4594 instruct loadI(iRegI dst, memoryI mem) %{
4595   match(Set dst (LoadI mem));
4596   ins_cost(MEMORY_REF_COST);
4597 
4598   size(4);
4599   format %{ "ldr $dst,$mem\t! int" %}
4600   ins_encode %{
4601     __ ldr($dst$$Register, $mem$$Address);
4602   %}
4603   ins_pipe(iload_mem);
4604 %}
4605 
4606 // Load Integer to Byte (8 bit signed)
4607 instruct loadI2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
4608   match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
4609   ins_cost(MEMORY_REF_COST);
4610 
4611   size(4);
4612 
4613   format %{ "LDRSB   $dst,$mem\t! int -> byte" %}
4614   ins_encode %{
4615     __ ldrsb($dst$$Register, $mem$$Address);
4616   %}
4617   ins_pipe(iload_mask_mem);
4618 %}
4619 
4620 // Load Integer to Unsigned Byte (8 bit UNsigned)
4621 instruct loadI2UB(iRegI dst, memoryB mem, immI_255 mask) %{
4622   match(Set dst (AndI (LoadI mem) mask));
4623   ins_cost(MEMORY_REF_COST);
4624 
4625   size(4);
4626 
4627   format %{ "LDRB   $dst,$mem\t! int -> ubyte" %}
4628   ins_encode %{
4629     __ ldrb($dst$$Register, $mem$$Address);
4630   %}
4631   ins_pipe(iload_mask_mem);
4632 %}
4633 
4634 // Load Integer to Short (16 bit signed)
4635 instruct loadI2S(iRegI dst, memoryS mem, immI_16 sixteen) %{
4636   match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
4637   ins_cost(MEMORY_REF_COST);
4638 
4639   size(4);
4640   format %{ "LDRSH   $dst,$mem\t! int -> short" %}
4641   ins_encode %{
4642     __ ldrsh($dst$$Register, $mem$$Address);
4643   %}
4644   ins_pipe(iload_mask_mem);
4645 %}
4646 
4647 // Load Integer to Unsigned Short (16 bit UNsigned)
4648 instruct loadI2US(iRegI dst, memoryS mem, immI_65535 mask) %{
4649   match(Set dst (AndI (LoadI mem) mask));
4650   ins_cost(MEMORY_REF_COST);
4651 
4652   size(4);
4653   format %{ "LDRH   $dst,$mem\t! int -> ushort/char" %}
4654   ins_encode %{
4655     __ ldrh($dst$$Register, $mem$$Address);
4656   %}
4657   ins_pipe(iload_mask_mem);
4658 %}
4659 
4660 // Load Integer into a Long Register
4661 instruct loadI2L(iRegL dst, memoryI mem) %{
4662   match(Set dst (ConvI2L (LoadI mem)));
4663   ins_cost(MEMORY_REF_COST);
4664 
4665   size(8);
4666   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
4667             "ASR   $dst.hi,$dst.lo,31\t! int->long" %}
4668   ins_encode %{
4669     __ ldr($dst$$Register, $mem$$Address);
4670     __ mov($dst$$Register->successor(), $dst$$Register, asr(31));
4671   %}
4672   ins_pipe(iload_mask_mem);
4673 %}
4674 
4675 // Load Integer with mask 0xFF into a Long Register
4676 instruct loadI2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
4677   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4678   ins_cost(MEMORY_REF_COST);
4679 
4680   size(8);
4681   format %{ "LDRB   $dst.lo,$mem\t! int & 0xFF -> long\n\t"
4682             "MOV    $dst.hi, 0" %}
4683   ins_encode %{
4684     __ ldrb($dst$$Register, $mem$$Address);
4685     __ mov($dst$$Register->successor(), 0);
4686   %}
4687   ins_pipe(iload_mem);
4688 %}
4689 
4690 // Load Integer with mask 0xFFFF into a Long Register
4691 instruct loadI2L_immI_65535(iRegL dst, memoryS mem, immI_65535 mask) %{
4692   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4693   ins_cost(MEMORY_REF_COST);
4694 
4695   size(8);
4696   format %{ "LDRH   $dst,$mem\t! int & 0xFFFF -> long\n\t"
4697             "MOV    $dst.hi, 0" %}
4698   ins_encode %{
4699     __ ldrh($dst$$Register, $mem$$Address);
4700     __ mov($dst$$Register->successor(), 0);
4701   %}
4702   ins_pipe(iload_mask_mem);
4703 %}
4704 
4705 // Load Integer with a 31-bit immediate mask into a Long Register
4706 instruct loadI2L_limmU31(iRegL dst, memoryI mem, limmU31 mask) %{
4707   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4708   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
4709 
4710   size(12);
4711   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
4712             "MOV    $dst.hi, 0\n\t"
4713             "AND   $dst,$dst,$mask" %}
4714 
4715   ins_encode %{
4716     __ ldr($dst$$Register, $mem$$Address);
4717     __ mov($dst$$Register->successor(), 0);
4718     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
4719   %}
4720   ins_pipe(iload_mem);
4721 %}
4722 
4723 // Load Integer with a 31-bit mask into a Long Register
4724 // FIXME: use iRegI mask, remove tmp?
4725 instruct loadI2L_immU31(iRegL dst, memoryI mem, immU31 mask, iRegI tmp) %{
4726   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4727   effect(TEMP dst, TEMP tmp);
4728 
4729   ins_cost(MEMORY_REF_COST + 4*DEFAULT_COST);
4730   size(20);
4731   format %{ "LDR      $mem,$dst\t! int & 31-bit mask -> long\n\t"
4732             "MOV      $dst.hi, 0\n\t"
4733             "MOV_SLOW $tmp,$mask\n\t"
4734             "AND      $dst,$tmp,$dst" %}
4735   ins_encode %{
4736     __ ldr($dst$$Register, $mem$$Address);
4737     __ mov($dst$$Register->successor(), 0);
4738     __ mov($tmp$$Register, $mask$$constant);
4739     __ andr($dst$$Register, $dst$$Register, $tmp$$Register);
4740   %}
4741   ins_pipe(iload_mem);
4742 %}
4743 
4744 // Load Unsigned Integer into a Long Register
4745 instruct loadUI2L(iRegL dst, memoryI mem, immL_32bits mask) %{
4746   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
4747   ins_cost(MEMORY_REF_COST);
4748 
4749   size(8);
4750   format %{ "LDR   $dst.lo,$mem\t! uint -> long\n\t"
4751             "MOV   $dst.hi,0" %}
4752   ins_encode %{
4753     __ ldr($dst$$Register, $mem$$Address);
4754     __ mov($dst$$Register->successor(), 0);
4755   %}
4756   ins_pipe(iload_mem);
4757 %}
4758 
4759 // Load Long
4760 
4761 instruct loadL(iRegLd dst, memoryL mem ) %{
4762   predicate(!((LoadLNode*)n)->require_atomic_access());
4763   match(Set dst (LoadL mem));
4764   effect(TEMP dst);
4765   ins_cost(MEMORY_REF_COST);
4766 
4767   size(4);
4768   format %{ "ldrd  $dst,$mem\t! long" %}
4769   ins_encode %{
4770     __ ldrd($dst$$Register, $mem$$Address);
4771   %}
4772   ins_pipe(iload_mem);
4773 %}
4774 
4775 instruct loadL_2instr(iRegL dst, memorylong mem ) %{
4776   predicate(!((LoadLNode*)n)->require_atomic_access());
4777   match(Set dst (LoadL mem));
4778   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
4779 
4780   size(8);
4781   format %{ "LDR    $dst.lo,$mem \t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
4782             "LDR    $dst.hi,$mem+4 or $mem" %}
4783   ins_encode %{
4784     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4785     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
4786 
4787     if ($dst$$Register == reg_to_register_object($mem$$base)) {
4788       __ ldr($dst$$Register->successor(), Amemhi);
4789       __ ldr($dst$$Register, Amemlo);
4790     } else {
4791       __ ldr($dst$$Register, Amemlo);
4792       __ ldr($dst$$Register->successor(), Amemhi);
4793     }
4794   %}
4795   ins_pipe(iload_mem);
4796 %}
4797 
4798 instruct loadL_volatile(iRegL dst, indirect mem ) %{
4799   predicate(((LoadLNode*)n)->require_atomic_access());
4800   match(Set dst (LoadL mem));
4801   ins_cost(MEMORY_REF_COST);
4802 
4803   size(4);
4804   format %{ "LDREXD    $dst,$mem\t! long" %}
4805   ins_encode %{
4806     __ atomic_ldrd($dst$$Register, reg_to_register_object($dst$$reg + 1), reg_to_register_object($mem$$base));
4807   %}
4808   ins_pipe(iload_mem);
4809 %}
4810 
4811 instruct loadL_volatile_fp(iRegL dst, memoryD mem ) %{
4812   predicate(((LoadLNode*)n)->require_atomic_access());
4813   match(Set dst (LoadL mem));
4814   ins_cost(MEMORY_REF_COST);
4815 
4816   size(8);
4817   format %{ "FLDD      S14, $mem"
4818             "FMRRD    $dst, S14\t! long \n't" %}
4819   ins_encode %{
4820     __ vldr_f64(f14, $mem$$Address);
4821     __ vmov_f64($dst$$Register, $dst$$Register->successor(), f14);
4822   %}
4823   ins_pipe(iload_mem);
4824 %}
4825 
4826 instruct loadL_unaligned(iRegL dst, memorylong mem ) %{
4827   match(Set dst (LoadL_unaligned mem));
4828   ins_cost(MEMORY_REF_COST);
4829 
4830   size(8);
4831   format %{ "LDR    $dst.lo,$mem\t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
4832             "LDR    $dst.hi,$mem+4" %}
4833   ins_encode %{
4834     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4835     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
4836 
4837     if ($dst$$Register == reg_to_register_object($mem$$base)) {
4838       __ ldr($dst$$Register->successor(), Amemhi);
4839       __ ldr($dst$$Register, Amemlo);
4840     } else {
4841       __ ldr($dst$$Register, Amemlo);
4842       __ ldr($dst$$Register->successor(), Amemhi);
4843     }
4844   %}
4845   ins_pipe(iload_mem);
4846 %}
4847 
4848 // Load Range
4849 instruct loadRange(iRegI dst, memoryI mem) %{
4850   match(Set dst (LoadRange mem));
4851   ins_cost(MEMORY_REF_COST);
4852 
4853   size(4);
4854   format %{ "LDR_u32 $dst,$mem\t! range" %}
4855   ins_encode %{
4856     __ ldr($dst$$Register, $mem$$Address);
4857   %}
4858   ins_pipe(iload_mem);
4859 %}
4860 
4861 // Load Pointer
4862 
4863 instruct loadP(iRegP dst, memoryP mem) %{
4864   match(Set dst (LoadP mem));
4865   ins_cost(MEMORY_REF_COST);
4866   size(4);
4867 
4868   format %{ "LDR   $dst,$mem\t! ptr" %}
4869   ins_encode %{
4870     __ ldr($dst$$Register, $mem$$Address);
4871   %}
4872   ins_pipe(iload_mem);
4873 %}
4874 
4875 // Load Klass Pointer
4876 instruct loadKlass(iRegP dst, memoryI mem) %{
4877   match(Set dst (LoadKlass mem));
4878   ins_cost(MEMORY_REF_COST);
4879   size(4);
4880 
4881   format %{ "LDR   $dst,$mem\t! klass ptr" %}
4882   ins_encode %{
4883     __ ldr($dst$$Register, $mem$$Address);
4884   %}
4885   ins_pipe(iload_mem);
4886 %}
4887 
4888 instruct loadD(regD dst, memoryD mem) %{
4889   match(Set dst (LoadD mem));
4890   ins_cost(MEMORY_REF_COST);
4891 
4892   size(4);
4893   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
4894   // only LDREXD and STREXD are 64-bit single-copy atomic
4895   format %{ "FLDD   $dst,$mem" %}
4896   ins_encode %{
4897     __ vldr_f64($dst$$FloatRegister, $mem$$Address);
4898   %}
4899   ins_pipe(floadD_mem);
4900 %}
4901 
4902 // Load Double - UNaligned
4903 instruct loadD_unaligned(regD_low dst, memoryF2 mem ) %{
4904   match(Set dst (LoadD_unaligned mem));
4905   ins_cost(MEMORY_REF_COST*2+DEFAULT_COST);
4906   size(8);
4907   format %{ "FLDS    $dst.lo,$mem\t! misaligned double\n"
4908           "\tFLDS    $dst.hi,$mem+4\t!" %}
4909   ins_encode %{
4910     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4911     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
4912       __ vldr_f32($dst$$FloatRegister, Amemlo);
4913       __ vldr_f32($dst$$FloatRegister->successor(FloatRegisterImpl::SINGLE), Amemhi);
4914   %}
4915   ins_pipe(iload_mem);
4916 %}
4917 
4918 instruct loadF(regF dst, memoryF mem) %{
4919   match(Set dst (LoadF mem));
4920 
4921   ins_cost(MEMORY_REF_COST);
4922   size(4);
4923   format %{ "FLDS    $dst,$mem" %}
4924   ins_encode %{
4925     __ vldr_f32($dst$$FloatRegister, $mem$$Address);
4926   %}
4927   ins_pipe(floadF_mem);
4928 %}
4929 
4930 // // Load Constant
4931 instruct loadConI( iRegI dst, immI src ) %{
4932   match(Set dst src);
4933   ins_cost(DEFAULT_COST * 3/2);
4934   format %{ "MOV_SLOW    $dst, $src" %}
4935   ins_encode %{
4936     __ mov($dst$$Register, $src$$constant);
4937   %}
4938   ins_pipe(ialu_hi_lo_reg);
4939 %}
4940 
4941 instruct loadConIMov( iRegI dst, immIMov src ) %{
4942   match(Set dst src);
4943   size(4);
4944   format %{ "MOV    $dst, $src" %}
4945   ins_encode %{
4946     __ mov($dst$$Register, $src$$constant);
4947   %}
4948   ins_pipe(ialu_imm);
4949 %}
4950 
4951 instruct loadConIMovn( iRegI dst, immIRotn src ) %{
4952   match(Set dst src);
4953   size(4);
4954   format %{ "MVN    $dst, ~$src" %}
4955   ins_encode %{
4956     __ mvn_i($dst$$Register, ~$src$$constant);
4957   %}
4958   ins_pipe(ialu_imm_n);
4959 %}
4960 
4961 instruct loadConI16( iRegI dst, immI16 src ) %{
4962   match(Set dst src);
4963   size(4);
4964   format %{ "MOVW    $dst, $src" %}
4965   ins_encode %{
4966     __ movw_i($dst$$Register, $src$$constant);
4967   %}
4968   ins_pipe(ialu_imm_n);
4969 %}
4970 
4971 instruct loadConP(iRegP dst, immP src) %{
4972   match(Set dst src);
4973   ins_cost(DEFAULT_COST * 3/2);
4974   format %{ "MOV_SLOW    $dst,$src\t!ptr" %}
4975   ins_encode %{
4976     relocInfo::relocType constant_reloc = _opnds[1]->constant_reloc();
4977     intptr_t val = $src$$constant;
4978     if (constant_reloc == relocInfo::oop_type) {
4979       __ movoop($dst$$Register, (jobject)val, true);
4980     } else if (constant_reloc == relocInfo::metadata_type) {
4981       __ mov_metadata($dst$$Register, (Metadata*)val);
4982     } else {
4983       __ mov($dst$$Register, val);
4984     }
4985   %}
4986   ins_pipe(loadConP);
4987 %}
4988 
4989 
4990 instruct loadConP_poll(iRegP dst, immP_poll src) %{
4991   match(Set dst src);
4992   ins_cost(DEFAULT_COST);
4993   format %{ "MOV_SLOW    $dst,$src\t!ptr" %}
4994   ins_encode %{
4995       __ mov($dst$$Register, $src$$constant);
4996   %}
4997   ins_pipe(loadConP_poll);
4998 %}
4999 
5000 instruct loadConL(iRegL dst, immL src) %{
5001   match(Set dst src);
5002   ins_cost(DEFAULT_COST * 4);
5003   format %{ "MOV_SLOW   $dst.lo, $src & 0x0FFFFFFFFL \t! long\n\t"
5004             "MOV_SLOW   $dst.hi, $src >> 32" %}
5005   ins_encode %{
5006     __ mov(reg_to_register_object($dst$$reg), $src$$constant & 0x0FFFFFFFFL);
5007     __ mov(reg_to_register_object($dst$$reg + 1), ((julong)($src$$constant)) >> 32);
5008   %}
5009   ins_pipe(loadConL);
5010 %}
5011 
5012 instruct loadConL16( iRegL dst, immL16 src ) %{
5013   match(Set dst src);
5014   ins_cost(DEFAULT_COST * 2);
5015 
5016   size(8);
5017   format %{ "MOVW    $dst.lo, $src \n\t"
5018             "MOVW    $dst.hi, 0 \n\t" %}
5019   ins_encode %{
5020     __ movw_i($dst$$Register, $src$$constant);
5021     __ movw_i(reg_to_register_object($dst$$reg + 1), 0);
5022   %}
5023   ins_pipe(ialu_imm);
5024 %}
5025 
5026 instruct loadConF_imm8(regF dst, imm8F src) %{
5027   match(Set dst src);
5028   ins_cost(DEFAULT_COST);
5029   size(4);
5030 
5031   format %{ "FCONSTS      $dst, $src"%}
5032 
5033   ins_encode %{
5034     __ vmov_f32($dst$$FloatRegister, $src$$constant);
5035   %}
5036   ins_pipe(loadConFD); // FIXME
5037 %}
5038 
5039 instruct loadConF(regF dst, immF src, iRegI tmp) %{
5040   match(Set dst src);
5041   ins_cost(DEFAULT_COST * 2);
5042   effect(TEMP tmp);
5043   size(3*4);
5044 
5045   format %{ "MOV_SLOW  $tmp, $src\n\t"
5046             "FMSR      $dst, $tmp"%}
5047 
5048   ins_encode %{
5049     // FIXME revisit once 6961697 is in
5050     union {
5051       jfloat f;
5052       int i;
5053     } v;
5054     v.f = $src$$constant;
5055     __ mov($tmp$$Register, v.i);
5056     __ vmov_f32($dst$$FloatRegister, $tmp$$Register);
5057   %}
5058   ins_pipe(loadConFD); // FIXME
5059 %}
5060 
5061 instruct loadConD_imm8(regD dst, imm8D src) %{
5062   match(Set dst src);
5063   ins_cost(DEFAULT_COST);
5064   size(4);
5065 
5066   format %{ "FCONSTD      $dst, $src"%}
5067 
5068   ins_encode %{
5069     __ vmov_f64($dst$$FloatRegister, $src$$constant);
5070   %}
5071   ins_pipe(loadConFD); // FIXME
5072 %}
5073 
5074 instruct loadConD(regD dst, immD src, iRegP tmp) %{
5075   match(Set dst src);
5076   effect(TEMP tmp);
5077   ins_cost(MEMORY_REF_COST);
5078   format %{ "FLDD  $dst, [$constanttablebase + $constantoffset]\t! load from constant table: double=$src" %}
5079 
5080   ins_encode %{
5081     Register r = $constanttablebase;
5082     int offset  = $constantoffset($src);
5083     if (!is_memoryD(offset)) {                // can't use a predicate
5084                                               // in load constant instructs
5085       __ add($tmp$$Register, r, offset);
5086       r = $tmp$$Register;
5087       offset = 0;
5088     }
5089     __ vldr_f64($dst$$FloatRegister, Address(r, offset));
5090   %}
5091   ins_pipe(loadConFD);
5092 %}
5093 
5094 // Prefetch instructions.
5095 // Must be safe to execute with invalid address (cannot fault).
5096 
5097 instruct prefetchAlloc_mp( memoryP mem ) %{
5098   predicate(VM_Version::features() & FT_MP_EXT);
5099   match( PrefetchAllocation mem );
5100   ins_cost(MEMORY_REF_COST);
5101   size(4);
5102 
5103   format %{ "PLDW $mem\t! Prefetch allocation" %}
5104   ins_encode %{
5105     __ pldw($mem$$Address);
5106   %}
5107   ins_pipe(iload_mem);
5108 %}
5109 
5110 instruct prefetchAlloc_sp( memoryP mem ) %{
5111   predicate(!(VM_Version::features() & FT_MP_EXT));
5112   match( PrefetchAllocation mem );
5113   ins_cost(MEMORY_REF_COST);
5114   size(4);
5115 
5116   format %{ "PLD $mem\t! Prefetch allocation" %}
5117   ins_encode %{
5118     __ pld($mem$$Address);
5119   %}
5120   ins_pipe(iload_mem);
5121 %}
5122 
5123 //----------Store Instructions-------------------------------------------------
5124 // Store Byte
5125 instruct storeB(memoryB mem, store_RegI src) %{
5126   match(Set mem (StoreB mem src));
5127   ins_cost(MEMORY_REF_COST);
5128 
5129   size(4);
5130   format %{ "STRB    $src,$mem\t! byte" %}
5131   ins_encode %{
5132     __ strb($src$$Register, $mem$$Address);
5133   %}
5134   ins_pipe(istore_mem_reg);
5135 %}
5136 
5137 instruct storeCM(memoryB mem, store_RegI src) %{
5138   match(Set mem (StoreCM mem src));
5139   ins_cost(MEMORY_REF_COST);
5140 
5141   size(4);
5142   format %{ "STRB    $src,$mem\t! CMS card-mark byte" %}
5143   ins_encode %{
5144     __ strb($src$$Register, $mem$$Address);
5145   %}
5146   ins_pipe(istore_mem_reg);
5147 %}
5148 
5149 // Store Char/Short
5150 
5151 instruct storeC(memoryS mem, store_RegI src) %{
5152   match(Set mem (StoreC mem src));
5153   ins_cost(MEMORY_REF_COST);
5154 
5155   size(4);
5156   format %{ "STRH    $src,$mem\t! short" %}
5157   ins_encode %{
5158     __ strh($src$$Register, $mem$$Address);
5159   %}
5160   ins_pipe(istore_mem_reg);
5161 %}
5162 
5163 // Store Integer
5164 
5165 instruct storeI(memoryI mem, store_RegI src) %{
5166   match(Set mem (StoreI mem src));
5167   ins_cost(MEMORY_REF_COST);
5168 
5169   size(4);
5170   format %{ "str $src,$mem" %}
5171   ins_encode %{
5172     __ str($src$$Register, $mem$$Address);
5173   %}
5174   ins_pipe(istore_mem_reg);
5175 %}
5176 
5177 // Store Long
5178 
5179 instruct storeL(memoryL mem, store_RegLd src) %{
5180   predicate(!((StoreLNode*)n)->require_atomic_access());
5181   match(Set mem (StoreL mem src));
5182   ins_cost(MEMORY_REF_COST);
5183 
5184   size(4);
5185   format %{ "strd  $src,$mem\t! long\n\t" %}
5186 
5187   ins_encode %{
5188     __ strd($src$$Register, $mem$$Address);
5189   %}
5190   ins_pipe(istore_mem_reg);
5191 %}
5192 
5193 instruct storeL_2instr(memorylong mem, iRegL src) %{
5194   predicate(!((StoreLNode*)n)->require_atomic_access());
5195   match(Set mem (StoreL mem src));
5196   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
5197 
5198   size(8);
5199   format %{ "STR    $src.lo,$mem\t! long\n\t"
5200             "STR    $src.hi,$mem+4" %}
5201 
5202   ins_encode %{
5203     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
5204     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
5205     __ str($src$$Register, Amemlo);
5206     __ str($src$$Register->successor(), Amemhi);
5207   %}
5208   ins_pipe(istore_mem_reg);
5209 %}
5210 
5211 instruct storeL_volatile(indirect mem, iRegL src) %{
5212   predicate(((StoreLNode*)n)->require_atomic_access());
5213   match(Set mem (StoreL mem src));
5214   ins_cost(MEMORY_REF_COST);
5215   size(4);
5216   format %{ "STMIA    $src,$mem\t! long" %}
5217   ins_encode %{
5218     // FIXME: why is stmia considered atomic?  Should be strexd
5219     // TODO: need 3 temp registers to use atomic_strd
5220     __ stmia(reg_to_register_object($mem$$base), RegSet::of($src$$Register, reg_to_register_object($src$$reg + 1)).bits(), /*wb*/false);
5221   %}
5222   ins_pipe(istore_mem_reg);
5223 %}
5224 
5225 instruct storeL_volatile_fp(memoryD mem, iRegL src) %{
5226   predicate(((StoreLNode*)n)->require_atomic_access());
5227   match(Set mem (StoreL mem src));
5228   ins_cost(MEMORY_REF_COST);
5229   size(8);
5230   format %{ "FMDRR    S14, $src\t! long \n\t"
5231             "FSTD     S14, $mem" %}
5232   ins_encode %{
5233     __ vmov_f64(f14, $src$$Register, $src$$Register->successor());
5234     __ vstr_f64(f14, $mem$$Address);
5235   %}
5236   ins_pipe(istore_mem_reg);
5237 %}
5238 
5239 // Store Pointer
5240 
5241 instruct storeP(memoryP mem, store_ptr_RegP src) %{
5242   match(Set mem (StoreP mem src));
5243   ins_cost(MEMORY_REF_COST);
5244   size(4);
5245 
5246   format %{ "STR    $src,$mem\t! ptr" %}
5247   ins_encode %{
5248     __ str($src$$Register, $mem$$Address);
5249   %}
5250   ins_pipe(istore_mem_spORreg);
5251 %}
5252 
5253 // Store Double
5254 
5255 instruct storeD(memoryD mem, regD src) %{
5256   match(Set mem (StoreD mem src));
5257   ins_cost(MEMORY_REF_COST);
5258 
5259   size(4);
5260   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
5261   // only LDREXD and STREXD are 64-bit single-copy atomic
5262   format %{ "FSTD   $src,$mem" %}
5263   ins_encode %{
5264     __ vstr_f64($src$$FloatRegister, $mem$$Address);
5265   %}
5266   ins_pipe(fstoreD_mem_reg);
5267 %}
5268 
5269 // Store Float
5270 
5271 instruct storeF( memoryF mem, regF src) %{
5272   match(Set mem (StoreF mem src));
5273   ins_cost(MEMORY_REF_COST);
5274 
5275   size(4);
5276   format %{ "FSTS    $src,$mem" %}
5277   ins_encode %{
5278     __ vstr_f32($src$$FloatRegister, $mem$$Address);
5279   %}
5280   ins_pipe(fstoreF_mem_reg);
5281 %}
5282 
5283 //----------MemBar Instructions-----------------------------------------------
5284 // Memory barrier flavors
5285 
5286 // TODO: take advantage of Aarch64 load-acquire, store-release, etc
5287 // pattern-match out unnecessary membars
5288 instruct membar_storestore() %{
5289   match(MemBarStoreStore);
5290   ins_cost(4*MEMORY_REF_COST);
5291 
5292   size(4);
5293   format %{ "MEMBAR-storestore" %}
5294   ins_encode %{
5295     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore));
5296   %}
5297   ins_pipe(long_memory_op);
5298 %}
5299 
5300 instruct membar_acquire() %{
5301   match(MemBarAcquire);
5302   match(LoadFence);
5303   ins_cost(4*MEMORY_REF_COST);
5304 
5305   size(4);
5306   format %{ "MEMBAR-acquire" %}
5307   ins_encode %{
5308     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore));
5309   %}
5310   ins_pipe(long_memory_op);
5311 %}
5312 
5313 instruct membar_acquire_lock() %{
5314   match(MemBarAcquireLock);
5315   ins_cost(0);
5316 
5317   size(0);
5318   format %{ "!MEMBAR-acquire (CAS in prior FastLock so empty encoding)" %}
5319   ins_encode( );
5320   ins_pipe(empty);
5321 %}
5322 
5323 instruct membar_release() %{
5324   match(MemBarRelease);
5325   match(StoreFence);
5326   ins_cost(4*MEMORY_REF_COST);
5327 
5328   size(4);
5329   format %{ "MEMBAR-release" %}
5330   ins_encode %{
5331     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore));
5332   %}
5333   ins_pipe(long_memory_op);
5334 %}
5335 
5336 instruct membar_release_lock() %{
5337   match(MemBarReleaseLock);
5338   ins_cost(0);
5339 
5340   size(0);
5341   format %{ "!MEMBAR-release (CAS in succeeding FastUnlock so empty encoding)" %}
5342   ins_encode( );
5343   ins_pipe(empty);
5344 %}
5345 
5346 instruct membar_volatile() %{
5347   match(MemBarVolatile);
5348   ins_cost(4*MEMORY_REF_COST);
5349 
5350   size(4);
5351   format %{ "MEMBAR-volatile" %}
5352   ins_encode %{
5353     __ membar(MacroAssembler::StoreLoad);
5354   %}
5355   ins_pipe(long_memory_op);
5356 %}
5357 
5358 instruct unnecessary_membar_volatile() %{
5359   match(MemBarVolatile);
5360   predicate(Matcher::post_store_load_barrier(n));
5361   ins_cost(0);
5362 
5363   size(0);
5364   format %{ "!MEMBAR-volatile (unnecessary so empty encoding)" %}
5365   ins_encode( );
5366   ins_pipe(empty);
5367 %}
5368 
5369 //----------Register Move Instructions-----------------------------------------
5370 // instruct roundDouble_nop(regD dst) %{
5371 //   match(Set dst (RoundDouble dst));
5372 //   ins_pipe(empty);
5373 // %}
5374 
5375 
5376 // instruct roundFloat_nop(regF dst) %{
5377 //   match(Set dst (RoundFloat dst));
5378 //   ins_pipe(empty);
5379 // %}
5380 
5381 
5382 // Cast Index to Pointer for unsafe natives
5383 instruct castX2P(iRegX src, iRegP dst) %{
5384   match(Set dst (CastX2P src));
5385 
5386   format %{ "MOV    $dst,$src\t! IntX->Ptr if $dst != $src" %}
5387   ins_encode %{
5388     if ($dst$$Register !=  $src$$Register) {
5389       __ mov($dst$$Register, $src$$Register);
5390     }
5391   %}
5392   ins_pipe(ialu_reg);
5393 %}
5394 
5395 // Cast Pointer to Index for unsafe natives
5396 instruct castP2X(iRegP src, iRegX dst) %{
5397   match(Set dst (CastP2X src));
5398 
5399   format %{ "MOV    $dst,$src\t! Ptr->IntX if $dst != $src" %}
5400   ins_encode %{
5401     if ($dst$$Register !=  $src$$Register) {
5402       __ mov($dst$$Register, $src$$Register);
5403     }
5404   %}
5405   ins_pipe(ialu_reg);
5406 %}
5407 
5408 //----------Conditional Move---------------------------------------------------
5409 // Conditional move
5410 instruct cmovIP_reg(cmpOpP cmp, flagsRegP pcc, iRegI dst, iRegI src) %{
5411   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
5412   ins_cost(150);
5413   size(4);
5414   format %{ "MOV$cmp  $dst,$src\t! int" %}
5415   ins_encode %{
5416     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
5417   %}
5418   ins_pipe(ialu_reg);
5419 %}
5420 
5421 instruct cmovIP_immMov(cmpOpP cmp, flagsRegP pcc, iRegI dst, immIMov src) %{
5422   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
5423   ins_cost(140);
5424   size(4);
5425   format %{ "MOV$cmp  $dst,$src" %}
5426   ins_encode %{
5427     __ mov($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
5428   %}
5429   ins_pipe(ialu_imm);
5430 %}
5431 
5432 instruct cmovIP_imm16(cmpOpP cmp, flagsRegP pcc, iRegI dst, immI16 src) %{
5433   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
5434   ins_cost(140);
5435   size(4);
5436   format %{ "MOVw$cmp  $dst,$src" %}
5437   ins_encode %{
5438     __ movw_i($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
5439   %}
5440   ins_pipe(ialu_imm);
5441 %}
5442 
5443 instruct cmovI_reg(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src) %{
5444   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
5445   ins_cost(150);
5446   size(4);
5447   format %{ "MOV$cmp  $dst,$src" %}
5448   ins_encode %{
5449     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
5450   %}
5451   ins_pipe(ialu_reg);
5452 %}
5453 
5454 instruct cmovI_immMov(cmpOp cmp, flagsReg icc, iRegI dst, immIMov src) %{
5455   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
5456   ins_cost(140);
5457   size(4);
5458   format %{ "MOV$cmp  $dst,$src" %}
5459   ins_encode %{
5460     __ mov($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
5461   %}
5462   ins_pipe(ialu_imm);
5463 %}
5464 
5465 instruct cmovII_imm16(cmpOp cmp, flagsReg icc, iRegI dst, immI16 src) %{
5466   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
5467   ins_cost(140);
5468   size(4);
5469   format %{ "MOVw$cmp  $dst,$src" %}
5470   ins_encode %{
5471     __ movw_i($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
5472   %}
5473   ins_pipe(ialu_imm);
5474 %}
5475 
5476 instruct cmovII_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, iRegI src) %{
5477   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
5478   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
5479             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
5480             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
5481             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
5482   ins_cost(150);
5483   size(4);
5484   format %{ "MOV$cmp  $dst,$src" %}
5485   ins_encode %{
5486     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
5487   %}
5488   ins_pipe(ialu_reg);
5489 %}
5490 
5491 instruct cmovII_immMov_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immIMov src) %{
5492   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
5493   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
5494             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
5495             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
5496             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
5497   ins_cost(140);
5498   size(4);
5499   format %{ "MOV$cmp  $dst,$src" %}
5500   ins_encode %{
5501     __ mov($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
5502   %}
5503   ins_pipe(ialu_imm);
5504 %}
5505 
5506 instruct cmovII_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immI16 src) %{
5507   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
5508   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
5509             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
5510             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
5511             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
5512   ins_cost(140);
5513   size(4);
5514   format %{ "MOVW$cmp  $dst,$src" %}
5515   ins_encode %{
5516     __ movw_i($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
5517   %}
5518   ins_pipe(ialu_imm);
5519 %}
5520 
5521 instruct cmovIIu_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
5522   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
5523   ins_cost(150);
5524   size(4);
5525   format %{ "MOV$cmp  $dst,$src" %}
5526   ins_encode %{
5527     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
5528   %}
5529   ins_pipe(ialu_reg);
5530 %}
5531 
5532 instruct cmovIIu_immMov(cmpOpU cmp, flagsRegU icc, iRegI dst, immIMov src) %{
5533   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
5534   ins_cost(140);
5535   size(4);
5536   format %{ "MOV$cmp  $dst,$src" %}
5537   ins_encode %{
5538     __ mov($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
5539   %}
5540   ins_pipe(ialu_imm);
5541 %}
5542 
5543 instruct cmovIIu_imm16(cmpOpU cmp, flagsRegU icc, iRegI dst, immI16 src) %{
5544   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
5545   ins_cost(140);
5546   size(4);
5547   format %{ "MOVW$cmp  $dst,$src" %}
5548   ins_encode %{
5549     __ movw_i($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
5550   %}
5551   ins_pipe(ialu_imm);
5552 %}
5553 
5554 // Conditional move
5555 instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{
5556   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
5557   ins_cost(150);
5558   size(4);
5559   format %{ "MOV$cmp  $dst,$src" %}
5560   ins_encode %{
5561     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
5562   %}
5563   ins_pipe(ialu_reg);
5564 %}
5565 
5566 instruct cmovPP_imm(cmpOpP cmp, flagsRegP pcc, iRegP dst, immP0 src) %{
5567   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
5568   ins_cost(140);
5569   size(4);
5570   format %{ "MOV$cmp  $dst,$src" %}
5571   ins_encode %{
5572     __ mov($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
5573   %}
5574   ins_pipe(ialu_imm);
5575 %}
5576 
5577 // This instruction also works with CmpN so we don't need cmovPN_reg.
5578 instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{
5579   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
5580   ins_cost(150);
5581 
5582   size(4);
5583   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
5584   ins_encode %{
5585     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
5586   %}
5587   ins_pipe(ialu_reg);
5588 %}
5589 
5590 instruct cmovPI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, iRegP src) %{
5591   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
5592   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
5593             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
5594             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
5595             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
5596   ins_cost(150);
5597 
5598   size(4);
5599   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
5600   ins_encode %{
5601     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
5602   %}
5603   ins_pipe(ialu_reg);
5604 %}
5605 
5606 instruct cmovPIu_reg(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src) %{
5607   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
5608   ins_cost(150);
5609 
5610   size(4);
5611   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
5612   ins_encode %{
5613     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
5614   %}
5615   ins_pipe(ialu_reg);
5616 %}
5617 
5618 instruct cmovPI_imm(cmpOp cmp, flagsReg icc, iRegP dst, immP0 src) %{
5619   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
5620   ins_cost(140);
5621 
5622   size(4);
5623   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
5624   ins_encode %{
5625     __ mov($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
5626   %}
5627   ins_pipe(ialu_imm);
5628 %}
5629 
5630 instruct cmovPI_imm_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, immP0 src) %{
5631   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
5632   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
5633             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
5634             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
5635             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
5636   ins_cost(140);
5637 
5638   size(4);
5639   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
5640   ins_encode %{
5641     __ mov($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
5642   %}
5643   ins_pipe(ialu_imm);
5644 %}
5645 
5646 instruct cmovPIu_imm(cmpOpU cmp, flagsRegU icc, iRegP dst, immP0 src) %{
5647   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
5648   ins_cost(140);
5649 
5650   size(4);
5651   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
5652   ins_encode %{
5653     __ mov($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
5654   %}
5655   ins_pipe(ialu_imm);
5656 %}
5657 
5658 // Conditional move
5659 instruct cmovFP_reg(cmpOpP cmp, flagsRegP pcc, regF dst, regF src) %{
5660   match(Set dst (CMoveF (Binary cmp pcc) (Binary dst src)));
5661   ins_cost(150);
5662   size(4);
5663   format %{ "FCPYS$cmp $dst,$src" %}
5664   ins_encode %{
5665     __ vmov_f32($dst$$FloatRegister, $src$$FloatRegister, (Assembler::Condition)($cmp$$cmpcode));
5666   %}
5667   ins_pipe(int_conditional_float_move);
5668 %}
5669 
5670 instruct cmovFI_reg(cmpOp cmp, flagsReg icc, regF dst, regF src) %{
5671   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
5672   ins_cost(150);
5673 
5674   size(4);
5675   format %{ "FCPYS$cmp $dst,$src" %}
5676   ins_encode %{
5677     __ vmov_f32($dst$$FloatRegister, $src$$FloatRegister, (Assembler::Condition)($cmp$$cmpcode));
5678   %}
5679   ins_pipe(int_conditional_float_move);
5680 %}
5681 
5682 instruct cmovFI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regF dst, regF src) %{
5683   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
5684   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
5685             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
5686             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
5687             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
5688   ins_cost(150);
5689 
5690   size(4);
5691   format %{ "FCPYS$cmp $dst,$src" %}
5692   ins_encode %{
5693     __ vmov_f32($dst$$FloatRegister, $src$$FloatRegister, (Assembler::Condition)($cmp$$cmpcode));
5694   %}
5695   ins_pipe(int_conditional_float_move);
5696 %}
5697 
5698 instruct cmovFIu_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src) %{
5699   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
5700   ins_cost(150);
5701 
5702   size(4);
5703   format %{ "FCPYS$cmp $dst,$src" %}
5704   ins_encode %{
5705     __ vmov_f32($dst$$FloatRegister, $src$$FloatRegister, (Assembler::Condition)($cmp$$cmpcode));
5706   %}
5707   ins_pipe(int_conditional_float_move);
5708 %}
5709 
5710 // Conditional move
5711 instruct cmovDP_reg(cmpOpP cmp, flagsRegP pcc, regD dst, regD src) %{
5712   match(Set dst (CMoveD (Binary cmp pcc) (Binary dst src)));
5713   ins_cost(150);
5714   size(4);
5715   format %{ "FCPYD$cmp $dst,$src" %}
5716   ins_encode %{
5717     __ vmov_f64($dst$$FloatRegister, $src$$FloatRegister, (Assembler::Condition)($cmp$$cmpcode));
5718   %}
5719   ins_pipe(int_conditional_double_move);
5720 %}
5721 
5722 instruct cmovDI_reg(cmpOp cmp, flagsReg icc, regD dst, regD src) %{
5723   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
5724   ins_cost(150);
5725 
5726   size(4);
5727   format %{ "FCPYD$cmp $dst,$src" %}
5728   ins_encode %{
5729     __ vmov_f64($dst$$FloatRegister, $src$$FloatRegister, (Assembler::Condition)($cmp$$cmpcode));
5730   %}
5731   ins_pipe(int_conditional_double_move);
5732 %}
5733 
5734 instruct cmovDI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regD dst, regD src) %{
5735   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
5736   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
5737   ins_cost(150);
5738 
5739   size(4);
5740   format %{ "FCPYD$cmp $dst,$src" %}
5741   ins_encode %{
5742     __ vmov_f64($dst$$FloatRegister, $src$$FloatRegister, (Assembler::Condition)($cmp$$cmpcode));
5743   %}
5744   ins_pipe(int_conditional_double_move);
5745 %}
5746 
5747 instruct cmovDIu_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src) %{
5748   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
5749   ins_cost(150);
5750 
5751   size(4);
5752   format %{ "FCPYD$cmp $dst,$src" %}
5753   ins_encode %{
5754     __ vmov_f64($dst$$FloatRegister, $src$$FloatRegister, (Assembler::Condition)($cmp$$cmpcode));
5755   %}
5756   ins_pipe(int_conditional_double_move);
5757 %}
5758 
5759 // Conditional move
5760 instruct cmovLP_reg(cmpOpP cmp, flagsRegP pcc, iRegL dst, iRegL src) %{
5761   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
5762   ins_cost(150);
5763 
5764   size(8);
5765   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
5766             "MOV$cmp  $dst.hi,$src.hi" %}
5767   ins_encode %{
5768     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
5769     __ mov($dst$$Register->successor(), $src$$Register->successor(), (Assembler::Condition)($cmp$$cmpcode));
5770   %}
5771   ins_pipe(ialu_reg);
5772 %}
5773 
5774 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
5775 // (hi($con$$constant), lo($con$$constant)) becomes
5776 instruct cmovLP_immRot(cmpOpP cmp, flagsRegP pcc, iRegL dst, immLlowRot src) %{
5777   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
5778   ins_cost(140);
5779 
5780   size(8);
5781   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
5782             "MOV$cmp  $dst.hi,0" %}
5783   ins_encode %{
5784     __ mov($dst$$Register, (long)$src$$constant, (Assembler::Condition)($cmp$$cmpcode));
5785     __ mov($dst$$Register->successor(), 0, (Assembler::Condition)($cmp$$cmpcode));
5786   %}
5787   ins_pipe(ialu_imm);
5788 %}
5789 
5790 instruct cmovLP_imm16(cmpOpP cmp, flagsRegP pcc, iRegL dst, immL16 src) %{
5791   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
5792   ins_cost(140);
5793 
5794   size(8);
5795   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
5796             "MOV$cmp  $dst.hi,0" %}
5797   ins_encode %{
5798     __ movw_i($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
5799     __ mov($dst$$Register->successor(), 0, (Assembler::Condition)($cmp$$cmpcode));
5800   %}
5801   ins_pipe(ialu_imm);
5802 %}
5803 
5804 instruct cmovLI_reg(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src) %{
5805   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5806   ins_cost(150);
5807 
5808   size(8);
5809   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
5810             "MOV$cmp  $dst.hi,$src.hi" %}
5811   ins_encode %{
5812     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
5813     __ mov($dst$$Register->successor(), $src$$Register->successor(), (Assembler::Condition)($cmp$$cmpcode));
5814   %}
5815   ins_pipe(ialu_reg);
5816 %}
5817 
5818 instruct cmovLI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, iRegL src) %{
5819   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5820   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
5821             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
5822             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
5823             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
5824   ins_cost(150);
5825 
5826   size(8);
5827   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
5828             "MOV$cmp  $dst.hi,$src.hi" %}
5829   ins_encode %{
5830     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
5831     __ mov($dst$$Register->successor(), $src$$Register->successor(), (Assembler::Condition)($cmp$$cmpcode));
5832   %}
5833   ins_pipe(ialu_reg);
5834 %}
5835 
5836 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
5837 // (hi($con$$constant), lo($con$$constant)) becomes
5838 instruct cmovLI_immRot(cmpOp cmp, flagsReg icc, iRegL dst, immLlowRot src) %{
5839   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5840   ins_cost(140);
5841 
5842   size(8);
5843   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
5844             "MOV$cmp  $dst.hi,0" %}
5845   ins_encode %{
5846     __ mov($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
5847     __ mov($dst$$Register->successor(), 0, (Assembler::Condition)($cmp$$cmpcode));
5848   %}
5849   ins_pipe(ialu_imm);
5850 %}
5851 
5852 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
5853 // (hi($con$$constant), lo($con$$constant)) becomes
5854 instruct cmovLI_immRot_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immLlowRot src) %{
5855   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5856   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
5857             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
5858             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
5859             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
5860   ins_cost(140);
5861 
5862   size(8);
5863   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
5864             "MOV$cmp  $dst.hi,0" %}
5865   ins_encode %{
5866     __ mov($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
5867     __ mov($dst$$Register->successor(), 0, (Assembler::Condition)($cmp$$cmpcode));
5868   %}
5869   ins_pipe(ialu_imm);
5870 %}
5871 
5872 instruct cmovLI_imm16(cmpOp cmp, flagsReg icc, iRegL dst, immL16 src) %{
5873   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5874   ins_cost(140);
5875 
5876   size(8);
5877   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
5878             "MOV$cmp  $dst.hi,0" %}
5879   ins_encode %{
5880     __ movw_i($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
5881     __ movw_i($dst$$Register->successor(), 0, (Assembler::Condition)($cmp$$cmpcode));
5882   %}
5883   ins_pipe(ialu_imm);
5884 %}
5885 
5886 instruct cmovLI_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immL16 src) %{
5887   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5888   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
5889             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
5890             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
5891             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
5892   ins_cost(140);
5893 
5894   size(8);
5895   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
5896             "MOV$cmp  $dst.hi,0" %}
5897   ins_encode %{
5898     __ movw_i($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
5899     __ movw_i($dst$$Register->successor(), 0, (Assembler::Condition)($cmp$$cmpcode));
5900   %}
5901   ins_pipe(ialu_imm);
5902 %}
5903 
5904 instruct cmovLIu_reg(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src) %{
5905   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5906   ins_cost(150);
5907 
5908   size(8);
5909   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
5910             "MOV$cmp  $dst.hi,$src.hi" %}
5911   ins_encode %{
5912     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
5913     __ mov($dst$$Register->successor(), $src$$Register->successor(), (Assembler::Condition)($cmp$$cmpcode));
5914   %}
5915   ins_pipe(ialu_reg);
5916 %}
5917 
5918 
5919 //----------OS and Locking Instructions----------------------------------------
5920 
5921 // This name is KNOWN by the ADLC and cannot be changed.
5922 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
5923 // for this guy.
5924 instruct tlsLoadP(RthreadRegP dst) %{
5925   match(Set dst (ThreadLocal));
5926 
5927   size(0);
5928   ins_cost(0);
5929   format %{ "! TLS is in $dst" %}
5930   ins_encode( /*empty encoding*/ );
5931   ins_pipe(ialu_none);
5932 %}
5933 
5934 instruct checkCastPP( iRegP dst ) %{
5935   match(Set dst (CheckCastPP dst));
5936 
5937   size(0);
5938   format %{ "! checkcastPP of $dst" %}
5939   ins_encode( /*empty encoding*/ );
5940   ins_pipe(empty);
5941 %}
5942 
5943 
5944 instruct castPP( iRegP dst ) %{
5945   match(Set dst (CastPP dst));
5946   format %{ "! castPP of $dst" %}
5947   ins_encode( /*empty encoding*/ );
5948   ins_pipe(empty);
5949 %}
5950 
5951 instruct castII( iRegI dst ) %{
5952   match(Set dst (CastII dst));
5953   format %{ "! castII of $dst" %}
5954   ins_encode( /*empty encoding*/ );
5955   ins_cost(0);
5956   ins_pipe(empty);
5957 %}
5958 
5959 //----------Arithmetic Instructions--------------------------------------------
5960 // Addition Instructions
5961 // Register Addition
5962 instruct addI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
5963   match(Set dst (AddI src1 src2));
5964 
5965   size(4);
5966   format %{ "add_32 $dst,$src1,$src2\t! int" %}
5967   ins_encode %{
5968     __ add($dst$$Register, $src1$$Register, $src2$$Register);
5969   %}
5970   ins_pipe(ialu_reg_reg);
5971 %}
5972 
5973 instruct addshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5974   match(Set dst (AddI (LShiftI src1 src2) src3));
5975 
5976   size(4);
5977   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
5978   ins_encode %{
5979     __ add($dst$$Register, $src3$$Register, $src1$$Register, lsl($src2$$Register));
5980   %}
5981   ins_pipe(ialu_reg_reg);
5982 %}
5983 
5984 instruct addshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
5985   match(Set dst (AddI (LShiftI src1 src2) src3));
5986 
5987   size(4);
5988   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
5989   ins_encode %{
5990     __ add($dst$$Register, $src3$$Register, $src1$$Register, lsl($src2$$constant));
5991   %}
5992   ins_pipe(ialu_reg_reg);
5993 %}
5994 
5995 instruct addsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5996   match(Set dst (AddI (RShiftI src1 src2) src3));
5997 
5998   size(4);
5999   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
6000   ins_encode %{
6001     __ add($dst$$Register, $src3$$Register, $src1$$Register, asr($src2$$Register));
6002   %}
6003   ins_pipe(ialu_reg_reg);
6004 %}
6005 
6006 instruct addsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
6007   match(Set dst (AddI (RShiftI src1 src2) src3));
6008 
6009   size(4);
6010   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
6011   ins_encode %{
6012     __ add($dst$$Register, $src3$$Register, $src1$$Register, asr($src2$$constant));
6013   %}
6014   ins_pipe(ialu_reg_reg);
6015 %}
6016 
6017 instruct addshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6018   match(Set dst (AddI (URShiftI src1 src2) src3));
6019 
6020   size(4);
6021   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
6022   ins_encode %{
6023     __ add($dst$$Register, $src3$$Register, $src1$$Register, lsr($src2$$Register));
6024   %}
6025   ins_pipe(ialu_reg_reg);
6026 %}
6027 
6028 instruct addshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
6029   match(Set dst (AddI (URShiftI src1 src2) src3));
6030 
6031   size(4);
6032   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
6033   ins_encode %{
6034     __ add($dst$$Register, $src3$$Register, $src1$$Register, lsr($src2$$constant));
6035   %}
6036   ins_pipe(ialu_reg_reg);
6037 %}
6038 
6039 // Immediate Addition
6040 instruct addI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
6041   match(Set dst (AddI src1 src2));
6042 
6043   size(4);
6044   format %{ "add_32 $dst,$src1,$src2\t! int" %}
6045   ins_encode %{
6046     __ add($dst$$Register, $src1$$Register, $src2$$constant);
6047   %}
6048   ins_pipe(ialu_reg_imm);
6049 %}
6050 
6051 // Pointer Register Addition
6052 instruct addP_reg_reg(iRegP dst, iRegP src1, iRegX src2) %{
6053   match(Set dst (AddP src1 src2));
6054 
6055   size(4);
6056   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
6057   ins_encode %{
6058     __ add($dst$$Register, $src1$$Register, $src2$$Register);
6059   %}
6060   ins_pipe(ialu_reg_reg);
6061 %}
6062 
6063 // shifted iRegX operand
6064 operand shiftedX(iRegX src2, shimmX src3) %{
6065 //constraint(ALLOC_IN_RC(sp_ptr_reg));
6066   match(LShiftX src2 src3);
6067 
6068   op_cost(1);
6069   format %{ "$src2 << $src3" %}
6070   interface(MEMORY_INTER) %{
6071     base($src2);
6072     index(0xff);
6073     scale($src3);
6074     disp(0x0);
6075   %}
6076 %}
6077 
6078 instruct addshlP_reg_reg_imm(iRegP dst, iRegP src1, shiftedX src2) %{
6079   match(Set dst (AddP src1 src2));
6080 
6081   ins_cost(DEFAULT_COST * 3/2);
6082   size(4);
6083   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
6084   ins_encode %{
6085     Register base = reg_to_register_object($src2$$base);
6086     __ add($dst$$Register, $src1$$Register, base, lsl($src2$$scale));
6087   %}
6088   ins_pipe(ialu_reg_reg);
6089 %}
6090 
6091 // Pointer Immediate Addition
6092 instruct addP_reg_aimmX(iRegP dst, iRegP src1, aimmX src2) %{
6093   match(Set dst (AddP src1 src2));
6094 
6095   size(4);
6096   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
6097   ins_encode %{
6098     __ add($dst$$Register, $src1$$Register, $src2$$constant);
6099   %}
6100   ins_pipe(ialu_reg_imm);
6101 %}
6102 
6103 // Long Addition
6104 instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg ccr) %{
6105   match(Set dst (AddL src1 src2));
6106   effect(KILL ccr);
6107   ins_cost(DEFAULT_COST*2);
6108   size(8);
6109   format %{ "ADDS    $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
6110             "ADC     $dst.hi,$src1.hi,$src2.hi" %}
6111   ins_encode %{
6112     __ adds($dst$$Register, $src1$$Register, $src2$$Register);
6113     __ adc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
6114   %}
6115   ins_pipe(ialu_reg_reg);
6116 %}
6117 
6118 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6119 // (hi($con$$constant), lo($con$$constant)) becomes
6120 instruct addL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg ccr) %{
6121   match(Set dst (AddL src1 con));
6122   effect(KILL ccr);
6123   size(8);
6124   format %{ "ADDS    $dst.lo,$src1.lo,$con\t! long\n\t"
6125             "ADC     $dst.hi,$src1.hi,0" %}
6126   ins_encode %{
6127     __ adds($dst$$Register, $src1$$Register, (long)$con$$constant);
6128     __ adc($dst$$Register->successor(), $src1$$Register->successor(), 0);
6129   %}
6130   ins_pipe(ialu_reg_imm);
6131 %}
6132 
6133 //----------Conditional_store--------------------------------------------------
6134 // Conditional-store of the updated heap-top.
6135 // Used during allocation of the shared heap.
6136 // Sets flags (EQ) on success.
6137 
6138 // TODO: optimize out barriers with AArch64 load-acquire/store-release
6139 // LoadP-locked.
6140 instruct loadPLocked(iRegP dst, memoryex mem) %{
6141   match(Set dst (LoadPLocked mem));
6142   size(4);
6143   format %{ "LDREX  $dst,$mem" %}
6144   ins_encode %{
6145     __ ldrex($dst$$Register,$mem$$Address);
6146   %}
6147   ins_pipe(iload_mem);
6148 %}
6149 
6150 instruct storePConditional( memoryex heap_top_ptr, iRegP oldval, iRegP newval, iRegI tmp, flagsRegP pcc ) %{
6151   predicate(_kids[1]->_kids[0]->_leaf->Opcode() == Op_LoadPLocked); // only works in conjunction with a LoadPLocked node
6152   match(Set pcc (StorePConditional heap_top_ptr (Binary oldval newval)));
6153   effect( TEMP tmp );
6154   size(8);
6155   format %{ "STREX  $tmp,$newval,$heap_top_ptr\n\t"
6156             "CMP    $tmp, 0" %}
6157   ins_encode %{
6158     __ strex($tmp$$Register, $newval$$Register, $heap_top_ptr$$Address);
6159     __ cmp($tmp$$Register, 0);
6160   %}
6161   ins_pipe( long_memory_op );
6162 %}
6163 
6164 // Conditional-store of an intx value.
6165 instruct storeXConditional( memoryex mem, iRegX oldval, iRegX newval, iRegX tmp, flagsReg icc ) %{
6166   match(Set icc (StoreIConditional mem (Binary oldval newval)));
6167   effect( TEMP tmp );
6168   size(28);
6169   format %{ "loop: \n\t"
6170             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem], DOESN'T set $newval=[$mem] in any case\n\t"
6171             "XORS     $tmp,$tmp, $oldval\n\t"
6172             "STREX.eq $tmp, $newval, $mem\n\t"
6173             "CMP.eq   $tmp, 1 \n\t"
6174             "B.eq     loop \n\t"
6175             "TEQ      $tmp, 0\n\t"
6176             "membar   LoadStore|LoadLoad" %}
6177   ins_encode %{
6178     Label loop;
6179     __ bind(loop);
6180     __ ldrex($tmp$$Register, $mem$$Address);
6181     __ eors($tmp$$Register, $tmp$$Register, $oldval$$Register);
6182     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, Assembler::EQ);
6183     __ cmp($tmp$$Register, 1, Assembler::EQ);
6184     __ b(loop, Assembler::EQ);
6185     __ teq($tmp$$Register, 0);
6186     // used by biased locking only. Requires a membar.
6187     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadStore | MacroAssembler::LoadLoad));
6188   %}
6189   ins_pipe( long_memory_op );
6190 %}
6191 
6192 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
6193 
6194 instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegLd newval, iRegI res, iRegLd tmp, flagsReg ccr ) %{
6195   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
6196   effect( KILL ccr, TEMP tmp);
6197   size(32);
6198   format %{ "loop: \n\t"
6199             "LDREXD   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
6200             "CMP      $tmp.lo, $oldval.lo\n\t"
6201             "CMP.eq   $tmp.hi, $oldval.hi\n\t"
6202             "STREXD.eq $tmp, $newval, $mem\n\t"
6203             "MOV.ne   $tmp, 0 \n\t"
6204             "XORS.eq  $tmp,$tmp, 1 \n\t"
6205             "B.eq     loop \n\t"
6206             "MOV      $res, $tmp" %}
6207   ins_encode %{
6208     Label loop;
6209     __ bind(loop);
6210     __ ldrexd($tmp$$Register, $mem$$Address);
6211     __ cmp($tmp$$Register, $oldval$$Register);
6212     __ cmp($tmp$$Register->successor(), $oldval$$Register->successor(), Assembler::EQ);
6213     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address, Assembler::EQ);
6214     __ mov($tmp$$Register, 0, Assembler::NE);
6215     __ eors($tmp$$Register, $tmp$$Register, 1, Assembler::EQ);
6216     __ b(loop, Assembler::EQ);
6217     __ mov($res$$Register, $tmp$$Register);
6218   %}
6219   ins_pipe( long_memory_op );
6220 %}
6221 
6222 
6223 instruct compareAndSwapI_bool(memoryex mem, iRegI oldval, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
6224   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
6225   effect( KILL ccr, TEMP tmp);
6226   size(28);
6227   format %{ "loop: \n\t"
6228             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
6229             "CMP      $tmp, $oldval\n\t"
6230             "STREX.eq $tmp, $newval, $mem\n\t"
6231             "MOV.ne   $tmp, 0 \n\t"
6232             "XORS.eq  $tmp,$tmp, 1 \n\t"
6233             "B.eq     loop \n\t"
6234             "MOV      $res, $tmp" %}
6235 
6236   ins_encode %{
6237     Label loop;
6238     __ bind(loop);
6239     __ ldrex($tmp$$Register,$mem$$Address);
6240     __ cmp($tmp$$Register, $oldval$$Register);
6241     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, Assembler::EQ);
6242     __ mov($tmp$$Register, 0, Assembler::NE);
6243     __ eors($tmp$$Register, $tmp$$Register, 1, Assembler::EQ);
6244     __ b(loop, Assembler::EQ);
6245     __ mov($res$$Register, $tmp$$Register);
6246   %}
6247   ins_pipe( long_memory_op );
6248 %}
6249 
6250 instruct compareAndSwapP_bool(memoryex mem, iRegP oldval, iRegP newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
6251   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
6252   effect( KILL ccr, TEMP tmp);
6253   size(28);
6254   format %{ "loop: \n\t"
6255             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
6256             "CMP      $tmp, $oldval\n\t"
6257             "STREX.eq $tmp, $newval, $mem\n\t"
6258             "MOV.ne   $tmp, 0 \n\t"
6259             "EORS.eq  $tmp,$tmp, 1 \n\t"
6260             "B.eq     loop \n\t"
6261             "MOV      $res, $tmp" %}
6262 
6263   ins_encode %{
6264     Label loop;
6265     __ bind(loop);
6266     __ ldrex($tmp$$Register,$mem$$Address);
6267     __ cmp($tmp$$Register, $oldval$$Register);
6268     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, Assembler::EQ);
6269     __ mov($tmp$$Register, 0, Assembler::NE);
6270     __ eors($tmp$$Register, $tmp$$Register, 1, Assembler::EQ);
6271     __ b(loop, Assembler::EQ);
6272     __ mov($res$$Register, $tmp$$Register);
6273   %}
6274   ins_pipe( long_memory_op );
6275 %}
6276 
6277 instruct xaddI_aimmI_no_res(memoryex mem, aimmI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
6278   predicate(n->as_LoadStore()->result_not_used());
6279   match(Set dummy (GetAndAddI mem add));
6280   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
6281   size(20);
6282   format %{ "loop: \n\t"
6283             "LDREX    $tmp1, $mem\n\t"
6284             "ADD      $tmp1, $tmp1, $add\n\t"
6285             "STREX    $tmp2, $tmp1, $mem\n\t"
6286             "CMP      $tmp2, 0 \n\t"
6287             "B.ne     loop \n\t" %}
6288 
6289   ins_encode %{
6290     Label loop;
6291     __ bind(loop);
6292     __ ldrex($tmp1$$Register,$mem$$Address);
6293     __ add($tmp1$$Register, $tmp1$$Register, $add$$constant);
6294     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
6295     __ cmp($tmp2$$Register, 0);
6296     __ b(loop, Assembler::NE);
6297   %}
6298   ins_pipe( long_memory_op );
6299 %}
6300 
6301 instruct xaddI_reg_no_res(memoryex mem, iRegI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
6302   predicate(n->as_LoadStore()->result_not_used());
6303   match(Set dummy (GetAndAddI mem add));
6304   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
6305   size(20);
6306   format %{ "loop: \n\t"
6307             "LDREX    $tmp1, $mem\n\t"
6308             "ADD      $tmp1, $tmp1, $add\n\t"
6309             "STREX    $tmp2, $tmp1, $mem\n\t"
6310             "CMP      $tmp2, 0 \n\t"
6311             "B.ne     loop \n\t" %}
6312 
6313   ins_encode %{
6314     Label loop;
6315     __ bind(loop);
6316     __ ldrex($tmp1$$Register,$mem$$Address);
6317     __ add($tmp1$$Register, $tmp1$$Register, $add$$Register);
6318     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
6319     __ cmp($tmp2$$Register, 0);
6320     __ b(loop, Assembler::NE);
6321   %}
6322   ins_pipe( long_memory_op );
6323 %}
6324 
6325 instruct xaddI_aimmI(memoryex mem, aimmI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
6326   match(Set res (GetAndAddI mem add));
6327   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
6328   size(20);
6329   format %{ "loop: \n\t"
6330             "LDREX    $res, $mem\n\t"
6331             "ADD      $tmp1, $res, $add\n\t"
6332             "STREX    $tmp2, $tmp1, $mem\n\t"
6333             "CMP      $tmp2, 0 \n\t"
6334             "B.ne     loop \n\t" %}
6335 
6336   ins_encode %{
6337     Label loop;
6338     __ bind(loop);
6339     __ ldrex($res$$Register,$mem$$Address);
6340     __ add($tmp1$$Register, $res$$Register, $add$$constant);
6341     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
6342     __ cmp($tmp2$$Register, 0);
6343     __ b(loop, Assembler::NE);
6344   %}
6345   ins_pipe( long_memory_op );
6346 %}
6347 
6348 instruct xaddI_reg(memoryex mem, iRegI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
6349   match(Set res (GetAndAddI mem add));
6350   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
6351   size(20);
6352   format %{ "loop: \n\t"
6353             "LDREX    $res, $mem\n\t"
6354             "ADD      $tmp1, $res, $add\n\t"
6355             "STREX    $tmp2, $tmp1, $mem\n\t"
6356             "CMP      $tmp2, 0 \n\t"
6357             "B.ne     loop \n\t" %}
6358 
6359   ins_encode %{
6360     Label loop;
6361     __ bind(loop);
6362     __ ldrex($res$$Register,$mem$$Address);
6363     __ add($tmp1$$Register, $res$$Register, $add$$Register);
6364     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
6365     __ cmp($tmp2$$Register, 0);
6366     __ b(loop, Assembler::NE);
6367   %}
6368   ins_pipe( long_memory_op );
6369 %}
6370 
6371 instruct xaddL_reg_no_res(memoryex mem, iRegL add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
6372   predicate(n->as_LoadStore()->result_not_used());
6373   match(Set dummy (GetAndAddL mem add));
6374   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
6375   size(24);
6376   format %{ "loop: \n\t"
6377             "LDREXD   $tmp1, $mem\n\t"
6378             "ADDS     $tmp1.lo, $tmp1.lo, $add.lo\n\t"
6379             "ADC      $tmp1.hi, $tmp1.hi, $add.hi\n\t"
6380             "STREXD   $tmp2, $tmp1, $mem\n\t"
6381             "CMP      $tmp2, 0 \n\t"
6382             "B.ne     loop \n\t" %}
6383 
6384   ins_encode %{
6385     Label loop;
6386     __ bind(loop);
6387     __ ldrexd($tmp1$$Register, $mem$$Address);
6388     __ adds($tmp1$$Register, $tmp1$$Register, $add$$Register);
6389     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), $add$$Register->successor());
6390     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
6391     __ cmp($tmp2$$Register, 0);
6392     __ b(loop, Assembler::NE);
6393   %}
6394   ins_pipe( long_memory_op );
6395 %}
6396 
6397 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6398 // (hi($con$$constant), lo($con$$constant)) becomes
6399 instruct xaddL_immRot_no_res(memoryex mem, immLlowRot add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
6400   predicate(n->as_LoadStore()->result_not_used());
6401   match(Set dummy (GetAndAddL mem add));
6402   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
6403   size(24);
6404   format %{ "loop: \n\t"
6405             "LDREXD   $tmp1, $mem\n\t"
6406             "ADDS     $tmp1.lo, $tmp1.lo, $add\n\t"
6407             "ADC      $tmp1.hi, $tmp1.hi, 0\n\t"
6408             "STREXD   $tmp2, $tmp1, $mem\n\t"
6409             "CMP      $tmp2, 0 \n\t"
6410             "B.ne     loop \n\t" %}
6411 
6412   ins_encode %{
6413     Label loop;
6414     __ bind(loop);
6415     __ ldrexd($tmp1$$Register, $mem$$Address);
6416     __ adds($tmp1$$Register, $tmp1$$Register, (long)$add$$constant);
6417     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), 0);
6418     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
6419     __ cmp($tmp2$$Register, 0);
6420     __ b(loop, Assembler::NE);
6421   %}
6422   ins_pipe( long_memory_op );
6423 %}
6424 
6425 instruct xaddL_reg(memoryex mem, iRegL add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
6426   match(Set res (GetAndAddL mem add));
6427   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
6428   size(24);
6429   format %{ "loop: \n\t"
6430             "LDREXD   $res, $mem\n\t"
6431             "ADDS     $tmp1.lo, $res.lo, $add.lo\n\t"
6432             "ADC      $tmp1.hi, $res.hi, $add.hi\n\t"
6433             "STREXD   $tmp2, $tmp1, $mem\n\t"
6434             "CMP      $tmp2, 0 \n\t"
6435             "B.ne     loop \n\t" %}
6436 
6437   ins_encode %{
6438     Label loop;
6439     __ bind(loop);
6440     __ ldrexd($res$$Register, $mem$$Address);
6441     __ adds($tmp1$$Register, $res$$Register, $add$$Register);
6442     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), $add$$Register->successor());
6443     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
6444     __ cmp($tmp2$$Register, 0);
6445     __ b(loop, Assembler::NE);
6446   %}
6447   ins_pipe( long_memory_op );
6448 %}
6449 
6450 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6451 // (hi($con$$constant), lo($con$$constant)) becomes
6452 instruct xaddL_immRot(memoryex mem, immLlowRot add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
6453   match(Set res (GetAndAddL mem add));
6454   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
6455   size(24);
6456   format %{ "loop: \n\t"
6457             "LDREXD   $res, $mem\n\t"
6458             "ADDS     $tmp1.lo, $res.lo, $add\n\t"
6459             "ADC      $tmp1.hi, $res.hi, 0\n\t"
6460             "STREXD   $tmp2, $tmp1, $mem\n\t"
6461             "CMP      $tmp2, 0 \n\t"
6462             "B.ne     loop \n\t" %}
6463 
6464   ins_encode %{
6465     Label loop;
6466     __ bind(loop);
6467     __ ldrexd($res$$Register, $mem$$Address);
6468     __ adds($tmp1$$Register, $res$$Register, (long)$add$$constant);
6469     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), 0);
6470     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
6471     __ cmp($tmp2$$Register, 0);
6472     __ b(loop, Assembler::NE);
6473   %}
6474   ins_pipe( long_memory_op );
6475 %}
6476 
6477 instruct xchgI(memoryex mem, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr) %{
6478   match(Set res (GetAndSetI mem newval));
6479   effect(KILL ccr, TEMP tmp, TEMP res);
6480   size(16);
6481   format %{ "loop: \n\t"
6482             "LDREX    $res, $mem\n\t"
6483             "STREX    $tmp, $newval, $mem\n\t"
6484             "CMP      $tmp, 0 \n\t"
6485             "B.ne     loop \n\t" %}
6486 
6487   ins_encode %{
6488     Label loop;
6489     __ bind(loop);
6490     __ ldrex($res$$Register,$mem$$Address);
6491     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
6492     __ cmp($tmp$$Register, 0);
6493     __ b(loop, Assembler::NE);
6494   %}
6495   ins_pipe( long_memory_op );
6496 %}
6497 
6498 instruct xchgL(memoryex mem, iRegLd newval, iRegLd res, iRegI tmp, flagsReg ccr) %{
6499   match(Set res (GetAndSetL mem newval));
6500   effect( KILL ccr, TEMP tmp, TEMP res);
6501   size(16);
6502   format %{ "loop: \n\t"
6503             "LDREXD   $res, $mem\n\t"
6504             "STREXD   $tmp, $newval, $mem\n\t"
6505             "CMP      $tmp, 0 \n\t"
6506             "B.ne     loop \n\t" %}
6507 
6508   ins_encode %{
6509     Label loop;
6510     __ bind(loop);
6511     __ ldrexd($res$$Register, $mem$$Address);
6512     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address);
6513     __ cmp($tmp$$Register, 0);
6514     __ b(loop, Assembler::NE);
6515   %}
6516   ins_pipe( long_memory_op );
6517 %}
6518 
6519 instruct xchgP(memoryex mem, iRegP newval, iRegP res, iRegI tmp, flagsReg ccr) %{
6520   match(Set res (GetAndSetP mem newval));
6521   effect(KILL ccr, TEMP tmp, TEMP res);
6522   size(16);
6523   format %{ "loop: \n\t"
6524             "LDREX    $res, $mem\n\t"
6525             "STREX    $tmp, $newval, $mem\n\t"
6526             "CMP      $tmp, 0 \n\t"
6527             "B.ne     loop \n\t" %}
6528 
6529   ins_encode %{
6530     Label loop;
6531     __ bind(loop);
6532     __ ldrex($res$$Register,$mem$$Address);
6533     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
6534     __ cmp($tmp$$Register, 0);
6535     __ b(loop, Assembler::NE);
6536   %}
6537   ins_pipe( long_memory_op );
6538 %}
6539 
6540 //---------------------
6541 // Subtraction Instructions
6542 // Register Subtraction
6543 instruct subI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6544   match(Set dst (SubI src1 src2));
6545 
6546   size(4);
6547   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
6548   ins_encode %{
6549     __ sub($dst$$Register, $src1$$Register, $src2$$Register);
6550   %}
6551   ins_pipe(ialu_reg_reg);
6552 %}
6553 
6554 instruct subshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6555   match(Set dst (SubI src1 (LShiftI src2 src3)));
6556 
6557   size(4);
6558   format %{ "SUB    $dst,$src1,$src2<<$src3" %}
6559   ins_encode %{
6560     __ sub($dst$$Register, $src1$$Register, $src2$$Register, lsl($src3$$Register));
6561   %}
6562   ins_pipe(ialu_reg_reg);
6563 %}
6564 
6565 instruct subshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6566   match(Set dst (SubI src1 (LShiftI src2 src3)));
6567 
6568   size(4);
6569   format %{ "sub_32 $dst,$src1,$src2<<$src3\t! int" %}
6570   ins_encode %{
6571     __ sub($dst$$Register, $src1$$Register, $src2$$Register, lsl($src3$$constant));
6572   %}
6573   ins_pipe(ialu_reg_reg);
6574 %}
6575 
6576 instruct subsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6577   match(Set dst (SubI src1 (RShiftI src2 src3)));
6578 
6579   size(4);
6580   format %{ "SUB    $dst,$src1,$src2>>$src3" %}
6581   ins_encode %{
6582     __ sub($dst$$Register, $src1$$Register, $src2$$Register, asr($src3$$Register));
6583   %}
6584   ins_pipe(ialu_reg_reg);
6585 %}
6586 
6587 instruct subsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6588   match(Set dst (SubI src1 (RShiftI src2 src3)));
6589 
6590   size(4);
6591   format %{ "sub_32 $dst,$src1,$src2>>$src3\t! int" %}
6592   ins_encode %{
6593     __ sub($dst$$Register, $src1$$Register, $src2$$Register, asr($src3$$constant));
6594   %}
6595   ins_pipe(ialu_reg_reg);
6596 %}
6597 
6598 instruct subshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6599   match(Set dst (SubI src1 (URShiftI src2 src3)));
6600 
6601   size(4);
6602   format %{ "SUB    $dst,$src1,$src2>>>$src3" %}
6603   ins_encode %{
6604     __ sub($dst$$Register, $src1$$Register, $src2$$Register, lsr($src3$$Register));
6605   %}
6606   ins_pipe(ialu_reg_reg);
6607 %}
6608 
6609 instruct subshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6610   match(Set dst (SubI src1 (URShiftI src2 src3)));
6611 
6612   size(4);
6613   format %{ "sub_32 $dst,$src1,$src2>>>$src3\t! int" %}
6614   ins_encode %{
6615     __ sub($dst$$Register, $src1$$Register, $src2$$Register, lsr($src3$$constant));
6616   %}
6617   ins_pipe(ialu_reg_reg);
6618 %}
6619 
6620 instruct rsbshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6621   match(Set dst (SubI (LShiftI src1 src2) src3));
6622 
6623   size(4);
6624   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
6625   ins_encode %{
6626     __ rsb($dst$$Register, $src3$$Register, $src1$$Register, lsl($src2$$Register));
6627   %}
6628   ins_pipe(ialu_reg_reg);
6629 %}
6630 
6631 instruct rsbshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
6632   match(Set dst (SubI (LShiftI src1 src2) src3));
6633 
6634   size(4);
6635   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
6636   ins_encode %{
6637     __ rsb($dst$$Register, $src3$$Register, $src1$$Register, lsl($src2$$constant));
6638   %}
6639   ins_pipe(ialu_reg_reg);
6640 %}
6641 
6642 instruct rsbsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6643   match(Set dst (SubI (RShiftI src1 src2) src3));
6644 
6645   size(4);
6646   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
6647   ins_encode %{
6648     __ rsb($dst$$Register, $src3$$Register, $src1$$Register, asr($src2$$Register));
6649   %}
6650   ins_pipe(ialu_reg_reg);
6651 %}
6652 
6653 instruct rsbsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
6654   match(Set dst (SubI (RShiftI src1 src2) src3));
6655 
6656   size(4);
6657   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
6658   ins_encode %{
6659     __ rsb($dst$$Register, $src3$$Register, $src1$$Register, asr($src2$$constant));
6660   %}
6661   ins_pipe(ialu_reg_reg);
6662 %}
6663 
6664 instruct rsbshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6665   match(Set dst (SubI (URShiftI src1 src2) src3));
6666 
6667   size(4);
6668   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
6669   ins_encode %{
6670     __ rsb($dst$$Register, $src3$$Register, $src1$$Register, lsr($src2$$Register));
6671   %}
6672   ins_pipe(ialu_reg_reg);
6673 %}
6674 
6675 instruct rsbshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
6676   match(Set dst (SubI (URShiftI src1 src2) src3));
6677 
6678   size(4);
6679   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
6680   ins_encode %{
6681     __ rsb($dst$$Register, $src3$$Register, $src1$$Register, lsr($src2$$constant));
6682   %}
6683   ins_pipe(ialu_reg_reg);
6684 %}
6685 
6686 // Immediate Subtraction
6687 instruct subI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
6688   match(Set dst (SubI src1 src2));
6689 
6690   size(4);
6691   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
6692   ins_encode %{
6693     __ sub($dst$$Register, $src1$$Register, $src2$$constant);
6694   %}
6695   ins_pipe(ialu_reg_imm);
6696 %}
6697 
6698 instruct subI_reg_immRotneg(iRegI dst, iRegI src1, aimmIneg src2) %{
6699   match(Set dst (AddI src1 src2));
6700 
6701   size(4);
6702   format %{ "sub_32 $dst,$src1,-($src2)\t! int" %}
6703   ins_encode %{
6704     __ sub($dst$$Register, $src1$$Register, -$src2$$constant);
6705   %}
6706   ins_pipe(ialu_reg_imm);
6707 %}
6708 
6709 instruct subI_immRot_reg(iRegI dst, immIRot src1, iRegI src2) %{
6710   match(Set dst (SubI src1 src2));
6711 
6712   size(4);
6713   format %{ "RSB    $dst,$src2,src1" %}
6714   ins_encode %{
6715     __ rsb($dst$$Register, $src2$$Register, $src1$$constant);
6716   %}
6717   ins_pipe(ialu_zero_reg);
6718 %}
6719 
6720 // Register Subtraction
6721 instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg icc ) %{
6722   match(Set dst (SubL src1 src2));
6723   effect (KILL icc);
6724 
6725   size(8);
6726   format %{ "SUBS   $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
6727             "SBC    $dst.hi,$src1.hi,$src2.hi" %}
6728   ins_encode %{
6729     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
6730     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
6731   %}
6732   ins_pipe(ialu_reg_reg);
6733 %}
6734 
6735 // Immediate Subtraction
6736 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6737 // (hi($con$$constant), lo($con$$constant)) becomes
6738 instruct subL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg icc) %{
6739   match(Set dst (SubL src1 con));
6740   effect (KILL icc);
6741 
6742   size(8);
6743   format %{ "SUB    $dst.lo,$src1.lo,$con\t! long\n\t"
6744             "SBC    $dst.hi,$src1.hi,0" %}
6745   ins_encode %{
6746     __ subs($dst$$Register, $src1$$Register, (long)$con$$constant);
6747     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), 0);
6748   %}
6749   ins_pipe(ialu_reg_imm);
6750 %}
6751 
6752 // Long negation
6753 instruct negL_reg_reg(iRegL dst, immL0 zero, iRegL src2, flagsReg icc) %{
6754   match(Set dst (SubL zero src2));
6755   effect (KILL icc);
6756 
6757   size(8);
6758   format %{ "RSBS   $dst.lo,$src2.lo,0\t! long\n\t"
6759             "RSC    $dst.hi,$src2.hi,0" %}
6760   ins_encode %{
6761     __ rsbs($dst$$Register, $src2$$Register, 0);
6762     __ rsc($dst$$Register->successor(), $src2$$Register->successor(), 0);
6763   %}
6764   ins_pipe(ialu_zero_reg);
6765 %}
6766 
6767 // Multiplication Instructions
6768 // Integer Multiplication
6769 // Register Multiplication
6770 instruct mulI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6771   match(Set dst (MulI src1 src2));
6772 
6773   ins_cost(DEFAULT_COST);
6774   size(4);
6775   format %{ "mul_32 $dst,$src1,$src2" %}
6776   ins_encode %{
6777     __ mul($dst$$Register, $src1$$Register, $src2$$Register);
6778   %}
6779   ins_pipe(imul_reg_reg);
6780 %}
6781 
6782 instruct mulL_lo1_hi2(iRegL dst, iRegL src1, iRegL src2) %{
6783   effect(DEF dst, USE src1, USE src2);
6784   ins_cost(DEFAULT_COST);
6785   size(4);
6786   format %{ "MUL  $dst.hi,$src1.lo,$src2.hi\t! long" %}
6787   ins_encode %{
6788     __ mul($dst$$Register->successor(), $src1$$Register, $src2$$Register->successor());
6789   %}
6790   ins_pipe(imul_reg_reg);
6791 %}
6792 
6793 instruct mulL_hi1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
6794   effect(USE_DEF dst, USE src1, USE src2);
6795   ins_cost(DEFAULT_COST*3/2);
6796   size(8);
6797   format %{ "MLA  $dst.hi,$src1.hi,$src2.lo,$dst.hi\t! long\n\t"
6798             "MOV  $dst.lo, 0"%}
6799   ins_encode %{
6800     __ mla($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register, $dst$$Register->successor());
6801     __ mov($dst$$Register, 0);
6802   %}
6803   ins_pipe(imul_reg_reg);
6804 %}
6805 
6806 instruct mulL_lo1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
6807   effect(USE_DEF dst, USE src1, USE src2);
6808   ins_cost(DEFAULT_COST*3/2);
6809   size(4);
6810   format %{ "UMLAL  $dst.lo,$dst.hi,$src1,$src2\t! long" %}
6811   ins_encode %{
6812     __ umlal($dst$$Register, $dst$$Register->successor(), $src1$$Register, $src2$$Register);
6813   %}
6814   ins_pipe(imul_reg_reg);
6815 %}
6816 
6817 instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
6818   match(Set dst (MulL src1 src2));
6819   ins_cost(DEFAULT_COST*8/2);
6820 
6821   expand %{
6822     mulL_lo1_hi2(dst, src1, src2);
6823     mulL_hi1_lo2(dst, src1, src2);
6824     mulL_lo1_lo2(dst, src1, src2);
6825   %}
6826 %}
6827 
6828 instruct mla_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI srcA) %{
6829   match(Set dst (AddI (MulI src1 src2) srcA));
6830 
6831   ins_cost(DEFAULT_COST*3/2);
6832   size(4);
6833   format %{ "MLA $dst,$src1,$src2,$srcA" %}
6834   ins_encode %{
6835     __ mla($dst$$Register, $src1$$Register, $src2$$Register, $srcA$$Register);
6836   %}
6837   ins_pipe(ialu_reg_reg);
6838 %}
6839 
6840 instruct mls_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI srcA) %{
6841   match(Set dst (SubI srcA (MulI src1 src2)));
6842 
6843   ins_cost(DEFAULT_COST*3/2);
6844   size(4);
6845   format %{ "MLS $dst,$src1,$src2,$srcA" %}
6846   ins_encode %{
6847     __ mls($dst$$Register, $src1$$Register, $src2$$Register, $srcA$$Register);
6848   %}
6849   ins_pipe(ialu_reg_reg);
6850 %}
6851 
6852 instruct smlal_reg_reg_reg(iRegL dst, iRegI src1, iRegI src2) %{
6853   match(Set dst (AddL (MulL (ConvI2L src1) (ConvI2L src2)) dst));
6854 
6855   ins_cost(DEFAULT_COST*3/2);
6856   size(4);
6857   format %{ "SMLAL $dst.lo,$dst.hi,$src1,$src2" %}
6858   ins_encode %{
6859     __ smlal($dst$$Register, $dst$$Register->successor(), $src1$$Register, $src2$$Register);
6860   %}
6861   ins_pipe(ialu_reg_reg);
6862 %}
6863 
6864 instruct smull_reg_reg_reg(iRegL dst, iRegI src1, iRegI src2) %{
6865   match(Set dst (MulL (ConvI2L src1) (ConvI2L src2)));
6866 
6867   ins_cost(DEFAULT_COST*3/2);
6868   size(4);
6869   format %{ "SMULL $dst.lo,$dst.hi,$src1,$src2" %}
6870   ins_encode %{
6871     __ smull($dst$$Register, $dst$$Register->successor(), $src1$$Register, $src2$$Register);
6872   %}
6873   ins_pipe(ialu_reg_reg);
6874 %}
6875 
6876 // Integer Division
6877 // Register Division
6878 instruct divI_reg_reg_IDIV(iRegI dst, iRegI src1, iRegI src2) %{
6879   match(Set dst (DivI src1 src2));
6880   predicate(VM_Version::features() & FT_HW_DIVIDE);
6881   ins_cost(2*DEFAULT_COST);
6882 
6883   format %{ "SDIV   $dst,$src1,$src2"%}
6884   ins_encode %{
6885     __ sdiv($dst$$Register, $src1$$Register, $src2$$Register);
6886   %}
6887   ins_pipe(sdiv_reg_reg_IDIV);
6888 %}
6889 
6890 instruct divI_reg_reg_SW(R0RegI dst, R1RegI src1, R2RegI src2, R9RegI temp1, R12RegI temp2, LRRegP lr, flagsReg ccr) %{
6891   match(Set dst (DivI src1 src2));
6892   predicate(!(VM_Version::features() & FT_HW_DIVIDE));
6893   effect( KILL ccr, TEMP temp1, TEMP temp2, USE_KILL src1,USE_KILL src2, KILL lr);
6894   ins_cost((2+71)*DEFAULT_COST);
6895 
6896   format %{ "DIV   $dst,$src1,$src2 ! call to StubRoutines::aarch32::idiv_entry()" %}
6897   ins_encode %{
6898     __ call(StubRoutines::aarch32::idiv_entry(), relocInfo::runtime_call_type);
6899   %}
6900   ins_pipe(sdiv_reg_reg_SW);
6901 %}
6902 
6903 // Register Long Division
6904 instruct divL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
6905   match(Set dst (DivL src1 src2));
6906   effect(CALL);
6907   ins_cost(DEFAULT_COST*71);
6908   format %{ "DIVL  $src1,$src2,$dst\t! long ! call to SharedRuntime::ldiv" %}
6909   ins_encode %{
6910     address target = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);
6911     __ call(target, relocInfo::runtime_call_type);
6912   %}
6913   ins_pipe(divL_reg_reg);
6914 %}
6915 
6916 // Integer Remainder
6917 // Register Remainder
6918 instruct modI_reg_reg_IDIV(iRegI dst, iRegI src1, iRegI src2, iRegI temp) %{
6919   match(Set dst (ModI src1 src2));
6920   predicate(VM_Version::features() & FT_HW_DIVIDE);
6921   effect( TEMP temp);
6922 
6923   format %{ "SDIV   $temp,$src1,$src2\n\t"
6924             "MLS    $dst, $temp, $src2, $src1"%}
6925   ins_encode %{
6926     __ sdiv($temp$$Register, $src1$$Register, $src2$$Register);
6927     __ mls($dst$$Register, $temp$$Register, $src2$$Register, $src1$$Register);
6928   %}
6929   ins_pipe(sdiv_reg_reg_IDIV);
6930 %}
6931 
6932 instruct modI_reg_reg_SW(R0RegI dst, R1RegI src1, R2RegI src2, R9RegI temp1, R12RegI temp2, LRRegP lr, flagsReg ccr ) %{
6933   match(Set dst (ModI src1 src2));
6934   predicate(!(VM_Version::features() & FT_HW_DIVIDE));
6935   effect( KILL ccr, TEMP temp1, TEMP temp2, KILL lr, USE_KILL src1, USE_KILL src2);
6936 
6937   format %{ "MODI   $dst,$src1,$src2\t ! call to StubRoutines::aarch32::irem_entry" %}
6938   ins_encode %{
6939     __ call(StubRoutines::aarch32::irem_entry(), relocInfo::runtime_call_type);
6940   %}
6941   ins_pipe(sdiv_reg_reg_SW);
6942 %}
6943 
6944 // Register Long Remainder
6945 instruct modL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
6946   match(Set dst (ModL src1 src2));
6947   effect(CALL);
6948   ins_cost(MEMORY_REF_COST); // FIXME
6949   format %{ "modL    $dst,$src1,$src2\t ! call to SharedRuntime::lrem" %}
6950   ins_encode %{
6951     address target = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
6952     __ call(target, relocInfo::runtime_call_type);
6953   %}
6954   ins_pipe(divL_reg_reg);
6955 %}
6956 
6957 // Integer Shift Instructions
6958 
6959 // Register Shift Left
6960 instruct shlI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6961   match(Set dst (LShiftI src1 src2));
6962 
6963   size(4);
6964   format %{ "LSL  $dst,$src1,$src2 \n\t" %}
6965   ins_encode %{
6966     __ mov($dst$$Register, $src1$$Register, lsl($src2$$Register));
6967   %}
6968   ins_pipe(ialu_reg_reg);
6969 %}
6970 
6971 // Register Shift Left Immediate
6972 instruct shlI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
6973   match(Set dst (LShiftI src1 src2));
6974 
6975   size(4);
6976   format %{ "LSL    $dst,$src1,$src2\t! int" %}
6977   ins_encode %{
6978     __ lsl($dst$$Register, $src1$$Register, $src2$$constant);
6979   %}
6980   ins_pipe(ialu_reg_imm);
6981 %}
6982 
6983 instruct shlL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
6984   effect(USE_DEF dst, USE src1, USE src2);
6985   size(4);
6986   format %{"OR  $dst.hi,$dst.hi,($src1.hi << $src2)"  %}
6987   ins_encode %{
6988     __ orr($dst$$Register->successor(), $dst$$Register->successor(), $src1$$Register->successor(), lsl($src2$$Register));
6989   %}
6990   ins_pipe(ialu_reg_reg);
6991 %}
6992 
6993 instruct shlL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
6994   effect(USE_DEF dst, USE src1, USE src2);
6995   size(4);
6996   format %{ "LSL  $dst.lo,$src1.lo,$src2 \n\t" %}
6997   ins_encode %{
6998     __ mov($dst$$Register, $src1$$Register, lsl($src2$$Register));
6999   %}
7000   ins_pipe(ialu_reg_reg);
7001 %}
7002 
7003 instruct shlL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
7004   effect(DEF dst, USE src1, USE src2, KILL ccr);
7005   size(16);
7006   format %{ "SUBS  $dst.hi,$src2,32 \n\t"
7007             "LSLpl $dst.hi,$src1.lo,$dst.hi \n\t"
7008             "RSBmi $dst.hi,$dst.hi,0 \n\t"
7009             "LSRmi $dst.hi,$src1.lo,$dst.hi" %}
7010 
7011   ins_encode %{
7012     // $src1$$Register and $dst$$Register->successor() can't be the same
7013     __ subs($dst$$Register->successor(), $src2$$Register, 32);
7014     __ mov($dst$$Register->successor(), $src1$$Register, lsl($dst$$Register->successor()), Assembler::PL);
7015     __ rsb($dst$$Register->successor(), $dst$$Register->successor(), 0, Assembler::MI);
7016     __ mov($dst$$Register->successor(), $src1$$Register, lsr($dst$$Register->successor()), Assembler::MI);
7017   %}
7018   ins_pipe(ialu_reg_reg);
7019 %}
7020 
7021 instruct shlL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
7022   match(Set dst (LShiftL src1 src2));
7023 
7024   expand %{
7025     flagsReg ccr;
7026     shlL_reg_reg_overlap(dst, src1, src2, ccr);
7027     shlL_reg_reg_merge_hi(dst, src1, src2);
7028     shlL_reg_reg_merge_lo(dst, src1, src2);
7029   %}
7030 %}
7031 
7032 // Register Shift Left Immediate
7033 instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
7034   match(Set dst (LShiftL src1 src2));
7035 
7036   size(8);
7037   format %{ "LSL   $dst.hi,$src1.lo,$src2-32\t! or mov if $src2==32\n\t"
7038             "MOV   $dst.lo, 0" %}
7039   ins_encode %{
7040     if ($src2$$constant == 32) {
7041       __ mov($dst$$Register->successor(), $src1$$Register);
7042     } else {
7043       __ mov($dst$$Register->successor(), $src1$$Register, lsl($src2$$constant-32));
7044     }
7045     __ mov($dst$$Register, 0);
7046   %}
7047   ins_pipe(ialu_reg_imm);
7048 %}
7049 
7050 instruct shlL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
7051   match(Set dst (LShiftL src1 src2));
7052 
7053   size(12);
7054   format %{ "LSL   $dst.hi,$src1.lo,$src2\n\t"
7055             "OR    $dst.hi, $dst.hi, $src1.lo >> 32-$src2\n\t"
7056             "LSL   $dst.lo,$src1.lo,$src2" %}
7057   ins_encode %{
7058     // The order of the following 3 instructions matters: src1.lo and
7059     // dst.hi can't overlap but src.hi and dst.hi can.
7060     __ mov($dst$$Register->successor(), $src1$$Register->successor(), lsl($src2$$constant));
7061     __ orr($dst$$Register->successor(), $dst$$Register->successor(), $src1$$Register, lsr(32-$src2$$constant));
7062     __ mov($dst$$Register, $src1$$Register, lsl($src2$$constant));
7063   %}
7064   ins_pipe(ialu_reg_imm);
7065 %}
7066 
7067 // Register Arithmetic Shift Right
7068 instruct sarI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
7069   match(Set dst (RShiftI src1 src2));
7070   size(4);
7071   format %{ "ASR    $dst,$src1,$src2\t! int" %}
7072   ins_encode %{
7073     __ mov($dst$$Register, $src1$$Register, asr($src2$$Register));
7074   %}
7075   ins_pipe(ialu_reg_reg);
7076 %}
7077 
7078 // Register Arithmetic Shift Right Immediate
7079 instruct sarI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
7080   match(Set dst (RShiftI src1 src2));
7081 
7082   size(4);
7083   format %{ "ASR    $dst,$src1,$src2" %}
7084   ins_encode %{
7085     __ mov($dst$$Register, $src1$$Register, asr($src2$$constant));
7086   %}
7087   ins_pipe(ialu_reg_imm);
7088 %}
7089 
7090 // Register Shift Right Arithmetic Long
7091 instruct sarL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
7092   effect(USE_DEF dst, USE src1, USE src2);
7093   size(4);
7094   format %{ "OR  $dst.lo,$dst.lo,($src1.lo >> $src2)"  %}
7095   ins_encode %{
7096     __ orr($dst$$Register, $dst$$Register, $src1$$Register, lsr($src2$$Register));
7097   %}
7098   ins_pipe(ialu_reg_reg);
7099 %}
7100 
7101 instruct sarL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
7102   effect(USE_DEF dst, USE src1, USE src2);
7103   size(4);
7104   format %{ "ASR  $dst.hi,$src1.hi,$src2 \n\t" %}
7105   ins_encode %{
7106     __ mov($dst$$Register->successor(), $src1$$Register->successor(), asr($src2$$Register));
7107   %}
7108   ins_pipe(ialu_reg_reg);
7109 %}
7110 
7111 instruct sarL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
7112   effect(DEF dst, USE src1, USE src2, KILL ccr);
7113   size(16);
7114   format %{ "SUBS  $dst.lo,$src2,32 \n\t"
7115             "ASRpl $dst.lo,$src1.hi,$dst.lo \n\t"
7116             "RSBmi $dst.lo,$dst.lo,0 \n\t"
7117             "LSLmi $dst.lo,$src1.hi,$dst.lo" %}
7118 
7119   ins_encode %{
7120     // $src1$$Register->successor() and $dst$$Register can't be the same
7121     __ subs($dst$$Register, $src2$$Register, 32);
7122     __ mov($dst$$Register, $src1$$Register->successor(), asr($dst$$Register), Assembler::PL);
7123     __ rsb($dst$$Register, $dst$$Register, 0, Assembler::MI);
7124     __ mov($dst$$Register, $src1$$Register->successor(), lsl($dst$$Register), Assembler::MI);
7125   %}
7126   ins_pipe(ialu_reg_reg);
7127 %}
7128 
7129 instruct sarL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
7130   match(Set dst (RShiftL src1 src2));
7131 
7132   expand %{
7133     flagsReg ccr;
7134     sarL_reg_reg_overlap(dst, src1, src2, ccr);
7135     sarL_reg_reg_merge_lo(dst, src1, src2);
7136     sarL_reg_reg_merge_hi(dst, src1, src2);
7137   %}
7138 %}
7139 
7140 // Register Shift Left Immediate
7141 instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
7142   match(Set dst (RShiftL src1 src2));
7143 
7144   size(8);
7145   format %{ "ASR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
7146             "ASR   $dst.hi,$src1.hi, $src2" %}
7147   ins_encode %{
7148     if ($src2$$constant == 32) {
7149       __ mov($dst$$Register, $src1$$Register->successor());
7150     } else{
7151       __ mov($dst$$Register, $src1$$Register->successor(), asr($src2$$constant-32));
7152     }
7153     __ mov($dst$$Register->successor(), $src1$$Register->successor(), asr(32));
7154   %}
7155 
7156   ins_pipe(ialu_reg_imm);
7157 %}
7158 
7159 instruct sarL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
7160   match(Set dst (RShiftL src1 src2));
7161   size(12);
7162   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
7163             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
7164             "ASR   $dst.hi,$src1.hi,$src2" %}
7165   ins_encode %{
7166     // The order of the following 3 instructions matters: src1.lo and
7167     // dst.hi can't overlap but src.hi and dst.hi can.
7168     __ mov($dst$$Register, $src1$$Register, lsr($src2$$constant));
7169     __ orr($dst$$Register, $dst$$Register, $src1$$Register->successor(), lsl(32-$src2$$constant));
7170     __ mov($dst$$Register->successor(), $src1$$Register->successor(), asr($src2$$constant));
7171   %}
7172   ins_pipe(ialu_reg_imm);
7173 %}
7174 
7175 // Register Shift Right
7176 instruct shrI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
7177   match(Set dst (URShiftI src1 src2));
7178   size(4);
7179   format %{ "LSR    $dst,$src1,$src2\t! int" %}
7180   ins_encode %{
7181     __ mov($dst$$Register, $src1$$Register, lsr($src2$$Register));
7182   %}
7183   ins_pipe(ialu_reg_reg);
7184 %}
7185 
7186 // Register Shift Right Immediate
7187 instruct shrI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
7188   match(Set dst (URShiftI src1 src2));
7189 
7190   size(4);
7191   format %{ "LSR    $dst,$src1,$src2" %}
7192   ins_encode %{
7193     __ mov($dst$$Register, $src1$$Register, lsr($src2$$constant));
7194   %}
7195   ins_pipe(ialu_reg_imm);
7196 %}
7197 
7198 // Register Shift Right
7199 instruct shrL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
7200   effect(USE_DEF dst, USE src1, USE src2);
7201   size(4);
7202   format %{ "OR   $dst.lo,$dst,($src1.lo >>> $src2)"  %}
7203   ins_encode %{
7204     __ orr($dst$$Register, $dst$$Register, $src1$$Register, lsr($src2$$Register));
7205   %}
7206   ins_pipe(ialu_reg_reg);
7207 %}
7208 
7209 instruct shrL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
7210   effect(USE_DEF dst, USE src1, USE src2);
7211   size(4);
7212   format %{ "LSR  $dst.hi,$src1.hi,$src2 \n\t" %}
7213   ins_encode %{
7214     __ mov($dst$$Register->successor(), $src1$$Register->successor(), lsr($src2$$Register));
7215   %}
7216   ins_pipe(ialu_reg_reg);
7217 %}
7218 
7219 instruct shrL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
7220   effect(DEF dst, USE src1, USE src2, KILL ccr);
7221   size(16);
7222   format %{ "SUBS  $dst,$src2,32 \n\t"
7223             "LSRpl $dst,$src1.hi,$dst \n\t"
7224             "RSBmi $dst,$dst,0 \n\t"
7225             "LSLmi $dst,$src1.hi,$dst" %}
7226 
7227   ins_encode %{
7228     // $src1$$Register->successor() and $dst$$Register can't be the same
7229     __ subs($dst$$Register, $src2$$Register, 32);
7230     __ mov($dst$$Register, $src1$$Register->successor(), lsr($dst$$Register), Assembler::PL);
7231     __ rsb($dst$$Register, $dst$$Register, 0, Assembler::MI);
7232     __ mov($dst$$Register, $src1$$Register->successor(), lsl($dst$$Register), Assembler::MI);
7233   %}
7234   ins_pipe(ialu_reg_reg);
7235 %}
7236 
7237 instruct shrL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
7238   match(Set dst (URShiftL src1 src2));
7239 
7240   expand %{
7241     flagsReg ccr;
7242     shrL_reg_reg_overlap(dst, src1, src2, ccr);
7243     shrL_reg_reg_merge_lo(dst, src1, src2);
7244     shrL_reg_reg_merge_hi(dst, src1, src2);
7245   %}
7246 %}
7247 
7248 // Register Shift Right Immediate
7249 instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
7250   match(Set dst (URShiftL src1 src2));
7251 
7252   size(8);
7253   format %{ "LSR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
7254             "MOV   $dst.hi, 0" %}
7255   ins_encode %{
7256     if ($src2$$constant == 32) {
7257       __ mov($dst$$Register, $src1$$Register->successor());
7258     } else {
7259       __ mov($dst$$Register, $src1$$Register->successor(), lsr($src2$$constant-32));
7260     }
7261     __ mov($dst$$Register->successor(), 0);
7262   %}
7263 
7264   ins_pipe(ialu_reg_imm);
7265 %}
7266 
7267 instruct shrL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
7268   match(Set dst (URShiftL src1 src2));
7269 
7270   size(12);
7271   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
7272             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
7273             "LSR   $dst.hi,$src1.hi,$src2" %}
7274   ins_encode %{
7275     // The order of the following 3 instructions matters: src1.lo and
7276     // dst.hi can't overlap but src.hi and dst.hi can.
7277     __ mov($dst$$Register, $src1$$Register, lsr($src2$$constant));
7278     __ orr($dst$$Register, $dst$$Register, $src1$$Register->successor(), lsl(32-$src2$$constant));
7279     __ mov($dst$$Register->successor(), $src1$$Register->successor(), lsr($src2$$constant));
7280   %}
7281   ins_pipe(ialu_reg_imm);
7282 %}
7283 
7284 
7285 instruct shrP_reg_imm5(iRegX dst, iRegP src1, immU5 src2) %{
7286   match(Set dst (URShiftI (CastP2X src1) src2));
7287   size(4);
7288   format %{ "LSR    $dst,$src1,$src2\t! Cast ptr $src1 to int and shift" %}
7289   ins_encode %{
7290     __ lsr($dst$$Register, $src1$$Register, $src2$$constant);
7291   %}
7292   ins_pipe(ialu_reg_imm);
7293 %}
7294 
7295 // Overcomplicated unsigned math
7296 instruct umull_lreg32_lreg32(iRegL dst, iRegL src1, iRegL src2) %{
7297   match(Set dst (MulL src1 src2));
7298   predicate(n->in(1)->Opcode() == Op_AndL && (((unsigned long long)n->in(1)->in(2)->find_long_con(-1))>>32)==0 &&
7299             n->in(2)->Opcode() == Op_AndL && (((unsigned long long)n->in(2)->in(2)->find_long_con(-1))>>32)==0);
7300 
7301   ins_cost(DEFAULT_COST*3/2);
7302   size(4);
7303   format %{ "UMULL $dst.lo,$dst.hi,$src1.lo,$src2.lo" %}
7304   ins_encode %{
7305     __ umull($dst$$Register, $dst$$Register->successor(), $src1$$Register, $src2$$Register);
7306   %}
7307   ins_pipe(imul_reg_reg);
7308 %}
7309 
7310 instruct umlal_reg32_reg32(iRegL dst, iRegL src1, iRegL src2) %{
7311   match(Set dst (AddL dst (MulL src1 src2)));
7312   predicate(
7313     n->in(2)->Opcode() == Op_MulL ?
7314     n->in(2)->in(1)->Opcode() == Op_AndL && (((unsigned long long)n->in(2)->in(1)->in(2)->find_long_con(-1))>>32)==0 &&
7315     n->in(2)->in(2)->Opcode() == Op_AndL && (((unsigned long long)n->in(2)->in(2)->in(2)->find_long_con(-1))>>32)==0 :
7316     n->in(1)->in(1)->Opcode() == Op_AndL && (((unsigned long long)n->in(1)->in(1)->in(2)->find_long_con(-1))>>32)==0 &&
7317     n->in(1)->in(2)->Opcode() == Op_AndL && (((unsigned long long)n->in(1)->in(2)->in(2)->find_long_con(-1))>>32)==0
7318     );
7319 
7320   ins_cost(DEFAULT_COST*3/2);
7321   size(4);
7322   format %{ "UMLAL $dst.lo,$dst.hi,$src1.lo,$src2.lo" %}
7323   ins_encode %{
7324     __ umlal($dst$$Register, $dst$$Register->successor(), $src1$$Register, $src2$$Register);
7325   %}
7326   ins_pipe(ialu_reg_reg);
7327 %}
7328 
7329 //----------Floating Point Arithmetic Instructions-----------------------------
7330 
7331 //  Add float single precision
7332 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
7333   match(Set dst (AddF src1 src2));
7334 
7335   size(4);
7336   format %{ "FADDS  $dst,$src1,$src2" %}
7337   ins_encode %{
7338     __ vadd_f32($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
7339   %}
7340 
7341   ins_pipe(faddF_reg_reg);
7342 %}
7343 
7344 //  Add float double precision
7345 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
7346   match(Set dst (AddD src1 src2));
7347 
7348   size(4);
7349   format %{ "FADDD  $dst,$src1,$src2" %}
7350   ins_encode %{
7351     __ vadd_f64($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
7352   %}
7353 
7354   ins_pipe(faddD_reg_reg);
7355 %}
7356 
7357 //  Sub float single precision
7358 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
7359   match(Set dst (SubF src1 src2));
7360 
7361   size(4);
7362   format %{ "FSUBS  $dst,$src1,$src2" %}
7363   ins_encode %{
7364     __ vsub_f32($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
7365   %}
7366   ins_pipe(faddF_reg_reg);
7367 %}
7368 
7369 //  Sub float double precision
7370 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
7371   match(Set dst (SubD src1 src2));
7372 
7373   size(4);
7374   format %{ "FSUBD  $dst,$src1,$src2" %}
7375   ins_encode %{
7376     __ vsub_f64($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
7377   %}
7378   ins_pipe(faddD_reg_reg);
7379 %}
7380 
7381 //  Mul float single precision
7382 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
7383   match(Set dst (MulF src1 src2));
7384 
7385   size(4);
7386   format %{ "FMULS  $dst,$src1,$src2" %}
7387   ins_encode %{
7388     __ vmul_f32($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
7389   %}
7390 
7391   ins_pipe(fmulF_reg_reg);
7392 %}
7393 
7394 //  Mul float double precision
7395 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
7396   match(Set dst (MulD src1 src2));
7397 
7398   size(4);
7399   format %{ "FMULD  $dst,$src1,$src2" %}
7400   ins_encode %{
7401     __ vmul_f64($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
7402   %}
7403 
7404   ins_pipe(fmulD_reg_reg);
7405 %}
7406 
7407 //  Div float single precision
7408 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
7409   match(Set dst (DivF src1 src2));
7410 
7411   size(4);
7412   format %{ "FDIVS  $dst,$src1,$src2" %}
7413   ins_encode %{
7414     __ vdiv_f32($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
7415   %}
7416 
7417   ins_pipe(fdivF_reg_reg);
7418 %}
7419 
7420 //  Div float double precision
7421 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
7422   match(Set dst (DivD src1 src2));
7423 
7424   size(4);
7425   format %{ "FDIVD  $dst,$src1,$src2" %}
7426   ins_encode %{
7427     __ vdiv_f64($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
7428   %}
7429 
7430   ins_pipe(fdivD_reg_reg);
7431 %}
7432 
7433 //  Absolute float double precision
7434 instruct absD_reg(regD dst, regD src) %{
7435   match(Set dst (AbsD src));
7436 
7437   size(4);
7438   format %{ "FABSd  $dst,$src" %}
7439   ins_encode %{
7440     __ vabs_f64($dst$$FloatRegister, $src$$FloatRegister);
7441   %}
7442   ins_pipe(faddD_reg);
7443 %}
7444 
7445 //  Absolute float single precision
7446 instruct absF_reg(regF dst, regF src) %{
7447   match(Set dst (AbsF src));
7448   format %{ "FABSs  $dst,$src" %}
7449   ins_encode %{
7450     __ vabs_f32($dst$$FloatRegister, $src$$FloatRegister);
7451   %}
7452   ins_pipe(faddF_reg);
7453 %}
7454 
7455 instruct negF_reg(regF dst, regF src) %{
7456   match(Set dst (NegF src));
7457 
7458   size(4);
7459   format %{ "FNEGs  $dst,$src" %}
7460   ins_encode %{
7461     __ vneg_f32($dst$$FloatRegister, $src$$FloatRegister);
7462   %}
7463   ins_pipe(faddF_reg);
7464 %}
7465 
7466 instruct negD_reg(regD dst, regD src) %{
7467   match(Set dst (NegD src));
7468 
7469   format %{ "FNEGd  $dst,$src" %}
7470   ins_encode %{
7471     __ vneg_f64($dst$$FloatRegister, $src$$FloatRegister);
7472   %}
7473   ins_pipe(faddD_reg);
7474 %}
7475 
7476 //  Sqrt float double precision
7477 instruct sqrtF_reg_reg(regF dst, regF src) %{
7478   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
7479 
7480   size(4);
7481   format %{ "FSQRTS $dst,$src" %}
7482   ins_encode %{
7483     __ vsqrt_f32($dst$$FloatRegister, $src$$FloatRegister);
7484   %}
7485   ins_pipe(fdivF_reg_reg);
7486 %}
7487 
7488 //  Sqrt float double precision
7489 instruct sqrtD_reg_reg(regD dst, regD src) %{
7490   match(Set dst (SqrtD src));
7491 
7492   size(4);
7493   format %{ "FSQRTD $dst,$src" %}
7494   ins_encode %{
7495     __ vsqrt_f64($dst$$FloatRegister, $src$$FloatRegister);
7496   %}
7497   ins_pipe(fdivD_reg_reg);
7498 %}
7499 
7500 //----------Logical Instructions-----------------------------------------------
7501 // And Instructions
7502 // Register And
7503 instruct andI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
7504   match(Set dst (AndI src1 src2));
7505 
7506   size(4);
7507   format %{ "and_32 $dst,$src1,$src2" %}
7508   ins_encode %{
7509     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
7510   %}
7511   ins_pipe(ialu_reg_reg);
7512 %}
7513 
7514 instruct andshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
7515   match(Set dst (AndI src1 (LShiftI src2 src3)));
7516 
7517   size(4);
7518   format %{ "AND    $dst,$src1,$src2<<$src3" %}
7519   ins_encode %{
7520     __ andr($dst$$Register, $src1$$Register, $src2$$Register, lsl($src3$$Register));
7521   %}
7522   ins_pipe(ialu_reg_reg);
7523 %}
7524 
7525 instruct andshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
7526   match(Set dst (AndI src1 (LShiftI src2 src3)));
7527 
7528   size(4);
7529   format %{ "and_32 $dst,$src1,$src2<<$src3" %}
7530   ins_encode %{
7531     __ andr($dst$$Register, $src1$$Register, $src2$$Register, lsl($src3$$constant));
7532   %}
7533   ins_pipe(ialu_reg_reg);
7534 %}
7535 
7536 instruct andsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
7537   match(Set dst (AndI src1 (RShiftI src2 src3)));
7538 
7539   size(4);
7540   format %{ "AND    $dst,$src1,$src2>>$src3" %}
7541   ins_encode %{
7542     __ andr($dst$$Register, $src1$$Register, $src2$$Register, asr($src3$$Register));
7543   %}
7544   ins_pipe(ialu_reg_reg);
7545 %}
7546 
7547 instruct andsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
7548   match(Set dst (AndI src1 (RShiftI src2 src3)));
7549 
7550   size(4);
7551   format %{ "and_32 $dst,$src1,$src2>>$src3" %}
7552   ins_encode %{
7553     __ andr($dst$$Register, $src1$$Register, $src2$$Register, asr($src3$$constant));
7554   %}
7555   ins_pipe(ialu_reg_reg);
7556 %}
7557 
7558 instruct andshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
7559   match(Set dst (AndI src1 (URShiftI src2 src3)));
7560 
7561   size(4);
7562   format %{ "AND    $dst,$src1,$src2>>>$src3" %}
7563   ins_encode %{
7564     __ andr($dst$$Register, $src1$$Register, $src2$$Register, lsr($src3$$Register));
7565   %}
7566   ins_pipe(ialu_reg_reg);
7567 %}
7568 
7569 instruct andshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
7570   match(Set dst (AndI src1 (URShiftI src2 src3)));
7571 
7572   size(4);
7573   format %{ "and_32 $dst,$src1,$src2>>>$src3" %}
7574   ins_encode %{
7575     __ andr($dst$$Register, $src1$$Register, $src2$$Register, lsr($src3$$constant));
7576   %}
7577   ins_pipe(ialu_reg_reg);
7578 %}
7579 
7580 // Immediate And
7581 instruct andI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
7582   match(Set dst (AndI src1 src2));
7583 
7584   size(4);
7585   format %{ "and_32 $dst,$src1,$src2\t! int" %}
7586   ins_encode %{
7587     __ andr($dst$$Register, $src1$$Register, $src2$$constant);
7588   %}
7589   ins_pipe(ialu_reg_imm);
7590 %}
7591 
7592 instruct andI_reg_limmn(iRegI dst, iRegI src1, limmIn src2) %{
7593   match(Set dst (AndI src1 src2));
7594 
7595   size(4);
7596   format %{ "bic    $dst,$src1,~$src2\t! int" %}
7597   ins_encode %{
7598     __ bic($dst$$Register, $src1$$Register, ~$src2$$constant);
7599   %}
7600   ins_pipe(ialu_reg_imm);
7601 %}
7602 
7603 // Register And Long
7604 instruct andL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
7605   match(Set dst (AndL src1 src2));
7606 
7607   ins_cost(DEFAULT_COST);
7608   size(8);
7609   format %{ "AND    $dst,$src1,$src2\t! long" %}
7610   ins_encode %{
7611     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
7612     __ andr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
7613   %}
7614   ins_pipe(ialu_reg_reg);
7615 %}
7616 
7617 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7618 // (hi($con$$constant), lo($con$$constant)) becomes
7619 instruct andL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
7620   match(Set dst (AndL src1 con));
7621   ins_cost(DEFAULT_COST);
7622   size(8);
7623   format %{ "AND    $dst,$src1,$con\t! long" %}
7624   ins_encode %{
7625     __ andr($dst$$Register, $src1$$Register, $con$$constant);
7626     __ andr($dst$$Register->successor(), $src1$$Register->successor(), 0u);
7627   %}
7628   ins_pipe(ialu_reg_imm);
7629 %}
7630 
7631 // Or Instructions
7632 // Register Or
7633 instruct orI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
7634   match(Set dst (OrI src1 src2));
7635 
7636   size(4);
7637   format %{ "orr_32 $dst,$src1,$src2\t! int" %}
7638   ins_encode %{
7639     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
7640   %}
7641   ins_pipe(ialu_reg_reg);
7642 %}
7643 
7644 instruct orshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
7645   match(Set dst (OrI src1 (LShiftI src2 src3)));
7646 
7647   size(4);
7648   format %{ "OR    $dst,$src1,$src2<<$src3" %}
7649   ins_encode %{
7650     __ orr($dst$$Register, $src1$$Register, $src2$$Register, lsl($src3$$Register));
7651   %}
7652   ins_pipe(ialu_reg_reg);
7653 %}
7654 
7655 instruct orshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
7656   match(Set dst (OrI src1 (LShiftI src2 src3)));
7657 
7658   size(4);
7659   format %{ "orr_32 $dst,$src1,$src2<<$src3" %}
7660   ins_encode %{
7661     __ orr($dst$$Register, $src1$$Register, $src2$$Register, lsl($src3$$constant));
7662   %}
7663   ins_pipe(ialu_reg_reg);
7664 %}
7665 
7666 instruct orsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
7667   match(Set dst (OrI src1 (RShiftI src2 src3)));
7668 
7669   size(4);
7670   format %{ "OR    $dst,$src1,$src2>>$src3" %}
7671   ins_encode %{
7672     __ orr($dst$$Register, $src1$$Register, $src2$$Register, asr($src3$$Register));
7673   %}
7674   ins_pipe(ialu_reg_reg);
7675 %}
7676 
7677 instruct orsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
7678   match(Set dst (OrI src1 (RShiftI src2 src3)));
7679 
7680   size(4);
7681   format %{ "orr_32 $dst,$src1,$src2>>$src3" %}
7682   ins_encode %{
7683     __ orr($dst$$Register, $src1$$Register, $src2$$Register, asr($src3$$constant));
7684   %}
7685   ins_pipe(ialu_reg_reg);
7686 %}
7687 
7688 instruct orshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
7689   match(Set dst (OrI src1 (URShiftI src2 src3)));
7690 
7691   size(4);
7692   format %{ "OR    $dst,$src1,$src2>>>$src3" %}
7693   ins_encode %{
7694     __ orr($dst$$Register, $src1$$Register, $src2$$Register, lsr($src3$$Register));
7695   %}
7696   ins_pipe(ialu_reg_reg);
7697 %}
7698 
7699 instruct orshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
7700   match(Set dst (OrI src1 (URShiftI src2 src3)));
7701 
7702   size(4);
7703   format %{ "orr_32 $dst,$src1,$src2>>>$src3" %}
7704   ins_encode %{
7705     __ orr($dst$$Register, $src1$$Register, $src2$$Register, lsr($src3$$constant));
7706   %}
7707   ins_pipe(ialu_reg_reg);
7708 %}
7709 
7710 // Immediate Or
7711 instruct orI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
7712   match(Set dst (OrI src1 src2));
7713 
7714   size(4);
7715   format %{ "orr_32  $dst,$src1,$src2" %}
7716   ins_encode %{
7717     __ orr($dst$$Register, $src1$$Register, $src2$$constant);
7718   %}
7719   ins_pipe(ialu_reg_imm);
7720 %}
7721 // TODO: orn_32 with limmIn
7722 
7723 // Register Or Long
7724 instruct orL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
7725   match(Set dst (OrL src1 src2));
7726 
7727   ins_cost(DEFAULT_COST);
7728   size(8);
7729   format %{ "OR     $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
7730             "OR     $dst.hi,$src1.hi,$src2.hi" %}
7731   ins_encode %{
7732     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
7733     __ orr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
7734   %}
7735   ins_pipe(ialu_reg_reg);
7736 %}
7737 
7738 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7739 // (hi($con$$constant), lo($con$$constant)) becomes
7740 instruct orL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
7741   match(Set dst (OrL src1 con));
7742   ins_cost(DEFAULT_COST);
7743   size(8);
7744   format %{ "OR     $dst.lo,$src1.lo,$con\t! long\n\t"
7745             "OR     $dst.hi,$src1.hi,$con" %}
7746   ins_encode %{
7747     __ orr($dst$$Register, $src1$$Register, $con$$constant);
7748     __ orr($dst$$Register->successor(), $src1$$Register->successor(), 0u);
7749   %}
7750   ins_pipe(ialu_reg_imm);
7751 %}
7752 
7753 #ifdef TODO
7754 // Use SPRegP to match Rthread (TLS register) without spilling.
7755 // Use store_ptr_RegP to match Rthread (TLS register) without spilling.
7756 // Use sp_ptr_RegP to match Rthread (TLS register) without spilling.
7757 instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
7758   match(Set dst (OrI src1 (CastP2X src2)));
7759   size(4);
7760   format %{ "OR     $dst,$src1,$src2" %}
7761   ins_encode %{
7762     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
7763   %}
7764   ins_pipe(ialu_reg_reg);
7765 %}
7766 #endif
7767 
7768 // Xor Instructions
7769 // Register Xor
7770 instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
7771   match(Set dst (XorI src1 src2));
7772 
7773   size(4);
7774   format %{ "eor_32 $dst,$src1,$src2" %}
7775   ins_encode %{
7776     __ eor($dst$$Register, $src1$$Register, $src2$$Register);
7777   %}
7778   ins_pipe(ialu_reg_reg);
7779 %}
7780 
7781 instruct xorshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
7782   match(Set dst (XorI src1 (LShiftI src2 src3)));
7783 
7784   size(4);
7785   format %{ "XOR    $dst,$src1,$src2<<$src3" %}
7786   ins_encode %{
7787     __ eor($dst$$Register, $src1$$Register, $src2$$Register, lsl($src3$$Register));
7788   %}
7789   ins_pipe(ialu_reg_reg);
7790 %}
7791 
7792 instruct xorshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
7793   match(Set dst (XorI src1 (LShiftI src2 src3)));
7794 
7795   size(4);
7796   format %{ "eor_32 $dst,$src1,$src2<<$src3" %}
7797   ins_encode %{
7798     __ eor($dst$$Register, $src1$$Register, $src2$$Register, lsl($src3$$constant));
7799   %}
7800   ins_pipe(ialu_reg_reg);
7801 %}
7802 
7803 instruct xorsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
7804   match(Set dst (XorI src1 (RShiftI src2 src3)));
7805 
7806   size(4);
7807   format %{ "XOR    $dst,$src1,$src2>>$src3" %}
7808   ins_encode %{
7809     __ eor($dst$$Register, $src1$$Register, $src2$$Register, asr($src3$$Register));
7810   %}
7811   ins_pipe(ialu_reg_reg);
7812 %}
7813 
7814 instruct xorsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
7815   match(Set dst (XorI src1 (RShiftI src2 src3)));
7816 
7817   size(4);
7818   format %{ "eor_32 $dst,$src1,$src2>>$src3" %}
7819   ins_encode %{
7820     __ eor($dst$$Register, $src1$$Register, $src2$$Register, asr($src3$$constant));
7821   %}
7822   ins_pipe(ialu_reg_reg);
7823 %}
7824 
7825 instruct xorshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
7826   match(Set dst (XorI src1 (URShiftI src2 src3)));
7827 
7828   size(4);
7829   format %{ "XOR    $dst,$src1,$src2>>>$src3" %}
7830   ins_encode %{
7831     __ eor($dst$$Register, $src1$$Register, $src2$$Register, lsr($src3$$Register));
7832   %}
7833   ins_pipe(ialu_reg_reg);
7834 %}
7835 
7836 instruct xorshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
7837   match(Set dst (XorI src1 (URShiftI src2 src3)));
7838 
7839   size(4);
7840   format %{ "eor_32 $dst,$src1,$src2>>>$src3" %}
7841   ins_encode %{
7842     __ eor($dst$$Register, $src1$$Register, $src2$$Register, lsr($src3$$constant));
7843   %}
7844   ins_pipe(ialu_reg_reg);
7845 %}
7846 
7847 // Immediate Xor
7848 instruct xorI_reg_imm(iRegI dst, iRegI src1, limmI src2) %{
7849   match(Set dst (XorI src1 src2));
7850 
7851   size(4);
7852   format %{ "eor_32 $dst,$src1,$src2" %}
7853   ins_encode %{
7854     __ eor($dst$$Register, $src1$$Register, $src2$$constant);
7855   %}
7856   ins_pipe(ialu_reg_imm);
7857 %}
7858 
7859 // Register Xor Long
7860 instruct xorL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
7861   match(Set dst (XorL src1 src2));
7862   ins_cost(DEFAULT_COST);
7863   size(8);
7864   format %{ "XOR     $dst.hi,$src1.hi,$src2.hi\t! long\n\t"
7865             "XOR     $dst.lo,$src1.lo,$src2.lo\t! long" %}
7866   ins_encode %{
7867     __ eor($dst$$Register, $src1$$Register, $src2$$Register);
7868     __ eor($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
7869   %}
7870   ins_pipe(ialu_reg_reg);
7871 %}
7872 
7873 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7874 // (hi($con$$constant), lo($con$$constant)) becomes
7875 instruct xorL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
7876   match(Set dst (XorL src1 con));
7877   ins_cost(DEFAULT_COST);
7878   size(8);
7879   format %{ "XOR     $dst.hi,$src1.hi,$con\t! long\n\t"
7880             "XOR     $dst.lo,$src1.lo,0\t! long" %}
7881   ins_encode %{
7882     __ eor($dst$$Register, $src1$$Register, $con$$constant);
7883     __ eor($dst$$Register->successor(), $src1$$Register->successor(), 0u);
7884   %}
7885   ins_pipe(ialu_reg_imm);
7886 %}
7887 
7888 //----------Convert to Boolean-------------------------------------------------
7889 instruct convI2B( iRegI dst, iRegI src, flagsReg ccr ) %{
7890   match(Set dst (Conv2B src));
7891   effect(KILL ccr);
7892   size(12);
7893   ins_cost(DEFAULT_COST*2);
7894   format %{ "TST    $src,$src \n\t"
7895             "MOV    $dst, 0   \n\t"
7896             "MOV.ne $dst, 1" %}
7897   ins_encode %{ // FIXME: can do better?
7898     __ tst($src$$Register, $src$$Register);
7899     __ mov($dst$$Register, 0);
7900     __ mov($dst$$Register, 1, Assembler::NE);
7901   %}
7902   ins_pipe(ialu_reg_ialu);
7903 %}
7904 
7905 instruct convP2B( iRegI dst, iRegP src, flagsReg ccr ) %{
7906   match(Set dst (Conv2B src));
7907   effect(KILL ccr);
7908   size(12);
7909   ins_cost(DEFAULT_COST*2);
7910   format %{ "TST    $src,$src \n\t"
7911             "MOV    $dst, 0   \n\t"
7912             "MOV.ne $dst, 1" %}
7913   ins_encode %{
7914     __ tst($src$$Register, $src$$Register);
7915     __ mov($dst$$Register, 0);
7916     __ mov($dst$$Register, 1, Assembler::NE);
7917   %}
7918   ins_pipe(ialu_reg_ialu);
7919 %}
7920 
7921 instruct cmpLTMask_reg_reg( iRegI dst, iRegI p, iRegI q, flagsReg ccr ) %{
7922   match(Set dst (CmpLTMask p q));
7923   effect( KILL ccr );
7924   ins_cost(DEFAULT_COST*3);
7925   format %{ "CMP    $p,$q\n\t"
7926             "MOV    $dst, #0\n\t"
7927             "MOV.lt $dst, #-1" %}
7928   ins_encode %{
7929     __ cmp($p$$Register, $q$$Register);
7930     __ mov_i($dst$$Register, 0);
7931     __ mvn_i($dst$$Register, 0, Assembler::LT);
7932   %}
7933   ins_pipe(ialu_reg_reg_ialu);
7934 %}
7935 
7936 instruct cmpLTMask_reg_imm( iRegI dst, iRegI p, aimmI q, flagsReg ccr ) %{
7937   match(Set dst (CmpLTMask p q));
7938   effect( KILL ccr );
7939   ins_cost(DEFAULT_COST*3);
7940   format %{ "CMP    $p,$q\n\t"
7941             "MOV    $dst, #0\n\t"
7942             "MOV.lt $dst, #-1" %}
7943   ins_encode %{
7944     __ cmp($p$$Register, $q$$constant);
7945     __ mov_i($dst$$Register, 0);
7946     __ mvn_i($dst$$Register, 0, Assembler::LT);
7947   %}
7948   ins_pipe(ialu_reg_reg_ialu);
7949 %}
7950 
7951 instruct cadd_cmpLTMask3( iRegI p, iRegI q, iRegI y, iRegI z, flagsReg ccr ) %{
7952   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
7953   effect( KILL ccr );
7954   ins_cost(DEFAULT_COST*2);
7955   format %{ "CMP    $p,$q\n\t"
7956             "ADD.lt $z,$y,$z" %}
7957   ins_encode %{
7958     __ cmp($p$$Register, $q$$Register);
7959     __ add($z$$Register, $y$$Register, $z$$Register, Assembler::LT);
7960   %}
7961   ins_pipe( cadd_cmpltmask );
7962 %}
7963 
7964 // FIXME: remove unused "dst"
7965 instruct cadd_cmpLTMask4( iRegI dst, iRegI p, aimmI q, iRegI y, iRegI z, flagsReg ccr ) %{
7966   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
7967   effect( KILL ccr );
7968   ins_cost(DEFAULT_COST*2);
7969   format %{ "CMP    $p,$q\n\t"
7970             "ADD.lt $z,$y,$z" %}
7971   ins_encode %{
7972     __ cmp($p$$Register, $q$$constant);
7973     __ add($z$$Register, $y$$Register, $z$$Register, Assembler::LT);
7974   %}
7975   ins_pipe( cadd_cmpltmask );
7976 %}
7977 
7978 instruct cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, flagsReg ccr ) %{
7979   match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
7980   effect( KILL ccr );
7981   ins_cost(DEFAULT_COST*2);
7982   format %{ "SUBS   $p,$p,$q\n\t"
7983             "ADD.lt $p,$y,$p" %}
7984   ins_encode %{
7985     __ subs($p$$Register, $p$$Register, $q$$Register);
7986     __ add($p$$Register, $y$$Register, $p$$Register, Assembler::LT);
7987   %}
7988   ins_pipe( cadd_cmpltmask );
7989 %}
7990 
7991 //----------Arithmetic Conversion Instructions---------------------------------
7992 // The conversions operations are all Alpha sorted.  Please keep it that way!
7993 
7994 instruct convD2F_reg(regF dst, regD src) %{
7995   match(Set dst (ConvD2F src));
7996   size(4);
7997   format %{ "FCVTSD  $dst,$src" %}
7998   ins_encode %{
7999     __ vcvt_f32_f64($dst$$FloatRegister, $src$$FloatRegister);
8000   %}
8001   ins_pipe(fcvtD2F);
8002 %}
8003 
8004 // Convert a double to an int in a float register.
8005 // If the double is a NAN, stuff a zero in instead.
8006 
8007 instruct convD2I_reg_reg(iRegI dst, regD src, regF tmp) %{
8008   match(Set dst (ConvD2I src));
8009   effect( TEMP tmp );
8010   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
8011   format %{ "FTOSIZD  $tmp,$src\n\t"
8012             "FMRS     $dst, $tmp" %}
8013   ins_encode %{
8014     __ vcvt_s32_f64($tmp$$FloatRegister, $src$$FloatRegister);
8015     __ vmov_f32($dst$$Register, $tmp$$FloatRegister);
8016   %}
8017   ins_pipe(fcvtD2I);
8018 %}
8019 
8020 // Convert a double to a long in a double register.
8021 // If the double is a NAN, stuff a zero in instead.
8022 
8023 // Double to Long conversion
8024 instruct convD2L_reg(R0R1RegL dst, regD src) %{
8025   match(Set dst (ConvD2L src));
8026   effect(CALL);
8027   ins_cost(MEMORY_REF_COST); // FIXME
8028   format %{ "convD2L    $dst,$src\t ! call to SharedRuntime::d2l" %}
8029   ins_encode %{
8030 #ifndef HARD_FLOAT_CC
8031     __ vmov_f64($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
8032 #else
8033     if ($src$$FloatRegister != d0) {
8034       __ vmov_f64(d0, $src$$FloatRegister);
8035     }
8036 #endif
8037     address target = CAST_FROM_FN_PTR(address, SharedRuntime::d2l);
8038     __ call(target, relocInfo::runtime_call_type);
8039   %}
8040   ins_pipe(fcvtD2L);
8041 %}
8042 
8043 instruct convF2D_reg(regD dst, regF src) %{
8044   match(Set dst (ConvF2D src));
8045   size(4);
8046   format %{ "FCVTDS  $dst,$src" %}
8047   ins_encode %{
8048     __ vcvt_f64_f32($dst$$FloatRegister, $src$$FloatRegister);
8049   %}
8050   ins_pipe(fcvtF2D);
8051 %}
8052 
8053 instruct convF2I_reg_reg(iRegI dst, regF src, regF tmp) %{
8054   match(Set dst (ConvF2I src));
8055   effect( TEMP tmp );
8056   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
8057   size(8);
8058   format %{ "FTOSIZS  $tmp,$src\n\t"
8059             "FMRS     $dst, $tmp" %}
8060   ins_encode %{
8061     __ vcvt_s32_f32($tmp$$FloatRegister, $src$$FloatRegister);
8062     __ vmov_f32($dst$$Register, $tmp$$FloatRegister);
8063   %}
8064   ins_pipe(fcvtF2I);
8065 %}
8066 
8067 // Float to Long conversion
8068 instruct convF2L_reg(R0R1RegL dst, regF src, R0RegI arg1) %{
8069   match(Set dst (ConvF2L src));
8070   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
8071   effect(CALL);
8072   format %{ "convF2L  $dst,$src\t! call to SharedRuntime::f2l" %}
8073   ins_encode %{
8074 #ifndef HARD_FLOAT_CC
8075     __ vmov_f32($arg1$$Register, $src$$FloatRegister);
8076 #else
8077     if($src$$FloatRegister != f0) {
8078       __ vmov_f32(f0, $src$$FloatRegister);
8079     }
8080 #endif
8081     address target = CAST_FROM_FN_PTR(address, SharedRuntime::f2l);
8082     __ call(target, relocInfo::runtime_call_type);
8083   %}
8084   ins_pipe(fcvtF2L);
8085 %}
8086 
8087 instruct convI2D_reg_reg(iRegI src, regD_low dst) %{
8088   match(Set dst (ConvI2D src));
8089   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
8090   size(8);
8091   format %{ "FMSR     $dst,$src \n\t"
8092             "FSITOD   $dst $dst"%}
8093   ins_encode %{
8094       __ vmov_f32($dst$$FloatRegister, $src$$Register);
8095       __ vcvt_f64_s32($dst$$FloatRegister, $dst$$FloatRegister);
8096   %}
8097   ins_pipe(fcvtI2D);
8098 %}
8099 
8100 instruct convI2F_reg_reg( regF dst, iRegI src ) %{
8101   match(Set dst (ConvI2F src));
8102   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
8103   size(8);
8104   format %{ "FMSR     $dst,$src \n\t"
8105             "FSITOS   $dst, $dst"%}
8106   ins_encode %{
8107       __ vmov_f32($dst$$FloatRegister, $src$$Register);
8108       __ vcvt_f32_s32($dst$$FloatRegister, $dst$$FloatRegister);
8109   %}
8110   ins_pipe(fcvtI2F);
8111 %}
8112 
8113 instruct convI2L_reg(iRegL dst, iRegI src) %{
8114   match(Set dst (ConvI2L src));
8115   size(8);
8116   format %{ "MOV    $dst.lo, $src \n\t"
8117             "ASR    $dst.hi,$src,31\t! int->long" %}
8118   ins_encode %{
8119     __ mov($dst$$Register, $src$$Register);
8120     __ mov($dst$$Register->successor(), $src$$Register, asr(31));
8121   %}
8122   ins_pipe(ialu_reg_reg);
8123 %}
8124 
8125 // Zero-extend convert int to long
8126 instruct convI2L_reg_zex(iRegL dst, iRegI src, immL_32bits mask ) %{
8127   match(Set dst (AndL (ConvI2L src) mask) );
8128   size(8);
8129   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend int to long\n\t"
8130             "MOV    $dst.hi, 0"%}
8131   ins_encode %{
8132     __ mov($dst$$Register, $src$$Register);
8133     __ mov($dst$$Register->successor(), 0);
8134   %}
8135   ins_pipe(ialu_reg_reg);
8136 %}
8137 
8138 // Zero-extend long
8139 instruct zerox_long(iRegL dst, iRegL src, immL_32bits mask ) %{
8140   match(Set dst (AndL src mask) );
8141   size(8);
8142   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend long\n\t"
8143             "MOV    $dst.hi, 0"%}
8144   ins_encode %{
8145     __ mov($dst$$Register, $src$$Register);
8146     __ mov($dst$$Register->successor(), 0);
8147   %}
8148   ins_pipe(ialu_reg_reg);
8149 %}
8150 
8151 instruct MoveF2I_reg_reg(iRegI dst, regF src) %{
8152   match(Set dst (MoveF2I src));
8153   effect(DEF dst, USE src);
8154   ins_cost(MEMORY_REF_COST); // FIXME
8155 
8156   size(4);
8157   format %{ "FMRS   $dst,$src\t! MoveF2I" %}
8158   ins_encode %{
8159     __ vmov_f32($dst$$Register, $src$$FloatRegister);
8160   %}
8161   ins_pipe(iload_mem); // FIXME
8162 %}
8163 
8164 instruct MoveI2F_reg_reg(regF dst, iRegI src) %{
8165   match(Set dst (MoveI2F src));
8166   ins_cost(MEMORY_REF_COST); // FIXME
8167 
8168   size(4);
8169   format %{ "FMSR   $dst,$src\t! MoveI2F" %}
8170   ins_encode %{
8171     __ vmov_f32($dst$$FloatRegister, $src$$Register);
8172   %}
8173   ins_pipe(iload_mem); // FIXME
8174 %}
8175 
8176 instruct MoveD2L_reg_reg(iRegL dst, regD src) %{
8177   match(Set dst (MoveD2L src));
8178   effect(DEF dst, USE src);
8179   ins_cost(MEMORY_REF_COST); // FIXME
8180 
8181   size(4);
8182   format %{ "FMRRD    $dst,$src\t! MoveD2L" %}
8183   ins_encode %{
8184     __ vmov_f64($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
8185   %}
8186   ins_pipe(iload_mem); // FIXME
8187 %}
8188 
8189 instruct MoveL2D_reg_reg(regD dst, iRegL src) %{
8190   match(Set dst (MoveL2D src));
8191   effect(DEF dst, USE src);
8192   ins_cost(MEMORY_REF_COST); // FIXME
8193 
8194   size(4);
8195   format %{ "FMDRR   $dst,$src\t! MoveL2D" %}
8196   ins_encode %{
8197     __ vmov_f64($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
8198   %}
8199   ins_pipe(ialu_reg_reg); // FIXME
8200 %}
8201 
8202 //-----------
8203 // Long to Double conversion
8204 
8205 // Magic constant, 0x43300000
8206 instruct loadConI_x43300000(iRegI dst) %{
8207   effect(DEF dst);
8208   size(8);
8209   format %{ "MOV_SLOW  $dst,0x43300000\t! 2^52" %}
8210   ins_encode %{
8211     __ mov($dst$$Register, 0x43300000);
8212   %}
8213   ins_pipe(ialu_none);
8214 %}
8215 
8216 // Magic constant, 0x41f00000
8217 instruct loadConI_x41f00000(iRegI dst) %{
8218   effect(DEF dst);
8219   size(8);
8220   format %{ "MOV_SLOW  $dst, 0x41f00000\t! 2^32" %}
8221   ins_encode %{
8222     __ mov($dst$$Register, 0x41f00000);
8223   %}
8224   ins_pipe(ialu_none);
8225 %}
8226 
8227 instruct loadConI_x0(iRegI dst) %{
8228   effect(DEF dst);
8229   size(4);
8230   format %{ "MOV  $dst, 0x0\t! 0" %}
8231   ins_encode %{
8232     __ mov($dst$$Register, 0);
8233   %}
8234   ins_pipe(ialu_none);
8235 %}
8236 
8237 // Construct a double from two float halves
8238 instruct regDHi_regDLo_to_regD(regD_low dst, regD_low src1, regD_low src2) %{
8239   effect(DEF dst, USE src1, USE src2);
8240   size(8);
8241   format %{ "FCPYS  $dst.hi,$src1.hi\n\t"
8242             "FCPYS  $dst.lo,$src2.lo" %}
8243   ins_encode %{
8244     __ vmov_f32($dst$$FloatRegister->successor(FloatRegisterImpl::SINGLE), $src1$$FloatRegister->successor(FloatRegisterImpl::SINGLE));
8245     __ vmov_f32($dst$$FloatRegister, $src2$$FloatRegister);
8246   %}
8247   ins_pipe(faddD_reg_reg);
8248 %}
8249 
8250 // Convert integer in high half of a double register (in the lower half of
8251 // the double register file) to double
8252 instruct convI2D_regDHi_regD(regD dst, regD_low src) %{
8253   effect(DEF dst, USE src);
8254   size(4);
8255   format %{ "FSITOD  $dst,$src" %}
8256   ins_encode %{
8257     __ vcvt_f64_s32($dst$$FloatRegister, $src$$FloatRegister->successor(FloatRegisterImpl::SINGLE));// TODO verify the samentics is the same as was before
8258   %}
8259   ins_pipe(fcvtLHi2D);
8260 %}
8261 
8262 // Add float double precision
8263 instruct addD_regD_regD(regD dst, regD src1, regD src2) %{
8264   effect(DEF dst, USE src1, USE src2);
8265   size(4);
8266   format %{ "FADDD  $dst,$src1,$src2" %}
8267   ins_encode %{
8268     __ vadd_f64($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8269   %}
8270   ins_pipe(faddD_reg_reg);
8271 %}
8272 
8273 // Sub float double precision
8274 instruct subD_regD_regD(regD dst, regD src1, regD src2) %{
8275   effect(DEF dst, USE src1, USE src2);
8276   size(4);
8277   format %{ "FSUBD  $dst,$src1,$src2" %}
8278   ins_encode %{
8279     __ vsub_f64($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8280   %}
8281   ins_pipe(faddD_reg_reg);
8282 %}
8283 
8284 // Mul float double precision
8285 instruct mulD_regD_regD(regD dst, regD src1, regD src2) %{
8286   effect(DEF dst, USE src1, USE src2);
8287   size(4);
8288   format %{ "FMULD  $dst,$src1,$src2" %}
8289   ins_encode %{
8290     __ vmul_f64($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8291   %}
8292   ins_pipe(fmulD_reg_reg);
8293 %}
8294 
8295 instruct regL_to_regD(regD dst, iRegL src) %{
8296   // No match rule to avoid chain rule match.
8297   effect(DEF dst, USE src);
8298   ins_cost(MEMORY_REF_COST);
8299   size(4);
8300   format %{ "FMDRR   $dst,$src\t! regL to regD" %}
8301   ins_encode %{
8302     __ vmov_f64($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
8303   %}
8304   ins_pipe(ialu_reg_reg); // FIXME
8305 %}
8306 
8307 instruct regI_regI_to_regD(regD dst, iRegI src1, iRegI src2) %{
8308   // No match rule to avoid chain rule match.
8309   effect(DEF dst, USE src1, USE src2);
8310   ins_cost(MEMORY_REF_COST);
8311   size(4);
8312   format %{ "FMDRR   $dst,$src1,$src2\t! regI,regI to regD" %}
8313   ins_encode %{
8314     __ vmov_f64($dst$$FloatRegister, $src1$$Register, $src2$$Register);
8315   %}
8316   ins_pipe(ialu_reg_reg); // FIXME
8317 %}
8318 
8319 instruct convL2D_reg_slow_fxtof(regD dst, iRegL src) %{
8320   match(Set dst (ConvL2D src));
8321   ins_cost(DEFAULT_COST*8 + MEMORY_REF_COST*6); // FIXME
8322 
8323   expand %{
8324     regD_low   tmpsrc;
8325     iRegI      ix43300000;
8326     iRegI      ix41f00000;
8327     iRegI      ix0;
8328     regD_low   dx43300000;
8329     regD       dx41f00000;
8330     regD       tmp1;
8331     regD_low   tmp2;
8332     regD       tmp3;
8333     regD       tmp4;
8334 
8335     regL_to_regD(tmpsrc, src);
8336 
8337     loadConI_x43300000(ix43300000);
8338     loadConI_x41f00000(ix41f00000);
8339     loadConI_x0(ix0);
8340 
8341     regI_regI_to_regD(dx43300000, ix0, ix43300000);
8342     regI_regI_to_regD(dx41f00000, ix0, ix41f00000);
8343 
8344     convI2D_regDHi_regD(tmp1, tmpsrc);
8345     regDHi_regDLo_to_regD(tmp2, dx43300000, tmpsrc);
8346     subD_regD_regD(tmp3, tmp2, dx43300000);
8347     mulD_regD_regD(tmp4, tmp1, dx41f00000);
8348     addD_regD_regD(dst, tmp3, tmp4);
8349   %}
8350 %}
8351 
8352 instruct convL2I_reg(iRegI dst, iRegL src) %{
8353   match(Set dst (ConvL2I src));
8354   size(4);
8355   format %{ "MOV    $dst,$src.lo\t! long->int" %}
8356   ins_encode %{
8357     __ mov($dst$$Register, $src$$Register);
8358   %}
8359   ins_pipe(ialu_move_reg_I_to_L);
8360 %}
8361 
8362 // Register Shift Right Immediate
8363 instruct shrL_reg_imm6_L2I(iRegI dst, iRegL src, immI_32_63 cnt) %{
8364   match(Set dst (ConvL2I (RShiftL src cnt)));
8365   size(4);
8366   format %{ "ASR    $dst,$src.hi,($cnt - 32)\t! long->int or mov if $cnt==32" %}
8367   ins_encode %{
8368     if ($cnt$$constant == 32) {
8369       __ mov($dst$$Register, $src$$Register->successor());
8370     } else {
8371       __ mov($dst$$Register, $src$$Register->successor(), asr($cnt$$constant - 32));
8372     }
8373   %}
8374   ins_pipe(ialu_reg_imm);
8375 %}
8376 
8377 
8378 //----------Control Flow Instructions------------------------------------------
8379 // Compare Instructions
8380 // Compare Integers
8381 instruct compI_iReg(flagsReg icc, iRegI op1, iRegI op2) %{
8382   match(Set icc (CmpI op1 op2));
8383   effect( DEF icc, USE op1, USE op2 );
8384 
8385   size(4);
8386   format %{ "cmp_32 $op1,$op2\t! int" %}
8387   ins_encode %{
8388     __ cmp($op1$$Register, $op2$$Register);
8389   %}
8390   ins_pipe(ialu_cconly_reg_reg);
8391 %}
8392 
8393 instruct compU_iReg(flagsRegU icc, iRegI op1, iRegI op2) %{
8394   match(Set icc (CmpU op1 op2));
8395 
8396   size(4);
8397   format %{ "cmp_32 $op1,$op2\t! unsigned int" %}
8398   ins_encode %{
8399     __ cmp($op1$$Register, $op2$$Register);
8400   %}
8401   ins_pipe(ialu_cconly_reg_reg);
8402 %}
8403 
8404 instruct compI_iReg_immneg(flagsReg icc, iRegI op1, aimmIneg op2) %{
8405   match(Set icc (CmpI op1 op2));
8406   effect( DEF icc, USE op1 );
8407 
8408   size(4);
8409   format %{ "cmn_32 $op1,-$op2\t! int" %}
8410   ins_encode %{
8411     __ cmn($op1$$Register, -$op2$$constant);
8412   %}
8413   ins_pipe(ialu_cconly_reg_imm);
8414 %}
8415 
8416 instruct compI_iReg_imm(flagsReg icc, iRegI op1, aimmI op2) %{
8417   match(Set icc (CmpI op1 op2));
8418   effect( DEF icc, USE op1 );
8419 
8420   size(4);
8421   format %{ "cmp_32 $op1,$op2\t! int" %}
8422   ins_encode %{
8423     __ cmp($op1$$Register, $op2$$constant);
8424   %}
8425   ins_pipe(ialu_cconly_reg_imm);
8426 %}
8427 
8428 instruct testI_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immI0 zero ) %{
8429   match(Set icc (CmpI (AndI op1 op2) zero));
8430   size(4);
8431   format %{ "tst $op2,$op1" %}
8432 
8433   ins_encode %{
8434     __ tst($op1$$Register, $op2$$Register);
8435   %}
8436   ins_pipe(ialu_cconly_reg_reg_zero);
8437 %}
8438 
8439 instruct testshlI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
8440   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
8441   size(4);
8442   format %{ "TST   $op2,$op1<<$op3" %}
8443 
8444   ins_encode %{
8445     __ tst($op1$$Register, $op2$$Register, lsl($op3$$Register));
8446   %}
8447   ins_pipe(ialu_cconly_reg_reg_zero);
8448 %}
8449 
8450 instruct testshlI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
8451   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
8452   size(4);
8453   format %{ "tst $op2,$op1<<$op3" %}
8454 
8455   ins_encode %{
8456     __ tst($op1$$Register, $op2$$Register, lsl($op3$$constant));
8457   %}
8458   ins_pipe(ialu_cconly_reg_reg_zero);
8459 %}
8460 
8461 instruct testsarI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
8462   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
8463   size(4);
8464   format %{ "TST   $op2,$op1<<$op3" %}
8465 
8466   ins_encode %{
8467     __ tst($op1$$Register, $op2$$Register, asr($op3$$Register));
8468   %}
8469   ins_pipe(ialu_cconly_reg_reg_zero);
8470 %}
8471 
8472 instruct testsarI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
8473   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
8474   size(4);
8475   format %{ "tst $op2,$op1<<$op3" %}
8476 
8477   ins_encode %{
8478     __ tst($op1$$Register, $op2$$Register, asr($op3$$constant));
8479   %}
8480   ins_pipe(ialu_cconly_reg_reg_zero);
8481 %}
8482 
8483 instruct testshrI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
8484   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
8485   size(4);
8486   format %{ "TST   $op2,$op1<<$op3" %}
8487 
8488   ins_encode %{
8489     __ tst($op1$$Register, $op2$$Register, lsr($op3$$Register));
8490   %}
8491   ins_pipe(ialu_cconly_reg_reg_zero);
8492 %}
8493 
8494 instruct testshrI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
8495   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
8496   size(4);
8497   format %{ "tst $op2,$op1<<$op3" %}
8498 
8499   ins_encode %{
8500     __ tst($op1$$Register, $op2$$Register, lsr($op3$$constant));
8501   %}
8502   ins_pipe(ialu_cconly_reg_reg_zero);
8503 %}
8504 
8505 instruct testI_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, limmI op2, immI0 zero ) %{
8506   match(Set icc (CmpI (AndI op1 op2) zero));
8507   size(4);
8508   format %{ "tst $op2,$op1" %}
8509 
8510   ins_encode %{
8511     __ tst($op1$$Register, $op2$$constant);
8512   %}
8513   ins_pipe(ialu_cconly_reg_imm_zero);
8514 %}
8515 
8516 instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegI tmp) %{
8517   match(Set xcc (CmpL op1 op2));
8518   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
8519 
8520   size(8);
8521   format %{ "CMP     $op1.low,$op2.low\t\t! long\n\t"
8522             "SBCS    $tmp,$op1.hi,$op2.hi" %}
8523   ins_encode %{
8524     __ cmp($op1$$Register, $op2$$Register);
8525     __ sbcs($tmp$$Register, $op1$$Register->successor(), $op2$$Register->successor());
8526   %}
8527   ins_pipe(ialu_cconly_reg_reg);
8528 %}
8529 
8530 instruct compL_reg_reg_EQNE(flagsRegL_EQNE xcc, iRegL op1, iRegL op2) %{
8531   match(Set xcc (CmpL op1 op2));
8532   effect( DEF xcc, USE op1, USE op2 );
8533 
8534   size(8);
8535   format %{ "TEQ    $op1.hi,$op2.hi\t\t! long\n\t"
8536             "TEQ.eq $op1.lo,$op2.lo" %}
8537   ins_encode %{
8538     __ teq($op1$$Register->successor(), $op2$$Register->successor());
8539     __ teq($op1$$Register, $op2$$Register, Assembler::EQ);
8540   %}
8541   ins_pipe(ialu_cconly_reg_reg);
8542 %}
8543 
8544 instruct compL_reg_reg_LEGT(flagsRegL_LEGT xcc, iRegL op1, iRegL op2, iRegI tmp) %{
8545   match(Set xcc (CmpL op1 op2));
8546   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
8547 
8548   size(8);
8549   format %{ "CMP     $op2.low,$op1.low\t\t! long\n\t"
8550             "SBCS    $tmp,$op2.hi,$op1.hi" %}
8551   ins_encode %{
8552     __ cmp($op2$$Register, $op1$$Register);
8553     __ sbcs($tmp$$Register, $op2$$Register->successor(), $op1$$Register->successor());
8554   %}
8555   ins_pipe(ialu_cconly_reg_reg);
8556 %}
8557 
8558 instruct compUL_reg_reg(flagsRegUL xcc, iRegL op1, iRegL op2) %{
8559   match(Set xcc (CmpUL op1 op2));
8560   effect( DEF xcc, USE op1, USE op2 );
8561 
8562   size(8);
8563   format %{ "CMP     $op1.hi,$op2.hi\t\t! long\n\t"
8564             "CMP.eq  $op1.low,$op2.low" %}
8565   ins_encode %{
8566     __ cmp($op1$$Register->successor(), $op2$$Register->successor());
8567     __ cmp($op1$$Register, $op2$$Register, Assembler::EQ);
8568   %}
8569   ins_pipe(ialu_cconly_reg_reg);
8570 %}
8571 
8572 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
8573 // (hi($con$$constant), lo($con$$constant)) becomes
8574 instruct compL_reg_con_LTGE(flagsRegL_LTGE xcc, iRegL op1, immLlowRot con, iRegI tmp) %{
8575   match(Set xcc (CmpL op1 con));
8576   effect( DEF xcc, USE op1, USE con, TEMP tmp );
8577 
8578   size(8);
8579   format %{ "CMP     $op1.low,$con\t\t! long\n\t"
8580             "SBCS    $tmp,$op1.hi,0" %}
8581   ins_encode %{
8582     __ cmp($op1$$Register, (int)$con$$constant);
8583     __ sbcs($tmp$$Register, $op1$$Register->successor(), 0);
8584   %}
8585 
8586   ins_pipe(ialu_cconly_reg_reg);
8587 %}
8588 
8589 instruct compUL_reg_con(flagsRegUL xcc, iRegL op1, immLlowRot con ) %{
8590   match(Set xcc (CmpUL op1 con));
8591   effect( DEF xcc, USE op1, USE con );
8592 
8593   size(8);
8594   format %{ "CMP     $op1.hi,0\t\t! long\n\t"
8595             "CMP.eq  $op1.low,$con" %}
8596   ins_encode %{
8597     __ cmp($op1$$Register->successor(), 0);
8598     __ cmp($op1$$Register, (int)$con$$constant, Assembler::EQ);
8599   %}
8600 
8601   ins_pipe(ialu_cconly_reg_reg);
8602 %}
8603 
8604 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
8605 // (hi($con$$constant), lo($con$$constant)) becomes
8606 instruct compL_reg_con_EQNE(flagsRegL_EQNE xcc, iRegL op1, immLlowRot con) %{
8607   match(Set xcc (CmpL op1 con));
8608   effect( DEF xcc, USE op1, USE con );
8609 
8610   size(8);
8611   format %{ "TEQ    $op1.hi,0\t\t! long\n\t"
8612             "TEQ.eq $op1.lo,$con" %}
8613   ins_encode %{
8614     __ teq($op1$$Register->successor(), 0);
8615     __ teq($op1$$Register, (int)$con$$constant, Assembler::EQ);
8616   %}
8617 
8618   ins_pipe(ialu_cconly_reg_reg);
8619 %}
8620 
8621 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
8622 // (hi($con$$constant), lo($con$$constant)) becomes
8623 instruct compL_reg_con_LEGT(flagsRegL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
8624   match(Set xcc (CmpL op1 con));
8625   effect( DEF xcc, USE op1, USE con, TEMP tmp );
8626 
8627   size(8);
8628   format %{ "RSBS    $tmp,$op1.low,$con\t\t! long\n\t"
8629             "RSCS    $tmp,$op1.hi,0" %}
8630   ins_encode %{
8631     __ rsbs($tmp$$Register, $op1$$Register, (long)$con$$constant);
8632     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
8633   %}
8634 
8635   ins_pipe(ialu_cconly_reg_reg);
8636 %}
8637 
8638 /* instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ */
8639 /*   match(Set xcc (CmpL (AndL op1 op2) zero)); */
8640 /*   ins_encode %{ */
8641 /*     __ stop("testL_reg_reg unimplemented"); */
8642 /*   %} */
8643 /*   ins_pipe(ialu_cconly_reg_reg); */
8644 /* %} */
8645 
8646 /* // useful for checking the alignment of a pointer: */
8647 /* instruct testL_reg_con(flagsRegL xcc, iRegL op1, immLlowRot con, immL0 zero) %{ */
8648 /*   match(Set xcc (CmpL (AndL op1 con) zero)); */
8649 /*   ins_encode %{ */
8650 /*     __ stop("testL_reg_con unimplemented"); */
8651 /*   %} */
8652 /*   ins_pipe(ialu_cconly_reg_reg); */
8653 /* %} */
8654 
8655 instruct compU_iReg_imm(flagsRegU icc, iRegI op1, aimmU31 op2 ) %{
8656   match(Set icc (CmpU op1 op2));
8657 
8658   size(4);
8659   format %{ "cmp_32 $op1,$op2\t! unsigned" %}
8660   ins_encode %{
8661     __ cmp($op1$$Register, $op2$$constant);
8662   %}
8663   ins_pipe(ialu_cconly_reg_imm);
8664 %}
8665 
8666 // Compare Pointers
8667 instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{
8668   match(Set pcc (CmpP op1 op2));
8669 
8670   size(4);
8671   format %{ "CMP    $op1,$op2\t! ptr" %}
8672   ins_encode %{
8673     __ cmp($op1$$Register, $op2$$Register);
8674   %}
8675   ins_pipe(ialu_cconly_reg_reg);
8676 %}
8677 
8678 instruct compP_iRegP_imm(flagsRegP pcc, iRegP op1, aimmP op2 ) %{
8679   match(Set pcc (CmpP op1 op2));
8680 
8681   size(4);
8682   format %{ "CMP    $op1,$op2\t! ptr" %}
8683   ins_encode %{
8684     assert($op2$$constant == 0 || _opnds[2]->constant_reloc() == relocInfo::none, "reloc in cmp?");
8685     __ cmp($op1$$Register, $op2$$constant);
8686   %}
8687   ins_pipe(ialu_cconly_reg_imm);
8688 %}
8689 
8690 //----------Max and Min--------------------------------------------------------
8691 // Min Instructions
8692 // Conditional move for min
8693 instruct cmovI_reg_lt( iRegI op2, iRegI op1, flagsReg icc ) %{
8694   effect( USE_DEF op2, USE op1, USE icc );
8695 
8696   size(4);
8697   format %{ "MOV.lt  $op2,$op1\t! min" %}
8698   ins_encode %{
8699     __ mov($op2$$Register, $op1$$Register, Assembler::LT);
8700   %}
8701   ins_pipe(ialu_reg_flags);
8702 %}
8703 
8704 // Min Register with Register.
8705 instruct minI_eReg(iRegI op1, iRegI op2) %{
8706   match(Set op2 (MinI op1 op2));
8707   ins_cost(DEFAULT_COST*2);
8708   expand %{
8709     flagsReg icc;
8710     compI_iReg(icc,op1,op2);
8711     cmovI_reg_lt(op2,op1,icc);
8712   %}
8713 %}
8714 
8715 // Max Instructions
8716 // Conditional move for max
8717 instruct cmovI_reg_gt( iRegI op2, iRegI op1, flagsReg icc ) %{
8718   effect( USE_DEF op2, USE op1, USE icc );
8719   format %{ "MOV.gt  $op2,$op1\t! max" %}
8720   ins_encode %{
8721     __ mov($op2$$Register, $op1$$Register, Assembler::GT);
8722   %}
8723   ins_pipe(ialu_reg_flags);
8724 %}
8725 
8726 // Max Register with Register
8727 instruct maxI_eReg(iRegI op1, iRegI op2) %{
8728   match(Set op2 (MaxI op1 op2));
8729   ins_cost(DEFAULT_COST*2);
8730   expand %{
8731     flagsReg icc;
8732     compI_iReg(icc,op1,op2);
8733     cmovI_reg_gt(op2,op1,icc);
8734   %}
8735 %}
8736 
8737 
8738 //----------Float Compares----------------------------------------------------
8739 // Compare floating, generate condition code
8740 instruct cmpF_cc(flagsRegF fcc, flagsReg icc, regF src1, regF src2) %{
8741   match(Set icc (CmpF src1 src2));
8742   effect(KILL fcc);
8743 
8744   size(8);
8745   format %{ "FCMPs  $src1,$src2\n\t"
8746             "FMSTAT" %}
8747   ins_encode %{
8748     __ vcmp_f32($src1$$FloatRegister, $src2$$FloatRegister);
8749     __ get_fpsr();
8750   %}
8751   ins_pipe(faddF_fcc_reg_reg_zero);
8752 %}
8753 
8754 instruct cmpF0_cc(flagsRegF fcc, flagsReg icc, regF src1, immF0 src2) %{
8755   match(Set icc (CmpF src1 src2));
8756   effect(KILL fcc);
8757 
8758   size(8);
8759   format %{ "FCMPs  $src1,$src2\n\t"
8760             "FMSTAT" %}
8761   ins_encode %{
8762     __ vcmp_f32($src1$$FloatRegister, 0);
8763     __ get_fpsr();
8764   %}
8765   ins_pipe(faddF_fcc_reg_reg_zero);
8766 %}
8767 
8768 instruct cmpD_cc(flagsRegF fcc, flagsReg icc, regD src1, regD src2) %{
8769   match(Set icc (CmpD src1 src2));
8770   effect(KILL fcc);
8771 
8772   size(8);
8773   format %{ "FCMPd  $src1,$src2 \n\t"
8774             "FMSTAT" %}
8775   ins_encode %{
8776     __ vcmp_f64($src1$$FloatRegister, $src2$$FloatRegister);
8777     __ get_fpsr();
8778   %}
8779   ins_pipe(faddD_fcc_reg_reg_zero);
8780 %}
8781 
8782 instruct cmpD0_cc(flagsRegF fcc, flagsReg icc, regD src1, immD0 src2) %{
8783   match(Set icc (CmpD src1 src2));
8784   effect(KILL fcc);
8785 
8786   size(8);
8787   format %{ "FCMPZd  $src1,$src2 \n\t"
8788             "FMSTAT" %}
8789   ins_encode %{
8790     __ vcmp_f64($src1$$FloatRegister, 0);
8791     __ get_fpsr();
8792   %}
8793   ins_pipe(faddD_fcc_reg_reg_zero);
8794 %}
8795 
8796 // Compare floating, generate -1,0,1
8797 instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsRegF fcc) %{
8798   match(Set dst (CmpF3 src1 src2));
8799   effect(KILL fcc);
8800   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
8801   size(20);
8802   // same number of instructions as code using conditional moves but
8803   // doesn't kill integer condition register
8804   format %{ "FCMPs  $dst,$src1,$src2 \n\t"
8805             "VMRS   $dst, FPSCR \n\t"
8806             "OR     $dst, $dst, 0x08000000 \n\t"
8807             "EOR    $dst, $dst, $dst << 3 \n\t"
8808             "MOV    $dst, $dst >> 30" %}
8809   ins_encode %{
8810     __ vcmp_f32($src1$$FloatRegister, $src2$$FloatRegister);
8811     __ floating_cmp($dst$$Register);
8812   %}
8813   ins_pipe( floating_cmp );
8814 %}
8815 
8816 instruct cmpF0_reg(iRegI dst, regF src1, immF0 src2, flagsRegF fcc) %{
8817   match(Set dst (CmpF3 src1 src2));
8818   effect(KILL fcc);
8819   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
8820   size(20);
8821   // same number of instructions as code using conditional moves but
8822   // doesn't kill integer condition register
8823   format %{ "FCMPZs $dst,$src1,$src2 \n\t"
8824             "VMRS   $dst, FPSCR \n\t"
8825             "OR     $dst, $dst, 0x08000000 \n\t"
8826             "EOR    $dst, $dst, $dst << 3 \n\t"
8827             "MOV    $dst, $dst >> 30" %}
8828   ins_encode %{
8829     __ vcmp_f32($src1$$FloatRegister, 0);
8830     __ floating_cmp($dst$$Register);
8831   %}
8832   ins_pipe( floating_cmp );
8833 %}
8834 
8835 instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsRegF fcc) %{
8836   match(Set dst (CmpD3 src1 src2));
8837   effect(KILL fcc);
8838   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
8839   size(20);
8840   // same number of instructions as code using conditional moves but
8841   // doesn't kill integer condition register
8842   format %{ "FCMPd  $dst,$src1,$src2 \n\t"
8843             "VMRS   $dst, FPSCR \n\t"
8844             "OR     $dst, $dst, 0x08000000 \n\t"
8845             "EOR    $dst, $dst, $dst << 3 \n\t"
8846             "MOV    $dst, $dst >> 30" %}
8847   ins_encode %{
8848     __ vcmp_f64($src1$$FloatRegister, $src2$$FloatRegister);
8849     __ floating_cmp($dst$$Register);
8850   %}
8851   ins_pipe( floating_cmp );
8852 %}
8853 
8854 instruct cmpD0_reg(iRegI dst, regD src1, immD0 src2, flagsRegF fcc) %{
8855   match(Set dst (CmpD3 src1 src2));
8856   effect(KILL fcc);
8857   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
8858   size(20);
8859   // same number of instructions as code using conditional moves but
8860   // doesn't kill integer condition register
8861   format %{ "FCMPZd $dst,$src1,$src2 \n\t"
8862             "VMRS   $dst, FPSCR \n\t"
8863             "OR     $dst, $dst, 0x08000000 \n\t"
8864             "EOR    $dst, $dst, $dst << 3 \n\t"
8865             "MOV    $dst, $dst >> 30" %}
8866   ins_encode %{
8867     __ vcmp_f64($src1$$FloatRegister, 0);
8868     __ floating_cmp($dst$$Register);
8869   %}
8870   ins_pipe( floating_cmp );
8871 %}
8872 
8873 //----------Branches---------------------------------------------------------
8874 // Jump
8875 // (compare 'operand indIndex' and 'instruct addP_reg_reg' above)
8876 // FIXME
8877 instruct jumpXtnd(iRegX switch_val, iRegP tmp) %{
8878   match(Jump switch_val);
8879   effect(TEMP tmp);
8880   ins_cost(350);
8881   format %{  "ADD    $tmp, $constanttablebase, $switch_val\n\t"
8882              "LDR    $tmp,[$tmp + $constantoffset]\n\t"
8883              "BX     $tmp" %}
8884   size(20);
8885   ins_encode %{
8886     Register table_reg;
8887     Register label_reg = $tmp$$Register;
8888     if (constant_offset() == 0) {
8889       table_reg = $constanttablebase;
8890       __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
8891     } else {
8892       table_reg = $tmp$$Register;
8893       int offset = $constantoffset;
8894       if (is_memoryP(offset)) {
8895         __ add(table_reg, $constanttablebase, $switch_val$$Register);
8896         __ ldr(label_reg, Address(table_reg, offset));
8897       } else {
8898         __ mov(table_reg, $constantoffset);
8899         __ add(table_reg, $constanttablebase, table_reg);
8900         __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
8901       }
8902     }
8903     __ b(label_reg); // ldr + b better than ldr to PC for branch predictor?
8904     //    __ ldr(PC, Address($table$$Register, $switch_val$$Register));
8905   %}
8906   ins_pipe(ialu_reg_reg);
8907 %}
8908 
8909 // // Direct Branch.
8910 instruct branch(label labl) %{
8911   match(Goto);
8912   effect(USE labl);
8913 
8914   size(4);
8915   ins_cost(BRANCH_COST);
8916   format %{ "B     $labl" %}
8917   ins_encode %{
8918     __ b(*($labl$$label));
8919   %}
8920   ins_pipe(br);
8921 %}
8922 
8923 // Conditional Direct Branch
8924 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{
8925   match(If cmp icc);
8926   effect(USE labl);
8927 
8928   size(4);
8929   ins_cost(BRANCH_COST);
8930   format %{ "B$cmp   $icc,$labl" %}
8931   ins_encode %{
8932     __ b(*($labl$$label), (Assembler::Condition)($cmp$$cmpcode));
8933   %}
8934   ins_pipe(br_cc);
8935 %}
8936 
8937 instruct branchCon_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, label labl) %{
8938   match(If cmp icc);
8939   effect(USE labl);
8940   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
8941 
8942   size(4);
8943   ins_cost(BRANCH_COST);
8944   format %{ "B$cmp   $icc,$labl" %}
8945   ins_encode %{
8946     __ b(*($labl$$label), (Assembler::Condition)($cmp$$cmpcode));
8947   %}
8948   ins_pipe(br_cc);
8949 %}
8950 
8951 instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{
8952   match(If cmp icc);
8953   effect(USE labl);
8954 
8955   size(4);
8956   ins_cost(BRANCH_COST);
8957   format %{ "B$cmp  $icc,$labl" %}
8958   ins_encode %{
8959     __ b(*($labl$$label), (Assembler::Condition)($cmp$$cmpcode));
8960   %}
8961   ins_pipe(br_cc);
8962 %}
8963 
8964 instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{
8965   match(If cmp pcc);
8966   effect(USE labl);
8967 
8968   size(4);
8969   ins_cost(BRANCH_COST);
8970   format %{ "B$cmp  $pcc,$labl" %}
8971   ins_encode %{
8972     __ b(*($labl$$label), (Assembler::Condition)($cmp$$cmpcode));
8973   %}
8974   ins_pipe(br_cc);
8975 %}
8976 
8977 instruct branchConL_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, label labl) %{
8978   match(If cmp xcc);
8979   effect(USE labl);
8980   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8981 
8982   size(4);
8983   ins_cost(BRANCH_COST);
8984   format %{ "B$cmp  $xcc,$labl" %}
8985   ins_encode %{
8986     __ b(*($labl$$label), (Assembler::Condition)($cmp$$cmpcode));
8987   %}
8988   ins_pipe(br_cc);
8989 %}
8990 
8991 instruct branchConL_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, label labl) %{
8992   match(If cmp xcc);
8993   effect(USE labl);
8994   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8995 
8996   size(4);
8997   ins_cost(BRANCH_COST);
8998   format %{ "B$cmp  $xcc,$labl" %}
8999   ins_encode %{
9000     __ b(*($labl$$label), (Assembler::Condition)($cmp$$cmpcode));
9001   %}
9002   ins_pipe(br_cc);
9003 %}
9004 
9005 instruct branchConL_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, label labl) %{
9006   match(If cmp xcc);
9007   effect(USE labl);
9008   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le );
9009 
9010   size(4);
9011   ins_cost(BRANCH_COST);
9012   format %{ "B$cmp  $xcc,$labl" %}
9013   ins_encode %{
9014     __ b(*($labl$$label), (Assembler::Condition)($cmp$$cmpcode));
9015   %}
9016   ins_pipe(br_cc);
9017 %}
9018 
9019 instruct branchConUL(cmpOpU cmp, flagsRegUL xcc, label labl) %{
9020   match(If cmp xcc);
9021   effect(USE labl);
9022 
9023   size(4);
9024   ins_cost(BRANCH_COST);
9025   format %{ "B$cmp  $xcc,$labl" %}
9026   ins_encode %{
9027     __ b(*($labl$$label), (Assembler::Condition)($cmp$$cmpcode));
9028   %}
9029   ins_pipe(br_cc);
9030 %}
9031 
9032 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
9033   match(CountedLoopEnd cmp icc);
9034   effect(USE labl);
9035 
9036   size(4);
9037   ins_cost(BRANCH_COST);
9038   format %{ "B$cmp   $icc,$labl\t! Loop end" %}
9039   ins_encode %{
9040     __ b(*($labl$$label), (Assembler::Condition)($cmp$$cmpcode));
9041   %}
9042   ins_pipe(br_cc);
9043 %}
9044 
9045 // instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{
9046 //   match(CountedLoopEnd cmp icc);
9047 //   ins_pipe(br_cc);
9048 // %}
9049 
9050 // ============================================================================
9051 // Long Compare
9052 //
9053 // Currently we hold longs in 2 registers.  Comparing such values efficiently
9054 // is tricky.  The flavor of compare used depends on whether we are testing
9055 // for LT, LE, or EQ.  For a simple LT test we can check just the sign bit.
9056 // The GE test is the negated LT test.  The LE test can be had by commuting
9057 // the operands (yielding a GE test) and then negating; negate again for the
9058 // GT test.  The EQ test is done by ORcc'ing the high and low halves, and the
9059 // NE test is negated from that.
9060 
9061 // Due to a shortcoming in the ADLC, it mixes up expressions like:
9062 // (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)).  Note the
9063 // difference between 'Y' and '0L'.  The tree-matches for the CmpI sections
9064 // are collapsed internally in the ADLC's dfa-gen code.  The match for
9065 // (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the
9066 // foo match ends up with the wrong leaf.  One fix is to not match both
9067 // reg-reg and reg-zero forms of long-compare.  This is unfortunate because
9068 // both forms beat the trinary form of long-compare and both are very useful
9069 // on Intel which has so few registers.
9070 
9071 // instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{
9072 //   match(If cmp xcc);
9073 //   ins_pipe(br_cc);
9074 // %}
9075 
9076 // Manifest a CmpL3 result in an integer register.  Very painful.
9077 // This is the test to avoid.
9078 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
9079   match(Set dst (CmpL3 src1 src2) );
9080   effect( KILL ccr );
9081   ins_cost(6*DEFAULT_COST); // FIXME
9082   size(32);
9083   format %{
9084       "CMP    $src1.hi, $src2.hi\t\t! long\n"
9085     "\tMOV.gt $dst, 1\n"
9086     "\tmvn.lt $dst, 0\n"
9087     "\tB.ne   done\n"
9088     "\tSUBS   $dst, $src1.lo, $src2.lo\n"
9089     "\tMOV.hi $dst, 1\n"
9090     "\tmvn.lo $dst, 0\n"
9091     "done:"     %}
9092   ins_encode %{
9093     Label done;
9094     __ cmp($src1$$Register->successor(), $src2$$Register->successor());
9095     __ mov_i($dst$$Register, 1, Assembler::GT);
9096     __ mvn_i($dst$$Register, 0, Assembler::LT);
9097     __ b(done, Assembler::NE);
9098     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
9099     __ mov_i($dst$$Register, 1, Assembler::HI);
9100     __ mvn_i($dst$$Register, 0, Assembler::LO);
9101     __ bind(done);
9102   %}
9103   ins_pipe(cmpL_reg);
9104 %}
9105 
9106 // Conditional move
9107 instruct cmovLL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, iRegL src) %{
9108   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
9109   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
9110 
9111   ins_cost(150);
9112   size(8);
9113   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
9114             "MOV$cmp  $dst,$src.hi" %}
9115   ins_encode %{
9116     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
9117     __ mov($dst$$Register->successor(), $src$$Register->successor(), (Assembler::Condition)($cmp$$cmpcode));
9118   %}
9119   ins_pipe(ialu_reg);
9120 %}
9121 
9122 instruct cmovLL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, iRegL src) %{
9123   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
9124   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
9125 
9126   ins_cost(150);
9127   size(8);
9128   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
9129             "MOV$cmp  $dst,$src.hi" %}
9130   ins_encode %{
9131     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
9132     __ mov($dst$$Register->successor(), $src$$Register->successor(), (Assembler::Condition)($cmp$$cmpcode));
9133   %}
9134   ins_pipe(ialu_reg);
9135 %}
9136 
9137 instruct cmovLL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, iRegL src) %{
9138   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
9139   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
9140 
9141   ins_cost(150);
9142   size(8);
9143   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
9144             "MOV$cmp  $dst,$src.hi" %}
9145   ins_encode %{
9146     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
9147     __ mov($dst$$Register->successor(), $src$$Register->successor(), (Assembler::Condition)($cmp$$cmpcode));
9148   %}
9149   ins_pipe(ialu_reg);
9150 %}
9151 
9152 instruct cmovLL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, immL0 src) %{
9153   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
9154   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
9155   ins_cost(140);
9156   size(8);
9157   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
9158             "MOV$cmp  $dst,0" %}
9159   ins_encode %{
9160     __ mov($dst$$Register, 0, (Assembler::Condition)($cmp$$cmpcode));
9161     __ mov($dst$$Register->successor(), 0, (Assembler::Condition)($cmp$$cmpcode));
9162   %}
9163   ins_pipe(ialu_imm);
9164 %}
9165 
9166 instruct cmovLL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, immL0 src) %{
9167   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
9168   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
9169   ins_cost(140);
9170   size(8);
9171   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
9172             "MOV$cmp  $dst,0" %}
9173   ins_encode %{
9174     __ mov($dst$$Register, 0, (Assembler::Condition)($cmp$$cmpcode));
9175     __ mov($dst$$Register->successor(), 0, (Assembler::Condition)($cmp$$cmpcode));
9176   %}
9177   ins_pipe(ialu_imm);
9178 %}
9179 
9180 instruct cmovLL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, immL0 src) %{
9181   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
9182   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
9183   ins_cost(140);
9184   size(8);
9185   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
9186             "MOV$cmp  $dst,0" %}
9187   ins_encode %{
9188     __ mov($dst$$Register, 0, (Assembler::Condition)($cmp$$cmpcode));
9189     __ mov($dst$$Register->successor(), 0, (Assembler::Condition)($cmp$$cmpcode));
9190   %}
9191   ins_pipe(ialu_imm);
9192 %}
9193 
9194 instruct cmovIL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, iRegI src) %{
9195   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
9196   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
9197 
9198   ins_cost(150);
9199   size(4);
9200   format %{ "MOV$cmp  $dst,$src" %}
9201   ins_encode %{
9202     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
9203   %}
9204   ins_pipe(ialu_reg);
9205 %}
9206 
9207 instruct cmovIL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, iRegI src) %{
9208   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
9209   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
9210 
9211   ins_cost(150);
9212   size(4);
9213   format %{ "MOV$cmp  $dst,$src" %}
9214   ins_encode %{
9215     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
9216   %}
9217   ins_pipe(ialu_reg);
9218 %}
9219 
9220 instruct cmovIL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, iRegI src) %{
9221   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
9222   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
9223 
9224   ins_cost(150);
9225   size(4);
9226   format %{ "MOV$cmp  $dst,$src" %}
9227   ins_encode %{
9228     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
9229   %}
9230   ins_pipe(ialu_reg);
9231 %}
9232 
9233 instruct cmovIL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immI16 src) %{
9234   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
9235   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
9236 
9237   ins_cost(140);
9238   format %{ "MOVW$cmp  $dst,$src" %}
9239   ins_encode %{
9240     __ movw_i($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
9241   %}
9242   ins_pipe(ialu_imm);
9243 %}
9244 
9245 instruct cmovIL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, immI16 src) %{
9246   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
9247   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
9248 
9249   ins_cost(140);
9250   format %{ "MOVW$cmp  $dst,$src" %}
9251   ins_encode %{
9252     __ movw_i($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
9253   %}
9254   ins_pipe(ialu_imm);
9255 %}
9256 
9257 instruct cmovIL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immI16 src) %{
9258   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
9259   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
9260 
9261   ins_cost(140);
9262   format %{ "MOVW$cmp  $dst,$src" %}
9263   ins_encode %{
9264     __ movw_i($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
9265   %}
9266   ins_pipe(ialu_imm);
9267 %}
9268 
9269 instruct cmovPL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, iRegP src) %{
9270   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
9271   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
9272 
9273   ins_cost(150);
9274   size(4);
9275   format %{ "MOV$cmp  $dst,$src" %}
9276   ins_encode %{
9277     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
9278   %}
9279   ins_pipe(ialu_reg);
9280 %}
9281 
9282 instruct cmovPL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, iRegP src) %{
9283   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
9284   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
9285 
9286   ins_cost(150);
9287   size(4);
9288   format %{ "MOV$cmp  $dst,$src" %}
9289   ins_encode %{
9290     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
9291   %}
9292   ins_pipe(ialu_reg);
9293 %}
9294 
9295 instruct cmovPL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, iRegP src) %{
9296   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
9297   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
9298 
9299   ins_cost(150);
9300   size(4);
9301   format %{ "MOV$cmp  $dst,$src" %}
9302   ins_encode %{
9303     __ mov($dst$$Register, $src$$Register, (Assembler::Condition)($cmp$$cmpcode));
9304   %}
9305   ins_pipe(ialu_reg);
9306 %}
9307 
9308 instruct cmovPL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, immP0 src) %{
9309   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
9310   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
9311 
9312   ins_cost(140);
9313   format %{ "MOVW$cmp  $dst,$src" %}
9314   ins_encode %{
9315     __ movw_i($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
9316   %}
9317   ins_pipe(ialu_imm);
9318 %}
9319 
9320 instruct cmovPL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, immP0 src) %{
9321   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
9322   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
9323 
9324   ins_cost(140);
9325   format %{ "MOVW$cmp  $dst,$src" %}
9326   ins_encode %{
9327     __ movw_i($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
9328   %}
9329   ins_pipe(ialu_imm);
9330 %}
9331 
9332 instruct cmovPL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, immP0 src) %{
9333   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
9334   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
9335 
9336   ins_cost(140);
9337   format %{ "MOVW$cmp  $dst,$src" %}
9338   ins_encode %{
9339     __ movw_i($dst$$Register, $src$$constant, (Assembler::Condition)($cmp$$cmpcode));
9340   %}
9341   ins_pipe(ialu_imm);
9342 %}
9343 
9344 instruct cmovFL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regF dst, regF src) %{
9345   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
9346   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
9347   ins_cost(150);
9348   size(4);
9349   format %{ "FCPYS$cmp $dst,$src" %}
9350   ins_encode %{
9351     __ vmov_f32($dst$$FloatRegister, $src$$FloatRegister, (Assembler::Condition)($cmp$$cmpcode));
9352   %}
9353   ins_pipe(int_conditional_float_move);
9354 %}
9355 
9356 instruct cmovFL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regF dst, regF src) %{
9357   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
9358   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
9359   ins_cost(150);
9360   size(4);
9361   format %{ "FCPYS$cmp $dst,$src" %}
9362   ins_encode %{
9363     __ vmov_f32($dst$$FloatRegister, $src$$FloatRegister, (Assembler::Condition)($cmp$$cmpcode));
9364   %}
9365   ins_pipe(int_conditional_float_move);
9366 %}
9367 
9368 instruct cmovFL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regF dst, regF src) %{
9369   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
9370   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
9371   ins_cost(150);
9372   size(4);
9373   format %{ "FCPYS$cmp $dst,$src" %}
9374   ins_encode %{
9375     __ vmov_f32($dst$$FloatRegister, $src$$FloatRegister, (Assembler::Condition)($cmp$$cmpcode));
9376   %}
9377   ins_pipe(int_conditional_float_move);
9378 %}
9379 
9380 instruct cmovDL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regD dst, regD src) %{
9381   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
9382   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
9383 
9384   ins_cost(150);
9385   size(4);
9386   format %{ "FCPYD$cmp $dst,$src" %}
9387   ins_encode %{
9388     __ vmov_f64($dst$$FloatRegister, $src$$FloatRegister, (Assembler::Condition)($cmp$$cmpcode));
9389   %}
9390   ins_pipe(int_conditional_float_move);
9391 %}
9392 
9393 instruct cmovDL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regD dst, regD src) %{
9394   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
9395   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
9396 
9397   ins_cost(150);
9398   size(4);
9399   format %{ "FCPYD$cmp $dst,$src" %}
9400   ins_encode %{
9401     __ vmov_f64($dst$$FloatRegister, $src$$FloatRegister, (Assembler::Condition)($cmp$$cmpcode));
9402   %}
9403   ins_pipe(int_conditional_float_move);
9404 %}
9405 
9406 instruct cmovDL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regD dst, regD src) %{
9407   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
9408   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
9409 
9410   ins_cost(150);
9411   size(4);
9412   format %{ "FCPYD$cmp $dst,$src" %}
9413   ins_encode %{
9414     __ vmov_f64($dst$$FloatRegister, $src$$FloatRegister, (Assembler::Condition)($cmp$$cmpcode));
9415   %}
9416   ins_pipe(int_conditional_float_move);
9417 %}
9418 
9419 // ============================================================================
9420 // Safepoint Instruction
9421 // rather than KILL R12, it would be better to use any reg as
9422 // TEMP. Can't do that at this point because it crashes the compiler
9423 instruct safePoint_poll(iRegP poll, R12RegI tmp, flagsReg icc) %{
9424   match(SafePoint poll);
9425   effect(USE poll, KILL tmp, KILL icc);
9426 
9427   size(4);
9428   format %{ "LDR   $tmp,[$poll]\t! Safepoint: poll for GC" %}
9429   ins_encode %{
9430     __ relocate(relocInfo::poll_type);
9431     __ ldr($tmp$$Register, Address($poll$$Register));
9432   %}
9433   ins_pipe(loadPollP);
9434 %}
9435 
9436 
9437 // ============================================================================
9438 // Call Instructions
9439 // Call Java Static Instruction
9440 instruct CallStaticJavaDirect( method meth ) %{
9441   match(CallStaticJava);
9442   predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke());
9443   effect(USE meth);
9444   size(call_static_enc_size(this, _method, _method_handle_invoke));
9445 
9446   ins_cost(CALL_COST);
9447   format %{ "CALL,static ==> " %}
9448   ins_encode( Java_Static_Call( meth ), call_epilog );
9449   ins_pipe(simple_call);
9450 %}
9451 
9452 // Call Java Static Instruction (method handle version)
9453 instruct CallStaticJavaHandle( method meth ) %{
9454   match(CallStaticJava);
9455   predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke());
9456   effect(USE meth);
9457   size(call_static_enc_size(this, _method, _method_handle_invoke));
9458 
9459   // FP is saved by all callees (for interpreter stack correction).
9460   // We use it here for a similar purpose, in {preserve,restore}_FP.
9461 
9462   ins_cost(CALL_COST);
9463   format %{ "CALL,static/MethodHandle ==> " %}
9464   ins_encode( preserve_SP, Java_Static_Call( meth ), restore_SP, call_epilog );
9465   ins_pipe(simple_call);
9466 %}
9467 
9468 // Call Java Dynamic Instruction
9469 instruct CallDynamicJavaDirect( method meth ) %{
9470   match(CallDynamicJava);
9471   effect(USE meth);
9472   size(call_dynamic_enc_size());
9473 
9474   ins_cost(CALL_COST);
9475   format %{ "MOV_OOP    (empty),R_R8\n\t"
9476             "CALL,dynamic  ; NOP ==> " %}
9477   ins_encode( Java_Dynamic_Call( meth ), call_epilog );
9478   ins_pipe(call);
9479 %}
9480 
9481 // Call Runtime Instruction
9482 instruct CallRuntimeDirect(method meth) %{
9483   match(CallRuntime);
9484   effect(USE meth);
9485   ins_cost(CALL_COST);
9486   size(call_runtime_enc_size(this));
9487 
9488   format %{ "CALL,runtime" %}
9489   ins_encode( Java_To_Runtime( meth ),
9490               call_epilog );
9491   ins_pipe(simple_call);
9492 %}
9493 
9494 // Call runtime without safepoint - same as CallRuntime
9495 instruct CallLeafDirect(method meth) %{
9496   match(CallLeaf);
9497   effect(USE meth);
9498   ins_cost(CALL_COST);
9499   size(call_runtime_enc_size(this));
9500 
9501   format %{ "CALL,runtime leaf" %}
9502   // TODO: ned save_last_PC here?
9503   ins_encode( Java_To_Runtime( meth ),
9504               call_epilog );
9505   ins_pipe(simple_call);
9506 %}
9507 
9508 // Call runtime without safepoint - same as CallLeaf
9509 instruct CallLeafNoFPDirect(method meth) %{
9510   match(CallLeafNoFP);
9511   effect(USE meth);
9512   ins_cost(CALL_COST);
9513   size(call_runtime_enc_size(this));
9514 
9515   format %{ "CALL,runtime leaf nofp" %}
9516   // TODO: ned save_last_PC here?
9517   ins_encode( Java_To_Runtime( meth ),
9518               call_epilog );
9519   ins_pipe(simple_call);
9520 %}
9521 
9522 // Tail Call; Jump from runtime stub to Java code.
9523 // Also known as an 'interprocedural jump'.
9524 // Target of jump will eventually return to caller.
9525 // TailJump below removes the return address.
9526 instruct TailCalljmpInd(iRegP jump_target, inline_cache_regP method_oop) %{
9527   match(TailCall jump_target method_oop );
9528 
9529   ins_cost(CALL_COST);
9530   format %{ "MOV    Rexception_pc, LR\n\t"
9531             "jump   $jump_target  \t! $method_oop holds method oop" %}
9532   ins_encode %{
9533     __ mov(r3, lr);   // this is used only to call
9534                                  // StubRoutines::forward_exception_entry()
9535                                  // which expects PC of exception in
9536                                  // R3. FIXME?
9537     __ b($jump_target$$Register);
9538   %}
9539   ins_pipe(tail_call);
9540 %}
9541 
9542 
9543 // Return Instruction
9544 instruct Ret() %{
9545   match(Return);
9546 
9547   format %{ "ret LR" %}
9548 
9549   ins_encode %{
9550     __ ret(lr);
9551   %}
9552 
9553   ins_pipe(br);
9554 %}
9555 
9556 
9557 // Tail Jump; remove the return address; jump to target.
9558 // TailCall above leaves the return address around.
9559 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
9560 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
9561 // "restore" before this instruction (in Epilogue), we need to materialize it
9562 // in %i0.
9563 instruct tailjmpInd(IPRegP jump_target, RExceptionRegP ex_oop) %{
9564   match( TailJump jump_target ex_oop );
9565   ins_cost(CALL_COST);
9566   format %{ "MOV    Rexception_pc, LR\n\t"
9567             "jump   $jump_target \t! $ex_oop holds exc. oop" %}
9568   ins_encode %{
9569     __ mov(r3, lr);
9570     __ b($jump_target$$Register);
9571   %}
9572   ins_pipe(tail_call);
9573 %}
9574 
9575 // Create exception oop: created by stack-crawling runtime code.
9576 // Created exception is now available to this handler, and is setup
9577 // just prior to jumping to this handler.  No code emitted.
9578 instruct CreateException( RExceptionRegP ex_oop )
9579 %{
9580   match(Set ex_oop (CreateEx));
9581   ins_cost(0);
9582 
9583   size(0);
9584   // use the following format syntax
9585   format %{ "! exception oop is in Rexception_obj; no code emitted" %}
9586   ins_encode();
9587   ins_pipe(empty);
9588 %}
9589 
9590 
9591 // Rethrow exception:
9592 // The exception oop will come in the first argument position.
9593 // Then JUMP (not call) to the rethrow stub code.
9594 instruct RethrowException()
9595 %{
9596   match(Rethrow);
9597   ins_cost(CALL_COST);
9598 
9599   // use the following format syntax
9600   format %{ "b    rethrow_stub" %}
9601   ins_encode %{
9602     Register scratch = r1;
9603     assert_different_registers(scratch, c_rarg0, lr);
9604     __ jump(OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type, scratch);
9605   %}
9606   ins_pipe(tail_call);
9607 %}
9608 
9609 
9610 // Die now
9611 instruct ShouldNotReachHere( )
9612 %{
9613   match(Halt);
9614   ins_cost(CALL_COST);
9615 
9616   size(4);
9617   // Use the following format syntax
9618   format %{ "ShouldNotReachHere" %}
9619   ins_encode %{
9620     __ udf(0xdead);
9621   %}
9622   ins_pipe(tail_call);
9623 %}
9624 
9625 // ============================================================================
9626 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
9627 // array for an instance of the superklass.  Set a hidden internal cache on a
9628 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
9629 // not zero for a miss or zero for a hit.  The encoding ALSO sets flags.
9630 instruct partialSubtypeCheck( R0RegP index, R1RegP sub, R2RegP super, flagsRegP pcc, LRRegP lr, R9RegI r9, R12RegI r12 ) %{
9631   match(Set index (PartialSubtypeCheck sub super));
9632   effect( KILL pcc, KILL r9, KILL r12, KILL lr );
9633   ins_cost(DEFAULT_COST*10);
9634   format %{ "CALL   PartialSubtypeCheck" %}
9635   ins_encode %{
9636     __ call(StubRoutines::aarch32::partial_subtype_check(), relocInfo::runtime_call_type);
9637   %}
9638   ins_pipe(partial_subtype_check_pipe);
9639 %}
9640 
9641 /* instruct partialSubtypeCheck_vs_zero( flagsRegP pcc, o1RegP sub, o2RegP super, immP0 zero, o0RegP idx, o7RegP o7 ) %{ */
9642 /*   match(Set pcc (CmpP (PartialSubtypeCheck sub super) zero)); */
9643 /*   ins_pipe(partial_subtype_check_pipe); */
9644 /* %} */
9645 
9646 
9647 // ============================================================================
9648 // inlined locking and unlocking
9649 
9650 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP mark, iRegP scratch2, iRegP scratch )
9651 %{
9652   match(Set pcc (FastLock object box));
9653 
9654   effect(TEMP mark, TEMP scratch, TEMP scratch2);
9655   ins_cost(100);
9656 
9657   format %{ "FASTLOCK  $object, $box; KILL $mark, $scratch, $scratch2" %}
9658   ins_encode %{
9659     __ fast_lock($object$$Register, $box$$Register, $mark$$Register, $scratch$$Register, $scratch2$$Register);
9660   %}
9661   ins_pipe(long_memory_op);
9662 %}
9663 
9664 
9665 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch ) %{
9666   match(Set pcc (FastUnlock object box));
9667   effect(TEMP scratch, TEMP scratch2);
9668   ins_cost(100);
9669 
9670   format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2" %}
9671   ins_encode %{
9672     __ fast_unlock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
9673   %}
9674   ins_pipe(long_memory_op);
9675 %}
9676 
9677 // Count and Base registers are fixed because the allocator cannot
9678 // kill unknown registers.  The encodings are generic.
9679 instruct clear_array(iRegX cnt, iRegP base, iRegI temp, iRegX zero, Universe dummy, flagsReg cpsr) %{
9680   match(Set dummy (ClearArray cnt base));
9681   effect(TEMP temp, TEMP zero, KILL cpsr);
9682   ins_cost(300);
9683   format %{ "MOV    $zero,0\n"
9684       "        MOV    $temp,$cnt\n"
9685       "loop:   SUBS   $temp,$temp,4\t! Count down a dword of bytes\n"
9686       "        STR.ge $zero,[$base+$temp]\t! delay slot"
9687       "        B.gt   loop\t\t! Clearing loop\n" %}
9688   ins_encode %{
9689     __ mov($zero$$Register, 0);
9690     __ mov($temp$$Register, $cnt$$Register);
9691     Label(loop);
9692     __ bind(loop);
9693     __ subs($temp$$Register, $temp$$Register, 4);
9694     __ str($zero$$Register, Address($base$$Register, $temp$$Register), Assembler::GE);
9695     __ b(loop, Assembler::GT);
9696   %}
9697   ins_pipe(long_memory_op);
9698 %}
9699 
9700 instruct string_compareUU(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result,
9701                           iRegI tmp1, iRegI tmp2, Q0_regD tmp3, Q1_regD tmp4, flagsReg ccr) %{
9702   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
9703   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
9704   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP result, KILL ccr);
9705 
9706   ins_cost(300);
9707   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
9708   ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result, tmp1, tmp2, tmp3, tmp4, (2), (2)) );
9709   ins_pipe(long_memory_op);
9710 %}
9711 
9712 instruct string_compareLL(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result,
9713                           iRegI tmp1, iRegI tmp2, Q0_regD tmp3, Q1_regD tmp4, flagsReg ccr) %{
9714   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
9715   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
9716   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP result, KILL ccr);
9717 
9718   ins_cost(300);
9719   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
9720   ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result, tmp1, tmp2, tmp3, tmp4, (1), (1)) );
9721   ins_pipe(long_memory_op);
9722 %}
9723 
9724 instruct string_compareUL(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result,
9725                           iRegI tmp1, iRegI tmp2, Q0_regD tmp3, Q1_regD tmp4, flagsReg ccr) %{
9726   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
9727   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
9728   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP result, KILL ccr);
9729 
9730   ins_cost(300);
9731   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
9732   ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result, tmp1, tmp2, tmp3, tmp4, (2), (1)) );
9733   ins_pipe(long_memory_op);
9734 %}
9735 
9736 instruct string_compareLU(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result,
9737                           iRegI tmp1, iRegI tmp2, Q0_regD tmp3, Q1_regD tmp4, flagsReg ccr) %{
9738   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
9739   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
9740   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP result, KILL ccr);
9741 
9742   ins_cost(300);
9743   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
9744   ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result, tmp1, tmp2, tmp3, tmp4, (1), (2)) );
9745   ins_pipe(long_memory_op);
9746 %}
9747 
9748 instruct string_equalsUU(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, flagsReg ccr) %{
9749   predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU);
9750   match(Set result (StrEquals (Binary str1 str2) cnt));
9751   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp1, TEMP result, KILL ccr);
9752 
9753   ins_cost(300);
9754   format %{ "String Equals $str1,$str2,$cnt -> $result   # KILL $tmp1" %}
9755   ins_encode( enc_Array_Equals(str1, str2, cnt, tmp1, result, (2), (false)) );
9756   ins_pipe(long_memory_op);
9757 %}
9758 
9759 instruct string_equalsLL(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, flagsReg ccr) %{
9760   predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
9761   match(Set result (StrEquals (Binary str1 str2) cnt));
9762   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp1, TEMP result, KILL ccr);
9763 
9764   ins_cost(300);
9765   format %{ "String Equals $str1,$str2,$cnt -> $result   # KILL $tmp1" %}
9766   ins_encode( enc_Array_Equals(str1, str2, cnt, tmp1, result, (1), (false)) );
9767   ins_pipe(long_memory_op);
9768 %}
9769 
9770 instruct array_equalsUU(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI result, flagsReg ccr) %{
9771   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
9772   match(Set result (AryEq ary1 ary2));
9773   effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP result, KILL ccr);
9774 
9775   ins_cost(300);
9776   format %{ "Array Equals $ary1,$ary2 -> $result   # KILL $tmp1,$tmp2" %}
9777   ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result, (2), (true)));
9778   ins_pipe(long_memory_op);
9779 %}
9780 
9781 instruct array_equalsLL(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI result, flagsReg ccr) %{
9782   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
9783   match(Set result (AryEq ary1 ary2));
9784   effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP result, KILL ccr);
9785 
9786   ins_cost(300);
9787   format %{ "Array Equals $ary1,$ary2 -> $result   # KILL $tmp1,$tmp2" %}
9788   ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result, (1), (true)));
9789   ins_pipe(long_memory_op);
9790 %}
9791 
9792 instruct string_compress(R2RegP src, R1RegP dst, R3RegI len,
9793                          R9RegI tmp1, Q0_regD tmp2, Q1_regD tmp3, R12RegI tmp4, LRRegP lr, R0RegI result, flagsReg ccr)
9794 %{
9795   match(Set result (StrCompressedCopy src (Binary dst len)));
9796   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP lr, USE_KILL src, USE_KILL dst, USE_KILL len, KILL ccr);
9797 
9798   format %{ "String Compress $src,$dst -> $result    // KILL $tmp1, $tmp2, $tmp3, $tmp4, $lr" %}
9799   ins_encode( enc_Char_Array_Compress(src, dst, len, tmp1, tmp2, tmp3, tmp4, result, ccr) );
9800   ins_pipe(long_memory_op);
9801 %}
9802 
9803 instruct string_inflate(Universe dummy, R0RegP src, R1RegP dst, R2RegI len,
9804                         iRegI tmp1, Q0_regD tmp2, LRRegP lr, flagsReg ccr)
9805 %{
9806   match(Set dummy (StrInflatedCopy src (Binary dst len)));
9807   effect(TEMP tmp1, TEMP tmp2, TEMP lr, USE_KILL src, USE_KILL dst, USE_KILL len, KILL ccr);
9808 
9809   format %{ "String Inflate $src,$dst    // KILL $tmp1, $tmp2, $lr" %}
9810   ins_encode( enc_Byte_Array_Inflate(src, dst, len, tmp1, tmp2, ccr) );
9811   ins_pipe(long_memory_op);
9812 %}
9813 
9814 //---------- Zeros Count Instructions ------------------------------------------
9815 
9816 instruct countLeadingZerosI(iRegI dst, iRegI src) %{
9817   match(Set dst (CountLeadingZerosI src));
9818   size(4);
9819   format %{ "CLZ_32 $dst,$src" %}
9820   ins_encode %{
9821     __ clz($dst$$Register, $src$$Register);
9822   %}
9823   ins_pipe(ialu_reg);
9824 %}
9825 
9826 instruct countLeadingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
9827   match(Set dst (CountLeadingZerosL src));
9828   effect(TEMP tmp, TEMP dst, KILL ccr);
9829   size(16);
9830   format %{ "CLZ    $dst,$src.hi\n\t"
9831             "TEQ    $dst,32\n\t"
9832             "CLZ.eq $tmp,$src.lo\n\t"
9833             "ADD.eq $dst, $dst, $tmp\n\t" %}
9834   ins_encode %{
9835     __ clz($dst$$Register, $src$$Register->successor());
9836     __ teq($dst$$Register, 32);
9837     __ clz($tmp$$Register, $src$$Register, Assembler::EQ);
9838     __ add($dst$$Register, $dst$$Register, $tmp$$Register, Assembler::EQ);
9839   %}
9840   ins_pipe(ialu_reg);
9841 %}
9842 
9843 instruct countTrailingZerosI(iRegI dst, iRegI src, iRegI tmp) %{
9844   match(Set dst (CountTrailingZerosI src));
9845   effect(TEMP tmp);
9846   size(8);
9847   format %{ "RBIT_32 $tmp, $src\n\t"
9848             "CLZ_32  $dst,$tmp" %}
9849   ins_encode %{
9850     __ rbit($tmp$$Register, $src$$Register);
9851     __ clz($dst$$Register, $tmp$$Register);
9852   %}
9853   ins_pipe(ialu_reg);
9854 %}
9855 
9856 instruct countTrailingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
9857   match(Set dst (CountTrailingZerosL src));
9858   effect(TEMP tmp, TEMP dst, KILL ccr);
9859   size(24);
9860   format %{ "RBIT   $tmp,$src.lo\n\t"
9861             "CLZ    $dst,$tmp\n\t"
9862             "TEQ    $dst,32\n\t"
9863             "RBIT   $tmp,$src.hi\n\t"
9864             "CLZ.eq $tmp,$tmp\n\t"
9865             "ADD.eq $dst,$dst,$tmp\n\t" %}
9866   ins_encode %{
9867     __ rbit($tmp$$Register, $src$$Register);
9868     __ clz($dst$$Register, $tmp$$Register);
9869     __ teq($dst$$Register, 32);
9870     __ rbit($tmp$$Register, $src$$Register->successor());
9871     __ clz($tmp$$Register, $tmp$$Register, Assembler::EQ);
9872     __ add($dst$$Register, $dst$$Register, $tmp$$Register, Assembler::EQ);
9873   %}
9874   ins_pipe(ialu_reg);
9875 %}
9876 
9877 
9878 //---------- Population Count Instructions -------------------------------------
9879 
9880 instruct popCountI(iRegI dst, iRegI src, regD_low tmp) %{
9881   predicate(UsePopCountInstruction);
9882   match(Set dst (PopCountI src));
9883   effect(TEMP tmp);
9884 
9885   format %{ "FMSR       $tmp,$src\n\t"
9886             "VCNT.8     $tmp,$tmp\n\t"
9887             "VPADDL.U8  $tmp,$tmp\n\t"
9888             "VPADDL.U16 $tmp,$tmp\n\t"
9889             "FMRS       $dst,$tmp" %}
9890   size(20);
9891 
9892   ins_encode %{
9893     __ vmov_f32($tmp$$FloatRegister, $src$$Register);
9894     __ vcnt_64($tmp$$FloatRegister, $tmp$$FloatRegister);
9895     __ vpaddl_64_u8($tmp$$FloatRegister, $tmp$$FloatRegister);
9896     __ vpaddl_64_u16($tmp$$FloatRegister, $tmp$$FloatRegister);
9897     __ vmov_f32($dst$$Register, $tmp$$FloatRegister);
9898   %}
9899   ins_pipe(ialu_reg); // FIXME
9900 %}
9901 
9902 // Note: Long.bitCount(long) returns an int.
9903 instruct popCountL(iRegI dst, iRegL src, regD_low tmp) %{
9904   predicate(UsePopCountInstruction);
9905   match(Set dst (PopCountL src));
9906   effect(TEMP tmp);
9907 
9908   format %{ "FMDRR       $tmp,$src.lo,$src.hi\n\t"
9909             "VCNT.8      $tmp,$tmp\n\t"
9910             "VPADDL.U8   $tmp,$tmp\n\t"
9911             "VPADDL.U16  $tmp,$tmp\n\t"
9912             "VPADDL.U32  $tmp,$tmp\n\t"
9913             "FMRS        $dst,$tmp" %}
9914 
9915   size(32);
9916 
9917   ins_encode %{
9918     __ vmov_f64($tmp$$FloatRegister, $src$$Register, $src$$Register->successor());
9919     __ vcnt_64($tmp$$FloatRegister, $tmp$$FloatRegister);
9920     __ vpaddl_64_u8($tmp$$FloatRegister, $tmp$$FloatRegister);
9921     __ vpaddl_64_u16($tmp$$FloatRegister, $tmp$$FloatRegister);
9922     __ vpaddl_64_u32($tmp$$FloatRegister, $tmp$$FloatRegister);
9923     __ vmov_f32($dst$$Register, $tmp$$FloatRegister);
9924   %}
9925   ins_pipe(ialu_reg);
9926 %}
9927 
9928 
9929 // ============================================================================
9930 //------------Bytes reverse--------------------------------------------------
9931 
9932 instruct bytes_reverse_int(iRegI dst, iRegI src) %{
9933   match(Set dst (ReverseBytesI src));
9934 
9935   size(4);
9936   format %{ "REV32 $dst,$src" %}
9937   ins_encode %{
9938     __ rev($dst$$Register, $src$$Register);
9939   %}
9940   ins_pipe( iload_mem ); // FIXME
9941 %}
9942 
9943 instruct bytes_reverse_long(iRegL dst, iRegL src) %{
9944   match(Set dst (ReverseBytesL src));
9945   effect(TEMP dst);
9946   size(8);
9947   format %{ "REV $dst.lo,$src.lo\n\t"
9948             "REV $dst.hi,$src.hi" %}
9949   ins_encode %{
9950     __ rev($dst$$Register, $src$$Register->successor());
9951     __ rev($dst$$Register->successor(), $src$$Register);
9952   %}
9953   ins_pipe( iload_mem ); // FIXME
9954 %}
9955 
9956 instruct bytes_reverse_unsigned_short(iRegI dst, iRegI src) %{
9957   match(Set dst (ReverseBytesUS src));
9958   size(4);
9959   format %{ "REV16 $dst,$src" %}
9960   ins_encode %{
9961     __ rev16($dst$$Register, $src$$Register);
9962   %}
9963   ins_pipe( iload_mem ); // FIXME
9964 %}
9965 
9966 instruct bytes_reverse_short(iRegI dst, iRegI src) %{
9967   match(Set dst (ReverseBytesS src));
9968   size(4);
9969   format %{ "REVSH $dst,$src" %}
9970   ins_encode %{
9971     __ revsh($dst$$Register, $src$$Register);
9972   %}
9973   ins_pipe( iload_mem ); // FIXME
9974 %}
9975 
9976 
9977 // ====================VECTOR INSTRUCTIONS=====================================
9978 
9979 // Load Aligned Packed values into a Double Register
9980 instruct loadV8(vecD dst, memoryD mem) %{
9981   predicate(n->as_LoadVector()->memory_size() == 8);
9982   match(Set dst (LoadVector mem));
9983   ins_cost(MEMORY_REF_COST);
9984   size(4);
9985   format %{ "FLDD   $mem,$dst\t! load vector (8 bytes)" %}
9986   ins_encode %{
9987     __ vldr_f64($dst$$FloatRegister, $mem$$Address);
9988   %}
9989   ins_pipe(floadD_mem);
9990 %}
9991 
9992 // Load Aligned Packed values into a Double Register Pair
9993 instruct loadV16(vecX dst, memoryvld mem) %{
9994   predicate(n->as_LoadVector()->memory_size() == 16);
9995   match(Set dst (LoadVector mem));
9996   ins_cost(MEMORY_REF_COST);
9997   size(4);
9998   format %{ "VLD1   $mem,$dst.Q\t! load vector (16 bytes)" %}
9999   ins_encode %{
10000     __ vld1_16($dst$$FloatRegister, $dst$$FloatRegister->successor(FloatRegisterImpl::DOUBLE), $mem$$Address, Assembler::ALIGN_STD);
10001   %}
10002   ins_pipe(floadD_mem); // FIXME
10003 %}
10004 
10005 // Store Vector in Double register to memory
10006 instruct storeV8(memoryD mem, vecD src) %{
10007   predicate(n->as_StoreVector()->memory_size() == 8);
10008   match(Set mem (StoreVector mem src));
10009   ins_cost(MEMORY_REF_COST);
10010   size(4);
10011   format %{ "FSTD   $src,$mem\t! store vector (8 bytes)" %}
10012   ins_encode %{
10013     __ vstr_f64($src$$FloatRegister, $mem$$Address);
10014   %}
10015   ins_pipe(fstoreD_mem_reg);
10016 %}
10017 
10018 // Store Vector in Double Register Pair to memory
10019 instruct storeV16(memoryvld mem, vecX src) %{
10020   predicate(n->as_StoreVector()->memory_size() == 16);
10021   match(Set mem (StoreVector mem src));
10022   ins_cost(MEMORY_REF_COST);
10023   size(4);
10024   format %{ "VST1   $src,$mem\t! store vector (16 bytes)" %}
10025   ins_encode %{
10026     __ vst1_16($src$$FloatRegister, $src$$FloatRegister->successor(FloatRegisterImpl::DOUBLE), $mem$$Address, Assembler::ALIGN_STD);
10027   %}
10028   ins_pipe(fstoreD_mem_reg); // FIXME
10029 %}
10030 
10031 // Replicate scalar to packed byte values in Double register
10032 instruct Repl8B_reg(vecD dst, iRegI src, iRegI tmp) %{
10033   predicate(n->as_Vector()->length() == 8);
10034   match(Set dst (ReplicateB src));
10035   ins_cost(DEFAULT_COST*4);
10036   effect(TEMP tmp);
10037   size(16);
10038 
10039   // FIXME: could use PKH instruction instead?
10040   format %{ "LSL      $tmp, $src, 24 \n\t"
10041             "OR       $tmp, $tmp, ($tmp >> 8) \n\t"
10042             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
10043             "FMDRR    $dst,$tmp,$tmp\t" %}
10044   ins_encode %{
10045     __ mov($tmp$$Register, $src$$Register, lsl(24));
10046     __ orr($tmp$$Register, $tmp$$Register, $tmp$$Register, lsr(8));
10047     __ orr($tmp$$Register, $tmp$$Register, $tmp$$Register, lsr(16));
10048     __ vmov_f64($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
10049   %}
10050   ins_pipe(ialu_reg); // FIXME
10051 %}
10052 
10053 // Replicate scalar to packed byte values in Double register
10054 instruct Repl8B_reg_simd(vecD dst, iRegI src) %{
10055   predicate(n->as_Vector()->length_in_bytes() == 8 && (VM_Version::features() & FT_AdvSIMD));
10056   match(Set dst (ReplicateB src));
10057   size(4);
10058 
10059   format %{ "VDUP.8 $dst,$src\t" %}
10060   ins_encode %{
10061     __ vdup_64_8($dst$$FloatRegister, $src$$Register);
10062   %}
10063   ins_pipe(ialu_reg); // FIXME
10064 %}
10065 
10066 // Replicate scalar to packed byte values in Double register pair
10067 instruct Repl16B_reg(vecX dst, iRegI src) %{
10068   predicate(n->as_Vector()->length_in_bytes() == 16);
10069   match(Set dst (ReplicateB src));
10070   size(4);
10071 
10072   format %{ "VDUP.8 $dst.Q,$src\t" %}
10073   ins_encode %{
10074     __ vdup_128_8($dst$$FloatRegister, $src$$Register);
10075   %}
10076   ins_pipe(ialu_reg); // FIXME
10077 %}
10078 
10079 // Replicate scalar constant to packed byte values in Double register
10080 instruct Repl8B_immI(vecD dst, immI src, iRegI tmp) %{
10081   predicate(n->as_Vector()->length() == 8);
10082   match(Set dst (ReplicateB src));
10083   ins_cost(DEFAULT_COST*2);
10084   effect(TEMP tmp);
10085   size(12);
10086 
10087   format %{ "MOV      $tmp, Repl4($src))\n\t"
10088             "FMDRR    $dst,$tmp,$tmp\t" %}
10089   ins_encode( LdReplImmI(src, dst, tmp, (4), (1)) );
10090   ins_pipe(loadConFD); // FIXME
10091 %}
10092 
10093 // Replicate scalar constant to packed byte values in Double register
10094 // TODO: support negative constants with MVNI?
10095 instruct Repl8B_immU8(vecD dst, immU8 src) %{
10096   predicate(n->as_Vector()->length_in_bytes() == 8 && (VM_Version::features() & FT_AdvSIMD));
10097   match(Set dst (ReplicateB src));
10098   size(4);
10099 
10100   format %{ "VMOV.U8  $dst,$src" %}
10101   ins_encode %{
10102     __ vmov_64_8($dst$$FloatRegister, $src$$constant);
10103   %}
10104   ins_pipe(loadConFD); // FIXME
10105 %}
10106 
10107 // Replicate scalar constant to packed byte values in Double register pair
10108 instruct Repl16B_immU8(vecX dst, immU8 src) %{
10109   predicate(n->as_Vector()->length_in_bytes() == 16 && (VM_Version::features() & FT_AdvSIMD));
10110   match(Set dst (ReplicateB src));
10111   size(4);
10112 
10113   format %{ "VMOV.U8  $dst.Q,$src" %}
10114   ins_encode %{
10115     __ vmov_128_8($dst$$FloatRegister, $src$$constant);
10116   %}
10117   ins_pipe(loadConFD); // FIXME
10118 %}
10119 
10120 // Replicate scalar to packed short/char values into Double register
10121 instruct Repl4S_reg(vecD dst, iRegI src, iRegI tmp) %{
10122   predicate(n->as_Vector()->length() == 4);
10123   match(Set dst (ReplicateS src));
10124   ins_cost(DEFAULT_COST*3);
10125   effect(TEMP tmp);
10126   size(12);
10127 
10128   // FIXME: could use PKH instruction instead?
10129   format %{ "LSL      $tmp, $src, 16 \n\t"
10130             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
10131             "FMDRR    $dst,$tmp,$tmp\t" %}
10132   ins_encode %{
10133     __ mov($tmp$$Register, $src$$Register, lsl(16));
10134     __ orr($tmp$$Register, $tmp$$Register, $tmp$$Register, lsr(16));
10135     __ vmov_f64($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
10136   %}
10137   ins_pipe(ialu_reg); // FIXME
10138 %}
10139 
10140 // Replicate scalar to packed byte values in Double register
10141 instruct Repl4S_reg_simd(vecD dst, iRegI src) %{
10142   predicate(n->as_Vector()->length_in_bytes() == 8 && (VM_Version::features() & FT_AdvSIMD));
10143   match(Set dst (ReplicateS src));
10144   size(4);
10145 
10146   format %{ "VDUP.16 $dst,$src\t" %}
10147   ins_encode %{
10148     __ vdup_64_16($dst$$FloatRegister, $src$$Register);
10149   %}
10150   ins_pipe(ialu_reg); // FIXME
10151 %}
10152 
10153 // Replicate scalar to packed byte values in Double register pair
10154 instruct Repl8S_reg(vecX dst, iRegI src) %{
10155   predicate(n->as_Vector()->length_in_bytes() == 16 && (VM_Version::features() & FT_AdvSIMD));
10156   match(Set dst (ReplicateS src));
10157   size(4);
10158 
10159   format %{ "VDUP.16 $dst.Q,$src\t" %}
10160   ins_encode %{
10161     __ vdup_128_16($dst$$FloatRegister, $src$$Register);
10162   %}
10163   ins_pipe(ialu_reg); // FIXME
10164 %}
10165 
10166 
10167 // Replicate scalar constant to packed short/char values in Double register
10168 instruct Repl4S_immI(vecD dst, immI src, iRegP tmp) %{
10169   predicate(n->as_Vector()->length() == 4);
10170   match(Set dst (ReplicateS src));
10171   effect(TEMP tmp);
10172   size(12);
10173   ins_cost(DEFAULT_COST*4); // FIXME
10174 
10175   format %{ "MOV      $tmp, Repl2($src))\n\t"
10176             "FMDRR    $dst,$tmp,$tmp\t" %}
10177   ins_encode( LdReplImmI(src, dst, tmp, (2), (2)) );
10178   ins_pipe(loadConFD); // FIXME
10179 %}
10180 
10181 // Replicate scalar constant to packed byte values in Double register
10182 instruct Repl4S_immU8(vecD dst, immU8 src) %{
10183   predicate(n->as_Vector()->length_in_bytes() == 8 && (VM_Version::features() & FT_AdvSIMD));
10184   match(Set dst (ReplicateS src));
10185   size(4);
10186 
10187   format %{ "VMOV.U16  $dst,$src" %}
10188   ins_encode %{
10189     __ vmov_64_16($dst$$FloatRegister, $src$$constant);
10190   %}
10191   ins_pipe(loadConFD); // FIXME
10192 %}
10193 
10194 // Replicate scalar constant to packed byte values in Double register pair
10195 instruct Repl8S_immU8(vecX dst, immU8 src) %{
10196   predicate(n->as_Vector()->length_in_bytes() == 16 && (VM_Version::features() & FT_AdvSIMD));
10197   match(Set dst (ReplicateS src));
10198   size(4);
10199 
10200   format %{ "VMOV.U16  $dst.Q,$src" %}
10201   ins_encode %{
10202     __ vmov_128_16($dst$$FloatRegister, $src$$constant);
10203   %}
10204   ins_pipe(loadConFD); // FIXME
10205 %}
10206 
10207 // Replicate scalar to packed int values in Double register
10208 instruct Repl2I_reg(vecD dst, iRegI src) %{
10209   predicate(n->as_Vector()->length() == 2);
10210   match(Set dst (ReplicateI src));
10211   size(4);
10212 
10213   format %{ "FMDRR    $dst,$src,$src\t" %}
10214   ins_encode %{
10215     __ vmov_f64($dst$$FloatRegister, $src$$Register, $src$$Register);
10216   %}
10217   ins_pipe(ialu_reg); // FIXME
10218 %}
10219 
10220 // Replicate scalar to packed int values in Double register pair
10221 instruct Repl4I_reg(vecX dst, iRegI src) %{
10222   predicate(n->as_Vector()->length() == 4);
10223   match(Set dst (ReplicateI src));
10224   ins_cost(DEFAULT_COST*2);
10225   size(8);
10226 
10227   format %{ "FMDRR    $dst.lo,$src,$src\n\t"
10228             "FMDRR    $dst.hi,$src,$src" %}
10229 
10230   ins_encode %{
10231     __ vmov_f64($dst$$FloatRegister, $src$$Register, $src$$Register);
10232     __ vmov_f64($dst$$FloatRegister->successor(FloatRegisterImpl::DOUBLE),
10233              $src$$Register, $src$$Register);
10234   %}
10235   ins_pipe(ialu_reg); // FIXME
10236 %}
10237 
10238 // Replicate scalar to packed int values in Double register
10239 instruct Repl2I_reg_simd(vecD dst, iRegI src) %{
10240   predicate(n->as_Vector()->length_in_bytes() == 8 && (VM_Version::features() & FT_AdvSIMD));
10241   match(Set dst (ReplicateI src));
10242   size(4);
10243 
10244   format %{ "VDUP.32 $dst.D,$src\t" %}
10245   ins_encode %{
10246     __ vdup_64_32($dst$$FloatRegister, $src$$Register);
10247   %}
10248   ins_pipe(ialu_reg); // FIXME
10249 %}
10250 
10251 // Replicate scalar to packed int values in Double register pair
10252 instruct Repl4I_reg_simd(vecX dst, iRegI src) %{
10253   predicate(n->as_Vector()->length_in_bytes() == 16 && (VM_Version::features() & FT_AdvSIMD));
10254   match(Set dst (ReplicateI src));
10255   size(4);
10256 
10257   format %{ "VDUP.32 $dst.Q,$src\t" %}
10258   ins_encode %{
10259     __ vdup_128_32($dst$$FloatRegister, $src$$Register);
10260   %}
10261   ins_pipe(ialu_reg); // FIXME
10262 %}
10263 
10264 
10265 // Replicate scalar zero constant to packed int values in Double register
10266 instruct Repl2I_immI(vecD dst, immI src, iRegI tmp) %{
10267   predicate(n->as_Vector()->length() == 2);
10268   match(Set dst (ReplicateI src));
10269   effect(TEMP tmp);
10270   size(12);
10271   ins_cost(DEFAULT_COST*4); // FIXME
10272 
10273   format %{ "MOV      $tmp, Repl1($src))\n\t"
10274             "FMDRR    $dst,$tmp,$tmp\t" %}
10275   ins_encode( LdReplImmI(src, dst, tmp, (1), (4)) );
10276   ins_pipe(loadConFD); // FIXME
10277 %}
10278 
10279 // Replicate scalar constant to packed byte values in Double register
10280 instruct Repl2I_immU8(vecD dst, immU8 src) %{
10281   predicate(n->as_Vector()->length_in_bytes() == 8 && (VM_Version::features() & FT_AdvSIMD));
10282   match(Set dst (ReplicateI src));
10283   size(4);
10284 
10285   format %{ "VMOV.I32  $dst.D,$src" %}
10286   ins_encode %{
10287     __ vmov_64_32($dst$$FloatRegister, $src$$constant);
10288   %}
10289   ins_pipe(loadConFD); // FIXME
10290 %}
10291 
10292 // Replicate scalar constant to packed byte values in Double register pair
10293 instruct Repl4I_immU8(vecX dst, immU8 src) %{
10294   predicate(n->as_Vector()->length_in_bytes() == 16 && (VM_Version::features() & FT_AdvSIMD));
10295   match(Set dst (ReplicateI src));
10296   size(4);
10297 
10298   format %{ "VMOV.I32  $dst.Q,$src" %}
10299   ins_encode %{
10300     __ vmov_128_32($dst$$FloatRegister, $src$$constant);
10301   %}
10302   ins_pipe(loadConFD); // FIXME
10303 %}
10304 
10305 // Replicate scalar to packed byte values in Double register pair
10306 instruct Repl2L_reg(vecX dst, iRegL src) %{
10307   predicate(n->as_Vector()->length() == 2);
10308   match(Set dst (ReplicateL src));
10309   size(8);
10310   ins_cost(DEFAULT_COST*2); // FIXME
10311 
10312   format %{ "FMDRR $dst.D,$src.lo,$src.hi\t\n"
10313             "FMDRR $dst.D.next,$src.lo,$src.hi" %}
10314   ins_encode %{
10315     __ vmov_f64($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
10316     __ vmov_f64($dst$$FloatRegister->successor(FloatRegisterImpl::DOUBLE),
10317              $src$$Register, $src$$Register->successor());
10318   %}
10319   ins_pipe(ialu_reg); // FIXME
10320 %}
10321 
10322 
10323 // Replicate scalar to packed float values in Double register
10324 instruct Repl2F_regI(vecD dst, iRegI src) %{
10325   predicate(n->as_Vector()->length() == 2);
10326   match(Set dst (ReplicateF src));
10327   size(4);
10328 
10329   format %{ "FMDRR    $dst.D,$src,$src\t" %}
10330   ins_encode %{
10331     __ vmov_f64($dst$$FloatRegister, $src$$Register, $src$$Register);
10332   %}
10333   ins_pipe(ialu_reg); // FIXME
10334 %}
10335 
10336 // Replicate scalar to packed float values in Double register
10337 instruct Repl2F_reg_vfp(vecD dst, regF src) %{
10338   predicate(n->as_Vector()->length() == 2);
10339   match(Set dst (ReplicateF src));
10340   size(4*2);
10341   ins_cost(DEFAULT_COST*2); // FIXME
10342 
10343   expand %{
10344     iRegI tmp;
10345     MoveF2I_reg_reg(tmp, src);
10346     Repl2F_regI(dst,tmp);
10347   %}
10348 %}
10349 
10350 // Replicate scalar to packed float values in Double register
10351 instruct Repl2F_reg_simd(vecD dst, regF src) %{
10352   predicate(n->as_Vector()->length_in_bytes() == 8 && (VM_Version::features() & FT_AdvSIMD));
10353   match(Set dst (ReplicateF src));
10354   size(4);
10355   ins_cost(DEFAULT_COST); // FIXME
10356 
10357   format %{ "VDUP.32  $dst.D,$src.D\t" %}
10358   ins_encode %{
10359     __ vdups_64($dst$$FloatRegister, $src$$FloatRegister);
10360   %}
10361   ins_pipe(ialu_reg); // FIXME
10362 %}
10363 
10364 // Replicate scalar to packed float values in Double register pair
10365 instruct Repl4F_reg(vecX dst, regF src, iRegI tmp) %{
10366   predicate(n->as_Vector()->length() == 4);
10367   match(Set dst (ReplicateF src));
10368   effect(TEMP tmp);
10369   size(4*3);
10370   ins_cost(DEFAULT_COST*3); // FIXME
10371 
10372   format %{ "FMRS     $tmp,$src\n\t"
10373             "FMDRR    $dst.D,$tmp,$tmp\n\t"
10374             "FMDRR    $dst.D.next,$tmp,$tmp\t" %}
10375   ins_encode %{
10376     __ vmov_f32($tmp$$Register, $src$$FloatRegister);
10377     __ vmov_f64($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
10378     __ vmov_f64($dst$$FloatRegister->successor(FloatRegisterImpl::DOUBLE),
10379              $tmp$$Register, $tmp$$Register);
10380   %}
10381   ins_pipe(ialu_reg); // FIXME
10382 %}
10383 
10384 // Replicate scalar to packed float values in Double register pair
10385 instruct Repl4F_reg_simd(vecX dst, regF src) %{
10386   predicate(n->as_Vector()->length_in_bytes() == 16 && (VM_Version::features() & FT_AdvSIMD));
10387   match(Set dst (ReplicateF src));
10388   size(4);
10389   ins_cost(DEFAULT_COST); // FIXME
10390 
10391   format %{ "VDUP.32  $dst.Q,$src.D\t" %}
10392   ins_encode %{
10393     __ vdups_128($dst$$FloatRegister, $src$$FloatRegister);
10394   %}
10395   ins_pipe(ialu_reg); // FIXME
10396 %}
10397 
10398 // Replicate scalar zero constant to packed float values in Double register
10399 instruct Repl2F_immI(vecD dst, immF src, iRegI tmp) %{
10400   predicate(n->as_Vector()->length() == 2);
10401   match(Set dst (ReplicateF src));
10402   effect(TEMP tmp);
10403   size(12);
10404   ins_cost(DEFAULT_COST*4); // FIXME
10405 
10406   format %{ "MOV      $tmp, Repl1($src))\n\t"
10407             "FMDRR    $dst,$tmp,$tmp\t" %}
10408   ins_encode( LdReplImmF(src, dst, tmp) );
10409   ins_pipe(loadConFD); // FIXME
10410 %}
10411 
10412 // Replicate scalar to packed double float values in Double register pair
10413 instruct Repl2D_reg(vecX dst, regD src) %{
10414   predicate(n->as_Vector()->length() == 2);
10415   match(Set dst (ReplicateD src));
10416   size(4*2);
10417   ins_cost(DEFAULT_COST*2); // FIXME
10418 
10419   format %{ "FCPYD    $dst.D.a,$src\n\t"
10420             "FCPYD    $dst.D.b,$src\t" %}
10421   ins_encode %{
10422     FloatRegister dsta = $dst$$FloatRegister;
10423     FloatRegister src = $src$$FloatRegister;
10424     __ vmov_f64(dsta, src);
10425     FloatRegister dstb = dsta->successor(FloatRegisterImpl::DOUBLE);
10426     __ vmov_f64(dstb, src);
10427   %}
10428   ins_pipe(ialu_reg); // FIXME
10429 %}
10430 
10431 // ====================VECTOR ARITHMETIC=======================================
10432 
10433 // --------------------------------- ADD --------------------------------------
10434 
10435 // Bytes vector add
10436 instruct vadd8B_reg(vecD dst, vecD src1, vecD src2) %{
10437   predicate(n->as_Vector()->length() == 8);
10438   match(Set dst (AddVB src1 src2));
10439   format %{ "VADD.I8 $dst,$src1,$src2\t! add packed8B" %}
10440   size(4);
10441   ins_encode %{
10442     __ vadd_64_8($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10443   %}
10444   ins_pipe( ialu_reg_reg ); // FIXME
10445 %}
10446 
10447 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
10448   predicate(n->as_Vector()->length() == 16);
10449   match(Set dst (AddVB src1 src2));
10450   size(4);
10451   format %{ "VADD.I8 $dst.Q,$src1.Q,$src2.Q\t! add packed16B" %}
10452   ins_encode %{
10453     __ vadd_128_8($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10454   %}
10455   ins_pipe( ialu_reg_reg ); // FIXME
10456 %}
10457 
10458 // Shorts/Chars vector add
10459 instruct vadd4S_reg(vecD dst, vecD src1, vecD src2) %{
10460   predicate(n->as_Vector()->length() == 4);
10461   match(Set dst (AddVS src1 src2));
10462   size(4);
10463   format %{ "VADD.I16 $dst,$src1,$src2\t! add packed4S" %}
10464   ins_encode %{
10465     __ vadd_64_16($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10466   %}
10467   ins_pipe( ialu_reg_reg ); // FIXME
10468 %}
10469 
10470 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
10471   predicate(n->as_Vector()->length() == 8);
10472   match(Set dst (AddVS src1 src2));
10473   size(4);
10474   format %{ "VADD.I16 $dst.Q,$src1.Q,$src2.Q\t! add packed8S" %}
10475   ins_encode %{
10476     __ vadd_128_16($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10477   %}
10478   ins_pipe( ialu_reg_reg ); // FIXME
10479 %}
10480 
10481 // Integers vector add
10482 instruct vadd2I_reg(vecD dst, vecD src1, vecD src2) %{
10483   predicate(n->as_Vector()->length() == 2);
10484   match(Set dst (AddVI src1 src2));
10485   size(4);
10486   format %{ "VADD.I32 $dst.D,$src1.D,$src2.D\t! add packed2I" %}
10487   ins_encode %{
10488     __ vadd_64_32($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10489   %}
10490   ins_pipe( ialu_reg_reg ); // FIXME
10491 %}
10492 
10493 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
10494   predicate(n->as_Vector()->length() == 4);
10495   match(Set dst (AddVI src1 src2));
10496   size(4);
10497   format %{ "VADD.I32 $dst.Q,$src1.Q,$src2.Q\t! add packed4I" %}
10498   ins_encode %{
10499     __ vadd_128_32($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10500   %}
10501   ins_pipe( ialu_reg_reg ); // FIXME
10502 %}
10503 
10504 // Longs vector add
10505 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
10506   predicate(n->as_Vector()->length() == 2);
10507   match(Set dst (AddVL src1 src2));
10508   size(4);
10509   format %{ "VADD.I64 $dst.Q,$src1.Q,$src2.Q\t! add packed2L" %}
10510   ins_encode %{
10511     bool quad = true;
10512     __ vadd_128_64($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10513   %}
10514   ins_pipe( ialu_reg_reg ); // FIXME
10515 %}
10516 
10517 // Floats vector add
10518 instruct vadd2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10519   predicate(n->as_Vector()->length() == 2);
10520   match(Set dst (AddVF src1 src2));
10521   ins_cost(DEFAULT_COST*2); // FIXME
10522 
10523   size(4*2);
10524   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
10525             "FADDS  $dst.b,$src1.b,$src2.b" %}
10526   ins_encode %{
10527     __ vadd_f32($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10528     __ vadd_f32($dst$$FloatRegister->successor(FloatRegisterImpl::SINGLE),
10529              $src1$$FloatRegister->successor(FloatRegisterImpl::SINGLE),
10530              $src2$$FloatRegister->successor(FloatRegisterImpl::SINGLE));
10531   %}
10532 
10533   ins_pipe(faddF_reg_reg); // FIXME
10534 %}
10535 
10536 instruct vadd4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10537   predicate(n->as_Vector()->length() == 4);
10538   match(Set dst (AddVF src1 src2));
10539   size(4*4);
10540   ins_cost(DEFAULT_COST*4); // FIXME
10541 
10542   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
10543             "FADDS  $dst.b,$src1.b,$src2.b\n\t"
10544             "FADDS  $dst.c,$src1.c,$src2.c\n\t"
10545             "FADDS  $dst.d,$src1.d,$src2.d" %}
10546 
10547   ins_encode %{
10548     FloatRegister dsta = $dst$$FloatRegister;
10549     FloatRegister src1a = $src1$$FloatRegister;
10550     FloatRegister src2a = $src2$$FloatRegister;
10551     __ vadd_f32(dsta, src1a, src2a);
10552     FloatRegister dstb = dsta->successor(FloatRegisterImpl::SINGLE);
10553     FloatRegister src1b = src1a->successor(FloatRegisterImpl::SINGLE);
10554     FloatRegister src2b = src2a->successor(FloatRegisterImpl::SINGLE);
10555     __ vadd_f32(dstb, src1b, src2b);
10556     FloatRegister dstc = dstb->successor(FloatRegisterImpl::SINGLE);
10557     FloatRegister src1c = src1b->successor(FloatRegisterImpl::SINGLE);
10558     FloatRegister src2c = src2b->successor(FloatRegisterImpl::SINGLE);
10559     __ vadd_f32(dstc, src1c, src2c);
10560     FloatRegister dstd = dstc->successor(FloatRegisterImpl::SINGLE);
10561     FloatRegister src1d = src1c->successor(FloatRegisterImpl::SINGLE);
10562     FloatRegister src2d = src2c->successor(FloatRegisterImpl::SINGLE);
10563     __ vadd_f32(dstd, src1d, src2d);
10564   %}
10565 
10566   ins_pipe(faddF_reg_reg); // FIXME
10567 %}
10568 
10569 instruct vadd2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10570   predicate(n->as_Vector()->length() == 2);
10571   match(Set dst (AddVD src1 src2));
10572   size(4*2);
10573   ins_cost(DEFAULT_COST*2); // FIXME
10574 
10575   format %{ "FADDD  $dst.a,$src1.a,$src2.a\n\t"
10576             "FADDD  $dst.b,$src1.b,$src2.b" %}
10577 
10578   ins_encode %{
10579     FloatRegister dsta = $dst$$FloatRegister;
10580     FloatRegister src1a = $src1$$FloatRegister;
10581     FloatRegister src2a = $src2$$FloatRegister;
10582     __ vadd_f64(dsta, src1a, src2a);
10583     FloatRegister dstb = dsta->successor(FloatRegisterImpl::DOUBLE);
10584     FloatRegister src1b = src1a->successor(FloatRegisterImpl::DOUBLE);
10585     FloatRegister src2b = src2a->successor(FloatRegisterImpl::DOUBLE);
10586     __ vadd_f64(dstb, src1b, src2b);
10587   %}
10588 
10589   ins_pipe(faddF_reg_reg); // FIXME
10590 %}
10591 
10592 
10593 // Bytes vector sub
10594 instruct vsub8B_reg(vecD dst, vecD src1, vecD src2) %{
10595   predicate(n->as_Vector()->length() == 8);
10596   match(Set dst (SubVB src1 src2));
10597   size(4);
10598   format %{ "VSUB.I8 $dst,$src1,$src2\t! sub packed8B" %}
10599   ins_encode %{
10600     __ vsub_64_8($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10601   %}
10602   ins_pipe( ialu_reg_reg ); // FIXME
10603 %}
10604 
10605 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
10606   predicate(n->as_Vector()->length() == 16);
10607   match(Set dst (SubVB src1 src2));
10608   size(4);
10609   format %{ "VSUB.I8 $dst.Q,$src1.Q,$src2.Q\t! sub packed16B" %}
10610   ins_encode %{
10611     __ vsub_128_8($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10612   %}
10613   ins_pipe( ialu_reg_reg ); // FIXME
10614 %}
10615 
10616 // Shorts/Chars vector sub
10617 instruct vsub4S_reg(vecD dst, vecD src1, vecD src2) %{
10618   predicate(n->as_Vector()->length() == 4);
10619   match(Set dst (SubVS src1 src2));
10620   size(4);
10621   format %{ "VSUB.I16 $dst,$src1,$src2\t! sub packed4S" %}
10622   ins_encode %{
10623     __ vsub_64_16($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10624   %}
10625   ins_pipe( ialu_reg_reg ); // FIXME
10626 %}
10627 
10628 instruct vsub16S_reg(vecX dst, vecX src1, vecX src2) %{
10629   predicate(n->as_Vector()->length() == 8);
10630   match(Set dst (SubVS src1 src2));
10631   size(4);
10632   format %{ "VSUB.I16 $dst.Q,$src1.Q,$src2.Q\t! sub packed8S" %}
10633   ins_encode %{
10634     __ vsub_128_16($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10635   %}
10636   ins_pipe( ialu_reg_reg ); // FIXME
10637 %}
10638 
10639 // Integers vector sub
10640 instruct vsub2I_reg(vecD dst, vecD src1, vecD src2) %{
10641   predicate(n->as_Vector()->length() == 2);
10642   match(Set dst (SubVI src1 src2));
10643   size(4);
10644   format %{ "VSUB.I32 $dst,$src1,$src2\t! sub packed2I" %}
10645   ins_encode %{
10646     __ vsub_64_32($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10647   %}
10648   ins_pipe( ialu_reg_reg ); // FIXME
10649 %}
10650 
10651 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
10652   predicate(n->as_Vector()->length() == 4);
10653   match(Set dst (SubVI src1 src2));
10654   size(4);
10655   format %{ "VSUB.I32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4I" %}
10656   ins_encode %{
10657     bool quad = true;
10658     __ vsub_128_32($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10659   %}
10660   ins_pipe( ialu_reg_reg ); // FIXME
10661 %}
10662 
10663 // Longs vector sub
10664 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
10665   predicate(n->as_Vector()->length() == 2);
10666   match(Set dst (SubVL src1 src2));
10667   size(4);
10668   format %{ "VSUB.I64 $dst.Q,$src1.Q,$src2.Q\t! sub packed2L" %}
10669   ins_encode %{
10670     __ vsub_128_64($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10671   %}
10672   ins_pipe( ialu_reg_reg ); // FIXME
10673 %}
10674 
10675 // Floats vector sub
10676 instruct vsub2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10677   predicate(n->as_Vector()->length() == 2);
10678   match(Set dst (SubVF src1 src2));
10679   size(4*2);
10680   ins_cost(DEFAULT_COST*2); // FIXME
10681 
10682   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10683             "FSUBS  $dst.b,$src1.b,$src2.b" %}
10684 
10685   ins_encode %{
10686     FloatRegister dsta = $dst$$FloatRegister;
10687     FloatRegister src1a = $src1$$FloatRegister;
10688     FloatRegister src2a = $src2$$FloatRegister;
10689     __ vsub_f32(dsta, src1a, src2a);
10690     FloatRegister dstb = dsta->successor(FloatRegisterImpl::SINGLE);
10691     FloatRegister src1b = src1a->successor(FloatRegisterImpl::SINGLE);
10692     FloatRegister src2b = src2a->successor(FloatRegisterImpl::SINGLE);
10693     __ vsub_f32(dstb, src1b, src2b);
10694   %}
10695 
10696   ins_pipe(faddF_reg_reg); // FIXME
10697 %}
10698 
10699 
10700 instruct vsub4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10701   predicate(n->as_Vector()->length() == 4);
10702   match(Set dst (SubVF src1 src2));
10703   size(4*4);
10704   ins_cost(DEFAULT_COST*4); // FIXME
10705 
10706   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10707             "FSUBS  $dst.b,$src1.b,$src2.b\n\t"
10708             "FSUBS  $dst.c,$src1.c,$src2.c\n\t"
10709             "FSUBS  $dst.d,$src1.d,$src2.d" %}
10710 
10711   ins_encode %{
10712     FloatRegister dsta = $dst$$FloatRegister;
10713     FloatRegister src1a = $src1$$FloatRegister;
10714     FloatRegister src2a = $src2$$FloatRegister;
10715     __ vsub_f32(dsta, src1a, src2a);
10716     FloatRegister dstb = dsta->successor(FloatRegisterImpl::SINGLE);
10717     FloatRegister src1b = src1a->successor(FloatRegisterImpl::SINGLE);
10718     FloatRegister src2b = src2a->successor(FloatRegisterImpl::SINGLE);
10719     __ vsub_f32(dstb, src1b, src2b);
10720     FloatRegister dstc = dstb->successor(FloatRegisterImpl::SINGLE);
10721     FloatRegister src1c = src1b->successor(FloatRegisterImpl::SINGLE);
10722     FloatRegister src2c = src2b->successor(FloatRegisterImpl::SINGLE);
10723     __ vsub_f32(dstc, src1c, src2c);
10724     FloatRegister dstd = dstc->successor(FloatRegisterImpl::SINGLE);
10725     FloatRegister src1d = src1c->successor(FloatRegisterImpl::SINGLE);
10726     FloatRegister src2d = src2c->successor(FloatRegisterImpl::SINGLE);
10727     __ vsub_f32(dstd, src1d, src2d);
10728   %}
10729 
10730   ins_pipe(faddF_reg_reg); // FIXME
10731 %}
10732 
10733 instruct vsub2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10734   predicate(n->as_Vector()->length() == 2);
10735   match(Set dst (SubVD src1 src2));
10736   size(4*2);
10737   ins_cost(DEFAULT_COST*2); // FIXME
10738 
10739   format %{ "FSUBD  $dst.a,$src1.a,$src2.a\n\t"
10740             "FSUBD  $dst.b,$src1.b,$src2.b" %}
10741 
10742   ins_encode %{
10743     FloatRegister dsta = $dst$$FloatRegister;
10744     FloatRegister src1a = $src1$$FloatRegister;
10745     FloatRegister src2a = $src2$$FloatRegister;
10746     __ vsub_f64(dsta, src1a, src2a);
10747     FloatRegister dstb = dsta->successor(FloatRegisterImpl::DOUBLE);
10748     FloatRegister src1b = src1a->successor(FloatRegisterImpl::DOUBLE);
10749     FloatRegister src2b = src2a->successor(FloatRegisterImpl::DOUBLE);
10750     __ vsub_f64(dstb, src1b, src2b);
10751   %}
10752 
10753   ins_pipe(faddF_reg_reg); // FIXME
10754 %}
10755 
10756 // Shorts/Chars vector mul
10757 instruct vmul4S_reg(vecD dst, vecD src1, vecD src2) %{
10758   predicate(n->as_Vector()->length() == 4);
10759   match(Set dst (MulVS src1 src2));
10760   size(4);
10761   format %{ "VMUL.I16 $dst,$src1,$src2\t! mul packed4S" %}
10762   ins_encode %{
10763     __ vmul_64_16($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10764   %}
10765   ins_pipe( ialu_reg_reg ); // FIXME
10766 %}
10767 
10768 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2) %{
10769   predicate(n->as_Vector()->length() == 8);
10770   match(Set dst (MulVS src1 src2));
10771   size(4);
10772   format %{ "VMUL.I16 $dst.Q,$src1.Q,$src2.Q\t! mul packed8S" %}
10773   ins_encode %{
10774     __ vmul_128_16($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10775   %}
10776   ins_pipe( ialu_reg_reg ); // FIXME
10777 %}
10778 
10779 // Integers vector mul
10780 instruct vmul2I_reg(vecD dst, vecD src1, vecD src2) %{
10781   predicate(n->as_Vector()->length() == 2);
10782   match(Set dst (MulVI src1 src2));
10783   size(4);
10784   format %{ "VMUL.I32 $dst,$src1,$src2\t! mul packed2I" %}
10785   ins_encode %{
10786     __ vmul_64_32($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10787   %}
10788   ins_pipe( ialu_reg_reg ); // FIXME
10789 %}
10790 
10791 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
10792   predicate(n->as_Vector()->length() == 4);
10793   match(Set dst (MulVI src1 src2));
10794   size(4);
10795   format %{ "VMUL.I32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4I" %}
10796   ins_encode %{
10797     __ vmul_128_32($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10798   %}
10799   ins_pipe( ialu_reg_reg ); // FIXME
10800 %}
10801 
10802 // Floats vector mul
10803 instruct vmul2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10804   predicate(n->as_Vector()->length() == 2);
10805   match(Set dst (MulVF src1 src2));
10806   size(4*2);
10807   ins_cost(DEFAULT_COST*2); // FIXME
10808 
10809   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10810             "FMULS  $dst.b,$src1.b,$src2.b" %}
10811   ins_encode %{
10812     __ vmul_f32($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10813     __ vmul_f32($dst$$FloatRegister->successor(FloatRegisterImpl::SINGLE),
10814              $src1$$FloatRegister->successor(FloatRegisterImpl::SINGLE),
10815              $src2$$FloatRegister->successor(FloatRegisterImpl::SINGLE));
10816   %}
10817 
10818   ins_pipe(fmulF_reg_reg); // FIXME
10819 %}
10820 
10821 instruct vmul4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10822   predicate(n->as_Vector()->length() == 4);
10823   match(Set dst (MulVF src1 src2));
10824   size(4*4);
10825   ins_cost(DEFAULT_COST*4); // FIXME
10826 
10827   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10828             "FMULS  $dst.b,$src1.b,$src2.b\n\t"
10829             "FMULS  $dst.c,$src1.c,$src2.c\n\t"
10830             "FMULS  $dst.d,$src1.d,$src2.d" %}
10831 
10832   ins_encode %{
10833     FloatRegister dsta = $dst$$FloatRegister;
10834     FloatRegister src1a = $src1$$FloatRegister;
10835     FloatRegister src2a = $src2$$FloatRegister;
10836     __ vmul_f32(dsta, src1a, src2a);
10837     FloatRegister dstb = dsta->successor(FloatRegisterImpl::SINGLE);
10838     FloatRegister src1b = src1a->successor(FloatRegisterImpl::SINGLE);
10839     FloatRegister src2b = src2a->successor(FloatRegisterImpl::SINGLE);
10840     __ vmul_f32(dstb, src1b, src2b);
10841     FloatRegister dstc = dstb->successor(FloatRegisterImpl::SINGLE);
10842     FloatRegister src1c = src1b->successor(FloatRegisterImpl::SINGLE);
10843     FloatRegister src2c = src2b->successor(FloatRegisterImpl::SINGLE);
10844     __ vmul_f32(dstc, src1c, src2c);
10845     FloatRegister dstd = dstc->successor(FloatRegisterImpl::SINGLE);
10846     FloatRegister src1d = src1c->successor(FloatRegisterImpl::SINGLE);
10847     FloatRegister src2d = src2c->successor(FloatRegisterImpl::SINGLE);
10848     __ vmul_f32(dstd, src1d, src2d);
10849   %}
10850 
10851   ins_pipe(fmulF_reg_reg); // FIXME
10852 %}
10853 
10854 instruct vmul2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10855   predicate(n->as_Vector()->length() == 2);
10856   match(Set dst (MulVD src1 src2));
10857   size(4*2);
10858   ins_cost(DEFAULT_COST*2); // FIXME
10859 
10860   format %{ "FMULD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10861             "FMULD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10862   ins_encode %{
10863     FloatRegister dsta = $dst$$FloatRegister;
10864     FloatRegister src1a = $src1$$FloatRegister;
10865     FloatRegister src2a = $src2$$FloatRegister;
10866     __ vmul_f64(dsta, src1a, src2a);
10867     FloatRegister dstb = dsta->successor(FloatRegisterImpl::DOUBLE);
10868     FloatRegister src1b = src1a->successor(FloatRegisterImpl::DOUBLE);
10869     FloatRegister src2b = src2a->successor(FloatRegisterImpl::DOUBLE);
10870     __ vmul_f64(dstb, src1b, src2b);
10871   %}
10872 
10873   ins_pipe(fmulD_reg_reg); // FIXME
10874 %}
10875 
10876 
10877 // Floats vector div
10878 instruct vdiv2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10879   predicate(n->as_Vector()->length() == 2);
10880   match(Set dst (DivVF src1 src2));
10881   size(4*2);
10882   ins_cost(DEFAULT_COST*2); // FIXME
10883 
10884   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10885             "FDIVS  $dst.b,$src1.b,$src2.b" %}
10886   ins_encode %{
10887     __ vdiv_f32($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10888     __ vdiv_f32($dst$$FloatRegister->successor(FloatRegisterImpl::SINGLE),
10889              $src1$$FloatRegister->successor(FloatRegisterImpl::SINGLE),
10890              $src2$$FloatRegister->successor(FloatRegisterImpl::SINGLE));
10891   %}
10892 
10893   ins_pipe(fdivF_reg_reg); // FIXME
10894 %}
10895 
10896 instruct vdiv4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10897   predicate(n->as_Vector()->length() == 4);
10898   match(Set dst (DivVF src1 src2));
10899   size(4*4);
10900   ins_cost(DEFAULT_COST*4); // FIXME
10901 
10902   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10903             "FDIVS  $dst.b,$src1.b,$src2.b\n\t"
10904             "FDIVS  $dst.c,$src1.c,$src2.c\n\t"
10905             "FDIVS  $dst.d,$src1.d,$src2.d" %}
10906 
10907   ins_encode %{
10908     FloatRegister dsta = $dst$$FloatRegister;
10909     FloatRegister src1a = $src1$$FloatRegister;
10910     FloatRegister src2a = $src2$$FloatRegister;
10911     __ vdiv_f32(dsta, src1a, src2a);
10912     FloatRegister dstb = dsta->successor(FloatRegisterImpl::SINGLE);
10913     FloatRegister src1b = src1a->successor(FloatRegisterImpl::SINGLE);
10914     FloatRegister src2b = src2a->successor(FloatRegisterImpl::SINGLE);
10915     __ vdiv_f32(dstb, src1b, src2b);
10916     FloatRegister dstc = dstb->successor(FloatRegisterImpl::SINGLE);
10917     FloatRegister src1c = src1b->successor(FloatRegisterImpl::SINGLE);
10918     FloatRegister src2c = src2b->successor(FloatRegisterImpl::SINGLE);
10919     __ vdiv_f32(dstc, src1c, src2c);
10920     FloatRegister dstd = dstc->successor(FloatRegisterImpl::SINGLE);
10921     FloatRegister src1d = src1c->successor(FloatRegisterImpl::SINGLE);
10922     FloatRegister src2d = src2c->successor(FloatRegisterImpl::SINGLE);
10923     __ vdiv_f32(dstd, src1d, src2d);
10924   %}
10925 
10926   ins_pipe(fdivF_reg_reg); // FIXME
10927 %}
10928 
10929 instruct vdiv2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10930   predicate(n->as_Vector()->length() == 2);
10931   match(Set dst (DivVD src1 src2));
10932   size(4*2);
10933   ins_cost(DEFAULT_COST*2); // FIXME
10934 
10935   format %{ "FDIVD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10936             "FDIVD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10937   ins_encode %{
10938     FloatRegister dsta = $dst$$FloatRegister;
10939     FloatRegister src1a = $src1$$FloatRegister;
10940     FloatRegister src2a = $src2$$FloatRegister;
10941     __ vdiv_f64(dsta, src1a, src2a);
10942     FloatRegister dstb = dsta->successor(FloatRegisterImpl::DOUBLE);
10943     FloatRegister src1b = src1a->successor(FloatRegisterImpl::DOUBLE);
10944     FloatRegister src2b = src2a->successor(FloatRegisterImpl::DOUBLE);
10945     __ vdiv_f64(dstb, src1b, src2b);
10946   %}
10947 
10948   ins_pipe(fdivD_reg_reg); // FIXME
10949 %}
10950 
10951 // --------------------------------- NEG --------------------------------------
10952 
10953 instruct vneg8B_reg(vecD dst, vecD src) %{
10954   predicate(n->as_Vector()->length_in_bytes() == 8);
10955   effect(DEF dst, USE src);
10956   size(4);
10957   ins_cost(DEFAULT_COST); // FIXME
10958   format %{ "VNEG.S8 $dst.D,$src.D\t! neg packed8B" %}
10959   ins_encode %{
10960     __ vneg_64_s8($dst$$FloatRegister, $src$$FloatRegister);
10961   %}
10962   ins_pipe( ialu_reg_reg ); // FIXME
10963 %}
10964 
10965 instruct vneg16B_reg(vecX dst, vecX src) %{
10966   predicate(n->as_Vector()->length_in_bytes() == 16);
10967   effect(DEF dst, USE src);
10968   size(4);
10969   ins_cost(DEFAULT_COST); // FIXME
10970   format %{ "VNEG.S8 $dst.Q,$src.Q\t! neg0 packed16B" %}
10971   ins_encode %{
10972     __ vneg_128_s8($dst$$FloatRegister, $src$$FloatRegister);
10973   %}
10974   ins_pipe( ialu_reg_reg ); // FIXME
10975 %}
10976 
10977 // ------------------------------ Shift ---------------------------------------
10978 
10979 instruct vslcntD(vecD dst, iRegI cnt) %{
10980   predicate(n->as_Vector()->length_in_bytes() == 8 && (VM_Version::features() & FT_AdvSIMD));
10981   match(Set dst (LShiftCntV cnt));
10982   size(4);
10983   ins_cost(DEFAULT_COST); // FIXME
10984   expand %{
10985     Repl8B_reg_simd(dst, cnt);
10986   %}
10987 %}
10988 
10989 instruct vslcntX(vecX dst, iRegI cnt) %{
10990   predicate(n->as_Vector()->length_in_bytes() == 16 && (VM_Version::features() & FT_AdvSIMD));
10991   match(Set dst (LShiftCntV cnt));
10992   size(4);
10993   ins_cost(DEFAULT_COST); // FIXME
10994   expand %{
10995     Repl16B_reg(dst, cnt);
10996   %}
10997 %}
10998 
10999 // Low bits of vector "shift" elements are used, so it
11000 // doesn't matter if we treat it as ints or bytes here.
11001 instruct vsrcntD(vecD dst, iRegI cnt) %{
11002   predicate(n->as_Vector()->length_in_bytes() == 8 && (VM_Version::features() & FT_AdvSIMD));
11003   match(Set dst (RShiftCntV cnt));
11004   size(4*2);
11005   ins_cost(DEFAULT_COST*2); // FIXME
11006 
11007   format %{ "VDUP.8 $dst.D,$cnt\n\t"
11008             "VNEG.S8 $dst.D,$dst.D\t! neg packed8B" %}
11009   ins_encode %{
11010     __ vdup_64_8($dst$$FloatRegister, $cnt$$Register);
11011     __ vneg_64_s8($dst$$FloatRegister, $dst$$FloatRegister);
11012   %}
11013   ins_pipe( ialu_reg_reg ); // FIXME
11014 %}
11015 
11016 instruct vsrcntX(vecX dst, iRegI cnt) %{
11017   predicate(n->as_Vector()->length_in_bytes() == 16 && (VM_Version::features() & FT_AdvSIMD));
11018   match(Set dst (RShiftCntV cnt));
11019   size(4*2);
11020   ins_cost(DEFAULT_COST*2); // FIXME
11021   format %{ "VDUP.8 $dst.Q,$cnt\n\t"
11022             "VNEG.S8 $dst.Q,$dst.Q\t! neg packed16B" %}
11023   ins_encode %{
11024     __ vdup_128_8($dst$$FloatRegister, $cnt$$Register);
11025     __ vneg_128_s8($dst$$FloatRegister, $dst$$FloatRegister);
11026   %}
11027   ins_pipe( ialu_reg_reg ); // FIXME
11028 %}
11029 
11030 // Byte vector logical left/right shift based on sign
11031 instruct vsh8B_reg(vecD dst, vecD src, vecD shift) %{
11032   predicate(n->as_Vector()->length() == 8);
11033   effect(DEF dst, USE src, USE shift);
11034   size(4);
11035   ins_cost(DEFAULT_COST); // FIXME
11036   format %{
11037     "VSHL.U8 $dst.D,$src.D,$shift.D\t! logical left/right shift packed8B"
11038   %}
11039   ins_encode %{
11040     __ vshl_64_u8($dst$$FloatRegister, $src$$FloatRegister, $shift$$FloatRegister);
11041   %}
11042   ins_pipe( ialu_reg_reg ); // FIXME
11043 %}
11044 
11045 instruct vsh16B_reg(vecX dst, vecX src, vecX shift) %{
11046   predicate(n->as_Vector()->length() == 16);
11047   effect(DEF dst, USE src, USE shift);
11048   size(4);
11049   ins_cost(DEFAULT_COST); // FIXME
11050   format %{
11051     "VSHL.U8 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed16B"
11052   %}
11053   ins_encode %{
11054     bool quad = true;
11055     __ vshl_128_u8($dst$$FloatRegister, $src$$FloatRegister, $shift$$FloatRegister);
11056   %}
11057   ins_pipe( ialu_reg_reg ); // FIXME
11058 %}
11059 
11060 // Shorts/Char vector logical left/right shift based on sign
11061 instruct vsh4S_reg(vecD dst, vecD src, vecD shift) %{
11062   predicate(n->as_Vector()->length() == 4);
11063   effect(DEF dst, USE src, USE shift);
11064   size(4);
11065   ins_cost(DEFAULT_COST); // FIXME
11066   format %{
11067     "VSHL.U16 $dst.D,$src.D,$shift.D\t! logical left/right shift packed4S"
11068   %}
11069   ins_encode %{
11070     __ vshl_64_u16($dst$$FloatRegister, $src$$FloatRegister, $shift$$FloatRegister);
11071   %}
11072   ins_pipe( ialu_reg_reg ); // FIXME
11073 %}
11074 
11075 instruct vsh8S_reg(vecX dst, vecX src, vecX shift) %{
11076   predicate(n->as_Vector()->length() == 8);
11077   effect(DEF dst, USE src, USE shift);
11078   size(4);
11079   ins_cost(DEFAULT_COST); // FIXME
11080   format %{
11081     "VSHL.U16 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed8S"
11082   %}
11083   ins_encode %{
11084     __ vshl_128_u16($dst$$FloatRegister, $src$$FloatRegister, $shift$$FloatRegister);
11085   %}
11086   ins_pipe( ialu_reg_reg ); // FIXME
11087 %}
11088 
11089 // Integers vector logical left/right shift based on sign
11090 instruct vsh2I_reg(vecD dst, vecD src, vecD shift) %{
11091   predicate(n->as_Vector()->length() == 2);
11092   effect(DEF dst, USE src, USE shift);
11093   size(4);
11094   ins_cost(DEFAULT_COST); // FIXME
11095   format %{
11096     "VSHL.U32 $dst.D,$src.D,$shift.D\t! logical left/right shift packed2I"
11097   %}
11098   ins_encode %{
11099     __ vshl_64_u32($dst$$FloatRegister, $src$$FloatRegister, $shift$$FloatRegister);
11100   %}
11101   ins_pipe( ialu_reg_reg ); // FIXME
11102 %}
11103 
11104 instruct vsh4I_reg(vecX dst, vecX src, vecX shift) %{
11105   predicate(n->as_Vector()->length() == 4);
11106   effect(DEF dst, USE src, USE shift);
11107   size(4);
11108   ins_cost(DEFAULT_COST); // FIXME
11109   format %{
11110     "VSHL.U32 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed4I"
11111   %}
11112   ins_encode %{
11113     __ vshl_128_u32($dst$$FloatRegister, $src$$FloatRegister, $shift$$FloatRegister);
11114   %}
11115   ins_pipe( ialu_reg_reg ); // FIXME
11116 %}
11117 
11118 // Longs vector logical left/right shift based on sign
11119 instruct vsh2L_reg(vecX dst, vecX src, vecX shift) %{
11120   predicate(n->as_Vector()->length() == 2);
11121   effect(DEF dst, USE src, USE shift);
11122   size(4);
11123   ins_cost(DEFAULT_COST); // FIXME
11124   format %{
11125     "VSHL.U64 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed2L"
11126   %}
11127   ins_encode %{
11128     __ vshl_128_u64($dst$$FloatRegister, $src$$FloatRegister, $shift$$FloatRegister);
11129   %}
11130   ins_pipe( ialu_reg_reg ); // FIXME
11131 %}
11132 
11133 // ------------------------------ LeftShift -----------------------------------
11134 
11135 // Byte vector left shift
11136 instruct vsl8B_reg(vecD dst, vecD src, vecD shift) %{
11137   predicate(n->as_Vector()->length() == 8);
11138   match(Set dst (LShiftVB src shift));
11139   size(4*1);
11140   ins_cost(DEFAULT_COST*1); // FIXME
11141   expand %{
11142     vsh8B_reg(dst, src, shift);
11143   %}
11144 %}
11145 
11146 instruct vsl16B_reg(vecX dst, vecX src, vecX shift) %{
11147   predicate(n->as_Vector()->length() == 16);
11148   match(Set dst (LShiftVB src shift));
11149   size(4*1);
11150   ins_cost(DEFAULT_COST*1); // FIXME
11151   expand %{
11152     vsh16B_reg(dst, src, shift);
11153   %}
11154 %}
11155 
11156 instruct vsl8B_immI(vecD dst, vecD src, immI shift) %{
11157   predicate(n->as_Vector()->length() == 8);
11158   match(Set dst (LShiftVB src shift));
11159   size(4);
11160   ins_cost(DEFAULT_COST); // FIXME
11161   format %{
11162     "VSHL.I8 $dst.D,$src.D,$shift\t! logical left shift packed8B"
11163   %}
11164   ins_encode %{
11165     __ vshl_64_8($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11166   %}
11167   ins_pipe( ialu_reg_reg ); // FIXME
11168 %}
11169 
11170 instruct vsl16B_immI(vecX dst, vecX src, immI shift) %{
11171   predicate(n->as_Vector()->length() == 16);
11172   match(Set dst (LShiftVB src shift));
11173   size(4);
11174   ins_cost(DEFAULT_COST); // FIXME
11175   format %{
11176     "VSHL.I8 $dst.Q,$src.Q,$shift\t! logical left shift packed16B"
11177   %}
11178   ins_encode %{
11179     bool quad = true;
11180     __ vshl_128_8($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11181   %}
11182   ins_pipe( ialu_reg_reg ); // FIXME
11183 %}
11184 
11185 // Shorts/Chars vector logical left/right shift
11186 instruct vsl4S_reg(vecD dst, vecD src, vecD shift) %{
11187   predicate(n->as_Vector()->length() == 4);
11188   match(Set dst (LShiftVS src shift));
11189   match(Set dst (URShiftVS src shift));
11190   size(4*1);
11191   ins_cost(DEFAULT_COST*1); // FIXME
11192   expand %{
11193     vsh4S_reg(dst, src, shift);
11194   %}
11195 %}
11196 
11197 instruct vsl8S_reg(vecX dst, vecX src, vecX shift) %{
11198   predicate(n->as_Vector()->length() == 8);
11199   match(Set dst (LShiftVS src shift));
11200   match(Set dst (URShiftVS src shift));
11201   size(4*1);
11202   ins_cost(DEFAULT_COST*1); // FIXME
11203   expand %{
11204     vsh8S_reg(dst, src, shift);
11205   %}
11206 %}
11207 
11208 instruct vsl4S_immI(vecD dst, vecD src, immI shift) %{
11209   predicate(n->as_Vector()->length() == 4);
11210   match(Set dst (LShiftVS src shift));
11211   size(4);
11212   ins_cost(DEFAULT_COST); // FIXME
11213   format %{
11214     "VSHL.I16 $dst.D,$src.D,$shift\t! logical left shift packed4S"
11215   %}
11216   ins_encode %{
11217     bool quad = false;
11218     __ vshl_64_16($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11219   %}
11220   ins_pipe( ialu_reg_reg ); // FIXME
11221 %}
11222 
11223 instruct vsl8S_immI(vecX dst, vecX src, immI shift) %{
11224   predicate(n->as_Vector()->length() == 8);
11225   match(Set dst (LShiftVS src shift));
11226   size(4);
11227   ins_cost(DEFAULT_COST); // FIXME
11228   format %{
11229     "VSHL.I16 $dst.Q,$src.Q,$shift\t! logical left shift packed8S"
11230   %}
11231   ins_encode %{
11232     bool quad = true;
11233     __ vshl_128_16($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11234   %}
11235   ins_pipe( ialu_reg_reg ); // FIXME
11236 %}
11237 
11238 // Integers vector logical left/right shift
11239 instruct vsl2I_reg(vecD dst, vecD src, vecD shift) %{
11240   predicate(n->as_Vector()->length() == 2 && (VM_Version::features() & FT_AdvSIMD));
11241   match(Set dst (LShiftVI src shift));
11242   match(Set dst (URShiftVI src shift));
11243   size(4*1);
11244   ins_cost(DEFAULT_COST*1); // FIXME
11245   expand %{
11246     vsh2I_reg(dst, src, shift);
11247   %}
11248 %}
11249 
11250 instruct vsl4I_reg(vecX dst, vecX src, vecX shift) %{
11251   predicate(n->as_Vector()->length() == 4 && (VM_Version::features() & FT_AdvSIMD));
11252   match(Set dst (LShiftVI src shift));
11253   match(Set dst (URShiftVI src shift));
11254   size(4*1);
11255   ins_cost(DEFAULT_COST*1); // FIXME
11256   expand %{
11257     vsh4I_reg(dst, src, shift);
11258   %}
11259 %}
11260 
11261 instruct vsl2I_immI(vecD dst, vecD src, immI shift) %{
11262   predicate(n->as_Vector()->length() == 2 && (VM_Version::features() & FT_AdvSIMD));
11263   match(Set dst (LShiftVI src shift));
11264   size(4);
11265   ins_cost(DEFAULT_COST); // FIXME
11266   format %{
11267     "VSHL.I32 $dst.D,$src.D,$shift\t! logical left shift packed2I"
11268   %}
11269   ins_encode %{
11270     __ vshl_64_32($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11271   %}
11272   ins_pipe( ialu_reg_reg ); // FIXME
11273 %}
11274 
11275 instruct vsl4I_immI(vecX dst, vecX src, immI shift) %{
11276   predicate(n->as_Vector()->length() == 4 && (VM_Version::features() & FT_AdvSIMD));
11277   match(Set dst (LShiftVI src shift));
11278   size(4);
11279   ins_cost(DEFAULT_COST); // FIXME
11280   format %{
11281     "VSHL.I32 $dst.Q,$src.Q,$shift\t! logical left shift packed4I"
11282   %}
11283   ins_encode %{
11284     __ vshl_128_32($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11285   %}
11286   ins_pipe( ialu_reg_reg ); // FIXME
11287 %}
11288 
11289 // Longs vector logical left/right shift
11290 instruct vsl2L_reg(vecX dst, vecX src, vecX shift) %{
11291   predicate(n->as_Vector()->length() == 2);
11292   match(Set dst (LShiftVL src shift));
11293   match(Set dst (URShiftVL src shift));
11294   size(4*1);
11295   ins_cost(DEFAULT_COST*1); // FIXME
11296   expand %{
11297     vsh2L_reg(dst, src, shift);
11298   %}
11299 %}
11300 
11301 instruct vsl2L_immI(vecX dst, vecX src, immI shift) %{
11302   predicate(n->as_Vector()->length() == 2);
11303   match(Set dst (LShiftVL src shift));
11304   size(4);
11305   ins_cost(DEFAULT_COST); // FIXME
11306   format %{
11307     "VSHL.I64 $dst.Q,$src.Q,$shift\t! logical left shift packed2L"
11308   %}
11309   ins_encode %{
11310     __ vshl_128_64($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11311   %}
11312   ins_pipe( ialu_reg_reg ); // FIXME
11313 %}
11314 
11315 // ----------------------- LogicalRightShift -----------------------------------
11316 
11317 // Bytes/Shorts vector logical right shift produces incorrect Java result
11318 // for negative data because java code convert short value into int with
11319 // sign extension before a shift.
11320 
11321 // Chars vector logical right shift
11322 instruct vsrl4S_immI(vecD dst, vecD src, immI shift) %{
11323   predicate(n->as_Vector()->length() == 4);
11324   match(Set dst (URShiftVS src shift));
11325   size(4);
11326   ins_cost(DEFAULT_COST); // FIXME
11327   format %{
11328     "VSHR.U16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
11329   %}
11330   ins_encode %{
11331     __ vshr_64_u16($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11332   %}
11333   ins_pipe( ialu_reg_reg ); // FIXME
11334 %}
11335 
11336 instruct vsrl8S_immI(vecX dst, vecX src, immI shift) %{
11337   predicate(n->as_Vector()->length() == 8);
11338   match(Set dst (URShiftVS src shift));
11339   size(4);
11340   ins_cost(DEFAULT_COST); // FIXME
11341   format %{
11342     "VSHR.U16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
11343   %}
11344   ins_encode %{
11345     __ vshr_128_u16($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11346   %}
11347   ins_pipe( ialu_reg_reg ); // FIXME
11348 %}
11349 
11350 // Integers vector logical right shift
11351 instruct vsrl2I_immI(vecD dst, vecD src, immI shift) %{
11352   predicate(n->as_Vector()->length() == 2 && (VM_Version::features() & FT_AdvSIMD));
11353   match(Set dst (URShiftVI src shift));
11354   size(4);
11355   ins_cost(DEFAULT_COST); // FIXME
11356   format %{
11357     "VSHR.U32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
11358   %}
11359   ins_encode %{
11360     __ vshr_64_u32($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11361   %}
11362   ins_pipe( ialu_reg_reg ); // FIXME
11363 %}
11364 
11365 instruct vsrl4I_immI(vecX dst, vecX src, immI shift) %{
11366   predicate(n->as_Vector()->length() == 4 && (VM_Version::features() & FT_AdvSIMD));
11367   match(Set dst (URShiftVI src shift));
11368   size(4);
11369   ins_cost(DEFAULT_COST); // FIXME
11370   format %{
11371     "VSHR.U32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
11372   %}
11373   ins_encode %{
11374     __ vshr_128_u32($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11375   %}
11376   ins_pipe( ialu_reg_reg ); // FIXME
11377 %}
11378 
11379 // Longs vector logical right shift
11380 instruct vsrl2L_immI(vecX dst, vecX src, immI shift) %{
11381   predicate(n->as_Vector()->length() == 2);
11382   match(Set dst (URShiftVL src shift));
11383   size(4);
11384   ins_cost(DEFAULT_COST); // FIXME
11385   format %{
11386     "VSHR.U64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
11387   %}
11388   ins_encode %{
11389     __ vshr_128_u64($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11390   %}
11391   ins_pipe( ialu_reg_reg ); // FIXME
11392 %}
11393 
11394 // ------------------- ArithmeticRightShift -----------------------------------
11395 
11396 // Bytes vector arithmetic left/right shift based on sign
11397 instruct vsha8B_reg(vecD dst, vecD src, vecD shift) %{
11398   predicate(n->as_Vector()->length() == 8);
11399   effect(DEF dst, USE src, USE shift);
11400   size(4);
11401   ins_cost(DEFAULT_COST); // FIXME
11402   format %{
11403     "VSHL.S8 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed8B"
11404   %}
11405   ins_encode %{
11406     __ vshl_64_s8($dst$$FloatRegister, $src$$FloatRegister, $shift$$FloatRegister);
11407   %}
11408   ins_pipe( ialu_reg_reg ); // FIXME
11409 %}
11410 
11411 instruct vsha16B_reg(vecX dst, vecX src, vecX shift) %{
11412   predicate(n->as_Vector()->length() == 16);
11413   effect(DEF dst, USE src, USE shift);
11414   size(4);
11415   ins_cost(DEFAULT_COST); // FIXME
11416   format %{
11417     "VSHL.S8 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed16B"
11418   %}
11419   ins_encode %{
11420     __ vshl_128_s8($dst$$FloatRegister, $src$$FloatRegister, $shift$$FloatRegister);
11421   %}
11422   ins_pipe( ialu_reg_reg ); // FIXME
11423 %}
11424 
11425 // Shorts vector arithmetic left/right shift based on sign
11426 instruct vsha4S_reg(vecD dst, vecD src, vecD shift) %{
11427   predicate(n->as_Vector()->length() == 4);
11428   effect(DEF dst, USE src, USE shift);
11429   size(4);
11430   ins_cost(DEFAULT_COST); // FIXME
11431   format %{
11432     "VSHL.S16 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed4S"
11433   %}
11434   ins_encode %{
11435     __ vshl_64_s16($dst$$FloatRegister, $src$$FloatRegister, $shift$$FloatRegister);
11436   %}
11437   ins_pipe( ialu_reg_reg ); // FIXME
11438 %}
11439 
11440 instruct vsha8S_reg(vecX dst, vecX src, vecX shift) %{
11441   predicate(n->as_Vector()->length() == 8);
11442   effect(DEF dst, USE src, USE shift);
11443   size(4);
11444   ins_cost(DEFAULT_COST); // FIXME
11445   format %{
11446     "VSHL.S16 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed8S"
11447   %}
11448   ins_encode %{
11449     __ vshl_128_s16($dst$$FloatRegister, $src$$FloatRegister, $shift$$FloatRegister);
11450   %}
11451   ins_pipe( ialu_reg_reg ); // FIXME
11452 %}
11453 
11454 // Integers vector arithmetic left/right shift based on sign
11455 instruct vsha2I_reg(vecD dst, vecD src, vecD shift) %{
11456   predicate(n->as_Vector()->length() == 2);
11457   effect(DEF dst, USE src, USE shift);
11458   size(4);
11459   ins_cost(DEFAULT_COST); // FIXME
11460   format %{
11461     "VSHL.S32 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed2I"
11462   %}
11463   ins_encode %{
11464     __ vshl_64_s32($dst$$FloatRegister, $src$$FloatRegister, $shift$$FloatRegister);
11465   %}
11466   ins_pipe( ialu_reg_reg ); // FIXME
11467 %}
11468 
11469 instruct vsha4I_reg(vecX dst, vecX src, vecX shift) %{
11470   predicate(n->as_Vector()->length() == 4);
11471   effect(DEF dst, USE src, USE shift);
11472   size(4);
11473   ins_cost(DEFAULT_COST); // FIXME
11474   format %{
11475     "VSHL.S32 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed4I"
11476   %}
11477   ins_encode %{
11478     __ vshl_128_s32($dst$$FloatRegister, $src$$FloatRegister, $shift$$FloatRegister);
11479   %}
11480   ins_pipe( ialu_reg_reg ); // FIXME
11481 %}
11482 
11483 // Longs vector arithmetic left/right shift based on sign
11484 instruct vsha2L_reg(vecX dst, vecX src, vecX shift) %{
11485   predicate(n->as_Vector()->length() == 2);
11486   effect(DEF dst, USE src, USE shift);
11487   size(4);
11488   ins_cost(DEFAULT_COST); // FIXME
11489   format %{
11490     "VSHL.S64 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed2L"
11491   %}
11492   ins_encode %{
11493     __ vshl_128_s64($dst$$FloatRegister, $src$$FloatRegister, $shift$$FloatRegister);
11494   %}
11495   ins_pipe( ialu_reg_reg ); // FIXME
11496 %}
11497 
11498 // Byte vector arithmetic right shift
11499 
11500 instruct vsra8B_reg(vecD dst, vecD src, vecD shift) %{
11501   predicate(n->as_Vector()->length() == 8);
11502   match(Set dst (RShiftVB src shift));
11503   size(4);
11504   ins_cost(DEFAULT_COST); // FIXME
11505   expand %{
11506     vsha8B_reg(dst, src, shift);
11507   %}
11508 %}
11509 
11510 instruct vsrl16B_reg(vecX dst, vecX src, vecX shift) %{
11511   predicate(n->as_Vector()->length() == 16);
11512   match(Set dst (RShiftVB src shift));
11513   size(4);
11514   ins_cost(DEFAULT_COST); // FIXME
11515   expand %{
11516     vsha16B_reg(dst, src, shift);
11517   %}
11518 %}
11519 
11520 instruct vsrl8B_immI(vecD dst, vecD src, immI shift) %{
11521   predicate(n->as_Vector()->length() == 8);
11522   match(Set dst (RShiftVB src shift));
11523   size(4);
11524   ins_cost(DEFAULT_COST); // FIXME
11525   format %{
11526     "VSHR.S8 $dst.D,$src.D,$shift\t! logical right shift packed8B"
11527   %}
11528   ins_encode %{
11529     __ vshr_64_s8($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11530   %}
11531   ins_pipe( ialu_reg_reg ); // FIXME
11532 %}
11533 
11534 instruct vsrl16B_immI(vecX dst, vecX src, immI shift) %{
11535   predicate(n->as_Vector()->length() == 16);
11536   match(Set dst (RShiftVB src shift));
11537   size(4);
11538   ins_cost(DEFAULT_COST); // FIXME
11539   format %{
11540     "VSHR.S8 $dst.Q,$src.Q,$shift\t! logical right shift packed16B"
11541   %}
11542   ins_encode %{
11543     __ vshr_128_s8($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11544   %}
11545   ins_pipe( ialu_reg_reg ); // FIXME
11546 %}
11547 
11548 // Shorts vector arithmetic right shift
11549 instruct vsra4S_reg(vecD dst, vecD src, vecD shift) %{
11550   predicate(n->as_Vector()->length() == 4);
11551   match(Set dst (RShiftVS src shift));
11552   size(4);
11553   ins_cost(DEFAULT_COST); // FIXME
11554   expand %{
11555     vsha4S_reg(dst, src, shift);
11556   %}
11557 %}
11558 
11559 instruct vsra8S_reg(vecX dst, vecX src, vecX shift) %{
11560   predicate(n->as_Vector()->length() == 8);
11561   match(Set dst (RShiftVS src shift));
11562   size(4);
11563   ins_cost(DEFAULT_COST); // FIXME
11564   expand %{
11565     vsha8S_reg(dst, src, shift);
11566   %}
11567 %}
11568 
11569 instruct vsra4S_immI(vecD dst, vecD src, immI shift) %{
11570   predicate(n->as_Vector()->length() == 4);
11571   match(Set dst (RShiftVS src shift));
11572   size(4);
11573   ins_cost(DEFAULT_COST); // FIXME
11574   format %{
11575     "VSHR.S16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
11576   %}
11577   ins_encode %{
11578     __ vshr_64_s16($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11579   %}
11580   ins_pipe( ialu_reg_reg ); // FIXME
11581 %}
11582 
11583 instruct vsra8S_immI(vecX dst, vecX src, immI shift) %{
11584   predicate(n->as_Vector()->length() == 8);
11585   match(Set dst (RShiftVS src shift));
11586   size(4);
11587   ins_cost(DEFAULT_COST); // FIXME
11588   format %{
11589     "VSHR.S16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
11590   %}
11591   ins_encode %{
11592     __ vshr_128_s16($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11593   %}
11594   ins_pipe( ialu_reg_reg ); // FIXME
11595 %}
11596 
11597 // Integers vector arithmetic right shift
11598 instruct vsra2I_reg(vecD dst, vecD src, vecD shift) %{
11599   predicate(n->as_Vector()->length() == 2);
11600   match(Set dst (RShiftVI src shift));
11601   size(4);
11602   ins_cost(DEFAULT_COST); // FIXME
11603   expand %{
11604     vsha2I_reg(dst, src, shift);
11605   %}
11606 %}
11607 
11608 instruct vsra4I_reg(vecX dst, vecX src, vecX shift) %{
11609   predicate(n->as_Vector()->length() == 4);
11610   match(Set dst (RShiftVI src shift));
11611   size(4);
11612   ins_cost(DEFAULT_COST); // FIXME
11613   expand %{
11614     vsha4I_reg(dst, src, shift);
11615   %}
11616 %}
11617 
11618 instruct vsra2I_immI(vecD dst, vecD src, immI shift) %{
11619   predicate(n->as_Vector()->length() == 2);
11620   match(Set dst (RShiftVI src shift));
11621   size(4);
11622   ins_cost(DEFAULT_COST); // FIXME
11623   format %{
11624     "VSHR.S32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
11625   %}
11626   ins_encode %{
11627     __ vshr_64_s32($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11628   %}
11629   ins_pipe( ialu_reg_reg ); // FIXME
11630 %}
11631 
11632 instruct vsra4I_immI(vecX dst, vecX src, immI shift) %{
11633   predicate(n->as_Vector()->length() == 4);
11634   match(Set dst (RShiftVI src shift));
11635   size(4);
11636   ins_cost(DEFAULT_COST); // FIXME
11637   format %{
11638     "VSHR.S32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
11639   %}
11640   ins_encode %{
11641     __ vshr_128_s32($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11642   %}
11643   ins_pipe( ialu_reg_reg ); // FIXME
11644 %}
11645 
11646 // Longs vector arithmetic right shift
11647 instruct vsra2L_reg(vecX dst, vecX src, vecX shift) %{
11648   predicate(n->as_Vector()->length() == 2);
11649   match(Set dst (RShiftVL src shift));
11650   size(4);
11651   ins_cost(DEFAULT_COST); // FIXME
11652   expand %{
11653     vsha2L_reg(dst, src, shift);
11654   %}
11655 %}
11656 
11657 instruct vsra2L_immI(vecX dst, vecX src, immI shift) %{
11658   predicate(n->as_Vector()->length() == 2);
11659   match(Set dst (RShiftVL src shift));
11660   size(4);
11661   ins_cost(DEFAULT_COST); // FIXME
11662   format %{
11663     "VSHR.S64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
11664   %}
11665   ins_encode %{
11666     __ vshr_128_s64($dst$$FloatRegister, $src$$FloatRegister, $shift$$constant);
11667   %}
11668   ins_pipe( ialu_reg_reg ); // FIXME
11669 %}
11670 
11671 // --------------------------------- AND --------------------------------------
11672 
11673 instruct vandD(vecD dst, vecD src1, vecD src2) %{
11674   predicate(n->as_Vector()->length_in_bytes() == 8);
11675   match(Set dst (AndV src1 src2));
11676   format %{ "VAND    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11677   ins_encode %{
11678     __ vand_64($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
11679   %}
11680   ins_pipe( ialu_reg_reg ); // FIXME
11681 %}
11682 
11683 instruct vandX(vecX dst, vecX src1, vecX src2) %{
11684   predicate(n->as_Vector()->length_in_bytes() == 16);
11685   match(Set dst (AndV src1 src2));
11686   format %{ "VAND    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11687   ins_encode %{
11688     bool quad = true;
11689     __ vand_128($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
11690   %}
11691   ins_pipe( ialu_reg_reg ); // FIXME
11692 %}
11693 
11694 // --------------------------------- OR ---------------------------------------
11695 
11696 instruct vorD(vecD dst, vecD src1, vecD src2) %{
11697   predicate(n->as_Vector()->length_in_bytes() == 8);
11698   match(Set dst (OrV src1 src2));
11699   format %{ "VOR     $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11700   ins_encode %{
11701     __ vorr_64($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
11702   %}
11703   ins_pipe( ialu_reg_reg ); // FIXME
11704 %}
11705 
11706 instruct vorX(vecX dst, vecX src1, vecX src2) %{
11707   predicate(n->as_Vector()->length_in_bytes() == 16);
11708   match(Set dst (OrV src1 src2));
11709   format %{ "VOR     $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11710   ins_encode %{
11711     __ vorr_128($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
11712   %}
11713   ins_pipe( ialu_reg_reg ); // FIXME
11714 %}
11715 
11716 // --------------------------------- XOR --------------------------------------
11717 
11718 instruct vxorD(vecD dst, vecD src1, vecD src2) %{
11719   predicate(n->as_Vector()->length_in_bytes() == 8);
11720   match(Set dst (XorV src1 src2));
11721   format %{ "VXOR    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11722   ins_encode %{
11723     __ veor_64($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
11724   %}
11725   ins_pipe( ialu_reg_reg ); // FIXME
11726 %}
11727 
11728 instruct vxorX(vecX dst, vecX src1, vecX src2) %{
11729   predicate(n->as_Vector()->length_in_bytes() == 16);
11730   match(Set dst (XorV src1 src2));
11731   format %{ "VXOR    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11732   ins_encode %{
11733     __ veor_128($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
11734   %}
11735   ins_pipe( ialu_reg_reg ); // FIXME
11736 %}
11737 
11738 
11739 //----------PEEPHOLE RULES-----------------------------------------------------
11740 // These must follow all instruction definitions as they use the names
11741 // defined in the instructions definitions.
11742 //
11743 // peepmatch ( root_instr_name [preceding_instruction]* );
11744 //
11745 // peepconstraint %{
11746 // (instruction_number.operand_name relational_op instruction_number.operand_name
11747 //  [, ...] );
11748 // // instruction numbers are zero-based using left to right order in peepmatch
11749 //
11750 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
11751 // // provide an instruction_number.operand_name for each operand that appears
11752 // // in the replacement instruction's match rule
11753 //
11754 // ---------VM FLAGS---------------------------------------------------------
11755 //
11756 // All peephole optimizations can be turned off using -XX:-OptoPeephole
11757 //
11758 // Each peephole rule is given an identifying number starting with zero and
11759 // increasing by one in the order seen by the parser.  An individual peephole
11760 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
11761 // on the command-line.
11762 //
11763 // ---------CURRENT LIMITATIONS----------------------------------------------
11764 //
11765 // Only match adjacent instructions in same basic block
11766 // Only equality constraints
11767 // Only constraints between operands, not (0.dest_reg == EAX_enc)
11768 // Only one replacement instruction
11769 //
11770 // ---------EXAMPLE----------------------------------------------------------
11771 //
11772 // // pertinent parts of existing instructions in architecture description
11773 // instruct movI(eRegI dst, eRegI src) %{
11774 //   match(Set dst (CopyI src));
11775 // %}
11776 //
11777 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
11778 //   match(Set dst (AddI dst src));
11779 //   effect(KILL cr);
11780 // %}
11781 //
11782 // // Change (inc mov) to lea
11783 // peephole %{
11784 //   // increment preceeded by register-register move
11785 //   peepmatch ( incI_eReg movI );
11786 //   // require that the destination register of the increment
11787 //   // match the destination register of the move
11788 //   peepconstraint ( 0.dst == 1.dst );
11789 //   // construct a replacement instruction that sets
11790 //   // the destination to ( move's source register + one )
11791 //   peepreplace ( incI_eReg_immI1( 0.dst 1.src 0.src ) );
11792 // %}
11793 //
11794 
11795 // // Change load of spilled value to only a spill
11796 // instruct storeI(memory mem, eRegI src) %{
11797 //   match(Set mem (StoreI mem src));
11798 // %}
11799 //
11800 // instruct loadI(eRegI dst, memory mem) %{
11801 //   match(Set dst (LoadI mem));
11802 // %}
11803 //
11804 // peephole %{
11805 //   peepmatch ( loadI storeI );
11806 //   peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
11807 //   peepreplace ( storeI( 1.mem 1.mem 1.src ) );
11808 // %}
11809 
11810 //----------SMARTSPILL RULES---------------------------------------------------
11811 // These must follow all instruction definitions as they use the names
11812 // defined in the instructions definitions.
11813 //
11814 // ARM will probably not have any of these rules due to RISC instruction set.
11815 
11816 //----------PIPELINE-----------------------------------------------------------
11817 // Rules which define the behavior of the target architectures pipeline.