1 //
    2 // Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
    3 // Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
    4 // Copyright (c) 2020, 2024, Huawei Technologies Co., Ltd. All rights reserved.
    5 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    6 //
    7 // This code is free software; you can redistribute it and/or modify it
    8 // under the terms of the GNU General Public License version 2 only, as
    9 // published by the Free Software Foundation.
   10 //
   11 // This code is distributed in the hope that it will be useful, but WITHOUT
   12 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14 // version 2 for more details (a copy is included in the LICENSE file that
   15 // accompanied this code).
   16 //
   17 // You should have received a copy of the GNU General Public License version
   18 // 2 along with this work; if not, write to the Free Software Foundation,
   19 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20 //
   21 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22 // or visit www.oracle.com if you need additional information or have any
   23 // questions.
   24 //
   25 //
   26 
   27 // RISCV Architecture Description File
   28 
   29 //----------REGISTER DEFINITION BLOCK------------------------------------------
   30 // This information is used by the matcher and the register allocator to
   31 // describe individual registers and classes of registers within the target
   32 // architecture.
   33 
   34 register %{
   35 //----------Architecture Description Register Definitions----------------------
   36 // General Registers
   37 // "reg_def"  name ( register save type, C convention save type,
   38 //                   ideal register type, encoding );
   39 // Register Save Types:
   40 //
   41 // NS  = No-Save:       The register allocator assumes that these registers
   42 //                      can be used without saving upon entry to the method, &
   43 //                      that they do not need to be saved at call sites.
   44 //
   45 // SOC = Save-On-Call:  The register allocator assumes that these registers
   46 //                      can be used without saving upon entry to the method,
   47 //                      but that they must be saved at call sites.
   48 //
   49 // SOE = Save-On-Entry: The register allocator assumes that these registers
   50 //                      must be saved before using them upon entry to the
   51 //                      method, but they do not need to be saved at call
   52 //                      sites.
   53 //
   54 // AS  = Always-Save:   The register allocator assumes that these registers
   55 //                      must be saved before using them upon entry to the
   56 //                      method, & that they must be saved at call sites.
   57 //
   58 // Ideal Register Type is used to determine how to save & restore a
   59 // register.  Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
   60 // spilled with LoadP/StoreP.  If the register supports both, use Op_RegI.
   61 //
   62 // The encoding number is the actual bit-pattern placed into the opcodes.
   63 
   64 // We must define the 64 bit int registers in two 32 bit halves, the
   65 // real lower register and a virtual upper half register. upper halves
   66 // are used by the register allocator but are not actually supplied as
   67 // operands to memory ops.
   68 //
   69 // follow the C1 compiler in making registers
   70 //
   71 //   x7, x9-x17, x27-x31 volatile (caller save)
   72 //   x0-x4, x8, x23 system (no save, no allocate)
   73 //   x5-x6 non-allocatable (so we can use them as temporary regs)
   74 
   75 //
   76 // as regards Java usage. we don't use any callee save registers
   77 // because this makes it difficult to de-optimise a frame (see comment
   78 // in x86 implementation of Deoptimization::unwind_callee_save_values)
   79 //
   80 
   81 // General Registers
   82 
   83 reg_def R0      ( NS,  NS,  Op_RegI, 0,  x0->as_VMReg()         ); // zr
   84 reg_def R0_H    ( NS,  NS,  Op_RegI, 0,  x0->as_VMReg()->next() );
   85 reg_def R1      ( NS,  SOC, Op_RegI, 1,  x1->as_VMReg()         ); // ra
   86 reg_def R1_H    ( NS,  SOC, Op_RegI, 1,  x1->as_VMReg()->next() );
   87 reg_def R2      ( NS,  NS,  Op_RegI, 2,  x2->as_VMReg()         ); // sp
   88 reg_def R2_H    ( NS,  NS,  Op_RegI, 2,  x2->as_VMReg()->next() );
   89 reg_def R3      ( NS,  NS,  Op_RegI, 3,  x3->as_VMReg()         ); // gp
   90 reg_def R3_H    ( NS,  NS,  Op_RegI, 3,  x3->as_VMReg()->next() );
   91 reg_def R4      ( NS,  NS,  Op_RegI, 4,  x4->as_VMReg()         ); // tp
   92 reg_def R4_H    ( NS,  NS,  Op_RegI, 4,  x4->as_VMReg()->next() );
   93 reg_def R7      ( SOC, SOC, Op_RegI, 7,  x7->as_VMReg()         );
   94 reg_def R7_H    ( SOC, SOC, Op_RegI, 7,  x7->as_VMReg()->next() );
   95 reg_def R8      ( NS,  SOE, Op_RegI, 8,  x8->as_VMReg()         ); // fp
   96 reg_def R8_H    ( NS,  SOE, Op_RegI, 8,  x8->as_VMReg()->next() );
   97 reg_def R9      ( SOC, SOE, Op_RegI, 9,  x9->as_VMReg()         );
   98 reg_def R9_H    ( SOC, SOE, Op_RegI, 9,  x9->as_VMReg()->next() );
   99 reg_def R10     ( SOC, SOC, Op_RegI, 10, x10->as_VMReg()        );
  100 reg_def R10_H   ( SOC, SOC, Op_RegI, 10, x10->as_VMReg()->next());
  101 reg_def R11     ( SOC, SOC, Op_RegI, 11, x11->as_VMReg()        );
  102 reg_def R11_H   ( SOC, SOC, Op_RegI, 11, x11->as_VMReg()->next());
  103 reg_def R12     ( SOC, SOC, Op_RegI, 12, x12->as_VMReg()        );
  104 reg_def R12_H   ( SOC, SOC, Op_RegI, 12, x12->as_VMReg()->next());
  105 reg_def R13     ( SOC, SOC, Op_RegI, 13, x13->as_VMReg()        );
  106 reg_def R13_H   ( SOC, SOC, Op_RegI, 13, x13->as_VMReg()->next());
  107 reg_def R14     ( SOC, SOC, Op_RegI, 14, x14->as_VMReg()        );
  108 reg_def R14_H   ( SOC, SOC, Op_RegI, 14, x14->as_VMReg()->next());
  109 reg_def R15     ( SOC, SOC, Op_RegI, 15, x15->as_VMReg()        );
  110 reg_def R15_H   ( SOC, SOC, Op_RegI, 15, x15->as_VMReg()->next());
  111 reg_def R16     ( SOC, SOC, Op_RegI, 16, x16->as_VMReg()        );
  112 reg_def R16_H   ( SOC, SOC, Op_RegI, 16, x16->as_VMReg()->next());
  113 reg_def R17     ( SOC, SOC, Op_RegI, 17, x17->as_VMReg()        );
  114 reg_def R17_H   ( SOC, SOC, Op_RegI, 17, x17->as_VMReg()->next());
  115 reg_def R18     ( SOC, SOE, Op_RegI, 18, x18->as_VMReg()        );
  116 reg_def R18_H   ( SOC, SOE, Op_RegI, 18, x18->as_VMReg()->next());
  117 reg_def R19     ( SOC, SOE, Op_RegI, 19, x19->as_VMReg()        );
  118 reg_def R19_H   ( SOC, SOE, Op_RegI, 19, x19->as_VMReg()->next());
  119 reg_def R20     ( SOC, SOE, Op_RegI, 20, x20->as_VMReg()        ); // caller esp
  120 reg_def R20_H   ( SOC, SOE, Op_RegI, 20, x20->as_VMReg()->next());
  121 reg_def R21     ( SOC, SOE, Op_RegI, 21, x21->as_VMReg()        );
  122 reg_def R21_H   ( SOC, SOE, Op_RegI, 21, x21->as_VMReg()->next());
  123 reg_def R22     ( SOC, SOE, Op_RegI, 22, x22->as_VMReg()        );
  124 reg_def R22_H   ( SOC, SOE, Op_RegI, 22, x22->as_VMReg()->next());
  125 reg_def R23     ( NS,  SOE, Op_RegI, 23, x23->as_VMReg()        ); // java thread
  126 reg_def R23_H   ( NS,  SOE, Op_RegI, 23, x23->as_VMReg()->next());
  127 reg_def R24     ( SOC, SOE, Op_RegI, 24, x24->as_VMReg()        );
  128 reg_def R24_H   ( SOC, SOE, Op_RegI, 24, x24->as_VMReg()->next());
  129 reg_def R25     ( SOC, SOE, Op_RegI, 25, x25->as_VMReg()        );
  130 reg_def R25_H   ( SOC, SOE, Op_RegI, 25, x25->as_VMReg()->next());
  131 reg_def R26     ( SOC, SOE, Op_RegI, 26, x26->as_VMReg()        );
  132 reg_def R26_H   ( SOC, SOE, Op_RegI, 26, x26->as_VMReg()->next());
  133 reg_def R27     ( SOC, SOE, Op_RegI, 27, x27->as_VMReg()        ); // heapbase
  134 reg_def R27_H   ( SOC, SOE, Op_RegI, 27, x27->as_VMReg()->next());
  135 reg_def R28     ( SOC, SOC, Op_RegI, 28, x28->as_VMReg()        );
  136 reg_def R28_H   ( SOC, SOC, Op_RegI, 28, x28->as_VMReg()->next());
  137 reg_def R29     ( SOC, SOC, Op_RegI, 29, x29->as_VMReg()        );
  138 reg_def R29_H   ( SOC, SOC, Op_RegI, 29, x29->as_VMReg()->next());
  139 reg_def R30     ( SOC, SOC, Op_RegI, 30, x30->as_VMReg()        );
  140 reg_def R30_H   ( SOC, SOC, Op_RegI, 30, x30->as_VMReg()->next());
  141 reg_def R31     ( SOC, SOC, Op_RegI, 31, x31->as_VMReg()        );
  142 reg_def R31_H   ( SOC, SOC, Op_RegI, 31, x31->as_VMReg()->next());
  143 
  144 // ----------------------------
  145 // Float/Double Registers
  146 // ----------------------------
  147 
  148 // Double Registers
  149 
  150 // The rules of ADL require that double registers be defined in pairs.
  151 // Each pair must be two 32-bit values, but not necessarily a pair of
  152 // single float registers. In each pair, ADLC-assigned register numbers
  153 // must be adjacent, with the lower number even. Finally, when the
  154 // CPU stores such a register pair to memory, the word associated with
  155 // the lower ADLC-assigned number must be stored to the lower address.
  156 
  157 // RISCV has 32 floating-point registers. Each can store a single
  158 // or double precision floating-point value.
  159 
  160 // for Java use float registers f0-f31 are always save on call whereas
  161 // the platform ABI treats f8-f9 and f18-f27 as callee save). Other
  162 // float registers are SOC as per the platform spec
  163 
  164 reg_def F0    ( SOC, SOC, Op_RegF,  0,  f0->as_VMReg()          );
  165 reg_def F0_H  ( SOC, SOC, Op_RegF,  0,  f0->as_VMReg()->next()  );
  166 reg_def F1    ( SOC, SOC, Op_RegF,  1,  f1->as_VMReg()          );
  167 reg_def F1_H  ( SOC, SOC, Op_RegF,  1,  f1->as_VMReg()->next()  );
  168 reg_def F2    ( SOC, SOC, Op_RegF,  2,  f2->as_VMReg()          );
  169 reg_def F2_H  ( SOC, SOC, Op_RegF,  2,  f2->as_VMReg()->next()  );
  170 reg_def F3    ( SOC, SOC, Op_RegF,  3,  f3->as_VMReg()          );
  171 reg_def F3_H  ( SOC, SOC, Op_RegF,  3,  f3->as_VMReg()->next()  );
  172 reg_def F4    ( SOC, SOC, Op_RegF,  4,  f4->as_VMReg()          );
  173 reg_def F4_H  ( SOC, SOC, Op_RegF,  4,  f4->as_VMReg()->next()  );
  174 reg_def F5    ( SOC, SOC, Op_RegF,  5,  f5->as_VMReg()          );
  175 reg_def F5_H  ( SOC, SOC, Op_RegF,  5,  f5->as_VMReg()->next()  );
  176 reg_def F6    ( SOC, SOC, Op_RegF,  6,  f6->as_VMReg()          );
  177 reg_def F6_H  ( SOC, SOC, Op_RegF,  6,  f6->as_VMReg()->next()  );
  178 reg_def F7    ( SOC, SOC, Op_RegF,  7,  f7->as_VMReg()          );
  179 reg_def F7_H  ( SOC, SOC, Op_RegF,  7,  f7->as_VMReg()->next()  );
  180 reg_def F8    ( SOC, SOE, Op_RegF,  8,  f8->as_VMReg()          );
  181 reg_def F8_H  ( SOC, SOE, Op_RegF,  8,  f8->as_VMReg()->next()  );
  182 reg_def F9    ( SOC, SOE, Op_RegF,  9,  f9->as_VMReg()          );
  183 reg_def F9_H  ( SOC, SOE, Op_RegF,  9,  f9->as_VMReg()->next()  );
  184 reg_def F10   ( SOC, SOC, Op_RegF,  10, f10->as_VMReg()         );
  185 reg_def F10_H ( SOC, SOC, Op_RegF,  10, f10->as_VMReg()->next() );
  186 reg_def F11   ( SOC, SOC, Op_RegF,  11, f11->as_VMReg()         );
  187 reg_def F11_H ( SOC, SOC, Op_RegF,  11, f11->as_VMReg()->next() );
  188 reg_def F12   ( SOC, SOC, Op_RegF,  12, f12->as_VMReg()         );
  189 reg_def F12_H ( SOC, SOC, Op_RegF,  12, f12->as_VMReg()->next() );
  190 reg_def F13   ( SOC, SOC, Op_RegF,  13, f13->as_VMReg()         );
  191 reg_def F13_H ( SOC, SOC, Op_RegF,  13, f13->as_VMReg()->next() );
  192 reg_def F14   ( SOC, SOC, Op_RegF,  14, f14->as_VMReg()         );
  193 reg_def F14_H ( SOC, SOC, Op_RegF,  14, f14->as_VMReg()->next() );
  194 reg_def F15   ( SOC, SOC, Op_RegF,  15, f15->as_VMReg()         );
  195 reg_def F15_H ( SOC, SOC, Op_RegF,  15, f15->as_VMReg()->next() );
  196 reg_def F16   ( SOC, SOC, Op_RegF,  16, f16->as_VMReg()         );
  197 reg_def F16_H ( SOC, SOC, Op_RegF,  16, f16->as_VMReg()->next() );
  198 reg_def F17   ( SOC, SOC, Op_RegF,  17, f17->as_VMReg()         );
  199 reg_def F17_H ( SOC, SOC, Op_RegF,  17, f17->as_VMReg()->next() );
  200 reg_def F18   ( SOC, SOE, Op_RegF,  18, f18->as_VMReg()         );
  201 reg_def F18_H ( SOC, SOE, Op_RegF,  18, f18->as_VMReg()->next() );
  202 reg_def F19   ( SOC, SOE, Op_RegF,  19, f19->as_VMReg()         );
  203 reg_def F19_H ( SOC, SOE, Op_RegF,  19, f19->as_VMReg()->next() );
  204 reg_def F20   ( SOC, SOE, Op_RegF,  20, f20->as_VMReg()         );
  205 reg_def F20_H ( SOC, SOE, Op_RegF,  20, f20->as_VMReg()->next() );
  206 reg_def F21   ( SOC, SOE, Op_RegF,  21, f21->as_VMReg()         );
  207 reg_def F21_H ( SOC, SOE, Op_RegF,  21, f21->as_VMReg()->next() );
  208 reg_def F22   ( SOC, SOE, Op_RegF,  22, f22->as_VMReg()         );
  209 reg_def F22_H ( SOC, SOE, Op_RegF,  22, f22->as_VMReg()->next() );
  210 reg_def F23   ( SOC, SOE, Op_RegF,  23, f23->as_VMReg()         );
  211 reg_def F23_H ( SOC, SOE, Op_RegF,  23, f23->as_VMReg()->next() );
  212 reg_def F24   ( SOC, SOE, Op_RegF,  24, f24->as_VMReg()         );
  213 reg_def F24_H ( SOC, SOE, Op_RegF,  24, f24->as_VMReg()->next() );
  214 reg_def F25   ( SOC, SOE, Op_RegF,  25, f25->as_VMReg()         );
  215 reg_def F25_H ( SOC, SOE, Op_RegF,  25, f25->as_VMReg()->next() );
  216 reg_def F26   ( SOC, SOE, Op_RegF,  26, f26->as_VMReg()         );
  217 reg_def F26_H ( SOC, SOE, Op_RegF,  26, f26->as_VMReg()->next() );
  218 reg_def F27   ( SOC, SOE, Op_RegF,  27, f27->as_VMReg()         );
  219 reg_def F27_H ( SOC, SOE, Op_RegF,  27, f27->as_VMReg()->next() );
  220 reg_def F28   ( SOC, SOC, Op_RegF,  28, f28->as_VMReg()         );
  221 reg_def F28_H ( SOC, SOC, Op_RegF,  28, f28->as_VMReg()->next() );
  222 reg_def F29   ( SOC, SOC, Op_RegF,  29, f29->as_VMReg()         );
  223 reg_def F29_H ( SOC, SOC, Op_RegF,  29, f29->as_VMReg()->next() );
  224 reg_def F30   ( SOC, SOC, Op_RegF,  30, f30->as_VMReg()         );
  225 reg_def F30_H ( SOC, SOC, Op_RegF,  30, f30->as_VMReg()->next() );
  226 reg_def F31   ( SOC, SOC, Op_RegF,  31, f31->as_VMReg()         );
  227 reg_def F31_H ( SOC, SOC, Op_RegF,  31, f31->as_VMReg()->next() );
  228 
  229 // ----------------------------
  230 // Vector Registers
  231 // ----------------------------
  232 
  233 // For RVV vector registers, we simply extend vector register size to 4
  234 // 'logical' slots. This is nominally 128 bits but it actually covers
  235 // all possible 'physical' RVV vector register lengths from 128 ~ 1024
  236 // bits. The 'physical' RVV vector register length is detected during
  237 // startup, so the register allocator is able to identify the correct
  238 // number of bytes needed for an RVV spill/unspill.
  239 
  240 reg_def V0    ( SOC, SOC, Op_VecA, 0,  v0->as_VMReg()           );
  241 reg_def V0_H  ( SOC, SOC, Op_VecA, 0,  v0->as_VMReg()->next()   );
  242 reg_def V0_J  ( SOC, SOC, Op_VecA, 0,  v0->as_VMReg()->next(2)  );
  243 reg_def V0_K  ( SOC, SOC, Op_VecA, 0,  v0->as_VMReg()->next(3)  );
  244 
  245 reg_def V1    ( SOC, SOC, Op_VecA, 1,  v1->as_VMReg()           );
  246 reg_def V1_H  ( SOC, SOC, Op_VecA, 1,  v1->as_VMReg()->next()   );
  247 reg_def V1_J  ( SOC, SOC, Op_VecA, 1,  v1->as_VMReg()->next(2)  );
  248 reg_def V1_K  ( SOC, SOC, Op_VecA, 1,  v1->as_VMReg()->next(3)  );
  249 
  250 reg_def V2    ( SOC, SOC, Op_VecA, 2,  v2->as_VMReg()           );
  251 reg_def V2_H  ( SOC, SOC, Op_VecA, 2,  v2->as_VMReg()->next()   );
  252 reg_def V2_J  ( SOC, SOC, Op_VecA, 2,  v2->as_VMReg()->next(2)  );
  253 reg_def V2_K  ( SOC, SOC, Op_VecA, 2,  v2->as_VMReg()->next(3)  );
  254 
  255 reg_def V3    ( SOC, SOC, Op_VecA, 3,  v3->as_VMReg()           );
  256 reg_def V3_H  ( SOC, SOC, Op_VecA, 3,  v3->as_VMReg()->next()   );
  257 reg_def V3_J  ( SOC, SOC, Op_VecA, 3,  v3->as_VMReg()->next(2)  );
  258 reg_def V3_K  ( SOC, SOC, Op_VecA, 3,  v3->as_VMReg()->next(3)  );
  259 
  260 reg_def V4    ( SOC, SOC, Op_VecA, 4,  v4->as_VMReg()           );
  261 reg_def V4_H  ( SOC, SOC, Op_VecA, 4,  v4->as_VMReg()->next()   );
  262 reg_def V4_J  ( SOC, SOC, Op_VecA, 4,  v4->as_VMReg()->next(2)  );
  263 reg_def V4_K  ( SOC, SOC, Op_VecA, 4,  v4->as_VMReg()->next(3)  );
  264 
  265 reg_def V5    ( SOC, SOC, Op_VecA, 5,  v5->as_VMReg()           );
  266 reg_def V5_H  ( SOC, SOC, Op_VecA, 5,  v5->as_VMReg()->next()   );
  267 reg_def V5_J  ( SOC, SOC, Op_VecA, 5,  v5->as_VMReg()->next(2)  );
  268 reg_def V5_K  ( SOC, SOC, Op_VecA, 5,  v5->as_VMReg()->next(3)  );
  269 
  270 reg_def V6    ( SOC, SOC, Op_VecA, 6,  v6->as_VMReg()           );
  271 reg_def V6_H  ( SOC, SOC, Op_VecA, 6,  v6->as_VMReg()->next()   );
  272 reg_def V6_J  ( SOC, SOC, Op_VecA, 6,  v6->as_VMReg()->next(2)  );
  273 reg_def V6_K  ( SOC, SOC, Op_VecA, 6,  v6->as_VMReg()->next(3)  );
  274 
  275 reg_def V7    ( SOC, SOC, Op_VecA, 7,  v7->as_VMReg()           );
  276 reg_def V7_H  ( SOC, SOC, Op_VecA, 7,  v7->as_VMReg()->next()   );
  277 reg_def V7_J  ( SOC, SOC, Op_VecA, 7,  v7->as_VMReg()->next(2)  );
  278 reg_def V7_K  ( SOC, SOC, Op_VecA, 7,  v7->as_VMReg()->next(3)  );
  279 
  280 reg_def V8    ( SOC, SOC, Op_VecA, 8,  v8->as_VMReg()           );
  281 reg_def V8_H  ( SOC, SOC, Op_VecA, 8,  v8->as_VMReg()->next()   );
  282 reg_def V8_J  ( SOC, SOC, Op_VecA, 8,  v8->as_VMReg()->next(2)  );
  283 reg_def V8_K  ( SOC, SOC, Op_VecA, 8,  v8->as_VMReg()->next(3)  );
  284 
  285 reg_def V9    ( SOC, SOC, Op_VecA, 9,  v9->as_VMReg()           );
  286 reg_def V9_H  ( SOC, SOC, Op_VecA, 9,  v9->as_VMReg()->next()   );
  287 reg_def V9_J  ( SOC, SOC, Op_VecA, 9,  v9->as_VMReg()->next(2)  );
  288 reg_def V9_K  ( SOC, SOC, Op_VecA, 9,  v9->as_VMReg()->next(3)  );
  289 
  290 reg_def V10   ( SOC, SOC, Op_VecA, 10, v10->as_VMReg()          );
  291 reg_def V10_H ( SOC, SOC, Op_VecA, 10, v10->as_VMReg()->next()  );
  292 reg_def V10_J ( SOC, SOC, Op_VecA, 10, v10->as_VMReg()->next(2) );
  293 reg_def V10_K ( SOC, SOC, Op_VecA, 10, v10->as_VMReg()->next(3) );
  294 
  295 reg_def V11   ( SOC, SOC, Op_VecA, 11, v11->as_VMReg()          );
  296 reg_def V11_H ( SOC, SOC, Op_VecA, 11, v11->as_VMReg()->next()  );
  297 reg_def V11_J ( SOC, SOC, Op_VecA, 11, v11->as_VMReg()->next(2) );
  298 reg_def V11_K ( SOC, SOC, Op_VecA, 11, v11->as_VMReg()->next(3) );
  299 
  300 reg_def V12   ( SOC, SOC, Op_VecA, 12, v12->as_VMReg()          );
  301 reg_def V12_H ( SOC, SOC, Op_VecA, 12, v12->as_VMReg()->next()  );
  302 reg_def V12_J ( SOC, SOC, Op_VecA, 12, v12->as_VMReg()->next(2) );
  303 reg_def V12_K ( SOC, SOC, Op_VecA, 12, v12->as_VMReg()->next(3) );
  304 
  305 reg_def V13   ( SOC, SOC, Op_VecA, 13, v13->as_VMReg()          );
  306 reg_def V13_H ( SOC, SOC, Op_VecA, 13, v13->as_VMReg()->next()  );
  307 reg_def V13_J ( SOC, SOC, Op_VecA, 13, v13->as_VMReg()->next(2) );
  308 reg_def V13_K ( SOC, SOC, Op_VecA, 13, v13->as_VMReg()->next(3) );
  309 
  310 reg_def V14   ( SOC, SOC, Op_VecA, 14, v14->as_VMReg()          );
  311 reg_def V14_H ( SOC, SOC, Op_VecA, 14, v14->as_VMReg()->next()  );
  312 reg_def V14_J ( SOC, SOC, Op_VecA, 14, v14->as_VMReg()->next(2) );
  313 reg_def V14_K ( SOC, SOC, Op_VecA, 14, v14->as_VMReg()->next(3) );
  314 
  315 reg_def V15   ( SOC, SOC, Op_VecA, 15, v15->as_VMReg()          );
  316 reg_def V15_H ( SOC, SOC, Op_VecA, 15, v15->as_VMReg()->next()  );
  317 reg_def V15_J ( SOC, SOC, Op_VecA, 15, v15->as_VMReg()->next(2) );
  318 reg_def V15_K ( SOC, SOC, Op_VecA, 15, v15->as_VMReg()->next(3) );
  319 
  320 reg_def V16   ( SOC, SOC, Op_VecA, 16, v16->as_VMReg()          );
  321 reg_def V16_H ( SOC, SOC, Op_VecA, 16, v16->as_VMReg()->next()  );
  322 reg_def V16_J ( SOC, SOC, Op_VecA, 16, v16->as_VMReg()->next(2) );
  323 reg_def V16_K ( SOC, SOC, Op_VecA, 16, v16->as_VMReg()->next(3) );
  324 
  325 reg_def V17   ( SOC, SOC, Op_VecA, 17, v17->as_VMReg()          );
  326 reg_def V17_H ( SOC, SOC, Op_VecA, 17, v17->as_VMReg()->next()  );
  327 reg_def V17_J ( SOC, SOC, Op_VecA, 17, v17->as_VMReg()->next(2) );
  328 reg_def V17_K ( SOC, SOC, Op_VecA, 17, v17->as_VMReg()->next(3) );
  329 
  330 reg_def V18   ( SOC, SOC, Op_VecA, 18, v18->as_VMReg()          );
  331 reg_def V18_H ( SOC, SOC, Op_VecA, 18, v18->as_VMReg()->next()  );
  332 reg_def V18_J ( SOC, SOC, Op_VecA, 18, v18->as_VMReg()->next(2) );
  333 reg_def V18_K ( SOC, SOC, Op_VecA, 18, v18->as_VMReg()->next(3) );
  334 
  335 reg_def V19   ( SOC, SOC, Op_VecA, 19, v19->as_VMReg()          );
  336 reg_def V19_H ( SOC, SOC, Op_VecA, 19, v19->as_VMReg()->next()  );
  337 reg_def V19_J ( SOC, SOC, Op_VecA, 19, v19->as_VMReg()->next(2) );
  338 reg_def V19_K ( SOC, SOC, Op_VecA, 19, v19->as_VMReg()->next(3) );
  339 
  340 reg_def V20   ( SOC, SOC, Op_VecA, 20, v20->as_VMReg()          );
  341 reg_def V20_H ( SOC, SOC, Op_VecA, 20, v20->as_VMReg()->next()  );
  342 reg_def V20_J ( SOC, SOC, Op_VecA, 20, v20->as_VMReg()->next(2) );
  343 reg_def V20_K ( SOC, SOC, Op_VecA, 20, v20->as_VMReg()->next(3) );
  344 
  345 reg_def V21   ( SOC, SOC, Op_VecA, 21, v21->as_VMReg()          );
  346 reg_def V21_H ( SOC, SOC, Op_VecA, 21, v21->as_VMReg()->next()  );
  347 reg_def V21_J ( SOC, SOC, Op_VecA, 21, v21->as_VMReg()->next(2) );
  348 reg_def V21_K ( SOC, SOC, Op_VecA, 21, v21->as_VMReg()->next(3) );
  349 
  350 reg_def V22   ( SOC, SOC, Op_VecA, 22, v22->as_VMReg()          );
  351 reg_def V22_H ( SOC, SOC, Op_VecA, 22, v22->as_VMReg()->next()  );
  352 reg_def V22_J ( SOC, SOC, Op_VecA, 22, v22->as_VMReg()->next(2) );
  353 reg_def V22_K ( SOC, SOC, Op_VecA, 22, v22->as_VMReg()->next(3) );
  354 
  355 reg_def V23   ( SOC, SOC, Op_VecA, 23, v23->as_VMReg()          );
  356 reg_def V23_H ( SOC, SOC, Op_VecA, 23, v23->as_VMReg()->next()  );
  357 reg_def V23_J ( SOC, SOC, Op_VecA, 23, v23->as_VMReg()->next(2) );
  358 reg_def V23_K ( SOC, SOC, Op_VecA, 23, v23->as_VMReg()->next(3) );
  359 
  360 reg_def V24   ( SOC, SOC, Op_VecA, 24, v24->as_VMReg()          );
  361 reg_def V24_H ( SOC, SOC, Op_VecA, 24, v24->as_VMReg()->next()  );
  362 reg_def V24_J ( SOC, SOC, Op_VecA, 24, v24->as_VMReg()->next(2) );
  363 reg_def V24_K ( SOC, SOC, Op_VecA, 24, v24->as_VMReg()->next(3) );
  364 
  365 reg_def V25   ( SOC, SOC, Op_VecA, 25, v25->as_VMReg()          );
  366 reg_def V25_H ( SOC, SOC, Op_VecA, 25, v25->as_VMReg()->next()  );
  367 reg_def V25_J ( SOC, SOC, Op_VecA, 25, v25->as_VMReg()->next(2) );
  368 reg_def V25_K ( SOC, SOC, Op_VecA, 25, v25->as_VMReg()->next(3) );
  369 
  370 reg_def V26   ( SOC, SOC, Op_VecA, 26, v26->as_VMReg()          );
  371 reg_def V26_H ( SOC, SOC, Op_VecA, 26, v26->as_VMReg()->next()  );
  372 reg_def V26_J ( SOC, SOC, Op_VecA, 26, v26->as_VMReg()->next(2) );
  373 reg_def V26_K ( SOC, SOC, Op_VecA, 26, v26->as_VMReg()->next(3) );
  374 
  375 reg_def V27   ( SOC, SOC, Op_VecA, 27, v27->as_VMReg()          );
  376 reg_def V27_H ( SOC, SOC, Op_VecA, 27, v27->as_VMReg()->next()  );
  377 reg_def V27_J ( SOC, SOC, Op_VecA, 27, v27->as_VMReg()->next(2) );
  378 reg_def V27_K ( SOC, SOC, Op_VecA, 27, v27->as_VMReg()->next(3) );
  379 
  380 reg_def V28   ( SOC, SOC, Op_VecA, 28, v28->as_VMReg()          );
  381 reg_def V28_H ( SOC, SOC, Op_VecA, 28, v28->as_VMReg()->next()  );
  382 reg_def V28_J ( SOC, SOC, Op_VecA, 28, v28->as_VMReg()->next(2) );
  383 reg_def V28_K ( SOC, SOC, Op_VecA, 28, v28->as_VMReg()->next(3) );
  384 
  385 reg_def V29   ( SOC, SOC, Op_VecA, 29, v29->as_VMReg()          );
  386 reg_def V29_H ( SOC, SOC, Op_VecA, 29, v29->as_VMReg()->next()  );
  387 reg_def V29_J ( SOC, SOC, Op_VecA, 29, v29->as_VMReg()->next(2) );
  388 reg_def V29_K ( SOC, SOC, Op_VecA, 29, v29->as_VMReg()->next(3) );
  389 
  390 reg_def V30   ( SOC, SOC, Op_VecA, 30, v30->as_VMReg()          );
  391 reg_def V30_H ( SOC, SOC, Op_VecA, 30, v30->as_VMReg()->next()  );
  392 reg_def V30_J ( SOC, SOC, Op_VecA, 30, v30->as_VMReg()->next(2) );
  393 reg_def V30_K ( SOC, SOC, Op_VecA, 30, v30->as_VMReg()->next(3) );
  394 
  395 reg_def V31   ( SOC, SOC, Op_VecA, 31, v31->as_VMReg()          );
  396 reg_def V31_H ( SOC, SOC, Op_VecA, 31, v31->as_VMReg()->next()  );
  397 reg_def V31_J ( SOC, SOC, Op_VecA, 31, v31->as_VMReg()->next(2) );
  398 reg_def V31_K ( SOC, SOC, Op_VecA, 31, v31->as_VMReg()->next(3) );
  399 
  400 // ----------------------------
  401 // Special Registers
  402 // ----------------------------
  403 
  404 // On riscv, the physical flag register is missing, so we use t1 instead,
  405 // to bridge the RegFlag semantics in share/opto
  406 
  407 reg_def RFLAGS   (SOC, SOC, Op_RegFlags, 6, x6->as_VMReg()        );
  408 
  409 // Specify priority of register selection within phases of register
  410 // allocation.  Highest priority is first.  A useful heuristic is to
  411 // give registers a low priority when they are required by machine
  412 // instructions, like EAX and EDX on I486, and choose no-save registers
  413 // before save-on-call, & save-on-call before save-on-entry.  Registers
  414 // which participate in fixed calling sequences should come last.
  415 // Registers which are used as pairs must fall on an even boundary.
  416 
  417 alloc_class chunk0(
  418     // volatiles
  419     R7,  R7_H,
  420     R28, R28_H,
  421     R29, R29_H,
  422     R30, R30_H,
  423     R31, R31_H,
  424 
  425     // arg registers
  426     R10, R10_H,
  427     R11, R11_H,
  428     R12, R12_H,
  429     R13, R13_H,
  430     R14, R14_H,
  431     R15, R15_H,
  432     R16, R16_H,
  433     R17, R17_H,
  434 
  435     // non-volatiles
  436     R9,  R9_H,
  437     R18, R18_H,
  438     R19, R19_H,
  439     R20, R20_H,
  440     R21, R21_H,
  441     R22, R22_H,
  442     R24, R24_H,
  443     R25, R25_H,
  444     R26, R26_H,
  445 
  446     // non-allocatable registers
  447     R23, R23_H, // java thread
  448     R27, R27_H, // heapbase
  449     R4,  R4_H,  // thread
  450     R8,  R8_H,  // fp
  451     R0,  R0_H,  // zero
  452     R1,  R1_H,  // ra
  453     R2,  R2_H,  // sp
  454     R3,  R3_H,  // gp
  455 );
  456 
  457 alloc_class chunk1(
  458 
  459     // no save
  460     F0,  F0_H,
  461     F1,  F1_H,
  462     F2,  F2_H,
  463     F3,  F3_H,
  464     F4,  F4_H,
  465     F5,  F5_H,
  466     F6,  F6_H,
  467     F7,  F7_H,
  468     F28, F28_H,
  469     F29, F29_H,
  470     F30, F30_H,
  471     F31, F31_H,
  472 
  473     // arg registers
  474     F10, F10_H,
  475     F11, F11_H,
  476     F12, F12_H,
  477     F13, F13_H,
  478     F14, F14_H,
  479     F15, F15_H,
  480     F16, F16_H,
  481     F17, F17_H,
  482 
  483     // non-volatiles
  484     F8,  F8_H,
  485     F9,  F9_H,
  486     F18, F18_H,
  487     F19, F19_H,
  488     F20, F20_H,
  489     F21, F21_H,
  490     F22, F22_H,
  491     F23, F23_H,
  492     F24, F24_H,
  493     F25, F25_H,
  494     F26, F26_H,
  495     F27, F27_H,
  496 );
  497 
  498 alloc_class chunk2(
  499     V0, V0_H, V0_J, V0_K,
  500     V1, V1_H, V1_J, V1_K,
  501     V2, V2_H, V2_J, V2_K,
  502     V3, V3_H, V3_J, V3_K,
  503     V4, V4_H, V4_J, V4_K,
  504     V5, V5_H, V5_J, V5_K,
  505     V6, V6_H, V6_J, V6_K,
  506     V7, V7_H, V7_J, V7_K,
  507     V8, V8_H, V8_J, V8_K,
  508     V9, V9_H, V9_J, V9_K,
  509     V10, V10_H, V10_J, V10_K,
  510     V11, V11_H, V11_J, V11_K,
  511     V12, V12_H, V12_J, V12_K,
  512     V13, V13_H, V13_J, V13_K,
  513     V14, V14_H, V14_J, V14_K,
  514     V15, V15_H, V15_J, V15_K,
  515     V16, V16_H, V16_J, V16_K,
  516     V17, V17_H, V17_J, V17_K,
  517     V18, V18_H, V18_J, V18_K,
  518     V19, V19_H, V19_J, V19_K,
  519     V20, V20_H, V20_J, V20_K,
  520     V21, V21_H, V21_J, V21_K,
  521     V22, V22_H, V22_J, V22_K,
  522     V23, V23_H, V23_J, V23_K,
  523     V24, V24_H, V24_J, V24_K,
  524     V25, V25_H, V25_J, V25_K,
  525     V26, V26_H, V26_J, V26_K,
  526     V27, V27_H, V27_J, V27_K,
  527     V28, V28_H, V28_J, V28_K,
  528     V29, V29_H, V29_J, V29_K,
  529     V30, V30_H, V30_J, V30_K,
  530     V31, V31_H, V31_J, V31_K,
  531 );
  532 
  533 alloc_class chunk3(RFLAGS);
  534 
  535 //----------Architecture Description Register Classes--------------------------
  536 // Several register classes are automatically defined based upon information in
  537 // this architecture description.
  538 // 1) reg_class inline_cache_reg           ( /* as def'd in frame section */ )
  539 // 2) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
  540 //
  541 
  542 // Class for all 32 bit general purpose registers
  543 reg_class all_reg32(
  544     R0,
  545     R1,
  546     R2,
  547     R3,
  548     R4,
  549     R7,
  550     R8,
  551     R9,
  552     R10,
  553     R11,
  554     R12,
  555     R13,
  556     R14,
  557     R15,
  558     R16,
  559     R17,
  560     R18,
  561     R19,
  562     R20,
  563     R21,
  564     R22,
  565     R23,
  566     R24,
  567     R25,
  568     R26,
  569     R27,
  570     R28,
  571     R29,
  572     R30,
  573     R31
  574 );
  575 
  576 // Class for any 32 bit integer registers (excluding zr)
  577 reg_class any_reg32 %{
  578   return _ANY_REG32_mask;
  579 %}
  580 
  581 // Singleton class for R10 int register
  582 reg_class int_r10_reg(R10);
  583 
  584 // Singleton class for R12 int register
  585 reg_class int_r12_reg(R12);
  586 
  587 // Singleton class for R13 int register
  588 reg_class int_r13_reg(R13);
  589 
  590 // Singleton class for R14 int register
  591 reg_class int_r14_reg(R14);
  592 
  593 // Class for all long integer registers
  594 reg_class all_reg(
  595     R0,  R0_H,
  596     R1,  R1_H,
  597     R2,  R2_H,
  598     R3,  R3_H,
  599     R4,  R4_H,
  600     R7,  R7_H,
  601     R8,  R8_H,
  602     R9,  R9_H,
  603     R10, R10_H,
  604     R11, R11_H,
  605     R12, R12_H,
  606     R13, R13_H,
  607     R14, R14_H,
  608     R15, R15_H,
  609     R16, R16_H,
  610     R17, R17_H,
  611     R18, R18_H,
  612     R19, R19_H,
  613     R20, R20_H,
  614     R21, R21_H,
  615     R22, R22_H,
  616     R23, R23_H,
  617     R24, R24_H,
  618     R25, R25_H,
  619     R26, R26_H,
  620     R27, R27_H,
  621     R28, R28_H,
  622     R29, R29_H,
  623     R30, R30_H,
  624     R31, R31_H
  625 );
  626 
  627 // Class for all long integer registers (excluding zr)
  628 reg_class any_reg %{
  629   return _ANY_REG_mask;
  630 %}
  631 
  632 // Class for non-allocatable 32 bit registers
  633 reg_class non_allocatable_reg32(
  634     R0,                       // zr
  635     R1,                       // ra
  636     R2,                       // sp
  637     R3,                       // gp
  638     R4,                       // tp
  639     R23                       // java thread
  640 );
  641 
  642 // Class for non-allocatable 64 bit registers
  643 reg_class non_allocatable_reg(
  644     R0,  R0_H,                // zr
  645     R1,  R1_H,                // ra
  646     R2,  R2_H,                // sp
  647     R3,  R3_H,                // gp
  648     R4,  R4_H,                // tp
  649     R23, R23_H                // java thread
  650 );
  651 
  652 // Class for all non-special integer registers
  653 reg_class no_special_reg32 %{
  654   return _NO_SPECIAL_REG32_mask;
  655 %}
  656 
  657 // Class for all non-special long integer registers
  658 reg_class no_special_reg %{
  659   return _NO_SPECIAL_REG_mask;
  660 %}
  661 
  662 reg_class ptr_reg %{
  663   return _PTR_REG_mask;
  664 %}
  665 
  666 // Class for all non_special pointer registers
  667 reg_class no_special_ptr_reg %{
  668   return _NO_SPECIAL_PTR_REG_mask;
  669 %}
  670 
  671 // Class for all non_special pointer registers (excluding fp)
  672 reg_class no_special_no_fp_ptr_reg %{
  673   return _NO_SPECIAL_NO_FP_PTR_REG_mask;
  674 %}
  675 
  676 // Class for 64 bit register r10
  677 reg_class r10_reg(
  678     R10, R10_H
  679 );
  680 
  681 // Class for 64 bit register r11
  682 reg_class r11_reg(
  683     R11, R11_H
  684 );
  685 
  686 // Class for 64 bit register r12
  687 reg_class r12_reg(
  688     R12, R12_H
  689 );
  690 
  691 // Class for 64 bit register r13
  692 reg_class r13_reg(
  693     R13, R13_H
  694 );
  695 
  696 // Class for 64 bit register r14
  697 reg_class r14_reg(
  698     R14, R14_H
  699 );
  700 
  701 // Class for 64 bit register r15
  702 reg_class r15_reg(
  703     R15, R15_H
  704 );
  705 
  706 // Class for 64 bit register r16
  707 reg_class r16_reg(
  708     R16, R16_H
  709 );
  710 
  711 // Class for method register
  712 reg_class method_reg(
  713     R31, R31_H
  714 );
  715 
  716 // Class for java thread register
  717 reg_class java_thread_reg(
  718     R23, R23_H
  719 );
  720 
  721 reg_class r28_reg(
  722     R28, R28_H
  723 );
  724 
  725 reg_class r29_reg(
  726     R29, R29_H
  727 );
  728 
  729 reg_class r30_reg(
  730     R30, R30_H
  731 );
  732 
  733 reg_class r31_reg(
  734     R31, R31_H
  735 );
  736 
  737 // Class for zero registesr
  738 reg_class zr_reg(
  739     R0, R0_H
  740 );
  741 
  742 // Class for thread register
  743 reg_class thread_reg(
  744     R4, R4_H
  745 );
  746 
  747 // Class for frame pointer register
  748 reg_class fp_reg(
  749     R8, R8_H
  750 );
  751 
  752 // Class for link register
  753 reg_class ra_reg(
  754     R1, R1_H
  755 );
  756 
  757 // Class for long sp register
  758 reg_class sp_reg(
  759     R2, R2_H
  760 );
  761 
  762 // Class for all float registers
  763 reg_class float_reg(
  764     F0,
  765     F1,
  766     F2,
  767     F3,
  768     F4,
  769     F5,
  770     F6,
  771     F7,
  772     F8,
  773     F9,
  774     F10,
  775     F11,
  776     F12,
  777     F13,
  778     F14,
  779     F15,
  780     F16,
  781     F17,
  782     F18,
  783     F19,
  784     F20,
  785     F21,
  786     F22,
  787     F23,
  788     F24,
  789     F25,
  790     F26,
  791     F27,
  792     F28,
  793     F29,
  794     F30,
  795     F31
  796 );
  797 
  798 // Double precision float registers have virtual `high halves' that
  799 // are needed by the allocator.
  800 // Class for all double registers
  801 reg_class double_reg(
  802     F0,  F0_H,
  803     F1,  F1_H,
  804     F2,  F2_H,
  805     F3,  F3_H,
  806     F4,  F4_H,
  807     F5,  F5_H,
  808     F6,  F6_H,
  809     F7,  F7_H,
  810     F8,  F8_H,
  811     F9,  F9_H,
  812     F10, F10_H,
  813     F11, F11_H,
  814     F12, F12_H,
  815     F13, F13_H,
  816     F14, F14_H,
  817     F15, F15_H,
  818     F16, F16_H,
  819     F17, F17_H,
  820     F18, F18_H,
  821     F19, F19_H,
  822     F20, F20_H,
  823     F21, F21_H,
  824     F22, F22_H,
  825     F23, F23_H,
  826     F24, F24_H,
  827     F25, F25_H,
  828     F26, F26_H,
  829     F27, F27_H,
  830     F28, F28_H,
  831     F29, F29_H,
  832     F30, F30_H,
  833     F31, F31_H
  834 );
  835 
  836 // Class for RVV vector registers
  837 // Note: v0, v30 and v31 are used as mask registers.
  838 reg_class vectora_reg(
  839     V1, V1_H, V1_J, V1_K,
  840     V2, V2_H, V2_J, V2_K,
  841     V3, V3_H, V3_J, V3_K,
  842     V4, V4_H, V4_J, V4_K,
  843     V5, V5_H, V5_J, V5_K,
  844     V6, V6_H, V6_J, V6_K,
  845     V7, V7_H, V7_J, V7_K,
  846     V8, V8_H, V8_J, V8_K,
  847     V9, V9_H, V9_J, V9_K,
  848     V10, V10_H, V10_J, V10_K,
  849     V11, V11_H, V11_J, V11_K,
  850     V12, V12_H, V12_J, V12_K,
  851     V13, V13_H, V13_J, V13_K,
  852     V14, V14_H, V14_J, V14_K,
  853     V15, V15_H, V15_J, V15_K,
  854     V16, V16_H, V16_J, V16_K,
  855     V17, V17_H, V17_J, V17_K,
  856     V18, V18_H, V18_J, V18_K,
  857     V19, V19_H, V19_J, V19_K,
  858     V20, V20_H, V20_J, V20_K,
  859     V21, V21_H, V21_J, V21_K,
  860     V22, V22_H, V22_J, V22_K,
  861     V23, V23_H, V23_J, V23_K,
  862     V24, V24_H, V24_J, V24_K,
  863     V25, V25_H, V25_J, V25_K,
  864     V26, V26_H, V26_J, V26_K,
  865     V27, V27_H, V27_J, V27_K,
  866     V28, V28_H, V28_J, V28_K,
  867     V29, V29_H, V29_J, V29_K
  868 );
  869 
  870 // Class for 64 bit register f0
  871 reg_class f0_reg(
  872     F0, F0_H
  873 );
  874 
  875 // Class for 64 bit register f1
  876 reg_class f1_reg(
  877     F1, F1_H
  878 );
  879 
  880 // Class for 64 bit register f2
  881 reg_class f2_reg(
  882     F2, F2_H
  883 );
  884 
  885 // Class for 64 bit register f3
  886 reg_class f3_reg(
  887     F3, F3_H
  888 );
  889 
  890 // class for vector register v1
  891 reg_class v1_reg(
  892     V1, V1_H, V1_J, V1_K
  893 );
  894 
  895 // class for vector register v2
  896 reg_class v2_reg(
  897     V2, V2_H, V2_J, V2_K
  898 );
  899 
  900 // class for vector register v3
  901 reg_class v3_reg(
  902     V3, V3_H, V3_J, V3_K
  903 );
  904 
  905 // class for vector register v4
  906 reg_class v4_reg(
  907     V4, V4_H, V4_J, V4_K
  908 );
  909 
  910 // class for vector register v5
  911 reg_class v5_reg(
  912     V5, V5_H, V5_J, V5_K
  913 );
  914 
  915 // class for vector register v6
  916 reg_class v6_reg(
  917     V6, V6_H, V6_J, V6_K
  918 );
  919 
  920 // class for vector register v7
  921 reg_class v7_reg(
  922     V7, V7_H, V7_J, V7_K
  923 );
  924 
  925 // class for vector register v8
  926 reg_class v8_reg(
  927     V8, V8_H, V8_J, V8_K
  928 );
  929 
  930 // class for vector register v9
  931 reg_class v9_reg(
  932     V9, V9_H, V9_J, V9_K
  933 );
  934 
  935 // class for vector register v10
  936 reg_class v10_reg(
  937     V10, V10_H, V10_J, V10_K
  938 );
  939 
  940 // class for vector register v11
  941 reg_class v11_reg(
  942     V11, V11_H, V11_J, V11_K
  943 );
  944 
  945 // class for condition codes
  946 reg_class reg_flags(RFLAGS);
  947 
  948 // Class for RVV v0 mask register
  949 // https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#53-vector-masking
  950 // The mask value used to control execution of a masked vector
  951 // instruction is always supplied by vector register v0.
  952 reg_class vmask_reg_v0 (
  953     V0
  954 );
  955 
  956 // Class for RVV mask registers
  957 // We need two more vmask registers to do the vector mask logical ops,
  958 // so define v30, v31 as mask register too.
  959 reg_class vmask_reg (
  960     V0,
  961     V30,
  962     V31
  963 );
  964 %}
  965 
  966 //----------DEFINITION BLOCK---------------------------------------------------
  967 // Define name --> value mappings to inform the ADLC of an integer valued name
  968 // Current support includes integer values in the range [0, 0x7FFFFFFF]
  969 // Format:
  970 //        int_def  <name>         ( <int_value>, <expression>);
  971 // Generated Code in ad_<arch>.hpp
  972 //        #define  <name>   (<expression>)
  973 //        // value == <int_value>
  974 // Generated code in ad_<arch>.cpp adlc_verification()
  975 //        assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
  976 //
  977 
  978 // we follow the ppc-aix port in using a simple cost model which ranks
  979 // register operations as cheap, memory ops as more expensive and
  980 // branches as most expensive. the first two have a low as well as a
  981 // normal cost. huge cost appears to be a way of saying don't do
  982 // something
  983 
  984 definitions %{
  985   // The default cost (of a register move instruction).
  986   int_def DEFAULT_COST         (  100,               100);
  987   int_def ALU_COST             (  100,  1 * DEFAULT_COST);          // unknown, const, arith, shift, slt,
  988                                                                     // multi, auipc, nop, logical, move
  989   int_def LOAD_COST            (  300,  3 * DEFAULT_COST);          // load, fpload
  990   int_def STORE_COST           (  100,  1 * DEFAULT_COST);          // store, fpstore
  991   int_def XFER_COST            (  300,  3 * DEFAULT_COST);          // mfc, mtc, fcvt, fmove, fcmp
  992   int_def FMVX_COST            (  100,  1 * DEFAULT_COST);          // shuffles with no conversion
  993   int_def BRANCH_COST          (  200,  2 * DEFAULT_COST);          // branch, jmp, call
  994   int_def IMUL_COST            ( 1000, 10 * DEFAULT_COST);          // imul
  995   int_def IDIVSI_COST          ( 3400, 34 * DEFAULT_COST);          // idivsi
  996   int_def IDIVDI_COST          ( 6600, 66 * DEFAULT_COST);          // idivdi
  997   int_def FMUL_SINGLE_COST     (  500,  5 * DEFAULT_COST);          // fmul, fmadd
  998   int_def FMUL_DOUBLE_COST     (  700,  7 * DEFAULT_COST);          // fmul, fmadd
  999   int_def FDIV_COST            ( 2000, 20 * DEFAULT_COST);          // fdiv
 1000   int_def FSQRT_COST           ( 2500, 25 * DEFAULT_COST);          // fsqrt
 1001   int_def VOLATILE_REF_COST    ( 1000, 10 * DEFAULT_COST);
 1002   int_def CACHE_MISS_COST      ( 2000, 20 * DEFAULT_COST);          // typicall cache miss penalty
 1003 %}
 1004 
 1005 
 1006 
 1007 //----------SOURCE BLOCK-------------------------------------------------------
 1008 // This is a block of C++ code which provides values, functions, and
 1009 // definitions necessary in the rest of the architecture description
 1010 
 1011 source_hpp %{
 1012 
 1013 #include "asm/macroAssembler.hpp"
 1014 #include "gc/shared/barrierSetAssembler.hpp"
 1015 #include "gc/shared/cardTable.hpp"
 1016 #include "gc/shared/cardTableBarrierSet.hpp"
 1017 #include "gc/shared/collectedHeap.hpp"
 1018 #include "opto/addnode.hpp"
 1019 #include "opto/convertnode.hpp"
 1020 #include "runtime/objectMonitor.hpp"
 1021 
 1022 extern RegMask _ANY_REG32_mask;
 1023 extern RegMask _ANY_REG_mask;
 1024 extern RegMask _PTR_REG_mask;
 1025 extern RegMask _NO_SPECIAL_REG32_mask;
 1026 extern RegMask _NO_SPECIAL_REG_mask;
 1027 extern RegMask _NO_SPECIAL_PTR_REG_mask;
 1028 extern RegMask _NO_SPECIAL_NO_FP_PTR_REG_mask;
 1029 
 1030 class CallStubImpl {
 1031 
 1032   //--------------------------------------------------------------
 1033   //---<  Used for optimization in Compile::shorten_branches  >---
 1034   //--------------------------------------------------------------
 1035 
 1036  public:
 1037   // Size of call trampoline stub.
 1038   static uint size_call_trampoline() {
 1039     return 0; // no call trampolines on this platform
 1040   }
 1041 
 1042   // number of relocations needed by a call trampoline stub
 1043   static uint reloc_call_trampoline() {
 1044     return 0; // no call trampolines on this platform
 1045   }
 1046 };
 1047 
 1048 class HandlerImpl {
 1049 
 1050  public:
 1051 
 1052   static int emit_deopt_handler(C2_MacroAssembler* masm);
 1053 
 1054   static uint size_deopt_handler() {
 1055     // count far call + j
 1056     return NativeInstruction::instruction_size + MacroAssembler::far_branch_size();
 1057   }
 1058 };
 1059 
 1060 class Node::PD {
 1061 public:
 1062   enum NodeFlags {
 1063     _last_flag = Node::_last_flag
 1064   };
 1065 };
 1066 
 1067 bool is_CAS(int opcode, bool maybe_volatile);
 1068 
 1069 // predicate controlling translation of CompareAndSwapX
 1070 bool needs_acquiring_load_reserved(const Node *load);
 1071 
 1072 // predicate controlling addressing modes
 1073 bool size_fits_all_mem_uses(AddPNode* addp, int shift);
 1074 %}
 1075 
 1076 source %{
 1077 
 1078 // Derived RegMask with conditionally allocatable registers
 1079 
 1080 RegMask _ANY_REG32_mask;
 1081 RegMask _ANY_REG_mask;
 1082 RegMask _PTR_REG_mask;
 1083 RegMask _NO_SPECIAL_REG32_mask;
 1084 RegMask _NO_SPECIAL_REG_mask;
 1085 RegMask _NO_SPECIAL_PTR_REG_mask;
 1086 RegMask _NO_SPECIAL_NO_FP_PTR_REG_mask;
 1087 
 1088 void reg_mask_init() {
 1089 
 1090   _ANY_REG32_mask.assignFrom(_ALL_REG32_mask);
 1091   _ANY_REG32_mask.remove(OptoReg::as_OptoReg(x0->as_VMReg()));
 1092 
 1093   _ANY_REG_mask.assignFrom(_ALL_REG_mask);
 1094   _ANY_REG_mask.subtract(_ZR_REG_mask);
 1095 
 1096   _PTR_REG_mask.assignFrom(_ALL_REG_mask);
 1097   _PTR_REG_mask.subtract(_ZR_REG_mask);
 1098 
 1099   _NO_SPECIAL_REG32_mask.assignFrom(_ALL_REG32_mask);
 1100   _NO_SPECIAL_REG32_mask.subtract(_NON_ALLOCATABLE_REG32_mask);
 1101 
 1102   _NO_SPECIAL_REG_mask.assignFrom(_ALL_REG_mask);
 1103   _NO_SPECIAL_REG_mask.subtract(_NON_ALLOCATABLE_REG_mask);
 1104 
 1105   _NO_SPECIAL_PTR_REG_mask.assignFrom(_ALL_REG_mask);
 1106   _NO_SPECIAL_PTR_REG_mask.subtract(_NON_ALLOCATABLE_REG_mask);
 1107 
 1108   // x27 is not allocatable when compressed oops is on and heapbase is not zero,
 1109   // compressed klass pointers doesn't use x27 when heapbase is zero.
 1110   if (UseCompressedOops && (CompressedOops::base() != nullptr)) {
 1111     _NO_SPECIAL_REG32_mask.remove(OptoReg::as_OptoReg(x27->as_VMReg()));
 1112     _NO_SPECIAL_REG_mask.remove(OptoReg::as_OptoReg(x27->as_VMReg()));
 1113     _NO_SPECIAL_PTR_REG_mask.remove(OptoReg::as_OptoReg(x27->as_VMReg()));
 1114   }
 1115 
 1116   // x8 is not allocatable when PreserveFramePointer is on
 1117   if (PreserveFramePointer) {
 1118     _NO_SPECIAL_REG32_mask.remove(OptoReg::as_OptoReg(x8->as_VMReg()));
 1119     _NO_SPECIAL_REG_mask.remove(OptoReg::as_OptoReg(x8->as_VMReg()));
 1120     _NO_SPECIAL_PTR_REG_mask.remove(OptoReg::as_OptoReg(x8->as_VMReg()));
 1121   }
 1122 
 1123   _NO_SPECIAL_NO_FP_PTR_REG_mask.assignFrom(_NO_SPECIAL_PTR_REG_mask);
 1124   _NO_SPECIAL_NO_FP_PTR_REG_mask.remove(OptoReg::as_OptoReg(x8->as_VMReg()));
 1125 }
 1126 
 1127 void PhaseOutput::pd_perform_mach_node_analysis() {
 1128 }
 1129 
 1130 int MachNode::pd_alignment_required() const {
 1131   return 1;
 1132 }
 1133 
 1134 int MachNode::compute_padding(int current_offset) const {
 1135   return 0;
 1136 }
 1137 
 1138 // is_CAS(int opcode, bool maybe_volatile)
 1139 //
 1140 // return true if opcode is one of the possible CompareAndSwapX
 1141 // values otherwise false.
 1142 bool is_CAS(int opcode, bool maybe_volatile)
 1143 {
 1144   switch (opcode) {
 1145     // We handle these
 1146     case Op_CompareAndSwapI:
 1147     case Op_CompareAndSwapL:
 1148     case Op_CompareAndSwapP:
 1149     case Op_CompareAndSwapN:
 1150     case Op_CompareAndSwapB:
 1151     case Op_CompareAndSwapS:
 1152     case Op_GetAndSetI:
 1153     case Op_GetAndSetL:
 1154     case Op_GetAndSetP:
 1155     case Op_GetAndSetN:
 1156     case Op_GetAndAddI:
 1157     case Op_GetAndAddL:
 1158       return true;
 1159     case Op_CompareAndExchangeI:
 1160     case Op_CompareAndExchangeN:
 1161     case Op_CompareAndExchangeB:
 1162     case Op_CompareAndExchangeS:
 1163     case Op_CompareAndExchangeL:
 1164     case Op_CompareAndExchangeP:
 1165     case Op_WeakCompareAndSwapB:
 1166     case Op_WeakCompareAndSwapS:
 1167     case Op_WeakCompareAndSwapI:
 1168     case Op_WeakCompareAndSwapL:
 1169     case Op_WeakCompareAndSwapP:
 1170     case Op_WeakCompareAndSwapN:
 1171       return maybe_volatile;
 1172     default:
 1173       return false;
 1174   }
 1175 }
 1176 
 1177 constexpr uint64_t MAJIK_DWORD = 0xabbaabbaabbaabbaull;
 1178 
 1179 // predicate controlling translation of CAS
 1180 //
 1181 // returns true if CAS needs to use an acquiring load otherwise false
 1182 bool needs_acquiring_load_reserved(const Node *n)
 1183 {
 1184   assert(n != nullptr && is_CAS(n->Opcode(), true), "expecting a compare and swap");
 1185 
 1186   LoadStoreNode* ldst = n->as_LoadStore();
 1187   if (n != nullptr && is_CAS(n->Opcode(), false)) {
 1188     assert(ldst != nullptr && ldst->trailing_membar() != nullptr, "expected trailing membar");
 1189   } else {
 1190     return ldst != nullptr && ldst->trailing_membar() != nullptr;
 1191   }
 1192   // so we can just return true here
 1193   return true;
 1194 }
 1195 #define __ masm->
 1196 
 1197 // advance declarations for helper functions to convert register
 1198 // indices to register objects
 1199 
 1200 // the ad file has to provide implementations of certain methods
 1201 // expected by the generic code
 1202 //
 1203 // REQUIRED FUNCTIONALITY
 1204 
 1205 //=============================================================================
 1206 
 1207 // !!!!! Special hack to get all types of calls to specify the byte offset
 1208 //       from the start of the call to the point where the return address
 1209 //       will point.
 1210 
 1211 int MachCallStaticJavaNode::ret_addr_offset()
 1212 {
 1213   return 3 * NativeInstruction::instruction_size; // auipc + ld + jalr
 1214 }
 1215 
 1216 int MachCallDynamicJavaNode::ret_addr_offset()
 1217 {
 1218   return NativeMovConstReg::movptr2_instruction_size + (3 * NativeInstruction::instruction_size); // movptr2, auipc + ld + jal
 1219 }
 1220 
 1221 int MachCallRuntimeNode::ret_addr_offset() {
 1222   // For address inside the code cache the call will be:
 1223   //   auipc + jalr
 1224   // For real runtime callouts it will be 8 instructions
 1225   // see riscv_enc_java_to_runtime
 1226   //   la(t0, retaddr)                                             ->  auipc + addi
 1227   //   sd(t0, Address(xthread, JavaThread::last_Java_pc_offset())) ->  sd
 1228   //   movptr(t1, addr, offset, t0)                                ->  lui + lui + slli + add
 1229   //   jalr(t1, offset)                                            ->  jalr
 1230   if (CodeCache::contains(_entry_point)) {
 1231     return 2 * NativeInstruction::instruction_size;
 1232   } else if (_entry_point == nullptr) {
 1233     // See CallLeafNoFPIndirect
 1234     return 1 * NativeInstruction::instruction_size;
 1235   } else {
 1236     return 8 * NativeInstruction::instruction_size;
 1237   }
 1238 }
 1239 
 1240 //
 1241 // Compute padding required for nodes which need alignment
 1242 //
 1243 
 1244 // With RVC a call instruction may get 2-byte aligned.
 1245 // The address of the call instruction needs to be 4-byte aligned to
 1246 // ensure that it does not span a cache line so that it can be patched.
 1247 int CallStaticJavaDirectNode::compute_padding(int current_offset) const
 1248 {
 1249   // to make sure the address of jal 4-byte aligned.
 1250   return align_up(current_offset, alignment_required()) - current_offset;
 1251 }
 1252 
 1253 // With RVC a call instruction may get 2-byte aligned.
 1254 // The address of the call instruction needs to be 4-byte aligned to
 1255 // ensure that it does not span a cache line so that it can be patched.
 1256 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const
 1257 {
 1258   // skip the movptr2 in MacroAssembler::ic_call():
 1259   // lui, lui, slli, add, addi
 1260   // Though movptr2() has already 4-byte aligned with or without RVC,
 1261   // We need to prevent from further changes by explicitly calculating the size.
 1262   current_offset += NativeMovConstReg::movptr2_instruction_size;
 1263   // to make sure the address of jal 4-byte aligned.
 1264   return align_up(current_offset, alignment_required()) - current_offset;
 1265 }
 1266 
 1267 int CallRuntimeDirectNode::compute_padding(int current_offset) const
 1268 {
 1269   return align_up(current_offset, alignment_required()) - current_offset;
 1270 }
 1271 
 1272 int CallLeafDirectNode::compute_padding(int current_offset) const
 1273 {
 1274   return align_up(current_offset, alignment_required()) - current_offset;
 1275 }
 1276 
 1277 int CallLeafDirectVectorNode::compute_padding(int current_offset) const
 1278 {
 1279   return align_up(current_offset, alignment_required()) - current_offset;
 1280 }
 1281 
 1282 int CallLeafNoFPIndirectNode::compute_padding(int current_offset) const
 1283 {
 1284   return align_up(current_offset, alignment_required()) - current_offset;
 1285 }
 1286 
 1287 int CallLeafNoFPDirectNode::compute_padding(int current_offset) const
 1288 {
 1289   return align_up(current_offset, alignment_required()) - current_offset;
 1290 }
 1291 
 1292 //=============================================================================
 1293 
 1294 #ifndef PRODUCT
 1295 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
 1296   assert_cond(st != nullptr);
 1297   st->print("BREAKPOINT");
 1298 }
 1299 #endif
 1300 
 1301 void MachBreakpointNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
 1302   __ ebreak();
 1303 }
 1304 
 1305 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
 1306   return MachNode::size(ra_);
 1307 }
 1308 
 1309 //=============================================================================
 1310 
 1311 #ifndef PRODUCT
 1312   void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const {
 1313     st->print("nop \t# %d bytes pad for loops and calls", _count);
 1314   }
 1315 #endif
 1316 
 1317   void MachNopNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc*) const {
 1318     Assembler::CompressibleScope scope(masm); // nops shall be 2-byte under RVC for alignment purposes.
 1319     for (int i = 0; i < _count; i++) {
 1320       __ nop();
 1321     }
 1322   }
 1323 
 1324   uint MachNopNode::size(PhaseRegAlloc*) const {
 1325     return _count * (UseRVC ? NativeInstruction::compressed_instruction_size : NativeInstruction::instruction_size);
 1326   }
 1327 
 1328 //=============================================================================
 1329 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::EMPTY;
 1330 
 1331 int ConstantTable::calculate_table_base_offset() const {
 1332   return 0;  // absolute addressing, no offset
 1333 }
 1334 
 1335 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
 1336 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
 1337   ShouldNotReachHere();
 1338 }
 1339 
 1340 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const {
 1341   // Empty encoding
 1342 }
 1343 
 1344 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
 1345   return 0;
 1346 }
 1347 
 1348 #ifndef PRODUCT
 1349 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
 1350   assert_cond(st != nullptr);
 1351   st->print("-- \t// MachConstantBaseNode (empty encoding)");
 1352 }
 1353 #endif
 1354 
 1355 #ifndef PRODUCT
 1356 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
 1357   assert_cond(st != nullptr && ra_ != nullptr);
 1358   Compile* C = ra_->C;
 1359 
 1360   int framesize = C->output()->frame_slots() << LogBytesPerInt;
 1361 
 1362   if (C->output()->need_stack_bang(framesize)) {
 1363     st->print("# stack bang size=%d\n\t", framesize);
 1364   }
 1365 
 1366   st->print("sub sp, sp, #%d\n\t", framesize);
 1367   st->print("sd  fp, [sp, #%d]\n\t", framesize - 2 * wordSize);
 1368   st->print("sd  ra, [sp, #%d]\n\t", framesize - wordSize);
 1369   if (PreserveFramePointer) { st->print("add fp, sp, #%d\n\t", framesize); }
 1370 
 1371   if (VerifyStackAtCalls) {
 1372     st->print("mv  t2, %ld\n\t", MAJIK_DWORD);
 1373     st->print("sd  t2, [sp, #%d]\n\t", framesize - 3 * wordSize);
 1374   }
 1375 
 1376   if (C->stub_function() == nullptr) {
 1377     st->print("ld  t0, [guard]\n\t");
 1378     st->print("membar LoadLoad\n\t");
 1379     st->print("ld  t1, [xthread, #thread_disarmed_guard_value_offset]\n\t");
 1380     st->print("beq t0, t1, skip\n\t");
 1381     st->print("jalr #nmethod_entry_barrier_stub\n\t");
 1382     st->print("j skip\n\t");
 1383     st->print("guard: int\n\t");
 1384     st->print("skip:\n\t");
 1385   }
 1386 }
 1387 #endif
 1388 
 1389 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
 1390   assert_cond(ra_ != nullptr);
 1391   Compile* C = ra_->C;
 1392 
 1393   __ verified_entry(C, 0);
 1394 
 1395   if (VerifyStackAtCalls) {
 1396     // n.b. frame size includes space for return pc and fp
 1397     const long framesize = C->output()->frame_size_in_bytes();
 1398     __ mv(t2, MAJIK_DWORD);
 1399     __ sd(t2, Address(sp, framesize - 3 * wordSize));
 1400   }
 1401 
 1402   if (C->stub_function() == nullptr) {
 1403     __ entry_barrier();
 1404   }
 1405 
 1406   if (!Compile::current()->output()->in_scratch_emit_size()) {
 1407     __ bind(*_verified_entry);
 1408   }
 1409 
 1410   C->output()->set_frame_complete(__ offset());
 1411 
 1412   if (C->has_mach_constant_base_node()) {
 1413     // NOTE: We set the table base offset here because users might be
 1414     // emitted before MachConstantBaseNode.
 1415     ConstantTable& constant_table = C->output()->constant_table();
 1416     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
 1417   }
 1418 }
 1419 
 1420 int MachPrologNode::reloc() const
 1421 {
 1422   return 0;
 1423 }
 1424 
 1425 //=============================================================================
 1426 
 1427 #ifndef PRODUCT
 1428 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
 1429   assert_cond(st != nullptr && ra_ != nullptr);
 1430   Compile* C = ra_->C;
 1431   assert_cond(C != nullptr);
 1432   int framesize = C->output()->frame_size_in_bytes();
 1433 
 1434   st->print("# pop frame %d\n\t", framesize);
 1435 
 1436   if (framesize == 0) {
 1437     st->print("ld  ra, [sp,#%d]\n\t", (2 * wordSize));
 1438     st->print("ld  fp, [sp,#%d]\n\t", (3 * wordSize));
 1439     st->print("add sp, sp, #%d\n\t", (2 * wordSize));
 1440   } else {
 1441     st->print("add  sp, sp, #%d\n\t", framesize);
 1442     st->print("ld  ra, [sp,#%d]\n\t", - 2 * wordSize);
 1443     st->print("ld  fp, [sp,#%d]\n\t", - wordSize);
 1444   }
 1445 
 1446   if (do_polling() && C->is_method_compilation()) {
 1447     st->print("# test polling word\n\t");
 1448     st->print("ld t0, [xthread,#%d]\n\t", in_bytes(JavaThread::polling_word_offset()));
 1449     st->print("bgtu sp, t0, #slow_path");
 1450   }
 1451 }
 1452 #endif
 1453 
 1454 void MachEpilogNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
 1455   assert_cond(ra_ != nullptr);
 1456   Compile* C = ra_->C;
 1457   assert_cond(C != nullptr);
 1458   int framesize = C->output()->frame_size_in_bytes();
 1459 
 1460   __ remove_frame(framesize);
 1461 
 1462   if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
 1463     __ reserved_stack_check();
 1464   }
 1465 
 1466   if (do_polling() && C->is_method_compilation()) {
 1467     Label dummy_label;
 1468     Label* code_stub = &dummy_label;
 1469     if (!C->output()->in_scratch_emit_size()) {
 1470       C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset());
 1471       C->output()->add_stub(stub);
 1472       code_stub = &stub->entry();
 1473     }
 1474     __ relocate(relocInfo::poll_return_type);
 1475     __ safepoint_poll(*code_stub, true /* at_return */, true /* in_nmethod */);
 1476   }
 1477 }
 1478 
 1479 int MachEpilogNode::reloc() const {
 1480   // Return number of relocatable values contained in this instruction.
 1481   return 1; // 1 for polling page.
 1482 }
 1483 const Pipeline * MachEpilogNode::pipeline() const {
 1484   return MachNode::pipeline_class();
 1485 }
 1486 
 1487 //=============================================================================
 1488 
 1489 // Figure out which register class each belongs in: rc_int, rc_float or
 1490 // rc_stack.
 1491 enum RC { rc_bad, rc_int, rc_float, rc_vector, rc_stack };
 1492 
 1493 static enum RC rc_class(OptoReg::Name reg) {
 1494 
 1495   if (reg == OptoReg::Bad) {
 1496     return rc_bad;
 1497   }
 1498 
 1499   // we have 30 int registers * 2 halves
 1500   // (t0 and t1 are omitted)
 1501   int slots_of_int_registers = Register::max_slots_per_register * (Register::number_of_registers - 2);
 1502   if (reg < slots_of_int_registers) {
 1503     return rc_int;
 1504   }
 1505 
 1506   // we have 32 float register * 2 halves
 1507   int slots_of_float_registers = FloatRegister::max_slots_per_register * FloatRegister::number_of_registers;
 1508   if (reg < slots_of_int_registers + slots_of_float_registers) {
 1509     return rc_float;
 1510   }
 1511 
 1512   // we have 32 vector register * 4 halves
 1513   int slots_of_vector_registers = VectorRegister::max_slots_per_register * VectorRegister::number_of_registers;
 1514   if (reg < slots_of_int_registers + slots_of_float_registers + slots_of_vector_registers) {
 1515     return rc_vector;
 1516   }
 1517 
 1518   // Between vector regs & stack is the flags regs.
 1519   assert(OptoReg::is_stack(reg), "blow up if spilling flags");
 1520 
 1521   return rc_stack;
 1522 }
 1523 
 1524 uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const {
 1525   assert_cond(ra_ != nullptr);
 1526   Compile* C = ra_->C;
 1527 
 1528   // Get registers to move.
 1529   OptoReg::Name src_hi = ra_->get_reg_second(in(1));
 1530   OptoReg::Name src_lo = ra_->get_reg_first(in(1));
 1531   OptoReg::Name dst_hi = ra_->get_reg_second(this);
 1532   OptoReg::Name dst_lo = ra_->get_reg_first(this);
 1533 
 1534   enum RC src_hi_rc = rc_class(src_hi);
 1535   enum RC src_lo_rc = rc_class(src_lo);
 1536   enum RC dst_hi_rc = rc_class(dst_hi);
 1537   enum RC dst_lo_rc = rc_class(dst_lo);
 1538 
 1539   assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register");
 1540 
 1541   if (src_hi != OptoReg::Bad && !bottom_type()->isa_pvectmask()) {
 1542     assert((src_lo & 1) == 0 && src_lo + 1 == src_hi &&
 1543            (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi,
 1544            "expected aligned-adjacent pairs");
 1545   }
 1546 
 1547   if (src_lo == dst_lo && src_hi == dst_hi) {
 1548     return 0;            // Self copy, no move.
 1549   }
 1550 
 1551   bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi &&
 1552               (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi;
 1553   int src_offset = ra_->reg2offset(src_lo);
 1554   int dst_offset = ra_->reg2offset(dst_lo);
 1555 
 1556   if (bottom_type()->isa_vect() != nullptr) {
 1557     uint ireg = ideal_reg();
 1558     if (ireg == Op_VecA && masm) {
 1559       int vector_reg_size_in_bytes = Matcher::scalable_vector_reg_size(T_BYTE);
 1560       if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
 1561         // stack to stack
 1562         __ spill_copy_vector_stack_to_stack(src_offset, dst_offset,
 1563                                             vector_reg_size_in_bytes);
 1564       } else if (src_lo_rc == rc_vector && dst_lo_rc == rc_stack) {
 1565         // vpr to stack
 1566         __ spill(as_VectorRegister(Matcher::_regEncode[src_lo]), ra_->reg2offset(dst_lo));
 1567       } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vector) {
 1568         // stack to vpr
 1569         __ unspill(as_VectorRegister(Matcher::_regEncode[dst_lo]), ra_->reg2offset(src_lo));
 1570       } else if (src_lo_rc == rc_vector && dst_lo_rc == rc_vector) {
 1571         // vpr to vpr
 1572         __ vsetvli_helper(T_BYTE, MaxVectorSize);
 1573         __ vmv_v_v(as_VectorRegister(Matcher::_regEncode[dst_lo]), as_VectorRegister(Matcher::_regEncode[src_lo]));
 1574       } else {
 1575         ShouldNotReachHere();
 1576       }
 1577     } else if (bottom_type()->isa_pvectmask() && masm) {
 1578       int vmask_size_in_bytes = Matcher::scalable_predicate_reg_slots() * 32 / 8;
 1579       if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
 1580         // stack to stack
 1581         __ spill_copy_vmask_stack_to_stack(src_offset, dst_offset,
 1582                                            vmask_size_in_bytes);
 1583       } else if (src_lo_rc == rc_vector && dst_lo_rc == rc_stack) {
 1584         // vmask to stack
 1585         __ spill_vmask(as_VectorRegister(Matcher::_regEncode[src_lo]), ra_->reg2offset(dst_lo));
 1586       } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vector) {
 1587         // stack to vmask
 1588         __ unspill_vmask(as_VectorRegister(Matcher::_regEncode[dst_lo]), ra_->reg2offset(src_lo));
 1589       } else if (src_lo_rc == rc_vector && dst_lo_rc == rc_vector) {
 1590         // vmask to vmask
 1591         __ vsetvli_helper(T_BYTE, MaxVectorSize >> 3);
 1592         __ vmv_v_v(as_VectorRegister(Matcher::_regEncode[dst_lo]), as_VectorRegister(Matcher::_regEncode[src_lo]));
 1593       } else {
 1594         ShouldNotReachHere();
 1595       }
 1596     }
 1597   } else if (masm != nullptr) {
 1598     switch (src_lo_rc) {
 1599       case rc_int:
 1600         if (dst_lo_rc == rc_int) {  // gpr --> gpr copy
 1601           if (!is64 && this->ideal_reg() != Op_RegI) { // zero extended for narrow oop or klass
 1602             __ zext(as_Register(Matcher::_regEncode[dst_lo]), as_Register(Matcher::_regEncode[src_lo]), 32);
 1603           } else {
 1604             __ mv(as_Register(Matcher::_regEncode[dst_lo]), as_Register(Matcher::_regEncode[src_lo]));
 1605           }
 1606         } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy
 1607           if (is64) {
 1608             __ fmv_d_x(as_FloatRegister(Matcher::_regEncode[dst_lo]),
 1609                        as_Register(Matcher::_regEncode[src_lo]));
 1610           } else {
 1611             __ fmv_w_x(as_FloatRegister(Matcher::_regEncode[dst_lo]),
 1612                        as_Register(Matcher::_regEncode[src_lo]));
 1613           }
 1614         } else {                    // gpr --> stack spill
 1615           assert(dst_lo_rc == rc_stack, "spill to bad register class");
 1616           __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset);
 1617         }
 1618         break;
 1619       case rc_float:
 1620         if (dst_lo_rc == rc_int) {  // fpr --> gpr copy
 1621           if (is64) {
 1622             __ fmv_x_d(as_Register(Matcher::_regEncode[dst_lo]),
 1623                        as_FloatRegister(Matcher::_regEncode[src_lo]));
 1624           } else {
 1625             __ fmv_x_w(as_Register(Matcher::_regEncode[dst_lo]),
 1626                        as_FloatRegister(Matcher::_regEncode[src_lo]));
 1627           }
 1628         } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy
 1629           if (is64) {
 1630             __ fmv_d(as_FloatRegister(Matcher::_regEncode[dst_lo]),
 1631                      as_FloatRegister(Matcher::_regEncode[src_lo]));
 1632           } else {
 1633             __ fmv_s(as_FloatRegister(Matcher::_regEncode[dst_lo]),
 1634                      as_FloatRegister(Matcher::_regEncode[src_lo]));
 1635           }
 1636         } else {                    // fpr --> stack spill
 1637           assert(dst_lo_rc == rc_stack, "spill to bad register class");
 1638           __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]),
 1639                    is64, dst_offset);
 1640         }
 1641         break;
 1642       case rc_stack:
 1643         if (dst_lo_rc == rc_int) {  // stack --> gpr load
 1644           if (this->ideal_reg() == Op_RegI) {
 1645             __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset);
 1646           } else { // // zero extended for narrow oop or klass
 1647             __ unspillu(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset);
 1648           }
 1649         } else if (dst_lo_rc == rc_float) { // stack --> fpr load
 1650           __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]),
 1651                      is64, src_offset);
 1652         } else {                    // stack --> stack copy
 1653           assert(dst_lo_rc == rc_stack, "spill to bad register class");
 1654           if (this->ideal_reg() == Op_RegI) {
 1655             __ unspill(t0, is64, src_offset);
 1656           } else { // zero extended for narrow oop or klass
 1657             __ unspillu(t0, is64, src_offset);
 1658           }
 1659           __ spill(t0, is64, dst_offset);
 1660         }
 1661         break;
 1662       default:
 1663         ShouldNotReachHere();
 1664     }
 1665   }
 1666 
 1667   if (st != nullptr) {
 1668     st->print("spill ");
 1669     if (src_lo_rc == rc_stack) {
 1670       st->print("[sp, #%d] -> ", src_offset);
 1671     } else {
 1672       st->print("%s -> ", Matcher::regName[src_lo]);
 1673     }
 1674     if (dst_lo_rc == rc_stack) {
 1675       st->print("[sp, #%d]", dst_offset);
 1676     } else {
 1677       st->print("%s", Matcher::regName[dst_lo]);
 1678     }
 1679     if (bottom_type()->isa_vect() && !bottom_type()->isa_pvectmask()) {
 1680       int vsize = 0;
 1681       if (ideal_reg() == Op_VecA) {
 1682         vsize = Matcher::scalable_vector_reg_size(T_BYTE) * 8;
 1683       } else {
 1684         ShouldNotReachHere();
 1685       }
 1686       st->print("\t# vector spill size = %d", vsize);
 1687     } else if (ideal_reg() == Op_RegVectMask) {
 1688       assert(Matcher::supports_scalable_vector(), "bad register type for spill");
 1689       int vsize = Matcher::scalable_predicate_reg_slots() * 32;
 1690       st->print("\t# vmask spill size = %d", vsize);
 1691     } else {
 1692       st->print("\t# spill size = %d", is64 ? 64 : 32);
 1693     }
 1694   }
 1695 
 1696   return 0;
 1697 }
 1698 
 1699 #ifndef PRODUCT
 1700 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
 1701   if (ra_ == nullptr) {
 1702     st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
 1703   } else {
 1704     implementation(nullptr, ra_, false, st);
 1705   }
 1706 }
 1707 #endif
 1708 
 1709 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
 1710   implementation(masm, ra_, false, nullptr);
 1711 }
 1712 
 1713 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
 1714   return MachNode::size(ra_);
 1715 }
 1716 
 1717 //=============================================================================
 1718 
 1719 #ifndef PRODUCT
 1720 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
 1721   assert_cond(ra_ != nullptr && st != nullptr);
 1722   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
 1723   int reg = ra_->get_reg_first(this);
 1724   st->print("add %s, sp, #%d\t# box lock",
 1725             Matcher::regName[reg], offset);
 1726 }
 1727 #endif
 1728 
 1729 void BoxLockNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
 1730   Assembler::IncompressibleScope scope(masm); // Fixed length: see BoxLockNode::size()
 1731 
 1732   assert_cond(ra_ != nullptr);
 1733   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
 1734   int reg    = ra_->get_encode(this);
 1735 
 1736   if (Assembler::is_simm12(offset)) {
 1737     __ addi(as_Register(reg), sp, offset);
 1738   } else {
 1739     __ li32(t0, offset);
 1740     __ add(as_Register(reg), sp, t0);
 1741   }
 1742 }
 1743 
 1744 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
 1745   // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
 1746   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
 1747 
 1748   if (Assembler::is_simm12(offset)) {
 1749     return NativeInstruction::instruction_size;
 1750   } else {
 1751     return 3 * NativeInstruction::instruction_size; // lui + addiw + add;
 1752   }
 1753 }
 1754 
 1755 //=============================================================================
 1756 
 1757 #ifndef PRODUCT
 1758 void MachVEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
 1759 {
 1760   Unimplemented();
 1761 }
 1762 #endif
 1763 
 1764 void MachVEPNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc* ra_) const
 1765 {
 1766   Unimplemented();
 1767 }
 1768 
 1769 //=============================================================================
 1770 
 1771 #ifndef PRODUCT
 1772 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
 1773 {
 1774   assert_cond(st != nullptr);
 1775   st->print_cr("# MachUEPNode");
 1776   st->print_cr("\tlwu t1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
 1777   st->print_cr("\tlwu t2, [t0      + CompiledICData::speculated_klass_offset()]\t# compressed klass");
 1778   st->print_cr("\tbeq t1, t2, ic_hit");
 1779   st->print_cr("\tj, SharedRuntime::_ic_miss_stub\t # Inline cache check");
 1780   st->print_cr("\tic_hit:");
 1781 }
 1782 #endif
 1783 
 1784 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const
 1785 {
 1786   // This is the unverified entry point.
 1787   __ ic_check(CodeEntryAlignment);
 1788 
 1789   // ic_check() aligns to CodeEntryAlignment >= InteriorEntryAlignment(min 16) > NativeInstruction::instruction_size(4).
 1790   assert(((__ offset()) % CodeEntryAlignment) == 0, "Misaligned verified entry point");
 1791 }
 1792 
 1793 // REQUIRED EMIT CODE
 1794 
 1795 //=============================================================================
 1796 
 1797 // Emit deopt handler code.
 1798 int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm)
 1799 {
 1800   address base = __ start_a_stub(size_deopt_handler());
 1801   if (base == nullptr) {
 1802     ciEnv::current()->record_failure("CodeCache is full");
 1803     return 0;  // CodeBuffer::expand failed
 1804   }
 1805   int offset = __ offset();
 1806 
 1807   Label start;
 1808   __ bind(start);
 1809 
 1810   __ far_call(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
 1811 
 1812   int entry_offset = __ offset();
 1813   __ j(start);
 1814 
 1815   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
 1816   assert(__ offset() - entry_offset >= NativePostCallNop::first_check_size,
 1817          "out of bounds read in post-call NOP check");
 1818   __ end_a_stub();
 1819   return entry_offset;
 1820 
 1821 }
 1822 // REQUIRED MATCHER CODE
 1823 
 1824 //=============================================================================
 1825 
 1826 bool Matcher::match_rule_supported(int opcode) {
 1827   if (!has_match_rule(opcode)) {
 1828     return false;
 1829   }
 1830 
 1831   switch (opcode) {
 1832     case Op_OnSpinWait:
 1833       return VM_Version::supports_on_spin_wait();
 1834     case Op_CacheWB:           // fall through
 1835     case Op_CacheWBPreSync:    // fall through
 1836     case Op_CacheWBPostSync:
 1837       if (!VM_Version::supports_data_cache_line_flush()) {
 1838         return false;
 1839       }
 1840       break;
 1841 
 1842     case Op_StrCompressedCopy: // fall through
 1843     case Op_StrInflatedCopy:   // fall through
 1844     case Op_CountPositives:    // fall through
 1845     case Op_EncodeISOArray:
 1846       return UseRVV;
 1847 
 1848     case Op_PopCountI:
 1849     case Op_PopCountL:
 1850       return UsePopCountInstruction;
 1851 
 1852     case Op_ReverseI:
 1853     case Op_ReverseL:
 1854       return UseZbkb;
 1855 
 1856     case Op_ReverseBytesI:
 1857     case Op_ReverseBytesL:
 1858     case Op_ReverseBytesS:
 1859     case Op_ReverseBytesUS:
 1860     case Op_RotateRight:
 1861     case Op_RotateLeft:
 1862     case Op_CountLeadingZerosI:
 1863     case Op_CountLeadingZerosL:
 1864     case Op_CountTrailingZerosI:
 1865     case Op_CountTrailingZerosL:
 1866       return UseZbb;
 1867 
 1868     case Op_FmaF:
 1869     case Op_FmaD:
 1870       return UseFMA;
 1871 
 1872     case Op_ConvHF2F:
 1873     case Op_ConvF2HF:
 1874       return VM_Version::supports_float16_float_conversion();
 1875     case Op_ReinterpretS2HF:
 1876     case Op_ReinterpretHF2S:
 1877       return UseZfh || UseZfhmin;
 1878     case Op_AddHF:
 1879     case Op_DivHF:
 1880     case Op_FmaHF:
 1881     case Op_MaxHF:
 1882     case Op_MinHF:
 1883     case Op_MulHF:
 1884     case Op_SqrtHF:
 1885     case Op_SubHF:
 1886       return UseZfh;
 1887 
 1888     case Op_CMoveP:
 1889     case Op_CMoveN:
 1890       return false;
 1891   }
 1892 
 1893   return true; // Per default match rules are supported.
 1894 }
 1895 
 1896 const RegMask* Matcher::predicate_reg_mask(void) {
 1897   return &_VMASK_REG_mask;
 1898 }
 1899 
 1900 // Vector calling convention not yet implemented.
 1901 bool Matcher::supports_vector_calling_convention(void) {
 1902   return EnableVectorSupport;
 1903 }
 1904 
 1905 OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
 1906   assert(EnableVectorSupport, "sanity");
 1907   assert(ideal_reg == Op_VecA, "sanity");
 1908   // check more info at https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc
 1909   int lo = V8_num;
 1910   int hi = V8_K_num;
 1911   return OptoRegPair(hi, lo);
 1912 }
 1913 
 1914 // Is this branch offset short enough that a short branch can be used?
 1915 //
 1916 // NOTE: If the platform does not provide any short branch variants, then
 1917 //       this method should return false for offset 0.
 1918 // |---label(L1)-----|
 1919 // |-----------------|
 1920 // |-----------------|----------eq: float-------------------
 1921 // |-----------------| // far_cmpD_branch   |   cmpD_branch
 1922 // |------- ---------|    feq;              |      feq;
 1923 // |-far_cmpD_branch-|    beqz done;        |      bnez L;
 1924 // |-----------------|    j L;              |
 1925 // |-----------------|    bind(done);       |
 1926 // |-----------------|--------------------------------------
 1927 // |-----------------| // so shortBrSize = br_size - 4;
 1928 // |-----------------| // so offs = offset - shortBrSize + 4;
 1929 // |---label(L2)-----|
 1930 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
 1931   // The passed offset is relative to address of the branch.
 1932   int shortBrSize = br_size - 4;
 1933   int offs = offset - shortBrSize + 4;
 1934   return (-4096 <= offs && offs < 4096);
 1935 }
 1936 
 1937 // Vector width in bytes.
 1938 int Matcher::vector_width_in_bytes(BasicType bt) {
 1939   if (UseRVV) {
 1940     // The MaxVectorSize should have been set by detecting RVV max vector register size when check UseRVV.
 1941     // MaxVectorSize == VM_Version::_initial_vector_length
 1942     int size = MaxVectorSize;
 1943     // Minimum 2 values in vector
 1944     if (size < 2 * type2aelembytes(bt)) size = 0;
 1945     // But never < 4
 1946     if (size < 4) size = 0;
 1947     return size;
 1948   }
 1949   return 0;
 1950 }
 1951 
 1952 // Limits on vector size (number of elements) loaded into vector.
 1953 int Matcher::max_vector_size(const BasicType bt) {
 1954   return vector_width_in_bytes(bt) / type2aelembytes(bt);
 1955 }
 1956 
 1957 int Matcher::min_vector_size(const BasicType bt) {
 1958   int size;
 1959   switch(bt) {
 1960     case T_BOOLEAN:
 1961       // Load/store a vector mask with only 2 elements for vector types
 1962       // such as "2I/2F/2L/2D".
 1963       size = 2;
 1964       break;
 1965     case T_BYTE:
 1966       // Generate a "4B" vector, to support vector cast between "8B/16B"
 1967       // and "4S/4I/4L/4F/4D".
 1968       size = 4;
 1969       break;
 1970     case T_SHORT:
 1971       // Generate a "2S" vector, to support vector cast between "4S/8S"
 1972       // and "2I/2L/2F/2D".
 1973       size = 2;
 1974       break;
 1975     default:
 1976       // Limit the min vector length to 64-bit.
 1977       size = 8 / type2aelembytes(bt);
 1978       // The number of elements in a vector should be at least 2.
 1979       size = MAX2(size, 2);
 1980   }
 1981 
 1982   int max_size = max_vector_size(bt);
 1983   return MIN2(size, max_size);
 1984 }
 1985 
 1986 int Matcher::max_vector_size_auto_vectorization(const BasicType bt) {
 1987   return Matcher::max_vector_size(bt);
 1988 }
 1989 
 1990 // Vector ideal reg.
 1991 uint Matcher::vector_ideal_reg(int len) {
 1992   assert(MaxVectorSize >= len, "");
 1993   if (UseRVV) {
 1994     return Op_VecA;
 1995   }
 1996 
 1997   ShouldNotReachHere();
 1998   return 0;
 1999 }
 2000 
 2001 int Matcher::scalable_vector_reg_size(const BasicType bt) {
 2002   return Matcher::max_vector_size(bt);
 2003 }
 2004 
 2005 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) {
 2006   ShouldNotReachHere(); // generic vector operands not supported
 2007   return nullptr;
 2008 }
 2009 
 2010 bool Matcher::is_reg2reg_move(MachNode* m) {
 2011   ShouldNotReachHere(); // generic vector operands not supported
 2012   return false;
 2013 }
 2014 
 2015 bool Matcher::is_register_biasing_candidate(const MachNode* mdef, int oper_index) {
 2016   return false;
 2017 }
 2018 
 2019 bool Matcher::is_generic_vector(MachOper* opnd) {
 2020   ShouldNotReachHere(); // generic vector operands not supported
 2021   return false;
 2022 }
 2023 
 2024 #ifdef ASSERT
 2025 // Return whether or not this register is ever used as an argument.
 2026 bool Matcher::can_be_java_arg(int reg)
 2027 {
 2028   return
 2029     reg ==  R10_num || reg == R10_H_num ||
 2030     reg ==  R11_num || reg == R11_H_num ||
 2031     reg ==  R12_num || reg == R12_H_num ||
 2032     reg ==  R13_num || reg == R13_H_num ||
 2033     reg ==  R14_num || reg == R14_H_num ||
 2034     reg ==  R15_num || reg == R15_H_num ||
 2035     reg ==  R16_num || reg == R16_H_num ||
 2036     reg ==  R17_num || reg == R17_H_num ||
 2037     reg ==  F10_num || reg == F10_H_num ||
 2038     reg ==  F11_num || reg == F11_H_num ||
 2039     reg ==  F12_num || reg == F12_H_num ||
 2040     reg ==  F13_num || reg == F13_H_num ||
 2041     reg ==  F14_num || reg == F14_H_num ||
 2042     reg ==  F15_num || reg == F15_H_num ||
 2043     reg ==  F16_num || reg == F16_H_num ||
 2044     reg ==  F17_num || reg == F17_H_num;
 2045 }
 2046 #endif
 2047 
 2048 uint Matcher::int_pressure_limit()
 2049 {
 2050   // A derived pointer is live at CallNode and then is flagged by RA
 2051   // as a spilled LRG. Spilling heuristics(Spill-USE) explicitly skip
 2052   // derived pointers and lastly fail to spill after reaching maximum
 2053   // number of iterations. Lowering the default pressure threshold to
 2054   // (_NO_SPECIAL_REG32_mask.size() minus 1) forces CallNode to become
 2055   // a high register pressure area of the code so that split_DEF can
 2056   // generate DefinitionSpillCopy for the derived pointer.
 2057   uint default_int_pressure_threshold = _NO_SPECIAL_REG32_mask.size() - 1;
 2058   if (!PreserveFramePointer) {
 2059     // When PreserveFramePointer is off, frame pointer is allocatable,
 2060     // but different from other SOC registers, it is excluded from
 2061     // fatproj's mask because its save type is No-Save. Decrease 1 to
 2062     // ensure high pressure at fatproj when PreserveFramePointer is off.
 2063     // See check_pressure_at_fatproj().
 2064     default_int_pressure_threshold--;
 2065   }
 2066   return (INTPRESSURE == -1) ? default_int_pressure_threshold : INTPRESSURE;
 2067 }
 2068 
 2069 uint Matcher::float_pressure_limit()
 2070 {
 2071   // _FLOAT_REG_mask is generated by adlc from the float_reg register class.
 2072   return (FLOATPRESSURE == -1) ? _FLOAT_REG_mask.size() : FLOATPRESSURE;
 2073 }
 2074 
 2075 const RegMask& Matcher::firstI_proj_mask() {
 2076   ShouldNotReachHere();
 2077   return RegMask::EMPTY;
 2078 }
 2079 
 2080 // Register for the second projection of an int pair
 2081 const RegMask& Matcher::secondI_proj_mask() {
 2082   ShouldNotReachHere();
 2083   return RegMask::EMPTY;
 2084 }
 2085 
 2086 // Register for the first projection of a long pair
 2087 const RegMask& Matcher::firstL_proj_mask() {
 2088   ShouldNotReachHere();
 2089   return RegMask::EMPTY;
 2090 }
 2091 
 2092 // Register for the second projection of a long pair
 2093 const RegMask& Matcher::secondL_proj_mask() {
 2094   ShouldNotReachHere();
 2095   return RegMask::EMPTY;
 2096 }
 2097 
 2098 bool size_fits_all_mem_uses(AddPNode* addp, int shift) {
 2099   assert_cond(addp != nullptr);
 2100   for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) {
 2101     Node* u = addp->fast_out(i);
 2102     if (u != nullptr && u->is_Mem()) {
 2103       int opsize = u->as_Mem()->memory_size();
 2104       assert(opsize > 0, "unexpected memory operand size");
 2105       if (u->as_Mem()->memory_size() != (1 << shift)) {
 2106         return false;
 2107       }
 2108     }
 2109   }
 2110   return true;
 2111 }
 2112 
 2113 // Binary src (Replicate scalar/immediate)
 2114 static bool is_vector_scalar_bitwise_pattern(Node* n, Node* m) {
 2115   if (n == nullptr || m == nullptr) {
 2116     return false;
 2117   }
 2118 
 2119   if (m->Opcode() != Op_Replicate) {
 2120     return false;
 2121   }
 2122 
 2123   switch (n->Opcode()) {
 2124     case Op_AndV:
 2125     case Op_OrV:
 2126     case Op_XorV:
 2127     case Op_AddVB:
 2128     case Op_AddVS:
 2129     case Op_AddVI:
 2130     case Op_AddVL:
 2131     case Op_SubVB:
 2132     case Op_SubVS:
 2133     case Op_SubVI:
 2134     case Op_SubVL:
 2135     case Op_MulVB:
 2136     case Op_MulVS:
 2137     case Op_MulVI:
 2138     case Op_MulVL: {
 2139       return true;
 2140     }
 2141     default:
 2142       return false;
 2143   }
 2144 }
 2145 
 2146 // (XorV src (Replicate m1))
 2147 // (XorVMask src (MaskAll m1))
 2148 static bool is_vector_bitwise_not_pattern(Node* n, Node* m) {
 2149   if (n != nullptr && m != nullptr) {
 2150     return (n->Opcode() == Op_XorV || n->Opcode() == Op_XorVMask) &&
 2151            VectorNode::is_all_ones_vector(m);
 2152   }
 2153   return false;
 2154 }
 2155 
 2156 // Should the Matcher clone input 'm' of node 'n'?
 2157 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
 2158   assert_cond(m != nullptr);
 2159   if (is_vshift_con_pattern(n, m) || // ShiftV src (ShiftCntV con)
 2160       is_vector_bitwise_not_pattern(n, m) ||
 2161       is_vector_scalar_bitwise_pattern(n, m) ||
 2162       is_encode_and_store_pattern(n, m)) {
 2163     mstack.push(m, Visit);
 2164     return true;
 2165   }
 2166   return false;
 2167 }
 2168 
 2169 // Should the Matcher clone shifts on addressing modes, expecting them
 2170 // to be subsumed into complex addressing expressions or compute them
 2171 // into registers?
 2172 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
 2173   return clone_base_plus_offset_address(m, mstack, address_visited);
 2174 }
 2175 
 2176 %}
 2177 
 2178 
 2179 
 2180 //----------ENCODING BLOCK-----------------------------------------------------
 2181 // This block specifies the encoding classes used by the compiler to
 2182 // output byte streams.  Encoding classes are parameterized macros
 2183 // used by Machine Instruction Nodes in order to generate the bit
 2184 // encoding of the instruction.  Operands specify their base encoding
 2185 // interface with the interface keyword.  There are currently
 2186 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
 2187 // COND_INTER.  REG_INTER causes an operand to generate a function
 2188 // which returns its register number when queried.  CONST_INTER causes
 2189 // an operand to generate a function which returns the value of the
 2190 // constant when queried.  MEMORY_INTER causes an operand to generate
 2191 // four functions which return the Base Register, the Index Register,
 2192 // the Scale Value, and the Offset Value of the operand when queried.
 2193 // COND_INTER causes an operand to generate six functions which return
 2194 // the encoding code (ie - encoding bits for the instruction)
 2195 // associated with each basic boolean condition for a conditional
 2196 // instruction.
 2197 //
 2198 // Instructions specify two basic values for encoding.  Again, a
 2199 // function is available to check if the constant displacement is an
 2200 // oop. They use the ins_encode keyword to specify their encoding
 2201 // classes (which must be a sequence of enc_class names, and their
 2202 // parameters, specified in the encoding block), and they use the
 2203 // opcode keyword to specify, in order, their primary, secondary, and
 2204 // tertiary opcode.  Only the opcode sections which a particular
 2205 // instruction needs for encoding need to be specified.
 2206 encode %{
 2207   // BEGIN Non-volatile memory access
 2208 
 2209   enc_class riscv_enc_mov_imm(iRegIorL dst, immIorL src) %{
 2210     int64_t con = (int64_t)$src$$constant;
 2211     Register dst_reg = as_Register($dst$$reg);
 2212     __ mv(dst_reg, con);
 2213   %}
 2214 
 2215   enc_class riscv_enc_mov_p(iRegP dst, immP src) %{
 2216     Register dst_reg = as_Register($dst$$reg);
 2217     address con = (address)$src$$constant;
 2218     if (con == nullptr || con == (address)1) {
 2219       ShouldNotReachHere();
 2220     } else {
 2221       relocInfo::relocType rtype = $src->constant_reloc();
 2222       if (rtype == relocInfo::oop_type) {
 2223         __ movoop(dst_reg, (jobject)con);
 2224       } else if (rtype == relocInfo::metadata_type) {
 2225         __ mov_metadata(dst_reg, (Metadata*)con);
 2226       } else {
 2227         assert(rtype == relocInfo::none || rtype == relocInfo::external_word_type, "unexpected reloc type");
 2228         __ mv(dst_reg, $src$$constant);
 2229       }
 2230     }
 2231   %}
 2232 
 2233   enc_class riscv_enc_mov_p1(iRegP dst) %{
 2234     Register dst_reg = as_Register($dst$$reg);
 2235     __ mv(dst_reg, 1);
 2236   %}
 2237 
 2238   enc_class riscv_enc_mov_n(iRegN dst, immN src) %{
 2239     Register dst_reg = as_Register($dst$$reg);
 2240     address con = (address)$src$$constant;
 2241     if (con == nullptr) {
 2242       ShouldNotReachHere();
 2243     } else {
 2244       relocInfo::relocType rtype = $src->constant_reloc();
 2245       assert(rtype == relocInfo::oop_type, "unexpected reloc type");
 2246       __ set_narrow_oop(dst_reg, (jobject)con);
 2247     }
 2248   %}
 2249 
 2250   enc_class riscv_enc_mov_zero(iRegNorP dst) %{
 2251     Register dst_reg = as_Register($dst$$reg);
 2252     __ mv(dst_reg, zr);
 2253   %}
 2254 
 2255   enc_class riscv_enc_mov_nk(iRegN dst, immNKlass src) %{
 2256     Register dst_reg = as_Register($dst$$reg);
 2257     address con = (address)$src$$constant;
 2258     if (con == nullptr) {
 2259       ShouldNotReachHere();
 2260     } else {
 2261       relocInfo::relocType rtype = $src->constant_reloc();
 2262       assert(rtype == relocInfo::metadata_type, "unexpected reloc type");
 2263       __ set_narrow_klass(dst_reg, (Klass *)con);
 2264     }
 2265   %}
 2266 
 2267   // compare and branch instruction encodings
 2268 
 2269   enc_class riscv_enc_j(label lbl) %{
 2270     Label* L = $lbl$$label;
 2271     __ j(*L);
 2272   %}
 2273 
 2274   enc_class riscv_enc_far_cmpULtGe_imm0_branch(cmpOpULtGe cmp, iRegIorL op1, label lbl) %{
 2275     Label* L = $lbl$$label;
 2276     switch ($cmp$$cmpcode) {
 2277       case(BoolTest::ge):
 2278         __ j(*L);
 2279         break;
 2280       case(BoolTest::lt):
 2281         break;
 2282       default:
 2283         Unimplemented();
 2284     }
 2285   %}
 2286 
 2287   // call instruction encodings
 2288 
 2289   enc_class riscv_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) %{
 2290     Register sub_reg = as_Register($sub$$reg);
 2291     Register super_reg = as_Register($super$$reg);
 2292     Register temp_reg = as_Register($temp$$reg);
 2293     Register result_reg = as_Register($result$$reg);
 2294     Register cr_reg = t1;
 2295 
 2296     Label miss;
 2297     Label done;
 2298     __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg,
 2299                                      nullptr, &miss, /*set_cond_codes*/ true);
 2300     if ($primary) {
 2301       __ mv(result_reg, zr);
 2302     } else {
 2303       __ mv(cr_reg, zr);
 2304       __ j(done);
 2305     }
 2306 
 2307     __ bind(miss);
 2308     if (!$primary) {
 2309       __ mv(cr_reg, 1);
 2310     }
 2311 
 2312     __ bind(done);
 2313   %}
 2314 
 2315   enc_class riscv_enc_java_static_call(method meth) %{
 2316     Assembler::IncompressibleScope scope(masm); // Fixed length: see ret_addr_offset
 2317 
 2318     address addr = (address)$meth$$method;
 2319     address call = nullptr;
 2320     assert_cond(addr != nullptr);
 2321     if (!_method) {
 2322       // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
 2323       call = __ reloc_call(Address(addr, relocInfo::runtime_call_type));
 2324       if (call == nullptr) {
 2325         ciEnv::current()->record_failure("CodeCache is full");
 2326         return;
 2327       }
 2328     } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) {
 2329       // The NOP here is purely to ensure that eliding a call to
 2330       // JVM_EnsureMaterializedForStackWalk doesn't change the code size.
 2331       __ nop();
 2332       __ nop();
 2333       __ nop();
 2334       __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)");
 2335     } else {
 2336       int method_index = resolved_method_index(masm);
 2337       RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
 2338                                                   : static_call_Relocation::spec(method_index);
 2339       call = __ reloc_call(Address(addr, rspec));
 2340       if (call == nullptr) {
 2341         ciEnv::current()->record_failure("CodeCache is full");
 2342         return;
 2343       }
 2344 
 2345       if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) {
 2346         // Calls of the same statically bound method can share
 2347         // a stub to the interpreter.
 2348         __ code()->shared_stub_to_interp_for(_method, call - (__ begin()));
 2349       } else {
 2350         // Emit stub for static call
 2351         address stub = CompiledDirectCall::emit_to_interp_stub(masm, call);
 2352         if (stub == nullptr) {
 2353           ciEnv::current()->record_failure("CodeCache is full");
 2354           return;
 2355         }
 2356       }
 2357     }
 2358 
 2359     __ post_call_nop();
 2360   %}
 2361 
 2362   enc_class riscv_enc_java_dynamic_call(method meth) %{
 2363     Assembler::IncompressibleScope scope(masm); // Fixed length: see ret_addr_offset
 2364     int method_index = resolved_method_index(masm);
 2365     address call = __ ic_call((address)$meth$$method, method_index);
 2366     if (call == nullptr) {
 2367       ciEnv::current()->record_failure("CodeCache is full");
 2368       return;
 2369     }
 2370 
 2371     __ post_call_nop();
 2372   %}
 2373 
 2374   enc_class riscv_enc_call_epilog() %{
 2375     if (VerifyStackAtCalls) {
 2376       // Check that stack depth is unchanged: find majik cookie on stack
 2377       int framesize = ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP, -3 * VMRegImpl::slots_per_word));
 2378       Label stack_ok;
 2379       __ ld(t1, Address(sp, framesize));
 2380       __ mv(t2, MAJIK_DWORD);
 2381       __ beq(t2, t1, stack_ok);
 2382       __ stop("MAJIK_DWORD not found");
 2383       __ bind(stack_ok);
 2384     }
 2385   %}
 2386 
 2387   enc_class riscv_enc_java_to_runtime(method meth) %{
 2388     Assembler::IncompressibleScope scope(masm); // Fixed length: see ret_addr_offset
 2389 
 2390     // Some calls to generated routines (arraycopy code) are scheduled by C2
 2391     // as runtime calls. if so we can call them using a far call (they will be
 2392     // in the code cache, thus in a reachable segment) otherwise we have to use
 2393     // a movptr+jalr pair which loads the absolute address into a register.
 2394     address entry = (address)$meth$$method;
 2395     if (CodeCache::contains(entry)) {
 2396       __ far_call(Address(entry, relocInfo::runtime_call_type));
 2397       __ post_call_nop();
 2398     } else {
 2399       Label retaddr;
 2400       // Make the anchor frame walkable
 2401       __ la(t0, retaddr);
 2402       __ sd(t0, Address(xthread, JavaThread::last_Java_pc_offset()));
 2403       int32_t offset = 0;
 2404       // No relocation needed
 2405       __ movptr(t1, entry, offset, t0); // lui + lui + slli + add
 2406       __ jalr(t1, offset);
 2407       __ bind(retaddr);
 2408       __ post_call_nop();
 2409     }
 2410   %}
 2411 
 2412   enc_class riscv_enc_tail_call(iRegP jump_target) %{
 2413     Register target_reg = as_Register($jump_target$$reg);
 2414     __ jr(target_reg);
 2415   %}
 2416 
 2417   enc_class riscv_enc_tail_jmp(iRegP jump_target) %{
 2418     Register target_reg = as_Register($jump_target$$reg);
 2419     // exception oop should be in x10
 2420     // ret addr has been popped into ra
 2421     // callee expects it in x13
 2422     __ mv(x13, ra);
 2423     __ jr(target_reg);
 2424   %}
 2425 
 2426   enc_class riscv_enc_rethrow() %{
 2427     __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub()));
 2428   %}
 2429 
 2430   enc_class riscv_enc_ret() %{
 2431     __ ret();
 2432   %}
 2433 
 2434 %}
 2435 
 2436 //----------FRAME--------------------------------------------------------------
 2437 // Definition of frame structure and management information.
 2438 //
 2439 //  S T A C K   L A Y O U T    Allocators stack-slot number
 2440 //                             |   (to get allocators register number
 2441 //  G  Owned by    |        |  v    add OptoReg::stack0())
 2442 //  r   CALLER     |        |
 2443 //  o     |        +--------+      pad to even-align allocators stack-slot
 2444 //  w     V        |  pad0  |        numbers; owned by CALLER
 2445 //  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
 2446 //  h     ^        |   in   |  5
 2447 //        |        |  args  |  4   Holes in incoming args owned by SELF
 2448 //  |     |        |        |  3
 2449 //  |     |        +--------+
 2450 //  V     |        | old out|      Empty on Intel, window on Sparc
 2451 //        |    old |preserve|      Must be even aligned.
 2452 //        |     SP-+--------+----> Matcher::_old_SP, even aligned
 2453 //        |        |   in   |  3   area for Intel ret address
 2454 //     Owned by    |preserve|      Empty on Sparc.
 2455 //       SELF      +--------+
 2456 //        |        |  pad2  |  2   pad to align old SP
 2457 //        |        +--------+  1
 2458 //        |        | locks  |  0
 2459 //        |        +--------+----> OptoReg::stack0(), even aligned
 2460 //        |        |  pad1  | 11   pad to align new SP
 2461 //        |        +--------+
 2462 //        |        |        | 10
 2463 //        |        | spills |  9   spills
 2464 //        V        |        |  8   (pad0 slot for callee)
 2465 //      -----------+--------+----> Matcher::_out_arg_limit, unaligned
 2466 //        ^        |  out   |  7
 2467 //        |        |  args  |  6   Holes in outgoing args owned by CALLEE
 2468 //     Owned by    +--------+
 2469 //      CALLEE     | new out|  6   Empty on Intel, window on Sparc
 2470 //        |    new |preserve|      Must be even-aligned.
 2471 //        |     SP-+--------+----> Matcher::_new_SP, even aligned
 2472 //        |        |        |
 2473 //
 2474 // Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
 2475 //         known from SELF's arguments and the Java calling convention.
 2476 //         Region 6-7 is determined per call site.
 2477 // Note 2: If the calling convention leaves holes in the incoming argument
 2478 //         area, those holes are owned by SELF.  Holes in the outgoing area
 2479 //         are owned by the CALLEE.  Holes should not be necessary in the
 2480 //         incoming area, as the Java calling convention is completely under
 2481 //         the control of the AD file.  Doubles can be sorted and packed to
 2482 //         avoid holes.  Holes in the outgoing arguments may be necessary for
 2483 //         varargs C calling conventions.
 2484 // Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
 2485 //         even aligned with pad0 as needed.
 2486 //         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
 2487 //           (the latter is true on Intel but is it false on RISCV?)
 2488 //         region 6-11 is even aligned; it may be padded out more so that
 2489 //         the region from SP to FP meets the minimum stack alignment.
 2490 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
 2491 //         alignment.  Region 11, pad1, may be dynamically extended so that
 2492 //         SP meets the minimum alignment.
 2493 
 2494 frame %{
 2495   // These three registers define part of the calling convention
 2496   // between compiled code and the interpreter.
 2497 
 2498   // Inline Cache Register or methodOop for I2C.
 2499   inline_cache_reg(R31);
 2500 
 2501   // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
 2502   cisc_spilling_operand_name(indOffset);
 2503 
 2504   // Number of stack slots consumed by locking an object
 2505   // generate Compile::sync_stack_slots
 2506   // VMRegImpl::slots_per_word = wordSize / stack_slot_size = 8 / 4 = 2
 2507   sync_stack_slots(1 * VMRegImpl::slots_per_word);
 2508 
 2509   // Compiled code's Frame Pointer
 2510   frame_pointer(R2);
 2511 
 2512   // Stack alignment requirement
 2513   stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
 2514 
 2515   // Number of outgoing stack slots killed above the out_preserve_stack_slots
 2516   // for calls to C.  Supports the var-args backing area for register parms.
 2517   varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes / BytesPerInt);
 2518 
 2519   // The after-PROLOG location of the return address.  Location of
 2520   // return address specifies a type (REG or STACK) and a number
 2521   // representing the register number (i.e. - use a register name) or
 2522   // stack slot.
 2523   // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
 2524   // Otherwise, it is above the locks and verification slot and alignment word
 2525   // TODO this may well be correct but need to check why that - 2 is there
 2526   // ppc port uses 0 but we definitely need to allow for fixed_slots
 2527   // which folds in the space used for monitors
 2528   return_addr(STACK - 2 +
 2529               align_up((Compile::current()->in_preserve_stack_slots() +
 2530                         Compile::current()->fixed_slots()),
 2531                        stack_alignment_in_slots()));
 2532 
 2533   // Location of compiled Java return values.  Same as C for now.
 2534   return_value
 2535   %{
 2536     assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL,
 2537            "only return normal values");
 2538 
 2539     static const int lo[Op_RegL + 1] = { // enum name
 2540       0,                                 // Op_Node
 2541       0,                                 // Op_Set
 2542       R10_num,                           // Op_RegN
 2543       R10_num,                           // Op_RegI
 2544       R10_num,                           // Op_RegP
 2545       F10_num,                           // Op_RegF
 2546       F10_num,                           // Op_RegD
 2547       R10_num                            // Op_RegL
 2548     };
 2549 
 2550     static const int hi[Op_RegL + 1] = { // enum name
 2551       0,                                 // Op_Node
 2552       0,                                 // Op_Set
 2553       OptoReg::Bad,                      // Op_RegN
 2554       OptoReg::Bad,                      // Op_RegI
 2555       R10_H_num,                         // Op_RegP
 2556       OptoReg::Bad,                      // Op_RegF
 2557       F10_H_num,                         // Op_RegD
 2558       R10_H_num                          // Op_RegL
 2559     };
 2560 
 2561     return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
 2562   %}
 2563 %}
 2564 
 2565 //----------ATTRIBUTES---------------------------------------------------------
 2566 //----------Operand Attributes-------------------------------------------------
 2567 op_attrib op_cost(1);        // Required cost attribute
 2568 
 2569 //----------Instruction Attributes---------------------------------------------
 2570 ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute
 2571 ins_attrib ins_size(32);        // Required size attribute (in bits)
 2572 ins_attrib ins_short_branch(0); // Required flag: is this instruction
 2573                                 // a non-matching short branch variant
 2574                                 // of some long branch?
 2575 ins_attrib ins_alignment(4);    // Required alignment attribute (must
 2576                                 // be a power of 2) specifies the
 2577                                 // alignment that some part of the
 2578                                 // instruction (not necessarily the
 2579                                 // start) requires.  If > 1, a
 2580                                 // compute_padding() function must be
 2581                                 // provided for the instruction
 2582 
 2583 // Whether this node is expanded during code emission into a sequence of
 2584 // instructions and the first instruction can perform an implicit null check.
 2585 ins_attrib ins_is_late_expanded_null_check_candidate(false);
 2586 
 2587 //----------OPERANDS-----------------------------------------------------------
 2588 // Operand definitions must precede instruction definitions for correct parsing
 2589 // in the ADLC because operands constitute user defined types which are used in
 2590 // instruction definitions.
 2591 
 2592 //----------Simple Operands----------------------------------------------------
 2593 
 2594 // Integer operands 32 bit
 2595 // 32 bit immediate
 2596 operand immI()
 2597 %{
 2598   match(ConI);
 2599 
 2600   op_cost(0);
 2601   format %{ %}
 2602   interface(CONST_INTER);
 2603 %}
 2604 
 2605 // 32 bit zero
 2606 operand immI0()
 2607 %{
 2608   predicate(n->get_int() == 0);
 2609   match(ConI);
 2610 
 2611   op_cost(0);
 2612   format %{ %}
 2613   interface(CONST_INTER);
 2614 %}
 2615 
 2616 // 32 bit unit increment
 2617 operand immI_1()
 2618 %{
 2619   predicate(n->get_int() == 1);
 2620   match(ConI);
 2621 
 2622   op_cost(0);
 2623   format %{ %}
 2624   interface(CONST_INTER);
 2625 %}
 2626 
 2627 // 32 bit unit decrement
 2628 operand immI_M1()
 2629 %{
 2630   predicate(n->get_int() == -1);
 2631   match(ConI);
 2632 
 2633   op_cost(0);
 2634   format %{ %}
 2635   interface(CONST_INTER);
 2636 %}
 2637 
 2638 // Unsigned Integer Immediate:  6-bit int, greater than 32
 2639 operand uimmI6_ge32() %{
 2640   predicate(((unsigned int)(n->get_int()) < 64) && (n->get_int() >= 32));
 2641   match(ConI);
 2642   op_cost(0);
 2643   format %{ %}
 2644   interface(CONST_INTER);
 2645 %}
 2646 
 2647 operand immI_le_4()
 2648 %{
 2649   predicate(n->get_int() <= 4);
 2650   match(ConI);
 2651 
 2652   op_cost(0);
 2653   format %{ %}
 2654   interface(CONST_INTER);
 2655 %}
 2656 
 2657 operand immI_4()
 2658 %{
 2659   predicate(n->get_int() == 4);
 2660   match(ConI);
 2661 
 2662   op_cost(0);
 2663   format %{ %}
 2664   interface(CONST_INTER);
 2665 %}
 2666 
 2667 operand immI_16()
 2668 %{
 2669   predicate(n->get_int() == 16);
 2670   match(ConI);
 2671   op_cost(0);
 2672   format %{ %}
 2673   interface(CONST_INTER);
 2674 %}
 2675 
 2676 operand immI_24()
 2677 %{
 2678   predicate(n->get_int() == 24);
 2679   match(ConI);
 2680   op_cost(0);
 2681   format %{ %}
 2682   interface(CONST_INTER);
 2683 %}
 2684 
 2685 operand immI_31()
 2686 %{
 2687   predicate(n->get_int() == 31);
 2688   match(ConI);
 2689 
 2690   op_cost(0);
 2691   format %{ %}
 2692   interface(CONST_INTER);
 2693 %}
 2694 
 2695 operand immI_63()
 2696 %{
 2697   predicate(n->get_int() == 63);
 2698   match(ConI);
 2699 
 2700   op_cost(0);
 2701   format %{ %}
 2702   interface(CONST_INTER);
 2703 %}
 2704 
 2705 // 32 bit integer valid for add immediate
 2706 operand immIAdd()
 2707 %{
 2708   predicate(Assembler::is_simm12((int64_t)n->get_int()));
 2709   match(ConI);
 2710   op_cost(0);
 2711   format %{ %}
 2712   interface(CONST_INTER);
 2713 %}
 2714 
 2715 // 32 bit integer valid for sub immediate
 2716 operand immISub()
 2717 %{
 2718   predicate(Assembler::is_simm12(-(int64_t)n->get_int()));
 2719   match(ConI);
 2720   op_cost(0);
 2721   format %{ %}
 2722   interface(CONST_INTER);
 2723 %}
 2724 
 2725 // 5 bit signed value.
 2726 operand immI5()
 2727 %{
 2728   predicate(n->get_int() <= 15 && n->get_int() >= -16);
 2729   match(ConI);
 2730 
 2731   op_cost(0);
 2732   format %{ %}
 2733   interface(CONST_INTER);
 2734 %}
 2735 
 2736 // 5 bit signed value (simm5)
 2737 operand immL5()
 2738 %{
 2739   predicate(n->get_long() <= 15 && n->get_long() >= -16);
 2740   match(ConL);
 2741 
 2742   op_cost(0);
 2743   format %{ %}
 2744   interface(CONST_INTER);
 2745 %}
 2746 
 2747 // Integer operands 64 bit
 2748 // 64 bit immediate
 2749 operand immL()
 2750 %{
 2751   match(ConL);
 2752 
 2753   op_cost(0);
 2754   format %{ %}
 2755   interface(CONST_INTER);
 2756 %}
 2757 
 2758 // 64 bit zero
 2759 operand immL0()
 2760 %{
 2761   predicate(n->get_long() == 0);
 2762   match(ConL);
 2763 
 2764   op_cost(0);
 2765   format %{ %}
 2766   interface(CONST_INTER);
 2767 %}
 2768 
 2769 // Pointer operands
 2770 // Pointer Immediate
 2771 operand immP()
 2772 %{
 2773   match(ConP);
 2774 
 2775   op_cost(0);
 2776   format %{ %}
 2777   interface(CONST_INTER);
 2778 %}
 2779 
 2780 // Null Pointer Immediate
 2781 operand immP0()
 2782 %{
 2783   predicate(n->get_ptr() == 0);
 2784   match(ConP);
 2785 
 2786   op_cost(0);
 2787   format %{ %}
 2788   interface(CONST_INTER);
 2789 %}
 2790 
 2791 // Pointer Immediate One
 2792 // this is used in object initialization (initial object header)
 2793 operand immP_1()
 2794 %{
 2795   predicate(n->get_ptr() == 1);
 2796   match(ConP);
 2797 
 2798   op_cost(0);
 2799   format %{ %}
 2800   interface(CONST_INTER);
 2801 %}
 2802 
 2803 // Int Immediate: low 16-bit mask
 2804 operand immI_16bits()
 2805 %{
 2806   predicate(n->get_int() == 0xFFFF);
 2807   match(ConI);
 2808   op_cost(0);
 2809   format %{ %}
 2810   interface(CONST_INTER);
 2811 %}
 2812 
 2813 operand immIpowerOf2() %{
 2814   predicate(is_power_of_2((juint)(n->get_int())));
 2815   match(ConI);
 2816   op_cost(0);
 2817   format %{ %}
 2818   interface(CONST_INTER);
 2819 %}
 2820 
 2821 // Long Immediate: low 32-bit mask
 2822 operand immL_32bits()
 2823 %{
 2824   predicate(n->get_long() == 0xFFFFFFFFL);
 2825   match(ConL);
 2826   op_cost(0);
 2827   format %{ %}
 2828   interface(CONST_INTER);
 2829 %}
 2830 
 2831 // 64 bit unit decrement
 2832 operand immL_M1()
 2833 %{
 2834   predicate(n->get_long() == -1);
 2835   match(ConL);
 2836 
 2837   op_cost(0);
 2838   format %{ %}
 2839   interface(CONST_INTER);
 2840 %}
 2841 
 2842 
 2843 // 64 bit integer valid for add immediate
 2844 operand immLAdd()
 2845 %{
 2846   predicate(Assembler::is_simm12(n->get_long()));
 2847   match(ConL);
 2848   op_cost(0);
 2849   format %{ %}
 2850   interface(CONST_INTER);
 2851 %}
 2852 
 2853 // 64 bit integer valid for sub immediate
 2854 operand immLSub()
 2855 %{
 2856   predicate(Assembler::is_simm12(-(n->get_long())));
 2857   match(ConL);
 2858   op_cost(0);
 2859   format %{ %}
 2860   interface(CONST_INTER);
 2861 %}
 2862 
 2863 // Narrow pointer operands
 2864 // Narrow Pointer Immediate
 2865 operand immN()
 2866 %{
 2867   match(ConN);
 2868 
 2869   op_cost(0);
 2870   format %{ %}
 2871   interface(CONST_INTER);
 2872 %}
 2873 
 2874 // Narrow Null Pointer Immediate
 2875 operand immN0()
 2876 %{
 2877   predicate(n->get_narrowcon() == 0);
 2878   match(ConN);
 2879 
 2880   op_cost(0);
 2881   format %{ %}
 2882   interface(CONST_INTER);
 2883 %}
 2884 
 2885 operand immNKlass()
 2886 %{
 2887   match(ConNKlass);
 2888 
 2889   op_cost(0);
 2890   format %{ %}
 2891   interface(CONST_INTER);
 2892 %}
 2893 
 2894 // Float and Double operands
 2895 // Double Immediate
 2896 operand immD()
 2897 %{
 2898   match(ConD);
 2899   op_cost(0);
 2900   format %{ %}
 2901   interface(CONST_INTER);
 2902 %}
 2903 
 2904 // Double Immediate: +0.0d
 2905 operand immD0()
 2906 %{
 2907   predicate(jlong_cast(n->getd()) == 0);
 2908   match(ConD);
 2909 
 2910   op_cost(0);
 2911   format %{ %}
 2912   interface(CONST_INTER);
 2913 %}
 2914 
 2915 // Float Immediate
 2916 operand immF()
 2917 %{
 2918   match(ConF);
 2919   op_cost(0);
 2920   format %{ %}
 2921   interface(CONST_INTER);
 2922 %}
 2923 
 2924 // Float Immediate: +0.0f.
 2925 operand immF0()
 2926 %{
 2927   predicate(jint_cast(n->getf()) == 0);
 2928   match(ConF);
 2929 
 2930   op_cost(0);
 2931   format %{ %}
 2932   interface(CONST_INTER);
 2933 %}
 2934 
 2935 // Half Float Immediate
 2936 operand immH()
 2937 %{
 2938   match(ConH);
 2939 
 2940   op_cost(0);
 2941   format %{ %}
 2942   interface(CONST_INTER);
 2943 %}
 2944 
 2945 // Half Float Immediate: +0.0f.
 2946 operand immH0()
 2947 %{
 2948   predicate(jint_cast(n->geth()) == 0);
 2949   match(ConH);
 2950 
 2951   op_cost(0);
 2952   format %{ %}
 2953   interface(CONST_INTER);
 2954 %}
 2955 
 2956 operand immIOffset()
 2957 %{
 2958   predicate(Assembler::is_simm12(n->get_int()));
 2959   match(ConI);
 2960   op_cost(0);
 2961   format %{ %}
 2962   interface(CONST_INTER);
 2963 %}
 2964 
 2965 operand immLOffset()
 2966 %{
 2967   predicate(Assembler::is_simm12(n->get_long()));
 2968   match(ConL);
 2969   op_cost(0);
 2970   format %{ %}
 2971   interface(CONST_INTER);
 2972 %}
 2973 
 2974 // Scale values
 2975 operand immIScale()
 2976 %{
 2977   predicate(1 <= n->get_int() && (n->get_int() <= 3));
 2978   match(ConI);
 2979 
 2980   op_cost(0);
 2981   format %{ %}
 2982   interface(CONST_INTER);
 2983 %}
 2984 
 2985 // Integer 32 bit Register Operands
 2986 operand iRegI()
 2987 %{
 2988   constraint(ALLOC_IN_RC(any_reg32));
 2989   match(RegI);
 2990   match(iRegINoSp);
 2991   op_cost(0);
 2992   format %{ %}
 2993   interface(REG_INTER);
 2994 %}
 2995 
 2996 // Integer 32 bit Register not Special
 2997 operand iRegINoSp()
 2998 %{
 2999   constraint(ALLOC_IN_RC(no_special_reg32));
 3000   match(RegI);
 3001   op_cost(0);
 3002   format %{ %}
 3003   interface(REG_INTER);
 3004 %}
 3005 
 3006 // Register R10 only
 3007 operand iRegI_R10()
 3008 %{
 3009   constraint(ALLOC_IN_RC(int_r10_reg));
 3010   match(RegI);
 3011   match(iRegINoSp);
 3012   op_cost(0);
 3013   format %{ %}
 3014   interface(REG_INTER);
 3015 %}
 3016 
 3017 // Register R12 only
 3018 operand iRegI_R12()
 3019 %{
 3020   constraint(ALLOC_IN_RC(int_r12_reg));
 3021   match(RegI);
 3022   match(iRegINoSp);
 3023   op_cost(0);
 3024   format %{ %}
 3025   interface(REG_INTER);
 3026 %}
 3027 
 3028 // Register R13 only
 3029 operand iRegI_R13()
 3030 %{
 3031   constraint(ALLOC_IN_RC(int_r13_reg));
 3032   match(RegI);
 3033   match(iRegINoSp);
 3034   op_cost(0);
 3035   format %{ %}
 3036   interface(REG_INTER);
 3037 %}
 3038 
 3039 // Register R14 only
 3040 operand iRegI_R14()
 3041 %{
 3042   constraint(ALLOC_IN_RC(int_r14_reg));
 3043   match(RegI);
 3044   match(iRegINoSp);
 3045   op_cost(0);
 3046   format %{ %}
 3047   interface(REG_INTER);
 3048 %}
 3049 
 3050 // Integer 64 bit Register Operands
 3051 operand iRegL()
 3052 %{
 3053   constraint(ALLOC_IN_RC(any_reg));
 3054   match(RegL);
 3055   match(iRegLNoSp);
 3056   op_cost(0);
 3057   format %{ %}
 3058   interface(REG_INTER);
 3059 %}
 3060 
 3061 // Integer 64 bit Register not Special
 3062 operand iRegLNoSp()
 3063 %{
 3064   constraint(ALLOC_IN_RC(no_special_reg));
 3065   match(RegL);
 3066   match(iRegL_R10);
 3067   format %{ %}
 3068   interface(REG_INTER);
 3069 %}
 3070 
 3071 // Long 64 bit Register R29 only
 3072 operand iRegL_R29()
 3073 %{
 3074   constraint(ALLOC_IN_RC(r29_reg));
 3075   match(RegL);
 3076   match(iRegLNoSp);
 3077   op_cost(0);
 3078   format %{ %}
 3079   interface(REG_INTER);
 3080 %}
 3081 
 3082 // Long 64 bit Register R30 only
 3083 operand iRegL_R30()
 3084 %{
 3085   constraint(ALLOC_IN_RC(r30_reg));
 3086   match(RegL);
 3087   match(iRegLNoSp);
 3088   op_cost(0);
 3089   format %{ %}
 3090   interface(REG_INTER);
 3091 %}
 3092 
 3093 // Pointer Register Operands
 3094 // Pointer Register
 3095 operand iRegP()
 3096 %{
 3097   constraint(ALLOC_IN_RC(ptr_reg));
 3098   match(RegP);
 3099   match(iRegPNoSp);
 3100   match(iRegP_R10);
 3101   match(iRegP_R15);
 3102   match(javaThread_RegP);
 3103   op_cost(0);
 3104   format %{ %}
 3105   interface(REG_INTER);
 3106 %}
 3107 
 3108 // Pointer 64 bit Register not Special
 3109 operand iRegPNoSp()
 3110 %{
 3111   constraint(ALLOC_IN_RC(no_special_ptr_reg));
 3112   match(RegP);
 3113   op_cost(0);
 3114   format %{ %}
 3115   interface(REG_INTER);
 3116 %}
 3117 
 3118 // This operand is not allowed to use fp even if
 3119 // fp is not used to hold the frame pointer.
 3120 operand iRegPNoSpNoFp()
 3121 %{
 3122   constraint(ALLOC_IN_RC(no_special_no_fp_ptr_reg));
 3123   match(RegP);
 3124   match(iRegPNoSp);
 3125   op_cost(0);
 3126   format %{ %}
 3127   interface(REG_INTER);
 3128 %}
 3129 
 3130 operand iRegP_R10()
 3131 %{
 3132   constraint(ALLOC_IN_RC(r10_reg));
 3133   match(RegP);
 3134   // match(iRegP);
 3135   match(iRegPNoSp);
 3136   op_cost(0);
 3137   format %{ %}
 3138   interface(REG_INTER);
 3139 %}
 3140 
 3141 // Pointer 64 bit Register R11 only
 3142 operand iRegP_R11()
 3143 %{
 3144   constraint(ALLOC_IN_RC(r11_reg));
 3145   match(RegP);
 3146   match(iRegPNoSp);
 3147   op_cost(0);
 3148   format %{ %}
 3149   interface(REG_INTER);
 3150 %}
 3151 
 3152 operand iRegP_R12()
 3153 %{
 3154   constraint(ALLOC_IN_RC(r12_reg));
 3155   match(RegP);
 3156   // match(iRegP);
 3157   match(iRegPNoSp);
 3158   op_cost(0);
 3159   format %{ %}
 3160   interface(REG_INTER);
 3161 %}
 3162 
 3163 // Pointer 64 bit Register R13 only
 3164 operand iRegP_R13()
 3165 %{
 3166   constraint(ALLOC_IN_RC(r13_reg));
 3167   match(RegP);
 3168   match(iRegPNoSp);
 3169   op_cost(0);
 3170   format %{ %}
 3171   interface(REG_INTER);
 3172 %}
 3173 
 3174 operand iRegP_R14()
 3175 %{
 3176   constraint(ALLOC_IN_RC(r14_reg));
 3177   match(RegP);
 3178   // match(iRegP);
 3179   match(iRegPNoSp);
 3180   op_cost(0);
 3181   format %{ %}
 3182   interface(REG_INTER);
 3183 %}
 3184 
 3185 operand iRegP_R15()
 3186 %{
 3187   constraint(ALLOC_IN_RC(r15_reg));
 3188   match(RegP);
 3189   // match(iRegP);
 3190   match(iRegPNoSp);
 3191   op_cost(0);
 3192   format %{ %}
 3193   interface(REG_INTER);
 3194 %}
 3195 
 3196 operand iRegP_R16()
 3197 %{
 3198   constraint(ALLOC_IN_RC(r16_reg));
 3199   match(RegP);
 3200   match(iRegPNoSp);
 3201   op_cost(0);
 3202   format %{ %}
 3203   interface(REG_INTER);
 3204 %}
 3205 
 3206 // Pointer 64 bit Register R28 only
 3207 operand iRegP_R28()
 3208 %{
 3209   constraint(ALLOC_IN_RC(r28_reg));
 3210   match(RegP);
 3211   match(iRegPNoSp);
 3212   op_cost(0);
 3213   format %{ %}
 3214   interface(REG_INTER);
 3215 %}
 3216 
 3217 // Pointer 64 bit Register R30 only
 3218 operand iRegP_R30()
 3219 %{
 3220   constraint(ALLOC_IN_RC(r30_reg));
 3221   match(RegP);
 3222   match(iRegPNoSp);
 3223   op_cost(0);
 3224   format %{ %}
 3225   interface(REG_INTER);
 3226 %}
 3227 
 3228 // Pointer 64 bit Register R31 only
 3229 operand iRegP_R31()
 3230 %{
 3231   constraint(ALLOC_IN_RC(r31_reg));
 3232   match(RegP);
 3233   match(iRegPNoSp);
 3234   op_cost(0);
 3235   format %{ %}
 3236   interface(REG_INTER);
 3237 %}
 3238 
 3239 // Pointer Register Operands
 3240 // Narrow Pointer Register
 3241 operand iRegN()
 3242 %{
 3243   constraint(ALLOC_IN_RC(any_reg32));
 3244   match(RegN);
 3245   match(iRegNNoSp);
 3246   op_cost(0);
 3247   format %{ %}
 3248   interface(REG_INTER);
 3249 %}
 3250 
 3251 // Integer 64 bit Register not Special
 3252 operand iRegNNoSp()
 3253 %{
 3254   constraint(ALLOC_IN_RC(no_special_reg32));
 3255   match(RegN);
 3256   op_cost(0);
 3257   format %{ %}
 3258   interface(REG_INTER);
 3259 %}
 3260 
 3261 // Long 64 bit Register R10 only
 3262 operand iRegL_R10()
 3263 %{
 3264   constraint(ALLOC_IN_RC(r10_reg));
 3265   match(RegL);
 3266   match(iRegLNoSp);
 3267   op_cost(0);
 3268   format %{ %}
 3269   interface(REG_INTER);
 3270 %}
 3271 
 3272 // Float Register
 3273 // Float register operands
 3274 operand fRegF()
 3275 %{
 3276   constraint(ALLOC_IN_RC(float_reg));
 3277   match(RegF);
 3278 
 3279   op_cost(0);
 3280   format %{ %}
 3281   interface(REG_INTER);
 3282 %}
 3283 
 3284 // Double Register
 3285 // Double register operands
 3286 operand fRegD()
 3287 %{
 3288   constraint(ALLOC_IN_RC(double_reg));
 3289   match(RegD);
 3290 
 3291   op_cost(0);
 3292   format %{ %}
 3293   interface(REG_INTER);
 3294 %}
 3295 
 3296 // Generic vector class. This will be used for
 3297 // all vector operands.
 3298 operand vReg()
 3299 %{
 3300   constraint(ALLOC_IN_RC(vectora_reg));
 3301   match(VecA);
 3302   op_cost(0);
 3303   format %{ %}
 3304   interface(REG_INTER);
 3305 %}
 3306 
 3307 operand vReg_V1()
 3308 %{
 3309   constraint(ALLOC_IN_RC(v1_reg));
 3310   match(VecA);
 3311   match(vReg);
 3312   op_cost(0);
 3313   format %{ %}
 3314   interface(REG_INTER);
 3315 %}
 3316 
 3317 operand vReg_V2()
 3318 %{
 3319   constraint(ALLOC_IN_RC(v2_reg));
 3320   match(VecA);
 3321   match(vReg);
 3322   op_cost(0);
 3323   format %{ %}
 3324   interface(REG_INTER);
 3325 %}
 3326 
 3327 operand vReg_V3()
 3328 %{
 3329   constraint(ALLOC_IN_RC(v3_reg));
 3330   match(VecA);
 3331   match(vReg);
 3332   op_cost(0);
 3333   format %{ %}
 3334   interface(REG_INTER);
 3335 %}
 3336 
 3337 operand vReg_V4()
 3338 %{
 3339   constraint(ALLOC_IN_RC(v4_reg));
 3340   match(VecA);
 3341   match(vReg);
 3342   op_cost(0);
 3343   format %{ %}
 3344   interface(REG_INTER);
 3345 %}
 3346 
 3347 operand vReg_V5()
 3348 %{
 3349   constraint(ALLOC_IN_RC(v5_reg));
 3350   match(VecA);
 3351   match(vReg);
 3352   op_cost(0);
 3353   format %{ %}
 3354   interface(REG_INTER);
 3355 %}
 3356 
 3357 operand vReg_V6()
 3358 %{
 3359   constraint(ALLOC_IN_RC(v6_reg));
 3360   match(VecA);
 3361   match(vReg);
 3362   op_cost(0);
 3363   format %{ %}
 3364   interface(REG_INTER);
 3365 %}
 3366 
 3367 operand vReg_V7()
 3368 %{
 3369   constraint(ALLOC_IN_RC(v7_reg));
 3370   match(VecA);
 3371   match(vReg);
 3372   op_cost(0);
 3373   format %{ %}
 3374   interface(REG_INTER);
 3375 %}
 3376 
 3377 operand vReg_V8()
 3378 %{
 3379   constraint(ALLOC_IN_RC(v8_reg));
 3380   match(VecA);
 3381   match(vReg);
 3382   op_cost(0);
 3383   format %{ %}
 3384   interface(REG_INTER);
 3385 %}
 3386 
 3387 operand vReg_V9()
 3388 %{
 3389   constraint(ALLOC_IN_RC(v9_reg));
 3390   match(VecA);
 3391   match(vReg);
 3392   op_cost(0);
 3393   format %{ %}
 3394   interface(REG_INTER);
 3395 %}
 3396 
 3397 operand vReg_V10()
 3398 %{
 3399   constraint(ALLOC_IN_RC(v10_reg));
 3400   match(VecA);
 3401   match(vReg);
 3402   op_cost(0);
 3403   format %{ %}
 3404   interface(REG_INTER);
 3405 %}
 3406 
 3407 operand vReg_V11()
 3408 %{
 3409   constraint(ALLOC_IN_RC(v11_reg));
 3410   match(VecA);
 3411   match(vReg);
 3412   op_cost(0);
 3413   format %{ %}
 3414   interface(REG_INTER);
 3415 %}
 3416 
 3417 operand vRegMask()
 3418 %{
 3419   constraint(ALLOC_IN_RC(vmask_reg));
 3420   match(RegVectMask);
 3421   match(vRegMask_V0);
 3422   op_cost(0);
 3423   format %{ %}
 3424   interface(REG_INTER);
 3425 %}
 3426 
 3427 // The mask value used to control execution of a masked
 3428 // vector instruction is always supplied by vector register v0.
 3429 operand vRegMask_V0()
 3430 %{
 3431   constraint(ALLOC_IN_RC(vmask_reg_v0));
 3432   match(RegVectMask);
 3433   match(vRegMask);
 3434   op_cost(0);
 3435   format %{ %}
 3436   interface(REG_INTER);
 3437 %}
 3438 
 3439 // Java Thread Register
 3440 operand javaThread_RegP(iRegP reg)
 3441 %{
 3442   constraint(ALLOC_IN_RC(java_thread_reg)); // java_thread_reg
 3443   match(reg);
 3444   op_cost(0);
 3445   format %{ %}
 3446   interface(REG_INTER);
 3447 %}
 3448 
 3449 //----------Memory Operands----------------------------------------------------
 3450 // RISCV has only base_plus_offset and literal address mode, so no need to use
 3451 // index and scale. Here set index as 0xffffffff and scale as 0x0.
 3452 operand indirect(iRegP reg)
 3453 %{
 3454   constraint(ALLOC_IN_RC(ptr_reg));
 3455   match(reg);
 3456   op_cost(0);
 3457   format %{ "[$reg]" %}
 3458   interface(MEMORY_INTER) %{
 3459     base($reg);
 3460     index(0xffffffff);
 3461     scale(0x0);
 3462     disp(0x0);
 3463   %}
 3464 %}
 3465 
 3466 operand indOffI(iRegP reg, immIOffset off)
 3467 %{
 3468   constraint(ALLOC_IN_RC(ptr_reg));
 3469   match(AddP reg off);
 3470   op_cost(0);
 3471   format %{ "[$reg, $off]" %}
 3472   interface(MEMORY_INTER) %{
 3473     base($reg);
 3474     index(0xffffffff);
 3475     scale(0x0);
 3476     disp($off);
 3477   %}
 3478 %}
 3479 
 3480 operand indOffL(iRegP reg, immLOffset off)
 3481 %{
 3482   constraint(ALLOC_IN_RC(ptr_reg));
 3483   match(AddP reg off);
 3484   op_cost(0);
 3485   format %{ "[$reg, $off]" %}
 3486   interface(MEMORY_INTER) %{
 3487     base($reg);
 3488     index(0xffffffff);
 3489     scale(0x0);
 3490     disp($off);
 3491   %}
 3492 %}
 3493 
 3494 operand indirectN(iRegN reg)
 3495 %{
 3496   predicate(CompressedOops::shift() == 0);
 3497   constraint(ALLOC_IN_RC(ptr_reg));
 3498   match(DecodeN reg);
 3499   op_cost(0);
 3500   format %{ "[$reg]\t# narrow" %}
 3501   interface(MEMORY_INTER) %{
 3502     base($reg);
 3503     index(0xffffffff);
 3504     scale(0x0);
 3505     disp(0x0);
 3506   %}
 3507 %}
 3508 
 3509 operand indOffIN(iRegN reg, immIOffset off)
 3510 %{
 3511   predicate(CompressedOops::shift() == 0);
 3512   constraint(ALLOC_IN_RC(ptr_reg));
 3513   match(AddP (DecodeN reg) off);
 3514   op_cost(0);
 3515   format %{ "[$reg, $off]\t# narrow" %}
 3516   interface(MEMORY_INTER) %{
 3517     base($reg);
 3518     index(0xffffffff);
 3519     scale(0x0);
 3520     disp($off);
 3521   %}
 3522 %}
 3523 
 3524 operand indOffLN(iRegN reg, immLOffset off)
 3525 %{
 3526   predicate(CompressedOops::shift() == 0);
 3527   constraint(ALLOC_IN_RC(ptr_reg));
 3528   match(AddP (DecodeN reg) off);
 3529   op_cost(0);
 3530   format %{ "[$reg, $off]\t# narrow" %}
 3531   interface(MEMORY_INTER) %{
 3532     base($reg);
 3533     index(0xffffffff);
 3534     scale(0x0);
 3535     disp($off);
 3536   %}
 3537 %}
 3538 
 3539 //----------Special Memory Operands--------------------------------------------
 3540 // Stack Slot Operand - This operand is used for loading and storing temporary
 3541 //                      values on the stack where a match requires a value to
 3542 //                      flow through memory.
 3543 operand stackSlotI(sRegI reg)
 3544 %{
 3545   constraint(ALLOC_IN_RC(stack_slots));
 3546   // No match rule because this operand is only generated in matching
 3547   // match(RegI);
 3548   format %{ "[$reg]" %}
 3549   interface(MEMORY_INTER) %{
 3550     base(0x02);  // RSP
 3551     index(0xffffffff);  // No Index
 3552     scale(0x0);  // No Scale
 3553     disp($reg);  // Stack Offset
 3554   %}
 3555 %}
 3556 
 3557 operand stackSlotF(sRegF reg)
 3558 %{
 3559   constraint(ALLOC_IN_RC(stack_slots));
 3560   // No match rule because this operand is only generated in matching
 3561   // match(RegF);
 3562   format %{ "[$reg]" %}
 3563   interface(MEMORY_INTER) %{
 3564     base(0x02);  // RSP
 3565     index(0xffffffff);  // No Index
 3566     scale(0x0);  // No Scale
 3567     disp($reg);  // Stack Offset
 3568   %}
 3569 %}
 3570 
 3571 operand stackSlotD(sRegD reg)
 3572 %{
 3573   constraint(ALLOC_IN_RC(stack_slots));
 3574   // No match rule because this operand is only generated in matching
 3575   // match(RegD);
 3576   format %{ "[$reg]" %}
 3577   interface(MEMORY_INTER) %{
 3578     base(0x02);  // RSP
 3579     index(0xffffffff);  // No Index
 3580     scale(0x0);  // No Scale
 3581     disp($reg);  // Stack Offset
 3582   %}
 3583 %}
 3584 
 3585 operand stackSlotL(sRegL reg)
 3586 %{
 3587   constraint(ALLOC_IN_RC(stack_slots));
 3588   // No match rule because this operand is only generated in matching
 3589   // match(RegL);
 3590   format %{ "[$reg]" %}
 3591   interface(MEMORY_INTER) %{
 3592     base(0x02);  // RSP
 3593     index(0xffffffff);  // No Index
 3594     scale(0x0);  // No Scale
 3595     disp($reg);  // Stack Offset
 3596   %}
 3597 %}
 3598 
 3599 // Special operand allowing long args to int ops to be truncated for free
 3600 
 3601 operand iRegL2I(iRegL reg) %{
 3602 
 3603   op_cost(0);
 3604 
 3605   match(ConvL2I reg);
 3606 
 3607   format %{ "l2i($reg)" %}
 3608 
 3609   interface(REG_INTER)
 3610 %}
 3611 
 3612 
 3613 // Comparison Operands
 3614 // NOTE: Label is a predefined operand which should not be redefined in
 3615 //       the AD file. It is generically handled within the ADLC.
 3616 
 3617 //----------Conditional Branch Operands----------------------------------------
 3618 // Comparison Op  - This is the operation of the comparison, and is limited to
 3619 //                  the following set of codes:
 3620 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
 3621 //
 3622 // Other attributes of the comparison, such as unsignedness, are specified
 3623 // by the comparison instruction that sets a condition code flags register.
 3624 // That result is represented by a flags operand whose subtype is appropriate
 3625 // to the unsignedness (etc.) of the comparison.
 3626 //
 3627 // Later, the instruction which matches both the Comparison Op (a Bool) and
 3628 // the flags (produced by the Cmp) specifies the coding of the comparison op
 3629 // by matching a specific subtype of Bool operand below, such as cmpOpU.
 3630 
 3631 
 3632 // used for signed integral comparisons and fp comparisons
 3633 operand cmpOp()
 3634 %{
 3635   match(Bool);
 3636 
 3637   format %{ "" %}
 3638 
 3639   // the values in interface derives from struct BoolTest::mask
 3640   interface(COND_INTER) %{
 3641     equal(0x0, "eq");
 3642     greater(0x1, "gt");
 3643     overflow(0x2, "overflow");
 3644     less(0x3, "lt");
 3645     not_equal(0x4, "ne");
 3646     less_equal(0x5, "le");
 3647     no_overflow(0x6, "no_overflow");
 3648     greater_equal(0x7, "ge");
 3649   %}
 3650 %}
 3651 
 3652 // used for unsigned integral comparisons
 3653 operand cmpOpU()
 3654 %{
 3655   match(Bool);
 3656 
 3657   format %{ "" %}
 3658   // the values in interface derives from struct BoolTest::mask
 3659   interface(COND_INTER) %{
 3660     equal(0x0, "eq");
 3661     greater(0x1, "gtu");
 3662     overflow(0x2, "overflow");
 3663     less(0x3, "ltu");
 3664     not_equal(0x4, "ne");
 3665     less_equal(0x5, "leu");
 3666     no_overflow(0x6, "no_overflow");
 3667     greater_equal(0x7, "geu");
 3668   %}
 3669 %}
 3670 
 3671 // used for certain integral comparisons which can be
 3672 // converted to bxx instructions
 3673 operand cmpOpEqNe()
 3674 %{
 3675   match(Bool);
 3676   op_cost(0);
 3677   predicate(n->as_Bool()->_test._test == BoolTest::ne ||
 3678             n->as_Bool()->_test._test == BoolTest::eq);
 3679 
 3680   format %{ "" %}
 3681   interface(COND_INTER) %{
 3682     equal(0x0, "eq");
 3683     greater(0x1, "gt");
 3684     overflow(0x2, "overflow");
 3685     less(0x3, "lt");
 3686     not_equal(0x4, "ne");
 3687     less_equal(0x5, "le");
 3688     no_overflow(0x6, "no_overflow");
 3689     greater_equal(0x7, "ge");
 3690   %}
 3691 %}
 3692 
 3693 operand cmpOpULtGe()
 3694 %{
 3695   match(Bool);
 3696   op_cost(0);
 3697   predicate(n->as_Bool()->_test._test == BoolTest::lt ||
 3698             n->as_Bool()->_test._test == BoolTest::ge);
 3699 
 3700   format %{ "" %}
 3701   interface(COND_INTER) %{
 3702     equal(0x0, "eq");
 3703     greater(0x1, "gtu");
 3704     overflow(0x2, "overflow");
 3705     less(0x3, "ltu");
 3706     not_equal(0x4, "ne");
 3707     less_equal(0x5, "leu");
 3708     no_overflow(0x6, "no_overflow");
 3709     greater_equal(0x7, "geu");
 3710   %}
 3711 %}
 3712 
 3713 operand cmpOpUEqNeLeGt()
 3714 %{
 3715   match(Bool);
 3716   op_cost(0);
 3717   predicate(n->as_Bool()->_test._test == BoolTest::ne ||
 3718             n->as_Bool()->_test._test == BoolTest::eq ||
 3719             n->as_Bool()->_test._test == BoolTest::le ||
 3720             n->as_Bool()->_test._test == BoolTest::gt);
 3721 
 3722   format %{ "" %}
 3723   interface(COND_INTER) %{
 3724     equal(0x0, "eq");
 3725     greater(0x1, "gtu");
 3726     overflow(0x2, "overflow");
 3727     less(0x3, "ltu");
 3728     not_equal(0x4, "ne");
 3729     less_equal(0x5, "leu");
 3730     no_overflow(0x6, "no_overflow");
 3731     greater_equal(0x7, "geu");
 3732   %}
 3733 %}
 3734 
 3735 
 3736 // Flags register, used as output of compare logic
 3737 operand rFlagsReg()
 3738 %{
 3739   constraint(ALLOC_IN_RC(reg_flags));
 3740   match(RegFlags);
 3741 
 3742   op_cost(0);
 3743   format %{ "RFLAGS" %}
 3744   interface(REG_INTER);
 3745 %}
 3746 
 3747 // Special Registers
 3748 
 3749 // Method Register
 3750 operand inline_cache_RegP(iRegP reg)
 3751 %{
 3752   constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg
 3753   match(reg);
 3754   match(iRegPNoSp);
 3755   op_cost(0);
 3756   format %{ %}
 3757   interface(REG_INTER);
 3758 %}
 3759 
 3760 //----------OPERAND CLASSES----------------------------------------------------
 3761 // Operand Classes are groups of operands that are used as to simplify
 3762 // instruction definitions by not requiring the AD writer to specify
 3763 // separate instructions for every form of operand when the
 3764 // instruction accepts multiple operand types with the same basic
 3765 // encoding and format. The classic case of this is memory operands.
 3766 
 3767 // memory is used to define read/write location for load/store
 3768 // instruction defs. we can turn a memory op into an Address
 3769 
 3770 opclass memory(indirect, indOffI, indOffL, indirectN, indOffIN, indOffLN);
 3771 
 3772 // iRegIorL2I is used for src inputs in rules for 32 bit int (I)
 3773 // operations. it allows the src to be either an iRegI or a (ConvL2I
 3774 // iRegL). in the latter case the l2i normally planted for a ConvL2I
 3775 // can be elided because the 32-bit instruction will just employ the
 3776 // lower 32 bits anyway.
 3777 //
 3778 // n.b. this does not elide all L2I conversions. if the truncated
 3779 // value is consumed by more than one operation then the ConvL2I
 3780 // cannot be bundled into the consuming nodes so an l2i gets planted
 3781 // (actually an addiw $dst, $src, 0) and the downstream instructions
 3782 // consume the result of the L2I as an iRegI input. That's a shame since
 3783 // the addiw is actually redundant but its not too costly.
 3784 
 3785 opclass iRegIorL2I(iRegI, iRegL2I);
 3786 opclass iRegIorL(iRegI, iRegL);
 3787 opclass iRegNorP(iRegN, iRegP);
 3788 opclass iRegILNP(iRegI, iRegL, iRegN, iRegP);
 3789 opclass iRegILNPNoSp(iRegINoSp, iRegLNoSp, iRegNNoSp, iRegPNoSp);
 3790 opclass immIorL(immI, immL);
 3791 
 3792 //----------PIPELINE-----------------------------------------------------------
 3793 // Rules which define the behavior of the target architectures pipeline.
 3794 
 3795 // For specific pipelines, e.g. generic RISC-V, define the stages of that pipeline
 3796 //pipe_desc(ID, EX, MEM, WR);
 3797 #define ID   S0
 3798 #define EX   S1
 3799 #define MEM  S2
 3800 #define WR   S3
 3801 
 3802 // Integer ALU reg operation
 3803 pipeline %{
 3804 
 3805 attributes %{
 3806   // RISC-V instructions are of length 2 or 4 bytes.
 3807   variable_size_instructions;
 3808   instruction_unit_size = 2;
 3809 
 3810   // Up to 4 instructions per bundle
 3811   max_instructions_per_bundle = 4;
 3812 
 3813   // The RISC-V processor fetches 64 bytes...
 3814   instruction_fetch_unit_size = 64;
 3815 
 3816   // ...in one line.
 3817   instruction_fetch_units = 1;
 3818 %}
 3819 
 3820 // We don't use an actual pipeline model so don't care about resources
 3821 // or description. we do use pipeline classes to introduce fixed
 3822 // latencies
 3823 
 3824 //----------RESOURCES----------------------------------------------------------
 3825 // Resources are the functional units available to the machine
 3826 
 3827 // Generic RISC-V pipeline
 3828 // 1 decoder
 3829 // 1 instruction decoded per cycle
 3830 // 1 load/store ops per cycle, 1 branch, 1 FPU
 3831 // 1 mul, 1 div
 3832 
 3833 resources ( DECODE,
 3834             ALU,
 3835             MUL,
 3836             DIV,
 3837             BRANCH,
 3838             LDST,
 3839             FPU);
 3840 
 3841 //----------PIPELINE DESCRIPTION-----------------------------------------------
 3842 // Pipeline Description specifies the stages in the machine's pipeline
 3843 
 3844 // Define the pipeline as a generic 6 stage pipeline
 3845 pipe_desc(S0, S1, S2, S3, S4, S5);
 3846 
 3847 //----------PIPELINE CLASSES---------------------------------------------------
 3848 // Pipeline Classes describe the stages in which input and output are
 3849 // referenced by the hardware pipeline.
 3850 
 3851 pipe_class fp_dop_reg_reg_s(fRegF dst, fRegF src1, fRegF src2)
 3852 %{
 3853   single_instruction;
 3854   src1   : S1(read);
 3855   src2   : S2(read);
 3856   dst    : S5(write);
 3857   DECODE : ID;
 3858   FPU    : S5;
 3859 %}
 3860 
 3861 pipe_class fp_dop_reg_reg_d(fRegD dst, fRegD src1, fRegD src2)
 3862 %{
 3863   src1   : S1(read);
 3864   src2   : S2(read);
 3865   dst    : S5(write);
 3866   DECODE : ID;
 3867   FPU    : S5;
 3868 %}
 3869 
 3870 pipe_class fp_uop_s(fRegF dst, fRegF src)
 3871 %{
 3872   single_instruction;
 3873   src    : S1(read);
 3874   dst    : S5(write);
 3875   DECODE : ID;
 3876   FPU    : S5;
 3877 %}
 3878 
 3879 pipe_class fp_uop_d(fRegD dst, fRegD src)
 3880 %{
 3881   single_instruction;
 3882   src    : S1(read);
 3883   dst    : S5(write);
 3884   DECODE : ID;
 3885   FPU    : S5;
 3886 %}
 3887 
 3888 pipe_class fp_d2f(fRegF dst, fRegD src)
 3889 %{
 3890   single_instruction;
 3891   src    : S1(read);
 3892   dst    : S5(write);
 3893   DECODE : ID;
 3894   FPU    : S5;
 3895 %}
 3896 
 3897 pipe_class fp_f2d(fRegD dst, fRegF src)
 3898 %{
 3899   single_instruction;
 3900   src    : S1(read);
 3901   dst    : S5(write);
 3902   DECODE : ID;
 3903   FPU    : S5;
 3904 %}
 3905 
 3906 pipe_class fp_f2i(iRegINoSp dst, fRegF src)
 3907 %{
 3908   single_instruction;
 3909   src    : S1(read);
 3910   dst    : S5(write);
 3911   DECODE : ID;
 3912   FPU    : S5;
 3913 %}
 3914 
 3915 pipe_class fp_f2l(iRegLNoSp dst, fRegF src)
 3916 %{
 3917   single_instruction;
 3918   src    : S1(read);
 3919   dst    : S5(write);
 3920   DECODE : ID;
 3921   FPU    : S5;
 3922 %}
 3923 
 3924 pipe_class fp_i2f(fRegF dst, iRegIorL2I src)
 3925 %{
 3926   single_instruction;
 3927   src    : S1(read);
 3928   dst    : S5(write);
 3929   DECODE : ID;
 3930   FPU    : S5;
 3931 %}
 3932 
 3933 pipe_class fp_l2f(fRegF dst, iRegL src)
 3934 %{
 3935   single_instruction;
 3936   src    : S1(read);
 3937   dst    : S5(write);
 3938   DECODE : ID;
 3939   FPU    : S5;
 3940 %}
 3941 
 3942 pipe_class fp_d2i(iRegINoSp dst, fRegD src)
 3943 %{
 3944   single_instruction;
 3945   src    : S1(read);
 3946   dst    : S5(write);
 3947   DECODE : ID;
 3948   FPU    : S5;
 3949 %}
 3950 
 3951 pipe_class fp_d2l(iRegLNoSp dst, fRegD src)
 3952 %{
 3953   single_instruction;
 3954   src    : S1(read);
 3955   dst    : S5(write);
 3956   DECODE : ID;
 3957   FPU    : S5;
 3958 %}
 3959 
 3960 pipe_class fp_i2d(fRegD dst, iRegIorL2I src)
 3961 %{
 3962   single_instruction;
 3963   src    : S1(read);
 3964   dst    : S5(write);
 3965   DECODE : ID;
 3966   FPU    : S5;
 3967 %}
 3968 
 3969 pipe_class fp_l2d(fRegD dst, iRegIorL2I src)
 3970 %{
 3971   single_instruction;
 3972   src    : S1(read);
 3973   dst    : S5(write);
 3974   DECODE : ID;
 3975   FPU    : S5;
 3976 %}
 3977 
 3978 pipe_class fp_div_s(fRegF dst, fRegF src1, fRegF src2)
 3979 %{
 3980   single_instruction;
 3981   src1   : S1(read);
 3982   src2   : S2(read);
 3983   dst    : S5(write);
 3984   DECODE : ID;
 3985   FPU    : S5;
 3986 %}
 3987 
 3988 pipe_class fp_div_d(fRegD dst, fRegD src1, fRegD src2)
 3989 %{
 3990   single_instruction;
 3991   src1   : S1(read);
 3992   src2   : S2(read);
 3993   dst    : S5(write);
 3994   DECODE : ID;
 3995   FPU    : S5;
 3996 %}
 3997 
 3998 pipe_class fp_sqrt_s(fRegF dst, fRegF src)
 3999 %{
 4000   single_instruction;
 4001   src    : S1(read);
 4002   dst    : S5(write);
 4003   DECODE : ID;
 4004   FPU    : S5;
 4005 %}
 4006 
 4007 pipe_class fp_sqrt_d(fRegD dst, fRegD src)
 4008 %{
 4009   single_instruction;
 4010   src    : S1(read);
 4011   dst    : S5(write);
 4012   DECODE : ID;
 4013   FPU    : S5;
 4014 %}
 4015 
 4016 pipe_class fp_load_constant_s(fRegF dst)
 4017 %{
 4018   single_instruction;
 4019   dst    : S5(write);
 4020   DECODE : ID;
 4021   FPU    : S5;
 4022 %}
 4023 
 4024 pipe_class fp_load_constant_d(fRegD dst)
 4025 %{
 4026   single_instruction;
 4027   dst    : S5(write);
 4028   DECODE : ID;
 4029   FPU    : S5;
 4030 %}
 4031 
 4032 pipe_class fp_load_mem_s(fRegF dst, memory mem)
 4033 %{
 4034   single_instruction;
 4035   mem    : S1(read);
 4036   dst    : S5(write);
 4037   DECODE : ID;
 4038   LDST   : MEM;
 4039 %}
 4040 
 4041 pipe_class fp_load_mem_d(fRegD dst, memory mem)
 4042 %{
 4043   single_instruction;
 4044   mem    : S1(read);
 4045   dst    : S5(write);
 4046   DECODE : ID;
 4047   LDST   : MEM;
 4048 %}
 4049 
 4050 pipe_class fp_store_reg_s(fRegF src, memory mem)
 4051 %{
 4052   single_instruction;
 4053   src    : S1(read);
 4054   mem    : S5(write);
 4055   DECODE : ID;
 4056   LDST   : MEM;
 4057 %}
 4058 
 4059 pipe_class fp_store_reg_d(fRegD src, memory mem)
 4060 %{
 4061   single_instruction;
 4062   src    : S1(read);
 4063   mem    : S5(write);
 4064   DECODE : ID;
 4065   LDST   : MEM;
 4066 %}
 4067 
 4068 //------- Integer ALU operations --------------------------
 4069 
 4070 // Integer ALU reg-reg operation
 4071 // Operands needs in ID, result generated in EX
 4072 // E.g.  ADD   Rd, Rs1, Rs2
 4073 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2)
 4074 %{
 4075   single_instruction;
 4076   dst    : EX(write);
 4077   src1   : ID(read);
 4078   src2   : ID(read);
 4079   DECODE : ID;
 4080   ALU    : EX;
 4081 %}
 4082 
 4083 // Integer ALU reg operation with constant shift
 4084 // E.g. SLLI    Rd, Rs1, #shift
 4085 pipe_class ialu_reg_shift(iRegI dst, iRegI src1)
 4086 %{
 4087   single_instruction;
 4088   dst    : EX(write);
 4089   src1   : ID(read);
 4090   DECODE : ID;
 4091   ALU    : EX;
 4092 %}
 4093 
 4094 // Integer ALU reg-reg operation with variable shift
 4095 // both operands must be available in ID
 4096 // E.g. SLL   Rd, Rs1, Rs2
 4097 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2)
 4098 %{
 4099   single_instruction;
 4100   dst    : EX(write);
 4101   src1   : ID(read);
 4102   src2   : ID(read);
 4103   DECODE : ID;
 4104   ALU    : EX;
 4105 %}
 4106 
 4107 // Integer ALU reg operation
 4108 // E.g. NEG   Rd, Rs2
 4109 pipe_class ialu_reg(iRegI dst, iRegI src)
 4110 %{
 4111   single_instruction;
 4112   dst    : EX(write);
 4113   src    : ID(read);
 4114   DECODE : ID;
 4115   ALU    : EX;
 4116 %}
 4117 
 4118 // Integer ALU reg immediate operation
 4119 // E.g. ADDI   Rd, Rs1, #imm
 4120 pipe_class ialu_reg_imm(iRegI dst, iRegI src1)
 4121 %{
 4122   single_instruction;
 4123   dst    : EX(write);
 4124   src1   : ID(read);
 4125   DECODE : ID;
 4126   ALU    : EX;
 4127 %}
 4128 
 4129 // Integer ALU immediate operation (no source operands)
 4130 // E.g. LI    Rd, #imm
 4131 pipe_class ialu_imm(iRegI dst)
 4132 %{
 4133   single_instruction;
 4134   dst    : EX(write);
 4135   DECODE : ID;
 4136   ALU    : EX;
 4137 %}
 4138 
 4139 //------- Multiply pipeline operations --------------------
 4140 
 4141 // Multiply reg-reg
 4142 // E.g. MULW   Rd, Rs1, Rs2
 4143 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2)
 4144 %{
 4145   single_instruction;
 4146   dst    : WR(write);
 4147   src1   : ID(read);
 4148   src2   : ID(read);
 4149   DECODE : ID;
 4150   MUL    : WR;
 4151 %}
 4152 
 4153 // E.g. MUL   RD, Rs1, Rs2
 4154 pipe_class lmul_reg_reg(iRegL dst, iRegL src1, iRegL src2)
 4155 %{
 4156   single_instruction;
 4157   fixed_latency(3); // Maximum latency for 64 bit mul
 4158   dst    : WR(write);
 4159   src1   : ID(read);
 4160   src2   : ID(read);
 4161   DECODE : ID;
 4162   MUL    : WR;
 4163 %}
 4164 
 4165 //------- Divide pipeline operations --------------------
 4166 
 4167 // E.g. DIVW   Rd, Rs1, Rs2
 4168 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2)
 4169 %{
 4170   single_instruction;
 4171   fixed_latency(8); // Maximum latency for 32 bit divide
 4172   dst    : WR(write);
 4173   src1   : ID(read);
 4174   src2   : ID(read);
 4175   DECODE : ID;
 4176   DIV    : WR;
 4177 %}
 4178 
 4179 // E.g. DIV   RD, Rs1, Rs2
 4180 pipe_class ldiv_reg_reg(iRegL dst, iRegL src1, iRegL src2)
 4181 %{
 4182   single_instruction;
 4183   fixed_latency(16); // Maximum latency for 64 bit divide
 4184   dst    : WR(write);
 4185   src1   : ID(read);
 4186   src2   : ID(read);
 4187   DECODE : ID;
 4188   DIV    : WR;
 4189 %}
 4190 
 4191 //------- Load pipeline operations ------------------------
 4192 
 4193 // Load - prefetch
 4194 // Eg.  PREFETCH_W  mem
 4195 pipe_class iload_prefetch(memory mem)
 4196 %{
 4197   single_instruction;
 4198   mem    : ID(read);
 4199   DECODE : ID;
 4200   LDST   : MEM;
 4201 %}
 4202 
 4203 // Load - reg, mem
 4204 // E.g. LA    Rd, mem
 4205 pipe_class iload_reg_mem(iRegI dst, memory mem)
 4206 %{
 4207   single_instruction;
 4208   dst    : WR(write);
 4209   mem    : ID(read);
 4210   DECODE : ID;
 4211   LDST   : MEM;
 4212 %}
 4213 
 4214 // Load - reg, reg
 4215 // E.g. LD    Rd, Rs
 4216 pipe_class iload_reg_reg(iRegI dst, iRegI src)
 4217 %{
 4218   single_instruction;
 4219   dst    : WR(write);
 4220   src    : ID(read);
 4221   DECODE : ID;
 4222   LDST   : MEM;
 4223 %}
 4224 
 4225 //------- Store pipeline operations -----------------------
 4226 
 4227 // Store - zr, mem
 4228 // E.g. SD    zr, mem
 4229 pipe_class istore_mem(memory mem)
 4230 %{
 4231   single_instruction;
 4232   mem    : ID(read);
 4233   DECODE : ID;
 4234   LDST   : MEM;
 4235 %}
 4236 
 4237 // Store - reg, mem
 4238 // E.g. SD    Rs, mem
 4239 pipe_class istore_reg_mem(iRegI src, memory mem)
 4240 %{
 4241   single_instruction;
 4242   mem    : ID(read);
 4243   src    : EX(read);
 4244   DECODE : ID;
 4245   LDST   : MEM;
 4246 %}
 4247 
 4248 // Store - reg, reg
 4249 // E.g. SD    Rs2, Rs1
 4250 pipe_class istore_reg_reg(iRegI dst, iRegI src)
 4251 %{
 4252   single_instruction;
 4253   dst    : ID(read);
 4254   src    : EX(read);
 4255   DECODE : ID;
 4256   LDST   : MEM;
 4257 %}
 4258 
 4259 //------- Control transfer pipeline operations ------------
 4260 
 4261 // Branch
 4262 pipe_class pipe_branch()
 4263 %{
 4264   single_instruction;
 4265   DECODE : ID;
 4266   BRANCH : EX;
 4267 %}
 4268 
 4269 // Branch
 4270 pipe_class pipe_branch_reg(iRegI src)
 4271 %{
 4272   single_instruction;
 4273   src    : ID(read);
 4274   DECODE : ID;
 4275   BRANCH : EX;
 4276 %}
 4277 
 4278 // Compare & Branch
 4279 // E.g. BEQ   Rs1, Rs2, L
 4280 pipe_class pipe_cmp_branch(iRegI src1, iRegI src2)
 4281 %{
 4282   single_instruction;
 4283   src1   : ID(read);
 4284   src2   : ID(read);
 4285   DECODE : ID;
 4286   BRANCH : EX;
 4287 %}
 4288 
 4289 // E.g. BEQZ Rs, L
 4290 pipe_class pipe_cmpz_branch(iRegI src)
 4291 %{
 4292   single_instruction;
 4293   src    : ID(read);
 4294   DECODE : ID;
 4295   BRANCH : EX;
 4296 %}
 4297 
 4298 //------- Synchronisation operations ----------------------
 4299 // Any operation requiring serialization
 4300 // E.g. FENCE/Atomic Ops/Load Acquire/Store Release
 4301 pipe_class pipe_serial()
 4302 %{
 4303   single_instruction;
 4304   force_serialization;
 4305   fixed_latency(16);
 4306   DECODE : ID;
 4307   LDST   : MEM;
 4308 %}
 4309 
 4310 pipe_class pipe_slow()
 4311 %{
 4312   instruction_count(10);
 4313   multiple_bundles;
 4314   force_serialization;
 4315   fixed_latency(16);
 4316   DECODE : ID;
 4317   LDST   : MEM;
 4318 %}
 4319 
 4320 // The real do-nothing guy
 4321 pipe_class real_empty()
 4322 %{
 4323     instruction_count(0);
 4324 %}
 4325 
 4326 // Empty pipeline class
 4327 pipe_class pipe_class_empty()
 4328 %{
 4329   single_instruction;
 4330   fixed_latency(0);
 4331 %}
 4332 
 4333 // Default pipeline class.
 4334 pipe_class pipe_class_default()
 4335 %{
 4336   single_instruction;
 4337   fixed_latency(2);
 4338 %}
 4339 
 4340 // Pipeline class for compares.
 4341 pipe_class pipe_class_compare()
 4342 %{
 4343   single_instruction;
 4344   fixed_latency(16);
 4345 %}
 4346 
 4347 // Pipeline class for memory operations.
 4348 pipe_class pipe_class_memory()
 4349 %{
 4350   single_instruction;
 4351   fixed_latency(16);
 4352 %}
 4353 
 4354 // Pipeline class for call.
 4355 pipe_class pipe_class_call()
 4356 %{
 4357   single_instruction;
 4358   fixed_latency(100);
 4359 %}
 4360 
 4361 // Define the class for the Nop node.
 4362 define %{
 4363    MachNop = pipe_class_empty;
 4364 %}
 4365 %}
 4366 //----------INSTRUCTIONS-------------------------------------------------------
 4367 //
 4368 // match      -- States which machine-independent subtree may be replaced
 4369 //               by this instruction.
 4370 // ins_cost   -- The estimated cost of this instruction is used by instruction
 4371 //               selection to identify a minimum cost tree of machine
 4372 //               instructions that matches a tree of machine-independent
 4373 //               instructions.
 4374 // format     -- A string providing the disassembly for this instruction.
 4375 //               The value of an instruction's operand may be inserted
 4376 //               by referring to it with a '$' prefix.
 4377 // opcode     -- Three instruction opcodes may be provided.  These are referred
 4378 //               to within an encode class as $primary, $secondary, and $tertiary
 4379 //               rrspectively.  The primary opcode is commonly used to
 4380 //               indicate the type of machine instruction, while secondary
 4381 //               and tertiary are often used for prefix options or addressing
 4382 //               modes.
 4383 // ins_encode -- A list of encode classes with parameters. The encode class
 4384 //               name must have been defined in an 'enc_class' specification
 4385 //               in the encode section of the architecture description.
 4386 
 4387 // ============================================================================
 4388 // Memory (Load/Store) Instructions
 4389 
 4390 // Load Instructions
 4391 
 4392 // Load Byte (8 bit signed)
 4393 instruct loadB(iRegINoSp dst, memory mem)
 4394 %{
 4395   match(Set dst (LoadB mem));
 4396 
 4397   ins_cost(LOAD_COST);
 4398   format %{ "lb  $dst, $mem\t# byte, #@loadB" %}
 4399 
 4400   ins_encode %{
 4401     __ lb(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4402   %}
 4403 
 4404   ins_pipe(iload_reg_mem);
 4405 %}
 4406 
 4407 // Load Byte (8 bit signed) into long
 4408 instruct loadB2L(iRegLNoSp dst, memory mem)
 4409 %{
 4410   match(Set dst (ConvI2L (LoadB mem)));
 4411 
 4412   ins_cost(LOAD_COST);
 4413   format %{ "lb  $dst, $mem\t# byte, #@loadB2L" %}
 4414 
 4415   ins_encode %{
 4416     __ lb(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4417   %}
 4418 
 4419   ins_pipe(iload_reg_mem);
 4420 %}
 4421 
 4422 // Load Byte (8 bit unsigned)
 4423 instruct loadUB(iRegINoSp dst, memory mem)
 4424 %{
 4425   match(Set dst (LoadUB mem));
 4426 
 4427   ins_cost(LOAD_COST);
 4428   format %{ "lbu  $dst, $mem\t# byte, #@loadUB" %}
 4429 
 4430   ins_encode %{
 4431     __ lbu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4432   %}
 4433 
 4434   ins_pipe(iload_reg_mem);
 4435 %}
 4436 
 4437 // Load Byte (8 bit unsigned) into long
 4438 instruct loadUB2L(iRegLNoSp dst, memory mem)
 4439 %{
 4440   match(Set dst (ConvI2L (LoadUB mem)));
 4441 
 4442   ins_cost(LOAD_COST);
 4443   format %{ "lbu  $dst, $mem\t# byte, #@loadUB2L" %}
 4444 
 4445   ins_encode %{
 4446     __ lbu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4447   %}
 4448 
 4449   ins_pipe(iload_reg_mem);
 4450 %}
 4451 
 4452 // Load Short (16 bit signed)
 4453 instruct loadS(iRegINoSp dst, memory mem)
 4454 %{
 4455   match(Set dst (LoadS mem));
 4456 
 4457   ins_cost(LOAD_COST);
 4458   format %{ "lh  $dst, $mem\t# short, #@loadS" %}
 4459 
 4460   ins_encode %{
 4461     __ lh(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4462   %}
 4463 
 4464   ins_pipe(iload_reg_mem);
 4465 %}
 4466 
 4467 // Load Short (16 bit signed) into long
 4468 instruct loadS2L(iRegLNoSp dst, memory mem)
 4469 %{
 4470   match(Set dst (ConvI2L (LoadS mem)));
 4471 
 4472   ins_cost(LOAD_COST);
 4473   format %{ "lh  $dst, $mem\t# short, #@loadS2L" %}
 4474 
 4475   ins_encode %{
 4476     __ lh(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4477   %}
 4478 
 4479   ins_pipe(iload_reg_mem);
 4480 %}
 4481 
 4482 // Load Char (16 bit unsigned)
 4483 instruct loadUS(iRegINoSp dst, memory mem)
 4484 %{
 4485   match(Set dst (LoadUS mem));
 4486 
 4487   ins_cost(LOAD_COST);
 4488   format %{ "lhu  $dst, $mem\t# short, #@loadUS" %}
 4489 
 4490   ins_encode %{
 4491     __ lhu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4492   %}
 4493 
 4494   ins_pipe(iload_reg_mem);
 4495 %}
 4496 
 4497 // Load Short/Char (16 bit unsigned) into long
 4498 instruct loadUS2L(iRegLNoSp dst, memory mem)
 4499 %{
 4500   match(Set dst (ConvI2L (LoadUS mem)));
 4501 
 4502   ins_cost(LOAD_COST);
 4503   format %{ "lhu  $dst, $mem\t# short, #@loadUS2L" %}
 4504 
 4505   ins_encode %{
 4506     __ lhu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4507   %}
 4508 
 4509   ins_pipe(iload_reg_mem);
 4510 %}
 4511 
 4512 // Load Integer (32 bit signed)
 4513 instruct loadI(iRegINoSp dst, memory mem)
 4514 %{
 4515   match(Set dst (LoadI mem));
 4516 
 4517   ins_cost(LOAD_COST);
 4518   format %{ "lw  $dst, $mem\t# int, #@loadI" %}
 4519 
 4520   ins_encode %{
 4521     __ lw(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4522   %}
 4523 
 4524   ins_pipe(iload_reg_mem);
 4525 %}
 4526 
 4527 // Load Integer (32 bit signed) into long
 4528 instruct loadI2L(iRegLNoSp dst, memory mem)
 4529 %{
 4530   match(Set dst (ConvI2L (LoadI mem)));
 4531 
 4532   ins_cost(LOAD_COST);
 4533   format %{ "lw  $dst, $mem\t# int, #@loadI2L" %}
 4534 
 4535   ins_encode %{
 4536     __ lw(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4537   %}
 4538 
 4539   ins_pipe(iload_reg_mem);
 4540 %}
 4541 
 4542 // Load Integer (32 bit unsigned) into long
 4543 instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask)
 4544 %{
 4545   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
 4546 
 4547   ins_cost(LOAD_COST);
 4548   format %{ "lwu  $dst, $mem\t# int, #@loadUI2L" %}
 4549 
 4550   ins_encode %{
 4551     __ lwu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4552   %}
 4553 
 4554   ins_pipe(iload_reg_mem);
 4555 %}
 4556 
 4557 // Load Long (64 bit signed)
 4558 instruct loadL(iRegLNoSp dst, memory mem)
 4559 %{
 4560   match(Set dst (LoadL mem));
 4561 
 4562   ins_cost(LOAD_COST);
 4563   format %{ "ld  $dst, $mem\t# int, #@loadL" %}
 4564 
 4565   ins_encode %{
 4566     __ ld(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4567   %}
 4568 
 4569   ins_pipe(iload_reg_mem);
 4570 %}
 4571 
 4572 // Load Range
 4573 instruct loadRange(iRegINoSp dst, memory mem)
 4574 %{
 4575   match(Set dst (LoadRange mem));
 4576 
 4577   ins_cost(LOAD_COST);
 4578   format %{ "lwu  $dst, $mem\t# range, #@loadRange" %}
 4579 
 4580   ins_encode %{
 4581     __ lwu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4582   %}
 4583 
 4584   ins_pipe(iload_reg_mem);
 4585 %}
 4586 
 4587 // Load Pointer
 4588 instruct loadP(iRegPNoSp dst, memory mem)
 4589 %{
 4590   match(Set dst (LoadP mem));
 4591   predicate(n->as_Load()->barrier_data() == 0);
 4592 
 4593   ins_cost(LOAD_COST);
 4594   format %{ "ld  $dst, $mem\t# ptr, #@loadP" %}
 4595 
 4596   ins_encode %{
 4597     __ ld(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4598   %}
 4599 
 4600   ins_pipe(iload_reg_mem);
 4601 %}
 4602 
 4603 // Load Compressed Pointer
 4604 instruct loadN(iRegNNoSp dst, memory mem)
 4605 %{
 4606   predicate(n->as_Load()->barrier_data() == 0);
 4607   match(Set dst (LoadN mem));
 4608 
 4609   ins_cost(LOAD_COST);
 4610   format %{ "lwu  $dst, $mem\t# compressed ptr, #@loadN" %}
 4611 
 4612   ins_encode %{
 4613     __ lwu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4614   %}
 4615 
 4616   ins_pipe(iload_reg_mem);
 4617 %}
 4618 
 4619 // Load Klass Pointer
 4620 instruct loadKlass(iRegPNoSp dst, memory mem)
 4621 %{
 4622   match(Set dst (LoadKlass mem));
 4623 
 4624   ins_cost(LOAD_COST);
 4625   format %{ "ld  $dst, $mem\t# class, #@loadKlass" %}
 4626 
 4627   ins_encode %{
 4628     __ ld(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4629   %}
 4630 
 4631   ins_pipe(iload_reg_mem);
 4632 %}
 4633 
 4634 // Load Narrow Klass Pointer
 4635 instruct loadNKlass(iRegNNoSp dst, memory mem)
 4636 %{
 4637   predicate(!UseCompactObjectHeaders);
 4638   match(Set dst (LoadNKlass mem));
 4639 
 4640   ins_cost(LOAD_COST);
 4641   format %{ "lwu  $dst, $mem\t# compressed class ptr, #@loadNKlass" %}
 4642 
 4643   ins_encode %{
 4644     __ lwu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4645   %}
 4646 
 4647   ins_pipe(iload_reg_mem);
 4648 %}
 4649 
 4650 instruct loadNKlassCompactHeaders(iRegNNoSp dst, memory mem)
 4651 %{
 4652   predicate(UseCompactObjectHeaders);
 4653   match(Set dst (LoadNKlass mem));
 4654 
 4655   ins_cost(LOAD_COST);
 4656   format %{
 4657     "lwu  $dst, $mem\t# compressed klass ptr, shifted\n\t"
 4658     "srli $dst, $dst, markWord::klass_shift_at_offset"
 4659   %}
 4660 
 4661   ins_encode %{
 4662     __ lwu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4663     __ srli(as_Register($dst$$reg), as_Register($dst$$reg), (unsigned) markWord::klass_shift_at_offset);
 4664   %}
 4665 
 4666   ins_pipe(iload_reg_mem);
 4667 %}
 4668 
 4669 // Load Float
 4670 instruct loadF(fRegF dst, memory mem)
 4671 %{
 4672   match(Set dst (LoadF mem));
 4673 
 4674   ins_cost(LOAD_COST);
 4675   format %{ "flw  $dst, $mem\t# float, #@loadF" %}
 4676 
 4677   ins_encode %{
 4678     __ flw(as_FloatRegister($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4679   %}
 4680 
 4681   ins_pipe(fp_load_mem_s);
 4682 %}
 4683 
 4684 // Load Double
 4685 instruct loadD(fRegD dst, memory mem)
 4686 %{
 4687   match(Set dst (LoadD mem));
 4688 
 4689   ins_cost(LOAD_COST);
 4690   format %{ "fld  $dst, $mem\t# double, #@loadD" %}
 4691 
 4692   ins_encode %{
 4693     __ fld(as_FloatRegister($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4694   %}
 4695 
 4696   ins_pipe(fp_load_mem_d);
 4697 %}
 4698 
 4699 // Load Int Constant
 4700 instruct loadConI(iRegINoSp dst, immI src)
 4701 %{
 4702   match(Set dst src);
 4703 
 4704   ins_cost(ALU_COST);
 4705   format %{ "mv $dst, $src\t# int, #@loadConI" %}
 4706 
 4707   ins_encode(riscv_enc_mov_imm(dst, src));
 4708 
 4709   ins_pipe(ialu_imm);
 4710 %}
 4711 
 4712 // Load Long Constant
 4713 instruct loadConL(iRegLNoSp dst, immL src)
 4714 %{
 4715   match(Set dst src);
 4716 
 4717   ins_cost(ALU_COST);
 4718   format %{ "mv $dst, $src\t# long, #@loadConL" %}
 4719 
 4720   ins_encode(riscv_enc_mov_imm(dst, src));
 4721 
 4722   ins_pipe(ialu_imm);
 4723 %}
 4724 
 4725 // Load Pointer Constant
 4726 instruct loadConP(iRegPNoSp dst, immP con)
 4727 %{
 4728   match(Set dst con);
 4729 
 4730   ins_cost(ALU_COST);
 4731   format %{ "mv  $dst, $con\t# ptr, #@loadConP" %}
 4732 
 4733   ins_encode(riscv_enc_mov_p(dst, con));
 4734 
 4735   ins_pipe(ialu_imm);
 4736 %}
 4737 
 4738 // Load Null Pointer Constant
 4739 instruct loadConP0(iRegPNoSp dst, immP0 con)
 4740 %{
 4741   match(Set dst con);
 4742 
 4743   ins_cost(ALU_COST);
 4744   format %{ "mv  $dst, $con\t# null pointer, #@loadConP0" %}
 4745 
 4746   ins_encode(riscv_enc_mov_zero(dst));
 4747 
 4748   ins_pipe(ialu_imm);
 4749 %}
 4750 
 4751 // Load Pointer Constant One
 4752 instruct loadConP1(iRegPNoSp dst, immP_1 con)
 4753 %{
 4754   match(Set dst con);
 4755 
 4756   ins_cost(ALU_COST);
 4757   format %{ "mv  $dst, $con\t# load ptr constant one, #@loadConP1" %}
 4758 
 4759   ins_encode(riscv_enc_mov_p1(dst));
 4760 
 4761   ins_pipe(ialu_imm);
 4762 %}
 4763 
 4764 // Load Narrow Pointer Constant
 4765 instruct loadConN(iRegNNoSp dst, immN con)
 4766 %{
 4767   match(Set dst con);
 4768 
 4769   ins_cost(ALU_COST * 4);
 4770   format %{ "mv  $dst, $con\t# compressed ptr, #@loadConN" %}
 4771 
 4772   ins_encode(riscv_enc_mov_n(dst, con));
 4773 
 4774   ins_pipe(ialu_imm);
 4775 %}
 4776 
 4777 // Load Narrow Null Pointer Constant
 4778 instruct loadConN0(iRegNNoSp dst, immN0 con)
 4779 %{
 4780   match(Set dst con);
 4781 
 4782   ins_cost(ALU_COST);
 4783   format %{ "mv  $dst, $con\t# compressed null pointer, #@loadConN0" %}
 4784 
 4785   ins_encode(riscv_enc_mov_zero(dst));
 4786 
 4787   ins_pipe(ialu_imm);
 4788 %}
 4789 
 4790 // Load Narrow Klass Constant
 4791 instruct loadConNKlass(iRegNNoSp dst, immNKlass con)
 4792 %{
 4793   match(Set dst con);
 4794 
 4795   ins_cost(ALU_COST * 6);
 4796   format %{ "mv  $dst, $con\t# compressed klass ptr, #@loadConNKlass" %}
 4797 
 4798   ins_encode(riscv_enc_mov_nk(dst, con));
 4799 
 4800   ins_pipe(ialu_imm);
 4801 %}
 4802 
 4803 // Load Half Float Constant
 4804 instruct loadConH(fRegF dst, immH con) %{
 4805   match(Set dst con);
 4806 
 4807   ins_cost(LOAD_COST);
 4808   format %{
 4809     "flh $dst, [$constantaddress]\t# load from constant table: float=$con, #@loadConH"
 4810   %}
 4811 
 4812   ins_encode %{
 4813     assert(UseZfh || UseZfhmin, "must");
 4814     if (MacroAssembler::can_hf_imm_load($con$$constant)) {
 4815       __ fli_h(as_FloatRegister($dst$$reg), $con$$constant);
 4816     } else {
 4817       __ flh(as_FloatRegister($dst$$reg), $constantaddress($con));
 4818     }
 4819   %}
 4820 
 4821   ins_pipe(fp_load_constant_s);
 4822 %}
 4823 
 4824 instruct loadConH0(fRegF dst, immH0 con) %{
 4825   match(Set dst con);
 4826 
 4827   ins_cost(XFER_COST);
 4828 
 4829   format %{ "fmv.h.x $dst, zr\t# float, #@loadConH0" %}
 4830 
 4831   ins_encode %{
 4832     assert(UseZfh || UseZfhmin, "must");
 4833     __ fmv_h_x(as_FloatRegister($dst$$reg), zr);
 4834   %}
 4835 
 4836   ins_pipe(fp_load_constant_s);
 4837 %}
 4838 
 4839 // Load Float Constant
 4840 instruct loadConF(fRegF dst, immF con) %{
 4841   match(Set dst con);
 4842 
 4843   ins_cost(LOAD_COST);
 4844   format %{
 4845     "flw $dst, [$constantaddress]\t# load from constant table: float=$con, #@loadConF"
 4846   %}
 4847 
 4848   ins_encode %{
 4849     if (MacroAssembler::can_fp_imm_load($con$$constant)) {
 4850       __ fli_s(as_FloatRegister($dst$$reg), $con$$constant);
 4851     } else {
 4852       __ flw(as_FloatRegister($dst$$reg), $constantaddress($con));
 4853     }
 4854   %}
 4855 
 4856   ins_pipe(fp_load_constant_s);
 4857 %}
 4858 
 4859 instruct loadConF0(fRegF dst, immF0 con) %{
 4860   match(Set dst con);
 4861 
 4862   ins_cost(XFER_COST);
 4863 
 4864   format %{ "fmv.w.x $dst, zr\t# float, #@loadConF0" %}
 4865 
 4866   ins_encode %{
 4867     __ fmv_w_x(as_FloatRegister($dst$$reg), zr);
 4868   %}
 4869 
 4870   ins_pipe(fp_load_constant_s);
 4871 %}
 4872 
 4873 // Load Double Constant
 4874 instruct loadConD(fRegD dst, immD con) %{
 4875   match(Set dst con);
 4876 
 4877   ins_cost(LOAD_COST);
 4878   format %{
 4879     "fld $dst, [$constantaddress]\t# load from constant table: double=$con, #@loadConD"
 4880   %}
 4881 
 4882   ins_encode %{
 4883     if (MacroAssembler::can_dp_imm_load($con$$constant)) {
 4884       __ fli_d(as_FloatRegister($dst$$reg), $con$$constant);
 4885     } else {
 4886       __ fld(as_FloatRegister($dst$$reg), $constantaddress($con));
 4887     }
 4888   %}
 4889 
 4890   ins_pipe(fp_load_constant_d);
 4891 %}
 4892 
 4893 instruct loadConD0(fRegD dst, immD0 con) %{
 4894   match(Set dst con);
 4895 
 4896   ins_cost(XFER_COST);
 4897 
 4898   format %{ "fmv.d.x $dst, zr\t# double, #@loadConD0" %}
 4899 
 4900   ins_encode %{
 4901     __ fmv_d_x(as_FloatRegister($dst$$reg), zr);
 4902   %}
 4903 
 4904   ins_pipe(fp_load_constant_d);
 4905 %}
 4906 
 4907 // Store Byte
 4908 instruct storeB(iRegIorL2I src, memory mem)
 4909 %{
 4910   match(Set mem (StoreB mem src));
 4911 
 4912   ins_cost(STORE_COST);
 4913   format %{ "sb  $src, $mem\t# byte, #@storeB" %}
 4914 
 4915   ins_encode %{
 4916     __ sb(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4917   %}
 4918 
 4919   ins_pipe(istore_reg_mem);
 4920 %}
 4921 
 4922 instruct storeimmB0(immI0 zero, memory mem)
 4923 %{
 4924   match(Set mem (StoreB mem zero));
 4925 
 4926   ins_cost(STORE_COST);
 4927   format %{ "sb zr, $mem\t# byte, #@storeimmB0" %}
 4928 
 4929   ins_encode %{
 4930     __ sb(zr, Address(as_Register($mem$$base), $mem$$disp));
 4931   %}
 4932 
 4933   ins_pipe(istore_mem);
 4934 %}
 4935 
 4936 // Store Char/Short
 4937 instruct storeC(iRegIorL2I src, memory mem)
 4938 %{
 4939   match(Set mem (StoreC mem src));
 4940 
 4941   ins_cost(STORE_COST);
 4942   format %{ "sh  $src, $mem\t# short, #@storeC" %}
 4943 
 4944   ins_encode %{
 4945     __ sh(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4946   %}
 4947 
 4948   ins_pipe(istore_reg_mem);
 4949 %}
 4950 
 4951 instruct storeimmC0(immI0 zero, memory mem)
 4952 %{
 4953   match(Set mem (StoreC mem zero));
 4954 
 4955   ins_cost(STORE_COST);
 4956   format %{ "sh  zr, $mem\t# short, #@storeimmC0" %}
 4957 
 4958   ins_encode %{
 4959     __ sh(zr, Address(as_Register($mem$$base), $mem$$disp));
 4960   %}
 4961 
 4962   ins_pipe(istore_mem);
 4963 %}
 4964 
 4965 // Store Integer
 4966 instruct storeI(iRegIorL2I src, memory mem)
 4967 %{
 4968   match(Set mem(StoreI mem src));
 4969 
 4970   ins_cost(STORE_COST);
 4971   format %{ "sw  $src, $mem\t# int, #@storeI" %}
 4972 
 4973   ins_encode %{
 4974     __ sw(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp));
 4975   %}
 4976 
 4977   ins_pipe(istore_reg_mem);
 4978 %}
 4979 
 4980 instruct storeimmI0(immI0 zero, memory mem)
 4981 %{
 4982   match(Set mem(StoreI mem zero));
 4983 
 4984   ins_cost(STORE_COST);
 4985   format %{ "sw  zr, $mem\t# int, #@storeimmI0" %}
 4986 
 4987   ins_encode %{
 4988     __ sw(zr, Address(as_Register($mem$$base), $mem$$disp));
 4989   %}
 4990 
 4991   ins_pipe(istore_mem);
 4992 %}
 4993 
 4994 // Store Long (64 bit signed)
 4995 instruct storeL(iRegL src, memory mem)
 4996 %{
 4997   match(Set mem (StoreL mem src));
 4998 
 4999   ins_cost(STORE_COST);
 5000   format %{ "sd  $src, $mem\t# long, #@storeL" %}
 5001 
 5002   ins_encode %{
 5003     __ sd(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp));
 5004   %}
 5005 
 5006   ins_pipe(istore_reg_mem);
 5007 %}
 5008 
 5009 // Store Long (64 bit signed)
 5010 instruct storeimmL0(immL0 zero, memory mem)
 5011 %{
 5012   match(Set mem (StoreL mem zero));
 5013 
 5014   ins_cost(STORE_COST);
 5015   format %{ "sd  zr, $mem\t# long, #@storeimmL0" %}
 5016 
 5017   ins_encode %{
 5018     __ sd(zr, Address(as_Register($mem$$base), $mem$$disp));
 5019   %}
 5020 
 5021   ins_pipe(istore_mem);
 5022 %}
 5023 
 5024 // Store Pointer
 5025 instruct storeP(iRegP src, memory mem)
 5026 %{
 5027   match(Set mem (StoreP mem src));
 5028   predicate(n->as_Store()->barrier_data() == 0);
 5029 
 5030   ins_cost(STORE_COST);
 5031   format %{ "sd  $src, $mem\t# ptr, #@storeP" %}
 5032 
 5033   ins_encode %{
 5034     __ sd(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp));
 5035   %}
 5036 
 5037   ins_pipe(istore_reg_mem);
 5038 %}
 5039 
 5040 // Store Pointer
 5041 instruct storeimmP0(immP0 zero, memory mem)
 5042 %{
 5043   match(Set mem (StoreP mem zero));
 5044   predicate(n->as_Store()->barrier_data() == 0);
 5045 
 5046   ins_cost(STORE_COST);
 5047   format %{ "sd zr, $mem\t# ptr, #@storeimmP0" %}
 5048 
 5049   ins_encode %{
 5050     __ sd(zr, Address(as_Register($mem$$base), $mem$$disp));
 5051   %}
 5052 
 5053   ins_pipe(istore_mem);
 5054 %}
 5055 
 5056 // Store Compressed Pointer
 5057 instruct storeN(iRegN src, memory mem)
 5058 %{
 5059   predicate(n->as_Store()->barrier_data() == 0);
 5060   match(Set mem (StoreN mem src));
 5061 
 5062   ins_cost(STORE_COST);
 5063   format %{ "sw  $src, $mem\t# compressed ptr, #@storeN" %}
 5064 
 5065   ins_encode %{
 5066     __ sw(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp));
 5067   %}
 5068 
 5069   ins_pipe(istore_reg_mem);
 5070 %}
 5071 
 5072 instruct storeImmN0(immN0 zero, memory mem)
 5073 %{
 5074   predicate(n->as_Store()->barrier_data() == 0);
 5075   match(Set mem (StoreN mem zero));
 5076 
 5077   ins_cost(STORE_COST);
 5078   format %{ "sw  zr, $mem\t# compressed ptr, #@storeImmN0" %}
 5079 
 5080   ins_encode %{
 5081     __ sw(zr, Address(as_Register($mem$$base), $mem$$disp));
 5082   %}
 5083 
 5084   ins_pipe(istore_reg_mem);
 5085 %}
 5086 
 5087 // Store Float
 5088 instruct storeF(fRegF src, memory mem)
 5089 %{
 5090   match(Set mem (StoreF mem src));
 5091 
 5092   ins_cost(STORE_COST);
 5093   format %{ "fsw  $src, $mem\t# float, #@storeF" %}
 5094 
 5095   ins_encode %{
 5096     __ fsw(as_FloatRegister($src$$reg), Address(as_Register($mem$$base), $mem$$disp));
 5097   %}
 5098 
 5099   ins_pipe(fp_store_reg_s);
 5100 %}
 5101 
 5102 // Store Double
 5103 instruct storeD(fRegD src, memory mem)
 5104 %{
 5105   match(Set mem (StoreD mem src));
 5106 
 5107   ins_cost(STORE_COST);
 5108   format %{ "fsd  $src, $mem\t# double, #@storeD" %}
 5109 
 5110   ins_encode %{
 5111     __ fsd(as_FloatRegister($src$$reg), Address(as_Register($mem$$base), $mem$$disp));
 5112   %}
 5113 
 5114   ins_pipe(fp_store_reg_d);
 5115 %}
 5116 
 5117 // Store Compressed Klass Pointer
 5118 instruct storeNKlass(iRegN src, memory mem)
 5119 %{
 5120   match(Set mem (StoreNKlass mem src));
 5121 
 5122   ins_cost(STORE_COST);
 5123   format %{ "sw  $src, $mem\t# compressed klass ptr, #@storeNKlass" %}
 5124 
 5125   ins_encode %{
 5126     __ sw(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp));
 5127   %}
 5128 
 5129   ins_pipe(istore_reg_mem);
 5130 %}
 5131 
 5132 // ============================================================================
 5133 // Prefetch instructions
 5134 // Must be safe to execute with invalid address (cannot fault).
 5135 
 5136 instruct prefetchalloc( memory mem ) %{
 5137   predicate(UseZicbop);
 5138   match(PrefetchAllocation mem);
 5139 
 5140   ins_cost(ALU_COST * 1);
 5141   format %{ "prefetch_w $mem\t# Prefetch for write" %}
 5142 
 5143   ins_encode %{
 5144     if (Assembler::is_simm12($mem$$disp)) {
 5145       if (($mem$$disp & 0x1f) == 0) {
 5146         __ prefetch_w(as_Register($mem$$base), $mem$$disp);
 5147       } else {
 5148         __ addi(t0, as_Register($mem$$base), $mem$$disp);
 5149         __ prefetch_w(t0, 0);
 5150       }
 5151     } else {
 5152       __ mv(t0, $mem$$disp);
 5153       __ add(t0, as_Register($mem$$base), t0);
 5154       __ prefetch_w(t0, 0);
 5155     }
 5156   %}
 5157 
 5158   ins_pipe(iload_prefetch);
 5159 %}
 5160 
 5161 // ============================================================================
 5162 // Atomic operation instructions
 5163 //
 5164 
 5165 // standard CompareAndSwapX when we are using barriers
 5166 // these have higher priority than the rules selected by a predicate
 5167 instruct compareAndSwapB_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval,
 5168                                 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr)
 5169 %{
 5170   predicate(!UseZabha || !UseZacas);
 5171 
 5172   match(Set res (CompareAndSwapB mem (Binary oldval newval)));
 5173 
 5174   ins_cost(2 * VOLATILE_REF_COST);
 5175 
 5176   effect(TEMP_DEF res, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
 5177 
 5178   format %{
 5179     "cmpxchg $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval\n\t"
 5180     "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapB_narrow"
 5181   %}
 5182 
 5183   ins_encode %{
 5184     __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8,
 5185                             Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register,
 5186                             true /* result as bool */, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
 5187   %}
 5188 
 5189   ins_pipe(pipe_slow);
 5190 %}
 5191 
 5192 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval)
 5193 %{
 5194   predicate(UseZabha && UseZacas);
 5195 
 5196   match(Set res (CompareAndSwapB mem (Binary oldval newval)));
 5197 
 5198   ins_cost(2 * VOLATILE_REF_COST);
 5199 
 5200   format %{
 5201     "cmpxchg $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval\n\t"
 5202     "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapB"
 5203   %}
 5204 
 5205   ins_encode %{
 5206     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8,
 5207                Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register,
 5208                true /* result as bool */);
 5209   %}
 5210 
 5211   ins_pipe(pipe_slow);
 5212 %}
 5213 
 5214 instruct compareAndSwapS_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval,
 5215                                 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr)
 5216 %{
 5217   predicate(!UseZabha || !UseZacas);
 5218 
 5219   match(Set res (CompareAndSwapS mem (Binary oldval newval)));
 5220 
 5221   ins_cost(2 * VOLATILE_REF_COST);
 5222 
 5223   effect(TEMP_DEF res, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
 5224 
 5225   format %{
 5226     "cmpxchg $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval\n\t"
 5227     "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapS_narrow"
 5228   %}
 5229 
 5230   ins_encode %{
 5231     __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16,
 5232                             Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register,
 5233                             true /* result as bool */, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
 5234   %}
 5235 
 5236   ins_pipe(pipe_slow);
 5237 %}
 5238 
 5239 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval)
 5240 %{
 5241   predicate(UseZabha && UseZacas);
 5242 
 5243   match(Set res (CompareAndSwapS mem (Binary oldval newval)));
 5244 
 5245   ins_cost(2 * VOLATILE_REF_COST);
 5246 
 5247   format %{
 5248     "cmpxchg $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval\n\t"
 5249     "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapS"
 5250   %}
 5251 
 5252   ins_encode %{
 5253     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16,
 5254                Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register,
 5255                true /* result as bool */);
 5256   %}
 5257 
 5258   ins_pipe(pipe_slow);
 5259 %}
 5260 
 5261 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval)
 5262 %{
 5263   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
 5264 
 5265   ins_cost(2 * VOLATILE_REF_COST);
 5266 
 5267   format %{
 5268     "cmpxchg $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval\n\t"
 5269     "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapI"
 5270   %}
 5271 
 5272   ins_encode %{
 5273     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32,
 5274                /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register,
 5275                /*result as bool*/ true);
 5276   %}
 5277 
 5278   ins_pipe(pipe_slow);
 5279 %}
 5280 
 5281 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval)
 5282 %{
 5283   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
 5284 
 5285   ins_cost(2 * VOLATILE_REF_COST);
 5286 
 5287   format %{
 5288     "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval\n\t"
 5289     "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapL"
 5290   %}
 5291 
 5292   ins_encode %{
 5293     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64,
 5294                /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register,
 5295                /*result as bool*/ true);
 5296   %}
 5297 
 5298   ins_pipe(pipe_slow);
 5299 %}
 5300 
 5301 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval)
 5302 %{
 5303   predicate(n->as_LoadStore()->barrier_data() == 0);
 5304 
 5305   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
 5306 
 5307   ins_cost(2 * VOLATILE_REF_COST);
 5308 
 5309   format %{
 5310     "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval\n\t"
 5311     "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapP"
 5312   %}
 5313 
 5314   ins_encode %{
 5315     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64,
 5316                /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register,
 5317                /*result as bool*/ true);
 5318   %}
 5319 
 5320   ins_pipe(pipe_slow);
 5321 %}
 5322 
 5323 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval)
 5324 %{
 5325   predicate(n->as_LoadStore()->barrier_data() == 0);
 5326 
 5327   match(Set res (CompareAndSwapN mem (Binary oldval newval)));
 5328 
 5329   ins_cost(2 * VOLATILE_REF_COST);
 5330 
 5331   format %{
 5332     "cmpxchg $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval\n\t"
 5333     "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapN"
 5334   %}
 5335 
 5336   ins_encode %{
 5337     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32,
 5338                /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register,
 5339                /*result as bool*/ true);
 5340   %}
 5341 
 5342   ins_pipe(pipe_slow);
 5343 %}
 5344 
 5345 // alternative CompareAndSwapX when we are eliding barriers
 5346 instruct compareAndSwapBAcq_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval,
 5347                                    iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr)
 5348 %{
 5349   predicate((!UseZabha || !UseZacas) && needs_acquiring_load_reserved(n));
 5350 
 5351   match(Set res (CompareAndSwapB mem (Binary oldval newval)));
 5352 
 5353   ins_cost(2 * VOLATILE_REF_COST);
 5354 
 5355   effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3);
 5356 
 5357   format %{
 5358     "cmpxchg_acq $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval\n\t"
 5359     "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapBAcq_narrow"
 5360   %}
 5361 
 5362   ins_encode %{
 5363     __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8,
 5364                             Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register,
 5365                             true /* result as bool */, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
 5366   %}
 5367 
 5368   ins_pipe(pipe_slow);
 5369 %}
 5370 
 5371 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval)
 5372 %{
 5373   predicate((UseZabha && UseZacas) && needs_acquiring_load_reserved(n));
 5374 
 5375   match(Set res (CompareAndSwapB mem (Binary oldval newval)));
 5376 
 5377   ins_cost(2 * VOLATILE_REF_COST);
 5378 
 5379   format %{
 5380     "cmpxchg $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval\n\t"
 5381     "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapBAcq"
 5382   %}
 5383 
 5384   ins_encode %{
 5385     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8,
 5386                Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register,
 5387                true /* result as bool */);
 5388   %}
 5389 
 5390   ins_pipe(pipe_slow);
 5391 %}
 5392 
 5393 instruct compareAndSwapSAcq_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval,
 5394                                    iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr)
 5395 %{
 5396   predicate((!UseZabha || !UseZacas) && needs_acquiring_load_reserved(n));
 5397 
 5398   match(Set res (CompareAndSwapS mem (Binary oldval newval)));
 5399 
 5400   ins_cost(2 * VOLATILE_REF_COST);
 5401 
 5402   effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3);
 5403 
 5404   format %{
 5405     "cmpxchg_acq $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval\n\t"
 5406     "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapSAcq_narrow"
 5407   %}
 5408 
 5409   ins_encode %{
 5410     __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16,
 5411                             Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register,
 5412                             true /* result as bool */, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
 5413   %}
 5414 
 5415   ins_pipe(pipe_slow);
 5416 %}
 5417 
 5418 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval)
 5419 %{
 5420   predicate((UseZabha && UseZacas) && needs_acquiring_load_reserved(n));
 5421 
 5422   match(Set res (CompareAndSwapS mem (Binary oldval newval)));
 5423 
 5424   ins_cost(2 * VOLATILE_REF_COST);
 5425 
 5426   format %{
 5427     "cmpxchg $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval\n\t"
 5428     "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapSAcq"
 5429   %}
 5430 
 5431   ins_encode %{
 5432     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16,
 5433                Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register,
 5434                true /* result as bool */);
 5435   %}
 5436 
 5437   ins_pipe(pipe_slow);
 5438 %}
 5439 
 5440 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval)
 5441 %{
 5442   predicate(needs_acquiring_load_reserved(n));
 5443 
 5444   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
 5445 
 5446   ins_cost(2 * VOLATILE_REF_COST);
 5447 
 5448   format %{
 5449     "cmpxchg_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval\n\t"
 5450     "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapIAcq"
 5451   %}
 5452 
 5453   ins_encode %{
 5454     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32,
 5455                /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register,
 5456                /*result as bool*/ true);
 5457   %}
 5458 
 5459   ins_pipe(pipe_slow);
 5460 %}
 5461 
 5462 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval)
 5463 %{
 5464   predicate(needs_acquiring_load_reserved(n));
 5465 
 5466   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
 5467 
 5468   ins_cost(2 * VOLATILE_REF_COST);
 5469 
 5470   format %{
 5471     "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval\n\t"
 5472     "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapLAcq"
 5473   %}
 5474 
 5475   ins_encode %{
 5476     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64,
 5477                /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register,
 5478                /*result as bool*/ true);
 5479   %}
 5480 
 5481   ins_pipe(pipe_slow);
 5482 %}
 5483 
 5484 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval)
 5485 %{
 5486   predicate(needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == 0));
 5487 
 5488   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
 5489 
 5490   ins_cost(2 * VOLATILE_REF_COST);
 5491 
 5492   format %{
 5493     "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval\n\t"
 5494     "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapPAcq"
 5495   %}
 5496 
 5497   ins_encode %{
 5498     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64,
 5499                /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register,
 5500                /*result as bool*/ true);
 5501   %}
 5502 
 5503   ins_pipe(pipe_slow);
 5504 %}
 5505 
 5506 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval)
 5507 %{
 5508   predicate(needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == 0);
 5509 
 5510   match(Set res (CompareAndSwapN mem (Binary oldval newval)));
 5511 
 5512   ins_cost(2 * VOLATILE_REF_COST);
 5513 
 5514   format %{
 5515     "cmpxchg_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval\n\t"
 5516     "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapNAcq"
 5517   %}
 5518 
 5519   ins_encode %{
 5520     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32,
 5521                /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register,
 5522                /*result as bool*/ true);
 5523   %}
 5524 
 5525   ins_pipe(pipe_slow);
 5526 %}
 5527 
 5528 // Sundry CAS operations.  Note that release is always true,
 5529 // regardless of the memory ordering of the CAS.  This is because we
 5530 // need the volatile case to be sequentially consistent but there is
 5531 // no trailing StoreLoad barrier emitted by C2.  Unfortunately we
 5532 // can't check the type of memory ordering here, so we always emit a
 5533 // sc_d(w) with rl bit set.
 5534 instruct compareAndExchangeB_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval,
 5535                                     iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr)
 5536 %{
 5537   predicate(!UseZabha || !UseZacas);
 5538 
 5539   match(Set res (CompareAndExchangeB mem (Binary oldval newval)));
 5540 
 5541   ins_cost(2 * VOLATILE_REF_COST);
 5542 
 5543   effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3);
 5544 
 5545   format %{
 5546     "cmpxchg $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeB_narrow"
 5547   %}
 5548 
 5549   ins_encode %{
 5550     __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8,
 5551                             /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register,
 5552                             /*result_as_bool*/ false, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
 5553   %}
 5554 
 5555   ins_pipe(pipe_slow);
 5556 %}
 5557 
 5558 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval)
 5559 %{
 5560   predicate(UseZabha && UseZacas);
 5561 
 5562   match(Set res (CompareAndExchangeB mem (Binary oldval newval)));
 5563 
 5564   ins_cost(2 * VOLATILE_REF_COST);
 5565 
 5566   format %{
 5567     "cmpxchg $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeB"
 5568   %}
 5569 
 5570   ins_encode %{
 5571     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8,
 5572                /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register);
 5573   %}
 5574 
 5575   ins_pipe(pipe_slow);
 5576 %}
 5577 
 5578 instruct compareAndExchangeS_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval,
 5579                                     iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr)
 5580 %{
 5581   predicate(!UseZabha || !UseZacas);
 5582 
 5583   match(Set res (CompareAndExchangeS mem (Binary oldval newval)));
 5584 
 5585   ins_cost(2 * VOLATILE_REF_COST);
 5586 
 5587   effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3);
 5588 
 5589   format %{
 5590     "cmpxchg $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeS_narrow"
 5591   %}
 5592 
 5593   ins_encode %{
 5594     __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16,
 5595                             /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register,
 5596                             /*result_as_bool*/ false, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
 5597   %}
 5598 
 5599   ins_pipe(pipe_slow);
 5600 %}
 5601 
 5602 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval)
 5603 %{
 5604   predicate(UseZabha && UseZacas);
 5605 
 5606   match(Set res (CompareAndExchangeS mem (Binary oldval newval)));
 5607 
 5608   ins_cost(2 * VOLATILE_REF_COST);
 5609 
 5610   format %{
 5611     "cmpxchg $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeS"
 5612   %}
 5613 
 5614   ins_encode %{
 5615     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16,
 5616                /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register);
 5617   %}
 5618 
 5619   ins_pipe(pipe_slow);
 5620 %}
 5621 
 5622 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval)
 5623 %{
 5624   match(Set res (CompareAndExchangeI mem (Binary oldval newval)));
 5625 
 5626   ins_cost(2 * VOLATILE_REF_COST);
 5627 
 5628   format %{
 5629     "cmpxchg $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeI"
 5630   %}
 5631 
 5632   ins_encode %{
 5633     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32,
 5634                /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register);
 5635   %}
 5636 
 5637   ins_pipe(pipe_slow);
 5638 %}
 5639 
 5640 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval)
 5641 %{
 5642   match(Set res (CompareAndExchangeL mem (Binary oldval newval)));
 5643 
 5644   ins_cost(2 * VOLATILE_REF_COST);
 5645 
 5646   format %{
 5647     "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeL"
 5648   %}
 5649 
 5650   ins_encode %{
 5651     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64,
 5652                /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register);
 5653   %}
 5654 
 5655   ins_pipe(pipe_slow);
 5656 %}
 5657 
 5658 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval)
 5659 %{
 5660   predicate(n->as_LoadStore()->barrier_data() == 0);
 5661 
 5662   match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
 5663 
 5664   ins_cost(2 * VOLATILE_REF_COST);
 5665 
 5666   format %{
 5667     "cmpxchg $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeN"
 5668   %}
 5669 
 5670   ins_encode %{
 5671     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32,
 5672                /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register);
 5673   %}
 5674 
 5675   ins_pipe(pipe_slow);
 5676 %}
 5677 
 5678 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval)
 5679 %{
 5680   predicate(n->as_LoadStore()->barrier_data() == 0);
 5681 
 5682   match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
 5683 
 5684   ins_cost(2 * VOLATILE_REF_COST);
 5685 
 5686   format %{
 5687     "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeP"
 5688   %}
 5689 
 5690   ins_encode %{
 5691     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64,
 5692                /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register);
 5693   %}
 5694 
 5695   ins_pipe(pipe_slow);
 5696 %}
 5697 
 5698 instruct compareAndExchangeBAcq_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval,
 5699                                        iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr)
 5700 %{
 5701   predicate((!UseZabha || !UseZacas) && needs_acquiring_load_reserved(n));
 5702 
 5703   match(Set res (CompareAndExchangeB mem (Binary oldval newval)));
 5704 
 5705   ins_cost(2 * VOLATILE_REF_COST);
 5706 
 5707   effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3);
 5708 
 5709   format %{
 5710     "cmpxchg_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeBAcq_narrow"
 5711   %}
 5712 
 5713   ins_encode %{
 5714     __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8,
 5715                             /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register,
 5716                             /*result_as_bool*/ false, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
 5717   %}
 5718 
 5719   ins_pipe(pipe_slow);
 5720 %}
 5721 
 5722 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval)
 5723 %{
 5724   predicate((UseZabha && UseZacas) && needs_acquiring_load_reserved(n));
 5725 
 5726   match(Set res (CompareAndExchangeB mem (Binary oldval newval)));
 5727 
 5728   ins_cost(2 * VOLATILE_REF_COST);
 5729 
 5730   format %{
 5731     "cmpxchg_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeBAcq"
 5732   %}
 5733 
 5734   ins_encode %{
 5735     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8,
 5736                /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register);
 5737   %}
 5738 
 5739   ins_pipe(pipe_slow);
 5740 %}
 5741 
 5742 instruct compareAndExchangeSAcq_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval,
 5743                                        iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr)
 5744 %{
 5745   predicate((!UseZabha || !UseZacas) && needs_acquiring_load_reserved(n));
 5746 
 5747   match(Set res (CompareAndExchangeS mem (Binary oldval newval)));
 5748 
 5749   ins_cost(2 * VOLATILE_REF_COST);
 5750 
 5751   effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3);
 5752 
 5753   format %{
 5754     "cmpxchg_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeSAcq_narrow"
 5755   %}
 5756 
 5757   ins_encode %{
 5758     __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16,
 5759                             /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register,
 5760                             /*result_as_bool*/ false, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
 5761   %}
 5762 
 5763   ins_pipe(pipe_slow);
 5764 %}
 5765 
 5766 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval)
 5767 %{
 5768   predicate((UseZabha && UseZacas) && needs_acquiring_load_reserved(n));
 5769 
 5770   match(Set res (CompareAndExchangeS mem (Binary oldval newval)));
 5771 
 5772   ins_cost(2 * VOLATILE_REF_COST);
 5773 
 5774   format %{
 5775     "cmpxchg_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeSAcq"
 5776   %}
 5777 
 5778   ins_encode %{
 5779     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16,
 5780                /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register);
 5781   %}
 5782 
 5783   ins_pipe(pipe_slow);
 5784 %}
 5785 
 5786 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval)
 5787 %{
 5788   predicate(needs_acquiring_load_reserved(n));
 5789 
 5790   match(Set res (CompareAndExchangeI mem (Binary oldval newval)));
 5791 
 5792   ins_cost(2 * VOLATILE_REF_COST);
 5793 
 5794   format %{
 5795     "cmpxchg_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeIAcq"
 5796   %}
 5797 
 5798   ins_encode %{
 5799     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32,
 5800                /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register);
 5801   %}
 5802 
 5803   ins_pipe(pipe_slow);
 5804 %}
 5805 
 5806 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval)
 5807 %{
 5808   predicate(needs_acquiring_load_reserved(n));
 5809 
 5810   match(Set res (CompareAndExchangeL mem (Binary oldval newval)));
 5811 
 5812   ins_cost(2 * VOLATILE_REF_COST);
 5813 
 5814   format %{
 5815     "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeLAcq"
 5816   %}
 5817 
 5818   ins_encode %{
 5819     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64,
 5820                /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register);
 5821   %}
 5822 
 5823   ins_pipe(pipe_slow);
 5824 %}
 5825 
 5826 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval)
 5827 %{
 5828   predicate(needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == 0);
 5829 
 5830   match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
 5831 
 5832   ins_cost(2 * VOLATILE_REF_COST);
 5833 
 5834   format %{
 5835     "cmpxchg_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeNAcq"
 5836   %}
 5837 
 5838   ins_encode %{
 5839     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32,
 5840                /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register);
 5841   %}
 5842 
 5843   ins_pipe(pipe_slow);
 5844 %}
 5845 
 5846 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval)
 5847 %{
 5848   predicate(needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == 0));
 5849 
 5850   match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
 5851 
 5852   ins_cost(2 * VOLATILE_REF_COST);
 5853 
 5854   format %{
 5855     "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangePAcq"
 5856   %}
 5857 
 5858   ins_encode %{
 5859     __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64,
 5860                /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register);
 5861   %}
 5862 
 5863   ins_pipe(pipe_slow);
 5864 %}
 5865 
 5866 instruct weakCompareAndSwapB_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval,
 5867                                     iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr)
 5868 %{
 5869   predicate(!UseZabha || !UseZacas);
 5870 
 5871   match(Set res (WeakCompareAndSwapB mem (Binary oldval newval)));
 5872 
 5873   ins_cost(2 * VOLATILE_REF_COST);
 5874 
 5875   effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3);
 5876 
 5877   format %{
 5878     "weak_cmpxchg $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval\n\t"
 5879     "# $res == 1 when success, #@weakCompareAndSwapB_narrow"
 5880   %}
 5881 
 5882   ins_encode %{
 5883     __ weak_cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8,
 5884                                  /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register,
 5885                                  $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
 5886   %}
 5887 
 5888   ins_pipe(pipe_slow);
 5889 %}
 5890 
 5891 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval)
 5892 %{
 5893   predicate(UseZabha && UseZacas);
 5894 
 5895   match(Set res (WeakCompareAndSwapB mem (Binary oldval newval)));
 5896 
 5897   ins_cost(2 * VOLATILE_REF_COST);
 5898 
 5899   format %{
 5900     "weak_cmpxchg $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval\n\t"
 5901     "# $res == 1 when success, #@weakCompareAndSwapB"
 5902   %}
 5903 
 5904   ins_encode %{
 5905     __ weak_cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8,
 5906                     /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register);
 5907   %}
 5908 
 5909   ins_pipe(pipe_slow);
 5910 %}
 5911 
 5912 instruct weakCompareAndSwapS_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval,
 5913                                     iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr)
 5914 %{
 5915   predicate(!UseZabha || !UseZacas);
 5916 
 5917   match(Set res (WeakCompareAndSwapS mem (Binary oldval newval)));
 5918 
 5919   ins_cost(2 * VOLATILE_REF_COST);
 5920 
 5921   effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3);
 5922 
 5923   format %{
 5924     "weak_cmpxchg $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval\n\t"
 5925     "# $res == 1 when success, #@weakCompareAndSwapS_narrow"
 5926   %}
 5927 
 5928   ins_encode %{
 5929     __ weak_cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16,
 5930                                  /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register,
 5931                                  $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
 5932   %}
 5933 
 5934   ins_pipe(pipe_slow);
 5935 %}
 5936 
 5937 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval)
 5938 %{
 5939   predicate(UseZabha && UseZacas);
 5940 
 5941   match(Set res (WeakCompareAndSwapS mem (Binary oldval newval)));
 5942 
 5943   ins_cost(2 * VOLATILE_REF_COST);
 5944 
 5945   format %{
 5946     "weak_cmpxchg $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval\n\t"
 5947     "# $res == 1 when success, #@weakCompareAndSwapS"
 5948   %}
 5949 
 5950   ins_encode %{
 5951     __ weak_cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16,
 5952                     /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register);
 5953   %}
 5954 
 5955   ins_pipe(pipe_slow);
 5956 %}
 5957 
 5958 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval)
 5959 %{
 5960   match(Set res (WeakCompareAndSwapI mem (Binary oldval newval)));
 5961 
 5962   ins_cost(2 * VOLATILE_REF_COST);
 5963 
 5964   format %{
 5965     "weak_cmpxchg $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval\n\t"
 5966     "# $res == 1 when success, #@weakCompareAndSwapI"
 5967   %}
 5968 
 5969   ins_encode %{
 5970     __ weak_cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32,
 5971                     /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register);
 5972   %}
 5973 
 5974   ins_pipe(pipe_slow);
 5975 %}
 5976 
 5977 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval)
 5978 %{
 5979   match(Set res (WeakCompareAndSwapL mem (Binary oldval newval)));
 5980 
 5981   ins_cost(2 * VOLATILE_REF_COST);
 5982 
 5983   format %{
 5984     "weak_cmpxchg $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval\n\t"
 5985     "# $res == 1 when success, #@weakCompareAndSwapL"
 5986   %}
 5987 
 5988   ins_encode %{
 5989     __ weak_cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64,
 5990                     /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register);
 5991   %}
 5992 
 5993   ins_pipe(pipe_slow);
 5994 %}
 5995 
 5996 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval)
 5997 %{
 5998   predicate(n->as_LoadStore()->barrier_data() == 0);
 5999 
 6000   match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
 6001 
 6002   ins_cost(2 * VOLATILE_REF_COST);
 6003 
 6004   format %{
 6005     "weak_cmpxchg $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval\n\t"
 6006     "# $res == 1 when success, #@weakCompareAndSwapN"
 6007   %}
 6008 
 6009   ins_encode %{
 6010     __ weak_cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32,
 6011                     /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register);
 6012   %}
 6013 
 6014   ins_pipe(pipe_slow);
 6015 %}
 6016 
 6017 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval)
 6018 %{
 6019   predicate(n->as_LoadStore()->barrier_data() == 0);
 6020 
 6021   match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
 6022 
 6023   ins_cost(2 * VOLATILE_REF_COST);
 6024 
 6025   format %{
 6026     "weak_cmpxchg $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval\n\t"
 6027     "# $res == 1 when success, #@weakCompareAndSwapP"
 6028   %}
 6029 
 6030   ins_encode %{
 6031     __ weak_cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64,
 6032                     /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register);
 6033   %}
 6034 
 6035   ins_pipe(pipe_slow);
 6036 %}
 6037 
 6038 instruct weakCompareAndSwapBAcq_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval,
 6039                                        iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr)
 6040 %{
 6041   predicate((!UseZabha || !UseZacas) && needs_acquiring_load_reserved(n));
 6042 
 6043   match(Set res (WeakCompareAndSwapB mem (Binary oldval newval)));
 6044 
 6045   ins_cost(2 * VOLATILE_REF_COST);
 6046 
 6047   effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3);
 6048 
 6049   format %{
 6050     "weak_cmpxchg_acq $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval\n\t"
 6051     "# $res == 1 when success, #@weakCompareAndSwapBAcq_narrow"
 6052   %}
 6053 
 6054   ins_encode %{
 6055     __ weak_cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8,
 6056                                  /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register,
 6057                                  $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
 6058   %}
 6059 
 6060   ins_pipe(pipe_slow);
 6061 %}
 6062 
 6063 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval)
 6064 %{
 6065   predicate((UseZabha && UseZacas) && needs_acquiring_load_reserved(n));
 6066 
 6067   match(Set res (WeakCompareAndSwapB mem (Binary oldval newval)));
 6068 
 6069   ins_cost(2 * VOLATILE_REF_COST);
 6070 
 6071   format %{
 6072     "weak_cmpxchg_acq $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval\n\t"
 6073     "# $res == 1 when success, #@weakCompareAndSwapBAcq"
 6074   %}
 6075 
 6076   ins_encode %{
 6077     __ weak_cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8,
 6078                     /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register);
 6079   %}
 6080 
 6081   ins_pipe(pipe_slow);
 6082 %}
 6083 
 6084 instruct weakCompareAndSwapSAcq_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval,
 6085                                        iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr)
 6086 %{
 6087   predicate((!UseZabha || !UseZacas) && needs_acquiring_load_reserved(n));
 6088 
 6089   match(Set res (WeakCompareAndSwapS mem (Binary oldval newval)));
 6090 
 6091   ins_cost(2 * VOLATILE_REF_COST);
 6092 
 6093   effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3);
 6094 
 6095   format %{
 6096     "weak_cmpxchg_acq $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval\n\t"
 6097     "# $res == 1 when success, #@weakCompareAndSwapSAcq_narrow"
 6098   %}
 6099 
 6100   ins_encode %{
 6101     __ weak_cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16,
 6102                                  /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register,
 6103                                  $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
 6104   %}
 6105 
 6106   ins_pipe(pipe_slow);
 6107 %}
 6108 
 6109 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval)
 6110 %{
 6111   predicate((UseZabha && UseZacas) && needs_acquiring_load_reserved(n));
 6112 
 6113   match(Set res (WeakCompareAndSwapS mem (Binary oldval newval)));
 6114 
 6115   ins_cost(2 * VOLATILE_REF_COST);
 6116 
 6117   format %{
 6118     "weak_cmpxchg_acq $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval\n\t"
 6119     "# $res == 1 when success, #@weakCompareAndSwapSAcq"
 6120   %}
 6121 
 6122   ins_encode %{
 6123     __ weak_cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16,
 6124                     /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register);
 6125   %}
 6126 
 6127   ins_pipe(pipe_slow);
 6128 %}
 6129 
 6130 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval)
 6131 %{
 6132   predicate(needs_acquiring_load_reserved(n));
 6133 
 6134   match(Set res (WeakCompareAndSwapI mem (Binary oldval newval)));
 6135 
 6136   ins_cost(2 * VOLATILE_REF_COST);
 6137 
 6138   format %{
 6139     "weak_cmpxchg_acq $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval\n\t"
 6140     "# $res == 1 when success, #@weakCompareAndSwapIAcq"
 6141   %}
 6142 
 6143   ins_encode %{
 6144     __ weak_cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32,
 6145                     /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register);
 6146   %}
 6147 
 6148   ins_pipe(pipe_slow);
 6149 %}
 6150 
 6151 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval)
 6152 %{
 6153   predicate(needs_acquiring_load_reserved(n));
 6154 
 6155   match(Set res (WeakCompareAndSwapL mem (Binary oldval newval)));
 6156 
 6157   ins_cost(2 * VOLATILE_REF_COST);
 6158 
 6159   format %{
 6160     "weak_cmpxchg_acq $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval\n\t"
 6161     "# $res == 1 when success, #@weakCompareAndSwapLAcq"
 6162   %}
 6163 
 6164   ins_encode %{
 6165     __ weak_cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64,
 6166                     /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register);
 6167   %}
 6168 
 6169   ins_pipe(pipe_slow);
 6170 %}
 6171 
 6172 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval)
 6173 %{
 6174   predicate(needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == 0);
 6175 
 6176   match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
 6177 
 6178   ins_cost(2 * VOLATILE_REF_COST);
 6179 
 6180   format %{
 6181     "weak_cmpxchg_acq $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval\n\t"
 6182     "# $res == 1 when success, #@weakCompareAndSwapNAcq"
 6183   %}
 6184 
 6185   ins_encode %{
 6186     __ weak_cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32,
 6187                     /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register);
 6188   %}
 6189 
 6190   ins_pipe(pipe_slow);
 6191 %}
 6192 
 6193 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval)
 6194 %{
 6195   predicate(needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == 0));
 6196 
 6197   match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
 6198 
 6199   ins_cost(2 * VOLATILE_REF_COST);
 6200 
 6201   format %{
 6202     "weak_cmpxchg_acq $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval\n\t"
 6203     "\t# $res == 1 when success, #@weakCompareAndSwapPAcq"
 6204   %}
 6205 
 6206   ins_encode %{
 6207     __ weak_cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64,
 6208                     /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register);
 6209   %}
 6210 
 6211   ins_pipe(pipe_slow);
 6212 %}
 6213 
 6214 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev)
 6215 %{
 6216   match(Set prev (GetAndSetI mem newv));
 6217 
 6218   ins_cost(ALU_COST);
 6219 
 6220   format %{ "atomic_xchgw  $prev, $newv, [$mem]\t#@get_and_setI" %}
 6221 
 6222   ins_encode %{
 6223     __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base));
 6224   %}
 6225 
 6226   ins_pipe(pipe_serial);
 6227 %}
 6228 
 6229 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev)
 6230 %{
 6231   match(Set prev (GetAndSetL mem newv));
 6232 
 6233   ins_cost(ALU_COST);
 6234 
 6235   format %{ "atomic_xchg  $prev, $newv, [$mem]\t#@get_and_setL" %}
 6236 
 6237   ins_encode %{
 6238     __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
 6239   %}
 6240 
 6241   ins_pipe(pipe_serial);
 6242 %}
 6243 
 6244 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev)
 6245 %{
 6246   predicate(n->as_LoadStore()->barrier_data() == 0);
 6247 
 6248   match(Set prev (GetAndSetN mem newv));
 6249 
 6250   ins_cost(ALU_COST);
 6251 
 6252   format %{ "atomic_xchgwu $prev, $newv, [$mem]\t#@get_and_setN" %}
 6253 
 6254   ins_encode %{
 6255     __ atomic_xchgwu($prev$$Register, $newv$$Register, as_Register($mem$$base));
 6256   %}
 6257 
 6258   ins_pipe(pipe_serial);
 6259 %}
 6260 
 6261 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev)
 6262 %{
 6263   predicate(n->as_LoadStore()->barrier_data() == 0);
 6264   match(Set prev (GetAndSetP mem newv));
 6265 
 6266   ins_cost(ALU_COST);
 6267 
 6268   format %{ "atomic_xchg  $prev, $newv, [$mem]\t#@get_and_setP" %}
 6269 
 6270   ins_encode %{
 6271     __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
 6272   %}
 6273 
 6274   ins_pipe(pipe_serial);
 6275 %}
 6276 
 6277 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev)
 6278 %{
 6279   predicate(needs_acquiring_load_reserved(n));
 6280 
 6281   match(Set prev (GetAndSetI mem newv));
 6282 
 6283   ins_cost(ALU_COST);
 6284 
 6285   format %{ "atomic_xchgw_acq  $prev, $newv, [$mem]\t#@get_and_setIAcq" %}
 6286 
 6287   ins_encode %{
 6288     __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base));
 6289   %}
 6290 
 6291   ins_pipe(pipe_serial);
 6292 %}
 6293 
 6294 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev)
 6295 %{
 6296   predicate(needs_acquiring_load_reserved(n));
 6297 
 6298   match(Set prev (GetAndSetL mem newv));
 6299 
 6300   ins_cost(ALU_COST);
 6301 
 6302   format %{ "atomic_xchg_acq  $prev, $newv, [$mem]\t#@get_and_setLAcq" %}
 6303 
 6304   ins_encode %{
 6305     __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base));
 6306   %}
 6307 
 6308   ins_pipe(pipe_serial);
 6309 %}
 6310 
 6311 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev)
 6312 %{
 6313   predicate(needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == 0);
 6314 
 6315   match(Set prev (GetAndSetN mem newv));
 6316 
 6317   ins_cost(ALU_COST);
 6318 
 6319   format %{ "atomic_xchgwu_acq $prev, $newv, [$mem]\t#@get_and_setNAcq" %}
 6320 
 6321   ins_encode %{
 6322     __ atomic_xchgalwu($prev$$Register, $newv$$Register, as_Register($mem$$base));
 6323   %}
 6324 
 6325   ins_pipe(pipe_serial);
 6326 %}
 6327 
 6328 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev)
 6329 %{
 6330   predicate(needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == 0));
 6331 
 6332   match(Set prev (GetAndSetP mem newv));
 6333 
 6334   ins_cost(ALU_COST);
 6335 
 6336   format %{ "atomic_xchg_acq  $prev, $newv, [$mem]\t#@get_and_setPAcq" %}
 6337 
 6338   ins_encode %{
 6339     __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base));
 6340   %}
 6341 
 6342   ins_pipe(pipe_serial);
 6343 %}
 6344 
 6345 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr)
 6346 %{
 6347   match(Set newval (GetAndAddL mem incr));
 6348 
 6349   ins_cost(ALU_COST);
 6350 
 6351   format %{ "get_and_addL $newval, [$mem], $incr\t#@get_and_addL" %}
 6352 
 6353   ins_encode %{
 6354     __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base));
 6355   %}
 6356 
 6357   ins_pipe(pipe_serial);
 6358 %}
 6359 
 6360 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr)
 6361 %{
 6362   predicate(n->as_LoadStore()->result_not_used());
 6363 
 6364   match(Set dummy (GetAndAddL mem incr));
 6365 
 6366   ins_cost(ALU_COST);
 6367 
 6368   format %{ "get_and_addL [$mem], $incr\t#@get_and_addL_no_res" %}
 6369 
 6370   ins_encode %{
 6371     __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base));
 6372   %}
 6373 
 6374   ins_pipe(pipe_serial);
 6375 %}
 6376 
 6377 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAdd incr)
 6378 %{
 6379   match(Set newval (GetAndAddL mem incr));
 6380 
 6381   ins_cost(ALU_COST);
 6382 
 6383   format %{ "get_and_addL $newval, [$mem], $incr\t#@get_and_addLi" %}
 6384 
 6385   ins_encode %{
 6386     __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base));
 6387   %}
 6388 
 6389   ins_pipe(pipe_serial);
 6390 %}
 6391 
 6392 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAdd incr)
 6393 %{
 6394   predicate(n->as_LoadStore()->result_not_used());
 6395 
 6396   match(Set dummy (GetAndAddL mem incr));
 6397 
 6398   ins_cost(ALU_COST);
 6399 
 6400   format %{ "get_and_addL [$mem], $incr\t#@get_and_addLi_no_res" %}
 6401 
 6402   ins_encode %{
 6403     __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base));
 6404   %}
 6405 
 6406   ins_pipe(pipe_serial);
 6407 %}
 6408 
 6409 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr)
 6410 %{
 6411   match(Set newval (GetAndAddI mem incr));
 6412 
 6413   ins_cost(ALU_COST);
 6414 
 6415   format %{ "get_and_addI $newval, [$mem], $incr\t#@get_and_addI" %}
 6416 
 6417   ins_encode %{
 6418     __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base));
 6419   %}
 6420 
 6421   ins_pipe(pipe_serial);
 6422 %}
 6423 
 6424 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr)
 6425 %{
 6426   predicate(n->as_LoadStore()->result_not_used());
 6427 
 6428   match(Set dummy (GetAndAddI mem incr));
 6429 
 6430   ins_cost(ALU_COST);
 6431 
 6432   format %{ "get_and_addI [$mem], $incr\t#@get_and_addI_no_res" %}
 6433 
 6434   ins_encode %{
 6435     __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base));
 6436   %}
 6437 
 6438   ins_pipe(pipe_serial);
 6439 %}
 6440 
 6441 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAdd incr)
 6442 %{
 6443   match(Set newval (GetAndAddI mem incr));
 6444 
 6445   ins_cost(ALU_COST);
 6446 
 6447   format %{ "get_and_addI $newval, [$mem], $incr\t#@get_and_addIi" %}
 6448 
 6449   ins_encode %{
 6450     __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base));
 6451   %}
 6452 
 6453   ins_pipe(pipe_serial);
 6454 %}
 6455 
 6456 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAdd incr)
 6457 %{
 6458   predicate(n->as_LoadStore()->result_not_used());
 6459 
 6460   match(Set dummy (GetAndAddI mem incr));
 6461 
 6462   ins_cost(ALU_COST);
 6463 
 6464   format %{ "get_and_addI [$mem], $incr\t#@get_and_addIi_no_res" %}
 6465 
 6466   ins_encode %{
 6467     __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base));
 6468   %}
 6469 
 6470   ins_pipe(pipe_serial);
 6471 %}
 6472 
 6473 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr)
 6474 %{
 6475   predicate(needs_acquiring_load_reserved(n));
 6476 
 6477   match(Set newval (GetAndAddL mem incr));
 6478 
 6479   ins_cost(ALU_COST);
 6480 
 6481   format %{ "get_and_addL_acq $newval, [$mem], $incr\t#@get_and_addLAcq" %}
 6482 
 6483   ins_encode %{
 6484     __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base));
 6485   %}
 6486 
 6487   ins_pipe(pipe_serial);
 6488 %}
 6489 
 6490 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{
 6491   predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_reserved(n));
 6492 
 6493   match(Set dummy (GetAndAddL mem incr));
 6494 
 6495   ins_cost(ALU_COST);
 6496 
 6497   format %{ "get_and_addL_acq [$mem], $incr\t#@get_and_addL_no_resAcq" %}
 6498 
 6499   ins_encode %{
 6500     __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base));
 6501   %}
 6502 
 6503   ins_pipe(pipe_serial);
 6504 %}
 6505 
 6506 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAdd incr)
 6507 %{
 6508   predicate(needs_acquiring_load_reserved(n));
 6509 
 6510   match(Set newval (GetAndAddL mem incr));
 6511 
 6512   ins_cost(ALU_COST);
 6513 
 6514   format %{ "get_and_addL_acq $newval, [$mem], $incr\t#@get_and_addLiAcq" %}
 6515 
 6516   ins_encode %{
 6517     __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base));
 6518   %}
 6519 
 6520   ins_pipe(pipe_serial);
 6521 %}
 6522 
 6523 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAdd incr)
 6524 %{
 6525   predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_reserved(n));
 6526 
 6527   match(Set dummy (GetAndAddL mem incr));
 6528 
 6529   ins_cost(ALU_COST);
 6530 
 6531   format %{ "get_and_addL_acq [$mem], $incr\t#@get_and_addLi_no_resAcq" %}
 6532 
 6533   ins_encode %{
 6534     __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base));
 6535   %}
 6536 
 6537   ins_pipe(pipe_serial);
 6538 %}
 6539 
 6540 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr)
 6541 %{
 6542   predicate(needs_acquiring_load_reserved(n));
 6543 
 6544   match(Set newval (GetAndAddI mem incr));
 6545 
 6546   ins_cost(ALU_COST);
 6547 
 6548   format %{ "get_and_addI_acq $newval, [$mem], $incr\t#@get_and_addIAcq" %}
 6549 
 6550   ins_encode %{
 6551     __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base));
 6552   %}
 6553 
 6554   ins_pipe(pipe_serial);
 6555 %}
 6556 
 6557 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr)
 6558 %{
 6559   predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_reserved(n));
 6560 
 6561   match(Set dummy (GetAndAddI mem incr));
 6562 
 6563   ins_cost(ALU_COST);
 6564 
 6565   format %{ "get_and_addI_acq [$mem], $incr\t#@get_and_addI_no_resAcq" %}
 6566 
 6567   ins_encode %{
 6568     __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base));
 6569   %}
 6570 
 6571   ins_pipe(pipe_serial);
 6572 %}
 6573 
 6574 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAdd incr)
 6575 %{
 6576   predicate(needs_acquiring_load_reserved(n));
 6577 
 6578   match(Set newval (GetAndAddI mem incr));
 6579 
 6580   ins_cost(ALU_COST);
 6581 
 6582   format %{ "get_and_addI_acq $newval, [$mem], $incr\t#@get_and_addIiAcq" %}
 6583 
 6584   ins_encode %{
 6585     __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base));
 6586   %}
 6587 
 6588   ins_pipe(pipe_serial);
 6589 %}
 6590 
 6591 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAdd incr)
 6592 %{
 6593   predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_reserved(n));
 6594 
 6595   match(Set dummy (GetAndAddI mem incr));
 6596 
 6597   ins_cost(ALU_COST);
 6598 
 6599   format %{ "get_and_addI_acq [$mem], $incr\t#@get_and_addIi_no_resAcq" %}
 6600 
 6601   ins_encode %{
 6602     __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base));
 6603   %}
 6604 
 6605   ins_pipe(pipe_serial);
 6606 %}
 6607 
 6608 // ============================================================================
 6609 // Arithmetic Instructions
 6610 //
 6611 
 6612 // Integer Addition
 6613 
 6614 // TODO
 6615 // these currently employ operations which do not set CR and hence are
 6616 // not flagged as killing CR but we would like to isolate the cases
 6617 // where we want to set flags from those where we don't. need to work
 6618 // out how to do that.
 6619 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
 6620   match(Set dst (AddI src1 src2));
 6621 
 6622   ins_cost(ALU_COST);
 6623   format %{ "addw  $dst, $src1, $src2\t#@addI_reg_reg" %}
 6624 
 6625   ins_encode %{
 6626     __ addw(as_Register($dst$$reg),
 6627             as_Register($src1$$reg),
 6628             as_Register($src2$$reg));
 6629   %}
 6630 
 6631   ins_pipe(ialu_reg_reg);
 6632 %}
 6633 
 6634 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAdd src2) %{
 6635   match(Set dst (AddI src1 src2));
 6636 
 6637   ins_cost(ALU_COST);
 6638   format %{ "addiw  $dst, $src1, $src2\t#@addI_reg_imm" %}
 6639 
 6640   ins_encode %{
 6641     __ addiw(as_Register($dst$$reg),
 6642              as_Register($src1$$reg),
 6643              $src2$$constant);
 6644   %}
 6645 
 6646   ins_pipe(ialu_reg_imm);
 6647 %}
 6648 
 6649 instruct addI_reg_imm_l2i(iRegINoSp dst, iRegL src1, immIAdd src2) %{
 6650   match(Set dst (AddI (ConvL2I src1) src2));
 6651 
 6652   ins_cost(ALU_COST);
 6653   format %{ "addiw  $dst, $src1, $src2\t#@addI_reg_imm_l2i" %}
 6654 
 6655   ins_encode %{
 6656     __ addiw(as_Register($dst$$reg),
 6657              as_Register($src1$$reg),
 6658              $src2$$constant);
 6659   %}
 6660 
 6661   ins_pipe(ialu_reg_imm);
 6662 %}
 6663 
 6664 // Pointer Addition
 6665 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{
 6666   match(Set dst (AddP src1 src2));
 6667 
 6668   ins_cost(ALU_COST);
 6669   format %{ "add $dst, $src1, $src2\t# ptr, #@addP_reg_reg" %}
 6670 
 6671   ins_encode %{
 6672     __ add(as_Register($dst$$reg),
 6673            as_Register($src1$$reg),
 6674            as_Register($src2$$reg));
 6675   %}
 6676 
 6677   ins_pipe(ialu_reg_reg);
 6678 %}
 6679 
 6680 // If we shift more than 32 bits, we need not convert I2L.
 6681 instruct lShiftL_regI_immGE32(iRegLNoSp dst, iRegI src, uimmI6_ge32 scale) %{
 6682   match(Set dst (LShiftL (ConvI2L src) scale));
 6683   ins_cost(ALU_COST);
 6684   format %{ "slli  $dst, $src, $scale & 63\t#@lShiftL_regI_immGE32" %}
 6685 
 6686   ins_encode %{
 6687     __ slli(as_Register($dst$$reg), as_Register($src$$reg), $scale$$constant & 63);
 6688   %}
 6689 
 6690   ins_pipe(ialu_reg_shift);
 6691 %}
 6692 
 6693 // Pointer Immediate Addition
 6694 // n.b. this needs to be more expensive than using an indirect memory
 6695 // operand
 6696 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAdd src2) %{
 6697   match(Set dst (AddP src1 src2));
 6698   ins_cost(ALU_COST);
 6699   format %{ "addi  $dst, $src1, $src2\t# ptr, #@addP_reg_imm" %}
 6700 
 6701   ins_encode %{
 6702     __ addi(as_Register($dst$$reg),
 6703             as_Register($src1$$reg),
 6704             $src2$$constant);
 6705   %}
 6706 
 6707   ins_pipe(ialu_reg_imm);
 6708 %}
 6709 
 6710 // Long Addition
 6711 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
 6712   match(Set dst (AddL src1 src2));
 6713   ins_cost(ALU_COST);
 6714   format %{ "add  $dst, $src1, $src2\t#@addL_reg_reg" %}
 6715 
 6716   ins_encode %{
 6717     __ add(as_Register($dst$$reg),
 6718            as_Register($src1$$reg),
 6719            as_Register($src2$$reg));
 6720   %}
 6721 
 6722   ins_pipe(ialu_reg_reg);
 6723 %}
 6724 
 6725 // No constant pool entries requiredLong Immediate Addition.
 6726 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{
 6727   match(Set dst (AddL src1 src2));
 6728   ins_cost(ALU_COST);
 6729   format %{ "addi  $dst, $src1, $src2\t#@addL_reg_imm" %}
 6730 
 6731   ins_encode %{
 6732     // src2 is imm, so actually call the addi
 6733     __ addi(as_Register($dst$$reg),
 6734             as_Register($src1$$reg),
 6735             $src2$$constant);
 6736   %}
 6737 
 6738   ins_pipe(ialu_reg_imm);
 6739 %}
 6740 
 6741 // Integer Subtraction
 6742 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
 6743   match(Set dst (SubI src1 src2));
 6744 
 6745   ins_cost(ALU_COST);
 6746   format %{ "subw  $dst, $src1, $src2\t#@subI_reg_reg" %}
 6747 
 6748   ins_encode %{
 6749     __ subw(as_Register($dst$$reg),
 6750             as_Register($src1$$reg),
 6751             as_Register($src2$$reg));
 6752   %}
 6753 
 6754   ins_pipe(ialu_reg_reg);
 6755 %}
 6756 
 6757 // Immediate Subtraction
 6758 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immISub src2) %{
 6759   match(Set dst (SubI src1 src2));
 6760 
 6761   ins_cost(ALU_COST);
 6762   format %{ "addiw  $dst, $src1, -$src2\t#@subI_reg_imm" %}
 6763 
 6764   ins_encode %{
 6765     // src2 is imm, so actually call the addiw
 6766     __ subiw(as_Register($dst$$reg),
 6767              as_Register($src1$$reg),
 6768              $src2$$constant);
 6769   %}
 6770 
 6771   ins_pipe(ialu_reg_imm);
 6772 %}
 6773 
 6774 // Long Subtraction
 6775 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
 6776   match(Set dst (SubL src1 src2));
 6777   ins_cost(ALU_COST);
 6778   format %{ "sub  $dst, $src1, $src2\t#@subL_reg_reg" %}
 6779 
 6780   ins_encode %{
 6781     __ sub(as_Register($dst$$reg),
 6782            as_Register($src1$$reg),
 6783            as_Register($src2$$reg));
 6784   %}
 6785 
 6786   ins_pipe(ialu_reg_reg);
 6787 %}
 6788 
 6789 // No constant pool entries requiredLong Immediate Subtraction.
 6790 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLSub src2) %{
 6791   match(Set dst (SubL src1 src2));
 6792   ins_cost(ALU_COST);
 6793   format %{ "addi  $dst, $src1, -$src2\t#@subL_reg_imm" %}
 6794 
 6795   ins_encode %{
 6796     // src2 is imm, so actually call the addi
 6797     __ subi(as_Register($dst$$reg),
 6798             as_Register($src1$$reg),
 6799             $src2$$constant);
 6800   %}
 6801 
 6802   ins_pipe(ialu_reg_imm);
 6803 %}
 6804 
 6805 // Integer Negation (special case for sub)
 6806 
 6807 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero) %{
 6808   match(Set dst (SubI zero src));
 6809   ins_cost(ALU_COST);
 6810   format %{ "subw  $dst, x0, $src\t# int, #@negI_reg" %}
 6811 
 6812   ins_encode %{
 6813     // actually call the subw
 6814     __ negw(as_Register($dst$$reg),
 6815             as_Register($src$$reg));
 6816   %}
 6817 
 6818   ins_pipe(ialu_reg);
 6819 %}
 6820 
 6821 // Long Negation
 6822 
 6823 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero) %{
 6824   match(Set dst (SubL zero src));
 6825   ins_cost(ALU_COST);
 6826   format %{ "sub  $dst, x0, $src\t# long, #@negL_reg" %}
 6827 
 6828   ins_encode %{
 6829     // actually call the sub
 6830     __ neg(as_Register($dst$$reg),
 6831            as_Register($src$$reg));
 6832   %}
 6833 
 6834   ins_pipe(ialu_reg);
 6835 %}
 6836 
 6837 // Integer Multiply
 6838 
 6839 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
 6840   match(Set dst (MulI src1 src2));
 6841   ins_cost(IMUL_COST);
 6842   format %{ "mulw  $dst, $src1, $src2\t#@mulI" %}
 6843 
 6844   //this means 2 word multi, and no sign extend to 64 bits
 6845   ins_encode %{
 6846     // riscv64 mulw will sign-extension to high 32 bits in dst reg
 6847     __ mulw(as_Register($dst$$reg),
 6848             as_Register($src1$$reg),
 6849             as_Register($src2$$reg));
 6850   %}
 6851 
 6852   ins_pipe(imul_reg_reg);
 6853 %}
 6854 
 6855 // Long Multiply
 6856 
 6857 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
 6858   match(Set dst (MulL src1 src2));
 6859   ins_cost(IMUL_COST);
 6860   format %{ "mul  $dst, $src1, $src2\t#@mulL" %}
 6861 
 6862   ins_encode %{
 6863     __ mul(as_Register($dst$$reg),
 6864            as_Register($src1$$reg),
 6865            as_Register($src2$$reg));
 6866   %}
 6867 
 6868   ins_pipe(lmul_reg_reg);
 6869 %}
 6870 
 6871 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2)
 6872 %{
 6873   match(Set dst (MulHiL src1 src2));
 6874   ins_cost(IMUL_COST);
 6875   format %{ "mulh  $dst, $src1, $src2\t# mulhi, #@mulHiL_rReg" %}
 6876 
 6877   ins_encode %{
 6878     __ mulh(as_Register($dst$$reg),
 6879             as_Register($src1$$reg),
 6880             as_Register($src2$$reg));
 6881   %}
 6882 
 6883   ins_pipe(lmul_reg_reg);
 6884 %}
 6885 
 6886 instruct umulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2)
 6887 %{
 6888   match(Set dst (UMulHiL src1 src2));
 6889   ins_cost(IMUL_COST);
 6890   format %{ "mulhu  $dst, $src1, $src2\t# umulhi, #@umulHiL_rReg" %}
 6891 
 6892   ins_encode %{
 6893     __ mulhu(as_Register($dst$$reg),
 6894              as_Register($src1$$reg),
 6895              as_Register($src2$$reg));
 6896   %}
 6897 
 6898   ins_pipe(lmul_reg_reg);
 6899 %}
 6900 
 6901 // Integer Divide
 6902 
 6903 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
 6904   match(Set dst (DivI src1 src2));
 6905   ins_cost(IDIVSI_COST);
 6906   format %{ "divw  $dst, $src1, $src2\t#@divI"%}
 6907 
 6908   ins_encode %{
 6909     __ divw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg));
 6910   %}
 6911   ins_pipe(idiv_reg_reg);
 6912 %}
 6913 
 6914 instruct UdivI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
 6915   match(Set dst (UDivI src1 src2));
 6916   ins_cost(IDIVSI_COST);
 6917   format %{ "divuw  $dst, $src1, $src2\t#@UdivI"%}
 6918 
 6919   ins_encode %{
 6920     __ divuw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg));
 6921   %}
 6922   ins_pipe(idiv_reg_reg);
 6923 %}
 6924 
 6925 instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{
 6926   match(Set dst (URShiftI (RShiftI src1 div1) div2));
 6927   ins_cost(ALU_COST);
 6928   format %{ "srliw $dst, $src1, $div1\t# int signExtract, #@signExtract" %}
 6929 
 6930   ins_encode %{
 6931     __ srliw(as_Register($dst$$reg), as_Register($src1$$reg), 31);
 6932   %}
 6933   ins_pipe(ialu_reg_shift);
 6934 %}
 6935 
 6936 // Long Divide
 6937 
 6938 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
 6939   match(Set dst (DivL src1 src2));
 6940   ins_cost(IDIVDI_COST);
 6941   format %{ "div  $dst, $src1, $src2\t#@divL" %}
 6942 
 6943   ins_encode %{
 6944     __ div(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg));
 6945   %}
 6946   ins_pipe(ldiv_reg_reg);
 6947 %}
 6948 
 6949 instruct UdivL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
 6950   match(Set dst (UDivL src1 src2));
 6951   ins_cost(IDIVDI_COST);
 6952 
 6953   format %{ "divu $dst, $src1, $src2\t#@UdivL" %}
 6954 
 6955   ins_encode %{
 6956     __ divu(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg));
 6957   %}
 6958   ins_pipe(ldiv_reg_reg);
 6959 %}
 6960 
 6961 instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{
 6962   match(Set dst (URShiftL (RShiftL src1 div1) div2));
 6963   ins_cost(ALU_COST);
 6964   format %{ "srli $dst, $src1, $div1\t# long signExtract, #@signExtractL" %}
 6965 
 6966   ins_encode %{
 6967     __ srli(as_Register($dst$$reg), as_Register($src1$$reg), 63);
 6968   %}
 6969   ins_pipe(ialu_reg_shift);
 6970 %}
 6971 
 6972 // Integer Remainder
 6973 
 6974 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
 6975   match(Set dst (ModI src1 src2));
 6976   ins_cost(IDIVSI_COST);
 6977   format %{ "remw  $dst, $src1, $src2\t#@modI" %}
 6978 
 6979   ins_encode %{
 6980     __ remw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg));
 6981   %}
 6982   ins_pipe(ialu_reg_reg);
 6983 %}
 6984 
 6985 instruct UmodI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
 6986   match(Set dst (UModI src1 src2));
 6987   ins_cost(IDIVSI_COST);
 6988   format %{ "remuw  $dst, $src1, $src2\t#@UmodI" %}
 6989 
 6990   ins_encode %{
 6991     __ remuw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg));
 6992   %}
 6993   ins_pipe(ialu_reg_reg);
 6994 %}
 6995 
 6996 // Long Remainder
 6997 
 6998 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
 6999   match(Set dst (ModL src1 src2));
 7000   ins_cost(IDIVDI_COST);
 7001   format %{ "rem  $dst, $src1, $src2\t#@modL" %}
 7002 
 7003   ins_encode %{
 7004     __ rem(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg));
 7005   %}
 7006   ins_pipe(ialu_reg_reg);
 7007 %}
 7008 
 7009 instruct UmodL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
 7010   match(Set dst (UModL src1 src2));
 7011   ins_cost(IDIVDI_COST);
 7012   format %{ "remu  $dst, $src1, $src2\t#@UmodL" %}
 7013 
 7014   ins_encode %{
 7015     __ remu(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg));
 7016   %}
 7017   ins_pipe(ialu_reg_reg);
 7018 %}
 7019 
 7020 // Integer Shifts
 7021 
 7022 // Shift Left Register
 7023 // Only the low 5 bits of src2 are considered for the shift amount, all other bits are ignored.
 7024 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
 7025   match(Set dst (LShiftI src1 src2));
 7026   ins_cost(ALU_COST);
 7027   format %{ "sllw  $dst, $src1, $src2\t#@lShiftI_reg_reg" %}
 7028 
 7029   ins_encode %{
 7030     __ sllw(as_Register($dst$$reg),
 7031             as_Register($src1$$reg),
 7032             as_Register($src2$$reg));
 7033   %}
 7034 
 7035   ins_pipe(ialu_reg_reg_vshift);
 7036 %}
 7037 
 7038 // Shift Left Immediate
 7039 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
 7040   match(Set dst (LShiftI src1 src2));
 7041   ins_cost(ALU_COST);
 7042   format %{ "slliw  $dst, $src1, ($src2 & 0x1f)\t#@lShiftI_reg_imm" %}
 7043 
 7044   ins_encode %{
 7045     // the shift amount is encoded in the lower
 7046     // 5 bits of the I-immediate field for RV32I
 7047     __ slliw(as_Register($dst$$reg),
 7048              as_Register($src1$$reg),
 7049              (unsigned) $src2$$constant & 0x1f);
 7050   %}
 7051 
 7052   ins_pipe(ialu_reg_shift);
 7053 %}
 7054 
 7055 // Shift Right Logical Register
 7056 // Only the low 5 bits of src2 are considered for the shift amount, all other bits are ignored.
 7057 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
 7058   match(Set dst (URShiftI src1 src2));
 7059   ins_cost(ALU_COST);
 7060   format %{ "srlw  $dst, $src1, $src2\t#@urShiftI_reg_reg" %}
 7061 
 7062   ins_encode %{
 7063     __ srlw(as_Register($dst$$reg),
 7064             as_Register($src1$$reg),
 7065             as_Register($src2$$reg));
 7066   %}
 7067 
 7068   ins_pipe(ialu_reg_reg_vshift);
 7069 %}
 7070 
 7071 // Shift Right Logical Immediate
 7072 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
 7073   match(Set dst (URShiftI src1 src2));
 7074   ins_cost(ALU_COST);
 7075   format %{ "srliw  $dst, $src1, ($src2 & 0x1f)\t#@urShiftI_reg_imm" %}
 7076 
 7077   ins_encode %{
 7078     // the shift amount is encoded in the lower
 7079     // 6 bits of the I-immediate field for RV64I
 7080     __ srliw(as_Register($dst$$reg),
 7081              as_Register($src1$$reg),
 7082              (unsigned) $src2$$constant & 0x1f);
 7083   %}
 7084 
 7085   ins_pipe(ialu_reg_shift);
 7086 %}
 7087 
 7088 // Shift Right Arithmetic Register
 7089 // Only the low 5 bits of src2 are considered for the shift amount, all other bits are ignored.
 7090 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
 7091   match(Set dst (RShiftI src1 src2));
 7092   ins_cost(ALU_COST);
 7093   format %{ "sraw  $dst, $src1, $src2\t#@rShiftI_reg_reg" %}
 7094 
 7095   ins_encode %{
 7096     // riscv will sign-ext dst high 32 bits
 7097     __ sraw(as_Register($dst$$reg),
 7098             as_Register($src1$$reg),
 7099             as_Register($src2$$reg));
 7100   %}
 7101 
 7102   ins_pipe(ialu_reg_reg_vshift);
 7103 %}
 7104 
 7105 // Shift Right Arithmetic Immediate
 7106 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
 7107   match(Set dst (RShiftI src1 src2));
 7108   ins_cost(ALU_COST);
 7109   format %{ "sraiw  $dst, $src1, ($src2 & 0x1f)\t#@rShiftI_reg_imm" %}
 7110 
 7111   ins_encode %{
 7112     // riscv will sign-ext dst high 32 bits
 7113     __ sraiw(as_Register($dst$$reg),
 7114              as_Register($src1$$reg),
 7115              (unsigned) $src2$$constant & 0x1f);
 7116   %}
 7117 
 7118   ins_pipe(ialu_reg_shift);
 7119 %}
 7120 
 7121 // Long Shifts
 7122 
 7123 // Shift Left Register
 7124 // Only the low 6 bits of src2 are considered for the shift amount, all other bits are ignored.
 7125 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
 7126   match(Set dst (LShiftL src1 src2));
 7127 
 7128   ins_cost(ALU_COST);
 7129   format %{ "sll  $dst, $src1, $src2\t#@lShiftL_reg_reg" %}
 7130 
 7131   ins_encode %{
 7132     __ sll(as_Register($dst$$reg),
 7133            as_Register($src1$$reg),
 7134            as_Register($src2$$reg));
 7135   %}
 7136 
 7137   ins_pipe(ialu_reg_reg_vshift);
 7138 %}
 7139 
 7140 // Shift Left Immediate
 7141 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
 7142   match(Set dst (LShiftL src1 src2));
 7143 
 7144   ins_cost(ALU_COST);
 7145   format %{ "slli  $dst, $src1, ($src2 & 0x3f)\t#@lShiftL_reg_imm" %}
 7146 
 7147   ins_encode %{
 7148     // the shift amount is encoded in the lower
 7149     // 6 bits of the I-immediate field for RV64I
 7150     __ slli(as_Register($dst$$reg),
 7151             as_Register($src1$$reg),
 7152             (unsigned) $src2$$constant & 0x3f);
 7153   %}
 7154 
 7155   ins_pipe(ialu_reg_shift);
 7156 %}
 7157 
 7158 // Shift Right Logical Register
 7159 // Only the low 6 bits of src2 are considered for the shift amount, all other bits are ignored.
 7160 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
 7161   match(Set dst (URShiftL src1 src2));
 7162 
 7163   ins_cost(ALU_COST);
 7164   format %{ "srl  $dst, $src1, $src2\t#@urShiftL_reg_reg" %}
 7165 
 7166   ins_encode %{
 7167     __ srl(as_Register($dst$$reg),
 7168             as_Register($src1$$reg),
 7169             as_Register($src2$$reg));
 7170   %}
 7171 
 7172   ins_pipe(ialu_reg_reg_vshift);
 7173 %}
 7174 
 7175 // Shift Right Logical Immediate
 7176 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
 7177   match(Set dst (URShiftL src1 src2));
 7178 
 7179   ins_cost(ALU_COST);
 7180   format %{ "srli  $dst, $src1, ($src2 & 0x3f)\t#@urShiftL_reg_imm" %}
 7181 
 7182   ins_encode %{
 7183     // the shift amount is encoded in the lower
 7184     // 6 bits of the I-immediate field for RV64I
 7185     __ srli(as_Register($dst$$reg),
 7186             as_Register($src1$$reg),
 7187             (unsigned) $src2$$constant & 0x3f);
 7188   %}
 7189 
 7190   ins_pipe(ialu_reg_shift);
 7191 %}
 7192 
 7193 // A special-case pattern for card table stores.
 7194 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{
 7195   match(Set dst (URShiftL (CastP2X src1) src2));
 7196 
 7197   ins_cost(ALU_COST);
 7198   format %{ "srli  $dst, p2x($src1), ($src2 & 0x3f)\t#@urShiftP_reg_imm" %}
 7199 
 7200   ins_encode %{
 7201     // the shift amount is encoded in the lower
 7202     // 6 bits of the I-immediate field for RV64I
 7203     __ srli(as_Register($dst$$reg),
 7204             as_Register($src1$$reg),
 7205             (unsigned) $src2$$constant & 0x3f);
 7206   %}
 7207 
 7208   ins_pipe(ialu_reg_shift);
 7209 %}
 7210 
 7211 // Shift Right Arithmetic Register
 7212 // Only the low 6 bits of src2 are considered for the shift amount, all other bits are ignored.
 7213 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
 7214   match(Set dst (RShiftL src1 src2));
 7215 
 7216   ins_cost(ALU_COST);
 7217   format %{ "sra  $dst, $src1, $src2\t#@rShiftL_reg_reg" %}
 7218 
 7219   ins_encode %{
 7220     __ sra(as_Register($dst$$reg),
 7221            as_Register($src1$$reg),
 7222            as_Register($src2$$reg));
 7223   %}
 7224 
 7225   ins_pipe(ialu_reg_reg_vshift);
 7226 %}
 7227 
 7228 // Shift Right Arithmetic Immediate
 7229 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
 7230   match(Set dst (RShiftL src1 src2));
 7231 
 7232   ins_cost(ALU_COST);
 7233   format %{ "srai  $dst, $src1, ($src2 & 0x3f)\t#@rShiftL_reg_imm" %}
 7234 
 7235   ins_encode %{
 7236     // the shift amount is encoded in the lower
 7237     // 6 bits of the I-immediate field for RV64I
 7238     __ srai(as_Register($dst$$reg),
 7239             as_Register($src1$$reg),
 7240             (unsigned) $src2$$constant & 0x3f);
 7241   %}
 7242 
 7243   ins_pipe(ialu_reg_shift);
 7244 %}
 7245 
 7246 instruct regI_not_reg(iRegINoSp dst, iRegI src1, immI_M1 m1) %{
 7247   match(Set dst (XorI src1 m1));
 7248   ins_cost(ALU_COST);
 7249   format %{ "xori  $dst, $src1, -1\t#@regI_not_reg" %}
 7250 
 7251   ins_encode %{
 7252     __ xori(as_Register($dst$$reg), as_Register($src1$$reg), -1);
 7253   %}
 7254 
 7255   ins_pipe(ialu_reg_imm);
 7256 %}
 7257 
 7258 instruct regL_not_reg(iRegLNoSp dst, iRegL src1, immL_M1 m1) %{
 7259   match(Set dst (XorL src1 m1));
 7260   ins_cost(ALU_COST);
 7261   format %{ "xori  $dst, $src1, -1\t#@regL_not_reg" %}
 7262 
 7263   ins_encode %{
 7264     __ xori(as_Register($dst$$reg), as_Register($src1$$reg), -1);
 7265   %}
 7266 
 7267   ins_pipe(ialu_reg_imm);
 7268 %}
 7269 
 7270 
 7271 // ============================================================================
 7272 // Floating Point Arithmetic Instructions
 7273 
 7274 instruct addF_reg_reg(fRegF dst, fRegF src1, fRegF src2) %{
 7275   match(Set dst (AddF src1 src2));
 7276 
 7277   ins_cost(DEFAULT_COST * 5);
 7278   format %{ "fadd.s  $dst, $src1, $src2\t#@addF_reg_reg" %}
 7279 
 7280   ins_encode %{
 7281     __ fadd_s(as_FloatRegister($dst$$reg),
 7282               as_FloatRegister($src1$$reg),
 7283               as_FloatRegister($src2$$reg));
 7284   %}
 7285 
 7286   ins_pipe(fp_dop_reg_reg_s);
 7287 %}
 7288 
 7289 instruct addD_reg_reg(fRegD dst, fRegD src1, fRegD src2) %{
 7290   match(Set dst (AddD src1 src2));
 7291 
 7292   ins_cost(DEFAULT_COST * 5);
 7293   format %{ "fadd.d  $dst, $src1, $src2\t#@addD_reg_reg" %}
 7294 
 7295   ins_encode %{
 7296     __ fadd_d(as_FloatRegister($dst$$reg),
 7297               as_FloatRegister($src1$$reg),
 7298               as_FloatRegister($src2$$reg));
 7299   %}
 7300 
 7301   ins_pipe(fp_dop_reg_reg_d);
 7302 %}
 7303 
 7304 instruct subF_reg_reg(fRegF dst, fRegF src1, fRegF src2) %{
 7305   match(Set dst (SubF src1 src2));
 7306 
 7307   ins_cost(DEFAULT_COST * 5);
 7308   format %{ "fsub.s  $dst, $src1, $src2\t#@subF_reg_reg" %}
 7309 
 7310   ins_encode %{
 7311     __ fsub_s(as_FloatRegister($dst$$reg),
 7312               as_FloatRegister($src1$$reg),
 7313               as_FloatRegister($src2$$reg));
 7314   %}
 7315 
 7316   ins_pipe(fp_dop_reg_reg_s);
 7317 %}
 7318 
 7319 instruct subD_reg_reg(fRegD dst, fRegD src1, fRegD src2) %{
 7320   match(Set dst (SubD src1 src2));
 7321 
 7322   ins_cost(DEFAULT_COST * 5);
 7323   format %{ "fsub.d  $dst, $src1, $src2\t#@subD_reg_reg" %}
 7324 
 7325   ins_encode %{
 7326     __ fsub_d(as_FloatRegister($dst$$reg),
 7327               as_FloatRegister($src1$$reg),
 7328               as_FloatRegister($src2$$reg));
 7329   %}
 7330 
 7331   ins_pipe(fp_dop_reg_reg_d);
 7332 %}
 7333 
 7334 instruct mulF_reg_reg(fRegF dst, fRegF src1, fRegF src2) %{
 7335   match(Set dst (MulF src1 src2));
 7336 
 7337   ins_cost(FMUL_SINGLE_COST);
 7338   format %{ "fmul.s  $dst, $src1, $src2\t#@mulF_reg_reg" %}
 7339 
 7340   ins_encode %{
 7341     __ fmul_s(as_FloatRegister($dst$$reg),
 7342               as_FloatRegister($src1$$reg),
 7343               as_FloatRegister($src2$$reg));
 7344   %}
 7345 
 7346   ins_pipe(fp_dop_reg_reg_s);
 7347 %}
 7348 
 7349 instruct mulD_reg_reg(fRegD dst, fRegD src1, fRegD src2) %{
 7350   match(Set dst (MulD src1 src2));
 7351 
 7352   ins_cost(FMUL_DOUBLE_COST);
 7353   format %{ "fmul.d  $dst, $src1, $src2\t#@mulD_reg_reg" %}
 7354 
 7355   ins_encode %{
 7356     __ fmul_d(as_FloatRegister($dst$$reg),
 7357               as_FloatRegister($src1$$reg),
 7358               as_FloatRegister($src2$$reg));
 7359   %}
 7360 
 7361   ins_pipe(fp_dop_reg_reg_d);
 7362 %}
 7363 
 7364 // src1 * src2 + src3
 7365 instruct maddF_reg_reg(fRegF dst, fRegF src1, fRegF src2, fRegF src3) %{
 7366   match(Set dst (FmaF src3 (Binary src1 src2)));
 7367 
 7368   ins_cost(FMUL_SINGLE_COST);
 7369   format %{ "fmadd.s  $dst, $src1, $src2, $src3\t#@maddF_reg_reg" %}
 7370 
 7371   ins_encode %{
 7372     assert(UseFMA, "Needs FMA instructions support.");
 7373     __ fmadd_s(as_FloatRegister($dst$$reg),
 7374                as_FloatRegister($src1$$reg),
 7375                as_FloatRegister($src2$$reg),
 7376                as_FloatRegister($src3$$reg));
 7377   %}
 7378 
 7379   ins_pipe(pipe_class_default);
 7380 %}
 7381 
 7382 // src1 * src2 + src3
 7383 instruct maddD_reg_reg(fRegD dst, fRegD src1, fRegD src2, fRegD src3) %{
 7384   match(Set dst (FmaD src3 (Binary src1 src2)));
 7385 
 7386   ins_cost(FMUL_DOUBLE_COST);
 7387   format %{ "fmadd.d  $dst, $src1, $src2, $src3\t#@maddD_reg_reg" %}
 7388 
 7389   ins_encode %{
 7390     assert(UseFMA, "Needs FMA instructions support.");
 7391     __ fmadd_d(as_FloatRegister($dst$$reg),
 7392                as_FloatRegister($src1$$reg),
 7393                as_FloatRegister($src2$$reg),
 7394                as_FloatRegister($src3$$reg));
 7395   %}
 7396 
 7397   ins_pipe(pipe_class_default);
 7398 %}
 7399 
 7400 // src1 * src2 - src3
 7401 instruct msubF_reg_reg(fRegF dst, fRegF src1, fRegF src2, fRegF src3) %{
 7402   match(Set dst (FmaF (NegF src3) (Binary src1 src2)));
 7403 
 7404   ins_cost(FMUL_SINGLE_COST);
 7405   format %{ "fmsub.s  $dst, $src1, $src2, $src3\t#@msubF_reg_reg" %}
 7406 
 7407   ins_encode %{
 7408     assert(UseFMA, "Needs FMA instructions support.");
 7409     __ fmsub_s(as_FloatRegister($dst$$reg),
 7410                as_FloatRegister($src1$$reg),
 7411                as_FloatRegister($src2$$reg),
 7412                as_FloatRegister($src3$$reg));
 7413   %}
 7414 
 7415   ins_pipe(pipe_class_default);
 7416 %}
 7417 
 7418 // src1 * src2 - src3
 7419 instruct msubD_reg_reg(fRegD dst, fRegD src1, fRegD src2, fRegD src3) %{
 7420   match(Set dst (FmaD (NegD src3) (Binary src1 src2)));
 7421 
 7422   ins_cost(FMUL_DOUBLE_COST);
 7423   format %{ "fmsub.d  $dst, $src1, $src2, $src3\t#@msubD_reg_reg" %}
 7424 
 7425   ins_encode %{
 7426     assert(UseFMA, "Needs FMA instructions support.");
 7427     __ fmsub_d(as_FloatRegister($dst$$reg),
 7428                as_FloatRegister($src1$$reg),
 7429                as_FloatRegister($src2$$reg),
 7430                as_FloatRegister($src3$$reg));
 7431   %}
 7432 
 7433   ins_pipe(pipe_class_default);
 7434 %}
 7435 
 7436 // src1 * (-src2) + src3
 7437 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
 7438 instruct nmsubF_reg_reg(fRegF dst, fRegF src1, fRegF src2, fRegF src3) %{
 7439   match(Set dst (FmaF src3 (Binary src1 (NegF src2))));
 7440 
 7441   ins_cost(FMUL_SINGLE_COST);
 7442   format %{ "fnmsub.s  $dst, $src1, $src2, $src3\t#@nmsubF_reg_reg" %}
 7443 
 7444   ins_encode %{
 7445     assert(UseFMA, "Needs FMA instructions support.");
 7446     __ fnmsub_s(as_FloatRegister($dst$$reg),
 7447                 as_FloatRegister($src1$$reg),
 7448                 as_FloatRegister($src2$$reg),
 7449                 as_FloatRegister($src3$$reg));
 7450   %}
 7451 
 7452   ins_pipe(pipe_class_default);
 7453 %}
 7454 
 7455 // src1 * (-src2) + src3
 7456 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
 7457 instruct nmsubD_reg_reg(fRegD dst, fRegD src1, fRegD src2, fRegD src3) %{
 7458   match(Set dst (FmaD src3 (Binary src1 (NegD src2))));
 7459 
 7460   ins_cost(FMUL_DOUBLE_COST);
 7461   format %{ "fnmsub.d  $dst, $src1, $src2, $src3\t#@nmsubD_reg_reg" %}
 7462 
 7463   ins_encode %{
 7464     assert(UseFMA, "Needs FMA instructions support.");
 7465     __ fnmsub_d(as_FloatRegister($dst$$reg),
 7466                 as_FloatRegister($src1$$reg),
 7467                 as_FloatRegister($src2$$reg),
 7468                 as_FloatRegister($src3$$reg));
 7469   %}
 7470 
 7471   ins_pipe(pipe_class_default);
 7472 %}
 7473 
 7474 // src1 * (-src2) - src3
 7475 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
 7476 instruct nmaddF_reg_reg(fRegF dst, fRegF src1, fRegF src2, fRegF src3) %{
 7477   match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2))));
 7478 
 7479   ins_cost(FMUL_SINGLE_COST);
 7480   format %{ "fnmadd.s  $dst, $src1, $src2, $src3\t#@nmaddF_reg_reg" %}
 7481 
 7482   ins_encode %{
 7483     assert(UseFMA, "Needs FMA instructions support.");
 7484     __ fnmadd_s(as_FloatRegister($dst$$reg),
 7485                 as_FloatRegister($src1$$reg),
 7486                 as_FloatRegister($src2$$reg),
 7487                 as_FloatRegister($src3$$reg));
 7488   %}
 7489 
 7490   ins_pipe(pipe_class_default);
 7491 %}
 7492 
 7493 // src1 * (-src2) - src3
 7494 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
 7495 instruct nmaddD_reg_reg(fRegD dst, fRegD src1, fRegD src2, fRegD src3) %{
 7496   match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2))));
 7497 
 7498   ins_cost(FMUL_DOUBLE_COST);
 7499   format %{ "fnmadd.d  $dst, $src1, $src2, $src3\t#@nmaddD_reg_reg" %}
 7500 
 7501   ins_encode %{
 7502     assert(UseFMA, "Needs FMA instructions support.");
 7503     __ fnmadd_d(as_FloatRegister($dst$$reg),
 7504                 as_FloatRegister($src1$$reg),
 7505                 as_FloatRegister($src2$$reg),
 7506                 as_FloatRegister($src3$$reg));
 7507   %}
 7508 
 7509   ins_pipe(pipe_class_default);
 7510 %}
 7511 
 7512 // Math.max(FF)F
 7513 instruct maxF_reg_reg(fRegF dst, fRegF src1, fRegF src2, rFlagsReg cr) %{
 7514   predicate(!UseZfa);
 7515   match(Set dst (MaxF src1 src2));
 7516   effect(KILL cr);
 7517 
 7518   format %{ "maxF $dst, $src1, $src2" %}
 7519 
 7520   ins_encode %{
 7521     __ minmax_fp(as_FloatRegister($dst$$reg),
 7522                  as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg),
 7523                  __ FLOAT_TYPE::single_precision, false /* is_min */);
 7524   %}
 7525 
 7526   ins_pipe(pipe_class_default);
 7527 %}
 7528 
 7529 instruct maxF_reg_reg_zfa(fRegF dst, fRegF src1, fRegF src2) %{
 7530   predicate(UseZfa);
 7531   match(Set dst (MaxF src1 src2));
 7532 
 7533   format %{ "maxF $dst, $src1, $src2" %}
 7534 
 7535   ins_encode %{
 7536     __ fmaxm_s(as_FloatRegister($dst$$reg),
 7537                as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
 7538   %}
 7539 
 7540   ins_pipe(pipe_class_default);
 7541 %}
 7542 
 7543 // Math.min(FF)F
 7544 instruct minF_reg_reg(fRegF dst, fRegF src1, fRegF src2, rFlagsReg cr) %{
 7545   predicate(!UseZfa);
 7546   match(Set dst (MinF src1 src2));
 7547   effect(KILL cr);
 7548 
 7549   format %{ "minF $dst, $src1, $src2" %}
 7550 
 7551   ins_encode %{
 7552     __ minmax_fp(as_FloatRegister($dst$$reg),
 7553                  as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg),
 7554                  __ FLOAT_TYPE::single_precision, true /* is_min */);
 7555   %}
 7556 
 7557   ins_pipe(pipe_class_default);
 7558 %}
 7559 
 7560 instruct minF_reg_reg_zfa(fRegF dst, fRegF src1, fRegF src2) %{
 7561   predicate(UseZfa);
 7562   match(Set dst (MinF src1 src2));
 7563 
 7564   format %{ "minF $dst, $src1, $src2" %}
 7565 
 7566   ins_encode %{
 7567     __ fminm_s(as_FloatRegister($dst$$reg),
 7568                as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
 7569   %}
 7570 
 7571   ins_pipe(pipe_class_default);
 7572 %}
 7573 
 7574 // Math.max(DD)D
 7575 instruct maxD_reg_reg(fRegD dst, fRegD src1, fRegD src2, rFlagsReg cr) %{
 7576   predicate(!UseZfa);
 7577   match(Set dst (MaxD src1 src2));
 7578   effect(KILL cr);
 7579 
 7580   format %{ "maxD $dst, $src1, $src2" %}
 7581 
 7582   ins_encode %{
 7583     __ minmax_fp(as_FloatRegister($dst$$reg),
 7584                  as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg),
 7585                  __ FLOAT_TYPE::double_precision, false /* is_min */);
 7586   %}
 7587 
 7588   ins_pipe(pipe_class_default);
 7589 %}
 7590 
 7591 instruct maxD_reg_reg_zfa(fRegD dst, fRegD src1, fRegD src2) %{
 7592   predicate(UseZfa);
 7593   match(Set dst (MaxD src1 src2));
 7594 
 7595   format %{ "maxD $dst, $src1, $src2" %}
 7596 
 7597   ins_encode %{
 7598     __ fmaxm_d(as_FloatRegister($dst$$reg),
 7599                as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
 7600   %}
 7601 
 7602   ins_pipe(pipe_class_default);
 7603 %}
 7604 
 7605 // Math.min(DD)D
 7606 instruct minD_reg_reg(fRegD dst, fRegD src1, fRegD src2, rFlagsReg cr) %{
 7607   predicate(!UseZfa);
 7608   match(Set dst (MinD src1 src2));
 7609   effect(KILL cr);
 7610 
 7611   format %{ "minD $dst, $src1, $src2" %}
 7612 
 7613   ins_encode %{
 7614     __ minmax_fp(as_FloatRegister($dst$$reg),
 7615                  as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg),
 7616                  __ FLOAT_TYPE::double_precision, true /* is_min */);
 7617   %}
 7618 
 7619   ins_pipe(pipe_class_default);
 7620 %}
 7621 
 7622 instruct minD_reg_reg_zfa(fRegD dst, fRegD src1, fRegD src2) %{
 7623   predicate(UseZfa);
 7624   match(Set dst (MinD src1 src2));
 7625 
 7626   format %{ "minD $dst, $src1, $src2" %}
 7627 
 7628   ins_encode %{
 7629     __ fminm_d(as_FloatRegister($dst$$reg),
 7630                as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
 7631   %}
 7632 
 7633   ins_pipe(pipe_class_default);
 7634 %}
 7635 
 7636 // Float.isInfinite
 7637 instruct isInfiniteF_reg_reg(iRegINoSp dst, fRegF src)
 7638 %{
 7639   match(Set dst (IsInfiniteF src));
 7640 
 7641   format %{ "isInfinite $dst, $src" %}
 7642   ins_encode %{
 7643     __ fclass_s(as_Register($dst$$reg), as_FloatRegister($src$$reg));
 7644     __ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::FClassBits::inf);
 7645     __ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg));
 7646   %}
 7647 
 7648   ins_pipe(pipe_class_default);
 7649 %}
 7650 
 7651 // Double.isInfinite
 7652 instruct isInfiniteD_reg_reg(iRegINoSp dst, fRegD src)
 7653 %{
 7654   match(Set dst (IsInfiniteD src));
 7655 
 7656   format %{ "isInfinite $dst, $src" %}
 7657   ins_encode %{
 7658     __ fclass_d(as_Register($dst$$reg), as_FloatRegister($src$$reg));
 7659     __ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::FClassBits::inf);
 7660     __ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg));
 7661   %}
 7662 
 7663   ins_pipe(pipe_class_default);
 7664 %}
 7665 
 7666 // Float.isFinite
 7667 instruct isFiniteF_reg_reg(iRegINoSp dst, fRegF src)
 7668 %{
 7669   match(Set dst (IsFiniteF src));
 7670 
 7671   format %{ "isFinite $dst, $src" %}
 7672   ins_encode %{
 7673     __ fclass_s(as_Register($dst$$reg), as_FloatRegister($src$$reg));
 7674     __ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::FClassBits::finite);
 7675     __ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg));
 7676   %}
 7677 
 7678   ins_pipe(pipe_class_default);
 7679 %}
 7680 
 7681 // Double.isFinite
 7682 instruct isFiniteD_reg_reg(iRegINoSp dst, fRegD src)
 7683 %{
 7684   match(Set dst (IsFiniteD src));
 7685 
 7686   format %{ "isFinite $dst, $src" %}
 7687   ins_encode %{
 7688     __ fclass_d(as_Register($dst$$reg), as_FloatRegister($src$$reg));
 7689     __ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::FClassBits::finite);
 7690     __ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg));
 7691   %}
 7692 
 7693   ins_pipe(pipe_class_default);
 7694 %}
 7695 
 7696 instruct divF_reg_reg(fRegF dst, fRegF src1, fRegF src2) %{
 7697   match(Set dst (DivF src1  src2));
 7698 
 7699   ins_cost(FDIV_COST);
 7700   format %{ "fdiv.s  $dst, $src1, $src2\t#@divF_reg_reg" %}
 7701 
 7702   ins_encode %{
 7703     __ fdiv_s(as_FloatRegister($dst$$reg),
 7704               as_FloatRegister($src1$$reg),
 7705               as_FloatRegister($src2$$reg));
 7706   %}
 7707 
 7708   ins_pipe(fp_div_s);
 7709 %}
 7710 
 7711 instruct divD_reg_reg(fRegD dst, fRegD src1, fRegD src2) %{
 7712   match(Set dst (DivD src1  src2));
 7713 
 7714   ins_cost(FDIV_COST);
 7715   format %{ "fdiv.d  $dst, $src1, $src2\t#@divD_reg_reg" %}
 7716 
 7717   ins_encode %{
 7718     __ fdiv_d(as_FloatRegister($dst$$reg),
 7719               as_FloatRegister($src1$$reg),
 7720               as_FloatRegister($src2$$reg));
 7721   %}
 7722 
 7723   ins_pipe(fp_div_d);
 7724 %}
 7725 
 7726 instruct negF_reg_reg(fRegF dst, fRegF src) %{
 7727   match(Set dst (NegF src));
 7728 
 7729   ins_cost(XFER_COST);
 7730   format %{ "fsgnjn.s  $dst, $src, $src\t#@negF_reg_reg" %}
 7731 
 7732   ins_encode %{
 7733     __ fneg_s(as_FloatRegister($dst$$reg),
 7734               as_FloatRegister($src$$reg));
 7735   %}
 7736 
 7737   ins_pipe(fp_uop_s);
 7738 %}
 7739 
 7740 instruct negD_reg_reg(fRegD dst, fRegD src) %{
 7741   match(Set dst (NegD src));
 7742 
 7743   ins_cost(XFER_COST);
 7744   format %{ "fsgnjn.d  $dst, $src, $src\t#@negD_reg_reg" %}
 7745 
 7746   ins_encode %{
 7747     __ fneg_d(as_FloatRegister($dst$$reg),
 7748               as_FloatRegister($src$$reg));
 7749   %}
 7750 
 7751   ins_pipe(fp_uop_d);
 7752 %}
 7753 
 7754 instruct absI_reg(iRegINoSp dst, iRegIorL2I src) %{
 7755   match(Set dst (AbsI src));
 7756 
 7757   ins_cost(ALU_COST * 3);
 7758   format %{
 7759     "sraiw  t0, $src, 0x1f\n\t"
 7760     "addw  $dst, $src, t0\n\t"
 7761     "xorr  $dst, $dst, t0\t#@absI_reg"
 7762   %}
 7763 
 7764   ins_encode %{
 7765     __ sraiw(t0, as_Register($src$$reg), 0x1f);
 7766     __ addw(as_Register($dst$$reg), as_Register($src$$reg), t0);
 7767     __ xorr(as_Register($dst$$reg), as_Register($dst$$reg), t0);
 7768   %}
 7769 
 7770   ins_pipe(pipe_class_default);
 7771 %}
 7772 
 7773 instruct absL_reg(iRegLNoSp dst, iRegL src) %{
 7774   match(Set dst (AbsL src));
 7775 
 7776   ins_cost(ALU_COST * 3);
 7777   format %{
 7778     "srai  t0, $src, 0x3f\n\t"
 7779     "add  $dst, $src, t0\n\t"
 7780     "xorr  $dst, $dst, t0\t#@absL_reg"
 7781   %}
 7782 
 7783   ins_encode %{
 7784     __ srai(t0, as_Register($src$$reg), 0x3f);
 7785     __ add(as_Register($dst$$reg), as_Register($src$$reg), t0);
 7786     __ xorr(as_Register($dst$$reg), as_Register($dst$$reg), t0);
 7787   %}
 7788 
 7789   ins_pipe(pipe_class_default);
 7790 %}
 7791 
 7792 instruct absF_reg(fRegF dst, fRegF src) %{
 7793   match(Set dst (AbsF src));
 7794 
 7795   ins_cost(XFER_COST);
 7796   format %{ "fsgnjx.s  $dst, $src, $src\t#@absF_reg" %}
 7797   ins_encode %{
 7798     __ fabs_s(as_FloatRegister($dst$$reg),
 7799               as_FloatRegister($src$$reg));
 7800   %}
 7801 
 7802   ins_pipe(fp_uop_s);
 7803 %}
 7804 
 7805 instruct absD_reg(fRegD dst, fRegD src) %{
 7806   match(Set dst (AbsD src));
 7807 
 7808   ins_cost(XFER_COST);
 7809   format %{ "fsgnjx.d  $dst, $src, $src\t#@absD_reg" %}
 7810   ins_encode %{
 7811     __ fabs_d(as_FloatRegister($dst$$reg),
 7812               as_FloatRegister($src$$reg));
 7813   %}
 7814 
 7815   ins_pipe(fp_uop_d);
 7816 %}
 7817 
 7818 instruct sqrtF_reg(fRegF dst, fRegF src) %{
 7819   match(Set dst (SqrtF src));
 7820 
 7821   ins_cost(FSQRT_COST);
 7822   format %{ "fsqrt.s  $dst, $src\t#@sqrtF_reg" %}
 7823   ins_encode %{
 7824     __ fsqrt_s(as_FloatRegister($dst$$reg),
 7825                as_FloatRegister($src$$reg));
 7826   %}
 7827 
 7828   ins_pipe(fp_sqrt_s);
 7829 %}
 7830 
 7831 instruct sqrtD_reg(fRegD dst, fRegD src) %{
 7832   match(Set dst (SqrtD src));
 7833 
 7834   ins_cost(FSQRT_COST);
 7835   format %{ "fsqrt.d  $dst, $src\t#@sqrtD_reg" %}
 7836   ins_encode %{
 7837     __ fsqrt_d(as_FloatRegister($dst$$reg),
 7838                as_FloatRegister($src$$reg));
 7839   %}
 7840 
 7841   ins_pipe(fp_sqrt_d);
 7842 %}
 7843 
 7844 // Round Instruction
 7845 instruct roundD_reg(fRegD dst, fRegD src, immI rmode, iRegLNoSp tmp1, iRegLNoSp tmp2, iRegLNoSp tmp3) %{
 7846   match(Set dst (RoundDoubleMode src rmode));
 7847   ins_cost(2 * XFER_COST + BRANCH_COST);
 7848   effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2, TEMP tmp3);
 7849 
 7850   format %{ "RoundDoubleMode $src, $rmode" %}
 7851   ins_encode %{
 7852     __ round_double_mode(as_FloatRegister($dst$$reg),
 7853                as_FloatRegister($src$$reg), $rmode$$constant, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
 7854   %}
 7855   ins_pipe(pipe_class_default);
 7856 %}
 7857 
 7858 // Copysign and signum intrinsics
 7859 
 7860 instruct copySignD_reg(fRegD dst, fRegD src1, fRegD src2, immD zero) %{
 7861   match(Set dst (CopySignD src1 (Binary src2 zero)));
 7862   format %{ "CopySignD  $dst $src1 $src2" %}
 7863   ins_encode %{
 7864     FloatRegister dst = as_FloatRegister($dst$$reg),
 7865                   src1 = as_FloatRegister($src1$$reg),
 7866                   src2 = as_FloatRegister($src2$$reg);
 7867     __ fsgnj_d(dst, src1, src2);
 7868   %}
 7869   ins_pipe(fp_dop_reg_reg_d);
 7870 %}
 7871 
 7872 instruct copySignF_reg(fRegF dst, fRegF src1, fRegF src2) %{
 7873   match(Set dst (CopySignF src1 src2));
 7874   format %{ "CopySignF  $dst $src1 $src2" %}
 7875   ins_encode %{
 7876     FloatRegister dst = as_FloatRegister($dst$$reg),
 7877                   src1 = as_FloatRegister($src1$$reg),
 7878                   src2 = as_FloatRegister($src2$$reg);
 7879     __ fsgnj_s(dst, src1, src2);
 7880   %}
 7881   ins_pipe(fp_dop_reg_reg_s);
 7882 %}
 7883 
 7884 instruct signumD_reg(fRegD dst, immD zero, fRegD one) %{
 7885   match(Set dst (SignumD dst (Binary zero one)));
 7886   format %{ "signumD  $dst, $dst" %}
 7887   ins_encode %{
 7888     __ signum_fp(as_FloatRegister($dst$$reg), as_FloatRegister($one$$reg), true /* is_double */);
 7889   %}
 7890   ins_pipe(pipe_class_default);
 7891 %}
 7892 
 7893 instruct signumF_reg(fRegF dst, immF zero, fRegF one) %{
 7894   match(Set dst (SignumF dst (Binary zero one)));
 7895   format %{ "signumF  $dst, $dst" %}
 7896   ins_encode %{
 7897     __ signum_fp(as_FloatRegister($dst$$reg), as_FloatRegister($one$$reg), false /* is_double */);
 7898   %}
 7899   ins_pipe(pipe_class_default);
 7900 %}
 7901 
 7902 // Arithmetic Instructions End
 7903 
 7904 // ============================================================================
 7905 // Logical Instructions
 7906 
 7907 // Register And
 7908 instruct andI_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2) %{
 7909   match(Set dst (AndI src1 src2));
 7910 
 7911   format %{ "andr  $dst, $src1, $src2\t#@andI_reg_reg" %}
 7912 
 7913   ins_cost(ALU_COST);
 7914   ins_encode %{
 7915     __ andr(as_Register($dst$$reg),
 7916             as_Register($src1$$reg),
 7917             as_Register($src2$$reg));
 7918   %}
 7919 
 7920   ins_pipe(ialu_reg_reg);
 7921 %}
 7922 
 7923 // Immediate And
 7924 instruct andI_reg_imm(iRegINoSp dst, iRegI src1, immIAdd src2) %{
 7925   match(Set dst (AndI src1 src2));
 7926 
 7927   format %{ "andi  $dst, $src1, $src2\t#@andI_reg_imm" %}
 7928 
 7929   ins_cost(ALU_COST);
 7930   ins_encode %{
 7931     __ andi(as_Register($dst$$reg),
 7932             as_Register($src1$$reg),
 7933             (int32_t)($src2$$constant));
 7934   %}
 7935 
 7936   ins_pipe(ialu_reg_imm);
 7937 %}
 7938 
 7939 // Register Or
 7940 instruct orI_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2) %{
 7941   match(Set dst (OrI src1 src2));
 7942 
 7943   format %{ "orr  $dst, $src1, $src2\t#@orI_reg_reg" %}
 7944 
 7945   ins_cost(ALU_COST);
 7946   ins_encode %{
 7947     __ orr(as_Register($dst$$reg),
 7948            as_Register($src1$$reg),
 7949            as_Register($src2$$reg));
 7950   %}
 7951 
 7952   ins_pipe(ialu_reg_reg);
 7953 %}
 7954 
 7955 // Immediate Or
 7956 instruct orI_reg_imm(iRegINoSp dst, iRegI src1, immIAdd src2) %{
 7957   match(Set dst (OrI src1 src2));
 7958 
 7959   format %{ "ori  $dst, $src1, $src2\t#@orI_reg_imm" %}
 7960 
 7961   ins_cost(ALU_COST);
 7962   ins_encode %{
 7963     __ ori(as_Register($dst$$reg),
 7964            as_Register($src1$$reg),
 7965            (int32_t)($src2$$constant));
 7966   %}
 7967 
 7968   ins_pipe(ialu_reg_imm);
 7969 %}
 7970 
 7971 // Register Xor
 7972 instruct xorI_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2) %{
 7973   match(Set dst (XorI src1 src2));
 7974 
 7975   format %{ "xorr  $dst, $src1, $src2\t#@xorI_reg_reg" %}
 7976 
 7977   ins_cost(ALU_COST);
 7978   ins_encode %{
 7979     __ xorr(as_Register($dst$$reg),
 7980             as_Register($src1$$reg),
 7981             as_Register($src2$$reg));
 7982   %}
 7983 
 7984   ins_pipe(ialu_reg_reg);
 7985 %}
 7986 
 7987 // Immediate Xor
 7988 instruct xorI_reg_imm(iRegINoSp dst, iRegI src1, immIAdd src2) %{
 7989   match(Set dst (XorI src1 src2));
 7990 
 7991   format %{ "xori  $dst, $src1, $src2\t#@xorI_reg_imm" %}
 7992 
 7993   ins_cost(ALU_COST);
 7994   ins_encode %{
 7995     __ xori(as_Register($dst$$reg),
 7996             as_Register($src1$$reg),
 7997             (int32_t)($src2$$constant));
 7998   %}
 7999 
 8000   ins_pipe(ialu_reg_imm);
 8001 %}
 8002 
 8003 // Register And Long
 8004 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
 8005   match(Set dst (AndL src1 src2));
 8006 
 8007   format %{ "andr  $dst, $src1, $src2\t#@andL_reg_reg" %}
 8008 
 8009   ins_cost(ALU_COST);
 8010   ins_encode %{
 8011     __ andr(as_Register($dst$$reg),
 8012             as_Register($src1$$reg),
 8013             as_Register($src2$$reg));
 8014   %}
 8015 
 8016   ins_pipe(ialu_reg_reg);
 8017 %}
 8018 
 8019 // Immediate And Long
 8020 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{
 8021   match(Set dst (AndL src1 src2));
 8022 
 8023   format %{ "andi  $dst, $src1, $src2\t#@andL_reg_imm" %}
 8024 
 8025   ins_cost(ALU_COST);
 8026   ins_encode %{
 8027     __ andi(as_Register($dst$$reg),
 8028             as_Register($src1$$reg),
 8029             (int32_t)($src2$$constant));
 8030   %}
 8031 
 8032   ins_pipe(ialu_reg_imm);
 8033 %}
 8034 
 8035 // Register Or Long
 8036 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
 8037   match(Set dst (OrL src1 src2));
 8038 
 8039   format %{ "orr  $dst, $src1, $src2\t#@orL_reg_reg" %}
 8040 
 8041   ins_cost(ALU_COST);
 8042   ins_encode %{
 8043     __ orr(as_Register($dst$$reg),
 8044            as_Register($src1$$reg),
 8045            as_Register($src2$$reg));
 8046   %}
 8047 
 8048   ins_pipe(ialu_reg_reg);
 8049 %}
 8050 
 8051 // Immediate Or Long
 8052 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{
 8053   match(Set dst (OrL src1 src2));
 8054 
 8055   format %{ "ori  $dst, $src1, $src2\t#@orL_reg_imm" %}
 8056 
 8057   ins_cost(ALU_COST);
 8058   ins_encode %{
 8059     __ ori(as_Register($dst$$reg),
 8060            as_Register($src1$$reg),
 8061            (int32_t)($src2$$constant));
 8062   %}
 8063 
 8064   ins_pipe(ialu_reg_imm);
 8065 %}
 8066 
 8067 // Register Xor Long
 8068 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
 8069   match(Set dst (XorL src1 src2));
 8070 
 8071   format %{ "xorr  $dst, $src1, $src2\t#@xorL_reg_reg" %}
 8072 
 8073   ins_cost(ALU_COST);
 8074   ins_encode %{
 8075     __ xorr(as_Register($dst$$reg),
 8076             as_Register($src1$$reg),
 8077             as_Register($src2$$reg));
 8078   %}
 8079 
 8080   ins_pipe(ialu_reg_reg);
 8081 %}
 8082 
 8083 // Immediate Xor Long
 8084 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{
 8085   match(Set dst (XorL src1 src2));
 8086 
 8087   ins_cost(ALU_COST);
 8088   format %{ "xori  $dst, $src1, $src2\t#@xorL_reg_imm" %}
 8089 
 8090   ins_encode %{
 8091     __ xori(as_Register($dst$$reg),
 8092             as_Register($src1$$reg),
 8093             (int32_t)($src2$$constant));
 8094   %}
 8095 
 8096   ins_pipe(ialu_reg_imm);
 8097 %}
 8098 
 8099 // ============================================================================
 8100 // MemBar Instruction
 8101 
 8102 // RVTSO
 8103 
 8104 instruct unnecessary_membar_rvtso() %{
 8105   predicate(UseZtso);
 8106   match(LoadFence);
 8107   match(StoreFence);
 8108   match(StoreStoreFence);
 8109   match(MemBarAcquire);
 8110   match(MemBarRelease);
 8111   match(MemBarStoreStore);
 8112   match(MemBarAcquireLock);
 8113   match(MemBarReleaseLock);
 8114 
 8115   ins_cost(0);
 8116 
 8117   size(0);
 8118 
 8119   format %{ "#@unnecessary_membar_rvtso elided/tso (empty encoding)" %}
 8120   ins_encode %{
 8121     __ block_comment("unnecessary_membar_rvtso");
 8122   %}
 8123   ins_pipe(real_empty);
 8124 %}
 8125 
 8126 instruct membar_storeload_rvtso() %{
 8127   predicate(UseZtso);
 8128   match(MemBarStoreLoad);
 8129   ins_cost(VOLATILE_REF_COST);
 8130 
 8131   format %{ "#@membar_storeload_rvtso\n\t"
 8132             "fence w, r"%}
 8133 
 8134   ins_encode %{
 8135     __ block_comment("membar_storeload_rvtso");
 8136     __ membar(MacroAssembler::StoreLoad);
 8137   %}
 8138 
 8139   ins_pipe(pipe_slow);
 8140 %}
 8141 
 8142 instruct membar_volatile_rvtso() %{
 8143   predicate(UseZtso);
 8144   match(MemBarVolatile);
 8145   ins_cost(VOLATILE_REF_COST);
 8146 
 8147   format %{ "#@membar_volatile_rvtso\n\t"
 8148             "fence w, r"%}
 8149 
 8150   ins_encode %{
 8151     __ block_comment("membar_volatile_rvtso");
 8152     __ membar(MacroAssembler::StoreLoad);
 8153   %}
 8154 
 8155   ins_pipe(pipe_slow);
 8156 %}
 8157 
 8158 instruct unnecessary_membar_volatile_rvtso() %{
 8159   predicate(UseZtso && Matcher::post_store_load_barrier(n));
 8160   match(MemBarVolatile);
 8161   ins_cost(0);
 8162 
 8163   size(0);
 8164 
 8165   format %{ "#@unnecessary_membar_volatile_rvtso (unnecessary so empty encoding)" %}
 8166   ins_encode %{
 8167     __ block_comment("unnecessary_membar_volatile_rvtso");
 8168   %}
 8169   ins_pipe(real_empty);
 8170 %}
 8171 
 8172 instruct membar_full_rvtso() %{
 8173   predicate(UseZtso);
 8174   match(MemBarFull);
 8175   ins_cost(VOLATILE_REF_COST);
 8176 
 8177   format %{ "#@membar_full_rvtso\n\t"
 8178             "fence rw, rw" %}
 8179 
 8180   ins_encode %{
 8181     __ block_comment("membar_full_rvtso");
 8182     __ membar(MacroAssembler::AnyAny);
 8183   %}
 8184 
 8185   ins_pipe(pipe_slow);
 8186 %}
 8187 
 8188 // RVWMO
 8189 
 8190 instruct membar_aqcuire_rvwmo() %{
 8191   predicate(!UseZtso);
 8192   match(LoadFence);
 8193   match(MemBarAcquire);
 8194   ins_cost(VOLATILE_REF_COST);
 8195 
 8196   format %{ "#@membar_aqcuire_rvwmo\n\t"
 8197             "fence r, rw" %}
 8198 
 8199   ins_encode %{
 8200     __ block_comment("membar_aqcuire_rvwmo");
 8201     __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore);
 8202   %}
 8203   ins_pipe(pipe_serial);
 8204 %}
 8205 
 8206 instruct membar_release_rvwmo() %{
 8207   predicate(!UseZtso);
 8208   match(StoreFence);
 8209   match(MemBarRelease);
 8210   ins_cost(VOLATILE_REF_COST);
 8211 
 8212   format %{ "#@membar_release_rvwmo\n\t"
 8213             "fence rw, w" %}
 8214 
 8215   ins_encode %{
 8216     __ block_comment("membar_release_rvwmo");
 8217     __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore);
 8218   %}
 8219   ins_pipe(pipe_serial);
 8220 %}
 8221 
 8222 instruct membar_storestore_rvwmo() %{
 8223   predicate(!UseZtso);
 8224   match(MemBarStoreStore);
 8225   match(StoreStoreFence);
 8226   ins_cost(VOLATILE_REF_COST);
 8227 
 8228   format %{ "#@membar_storestore_rvwmo\n\t"
 8229             "fence w, w" %}
 8230 
 8231   ins_encode %{
 8232     __ membar(MacroAssembler::StoreStore);
 8233   %}
 8234   ins_pipe(pipe_serial);
 8235 %}
 8236 
 8237 instruct membar_storeload_rvwmo() %{
 8238   predicate(!UseZtso);
 8239   match(MemBarStoreLoad);
 8240   ins_cost(VOLATILE_REF_COST);
 8241 
 8242   format %{ "#@membar_storeload_rvwmo\n\t"
 8243             "fence w, r"%}
 8244 
 8245   ins_encode %{
 8246     __ block_comment("membar_storeload_rvwmo");
 8247     __ membar(MacroAssembler::StoreLoad);
 8248   %}
 8249 
 8250   ins_pipe(pipe_serial);
 8251 %}
 8252 
 8253 instruct membar_volatile_rvwmo() %{
 8254   predicate(!UseZtso);
 8255   match(MemBarVolatile);
 8256   ins_cost(VOLATILE_REF_COST);
 8257 
 8258   format %{ "#@membar_volatile_rvwmo\n\t"
 8259             "fence w, r"%}
 8260 
 8261   ins_encode %{
 8262     __ block_comment("membar_volatile_rvwmo");
 8263     __ membar(MacroAssembler::StoreLoad);
 8264   %}
 8265 
 8266   ins_pipe(pipe_serial);
 8267 %}
 8268 
 8269 instruct membar_lock_rvwmo() %{
 8270   predicate(!UseZtso);
 8271   match(MemBarAcquireLock);
 8272   match(MemBarReleaseLock);
 8273   ins_cost(0);
 8274 
 8275   format %{ "#@membar_lock_rvwmo (elided)" %}
 8276 
 8277   ins_encode %{
 8278     __ block_comment("membar_lock_rvwmo (elided)");
 8279   %}
 8280 
 8281   ins_pipe(pipe_serial);
 8282 %}
 8283 
 8284 instruct unnecessary_membar_volatile_rvwmo() %{
 8285   predicate(!UseZtso && Matcher::post_store_load_barrier(n));
 8286   match(MemBarVolatile);
 8287   ins_cost(0);
 8288 
 8289   size(0);
 8290   format %{ "#@unnecessary_membar_volatile_rvwmo (unnecessary so empty encoding)" %}
 8291   ins_encode %{
 8292     __ block_comment("unnecessary_membar_volatile_rvwmo");
 8293   %}
 8294   ins_pipe(real_empty);
 8295 %}
 8296 
 8297 instruct membar_full_rvwmo() %{
 8298   predicate(!UseZtso);
 8299   match(MemBarFull);
 8300   ins_cost(VOLATILE_REF_COST);
 8301 
 8302   format %{ "#@membar_full_rvwmo\n\t"
 8303             "fence rw, rw" %}
 8304 
 8305   ins_encode %{
 8306     __ block_comment("membar_full_rvwmo");
 8307     __ membar(MacroAssembler::AnyAny);
 8308   %}
 8309 
 8310   ins_pipe(pipe_serial);
 8311 %}
 8312 
 8313 instruct spin_wait() %{
 8314   predicate(UseZihintpause);
 8315   match(OnSpinWait);
 8316   ins_cost(CACHE_MISS_COST);
 8317 
 8318   format %{ "spin_wait" %}
 8319 
 8320   ins_encode %{
 8321     __ pause();
 8322   %}
 8323 
 8324   ins_pipe(pipe_serial);
 8325 %}
 8326 
 8327 // ============================================================================
 8328 // Cast Instructions (Java-level type cast)
 8329 
 8330 instruct castI2N(iRegNNoSp dst, iRegI src) %{
 8331   match(Set dst (CastI2N src));
 8332 
 8333   ins_cost(ALU_COST);
 8334   format %{ "zext $dst, $src, 32\t# int -> narrow ptr" %}
 8335 
 8336   ins_encode %{
 8337     __ zext(as_Register($dst$$reg), as_Register($src$$reg), 32);
 8338   %}
 8339 
 8340   ins_pipe(ialu_reg);
 8341 %}
 8342 
 8343 instruct castN2X(iRegLNoSp dst, iRegN src) %{
 8344   match(Set dst (CastP2X src));
 8345 
 8346   ins_cost(ALU_COST);
 8347   format %{ "mv $dst, $src\t# ptr -> long" %}
 8348 
 8349   ins_encode %{
 8350     if ($dst$$reg != $src$$reg) {
 8351       __ mv(as_Register($dst$$reg), as_Register($src$$reg));
 8352     }
 8353   %}
 8354 
 8355   ins_pipe(ialu_reg);
 8356 %}
 8357 
 8358 instruct castX2P(iRegPNoSp dst, iRegL src) %{
 8359   match(Set dst (CastX2P src));
 8360 
 8361   ins_cost(ALU_COST);
 8362   format %{ "mv  $dst, $src\t# long -> ptr, #@castX2P" %}
 8363 
 8364   ins_encode %{
 8365     if ($dst$$reg != $src$$reg) {
 8366       __ mv(as_Register($dst$$reg), as_Register($src$$reg));
 8367     }
 8368   %}
 8369 
 8370   ins_pipe(ialu_reg);
 8371 %}
 8372 
 8373 instruct castP2X(iRegLNoSp dst, iRegP src) %{
 8374   match(Set dst (CastP2X src));
 8375 
 8376   ins_cost(ALU_COST);
 8377   format %{ "mv  $dst, $src\t# ptr -> long, #@castP2X" %}
 8378 
 8379   ins_encode %{
 8380     if ($dst$$reg != $src$$reg) {
 8381       __ mv(as_Register($dst$$reg), as_Register($src$$reg));
 8382     }
 8383   %}
 8384 
 8385   ins_pipe(ialu_reg);
 8386 %}
 8387 
 8388 instruct castPP(iRegPNoSp dst)
 8389 %{
 8390   match(Set dst (CastPP dst));
 8391   ins_cost(0);
 8392 
 8393   size(0);
 8394   format %{ "# castPP of $dst, #@castPP" %}
 8395   ins_encode(/* empty encoding */);
 8396   ins_pipe(pipe_class_empty);
 8397 %}
 8398 
 8399 instruct castLL(iRegL dst)
 8400 %{
 8401   match(Set dst (CastLL dst));
 8402 
 8403   size(0);
 8404   format %{ "# castLL of $dst, #@castLL" %}
 8405   ins_encode(/* empty encoding */);
 8406   ins_cost(0);
 8407   ins_pipe(pipe_class_empty);
 8408 %}
 8409 
 8410 instruct castII(iRegI dst)
 8411 %{
 8412   match(Set dst (CastII dst));
 8413 
 8414   size(0);
 8415   format %{ "# castII of $dst, #@castII" %}
 8416   ins_encode(/* empty encoding */);
 8417   ins_cost(0);
 8418   ins_pipe(pipe_class_empty);
 8419 %}
 8420 
 8421 instruct checkCastPP(iRegPNoSp dst)
 8422 %{
 8423   match(Set dst (CheckCastPP dst));
 8424 
 8425   size(0);
 8426   ins_cost(0);
 8427   format %{ "# checkcastPP of $dst, #@checkCastPP" %}
 8428   ins_encode(/* empty encoding */);
 8429   ins_pipe(pipe_class_empty);
 8430 %}
 8431 
 8432 instruct castHH(fRegF dst)
 8433 %{
 8434   match(Set dst (CastHH dst));
 8435 
 8436   size(0);
 8437   format %{ "# castHH of $dst" %}
 8438   ins_encode(/* empty encoding */);
 8439   ins_cost(0);
 8440   ins_pipe(pipe_class_empty);
 8441 %}
 8442 
 8443 instruct castFF(fRegF dst)
 8444 %{
 8445   match(Set dst (CastFF dst));
 8446 
 8447   size(0);
 8448   format %{ "# castFF of $dst" %}
 8449   ins_encode(/* empty encoding */);
 8450   ins_cost(0);
 8451   ins_pipe(pipe_class_empty);
 8452 %}
 8453 
 8454 instruct castDD(fRegD dst)
 8455 %{
 8456   match(Set dst (CastDD dst));
 8457 
 8458   size(0);
 8459   format %{ "# castDD of $dst" %}
 8460   ins_encode(/* empty encoding */);
 8461   ins_cost(0);
 8462   ins_pipe(pipe_class_empty);
 8463 %}
 8464 
 8465 instruct castVV(vReg dst)
 8466 %{
 8467   match(Set dst (CastVV dst));
 8468 
 8469   size(0);
 8470   format %{ "# castVV of $dst" %}
 8471   ins_encode(/* empty encoding */);
 8472   ins_cost(0);
 8473   ins_pipe(pipe_class_empty);
 8474 %}
 8475 
 8476 instruct castVVMask(vRegMask dst)
 8477 %{
 8478   match(Set dst (CastVV dst));
 8479 
 8480   size(0);
 8481   format %{ "# castVV of $dst" %}
 8482   ins_encode(/* empty encoding */);
 8483   ins_cost(0);
 8484   ins_pipe(pipe_class_empty);
 8485 %}
 8486 
 8487 // ============================================================================
 8488 // Convert Instructions
 8489 
 8490 // int to bool
 8491 instruct convI2Bool(iRegINoSp dst, iRegI src)
 8492 %{
 8493   match(Set dst (Conv2B src));
 8494 
 8495   ins_cost(ALU_COST);
 8496   format %{ "snez  $dst, $src\t#@convI2Bool" %}
 8497 
 8498   ins_encode %{
 8499     __ snez(as_Register($dst$$reg), as_Register($src$$reg));
 8500   %}
 8501 
 8502   ins_pipe(ialu_reg);
 8503 %}
 8504 
 8505 // pointer to bool
 8506 instruct convP2Bool(iRegINoSp dst, iRegP src)
 8507 %{
 8508   match(Set dst (Conv2B src));
 8509 
 8510   ins_cost(ALU_COST);
 8511   format %{ "snez  $dst, $src\t#@convP2Bool" %}
 8512 
 8513   ins_encode %{
 8514     __ snez(as_Register($dst$$reg), as_Register($src$$reg));
 8515   %}
 8516 
 8517   ins_pipe(ialu_reg);
 8518 %}
 8519 
 8520 // int <-> long
 8521 
 8522 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src)
 8523 %{
 8524   match(Set dst (ConvI2L src));
 8525 
 8526   ins_cost(ALU_COST);
 8527   format %{ "addw  $dst, $src, zr\t#@convI2L_reg_reg" %}
 8528   ins_encode %{
 8529     __ sext(as_Register($dst$$reg), as_Register($src$$reg), 32);
 8530   %}
 8531   ins_pipe(ialu_reg);
 8532 %}
 8533 
 8534 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{
 8535   match(Set dst (ConvL2I src));
 8536 
 8537   ins_cost(ALU_COST);
 8538   format %{ "addw  $dst, $src, zr\t#@convL2I_reg" %}
 8539 
 8540   ins_encode %{
 8541     __ sext(as_Register($dst$$reg), as_Register($src$$reg), 32);
 8542   %}
 8543 
 8544   ins_pipe(ialu_reg);
 8545 %}
 8546 
 8547 // int to unsigned long (Zero-extend)
 8548 instruct convI2UL_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask)
 8549 %{
 8550   match(Set dst (AndL (ConvI2L src) mask));
 8551 
 8552   ins_cost(ALU_COST * 2);
 8553   format %{ "zext $dst, $src, 32\t# i2ul, #@convI2UL_reg_reg" %}
 8554 
 8555   ins_encode %{
 8556     __ zext(as_Register($dst$$reg), as_Register($src$$reg), 32);
 8557   %}
 8558 
 8559   ins_pipe(ialu_reg_shift);
 8560 %}
 8561 
 8562 // float <-> double
 8563 
 8564 instruct convF2D_reg(fRegD dst, fRegF src) %{
 8565   match(Set dst (ConvF2D src));
 8566 
 8567   ins_cost(XFER_COST);
 8568   format %{ "fcvt.d.s  $dst, $src\t#@convF2D_reg" %}
 8569 
 8570   ins_encode %{
 8571     __ fcvt_d_s(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg));
 8572   %}
 8573 
 8574   ins_pipe(fp_f2d);
 8575 %}
 8576 
 8577 instruct convD2F_reg(fRegF dst, fRegD src) %{
 8578   match(Set dst (ConvD2F src));
 8579 
 8580   ins_cost(XFER_COST);
 8581   format %{ "fcvt.s.d  $dst, $src\t#@convD2F_reg" %}
 8582 
 8583   ins_encode %{
 8584     __ fcvt_s_d(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg));
 8585   %}
 8586 
 8587   ins_pipe(fp_d2f);
 8588 %}
 8589 
 8590 // single <-> half precision
 8591 
 8592 instruct convHF2F_reg_reg(fRegF dst, iRegIorL2I src, iRegINoSp tmp) %{
 8593   match(Set dst (ConvHF2F src));
 8594   effect(TEMP tmp);
 8595   format %{ "fmv.h.x $dst, $src\t# move source from $src to $dst\n\t"
 8596             "fcvt.s.h $dst, $dst\t# convert half to single precision"
 8597   %}
 8598   ins_encode %{
 8599     __ float16_to_float($dst$$FloatRegister, $src$$Register, $tmp$$Register);
 8600   %}
 8601   ins_pipe(pipe_slow);
 8602 %}
 8603 
 8604 instruct convF2HF_reg_reg(iRegINoSp dst, fRegF src, fRegF ftmp, iRegINoSp xtmp) %{
 8605   match(Set dst (ConvF2HF src));
 8606   effect(TEMP_DEF dst, TEMP ftmp, TEMP xtmp);
 8607   format %{ "fcvt.h.s $ftmp, $src\t# convert single precision to half\n\t"
 8608             "fmv.x.h $dst, $ftmp\t# move result from $ftmp to $dst"
 8609   %}
 8610   ins_encode %{
 8611     __ float_to_float16($dst$$Register, $src$$FloatRegister, $ftmp$$FloatRegister, $xtmp$$Register);
 8612   %}
 8613   ins_pipe(pipe_slow);
 8614 %}
 8615 
 8616 // half precision operations
 8617 
 8618 instruct reinterpretS2HF(fRegF dst, iRegI src)
 8619 %{
 8620   match(Set dst (ReinterpretS2HF src));
 8621   format %{ "fmv.h.x $dst, $src\t# reinterpretS2HF" %}
 8622   ins_encode %{
 8623     __ fmv_h_x($dst$$FloatRegister, $src$$Register);
 8624   %}
 8625   ins_pipe(fp_i2f);
 8626 %}
 8627 
 8628 instruct convF2HFAndS2HF(fRegF dst, fRegF src)
 8629 %{
 8630   match(Set dst (ReinterpretS2HF (ConvF2HF src)));
 8631   format %{ "convF2HFAndS2HF $dst, $src" %}
 8632   ins_encode %{
 8633     __ fcvt_h_s($dst$$FloatRegister, $src$$FloatRegister);
 8634   %}
 8635   ins_pipe(fp_uop_s);
 8636 %}
 8637 
 8638 instruct reinterpretHF2S(iRegINoSp dst, fRegF src)
 8639 %{
 8640   match(Set dst (ReinterpretHF2S src));
 8641   format %{ "fmv.x.h $dst, $src\t# reinterpretHF2S" %}
 8642   ins_encode %{
 8643     __ fmv_x_h($dst$$Register, $src$$FloatRegister);
 8644   %}
 8645   ins_pipe(fp_f2i);
 8646 %}
 8647 
 8648 instruct convHF2SAndHF2F(fRegF dst, fRegF src)
 8649 %{
 8650   match(Set dst (ConvHF2F (ReinterpretHF2S src)));
 8651   format %{ "convHF2SAndHF2F $dst, $src" %}
 8652   ins_encode %{
 8653     __ fcvt_s_h($dst$$FloatRegister, $src$$FloatRegister);
 8654   %}
 8655   ins_pipe(fp_uop_s);
 8656 %}
 8657 
 8658 instruct sqrt_HF_reg(fRegF dst, fRegF src)
 8659 %{
 8660   match(Set dst (SqrtHF src));
 8661   format %{ "fsqrt.h $dst, $src" %}
 8662   ins_encode %{
 8663     __ fsqrt_h($dst$$FloatRegister, $src$$FloatRegister);
 8664   %}
 8665   ins_pipe(fp_sqrt_s);
 8666 %}
 8667 
 8668 instruct binOps_HF_reg(fRegF dst, fRegF src1, fRegF src2)
 8669 %{
 8670   match(Set dst (AddHF src1 src2));
 8671   match(Set dst (SubHF src1 src2));
 8672   match(Set dst (MulHF src1 src2));
 8673   match(Set dst (DivHF src1 src2));
 8674   format %{ "binop_hf $dst, $src1, $src2" %}
 8675   ins_encode %{
 8676     int opcode = this->ideal_Opcode();
 8677     switch(opcode) {
 8678       case Op_AddHF: __ fadd_h($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); break;
 8679       case Op_SubHF: __ fsub_h($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); break;
 8680       case Op_MulHF: __ fmul_h($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); break;
 8681       case Op_DivHF: __ fdiv_h($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); break;
 8682       default: assert(false, "%s is not supported here", NodeClassNames[opcode]); break;
 8683     }
 8684   %}
 8685   ins_pipe(fp_dop_reg_reg_s);
 8686 %}
 8687 
 8688 instruct min_HF_reg(fRegF dst, fRegF src1, fRegF src2, rFlagsReg cr)
 8689 %{
 8690   predicate(!UseZfa);
 8691   match(Set dst (MinHF src1 src2));
 8692   effect(KILL cr);
 8693 
 8694   format %{ "min_hf $dst, $src1, $src2" %}
 8695 
 8696   ins_encode %{
 8697     __ minmax_fp($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 8698                  __ FLOAT_TYPE::half_precision, true /* is_min */);
 8699   %}
 8700   ins_pipe(pipe_class_default);
 8701 %}
 8702 
 8703 instruct min_HF_reg_zfa(fRegF dst, fRegF src1, fRegF src2)
 8704 %{
 8705   predicate(UseZfa);
 8706   match(Set dst (MinHF src1 src2));
 8707 
 8708   format %{ "min_hf $dst, $src1, $src2" %}
 8709 
 8710   ins_encode %{
 8711     __ fminm_h(as_FloatRegister($dst$$reg),
 8712                as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
 8713   %}
 8714 
 8715   ins_pipe(pipe_class_default);
 8716 %}
 8717 
 8718 instruct max_HF_reg(fRegF dst, fRegF src1, fRegF src2, rFlagsReg cr)
 8719 %{
 8720   predicate(!UseZfa);
 8721   match(Set dst (MaxHF src1 src2));
 8722   effect(KILL cr);
 8723 
 8724   format %{ "max_hf $dst, $src1, $src2" %}
 8725 
 8726   ins_encode %{
 8727     __ minmax_fp($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 8728                  __ FLOAT_TYPE::half_precision, false /* is_min */);
 8729   %}
 8730   ins_pipe(pipe_class_default);
 8731 %}
 8732 
 8733 instruct max_HF_reg_zfa(fRegF dst, fRegF src1, fRegF src2)
 8734 %{
 8735   predicate(UseZfa);
 8736   match(Set dst (MaxHF src1 src2));
 8737 
 8738   format %{ "max_hf $dst, $src1, $src2" %}
 8739 
 8740   ins_encode %{
 8741     __ fmaxm_h(as_FloatRegister($dst$$reg),
 8742                as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
 8743   %}
 8744 
 8745   ins_pipe(pipe_class_default);
 8746 %}
 8747 
 8748 instruct fma_HF_reg(fRegF dst, fRegF src1, fRegF src2, fRegF src3)
 8749 %{
 8750   match(Set dst (FmaHF src3 (Binary src1 src2)));
 8751   format %{ "fmadd.h $dst, $src1, $src2, $src3\t# $dst = $src1 * $src2 + $src3 fma packedH" %}
 8752   ins_encode %{
 8753     __ fmadd_h($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
 8754   %}
 8755   ins_pipe(pipe_class_default);
 8756 %}
 8757 
 8758 // float <-> int
 8759 
 8760 instruct convF2I_reg_reg(iRegINoSp dst, fRegF src) %{
 8761   match(Set dst (ConvF2I src));
 8762 
 8763   ins_cost(XFER_COST);
 8764   format %{ "fcvt.w.s  $dst, $src\t#@convF2I_reg_reg" %}
 8765 
 8766   ins_encode %{
 8767     __ fcvt_w_s_safe($dst$$Register, $src$$FloatRegister);
 8768   %}
 8769 
 8770   ins_pipe(fp_f2i);
 8771 %}
 8772 
 8773 instruct convI2F_reg_reg(fRegF dst, iRegIorL2I src) %{
 8774   match(Set dst (ConvI2F src));
 8775 
 8776   ins_cost(XFER_COST);
 8777   format %{ "fcvt.s.w  $dst, $src\t#@convI2F_reg_reg" %}
 8778 
 8779   ins_encode %{
 8780     __ fcvt_s_w(as_FloatRegister($dst$$reg), as_Register($src$$reg));
 8781   %}
 8782 
 8783   ins_pipe(fp_i2f);
 8784 %}
 8785 
 8786 // float <-> long
 8787 
 8788 instruct convF2L_reg_reg(iRegLNoSp dst, fRegF src) %{
 8789   match(Set dst (ConvF2L src));
 8790 
 8791   ins_cost(XFER_COST);
 8792   format %{ "fcvt.l.s  $dst, $src\t#@convF2L_reg_reg" %}
 8793 
 8794   ins_encode %{
 8795     __ fcvt_l_s_safe($dst$$Register, $src$$FloatRegister);
 8796   %}
 8797 
 8798   ins_pipe(fp_f2l);
 8799 %}
 8800 
 8801 instruct convL2F_reg_reg(fRegF dst, iRegL src) %{
 8802   match(Set dst (ConvL2F src));
 8803 
 8804   ins_cost(XFER_COST);
 8805   format %{ "fcvt.s.l  $dst, $src\t#@convL2F_reg_reg" %}
 8806 
 8807   ins_encode %{
 8808     __ fcvt_s_l(as_FloatRegister($dst$$reg), as_Register($src$$reg));
 8809   %}
 8810 
 8811   ins_pipe(fp_l2f);
 8812 %}
 8813 
 8814 // double <-> int
 8815 
 8816 instruct convD2I_reg_reg(iRegINoSp dst, fRegD src) %{
 8817   match(Set dst (ConvD2I src));
 8818 
 8819   ins_cost(XFER_COST);
 8820   format %{ "fcvt.w.d  $dst, $src\t#@convD2I_reg_reg" %}
 8821 
 8822   ins_encode %{
 8823     __ fcvt_w_d_safe($dst$$Register, $src$$FloatRegister);
 8824   %}
 8825 
 8826   ins_pipe(fp_d2i);
 8827 %}
 8828 
 8829 instruct convI2D_reg_reg(fRegD dst, iRegIorL2I src) %{
 8830   match(Set dst (ConvI2D src));
 8831 
 8832   ins_cost(XFER_COST);
 8833   format %{ "fcvt.d.w  $dst, $src\t#@convI2D_reg_reg" %}
 8834 
 8835   ins_encode %{
 8836     __ fcvt_d_w(as_FloatRegister($dst$$reg), as_Register($src$$reg));
 8837   %}
 8838 
 8839   ins_pipe(fp_i2d);
 8840 %}
 8841 
 8842 // double <-> long
 8843 
 8844 instruct convD2L_reg_reg(iRegLNoSp dst, fRegD src) %{
 8845   match(Set dst (ConvD2L src));
 8846 
 8847   ins_cost(XFER_COST);
 8848   format %{ "fcvt.l.d  $dst, $src\t#@convD2L_reg_reg" %}
 8849 
 8850   ins_encode %{
 8851     __ fcvt_l_d_safe($dst$$Register, $src$$FloatRegister);
 8852   %}
 8853 
 8854   ins_pipe(fp_d2l);
 8855 %}
 8856 
 8857 instruct convL2D_reg_reg(fRegD dst, iRegL src) %{
 8858   match(Set dst (ConvL2D src));
 8859 
 8860   ins_cost(XFER_COST);
 8861   format %{ "fcvt.d.l  $dst, $src\t#@convL2D_reg_reg" %}
 8862 
 8863   ins_encode %{
 8864     __ fcvt_d_l(as_FloatRegister($dst$$reg), as_Register($src$$reg));
 8865   %}
 8866 
 8867   ins_pipe(fp_l2d);
 8868 %}
 8869 
 8870 // Convert oop into int for vectors alignment masking
 8871 instruct convP2I(iRegINoSp dst, iRegP src) %{
 8872   match(Set dst (ConvL2I (CastP2X src)));
 8873 
 8874   ins_cost(ALU_COST * 2);
 8875   format %{ "zext $dst, $src, 32\t# ptr -> int, #@convP2I" %}
 8876 
 8877   ins_encode %{
 8878     __ zext($dst$$Register, $src$$Register, 32);
 8879   %}
 8880 
 8881   ins_pipe(ialu_reg);
 8882 %}
 8883 
 8884 // Convert compressed oop into int for vectors alignment masking
 8885 // in case of 32bit oops (heap < 4Gb).
 8886 instruct convN2I(iRegINoSp dst, iRegN src)
 8887 %{
 8888   predicate(CompressedOops::shift() == 0);
 8889   match(Set dst (ConvL2I (CastP2X (DecodeN src))));
 8890 
 8891   ins_cost(ALU_COST);
 8892   format %{ "mv  $dst, $src\t# compressed ptr -> int, #@convN2I" %}
 8893 
 8894   ins_encode %{
 8895     __ mv($dst$$Register, $src$$Register);
 8896   %}
 8897 
 8898   ins_pipe(ialu_reg);
 8899 %}
 8900 
 8901 instruct round_double_reg(iRegLNoSp dst, fRegD src, fRegD ftmp) %{
 8902   match(Set dst (RoundD src));
 8903 
 8904   ins_cost(XFER_COST + BRANCH_COST);
 8905   effect(TEMP ftmp);
 8906   format %{ "java_round_double $dst, $src\t#@round_double_reg" %}
 8907 
 8908   ins_encode %{
 8909     __ java_round_double($dst$$Register, as_FloatRegister($src$$reg), as_FloatRegister($ftmp$$reg));
 8910   %}
 8911 
 8912   ins_pipe(pipe_slow);
 8913 %}
 8914 
 8915 instruct round_float_reg(iRegINoSp dst, fRegF src, fRegF ftmp) %{
 8916   match(Set dst (RoundF src));
 8917 
 8918   ins_cost(XFER_COST + BRANCH_COST);
 8919   effect(TEMP ftmp);
 8920   format %{ "java_round_float $dst, $src\t#@round_float_reg" %}
 8921 
 8922   ins_encode %{
 8923     __ java_round_float($dst$$Register, as_FloatRegister($src$$reg), as_FloatRegister($ftmp$$reg));
 8924   %}
 8925 
 8926   ins_pipe(pipe_slow);
 8927 %}
 8928 
 8929 // Convert oop pointer into compressed form
 8930 instruct encodeHeapOop(iRegNNoSp dst, iRegP src) %{
 8931   predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
 8932   match(Set dst (EncodeP src));
 8933   ins_cost(ALU_COST);
 8934   format %{ "encode_heap_oop  $dst, $src\t#@encodeHeapOop" %}
 8935   ins_encode %{
 8936     Register s = $src$$Register;
 8937     Register d = $dst$$Register;
 8938     __ encode_heap_oop(d, s);
 8939   %}
 8940   ins_pipe(pipe_class_default);
 8941 %}
 8942 
 8943 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src) %{
 8944   predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
 8945   match(Set dst (EncodeP src));
 8946   ins_cost(ALU_COST);
 8947   format %{ "encode_heap_oop_not_null $dst, $src\t#@encodeHeapOop_not_null" %}
 8948   ins_encode %{
 8949     __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
 8950   %}
 8951   ins_pipe(pipe_class_default);
 8952 %}
 8953 
 8954 instruct decodeHeapOop(iRegPNoSp dst, iRegN src) %{
 8955   predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
 8956             n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
 8957   match(Set dst (DecodeN src));
 8958 
 8959   ins_cost(0);
 8960   format %{ "decode_heap_oop  $dst, $src\t#@decodeHeapOop" %}
 8961   ins_encode %{
 8962     Register s = $src$$Register;
 8963     Register d = $dst$$Register;
 8964     __ decode_heap_oop(d, s);
 8965   %}
 8966   ins_pipe(pipe_class_default);
 8967 %}
 8968 
 8969 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src) %{
 8970   predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
 8971             n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
 8972   match(Set dst (DecodeN src));
 8973 
 8974   ins_cost(0);
 8975   format %{ "decode_heap_oop_not_null $dst, $src\t#@decodeHeapOop_not_null" %}
 8976   ins_encode %{
 8977     Register s = $src$$Register;
 8978     Register d = $dst$$Register;
 8979     __ decode_heap_oop_not_null(d, s);
 8980   %}
 8981   ins_pipe(pipe_class_default);
 8982 %}
 8983 
 8984 // Convert klass pointer into compressed form.
 8985 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{
 8986   match(Set dst (EncodePKlass src));
 8987 
 8988   ins_cost(ALU_COST);
 8989   format %{ "encode_klass_not_null  $dst, $src\t#@encodeKlass_not_null" %}
 8990 
 8991   ins_encode %{
 8992     Register src_reg = as_Register($src$$reg);
 8993     Register dst_reg = as_Register($dst$$reg);
 8994     __ encode_klass_not_null(dst_reg, src_reg, t0);
 8995   %}
 8996 
 8997    ins_pipe(pipe_class_default);
 8998 %}
 8999 
 9000 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src, iRegPNoSp tmp) %{
 9001   match(Set dst (DecodeNKlass src));
 9002 
 9003   effect(TEMP_DEF dst, TEMP tmp);
 9004 
 9005   ins_cost(ALU_COST);
 9006   format %{ "decode_klass_not_null  $dst, $src\t#@decodeKlass_not_null" %}
 9007 
 9008   ins_encode %{
 9009     Register src_reg = as_Register($src$$reg);
 9010     Register dst_reg = as_Register($dst$$reg);
 9011     Register tmp_reg = as_Register($tmp$$reg);
 9012     __ decode_klass_not_null(dst_reg, src_reg, tmp_reg);
 9013   %}
 9014 
 9015    ins_pipe(pipe_class_default);
 9016 %}
 9017 
 9018 // stack <-> reg and reg <-> reg shuffles with no conversion
 9019 
 9020 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{
 9021 
 9022   match(Set dst (MoveF2I src));
 9023 
 9024   effect(DEF dst, USE src);
 9025 
 9026   ins_cost(LOAD_COST);
 9027 
 9028   format %{ "lw  $dst, $src\t#@MoveF2I_stack_reg" %}
 9029 
 9030   ins_encode %{
 9031     __ lw(as_Register($dst$$reg), Address(sp, $src$$disp));
 9032   %}
 9033 
 9034   ins_pipe(iload_reg_reg);
 9035 
 9036 %}
 9037 
 9038 instruct MoveI2F_stack_reg(fRegF dst, stackSlotI src) %{
 9039 
 9040   match(Set dst (MoveI2F src));
 9041 
 9042   effect(DEF dst, USE src);
 9043 
 9044   ins_cost(LOAD_COST);
 9045 
 9046   format %{ "flw  $dst, $src\t#@MoveI2F_stack_reg" %}
 9047 
 9048   ins_encode %{
 9049     __ flw(as_FloatRegister($dst$$reg), Address(sp, $src$$disp));
 9050   %}
 9051 
 9052   ins_pipe(fp_load_mem_s);
 9053 
 9054 %}
 9055 
 9056 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{
 9057 
 9058   match(Set dst (MoveD2L src));
 9059 
 9060   effect(DEF dst, USE src);
 9061 
 9062   ins_cost(LOAD_COST);
 9063 
 9064   format %{ "ld  $dst, $src\t#@MoveD2L_stack_reg" %}
 9065 
 9066   ins_encode %{
 9067     __ ld(as_Register($dst$$reg), Address(sp, $src$$disp));
 9068   %}
 9069 
 9070   ins_pipe(iload_reg_reg);
 9071 
 9072 %}
 9073 
 9074 instruct MoveL2D_stack_reg(fRegD dst, stackSlotL src) %{
 9075 
 9076   match(Set dst (MoveL2D src));
 9077 
 9078   effect(DEF dst, USE src);
 9079 
 9080   ins_cost(LOAD_COST);
 9081 
 9082   format %{ "fld  $dst, $src\t#@MoveL2D_stack_reg" %}
 9083 
 9084   ins_encode %{
 9085     __ fld(as_FloatRegister($dst$$reg), Address(sp, $src$$disp));
 9086   %}
 9087 
 9088   ins_pipe(fp_load_mem_d);
 9089 
 9090 %}
 9091 
 9092 instruct MoveF2I_reg_stack(stackSlotI dst, fRegF src) %{
 9093 
 9094   match(Set dst (MoveF2I src));
 9095 
 9096   effect(DEF dst, USE src);
 9097 
 9098   ins_cost(STORE_COST);
 9099 
 9100   format %{ "fsw  $src, $dst\t#@MoveF2I_reg_stack" %}
 9101 
 9102   ins_encode %{
 9103     __ fsw(as_FloatRegister($src$$reg), Address(sp, $dst$$disp));
 9104   %}
 9105 
 9106   ins_pipe(fp_store_reg_s);
 9107 
 9108 %}
 9109 
 9110 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{
 9111 
 9112   match(Set dst (MoveI2F src));
 9113 
 9114   effect(DEF dst, USE src);
 9115 
 9116   ins_cost(STORE_COST);
 9117 
 9118   format %{ "sw  $src, $dst\t#@MoveI2F_reg_stack" %}
 9119 
 9120   ins_encode %{
 9121     __ sw(as_Register($src$$reg), Address(sp, $dst$$disp));
 9122   %}
 9123 
 9124   ins_pipe(istore_reg_reg);
 9125 
 9126 %}
 9127 
 9128 instruct MoveD2L_reg_stack(stackSlotL dst, fRegD src) %{
 9129 
 9130   match(Set dst (MoveD2L src));
 9131 
 9132   effect(DEF dst, USE src);
 9133 
 9134   ins_cost(STORE_COST);
 9135 
 9136   format %{ "fsd  $dst, $src\t#@MoveD2L_reg_stack" %}
 9137 
 9138   ins_encode %{
 9139     __ fsd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp));
 9140   %}
 9141 
 9142   ins_pipe(fp_store_reg_d);
 9143 
 9144 %}
 9145 
 9146 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{
 9147 
 9148   match(Set dst (MoveL2D src));
 9149 
 9150   effect(DEF dst, USE src);
 9151 
 9152   ins_cost(STORE_COST);
 9153 
 9154   format %{ "sd  $src, $dst\t#@MoveL2D_reg_stack" %}
 9155 
 9156   ins_encode %{
 9157     __ sd(as_Register($src$$reg), Address(sp, $dst$$disp));
 9158   %}
 9159 
 9160   ins_pipe(istore_reg_reg);
 9161 
 9162 %}
 9163 
 9164 instruct MoveF2I_reg_reg(iRegINoSp dst, fRegF src) %{
 9165 
 9166   match(Set dst (MoveF2I src));
 9167 
 9168   effect(DEF dst, USE src);
 9169 
 9170   ins_cost(FMVX_COST);
 9171 
 9172   format %{ "fmv.x.w  $dst, $src\t#@MoveF2I_reg_reg" %}
 9173 
 9174   ins_encode %{
 9175     __ fmv_x_w(as_Register($dst$$reg), as_FloatRegister($src$$reg));
 9176   %}
 9177 
 9178   ins_pipe(fp_f2i);
 9179 
 9180 %}
 9181 
 9182 instruct MoveI2F_reg_reg(fRegF dst, iRegI src) %{
 9183 
 9184   match(Set dst (MoveI2F src));
 9185 
 9186   effect(DEF dst, USE src);
 9187 
 9188   ins_cost(FMVX_COST);
 9189 
 9190   format %{ "fmv.w.x  $dst, $src\t#@MoveI2F_reg_reg" %}
 9191 
 9192   ins_encode %{
 9193     __ fmv_w_x(as_FloatRegister($dst$$reg), as_Register($src$$reg));
 9194   %}
 9195 
 9196   ins_pipe(fp_i2f);
 9197 
 9198 %}
 9199 
 9200 instruct MoveD2L_reg_reg(iRegLNoSp dst, fRegD src) %{
 9201 
 9202   match(Set dst (MoveD2L src));
 9203 
 9204   effect(DEF dst, USE src);
 9205 
 9206   ins_cost(FMVX_COST);
 9207 
 9208   format %{ "fmv.x.d $dst, $src\t#@MoveD2L_reg_reg" %}
 9209 
 9210   ins_encode %{
 9211     __ fmv_x_d(as_Register($dst$$reg), as_FloatRegister($src$$reg));
 9212   %}
 9213 
 9214   ins_pipe(fp_d2l);
 9215 
 9216 %}
 9217 
 9218 instruct MoveL2D_reg_reg(fRegD dst, iRegL src) %{
 9219 
 9220   match(Set dst (MoveL2D src));
 9221 
 9222   effect(DEF dst, USE src);
 9223 
 9224   ins_cost(FMVX_COST);
 9225 
 9226   format %{ "fmv.d.x  $dst, $src\t#@MoveL2D_reg_reg" %}
 9227 
 9228   ins_encode %{
 9229     __ fmv_d_x(as_FloatRegister($dst$$reg), as_Register($src$$reg));
 9230   %}
 9231 
 9232   ins_pipe(fp_l2d);
 9233 
 9234 %}
 9235 
 9236 // ============================================================================
 9237 // Compare Instructions which set the result float comparisons in dest register.
 9238 
 9239 instruct cmpF3_reg_reg(iRegINoSp dst, fRegF op1, fRegF op2)
 9240 %{
 9241   match(Set dst (CmpF3 op1 op2));
 9242 
 9243   ins_cost(XFER_COST * 2 + BRANCH_COST + ALU_COST);
 9244   format %{ "flt.s  $dst, $op2, $op1\t#@cmpF3_reg_reg\n\t"
 9245             "bgtz   $dst, done\n\t"
 9246             "feq.s  $dst, $op1, $op2\n\t"
 9247             "addi   $dst, $dst, -1\n\t"
 9248             "done:"
 9249   %}
 9250 
 9251   ins_encode %{
 9252     // we want -1 for unordered or less than, 0 for equal and 1 for greater than.
 9253     __ float_compare(as_Register($dst$$reg), as_FloatRegister($op1$$reg),
 9254                      as_FloatRegister($op2$$reg), -1 /*unordered_result < 0*/);
 9255   %}
 9256 
 9257   ins_pipe(pipe_class_default);
 9258 %}
 9259 
 9260 instruct cmpD3_reg_reg(iRegINoSp dst, fRegD op1, fRegD op2)
 9261 %{
 9262   match(Set dst (CmpD3 op1 op2));
 9263 
 9264   ins_cost(XFER_COST * 2 + BRANCH_COST + ALU_COST);
 9265   format %{ "flt.d  $dst, $op2, $op1\t#@cmpD3_reg_reg\n\t"
 9266             "bgtz   $dst, done\n\t"
 9267             "feq.d  $dst, $op1, $op2\n\t"
 9268             "addi   $dst, $dst, -1\n\t"
 9269             "done:"
 9270   %}
 9271 
 9272   ins_encode %{
 9273     // we want -1 for unordered or less than, 0 for equal and 1 for greater than.
 9274     __ double_compare(as_Register($dst$$reg), as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg), -1 /*unordered_result < 0*/);
 9275   %}
 9276 
 9277   ins_pipe(pipe_class_default);
 9278 %}
 9279 
 9280 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL op1, iRegL op2)
 9281 %{
 9282   match(Set dst (CmpL3 op1 op2));
 9283 
 9284   ins_cost(ALU_COST * 3 + BRANCH_COST);
 9285   format %{ "slt   $dst, $op2, $op1\t#@cmpL3_reg_reg\n\t"
 9286             "bnez  $dst, done\n\t"
 9287             "slt   $dst, $op1, $op2\n\t"
 9288             "neg   $dst, $dst\n\t"
 9289             "done:"
 9290   %}
 9291   ins_encode %{
 9292     __ cmp_l2i(t0, as_Register($op1$$reg), as_Register($op2$$reg));
 9293     __ mv(as_Register($dst$$reg), t0);
 9294   %}
 9295 
 9296   ins_pipe(pipe_class_default);
 9297 %}
 9298 
 9299 instruct cmpUL3_reg_reg(iRegINoSp dst, iRegL op1, iRegL op2)
 9300 %{
 9301   match(Set dst (CmpUL3 op1 op2));
 9302 
 9303   ins_cost(ALU_COST * 3 + BRANCH_COST);
 9304   format %{ "sltu  $dst, $op2, $op1\t#@cmpUL3_reg_reg\n\t"
 9305             "bnez  $dst, done\n\t"
 9306             "sltu  $dst, $op1, $op2\n\t"
 9307             "neg   $dst, $dst\n\t"
 9308             "done:"
 9309   %}
 9310   ins_encode %{
 9311     __ cmp_ul2i(t0, as_Register($op1$$reg), as_Register($op2$$reg));
 9312     __ mv(as_Register($dst$$reg), t0);
 9313   %}
 9314 
 9315   ins_pipe(pipe_class_default);
 9316 %}
 9317 
 9318 instruct cmpU3_reg_reg(iRegINoSp dst, iRegI op1, iRegI op2)
 9319 %{
 9320   match(Set dst (CmpU3 op1 op2));
 9321 
 9322   ins_cost(ALU_COST * 3 + BRANCH_COST);
 9323   format %{ "sltu  $dst, $op2, $op1\t#@cmpU3_reg_reg\n\t"
 9324             "bnez  $dst, done\n\t"
 9325             "sltu  $dst, $op1, $op2\n\t"
 9326             "neg   $dst, $dst\n\t"
 9327             "done:"
 9328   %}
 9329   ins_encode %{
 9330     __ cmp_uw2i(t0, as_Register($op1$$reg), as_Register($op2$$reg));
 9331     __ mv(as_Register($dst$$reg), t0);
 9332   %}
 9333 
 9334   ins_pipe(pipe_class_default);
 9335 %}
 9336 
 9337 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegI p, iRegI q)
 9338 %{
 9339   match(Set dst (CmpLTMask p q));
 9340 
 9341   ins_cost(2 * ALU_COST);
 9342 
 9343   format %{ "slt $dst, $p, $q\t#@cmpLTMask_reg_reg\n\t"
 9344             "subw $dst, zr, $dst\t#@cmpLTMask_reg_reg"
 9345   %}
 9346 
 9347   ins_encode %{
 9348     __ slt(as_Register($dst$$reg), as_Register($p$$reg), as_Register($q$$reg));
 9349     __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg));
 9350   %}
 9351 
 9352   ins_pipe(ialu_reg_reg);
 9353 %}
 9354 
 9355 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I op, immI0 zero)
 9356 %{
 9357   match(Set dst (CmpLTMask op zero));
 9358 
 9359   ins_cost(ALU_COST);
 9360 
 9361   format %{ "sraiw $dst, $dst, 31\t#@cmpLTMask_reg_reg" %}
 9362 
 9363   ins_encode %{
 9364     __ sraiw(as_Register($dst$$reg), as_Register($op$$reg), 31);
 9365   %}
 9366 
 9367   ins_pipe(ialu_reg_shift);
 9368 %}
 9369 
 9370 
 9371 // ============================================================================
 9372 // Max and Min
 9373 
 9374 instruct minI_reg_reg(iRegINoSp dst, iRegI src)
 9375 %{
 9376   match(Set dst (MinI dst src));
 9377 
 9378   ins_cost(BRANCH_COST + ALU_COST);
 9379   format %{"minI_reg_reg $dst, $dst, $src\t#@minI_reg_reg\n\t"%}
 9380 
 9381   ins_encode %{
 9382     __ cmov_gt(as_Register($dst$$reg), as_Register($src$$reg),
 9383                as_Register($dst$$reg), as_Register($src$$reg));
 9384   %}
 9385 
 9386   ins_pipe(pipe_class_compare);
 9387 %}
 9388 
 9389 instruct maxI_reg_reg(iRegINoSp dst, iRegI src)
 9390 %{
 9391   match(Set dst (MaxI dst src));
 9392 
 9393   ins_cost(BRANCH_COST + ALU_COST);
 9394   format %{"maxI_reg_reg $dst, $dst, $src\t#@maxI_reg_reg\n\t"%}
 9395 
 9396   ins_encode %{
 9397     __ cmov_lt(as_Register($dst$$reg), as_Register($src$$reg),
 9398                as_Register($dst$$reg), as_Register($src$$reg));
 9399   %}
 9400 
 9401   ins_pipe(pipe_class_compare);
 9402 %}
 9403 
 9404 // special case for comparing with zero
 9405 // n.b. this is selected in preference to the rule above because it
 9406 // avoids loading constant 0 into a source register
 9407 
 9408 instruct minI_reg_zero(iRegINoSp dst, immI0 zero)
 9409 %{
 9410   match(Set dst (MinI dst zero));
 9411   match(Set dst (MinI zero dst));
 9412 
 9413   ins_cost(BRANCH_COST + ALU_COST);
 9414   format %{"minI_reg_zero $dst, $dst, zr\t#@minI_reg_zero\n\t"%}
 9415 
 9416   ins_encode %{
 9417     __ cmov_gt(as_Register($dst$$reg), zr,
 9418                as_Register($dst$$reg), zr);
 9419   %}
 9420 
 9421   ins_pipe(pipe_class_compare);
 9422 %}
 9423 
 9424 instruct maxI_reg_zero(iRegINoSp dst, immI0 zero)
 9425 %{
 9426   match(Set dst (MaxI dst zero));
 9427   match(Set dst (MaxI zero dst));
 9428 
 9429   ins_cost(BRANCH_COST + ALU_COST);
 9430   format %{"maxI_reg_zero $dst, $dst, zr\t#@maxI_reg_zero\n\t"%}
 9431 
 9432   ins_encode %{
 9433     __ cmov_lt(as_Register($dst$$reg), zr,
 9434                as_Register($dst$$reg), zr);
 9435   %}
 9436 
 9437   ins_pipe(pipe_class_compare);
 9438 %}
 9439 
 9440 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2)
 9441 %{
 9442   match(Set dst (MinI src1 src2));
 9443 
 9444   effect(DEF dst, USE src1, USE src2);
 9445 
 9446   ins_cost(BRANCH_COST + ALU_COST * 2);
 9447   format %{"minI_rReg $dst, $src1, $src2\t#@minI_rReg\n\t"%}
 9448 
 9449   ins_encode %{
 9450     __ mv(as_Register($dst$$reg), as_Register($src1$$reg));
 9451     __ cmov_gt(as_Register($src1$$reg), as_Register($src2$$reg),
 9452                as_Register($dst$$reg), as_Register($src2$$reg));
 9453   %}
 9454 
 9455   ins_pipe(pipe_class_compare);
 9456 %}
 9457 
 9458 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2)
 9459 %{
 9460   match(Set dst (MaxI src1 src2));
 9461 
 9462   effect(DEF dst, USE src1, USE src2);
 9463 
 9464   ins_cost(BRANCH_COST + ALU_COST * 2);
 9465   format %{"maxI_rReg $dst, $src1, $src2\t#@maxI_rReg\n\t"%}
 9466 
 9467   ins_encode %{
 9468     __ mv(as_Register($dst$$reg), as_Register($src1$$reg));
 9469     __ cmov_lt(as_Register($src1$$reg), as_Register($src2$$reg),
 9470                as_Register($dst$$reg), as_Register($src2$$reg));
 9471   %}
 9472 
 9473   ins_pipe(pipe_class_compare);
 9474 %}
 9475 
 9476 // ============================================================================
 9477 // Branch Instructions
 9478 // Direct Branch.
 9479 instruct branch(label lbl)
 9480 %{
 9481   match(Goto);
 9482 
 9483   effect(USE lbl);
 9484 
 9485   ins_cost(BRANCH_COST);
 9486   format %{ "j  $lbl\t#@branch" %}
 9487 
 9488   ins_encode(riscv_enc_j(lbl));
 9489 
 9490   ins_pipe(pipe_branch);
 9491 %}
 9492 
 9493 // ============================================================================
 9494 // Compare and Branch Instructions
 9495 
 9496 // Patterns for short (< 12KiB) variants
 9497 
 9498 // Compare flags and branch near instructions.
 9499 instruct cmpFlag_branch(cmpOpEqNe cmp, rFlagsReg cr, label lbl) %{
 9500   match(If cmp cr);
 9501   effect(USE lbl);
 9502 
 9503   ins_cost(BRANCH_COST);
 9504   format %{ "b$cmp  $cr, zr, $lbl\t#@cmpFlag_branch" %}
 9505 
 9506   ins_encode %{
 9507     __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($cr$$reg), *($lbl$$label));
 9508   %}
 9509   ins_pipe(pipe_cmpz_branch);
 9510   ins_short_branch(1);
 9511 %}
 9512 
 9513 // Compare signed int and branch near instructions
 9514 instruct cmpI_branch(cmpOp cmp, iRegI op1, iRegI op2, label lbl)
 9515 %{
 9516   // Same match rule as `far_cmpI_branch'.
 9517   match(If cmp (CmpI op1 op2));
 9518 
 9519   effect(USE lbl);
 9520 
 9521   ins_cost(BRANCH_COST);
 9522 
 9523   format %{ "b$cmp  $op1, $op2, $lbl\t#@cmpI_branch" %}
 9524 
 9525   ins_encode %{
 9526     __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label));
 9527   %}
 9528 
 9529   ins_pipe(pipe_cmp_branch);
 9530   ins_short_branch(1);
 9531 %}
 9532 
 9533 instruct cmpI_loop(cmpOp cmp, iRegI op1, iRegI op2, label lbl)
 9534 %{
 9535   // Same match rule as `far_cmpI_loop'.
 9536   match(CountedLoopEnd cmp (CmpI op1 op2));
 9537 
 9538   effect(USE lbl);
 9539 
 9540   ins_cost(BRANCH_COST);
 9541 
 9542   format %{ "b$cmp  $op1, $op2, $lbl\t#@cmpI_loop" %}
 9543 
 9544   ins_encode %{
 9545     __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label));
 9546   %}
 9547 
 9548   ins_pipe(pipe_cmp_branch);
 9549   ins_short_branch(1);
 9550 %}
 9551 
 9552 // Compare unsigned int and branch near instructions
 9553 instruct cmpU_branch(cmpOpU cmp, iRegI op1, iRegI op2, label lbl)
 9554 %{
 9555   // Same match rule as `far_cmpU_branch'.
 9556   match(If cmp (CmpU op1 op2));
 9557 
 9558   effect(USE lbl);
 9559 
 9560   ins_cost(BRANCH_COST);
 9561 
 9562   format %{ "b$cmp  $op1, $op2, $lbl\t#@cmpU_branch" %}
 9563 
 9564   ins_encode %{
 9565     __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg),
 9566                   as_Register($op2$$reg), *($lbl$$label));
 9567   %}
 9568 
 9569   ins_pipe(pipe_cmp_branch);
 9570   ins_short_branch(1);
 9571 %}
 9572 
 9573 // Compare signed long and branch near instructions
 9574 instruct cmpL_branch(cmpOp cmp, iRegL op1, iRegL op2, label lbl)
 9575 %{
 9576   // Same match rule as `far_cmpL_branch'.
 9577   match(If cmp (CmpL op1 op2));
 9578 
 9579   effect(USE lbl);
 9580 
 9581   ins_cost(BRANCH_COST);
 9582 
 9583   format %{ "b$cmp  $op1, $op2, $lbl\t#@cmpL_branch" %}
 9584 
 9585   ins_encode %{
 9586     __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label));
 9587   %}
 9588 
 9589   ins_pipe(pipe_cmp_branch);
 9590   ins_short_branch(1);
 9591 %}
 9592 
 9593 instruct cmpL_loop(cmpOp cmp, iRegL op1, iRegL op2, label lbl)
 9594 %{
 9595   // Same match rule as `far_cmpL_loop'.
 9596   match(CountedLoopEnd cmp (CmpL op1 op2));
 9597 
 9598   effect(USE lbl);
 9599 
 9600   ins_cost(BRANCH_COST);
 9601 
 9602   format %{ "b$cmp  $op1, $op2, $lbl\t#@cmpL_loop" %}
 9603 
 9604   ins_encode %{
 9605     __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label));
 9606   %}
 9607 
 9608   ins_pipe(pipe_cmp_branch);
 9609   ins_short_branch(1);
 9610 %}
 9611 
 9612 // Compare unsigned long and branch near instructions
 9613 instruct cmpUL_branch(cmpOpU cmp, iRegL op1, iRegL op2, label lbl)
 9614 %{
 9615   // Same match rule as `far_cmpUL_branch'.
 9616   match(If cmp (CmpUL op1 op2));
 9617 
 9618   effect(USE lbl);
 9619 
 9620   ins_cost(BRANCH_COST);
 9621   format %{ "b$cmp  $op1, $op2, $lbl\t#@cmpUL_branch" %}
 9622 
 9623   ins_encode %{
 9624     __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg),
 9625                   as_Register($op2$$reg), *($lbl$$label));
 9626   %}
 9627 
 9628   ins_pipe(pipe_cmp_branch);
 9629   ins_short_branch(1);
 9630 %}
 9631 
 9632 // Compare pointer and branch near instructions
 9633 instruct cmpP_branch(cmpOpU cmp, iRegP op1, iRegP op2, label lbl)
 9634 %{
 9635   // Same match rule as `far_cmpP_branch'.
 9636   match(If cmp (CmpP op1 op2));
 9637 
 9638   effect(USE lbl);
 9639 
 9640   ins_cost(BRANCH_COST);
 9641 
 9642   format %{ "b$cmp  $op1, $op2, $lbl\t#@cmpP_branch" %}
 9643 
 9644   ins_encode %{
 9645     __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg),
 9646                   as_Register($op2$$reg), *($lbl$$label));
 9647   %}
 9648 
 9649   ins_pipe(pipe_cmp_branch);
 9650   ins_short_branch(1);
 9651 %}
 9652 
 9653 // Compare narrow pointer and branch near instructions
 9654 instruct cmpN_branch(cmpOpU cmp, iRegN op1, iRegN op2, label lbl)
 9655 %{
 9656   // Same match rule as `far_cmpN_branch'.
 9657   match(If cmp (CmpN op1 op2));
 9658 
 9659   effect(USE lbl);
 9660 
 9661   ins_cost(BRANCH_COST);
 9662 
 9663   format %{ "b$cmp  $op1, $op2, $lbl\t#@cmpN_branch" %}
 9664 
 9665   ins_encode %{
 9666     __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg),
 9667                   as_Register($op2$$reg), *($lbl$$label));
 9668   %}
 9669 
 9670   ins_pipe(pipe_cmp_branch);
 9671   ins_short_branch(1);
 9672 %}
 9673 
 9674 // Compare float and branch near instructions
 9675 instruct cmpF_branch(cmpOp cmp, fRegF op1, fRegF op2, label lbl)
 9676 %{
 9677   // Same match rule as `far_cmpF_branch'.
 9678   match(If cmp (CmpF op1 op2));
 9679 
 9680   effect(USE lbl);
 9681 
 9682   ins_cost(XFER_COST + BRANCH_COST);
 9683   format %{ "float_b$cmp $op1, $op2, $lbl \t#@cmpF_branch"%}
 9684 
 9685   ins_encode %{
 9686     __ float_cmp_branch($cmp$$cmpcode, as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg), *($lbl$$label));
 9687   %}
 9688 
 9689   ins_pipe(pipe_class_compare);
 9690   ins_short_branch(1);
 9691 %}
 9692 
 9693 // Compare double and branch near instructions
 9694 instruct cmpD_branch(cmpOp cmp, fRegD op1, fRegD op2, label lbl)
 9695 %{
 9696   // Same match rule as `far_cmpD_branch'.
 9697   match(If cmp (CmpD op1 op2));
 9698   effect(USE lbl);
 9699 
 9700   ins_cost(XFER_COST + BRANCH_COST);
 9701   format %{ "double_b$cmp $op1, $op2, $lbl\t#@cmpD_branch"%}
 9702 
 9703   ins_encode %{
 9704     __ float_cmp_branch($cmp$$cmpcode | C2_MacroAssembler::double_branch_mask, as_FloatRegister($op1$$reg),
 9705                         as_FloatRegister($op2$$reg), *($lbl$$label));
 9706   %}
 9707 
 9708   ins_pipe(pipe_class_compare);
 9709   ins_short_branch(1);
 9710 %}
 9711 
 9712 // Compare signed int with zero and branch near instructions
 9713 instruct cmpI_reg_imm0_branch(cmpOp cmp, iRegI op1, immI0 zero, label lbl)
 9714 %{
 9715   // Same match rule as `far_cmpI_reg_imm0_branch'.
 9716   match(If cmp (CmpI op1 zero));
 9717 
 9718   effect(USE op1, USE lbl);
 9719 
 9720   ins_cost(BRANCH_COST);
 9721   format %{ "b$cmp  $op1, zr, $lbl\t#@cmpI_reg_imm0_branch" %}
 9722 
 9723   ins_encode %{
 9724     __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label));
 9725   %}
 9726 
 9727   ins_pipe(pipe_cmpz_branch);
 9728   ins_short_branch(1);
 9729 %}
 9730 
 9731 instruct cmpI_reg_imm0_loop(cmpOp cmp, iRegI op1, immI0 zero, label lbl)
 9732 %{
 9733   // Same match rule as `far_cmpI_reg_imm0_loop'.
 9734   match(CountedLoopEnd cmp (CmpI op1 zero));
 9735 
 9736   effect(USE op1, USE lbl);
 9737 
 9738   ins_cost(BRANCH_COST);
 9739 
 9740   format %{ "b$cmp  $op1, zr, $lbl\t#@cmpI_reg_imm0_loop" %}
 9741 
 9742   ins_encode %{
 9743     __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label));
 9744   %}
 9745 
 9746   ins_pipe(pipe_cmpz_branch);
 9747   ins_short_branch(1);
 9748 %}
 9749 
 9750 // Compare unsigned int with zero and branch near instructions
 9751 instruct cmpUEqNeLeGt_reg_imm0_branch(cmpOpUEqNeLeGt cmp, iRegI op1, immI0 zero, label lbl)
 9752 %{
 9753   // Same match rule as `far_cmpUEqNeLeGt_reg_imm0_branch'.
 9754   match(If cmp (CmpU op1 zero));
 9755 
 9756   effect(USE op1, USE lbl);
 9757 
 9758   ins_cost(BRANCH_COST);
 9759 
 9760   format %{ "b$cmp  $op1, zr, $lbl\t#@cmpUEqNeLeGt_reg_imm0_branch" %}
 9761 
 9762   ins_encode %{
 9763     __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label));
 9764   %}
 9765 
 9766   ins_pipe(pipe_cmpz_branch);
 9767   ins_short_branch(1);
 9768 %}
 9769 
 9770 // Compare signed long with zero and branch near instructions
 9771 instruct cmpL_reg_imm0_branch(cmpOp cmp, iRegL op1, immL0 zero, label lbl)
 9772 %{
 9773   // Same match rule as `far_cmpL_reg_imm0_branch'.
 9774   match(If cmp (CmpL op1 zero));
 9775 
 9776   effect(USE op1, USE lbl);
 9777 
 9778   ins_cost(BRANCH_COST);
 9779 
 9780   format %{ "b$cmp  $op1, zr, $lbl\t#@cmpL_reg_imm0_branch" %}
 9781 
 9782   ins_encode %{
 9783     __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label));
 9784   %}
 9785 
 9786   ins_pipe(pipe_cmpz_branch);
 9787   ins_short_branch(1);
 9788 %}
 9789 
 9790 instruct cmpL_reg_imm0_loop(cmpOp cmp, iRegL op1, immL0 zero, label lbl)
 9791 %{
 9792   // Same match rule as `far_cmpL_reg_imm0_loop'.
 9793   match(CountedLoopEnd cmp (CmpL op1 zero));
 9794 
 9795   effect(USE op1, USE lbl);
 9796 
 9797   ins_cost(BRANCH_COST);
 9798 
 9799   format %{ "b$cmp  $op1, zr, $lbl\t#@cmpL_reg_imm0_loop" %}
 9800 
 9801   ins_encode %{
 9802     __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label));
 9803   %}
 9804 
 9805   ins_pipe(pipe_cmpz_branch);
 9806   ins_short_branch(1);
 9807 %}
 9808 
 9809 // Compare unsigned long with zero and branch near instructions
 9810 instruct cmpULEqNeLeGt_reg_imm0_branch(cmpOpUEqNeLeGt cmp, iRegL op1, immL0 zero, label lbl)
 9811 %{
 9812   // Same match rule as `far_cmpULEqNeLeGt_reg_imm0_branch'.
 9813   match(If cmp (CmpUL op1 zero));
 9814 
 9815   effect(USE op1, USE lbl);
 9816 
 9817   ins_cost(BRANCH_COST);
 9818 
 9819   format %{ "b$cmp  $op1, zr, $lbl\t#@cmpULEqNeLeGt_reg_imm0_branch" %}
 9820 
 9821   ins_encode %{
 9822     __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label));
 9823   %}
 9824 
 9825   ins_pipe(pipe_cmpz_branch);
 9826   ins_short_branch(1);
 9827 %}
 9828 
 9829 // Compare pointer with zero and branch near instructions
 9830 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 zero, label lbl) %{
 9831   // Same match rule as `far_cmpP_reg_imm0_branch'.
 9832   match(If cmp (CmpP op1 zero));
 9833   effect(USE lbl);
 9834 
 9835   ins_cost(BRANCH_COST);
 9836   format %{ "b$cmp   $op1, zr, $lbl\t#@cmpP_imm0_branch" %}
 9837 
 9838   ins_encode %{
 9839     __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label));
 9840   %}
 9841 
 9842   ins_pipe(pipe_cmpz_branch);
 9843   ins_short_branch(1);
 9844 %}
 9845 
 9846 // Compare narrow pointer with zero and branch near instructions
 9847 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 zero, label lbl) %{
 9848   // Same match rule as `far_cmpN_reg_imm0_branch'.
 9849   match(If cmp (CmpN op1 zero));
 9850   effect(USE lbl);
 9851 
 9852   ins_cost(BRANCH_COST);
 9853 
 9854   format %{ "b$cmp  $op1, zr, $lbl\t#@cmpN_imm0_branch" %}
 9855 
 9856   ins_encode %{
 9857     __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label));
 9858   %}
 9859 
 9860   ins_pipe(pipe_cmpz_branch);
 9861   ins_short_branch(1);
 9862 %}
 9863 
 9864 // Compare narrow pointer with pointer zero and branch near instructions
 9865 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN op1, immP0 zero, label lbl) %{
 9866   // Same match rule as `far_cmpP_narrowOop_imm0_branch'.
 9867   match(If cmp (CmpP (DecodeN op1) zero));
 9868   effect(USE lbl);
 9869 
 9870   ins_cost(BRANCH_COST);
 9871   format %{ "b$cmp   $op1, zr, $lbl\t#@cmpP_narrowOop_imm0_branch" %}
 9872 
 9873   ins_encode %{
 9874     __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label));
 9875   %}
 9876 
 9877   ins_pipe(pipe_cmpz_branch);
 9878   ins_short_branch(1);
 9879 %}
 9880 
 9881 // Patterns for far (20KiB) variants
 9882 
 9883 instruct far_cmpFlag_branch(cmpOp cmp, rFlagsReg cr, label lbl) %{
 9884   match(If cmp cr);
 9885   effect(USE lbl);
 9886 
 9887   ins_cost(BRANCH_COST);
 9888   format %{ "far_b$cmp $cr, zr, $lbl\t#@far_cmpFlag_branch"%}
 9889 
 9890   ins_encode %{
 9891     __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($cr$$reg), *($lbl$$label), /* is_far */ true);
 9892   %}
 9893 
 9894   ins_pipe(pipe_cmpz_branch);
 9895 %}
 9896 
 9897 // Compare signed int and branch far instructions
 9898 instruct far_cmpI_branch(cmpOp cmp, iRegI op1, iRegI op2, label lbl) %{
 9899   match(If cmp (CmpI op1 op2));
 9900   effect(USE lbl);
 9901 
 9902   ins_cost(BRANCH_COST * 2);
 9903 
 9904   // the format instruction [far_b$cmp] here is be used as two insructions
 9905   // in macroassembler: b$not_cmp(op1, op2, done), j($lbl), bind(done)
 9906   format %{ "far_b$cmp  $op1, $op2, $lbl\t#@far_cmpI_branch" %}
 9907 
 9908   ins_encode %{
 9909     __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label), /* is_far */ true);
 9910   %}
 9911 
 9912   ins_pipe(pipe_cmp_branch);
 9913 %}
 9914 
 9915 instruct far_cmpI_loop(cmpOp cmp, iRegI op1, iRegI op2, label lbl) %{
 9916   match(CountedLoopEnd cmp (CmpI op1 op2));
 9917   effect(USE lbl);
 9918 
 9919   ins_cost(BRANCH_COST * 2);
 9920   format %{ "far_b$cmp  $op1, $op2, $lbl\t#@far_cmpI_loop" %}
 9921 
 9922   ins_encode %{
 9923     __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label), /* is_far */ true);
 9924   %}
 9925 
 9926   ins_pipe(pipe_cmp_branch);
 9927 %}
 9928 
 9929 instruct far_cmpU_branch(cmpOpU cmp, iRegI op1, iRegI op2, label lbl) %{
 9930   match(If cmp (CmpU op1 op2));
 9931   effect(USE lbl);
 9932 
 9933   ins_cost(BRANCH_COST * 2);
 9934   format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpU_branch" %}
 9935 
 9936   ins_encode %{
 9937     __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg),
 9938                        as_Register($op2$$reg), *($lbl$$label), /* is_far */ true);
 9939   %}
 9940 
 9941   ins_pipe(pipe_cmp_branch);
 9942 %}
 9943 
 9944 instruct far_cmpL_branch(cmpOp cmp, iRegL op1, iRegL op2, label lbl) %{
 9945   match(If cmp (CmpL op1 op2));
 9946   effect(USE lbl);
 9947 
 9948   ins_cost(BRANCH_COST * 2);
 9949   format %{ "far_b$cmp  $op1, $op2, $lbl\t#@far_cmpL_branch" %}
 9950 
 9951   ins_encode %{
 9952     __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label), /* is_far */ true);
 9953   %}
 9954 
 9955   ins_pipe(pipe_cmp_branch);
 9956 %}
 9957 
 9958 instruct far_cmpLloop(cmpOp cmp, iRegL op1, iRegL op2, label lbl) %{
 9959   match(CountedLoopEnd cmp (CmpL op1 op2));
 9960   effect(USE lbl);
 9961 
 9962   ins_cost(BRANCH_COST * 2);
 9963   format %{ "far_b$cmp  $op1, $op2, $lbl\t#@far_cmpL_loop" %}
 9964 
 9965   ins_encode %{
 9966     __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label), /* is_far */ true);
 9967   %}
 9968 
 9969   ins_pipe(pipe_cmp_branch);
 9970 %}
 9971 
 9972 instruct far_cmpUL_branch(cmpOpU cmp, iRegL op1, iRegL op2, label lbl) %{
 9973   match(If cmp (CmpUL op1 op2));
 9974   effect(USE lbl);
 9975 
 9976   ins_cost(BRANCH_COST * 2);
 9977   format %{ "far_b$cmp  $op1, $op2, $lbl\t#@far_cmpUL_branch" %}
 9978 
 9979   ins_encode %{
 9980     __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg),
 9981                        as_Register($op2$$reg), *($lbl$$label), /* is_far */ true);
 9982   %}
 9983 
 9984   ins_pipe(pipe_cmp_branch);
 9985 %}
 9986 
 9987 instruct far_cmpP_branch(cmpOpU cmp, iRegP op1, iRegP op2, label lbl)
 9988 %{
 9989   match(If cmp (CmpP op1 op2));
 9990 
 9991   effect(USE lbl);
 9992 
 9993   ins_cost(BRANCH_COST * 2);
 9994 
 9995   format %{ "far_b$cmp  $op1, $op2, $lbl\t#@far_cmpP_branch" %}
 9996 
 9997   ins_encode %{
 9998     __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg),
 9999                        as_Register($op2$$reg), *($lbl$$label), /* is_far */ true);
10000   %}
10001 
10002   ins_pipe(pipe_cmp_branch);
10003 %}
10004 
10005 instruct far_cmpN_branch(cmpOpU cmp, iRegN op1, iRegN op2, label lbl)
10006 %{
10007   match(If cmp (CmpN op1 op2));
10008 
10009   effect(USE lbl);
10010 
10011   ins_cost(BRANCH_COST * 2);
10012 
10013   format %{ "far_b$cmp  $op1, $op2, $lbl\t#@far_cmpN_branch" %}
10014 
10015   ins_encode %{
10016     __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg),
10017                        as_Register($op2$$reg), *($lbl$$label), /* is_far */ true);
10018   %}
10019 
10020   ins_pipe(pipe_cmp_branch);
10021 %}
10022 
10023 // Float compare and branch instructions
10024 instruct far_cmpF_branch(cmpOp cmp, fRegF op1, fRegF op2, label lbl)
10025 %{
10026   match(If cmp (CmpF op1 op2));
10027 
10028   effect(USE lbl);
10029 
10030   ins_cost(XFER_COST + BRANCH_COST * 2);
10031   format %{ "far_float_b$cmp $op1, $op2, $lbl\t#@far_cmpF_branch"%}
10032 
10033   ins_encode %{
10034     __ float_cmp_branch($cmp$$cmpcode, as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
10035                         *($lbl$$label), /* is_far */ true);
10036   %}
10037 
10038   ins_pipe(pipe_class_compare);
10039 %}
10040 
10041 // Double compare and branch instructions
10042 instruct far_cmpD_branch(cmpOp cmp, fRegD op1, fRegD op2, label lbl)
10043 %{
10044   match(If cmp (CmpD op1 op2));
10045   effect(USE lbl);
10046 
10047   ins_cost(XFER_COST + BRANCH_COST * 2);
10048   format %{ "far_double_b$cmp $op1, $op2, $lbl\t#@far_cmpD_branch"%}
10049 
10050   ins_encode %{
10051     __ float_cmp_branch($cmp$$cmpcode | C2_MacroAssembler::double_branch_mask, as_FloatRegister($op1$$reg),
10052                         as_FloatRegister($op2$$reg), *($lbl$$label), /* is_far */ true);
10053   %}
10054 
10055   ins_pipe(pipe_class_compare);
10056 %}
10057 
10058 instruct far_cmpI_reg_imm0_branch(cmpOp cmp, iRegI op1, immI0 zero, label lbl)
10059 %{
10060   match(If cmp (CmpI op1 zero));
10061 
10062   effect(USE op1, USE lbl);
10063 
10064   ins_cost(BRANCH_COST * 2);
10065 
10066   format %{ "far_b$cmp  $op1, zr, $lbl\t#@far_cmpI_reg_imm0_branch" %}
10067 
10068   ins_encode %{
10069     __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label), /* is_far */ true);
10070   %}
10071 
10072   ins_pipe(pipe_cmpz_branch);
10073 %}
10074 
10075 instruct far_cmpI_reg_imm0_loop(cmpOp cmp, iRegI op1, immI0 zero, label lbl)
10076 %{
10077   match(CountedLoopEnd cmp (CmpI op1 zero));
10078 
10079   effect(USE op1, USE lbl);
10080 
10081   ins_cost(BRANCH_COST * 2);
10082 
10083   format %{ "far_b$cmp  $op1, zr, $lbl\t#@far_cmpI_reg_imm0_loop" %}
10084 
10085   ins_encode %{
10086     __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label), /* is_far */ true);
10087   %}
10088 
10089   ins_pipe(pipe_cmpz_branch);
10090 %}
10091 
10092 instruct far_cmpUEqNeLeGt_imm0_branch(cmpOpUEqNeLeGt cmp, iRegI op1, immI0 zero, label lbl)
10093 %{
10094   match(If cmp (CmpU op1 zero));
10095 
10096   effect(USE op1, USE lbl);
10097 
10098   ins_cost(BRANCH_COST * 2);
10099 
10100   format %{ "far_b$cmp  $op1, zr, $lbl\t#@far_cmpUEqNeLeGt_imm0_branch" %}
10101 
10102   ins_encode %{
10103     __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true);
10104   %}
10105 
10106   ins_pipe(pipe_cmpz_branch);
10107 %}
10108 
10109 // compare lt/ge unsigned instructs has no short instruct with same match
10110 instruct far_cmpULtGe_reg_imm0_branch(cmpOpULtGe cmp, iRegI op1, immI0 zero, label lbl)
10111 %{
10112   match(If cmp (CmpU op1 zero));
10113 
10114   effect(USE op1, USE lbl);
10115 
10116   ins_cost(BRANCH_COST);
10117 
10118   format %{ "j  $lbl if $cmp == ge\t#@far_cmpULtGe_reg_imm0_branch" %}
10119 
10120   ins_encode(riscv_enc_far_cmpULtGe_imm0_branch(cmp, op1, lbl));
10121 
10122   ins_pipe(pipe_cmpz_branch);
10123 %}
10124 
10125 instruct far_cmpL_reg_imm0_branch(cmpOp cmp, iRegL op1, immL0 zero, label lbl)
10126 %{
10127   match(If cmp (CmpL op1 zero));
10128 
10129   effect(USE op1, USE lbl);
10130 
10131   ins_cost(BRANCH_COST * 2);
10132 
10133   format %{ "far_b$cmp  $op1, zr, $lbl\t#@far_cmpL_reg_imm0_branch" %}
10134 
10135   ins_encode %{
10136     __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label), /* is_far */ true);
10137   %}
10138 
10139   ins_pipe(pipe_cmpz_branch);
10140 %}
10141 
10142 instruct far_cmpL_reg_imm0_loop(cmpOp cmp, iRegL op1, immL0 zero, label lbl)
10143 %{
10144   match(CountedLoopEnd cmp (CmpL op1 zero));
10145 
10146   effect(USE op1, USE lbl);
10147 
10148   ins_cost(BRANCH_COST * 2);
10149 
10150   format %{ "far_b$cmp  $op1, zr, $lbl\t#@far_cmpL_reg_imm0_loop" %}
10151 
10152   ins_encode %{
10153     __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label), /* is_far */ true);
10154   %}
10155 
10156   ins_pipe(pipe_cmpz_branch);
10157 %}
10158 
10159 instruct far_cmpULEqNeLeGt_reg_imm0_branch(cmpOpUEqNeLeGt cmp, iRegL op1, immL0 zero, label lbl)
10160 %{
10161   match(If cmp (CmpUL op1 zero));
10162 
10163   effect(USE op1, USE lbl);
10164 
10165   ins_cost(BRANCH_COST * 2);
10166 
10167   format %{ "far_b$cmp  $op1, zr, $lbl\t#@far_cmpULEqNeLeGt_reg_imm0_branch" %}
10168 
10169   ins_encode %{
10170     __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true);
10171   %}
10172 
10173   ins_pipe(pipe_cmpz_branch);
10174 %}
10175 
10176 // compare lt/ge unsigned instructs has no short instruct with same match
10177 instruct far_cmpULLtGe_reg_imm0_branch(cmpOpULtGe cmp, iRegL op1, immL0 zero, label lbl)
10178 %{
10179   match(If cmp (CmpUL op1 zero));
10180 
10181   effect(USE op1, USE lbl);
10182 
10183   ins_cost(BRANCH_COST);
10184 
10185   format %{ "j  $lbl if $cmp == ge\t#@far_cmpULLtGe_reg_imm0_branch" %}
10186 
10187   ins_encode(riscv_enc_far_cmpULtGe_imm0_branch(cmp, op1, lbl));
10188 
10189   ins_pipe(pipe_cmpz_branch);
10190 %}
10191 
10192 instruct far_cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 zero, label lbl) %{
10193   match(If cmp (CmpP op1 zero));
10194   effect(USE lbl);
10195 
10196   ins_cost(BRANCH_COST * 2);
10197   format %{ "far_b$cmp   $op1, zr, $lbl\t#@far_cmpP_imm0_branch" %}
10198 
10199   ins_encode %{
10200     __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true);
10201   %}
10202 
10203   ins_pipe(pipe_cmpz_branch);
10204 %}
10205 
10206 instruct far_cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 zero, label lbl) %{
10207   match(If cmp (CmpN op1 zero));
10208   effect(USE lbl);
10209 
10210   ins_cost(BRANCH_COST * 2);
10211 
10212   format %{ "far_b$cmp  $op1, zr, $lbl\t#@far_cmpN_imm0_branch" %}
10213 
10214   ins_encode %{
10215     __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true);
10216   %}
10217 
10218   ins_pipe(pipe_cmpz_branch);
10219 %}
10220 
10221 instruct far_cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN op1, immP0 zero, label lbl) %{
10222   match(If cmp (CmpP (DecodeN op1) zero));
10223   effect(USE lbl);
10224 
10225   ins_cost(BRANCH_COST * 2);
10226   format %{ "far_b$cmp   $op1, zr, $lbl\t#@far_cmpP_narrowOop_imm0_branch" %}
10227 
10228   ins_encode %{
10229     __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true);
10230   %}
10231 
10232   ins_pipe(pipe_cmpz_branch);
10233 %}
10234 
10235 // ============================================================================
10236 // Conditional Move Instructions
10237 
10238 // --------- CMoveI ---------
10239 
10240 instruct cmovI_cmpI(iRegINoSp dst, iRegI src, iRegI op1, iRegI op2, cmpOp cop) %{
10241   match(Set dst (CMoveI (Binary cop (CmpI op1 op2)) (Binary dst src)));
10242   ins_cost(ALU_COST + BRANCH_COST);
10243 
10244   format %{
10245     "CMoveI $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpI\n\t"
10246   %}
10247 
10248   ins_encode %{
10249     __ enc_cmove($cop$$cmpcode,
10250                  as_Register($op1$$reg), as_Register($op2$$reg),
10251                  as_Register($dst$$reg), as_Register($src$$reg));
10252   %}
10253 
10254   ins_pipe(pipe_class_compare);
10255 %}
10256 
10257 instruct cmovI_cmpU(iRegINoSp dst, iRegI src, iRegI op1, iRegI op2, cmpOpU cop) %{
10258   match(Set dst (CMoveI (Binary cop (CmpU op1 op2)) (Binary dst src)));
10259   ins_cost(ALU_COST + BRANCH_COST);
10260 
10261   format %{
10262     "CMoveI $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpU\n\t"
10263   %}
10264 
10265   ins_encode %{
10266     __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
10267                  as_Register($op1$$reg), as_Register($op2$$reg),
10268                  as_Register($dst$$reg), as_Register($src$$reg));
10269   %}
10270 
10271   ins_pipe(pipe_class_compare);
10272 %}
10273 
10274 instruct cmovI_cmpL(iRegINoSp dst, iRegI src, iRegL op1, iRegL op2, cmpOp cop) %{
10275   match(Set dst (CMoveI (Binary cop (CmpL op1 op2)) (Binary dst src)));
10276   ins_cost(ALU_COST + BRANCH_COST);
10277 
10278   format %{
10279     "CMoveI $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpL\n\t"
10280   %}
10281 
10282   ins_encode %{
10283     __ enc_cmove($cop$$cmpcode,
10284                  as_Register($op1$$reg), as_Register($op2$$reg),
10285                  as_Register($dst$$reg), as_Register($src$$reg));
10286   %}
10287 
10288   ins_pipe(pipe_class_compare);
10289 %}
10290 
10291 instruct cmovI_cmpUL(iRegINoSp dst, iRegI src, iRegL op1, iRegL op2, cmpOpU cop) %{
10292   match(Set dst (CMoveI (Binary cop (CmpUL op1 op2)) (Binary dst src)));
10293   ins_cost(ALU_COST + BRANCH_COST);
10294 
10295   format %{
10296     "CMoveI $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpUL\n\t"
10297   %}
10298 
10299   ins_encode %{
10300     __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
10301                  as_Register($op1$$reg), as_Register($op2$$reg),
10302                  as_Register($dst$$reg), as_Register($src$$reg));
10303   %}
10304 
10305   ins_pipe(pipe_class_compare);
10306 %}
10307 
10308 instruct cmovI_cmpF(iRegINoSp dst, iRegI src, fRegF op1, fRegF op2, cmpOp cop) %{
10309   match(Set dst (CMoveI (Binary cop (CmpF op1 op2)) (Binary dst src)));
10310   ins_cost(ALU_COST + BRANCH_COST);
10311 
10312   format %{
10313     "CMoveI $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpF\n\t"
10314   %}
10315 
10316   ins_encode %{
10317     __ enc_cmove_cmp_fp($cop$$cmpcode,
10318                         as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
10319                         as_Register($dst$$reg), as_Register($src$$reg), true /* is_single */);
10320   %}
10321 
10322   ins_pipe(pipe_class_compare);
10323 %}
10324 
10325 instruct cmovI_cmpD(iRegINoSp dst, iRegI src, fRegD op1, fRegD op2, cmpOp cop) %{
10326   match(Set dst (CMoveI (Binary cop (CmpD op1 op2)) (Binary dst src)));
10327   ins_cost(ALU_COST + BRANCH_COST);
10328 
10329   format %{
10330     "CMoveI $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpD\n\t"
10331   %}
10332 
10333   ins_encode %{
10334     __ enc_cmove_cmp_fp($cop$$cmpcode | C2_MacroAssembler::double_branch_mask,
10335                         as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
10336                         as_Register($dst$$reg), as_Register($src$$reg), false /* is_single */);
10337   %}
10338 
10339   ins_pipe(pipe_class_compare);
10340 %}
10341 
10342 instruct cmovI_cmpN(iRegINoSp dst, iRegI src, iRegN op1, iRegN op2, cmpOpU cop) %{
10343   match(Set dst (CMoveI (Binary cop (CmpN op1 op2)) (Binary dst src)));
10344   ins_cost(ALU_COST + BRANCH_COST);
10345 
10346   format %{
10347     "CMoveI $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpN\n\t"
10348   %}
10349 
10350   ins_encode %{
10351     __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
10352                  as_Register($op1$$reg), as_Register($op2$$reg),
10353                  as_Register($dst$$reg), as_Register($src$$reg));
10354   %}
10355 
10356   ins_pipe(pipe_class_compare);
10357 %}
10358 
10359 instruct cmovI_cmpP(iRegINoSp dst, iRegI src, iRegP op1, iRegP op2, cmpOpU cop) %{
10360   match(Set dst (CMoveI (Binary cop (CmpP op1 op2)) (Binary dst src)));
10361   ins_cost(ALU_COST + BRANCH_COST);
10362 
10363   format %{
10364     "CMoveI $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpP\n\t"
10365   %}
10366 
10367   ins_encode %{
10368     __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
10369                  as_Register($op1$$reg), as_Register($op2$$reg),
10370                  as_Register($dst$$reg), as_Register($src$$reg));
10371   %}
10372 
10373   ins_pipe(pipe_class_compare);
10374 %}
10375 
10376 // --------- CMoveL ---------
10377 
10378 instruct cmovL_cmpL(iRegLNoSp dst, iRegL src, iRegL op1, iRegL op2, cmpOp cop) %{
10379   match(Set dst (CMoveL (Binary cop (CmpL op1 op2)) (Binary dst src)));
10380   ins_cost(ALU_COST + BRANCH_COST);
10381 
10382   format %{
10383     "CMoveL $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpL\n\t"
10384   %}
10385 
10386   ins_encode %{
10387     __ enc_cmove($cop$$cmpcode,
10388                  as_Register($op1$$reg), as_Register($op2$$reg),
10389                  as_Register($dst$$reg), as_Register($src$$reg));
10390   %}
10391 
10392   ins_pipe(pipe_class_compare);
10393 %}
10394 
10395 instruct cmovL_cmpUL(iRegLNoSp dst, iRegL src, iRegL op1, iRegL op2, cmpOpU cop) %{
10396   match(Set dst (CMoveL (Binary cop (CmpUL op1 op2)) (Binary dst src)));
10397   ins_cost(ALU_COST + BRANCH_COST);
10398 
10399   format %{
10400     "CMoveL $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpUL\n\t"
10401   %}
10402 
10403   ins_encode %{
10404     __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
10405                  as_Register($op1$$reg), as_Register($op2$$reg),
10406                  as_Register($dst$$reg), as_Register($src$$reg));
10407   %}
10408 
10409   ins_pipe(pipe_class_compare);
10410 %}
10411 
10412 instruct cmovL_cmpI(iRegLNoSp dst, iRegL src, iRegI op1, iRegI op2, cmpOp cop) %{
10413   match(Set dst (CMoveL (Binary cop (CmpI op1 op2)) (Binary dst src)));
10414   ins_cost(ALU_COST + BRANCH_COST);
10415 
10416   format %{
10417     "CMoveL $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpI\n\t"
10418   %}
10419 
10420   ins_encode %{
10421     __ enc_cmove($cop$$cmpcode,
10422                  as_Register($op1$$reg), as_Register($op2$$reg),
10423                  as_Register($dst$$reg), as_Register($src$$reg));
10424   %}
10425 
10426   ins_pipe(pipe_class_compare);
10427 %}
10428 
10429 instruct cmovL_cmpU(iRegLNoSp dst, iRegL src, iRegI op1, iRegI op2, cmpOpU cop) %{
10430   match(Set dst (CMoveL (Binary cop (CmpU op1 op2)) (Binary dst src)));
10431   ins_cost(ALU_COST + BRANCH_COST);
10432 
10433   format %{
10434     "CMoveL $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpU\n\t"
10435   %}
10436 
10437   ins_encode %{
10438     __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
10439                  as_Register($op1$$reg), as_Register($op2$$reg),
10440                  as_Register($dst$$reg), as_Register($src$$reg));
10441   %}
10442 
10443   ins_pipe(pipe_class_compare);
10444 %}
10445 
10446 instruct cmovL_cmpF(iRegLNoSp dst, iRegL src, fRegF op1, fRegF op2, cmpOp cop) %{
10447   match(Set dst (CMoveL (Binary cop (CmpF op1 op2)) (Binary dst src)));
10448   ins_cost(ALU_COST + BRANCH_COST);
10449 
10450   format %{
10451     "CMoveL $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpF\n\t"
10452   %}
10453 
10454   ins_encode %{
10455     __ enc_cmove_cmp_fp($cop$$cmpcode,
10456                         as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
10457                         as_Register($dst$$reg), as_Register($src$$reg), true /* is_single */);
10458   %}
10459 
10460   ins_pipe(pipe_class_compare);
10461 %}
10462 
10463 instruct cmovL_cmpD(iRegLNoSp dst, iRegL src, fRegD op1, fRegD op2, cmpOp cop) %{
10464   match(Set dst (CMoveL (Binary cop (CmpD op1 op2)) (Binary dst src)));
10465   ins_cost(ALU_COST + BRANCH_COST);
10466 
10467   format %{
10468     "CMoveL $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpD\n\t"
10469   %}
10470 
10471   ins_encode %{
10472     __ enc_cmove_cmp_fp($cop$$cmpcode | C2_MacroAssembler::double_branch_mask,
10473                         as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
10474                         as_Register($dst$$reg), as_Register($src$$reg), false /* is_single */);
10475   %}
10476 
10477   ins_pipe(pipe_class_compare);
10478 %}
10479 
10480 instruct cmovL_cmpN(iRegLNoSp dst, iRegL src, iRegN op1, iRegN op2, cmpOpU cop) %{
10481   match(Set dst (CMoveL (Binary cop (CmpN op1 op2)) (Binary dst src)));
10482   ins_cost(ALU_COST + BRANCH_COST);
10483 
10484   format %{
10485     "CMoveL $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpN\n\t"
10486   %}
10487 
10488   ins_encode %{
10489     __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
10490                  as_Register($op1$$reg), as_Register($op2$$reg),
10491                  as_Register($dst$$reg), as_Register($src$$reg));
10492   %}
10493 
10494   ins_pipe(pipe_class_compare);
10495 %}
10496 
10497 instruct cmovL_cmpP(iRegLNoSp dst, iRegL src, iRegP op1, iRegP op2, cmpOpU cop) %{
10498   match(Set dst (CMoveL (Binary cop (CmpP op1 op2)) (Binary dst src)));
10499   ins_cost(ALU_COST + BRANCH_COST);
10500 
10501   format %{
10502     "CMoveL $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpP\n\t"
10503   %}
10504 
10505   ins_encode %{
10506     __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
10507                  as_Register($op1$$reg), as_Register($op2$$reg),
10508                  as_Register($dst$$reg), as_Register($src$$reg));
10509   %}
10510 
10511   ins_pipe(pipe_class_compare);
10512 %}
10513 
10514 // --------- CMoveF ---------
10515 
10516 instruct cmovF_cmpI(fRegF dst, fRegF src, iRegI op1, iRegI op2, cmpOp cop) %{
10517   match(Set dst (CMoveF (Binary cop (CmpI op1 op2)) (Binary dst src)));
10518   ins_cost(ALU_COST + BRANCH_COST);
10519 
10520   format %{
10521     "CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpI\n\t"
10522   %}
10523 
10524   ins_encode %{
10525     __ enc_cmove_fp_cmp($cop$$cmpcode,
10526                  as_Register($op1$$reg), as_Register($op2$$reg),
10527                  as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
10528   %}
10529 
10530   ins_pipe(pipe_class_compare);
10531 %}
10532 
10533 instruct cmovF_cmpU(fRegF dst, fRegF src, iRegI op1, iRegI op2, cmpOpU cop) %{
10534   match(Set dst (CMoveF (Binary cop (CmpU op1 op2)) (Binary dst src)));
10535   ins_cost(ALU_COST + BRANCH_COST);
10536 
10537   format %{
10538     "CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpU\n\t"
10539   %}
10540 
10541   ins_encode %{
10542     __ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
10543                  as_Register($op1$$reg), as_Register($op2$$reg),
10544                  as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
10545   %}
10546 
10547   ins_pipe(pipe_class_compare);
10548 %}
10549 
10550 instruct cmovF_cmpL(fRegF dst, fRegF src, iRegL op1, iRegL op2, cmpOp cop) %{
10551   match(Set dst (CMoveF (Binary cop (CmpL op1 op2)) (Binary dst src)));
10552   ins_cost(ALU_COST + BRANCH_COST);
10553 
10554   format %{
10555     "CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpL\n\t"
10556   %}
10557 
10558   ins_encode %{
10559     __ enc_cmove_fp_cmp($cop$$cmpcode,
10560                  as_Register($op1$$reg), as_Register($op2$$reg),
10561                  as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
10562   %}
10563 
10564   ins_pipe(pipe_class_compare);
10565 %}
10566 
10567 instruct cmovF_cmpUL(fRegF dst, fRegF src, iRegL op1, iRegL op2, cmpOpU cop) %{
10568   match(Set dst (CMoveF (Binary cop (CmpUL op1 op2)) (Binary dst src)));
10569   ins_cost(ALU_COST + BRANCH_COST);
10570 
10571   format %{
10572     "CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpUL\n\t"
10573   %}
10574 
10575   ins_encode %{
10576     __ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
10577                  as_Register($op1$$reg), as_Register($op2$$reg),
10578                  as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
10579   %}
10580 
10581   ins_pipe(pipe_class_compare);
10582 %}
10583 
10584 instruct cmovF_cmpF(fRegF dst, fRegF src, fRegF op1, fRegF op2, cmpOp cop) %{
10585   match(Set dst (CMoveF (Binary cop (CmpF op1 op2)) (Binary dst src)));
10586   ins_cost(ALU_COST + BRANCH_COST);
10587 
10588   format %{
10589     "CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpF\n\t"
10590   %}
10591 
10592   ins_encode %{
10593     __ enc_cmove_fp_cmp_fp($cop$$cmpcode,
10594                     as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
10595                     as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
10596                     true /* cmp_single */, true /* cmov_single */);
10597   %}
10598 
10599   ins_pipe(pipe_class_compare);
10600 %}
10601 
10602 instruct cmovF_cmpD(fRegF dst, fRegF src, fRegD op1, fRegD op2, cmpOp cop) %{
10603   match(Set dst (CMoveF (Binary cop (CmpD op1 op2)) (Binary dst src)));
10604   ins_cost(ALU_COST + BRANCH_COST);
10605 
10606   format %{
10607     "CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpD\n\t"
10608   %}
10609 
10610   ins_encode %{
10611     __ enc_cmove_fp_cmp_fp($cop$$cmpcode | C2_MacroAssembler::double_branch_mask,
10612                     as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
10613                     as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
10614                     false /* cmp_single */, true /* cmov_single */);
10615   %}
10616 
10617   ins_pipe(pipe_class_compare);
10618 %}
10619 
10620 instruct cmovF_cmpN(fRegF dst, fRegF src, iRegN op1, iRegN op2, cmpOp cop) %{
10621   match(Set dst (CMoveF (Binary cop (CmpN op1 op2)) (Binary dst src)));
10622   ins_cost(ALU_COST + BRANCH_COST);
10623 
10624   format %{
10625     "CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpN\n\t"
10626   %}
10627 
10628   ins_encode %{
10629     __ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
10630                  as_Register($op1$$reg), as_Register($op2$$reg),
10631                  as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
10632   %}
10633 
10634   ins_pipe(pipe_class_compare);
10635 %}
10636 
10637 instruct cmovF_cmpP(fRegF dst, fRegF src, iRegP op1, iRegP op2, cmpOp cop) %{
10638   match(Set dst (CMoveF (Binary cop (CmpP op1 op2)) (Binary dst src)));
10639   ins_cost(ALU_COST + BRANCH_COST);
10640 
10641   format %{
10642     "CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpP\n\t"
10643   %}
10644 
10645   ins_encode %{
10646     __ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
10647                  as_Register($op1$$reg), as_Register($op2$$reg),
10648                  as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
10649   %}
10650 
10651   ins_pipe(pipe_class_compare);
10652 %}
10653 
10654 // --------- CMoveD ---------
10655 
10656 instruct cmovD_cmpI(fRegD dst, fRegD src, iRegI op1, iRegI op2, cmpOp cop) %{
10657   match(Set dst (CMoveD (Binary cop (CmpI op1 op2)) (Binary dst src)));
10658   ins_cost(ALU_COST + BRANCH_COST);
10659 
10660   format %{
10661     "CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpI\n\t"
10662   %}
10663 
10664   ins_encode %{
10665     __ enc_cmove_fp_cmp($cop$$cmpcode,
10666                  as_Register($op1$$reg), as_Register($op2$$reg),
10667                  as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
10668   %}
10669 
10670   ins_pipe(pipe_class_compare);
10671 %}
10672 
10673 instruct cmovD_cmpU(fRegD dst, fRegD src, iRegI op1, iRegI op2, cmpOpU cop) %{
10674   match(Set dst (CMoveD (Binary cop (CmpU op1 op2)) (Binary dst src)));
10675   ins_cost(ALU_COST + BRANCH_COST);
10676 
10677   format %{
10678     "CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpU\n\t"
10679   %}
10680 
10681   ins_encode %{
10682     __ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
10683                  as_Register($op1$$reg), as_Register($op2$$reg),
10684                  as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
10685   %}
10686 
10687   ins_pipe(pipe_class_compare);
10688 %}
10689 
10690 instruct cmovD_cmpL(fRegD dst, fRegD src, iRegL op1, iRegL op2, cmpOp cop) %{
10691   match(Set dst (CMoveD (Binary cop (CmpL op1 op2)) (Binary dst src)));
10692   ins_cost(ALU_COST + BRANCH_COST);
10693 
10694   format %{
10695     "CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpL\n\t"
10696   %}
10697 
10698   ins_encode %{
10699     __ enc_cmove_fp_cmp($cop$$cmpcode,
10700                  as_Register($op1$$reg), as_Register($op2$$reg),
10701                  as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
10702   %}
10703 
10704   ins_pipe(pipe_class_compare);
10705 %}
10706 
10707 instruct cmovD_cmpUL(fRegD dst, fRegD src, iRegL op1, iRegL op2, cmpOpU cop) %{
10708   match(Set dst (CMoveD (Binary cop (CmpUL op1 op2)) (Binary dst src)));
10709   ins_cost(ALU_COST + BRANCH_COST);
10710 
10711   format %{
10712     "CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpUL\n\t"
10713   %}
10714 
10715   ins_encode %{
10716     __ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
10717                  as_Register($op1$$reg), as_Register($op2$$reg),
10718                  as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
10719   %}
10720 
10721   ins_pipe(pipe_class_compare);
10722 %}
10723 
10724 instruct cmovD_cmpF(fRegD dst, fRegD src, fRegF op1, fRegF op2, cmpOp cop) %{
10725   match(Set dst (CMoveD (Binary cop (CmpF op1 op2)) (Binary dst src)));
10726   ins_cost(ALU_COST + BRANCH_COST);
10727 
10728   format %{
10729     "CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpF\n\t"
10730   %}
10731 
10732   ins_encode %{
10733     __ enc_cmove_fp_cmp_fp($cop$$cmpcode,
10734                     as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
10735                     as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
10736                     true /* cmp_single */, false /* cmov_single */);
10737   %}
10738 
10739   ins_pipe(pipe_class_compare);
10740 %}
10741 
10742 instruct cmovD_cmpD(fRegD dst, fRegD src, fRegD op1, fRegD op2, cmpOp cop) %{
10743   match(Set dst (CMoveD (Binary cop (CmpD op1 op2)) (Binary dst src)));
10744   ins_cost(ALU_COST + BRANCH_COST);
10745 
10746   format %{
10747     "CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpD\n\t"
10748   %}
10749 
10750   ins_encode %{
10751     __ enc_cmove_fp_cmp_fp($cop$$cmpcode | C2_MacroAssembler::double_branch_mask,
10752                     as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
10753                     as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
10754                     false /* cmp_single */, false /* cmov_single */);
10755   %}
10756 
10757   ins_pipe(pipe_class_compare);
10758 %}
10759 
10760 instruct cmovD_cmpN(fRegD dst, fRegD src, iRegN op1, iRegN op2, cmpOp cop) %{
10761   match(Set dst (CMoveD (Binary cop (CmpN op1 op2)) (Binary dst src)));
10762   ins_cost(ALU_COST + BRANCH_COST);
10763 
10764   format %{
10765     "CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpN\n\t"
10766   %}
10767 
10768   ins_encode %{
10769     __ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
10770                  as_Register($op1$$reg), as_Register($op2$$reg),
10771                  as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
10772   %}
10773 
10774   ins_pipe(pipe_class_compare);
10775 %}
10776 
10777 instruct cmovD_cmpP(fRegD dst, fRegD src, iRegP op1, iRegP op2, cmpOp cop) %{
10778   match(Set dst (CMoveD (Binary cop (CmpP op1 op2)) (Binary dst src)));
10779   ins_cost(ALU_COST + BRANCH_COST);
10780 
10781   format %{
10782     "CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpP\n\t"
10783   %}
10784 
10785   ins_encode %{
10786     __ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
10787                  as_Register($op1$$reg), as_Register($op2$$reg),
10788                  as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
10789   %}
10790 
10791   ins_pipe(pipe_class_compare);
10792 %}
10793 
10794 // ============================================================================
10795 // Procedure Call/Return Instructions
10796 
10797 // Call Java Static Instruction
10798 // Note: If this code changes, the corresponding ret_addr_offset() and
10799 //       compute_padding() functions will have to be adjusted.
10800 instruct CallStaticJavaDirect(method meth)
10801 %{
10802   match(CallStaticJava);
10803 
10804   effect(USE meth);
10805 
10806   ins_cost(BRANCH_COST);
10807 
10808   format %{ "CALL,static $meth\t#@CallStaticJavaDirect" %}
10809 
10810   ins_encode(riscv_enc_java_static_call(meth),
10811              riscv_enc_call_epilog);
10812 
10813   ins_pipe(pipe_class_call);
10814   ins_alignment(4);
10815 %}
10816 
10817 // TO HERE
10818 
10819 // Call Java Dynamic Instruction
10820 // Note: If this code changes, the corresponding ret_addr_offset() and
10821 //       compute_padding() functions will have to be adjusted.
10822 instruct CallDynamicJavaDirect(method meth)
10823 %{
10824   match(CallDynamicJava);
10825 
10826   effect(USE meth);
10827 
10828   ins_cost(BRANCH_COST + ALU_COST * 5);
10829 
10830   format %{ "CALL,dynamic $meth\t#@CallDynamicJavaDirect" %}
10831 
10832   ins_encode(riscv_enc_java_dynamic_call(meth),
10833              riscv_enc_call_epilog);
10834 
10835   ins_pipe(pipe_class_call);
10836   ins_alignment(4);
10837 %}
10838 
10839 // Call Runtime Instruction
10840 
10841 instruct CallRuntimeDirect(method meth)
10842 %{
10843   match(CallRuntime);
10844 
10845   effect(USE meth);
10846 
10847   ins_cost(BRANCH_COST);
10848 
10849   format %{ "CALL, runtime $meth\t#@CallRuntimeDirect" %}
10850 
10851   ins_encode(riscv_enc_java_to_runtime(meth));
10852 
10853   ins_pipe(pipe_class_call);
10854   ins_alignment(4);
10855 %}
10856 
10857 // Call Runtime Instruction
10858 
10859 instruct CallLeafDirect(method meth)
10860 %{
10861   match(CallLeaf);
10862 
10863   effect(USE meth);
10864 
10865   ins_cost(BRANCH_COST);
10866 
10867   format %{ "CALL, runtime leaf $meth\t#@CallLeafDirect" %}
10868 
10869   ins_encode(riscv_enc_java_to_runtime(meth));
10870 
10871   ins_pipe(pipe_class_call);
10872   ins_alignment(4);
10873 %}
10874 
10875 // Call Runtime Instruction without safepoint and with vector arguments
10876 
10877 instruct CallLeafDirectVector(method meth)
10878 %{
10879   match(CallLeafVector);
10880 
10881   effect(USE meth);
10882 
10883   ins_cost(BRANCH_COST);
10884 
10885   format %{ "CALL, runtime leaf vector $meth" %}
10886 
10887   ins_encode(riscv_enc_java_to_runtime(meth));
10888 
10889   ins_pipe(pipe_class_call);
10890   ins_alignment(4);
10891 %}
10892 
10893 // Call Runtime Instruction
10894 
10895 // entry point is null, target holds the address to call
10896 instruct CallLeafNoFPIndirect(iRegP target)
10897 %{
10898   predicate(n->as_Call()->entry_point() == nullptr);
10899 
10900   match(CallLeafNoFP target);
10901 
10902   ins_cost(BRANCH_COST);
10903 
10904   format %{ "CALL, runtime leaf nofp indirect $target" %}
10905 
10906   ins_encode %{
10907     Assembler::IncompressibleScope scope(masm); // Fixed length: see ret_addr_offset
10908     __ jalr($target$$Register);
10909     __ post_call_nop();
10910   %}
10911 
10912   ins_pipe(pipe_class_call);
10913   ins_alignment(4);
10914 %}
10915 
10916 instruct CallLeafNoFPDirect(method meth)
10917 %{
10918   predicate(n->as_Call()->entry_point() != nullptr);
10919 
10920   match(CallLeafNoFP);
10921 
10922   effect(USE meth);
10923 
10924   ins_cost(BRANCH_COST);
10925 
10926   format %{ "CALL, runtime leaf nofp $meth\t#@CallLeafNoFPDirect" %}
10927 
10928   ins_encode(riscv_enc_java_to_runtime(meth));
10929 
10930   ins_pipe(pipe_class_call);
10931   ins_alignment(4);
10932 %}
10933 
10934 // ============================================================================
10935 // Partial Subtype Check
10936 //
10937 // superklass array for an instance of the superklass.  Set a hidden
10938 // internal cache on a hit (cache is checked with exposed code in
10939 // gen_subtype_check()).  Return zero for a hit.  The encoding
10940 // ALSO sets flags.
10941 
10942 instruct partialSubtypeCheck(iRegP_R15 result, iRegP_R14 sub, iRegP_R10 super, iRegP_R12 tmp, rFlagsReg cr)
10943 %{
10944   predicate(!UseSecondarySupersTable);
10945   match(Set result (PartialSubtypeCheck sub super));
10946   effect(KILL tmp, KILL cr);
10947 
10948   ins_cost(20 * DEFAULT_COST);
10949   format %{ "partialSubtypeCheck $result, $sub, $super\t#@partialSubtypeCheck" %}
10950 
10951   ins_encode(riscv_enc_partial_subtype_check(sub, super, tmp, result));
10952 
10953   opcode(0x1); // Force zero of result reg on hit
10954 
10955   ins_pipe(pipe_class_memory);
10956 %}
10957 
10958 // Two versions of partialSubtypeCheck, both used when we need to
10959 // search for a super class in the secondary supers array. The first
10960 // is used when we don't know _a priori_ the class being searched
10961 // for. The second, far more common, is used when we do know: this is
10962 // used for instanceof, checkcast, and any case where C2 can determine
10963 // it by constant propagation.
10964 
10965 instruct partialSubtypeCheckVarSuper(iRegP_R14 sub, iRegP_R10 super, iRegP_R15 result,
10966                                      iRegP_R11 tmpR11, iRegP_R12 tmpR12, iRegP_R13 tmpR13,
10967                                      iRegP_R16 tmpR16, rFlagsReg cr)
10968 %{
10969   predicate(UseSecondarySupersTable);
10970   match(Set result (PartialSubtypeCheck sub super));
10971   effect(TEMP tmpR11, TEMP tmpR12, TEMP tmpR13, TEMP tmpR16, KILL cr);
10972 
10973   ins_cost(10 * DEFAULT_COST);  // slightly larger than the next version
10974   format %{ "partialSubtypeCheck $result, $sub, $super" %}
10975 
10976   ins_encode %{
10977     __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register, $result$$Register,
10978                                          $tmpR11$$Register, $tmpR12$$Register, $tmpR13$$Register,
10979                                          $tmpR16$$Register, nullptr /*L_success*/);
10980   %}
10981 
10982   ins_pipe(pipe_class_memory);
10983 %}
10984 
10985 instruct partialSubtypeCheckConstSuper(iRegP_R14 sub, iRegP_R10 super_reg, immP super_con, iRegP_R15 result,
10986                                        iRegP_R11 tmpR11, iRegP_R12 tmpR12, iRegP_R13 tmpR13, iRegP_R16 tmpR16, rFlagsReg cr)
10987 %{
10988   predicate(UseSecondarySupersTable);
10989   match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con)));
10990   effect(TEMP tmpR11, TEMP tmpR12, TEMP tmpR13, TEMP tmpR16, KILL cr);
10991 
10992   ins_cost(5 * DEFAULT_COST); // needs to be less than competing nodes
10993   format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %}
10994 
10995   ins_encode %{
10996     bool success = false;
10997     u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot();
10998     if (InlineSecondarySupersTest) {
10999       success = __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register, $result$$Register,
11000                                                        $tmpR11$$Register, $tmpR12$$Register, $tmpR13$$Register,
11001                                                        $tmpR16$$Register, super_klass_slot);
11002     } else {
11003       address call = __ reloc_call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot)));
11004       success = (call != nullptr);
11005     }
11006     if (!success) {
11007       ciEnv::current()->record_failure("CodeCache is full");
11008       return;
11009     }
11010   %}
11011 
11012   ins_pipe(pipe_class_memory);
11013 %}
11014 
11015 instruct string_compareU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
11016                          iRegI_R10 result, iRegP_R28 tmp1, iRegL_R29 tmp2, iRegL_R30 tmp3, rFlagsReg cr)
11017 %{
11018   predicate(!UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::UU);
11019   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11020   effect(KILL tmp1, KILL tmp2, KILL tmp3, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11021 
11022   format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareU" %}
11023   ins_encode %{
11024     // Count is in 8-bit bytes; non-Compact chars are 16 bits.
11025     __ string_compare($str1$$Register, $str2$$Register,
11026                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
11027                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
11028                       StrIntrinsicNode::UU);
11029   %}
11030   ins_pipe(pipe_class_memory);
11031 %}
11032 
11033 instruct string_compareL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
11034                          iRegI_R10 result, iRegP_R28 tmp1, iRegL_R29 tmp2, iRegL_R30 tmp3, rFlagsReg cr)
11035 %{
11036   predicate(!UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::LL);
11037   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11038   effect(KILL tmp1, KILL tmp2, KILL tmp3, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11039 
11040   format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareL" %}
11041   ins_encode %{
11042     __ string_compare($str1$$Register, $str2$$Register,
11043                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
11044                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
11045                       StrIntrinsicNode::LL);
11046   %}
11047   ins_pipe(pipe_class_memory);
11048 %}
11049 
11050 instruct string_compareUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
11051                           iRegI_R10 result, iRegP_R28 tmp1, iRegL_R29 tmp2, iRegL_R30 tmp3, rFlagsReg cr)
11052 %{
11053   predicate(!UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::UL);
11054   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11055   effect(KILL tmp1, KILL tmp2, KILL tmp3, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11056 
11057   format %{"String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareUL" %}
11058   ins_encode %{
11059     __ string_compare($str1$$Register, $str2$$Register,
11060                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
11061                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
11062                       StrIntrinsicNode::UL);
11063   %}
11064   ins_pipe(pipe_class_memory);
11065 %}
11066 
11067 instruct string_compareLU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
11068                           iRegI_R10 result, iRegP_R28 tmp1, iRegL_R29 tmp2, iRegL_R30 tmp3,
11069                           rFlagsReg cr)
11070 %{
11071   predicate(!UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::LU);
11072   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11073   effect(KILL tmp1, KILL tmp2, KILL tmp3, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11074 
11075   format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareLU" %}
11076   ins_encode %{
11077     __ string_compare($str1$$Register, $str2$$Register,
11078                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
11079                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
11080                       StrIntrinsicNode::LU);
11081   %}
11082   ins_pipe(pipe_class_memory);
11083 %}
11084 
11085 instruct string_indexofUU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
11086                           iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3,
11087                           iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr)
11088 %{
11089   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
11090   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
11091   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP_DEF result,
11092          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr);
11093 
11094   format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %}
11095   ins_encode %{
11096     __ string_indexof($str1$$Register, $str2$$Register,
11097                       $cnt1$$Register, $cnt2$$Register,
11098                       $tmp1$$Register, $tmp2$$Register,
11099                       $tmp3$$Register, $tmp4$$Register,
11100                       $tmp5$$Register, $tmp6$$Register,
11101                       $result$$Register, StrIntrinsicNode::UU);
11102   %}
11103   ins_pipe(pipe_class_memory);
11104 %}
11105 
11106 instruct string_indexofLL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
11107                           iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3,
11108                           iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr)
11109 %{
11110   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
11111   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
11112   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP_DEF result,
11113          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr);
11114 
11115   format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %}
11116   ins_encode %{
11117     __ string_indexof($str1$$Register, $str2$$Register,
11118                       $cnt1$$Register, $cnt2$$Register,
11119                       $tmp1$$Register, $tmp2$$Register,
11120                       $tmp3$$Register, $tmp4$$Register,
11121                       $tmp5$$Register, $tmp6$$Register,
11122                       $result$$Register, StrIntrinsicNode::LL);
11123   %}
11124   ins_pipe(pipe_class_memory);
11125 %}
11126 
11127 instruct string_indexofUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
11128                           iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3,
11129                           iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr)
11130 %{
11131   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
11132   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
11133   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP_DEF result,
11134          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr);
11135   format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %}
11136 
11137   ins_encode %{
11138     __ string_indexof($str1$$Register, $str2$$Register,
11139                       $cnt1$$Register, $cnt2$$Register,
11140                       $tmp1$$Register, $tmp2$$Register,
11141                       $tmp3$$Register, $tmp4$$Register,
11142                       $tmp5$$Register, $tmp6$$Register,
11143                       $result$$Register, StrIntrinsicNode::UL);
11144   %}
11145   ins_pipe(pipe_class_memory);
11146 %}
11147 
11148 instruct string_indexof_conUU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2,
11149                               immI_le_4 int_cnt2, iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2,
11150                               iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
11151 %{
11152   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
11153   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
11154   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, TEMP_DEF result,
11155          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
11156 
11157   format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %}
11158 
11159   ins_encode %{
11160     int icnt2 = (int)$int_cnt2$$constant;
11161     __ string_indexof_linearscan($str1$$Register, $str2$$Register,
11162                                  $cnt1$$Register, zr,
11163                                  $tmp1$$Register, $tmp2$$Register,
11164                                  $tmp3$$Register, $tmp4$$Register,
11165                                  icnt2, $result$$Register, StrIntrinsicNode::UU);
11166   %}
11167   ins_pipe(pipe_class_memory);
11168 %}
11169 
11170 instruct string_indexof_conLL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2,
11171                               immI_le_4 int_cnt2, iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2,
11172                               iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
11173 %{
11174   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
11175   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
11176   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, TEMP_DEF result,
11177          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
11178 
11179   format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %}
11180   ins_encode %{
11181     int icnt2 = (int)$int_cnt2$$constant;
11182     __ string_indexof_linearscan($str1$$Register, $str2$$Register,
11183                                  $cnt1$$Register, zr,
11184                                  $tmp1$$Register, $tmp2$$Register,
11185                                  $tmp3$$Register, $tmp4$$Register,
11186                                  icnt2, $result$$Register, StrIntrinsicNode::LL);
11187   %}
11188   ins_pipe(pipe_class_memory);
11189 %}
11190 
11191 instruct string_indexof_conUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2,
11192                               immI_1 int_cnt2, iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2,
11193                               iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
11194 %{
11195   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
11196   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
11197   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, TEMP_DEF result,
11198          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
11199 
11200   format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %}
11201   ins_encode %{
11202     int icnt2 = (int)$int_cnt2$$constant;
11203     __ string_indexof_linearscan($str1$$Register, $str2$$Register,
11204                                  $cnt1$$Register, zr,
11205                                  $tmp1$$Register, $tmp2$$Register,
11206                                  $tmp3$$Register, $tmp4$$Register,
11207                                  icnt2, $result$$Register, StrIntrinsicNode::UL);
11208   %}
11209   ins_pipe(pipe_class_memory);
11210 %}
11211 
11212 instruct stringU_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch,
11213                               iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2,
11214                               iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
11215 %{
11216   match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
11217   predicate(!UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U));
11218   effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP_DEF result,
11219          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
11220 
11221   format %{ "StringUTF16 IndexOf char[] $str1, $cnt1, $ch -> $result" %}
11222   ins_encode %{
11223     __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register,
11224                            $result$$Register, $tmp1$$Register, $tmp2$$Register,
11225                            $tmp3$$Register, $tmp4$$Register, false /* isU */);
11226   %}
11227   ins_pipe(pipe_class_memory);
11228 %}
11229 
11230 
11231 instruct stringL_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch,
11232                               iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2,
11233                               iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
11234 %{
11235   match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
11236   predicate(!UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L));
11237   effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP_DEF result,
11238          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
11239 
11240   format %{ "StringLatin1 IndexOf char[] $str1, $cnt1, $ch -> $result" %}
11241   ins_encode %{
11242     __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register,
11243                            $result$$Register, $tmp1$$Register, $tmp2$$Register,
11244                            $tmp3$$Register, $tmp4$$Register, true /* isL */);
11245   %}
11246   ins_pipe(pipe_class_memory);
11247 %}
11248 
11249 // ============================================================================
11250 // clearing of an array
11251 
11252 instruct clearArray_reg_reg_immL0(iRegL_R29 cnt, iRegP_R28 base, immL0 zero,
11253                                   iRegP_R30 tmp1, iRegP_R31 tmp2, rFlagsReg cr,
11254                                   Universe dummy)
11255 %{
11256   // temp registers must match the one used in StubGenerator::generate_zero_blocks()
11257   predicate(UseBlockZeroing || !UseRVV);
11258   match(Set dummy (ClearArray (Binary cnt base) zero));
11259   effect(USE_KILL cnt, USE_KILL base, TEMP tmp1, TEMP tmp2, KILL cr);
11260 
11261   ins_cost(4 * DEFAULT_COST);
11262   format %{ "ClearArray $cnt, $base\t#@clearArray_reg_reg_immL0" %}
11263 
11264   ins_encode %{
11265     address tpc = __ zero_words($base$$Register, $cnt$$Register);
11266     if (tpc == nullptr) {
11267       ciEnv::current()->record_failure("CodeCache is full");
11268       return;
11269     }
11270   %}
11271 
11272   ins_pipe(pipe_class_memory);
11273 %}
11274 
11275 instruct clearArray_reg_reg(iRegL_R29 cnt, iRegP_R28 base, iRegL val,
11276                             iRegP_R30 tmp1, iRegP_R31 tmp2, rFlagsReg cr,
11277                             Universe dummy)
11278 %{
11279   // temp registers must match the one used in StubGenerator::generate_zero_blocks()
11280   predicate(((ClearArrayNode*)n)->word_copy_only());
11281   match(Set dummy (ClearArray (Binary cnt base) val));
11282   effect(USE_KILL cnt, USE_KILL base, TEMP tmp1, TEMP tmp2, KILL cr);
11283 
11284   ins_cost(4 * DEFAULT_COST);
11285   format %{ "ClearArray $cnt, $base, $val\t#@clearArray_reg_reg" %}
11286 
11287   ins_encode %{
11288     __ fill_words($base$$Register, $cnt$$Register, $val$$Register);
11289   %}
11290 
11291   ins_pipe(pipe_class_memory);
11292 %}
11293 
11294 instruct clearArray_imm_reg(immL cnt, iRegP_R28 base, immL0 zero, Universe dummy, rFlagsReg cr)
11295 %{
11296   predicate(!UseRVV
11297             && (uint64_t)n->in(2)->in(1)->get_long()
11298                < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord)
11299             && !((ClearArrayNode*)n)->word_copy_only());
11300   match(Set dummy (ClearArray (Binary cnt base) zero));
11301   effect(USE_KILL base, KILL cr);
11302 
11303   ins_cost(4 * DEFAULT_COST);
11304   format %{ "ClearArray $cnt, $base\t#@clearArray_imm_reg" %}
11305 
11306   ins_encode %{
11307     __ zero_words($base$$Register, (uint64_t)$cnt$$constant);
11308   %}
11309 
11310   ins_pipe(pipe_class_memory);
11311 %}
11312 
11313 instruct string_equalsL(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt,
11314                         iRegI_R10 result, rFlagsReg cr)
11315 %{
11316   predicate(!UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
11317   match(Set result (StrEquals (Binary str1 str2) cnt));
11318   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr);
11319 
11320   format %{ "String Equals $str1, $str2, $cnt -> $result\t#@string_equalsL" %}
11321   ins_encode %{
11322     // Count is in 8-bit bytes; non-Compact chars are 16 bits.
11323     __ string_equals($str1$$Register, $str2$$Register,
11324                      $result$$Register, $cnt$$Register);
11325   %}
11326   ins_pipe(pipe_class_memory);
11327 %}
11328 
11329 instruct array_equalsB(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result,
11330                        iRegP_R13 tmp1, iRegP_R14 tmp2, iRegP_R15 tmp3)
11331 %{
11332   predicate(!UseRVV && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
11333   match(Set result (AryEq ary1 ary2));
11334   effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3);
11335 
11336   format %{ "Array Equals $ary1, $ary2 -> $result\t#@array_equalsB // KILL all" %}
11337   ins_encode %{
11338     __ arrays_equals($ary1$$Register, $ary2$$Register,
11339                      $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
11340                      $result$$Register, 1);
11341   %}
11342   ins_pipe(pipe_class_memory);
11343 %}
11344 
11345 instruct array_equalsC(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result,
11346                        iRegP_R13 tmp1, iRegP_R14 tmp2, iRegP_R15 tmp3)
11347 %{
11348   predicate(!UseRVV && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
11349   match(Set result (AryEq ary1 ary2));
11350   effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3);
11351 
11352   format %{ "Array Equals $ary1, $ary2 -> $result\t#@array_equalsC // KILL all" %}
11353   ins_encode %{
11354     __ arrays_equals($ary1$$Register, $ary2$$Register,
11355                      $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
11356                      $result$$Register, 2);
11357   %}
11358   ins_pipe(pipe_class_memory);
11359 %}
11360 
11361 // fast ArraysSupport.vectorizedHashCode
11362 instruct arrays_hashcode(iRegP_R11 ary, iRegI_R12 cnt, iRegI_R10 result, immI basic_type,
11363                          iRegLNoSp tmp1, iRegLNoSp tmp2,
11364                          iRegLNoSp tmp3, iRegLNoSp tmp4,
11365                          iRegLNoSp tmp5, iRegLNoSp tmp6, rFlagsReg cr)
11366 %{
11367   predicate(!UseRVV);
11368   match(Set result (VectorizedHashCode (Binary ary cnt) (Binary result basic_type)));
11369   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6,
11370          USE_KILL ary, USE_KILL cnt, USE basic_type, KILL cr);
11371 
11372   format %{ "Array HashCode array[] $ary,$cnt,$result,$basic_type -> $result   // KILL all" %}
11373   ins_encode %{
11374     __ arrays_hashcode($ary$$Register, $cnt$$Register, $result$$Register,
11375                        $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
11376                        $tmp4$$Register, $tmp5$$Register, $tmp6$$Register,
11377                        (BasicType)$basic_type$$constant);
11378   %}
11379   ins_pipe(pipe_class_memory);
11380 %}
11381 
11382 // ============================================================================
11383 // Safepoint Instructions
11384 
11385 instruct safePoint(iRegP poll)
11386 %{
11387   match(SafePoint poll);
11388 
11389   ins_cost(2 * LOAD_COST);
11390   format %{
11391     "lwu zr, [$poll]\t# Safepoint: poll for GC, #@safePoint"
11392   %}
11393   ins_encode %{
11394     __ read_polling_page(as_Register($poll$$reg), 0, relocInfo::poll_type);
11395   %}
11396   ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem);
11397 %}
11398 
11399 // ============================================================================
11400 // This name is KNOWN by the ADLC and cannot be changed.
11401 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
11402 // for this guy.
11403 instruct tlsLoadP(javaThread_RegP dst)
11404 %{
11405   match(Set dst (ThreadLocal));
11406 
11407   ins_cost(0);
11408 
11409   format %{ " -- \t// $dst=Thread::current(), empty, #@tlsLoadP" %}
11410 
11411   size(0);
11412 
11413   ins_encode( /*empty*/ );
11414 
11415   ins_pipe(pipe_class_empty);
11416 %}
11417 
11418 // inlined locking and unlocking
11419 // using t1 as the 'flag' register to bridge the BoolNode producers and consumers
11420 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box,
11421                      iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3, iRegPNoSp tmp4)
11422 %{
11423   match(Set cr (FastLock object box));
11424   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4);
11425 
11426   ins_cost(10 * DEFAULT_COST);
11427   format %{ "fastlock $object,$box\t! kills $tmp1,$tmp2,$tmp3,$tmp4 #@cmpFastLock" %}
11428 
11429   ins_encode %{
11430     __ fast_lock($object$$Register, $box$$Register,
11431                  $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register);
11432   %}
11433 
11434   ins_pipe(pipe_serial);
11435 %}
11436 
11437 // using t1 as the 'flag' register to bridge the BoolNode producers and consumers
11438 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box,
11439                        iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3)
11440 %{
11441   match(Set cr (FastUnlock object box));
11442   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
11443 
11444   ins_cost(10 * DEFAULT_COST);
11445   format %{ "fastunlock $object,$box\t! kills $tmp1,$tmp2,$tmp3 #@cmpFastUnlock" %}
11446 
11447   ins_encode %{
11448     __ fast_unlock($object$$Register, $box$$Register,
11449                    $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
11450   %}
11451 
11452   ins_pipe(pipe_serial);
11453 %}
11454 
11455 // Tail Call; Jump from runtime stub to Java code.
11456 // Also known as an 'interprocedural jump'.
11457 // Target of jump will eventually return to caller.
11458 // TailJump below removes the return address.
11459 // Don't use fp for 'jump_target' because a MachEpilogNode has already been
11460 // emitted just above the TailCall which has reset fp to the caller state.
11461 instruct TailCalljmpInd(iRegPNoSpNoFp jump_target, inline_cache_RegP method_oop)
11462 %{
11463   match(TailCall jump_target method_oop);
11464 
11465   ins_cost(BRANCH_COST);
11466 
11467   format %{ "jalr $jump_target\t# $method_oop holds method oop, #@TailCalljmpInd." %}
11468 
11469   ins_encode(riscv_enc_tail_call(jump_target));
11470 
11471   ins_pipe(pipe_class_call);
11472 %}
11473 
11474 instruct TailjmpInd(iRegPNoSpNoFp jump_target, iRegP_R10 ex_oop)
11475 %{
11476   match(TailJump jump_target ex_oop);
11477 
11478   ins_cost(ALU_COST + BRANCH_COST);
11479 
11480   format %{ "jalr $jump_target\t# $ex_oop holds exception oop, #@TailjmpInd." %}
11481 
11482   ins_encode(riscv_enc_tail_jmp(jump_target));
11483 
11484   ins_pipe(pipe_class_call);
11485 %}
11486 
11487 // Forward exception.
11488 instruct ForwardExceptionjmp()
11489 %{
11490   match(ForwardException);
11491 
11492   ins_cost(BRANCH_COST);
11493 
11494   format %{ "j forward_exception_stub\t#@ForwardException" %}
11495 
11496   ins_encode %{
11497     __ far_jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
11498   %}
11499 
11500   ins_pipe(pipe_class_call);
11501 %}
11502 
11503 // Create exception oop: created by stack-crawling runtime code.
11504 // Created exception is now available to this handler, and is setup
11505 // just prior to jumping to this handler. No code emitted.
11506 instruct CreateException(iRegP_R10 ex_oop)
11507 %{
11508   match(Set ex_oop (CreateEx));
11509 
11510   ins_cost(0);
11511   format %{ " -- \t// exception oop; no code emitted, #@CreateException" %}
11512 
11513   size(0);
11514 
11515   ins_encode( /*empty*/ );
11516 
11517   ins_pipe(pipe_class_empty);
11518 %}
11519 
11520 // Rethrow exception: The exception oop will come in the first
11521 // argument position. Then JUMP (not call) to the rethrow stub code.
11522 instruct RethrowException()
11523 %{
11524   match(Rethrow);
11525 
11526   ins_cost(BRANCH_COST);
11527 
11528   format %{ "j rethrow_stub\t#@RethrowException" %}
11529 
11530   ins_encode(riscv_enc_rethrow());
11531 
11532   ins_pipe(pipe_class_call);
11533 %}
11534 
11535 // Return Instruction
11536 // epilog node loads ret address into ra as part of frame pop
11537 instruct Ret()
11538 %{
11539   match(Return);
11540 
11541   ins_cost(BRANCH_COST);
11542   format %{ "ret\t// return register, #@Ret" %}
11543 
11544   ins_encode(riscv_enc_ret());
11545 
11546   ins_pipe(pipe_branch);
11547 %}
11548 
11549 // Die now.
11550 instruct ShouldNotReachHere() %{
11551   match(Halt);
11552 
11553   ins_cost(BRANCH_COST);
11554 
11555   format %{ "#@ShouldNotReachHere" %}
11556 
11557   ins_encode %{
11558     if (is_reachable()) {
11559       const char* str = __ code_string(_halt_reason);
11560       __ stop(str);
11561     }
11562   %}
11563 
11564   ins_pipe(pipe_class_default);
11565 %}
11566 
11567 
11568 //----------PEEPHOLE RULES-----------------------------------------------------
11569 // These must follow all instruction definitions as they use the names
11570 // defined in the instructions definitions.
11571 //
11572 // peepmatch ( root_instr_name [preceding_instruction]* );
11573 //
11574 // peepconstraint %{
11575 // (instruction_number.operand_name relational_op instruction_number.operand_name
11576 //  [, ...] );
11577 // // instruction numbers are zero-based using left to right order in peepmatch
11578 //
11579 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
11580 // // provide an instruction_number.operand_name for each operand that appears
11581 // // in the replacement instruction's match rule
11582 //
11583 // ---------VM FLAGS---------------------------------------------------------
11584 //
11585 // All peephole optimizations can be turned off using -XX:-OptoPeephole
11586 //
11587 // Each peephole rule is given an identifying number starting with zero and
11588 // increasing by one in the order seen by the parser.  An individual peephole
11589 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
11590 // on the command-line.
11591 //
11592 // ---------CURRENT LIMITATIONS----------------------------------------------
11593 //
11594 // Only match adjacent instructions in same basic block
11595 // Only equality constraints
11596 // Only constraints between operands, not (0.dest_reg == RAX_enc)
11597 // Only one replacement instruction
11598 //
11599 //----------SMARTSPILL RULES---------------------------------------------------
11600 // These must follow all instruction definitions as they use the names
11601 // defined in the instructions definitions.
11602 
11603 // Local Variables:
11604 // mode: c++
11605 // End: