1 //
   2 // Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
   3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4 //
   5 // This code is free software; you can redistribute it and/or modify it
   6 // under the terms of the GNU General Public License version 2 only, as
   7 // published by the Free Software Foundation.
   8 //
   9 // This code is distributed in the hope that it will be useful, but WITHOUT
  10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12 // version 2 for more details (a copy is included in the LICENSE file that
  13 // accompanied this code).
  14 //
  15 // You should have received a copy of the GNU General Public License version
  16 // 2 along with this work; if not, write to the Free Software Foundation,
  17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18 //
  19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20 // or visit www.oracle.com if you need additional information or have any
  21 // questions.
  22 //
  23 
  24 // ARM Architecture Description File
  25 
  26 //----------DEFINITION BLOCK---------------------------------------------------
  27 // Define name --> value mappings to inform the ADLC of an integer valued name
  28 // Current support includes integer values in the range [0, 0x7FFFFFFF]
  29 // Format:
  30 //        int_def  <name>         ( <int_value>, <expression>);
  31 // Generated Code in ad_<arch>.hpp
  32 //        #define  <name>   (<expression>)
  33 //        // value == <int_value>
  34 // Generated code in ad_<arch>.cpp adlc_verification()
  35 //        assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
  36 //
  37 definitions %{
  38 // The default cost (of an ALU instruction).
  39   int_def DEFAULT_COST      (    100,     100);
  40   int_def HUGE_COST         (1000000, 1000000);
  41 
  42 // Memory refs are twice as expensive as run-of-the-mill.
  43   int_def MEMORY_REF_COST   (    200, DEFAULT_COST * 2);
  44 
  45 // Branches are even more expensive.
  46   int_def BRANCH_COST       (    300, DEFAULT_COST * 3);
  47   int_def CALL_COST         (    300, DEFAULT_COST * 3);
  48 %}
  49 
  50 
  51 //----------SOURCE BLOCK-------------------------------------------------------
  52 // This is a block of C++ code which provides values, functions, and
  53 // definitions necessary in the rest of the architecture description
  54 source_hpp %{
  55 // Header information of the source block.
  56 // Method declarations/definitions which are used outside
  57 // the ad-scope can conveniently be defined here.
  58 //
  59 // To keep related declarations/definitions/uses close together,
  60 // we switch between source %{ }% and source_hpp %{ }% freely as needed.
  61 
  62 // Does destination need to be loaded in a register then passed to a
  63 // branch instruction?
  64 extern bool maybe_far_call(const CallNode *n);
  65 extern bool maybe_far_call(const MachCallNode *n);
  66 static inline bool cache_reachable() {
  67   return MacroAssembler::_cache_fully_reachable();
  68 }
  69 
  70 #ifdef AARCH64
  71 #define ldr_32 ldr_w
  72 #define str_32 str_w
  73 #else
  74 #define ldr_32 ldr
  75 #define str_32 str
  76 #define tst_32 tst
  77 #define teq_32 teq
  78 #endif
  79 #if 1
  80 extern bool PrintOptoAssembly;
  81 #endif
  82 
  83 class c2 {
  84 public:
  85   static OptoRegPair return_value(int ideal_reg);
  86 };
  87 
  88 class CallStubImpl {
  89 
  90   //--------------------------------------------------------------
  91   //---<  Used for optimization in Compile::Shorten_branches  >---
  92   //--------------------------------------------------------------
  93 
  94  public:
  95   // Size of call trampoline stub.
  96   static uint size_call_trampoline() {
  97     return 0; // no call trampolines on this platform
  98   }
  99 
 100   // number of relocations needed by a call trampoline stub
 101   static uint reloc_call_trampoline() {
 102     return 0; // no call trampolines on this platform
 103   }
 104 };
 105 
 106 class HandlerImpl {
 107 
 108  public:
 109 
 110   static int emit_exception_handler(CodeBuffer &cbuf);
 111   static int emit_deopt_handler(CodeBuffer& cbuf);
 112 
 113   static uint size_exception_handler() {
 114 #ifdef AARCH64
 115     // ldr_literal; br; (pad); <literal>
 116     return 3 * Assembler::InstructionSize + wordSize;
 117 #else
 118     return ( 3 * 4 );
 119 #endif
 120   }
 121 
 122 
 123   static uint size_deopt_handler() {
 124     return ( 9 * 4 );
 125   }
 126 
 127 };
 128 
 129 %}
 130 
 131 source %{
 132 #define __ _masm.
 133 
 134 static FloatRegister reg_to_FloatRegister_object(int register_encoding);
 135 static Register reg_to_register_object(int register_encoding);
 136 
 137 
 138 // ****************************************************************************
 139 
 140 // REQUIRED FUNCTIONALITY
 141 
 142 // Indicate if the safepoint node needs the polling page as an input.
 143 // Since ARM does not have absolute addressing, it does.
 144 bool SafePointNode::needs_polling_address_input() {
 145   return true;
 146 }
 147 
 148 // emit an interrupt that is caught by the debugger (for debugging compiler)
 149 void emit_break(CodeBuffer &cbuf) {
 150   MacroAssembler _masm(&cbuf);
 151   __ breakpoint();
 152 }
 153 
 154 #ifndef PRODUCT
 155 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream *st ) const {
 156   st->print("TA");
 157 }
 158 #endif
 159 
 160 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 161   emit_break(cbuf);
 162 }
 163 
 164 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
 165   return MachNode::size(ra_);
 166 }
 167 
 168 
 169 void emit_nop(CodeBuffer &cbuf) {
 170   MacroAssembler _masm(&cbuf);
 171   __ nop();
 172 }
 173 
 174 
 175 void emit_call_reloc(CodeBuffer &cbuf, const MachCallNode *n, MachOper *m, RelocationHolder const& rspec) {
 176   int ret_addr_offset0 = n->as_MachCall()->ret_addr_offset();
 177   int call_site_offset = cbuf.insts()->mark_off();
 178   MacroAssembler _masm(&cbuf);
 179   __ set_inst_mark(); // needed in emit_to_interp_stub() to locate the call
 180   address target = (address)m->method();
 181   assert(n->as_MachCall()->entry_point() == target, "sanity");
 182   assert(maybe_far_call(n) == !__ reachable_from_cache(target), "sanity");
 183   assert(cache_reachable() == __ cache_fully_reachable(), "sanity");
 184 
 185   assert(target != NULL, "need real address");
 186 
 187   int ret_addr_offset = -1;
 188   if (rspec.type() == relocInfo::runtime_call_type) {
 189     __ call(target, rspec);
 190     ret_addr_offset = __ offset();
 191   } else {
 192     // scratches Rtemp
 193     ret_addr_offset = __ patchable_call(target, rspec, true);
 194   }
 195   assert(ret_addr_offset - call_site_offset == ret_addr_offset0, "fix ret_addr_offset()");
 196 }
 197 
 198 //=============================================================================
 199 // REQUIRED FUNCTIONALITY for encoding
 200 void emit_lo(CodeBuffer &cbuf, int val) {  }
 201 void emit_hi(CodeBuffer &cbuf, int val) {  }
 202 
 203 
 204 //=============================================================================
 205 const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask();
 206 
 207 int Compile::ConstantTable::calculate_table_base_offset() const {
 208 #ifdef AARCH64
 209   return 0;
 210 #else
 211   int offset = -(size() / 2);
 212   // flds, fldd: 8-bit  offset multiplied by 4: +/- 1024
 213   // ldr, ldrb : 12-bit offset:                 +/- 4096
 214   if (!Assembler::is_simm10(offset)) {
 215     offset = Assembler::min_simm10();
 216   }
 217   return offset;
 218 #endif
 219 }
 220 
 221 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
 222 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
 223   ShouldNotReachHere();
 224 }
 225 
 226 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
 227   Compile* C = ra_->C;
 228   Compile::ConstantTable& constant_table = C->constant_table();
 229   MacroAssembler _masm(&cbuf);
 230 
 231   Register r = as_Register(ra_->get_encode(this));
 232   CodeSection* consts_section = __ code()->consts();
 233   int consts_size = consts_section->align_at_start(consts_section->size());
 234   assert(constant_table.size() == consts_size, "must be: %d == %d", constant_table.size(), consts_size);
 235 
 236   // Materialize the constant table base.
 237   address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
 238   RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
 239   __ mov_address(r, baseaddr, rspec);
 240 }
 241 
 242 uint MachConstantBaseNode::size(PhaseRegAlloc*) const {
 243 #ifdef AARCH64
 244   return 5 * Assembler::InstructionSize;
 245 #else
 246   return 8;
 247 #endif
 248 }
 249 
 250 #ifndef PRODUCT
 251 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
 252   char reg[128];
 253   ra_->dump_register(this, reg);
 254   st->print("MOV_SLOW    &constanttable,%s\t! constant table base", reg);
 255 }
 256 #endif
 257 
 258 #ifndef PRODUCT
 259 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
 260   Compile* C = ra_->C;
 261 
 262   for (int i = 0; i < OptoPrologueNops; i++) {
 263     st->print_cr("NOP"); st->print("\t");
 264   }
 265 #ifdef AARCH64
 266   if (OptoPrologueNops <= 0) {
 267     st->print_cr("NOP\t! required for safe patching");
 268     st->print("\t");
 269   }
 270 #endif
 271 
 272   size_t framesize = C->frame_size_in_bytes();
 273   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
 274   int bangsize = C->bang_size_in_bytes();
 275   // Remove two words for return addr and rbp,
 276   framesize -= 2*wordSize;
 277   bangsize -= 2*wordSize;
 278 
 279   // Calls to C2R adapters often do not accept exceptional returns.
 280   // We require that their callers must bang for them.  But be careful, because
 281   // some VM calls (such as call site linkage) can use several kilobytes of
 282   // stack.  But the stack safety zone should account for that.
 283   // See bugs 4446381, 4468289, 4497237.
 284   if (C->need_stack_bang(bangsize)) {
 285     st->print_cr("! stack bang (%d bytes)", bangsize); st->print("\t");
 286   }
 287   st->print_cr("PUSH   R_FP|R_LR_LR"); st->print("\t");
 288   if (framesize != 0) {
 289     st->print   ("SUB    R_SP, R_SP, " SIZE_FORMAT,framesize);
 290   }
 291 }
 292 #endif
 293 
 294 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 295   Compile* C = ra_->C;
 296   MacroAssembler _masm(&cbuf);
 297 
 298   for (int i = 0; i < OptoPrologueNops; i++) {
 299     __ nop();
 300   }
 301 #ifdef AARCH64
 302   if (OptoPrologueNops <= 0) {
 303     __ nop(); // required for safe patching by patch_verified_entry()
 304   }
 305 #endif
 306 
 307   size_t framesize = C->frame_size_in_bytes();
 308   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
 309   int bangsize = C->bang_size_in_bytes();
 310   // Remove two words for return addr and fp,
 311   framesize -= 2*wordSize;
 312   bangsize -= 2*wordSize;
 313 
 314   // Calls to C2R adapters often do not accept exceptional returns.
 315   // We require that their callers must bang for them.  But be careful, because
 316   // some VM calls (such as call site linkage) can use several kilobytes of
 317   // stack.  But the stack safety zone should account for that.
 318   // See bugs 4446381, 4468289, 4497237.
 319   if (C->need_stack_bang(bangsize)) {
 320     __ arm_stack_overflow_check(bangsize, Rtemp);
 321   }
 322 
 323   __ raw_push(FP, LR);
 324   if (framesize != 0) {
 325     __ sub_slow(SP, SP, framesize);
 326   }
 327 
 328   // offset from scratch buffer is not valid
 329   if (strcmp(cbuf.name(), "Compile::Fill_buffer") == 0) {
 330     C->set_frame_complete( __ offset() );
 331   }
 332 
 333   if (C->has_mach_constant_base_node()) {
 334     // NOTE: We set the table base offset here because users might be
 335     // emitted before MachConstantBaseNode.
 336     Compile::ConstantTable& constant_table = C->constant_table();
 337     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
 338   }
 339 }
 340 
 341 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
 342   return MachNode::size(ra_);
 343 }
 344 
 345 int MachPrologNode::reloc() const {
 346   return 10; // a large enough number
 347 }
 348 
 349 //=============================================================================
 350 #ifndef PRODUCT
 351 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
 352   Compile* C = ra_->C;
 353 
 354   size_t framesize = C->frame_size_in_bytes();
 355   framesize -= 2*wordSize;
 356 
 357   if (framesize != 0) {
 358     st->print("ADD    R_SP, R_SP, " SIZE_FORMAT "\n\t",framesize);
 359   }
 360   st->print("POP    R_FP|R_LR_LR");
 361 
 362   if (do_polling() && ra_->C->is_method_compilation()) {
 363     st->print("\n\t");
 364 #ifdef AARCH64
 365     if (MacroAssembler::page_reachable_from_cache(os::get_polling_page())) {
 366       st->print("ADRP     Rtemp, #PollAddr\t! Load Polling address\n\t");
 367       st->print("LDR      ZR,[Rtemp + #PollAddr & 0xfff]\t!Poll for Safepointing");
 368     } else {
 369       st->print("mov_slow Rtemp, #PollAddr\t! Load Polling address\n\t");
 370       st->print("LDR      ZR,[Rtemp]\t!Poll for Safepointing");
 371     }
 372 #else
 373     st->print("MOV    Rtemp, #PollAddr\t! Load Polling address\n\t");
 374     st->print("LDR    Rtemp,[Rtemp]\t!Poll for Safepointing");
 375 #endif
 376   }
 377 }
 378 #endif
 379 
 380 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 381   MacroAssembler _masm(&cbuf);
 382   Compile* C = ra_->C;
 383 
 384   size_t framesize = C->frame_size_in_bytes();
 385   framesize -= 2*wordSize;
 386   if (framesize != 0) {
 387     __ add_slow(SP, SP, framesize);
 388   }
 389   __ raw_pop(FP, LR);
 390 
 391   // If this does safepoint polling, then do it here
 392   if (do_polling() && ra_->C->is_method_compilation()) {
 393 #ifdef AARCH64
 394     if (false && MacroAssembler::page_reachable_from_cache(os::get_polling_page())) {
 395 /* FIXME: TODO
 396       __ relocate(relocInfo::xxx);
 397       __ adrp(Rtemp, (intptr_t)os::get_polling_page());
 398       __ relocate(relocInfo::poll_return_type);
 399       int offset = os::get_polling_page() & 0xfff;
 400       __ ldr(ZR, Address(Rtemp + offset));
 401 */
 402     } else {
 403       __ mov_address(Rtemp, (address)os::get_polling_page(), symbolic_Relocation::polling_page_reference);
 404       __ relocate(relocInfo::poll_return_type);
 405       __ ldr(ZR, Address(Rtemp));
 406     }
 407 #else
 408     // mov_slow here is usually one or two instruction
 409     __ mov_address(Rtemp, (address)os::get_polling_page(), symbolic_Relocation::polling_page_reference);
 410     __ relocate(relocInfo::poll_return_type);
 411     __ ldr(Rtemp, Address(Rtemp));
 412 #endif
 413   }
 414 }
 415 
 416 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
 417 #ifdef AARCH64
 418   // allow for added alignment nop from mov_address bind_literal
 419   return MachNode::size(ra_) + 1 * Assembler::InstructionSize;
 420 #else
 421   return MachNode::size(ra_);
 422 #endif
 423 }
 424 
 425 int MachEpilogNode::reloc() const {
 426   return 16; // a large enough number
 427 }
 428 
 429 const Pipeline * MachEpilogNode::pipeline() const {
 430   return MachNode::pipeline_class();
 431 }
 432 
 433 int MachEpilogNode::safepoint_offset() const {
 434   assert( do_polling(), "no return for this epilog node");
 435   //  return MacroAssembler::size_of_sethi(os::get_polling_page());
 436   Unimplemented();
 437   return 0;
 438 }
 439 
 440 //=============================================================================
 441 
 442 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
 443 enum RC { rc_bad, rc_int, rc_float, rc_stack };
 444 static enum RC rc_class( OptoReg::Name reg ) {
 445   if (!OptoReg::is_valid(reg)) return rc_bad;
 446   if (OptoReg::is_stack(reg)) return rc_stack;
 447   VMReg r = OptoReg::as_VMReg(reg);
 448   if (r->is_Register()) return rc_int;
 449   assert(r->is_FloatRegister(), "must be");
 450   return rc_float;
 451 }
 452 
 453 static inline bool is_iRegLd_memhd(OptoReg::Name src_first, OptoReg::Name src_second, int offset) {
 454 #ifdef AARCH64
 455   return is_memoryHD(offset);
 456 #else
 457   int rlo = Matcher::_regEncode[src_first];
 458   int rhi = Matcher::_regEncode[src_second];
 459   if (!((rlo&1)==0 && (rlo+1 == rhi))) {
 460     tty->print_cr("CAUGHT BAD LDRD/STRD");
 461   }
 462   return (rlo&1)==0 && (rlo+1 == rhi) && is_memoryHD(offset);
 463 #endif
 464 }
 465 
 466 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
 467                                         PhaseRegAlloc *ra_,
 468                                         bool do_size,
 469                                         outputStream* st ) const {
 470   // Get registers to move
 471   OptoReg::Name src_second = ra_->get_reg_second(in(1));
 472   OptoReg::Name src_first = ra_->get_reg_first(in(1));
 473   OptoReg::Name dst_second = ra_->get_reg_second(this );
 474   OptoReg::Name dst_first = ra_->get_reg_first(this );
 475 
 476   enum RC src_second_rc = rc_class(src_second);
 477   enum RC src_first_rc = rc_class(src_first);
 478   enum RC dst_second_rc = rc_class(dst_second);
 479   enum RC dst_first_rc = rc_class(dst_first);
 480 
 481   assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
 482 
 483   // Generate spill code!
 484   int size = 0;
 485 
 486   if (src_first == dst_first && src_second == dst_second)
 487     return size;            // Self copy, no move
 488 
 489 #ifdef TODO
 490   if (bottom_type()->isa_vect() != NULL) {
 491   }
 492 #endif
 493 
 494   // Shared code does not expect instruction set capability based bailouts here.
 495   // Handle offset unreachable bailout with minimal change in shared code.
 496   // Bailout only for real instruction emit.
 497   // This requires a single comment change in shared code. ( see output.cpp "Normal" instruction case )
 498 
 499   MacroAssembler _masm(cbuf);
 500 
 501   // --------------------------------------
 502   // Check for mem-mem move.  Load into unused float registers and fall into
 503   // the float-store case.
 504   if (src_first_rc == rc_stack && dst_first_rc == rc_stack) {
 505     int offset = ra_->reg2offset(src_first);
 506     if (cbuf && !is_memoryfp(offset)) {
 507       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 508       return 0;
 509     } else {
 510       if (src_second_rc != rc_bad) {
 511         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
 512         src_first     = OptoReg::Name(R_mem_copy_lo_num);
 513         src_second    = OptoReg::Name(R_mem_copy_hi_num);
 514         src_first_rc  = rc_float;
 515         src_second_rc = rc_float;
 516         if (cbuf) {
 517           __ ldr_double(Rmemcopy, Address(SP, offset));
 518         } else if (!do_size) {
 519           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
 520         }
 521       } else {
 522         src_first     = OptoReg::Name(R_mem_copy_lo_num);
 523         src_first_rc  = rc_float;
 524         if (cbuf) {
 525           __ ldr_float(Rmemcopy, Address(SP, offset));
 526         } else if (!do_size) {
 527           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
 528         }
 529       }
 530       size += 4;
 531     }
 532   }
 533 
 534   if (src_second_rc == rc_stack && dst_second_rc == rc_stack) {
 535     Unimplemented();
 536   }
 537 
 538   // --------------------------------------
 539   // Check for integer reg-reg copy
 540   if (src_first_rc == rc_int && dst_first_rc == rc_int) {
 541     // Else normal reg-reg copy
 542     assert( src_second != dst_first, "smashed second before evacuating it" );
 543     if (cbuf) {
 544       __ mov(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
 545 #ifndef PRODUCT
 546     } else if (!do_size) {
 547       st->print("MOV    R_%s, R_%s\t# spill",
 548                 Matcher::regName[dst_first],
 549                 Matcher::regName[src_first]);
 550 #endif
 551     }
 552 #ifdef AARCH64
 553     if (src_first+1 == src_second && dst_first+1 == dst_second) {
 554       return size + 4;
 555     }
 556 #endif
 557     size += 4;
 558   }
 559 
 560   // Check for integer store
 561   if (src_first_rc == rc_int && dst_first_rc == rc_stack) {
 562     int offset = ra_->reg2offset(dst_first);
 563     if (cbuf && !is_memoryI(offset)) {
 564       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 565       return 0;
 566     } else {
 567       if (src_second_rc != rc_bad && is_iRegLd_memhd(src_first, src_second, offset)) {
 568         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
 569         if (cbuf) {
 570           __ str_64(reg_to_register_object(Matcher::_regEncode[src_first]), Address(SP, offset));
 571 #ifndef PRODUCT
 572         } else if (!do_size) {
 573           if (size != 0) st->print("\n\t");
 574           st->print(STR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
 575 #endif
 576         }
 577         return size + 4;
 578       } else {
 579         if (cbuf) {
 580           __ str_32(reg_to_register_object(Matcher::_regEncode[src_first]), Address(SP, offset));
 581 #ifndef PRODUCT
 582         } else if (!do_size) {
 583           if (size != 0) st->print("\n\t");
 584           st->print(STR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
 585 #endif
 586         }
 587       }
 588     }
 589     size += 4;
 590   }
 591 
 592   // Check for integer load
 593   if (dst_first_rc == rc_int && src_first_rc == rc_stack) {
 594     int offset = ra_->reg2offset(src_first);
 595     if (cbuf && !is_memoryI(offset)) {
 596       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 597       return 0;
 598     } else {
 599       if (src_second_rc != rc_bad && is_iRegLd_memhd(dst_first, dst_second, offset)) {
 600         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
 601         if (cbuf) {
 602           __ ldr_64(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
 603 #ifndef PRODUCT
 604         } else if (!do_size) {
 605           if (size != 0) st->print("\n\t");
 606           st->print(LDR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
 607 #endif
 608         }
 609         return size + 4;
 610       } else {
 611         if (cbuf) {
 612           __ ldr_32(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
 613 #ifndef PRODUCT
 614         } else if (!do_size) {
 615           if (size != 0) st->print("\n\t");
 616           st->print(LDR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
 617 #endif
 618         }
 619       }
 620     }
 621     size += 4;
 622   }
 623 
 624   // Check for float reg-reg copy
 625   if (src_first_rc == rc_float && dst_first_rc == rc_float) {
 626     if (src_second_rc != rc_bad) {
 627       assert((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
 628       if (cbuf) {
 629       __ mov_double(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
 630 #ifndef PRODUCT
 631       } else if (!do_size) {
 632         st->print(MOV_DOUBLE "    R_%s, R_%s\t# spill",
 633                   Matcher::regName[dst_first],
 634                   Matcher::regName[src_first]);
 635 #endif
 636       }
 637       return 4;
 638     }
 639     if (cbuf) {
 640       __ mov_float(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
 641 #ifndef PRODUCT
 642     } else if (!do_size) {
 643       st->print(MOV_FLOAT "    R_%s, R_%s\t# spill",
 644                 Matcher::regName[dst_first],
 645                 Matcher::regName[src_first]);
 646 #endif
 647     }
 648     size = 4;
 649   }
 650 
 651   // Check for float store
 652   if (src_first_rc == rc_float && dst_first_rc == rc_stack) {
 653     int offset = ra_->reg2offset(dst_first);
 654     if (cbuf && !is_memoryfp(offset)) {
 655       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 656       return 0;
 657     } else {
 658       // Further check for aligned-adjacent pair, so we can use a double store
 659       if (src_second_rc != rc_bad) {
 660         assert((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers and stack slots must be aligned/contiguous");
 661         if (cbuf) {
 662           __ str_double(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(SP, offset));
 663 #ifndef PRODUCT
 664         } else if (!do_size) {
 665           if (size != 0) st->print("\n\t");
 666           st->print(STR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
 667 #endif
 668         }
 669         return size + 4;
 670       } else {
 671         if (cbuf) {
 672           __ str_float(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(SP, offset));
 673 #ifndef PRODUCT
 674         } else if (!do_size) {
 675           if (size != 0) st->print("\n\t");
 676           st->print(STR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
 677 #endif
 678         }
 679       }
 680     }
 681     size += 4;
 682   }
 683 
 684   // Check for float load
 685   if (dst_first_rc == rc_float && src_first_rc == rc_stack) {
 686     int offset = ra_->reg2offset(src_first);
 687     if (cbuf && !is_memoryfp(offset)) {
 688       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 689       return 0;
 690     } else {
 691       // Further check for aligned-adjacent pair, so we can use a double store
 692       if (src_second_rc != rc_bad) {
 693         assert((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers and stack slots must be aligned/contiguous");
 694         if (cbuf) {
 695           __ ldr_double(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
 696 #ifndef PRODUCT
 697         } else if (!do_size) {
 698           if (size != 0) st->print("\n\t");
 699           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
 700 #endif
 701         }
 702         return size + 4;
 703       } else {
 704         if (cbuf) {
 705           __ ldr_float(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
 706 #ifndef PRODUCT
 707         } else if (!do_size) {
 708           if (size != 0) st->print("\n\t");
 709           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
 710 #endif
 711         }
 712       }
 713     }
 714     size += 4;
 715   }
 716 
 717   // check for int reg -> float reg move
 718   if (src_first_rc == rc_int && dst_first_rc == rc_float) {
 719     // Further check for aligned-adjacent pair, so we can use a single instruction
 720     if (src_second_rc != rc_bad) {
 721       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
 722       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
 723       assert(src_second_rc == rc_int && dst_second_rc == rc_float, "unsupported");
 724       if (cbuf) {
 725 #ifdef AARCH64
 726         __ fmov_dx(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
 727 #else
 728         __ fmdrr(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]), reg_to_register_object(Matcher::_regEncode[src_second]));
 729 #endif
 730 #ifndef PRODUCT
 731       } else if (!do_size) {
 732         if (size != 0) st->print("\n\t");
 733 #ifdef AARCH64
 734         st->print("FMOV_DX   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
 735 #else
 736         st->print("FMDRR   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first), OptoReg::regname(src_second));
 737 #endif
 738 #endif
 739       }
 740       return size + 4;
 741     } else {
 742       if (cbuf) {
 743         __ fmsr(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
 744 #ifndef PRODUCT
 745       } else if (!do_size) {
 746         if (size != 0) st->print("\n\t");
 747         st->print(FMSR "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
 748 #endif
 749       }
 750       size += 4;
 751     }
 752   }
 753 
 754   // check for float reg -> int reg move
 755   if (src_first_rc == rc_float && dst_first_rc == rc_int) {
 756     // Further check for aligned-adjacent pair, so we can use a single instruction
 757     if (src_second_rc != rc_bad) {
 758       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
 759       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
 760       assert(src_second_rc == rc_float && dst_second_rc == rc_int, "unsupported");
 761       if (cbuf) {
 762 #ifdef AARCH64
 763         __ fmov_xd(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
 764 #else
 765         __ fmrrd(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[dst_second]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
 766 #endif
 767 #ifndef PRODUCT
 768       } else if (!do_size) {
 769         if (size != 0) st->print("\n\t");
 770 #ifdef AARCH64
 771         st->print("FMOV_XD R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
 772 #else
 773         st->print("FMRRD   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(dst_second), OptoReg::regname(src_first));
 774 #endif
 775 #endif
 776       }
 777       return size + 4;
 778     } else {
 779       if (cbuf) {
 780         __ fmrs(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
 781 #ifndef PRODUCT
 782       } else if (!do_size) {
 783         if (size != 0) st->print("\n\t");
 784         st->print(FMRS "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
 785 #endif
 786       }
 787       size += 4;
 788     }
 789   }
 790 
 791   // --------------------------------------------------------------------
 792   // Check for hi bits still needing moving.  Only happens for misaligned
 793   // arguments to native calls.
 794   if (src_second == dst_second)
 795     return size;               // Self copy; no move
 796   assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" );
 797 
 798 #ifndef AARCH64
 799   // Check for integer reg-reg copy.  Hi bits are stuck up in the top
 800   // 32-bits of a 64-bit register, but are needed in low bits of another
 801   // register (else it's a hi-bits-to-hi-bits copy which should have
 802   // happened already as part of a 64-bit move)
 803   if (src_second_rc == rc_int && dst_second_rc == rc_int) {
 804     if (cbuf) {
 805       __ mov(reg_to_register_object(Matcher::_regEncode[dst_second]), reg_to_register_object(Matcher::_regEncode[src_second]));
 806 #ifndef PRODUCT
 807     } else if (!do_size) {
 808       if (size != 0) st->print("\n\t");
 809       st->print("MOV    R_%s, R_%s\t# spill high",
 810                 Matcher::regName[dst_second],
 811                 Matcher::regName[src_second]);
 812 #endif
 813     }
 814     return size+4;
 815   }
 816 
 817   // Check for high word integer store
 818   if (src_second_rc == rc_int && dst_second_rc == rc_stack) {
 819     int offset = ra_->reg2offset(dst_second);
 820 
 821     if (cbuf && !is_memoryP(offset)) {
 822       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 823       return 0;
 824     } else {
 825       if (cbuf) {
 826         __ str(reg_to_register_object(Matcher::_regEncode[src_second]), Address(SP, offset));
 827 #ifndef PRODUCT
 828       } else if (!do_size) {
 829         if (size != 0) st->print("\n\t");
 830         st->print("STR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_second), offset);
 831 #endif
 832       }
 833     }
 834     return size + 4;
 835   }
 836 
 837   // Check for high word integer load
 838   if (dst_second_rc == rc_int && src_second_rc == rc_stack) {
 839     int offset = ra_->reg2offset(src_second);
 840     if (cbuf && !is_memoryP(offset)) {
 841       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 842       return 0;
 843     } else {
 844       if (cbuf) {
 845         __ ldr(reg_to_register_object(Matcher::_regEncode[dst_second]), Address(SP, offset));
 846 #ifndef PRODUCT
 847       } else if (!do_size) {
 848         if (size != 0) st->print("\n\t");
 849         st->print("LDR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_second), offset);
 850 #endif
 851       }
 852     }
 853     return size + 4;
 854   }
 855 #endif
 856 
 857   Unimplemented();
 858   return 0; // Mute compiler
 859 }
 860 
 861 #ifndef PRODUCT
 862 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
 863   implementation( NULL, ra_, false, st );
 864 }
 865 #endif
 866 
 867 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 868   implementation( &cbuf, ra_, false, NULL );
 869 }
 870 
 871 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
 872   return implementation( NULL, ra_, true, NULL );
 873 }
 874 
 875 //=============================================================================
 876 #ifndef PRODUCT
 877 void MachNopNode::format( PhaseRegAlloc *, outputStream *st ) const {
 878   st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
 879 }
 880 #endif
 881 
 882 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
 883   MacroAssembler _masm(&cbuf);
 884   for(int i = 0; i < _count; i += 1) {
 885     __ nop();
 886   }
 887 }
 888 
 889 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
 890   return 4 * _count;
 891 }
 892 
 893 
 894 //=============================================================================
 895 #ifndef PRODUCT
 896 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
 897   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
 898   int reg = ra_->get_reg_first(this);
 899   st->print("ADD    %s,R_SP+#%d",Matcher::regName[reg], offset);
 900 }
 901 #endif
 902 
 903 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 904   MacroAssembler _masm(&cbuf);
 905   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
 906   int reg = ra_->get_encode(this);
 907   Register dst = reg_to_register_object(reg);
 908 
 909   if (is_aimm(offset)) {
 910     __ add(dst, SP, offset);
 911   } else {
 912     __ mov_slow(dst, offset);
 913 #ifdef AARCH64
 914     __ add(dst, SP, dst, ex_lsl);
 915 #else
 916     __ add(dst, SP, dst);
 917 #endif
 918   }
 919 }
 920 
 921 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
 922   // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_)
 923   assert(ra_ == ra_->C->regalloc(), "sanity");
 924   return ra_->C->scratch_emit_size(this);
 925 }
 926 
 927 //=============================================================================
 928 #ifndef PRODUCT
 929 #ifdef AARCH64
 930 #define R_RTEMP "R_R16"
 931 #else
 932 #define R_RTEMP "R_R12"
 933 #endif
 934 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
 935   st->print_cr("\nUEP:");
 936   if (UseCompressedClassPointers) {
 937     st->print_cr("\tLDR_w " R_RTEMP ",[R_R0 + oopDesc::klass_offset_in_bytes]\t! Inline cache check");
 938     st->print_cr("\tdecode_klass " R_RTEMP);
 939   } else {
 940     st->print_cr("\tLDR   " R_RTEMP ",[R_R0 + oopDesc::klass_offset_in_bytes]\t! Inline cache check");
 941   }
 942   st->print_cr("\tCMP   " R_RTEMP ",R_R8" );
 943   st->print   ("\tB.NE  SharedRuntime::handle_ic_miss_stub");
 944 }
 945 #endif
 946 
 947 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 948   MacroAssembler _masm(&cbuf);
 949   Register iCache  = reg_to_register_object(Matcher::inline_cache_reg_encode());
 950   assert(iCache == Ricklass, "should be");
 951   Register receiver = R0;
 952 
 953   __ load_klass(Rtemp, receiver);
 954   __ cmp(Rtemp, iCache);
 955 #ifdef AARCH64
 956   Label match;
 957   __ b(match, eq);
 958   __ jump(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type, Rtemp);
 959   __ bind(match);
 960 #else
 961   __ jump(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type, noreg, ne);
 962 #endif
 963 }
 964 
 965 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
 966   return MachNode::size(ra_);
 967 }
 968 
 969 
 970 //=============================================================================
 971 
 972 // Emit exception handler code.
 973 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) {
 974   MacroAssembler _masm(&cbuf);
 975 
 976   address base = __ start_a_stub(size_exception_handler());
 977   if (base == NULL) {
 978     ciEnv::current()->record_failure("CodeCache is full");
 979     return 0;  // CodeBuffer::expand failed
 980   }
 981 
 982   int offset = __ offset();
 983 
 984   // OK to trash LR, because exception blob will kill it
 985   __ jump(OptoRuntime::exception_blob()->entry_point(), relocInfo::runtime_call_type, LR_tmp);
 986 
 987   assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
 988 
 989   __ end_a_stub();
 990 
 991   return offset;
 992 }
 993 
 994 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
 995   // Can't use any of the current frame's registers as we may have deopted
 996   // at a poll and everything can be live.
 997   MacroAssembler _masm(&cbuf);
 998 
 999   address base = __ start_a_stub(size_deopt_handler());
1000   if (base == NULL) {
1001     ciEnv::current()->record_failure("CodeCache is full");
1002     return 0;  // CodeBuffer::expand failed
1003   }
1004 
1005   int offset = __ offset();
1006   address deopt_pc = __ pc();
1007 
1008 #ifdef AARCH64
1009   // See LR saved by caller in sharedRuntime_arm.cpp
1010   // see also hse1 ws
1011   // see also LIR_Assembler::emit_deopt_handler
1012 
1013   __ raw_push(LR, LR); // preserve LR in both slots
1014   __ mov_relative_address(LR, deopt_pc);
1015   __ str(LR, Address(SP, 1 * wordSize)); // save deopt PC
1016   // OK to kill LR, because deopt blob will restore it from SP[0]
1017   __ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, LR_tmp);
1018 #else
1019   __ sub(SP, SP, wordSize); // make room for saved PC
1020   __ push(LR); // save LR that may be live when we get here
1021   __ mov_relative_address(LR, deopt_pc);
1022   __ str(LR, Address(SP, wordSize)); // save deopt PC
1023   __ pop(LR); // restore LR
1024   __ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, noreg);
1025 #endif
1026 
1027   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
1028 
1029   __ end_a_stub();
1030   return offset;
1031 }
1032 
1033 const bool Matcher::match_rule_supported(int opcode) {
1034   if (!has_match_rule(opcode))
1035     return false;
1036 
1037   switch (opcode) {
1038   case Op_PopCountI:
1039   case Op_PopCountL:
1040     if (!UsePopCountInstruction)
1041       return false;
1042     break;
1043   case Op_LShiftCntV:
1044   case Op_RShiftCntV:
1045   case Op_AddVB:
1046   case Op_AddVS:
1047   case Op_AddVI:
1048   case Op_AddVL:
1049   case Op_SubVB:
1050   case Op_SubVS:
1051   case Op_SubVI:
1052   case Op_SubVL:
1053   case Op_MulVS:
1054   case Op_MulVI:
1055   case Op_LShiftVB:
1056   case Op_LShiftVS:
1057   case Op_LShiftVI:
1058   case Op_LShiftVL:
1059   case Op_RShiftVB:
1060   case Op_RShiftVS:
1061   case Op_RShiftVI:
1062   case Op_RShiftVL:
1063   case Op_URShiftVB:
1064   case Op_URShiftVS:
1065   case Op_URShiftVI:
1066   case Op_URShiftVL:
1067   case Op_AndV:
1068   case Op_OrV:
1069   case Op_XorV:
1070     return VM_Version::has_simd();
1071   case Op_LoadVector:
1072   case Op_StoreVector:
1073   case Op_AddVF:
1074   case Op_SubVF:
1075   case Op_MulVF:
1076 #ifdef AARCH64
1077     return VM_Version::has_simd();
1078 #else
1079     return VM_Version::has_vfp() || VM_Version::has_simd();
1080 #endif
1081   case Op_AddVD:
1082   case Op_SubVD:
1083   case Op_MulVD:
1084   case Op_DivVF:
1085   case Op_DivVD:
1086 #ifdef AARCH64
1087     return VM_Version::has_simd();
1088 #else
1089     return VM_Version::has_vfp();
1090 #endif
1091   }
1092 
1093   return true;  // Per default match rules are supported.
1094 }
1095 
1096 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) {
1097 
1098   // TODO
1099   // identify extra cases that we might want to provide match rules for
1100   // e.g. Op_ vector nodes and other intrinsics while guarding with vlen
1101   bool ret_value = match_rule_supported(opcode);
1102   // Add rules here.
1103 
1104   return ret_value;  // Per default match rules are supported.
1105 }
1106 
1107 const bool Matcher::has_predicated_vectors(void) {
1108   return false;
1109 }
1110 
1111 const int Matcher::float_pressure(int default_pressure_threshold) {
1112   return default_pressure_threshold;
1113 }
1114 
1115 int Matcher::regnum_to_fpu_offset(int regnum) {
1116   return regnum - 32; // The FP registers are in the second chunk
1117 }
1118 
1119 // Vector width in bytes
1120 const int Matcher::vector_width_in_bytes(BasicType bt) {
1121   return MaxVectorSize;
1122 }
1123 
1124 // Vector ideal reg corresponding to specified size in bytes
1125 const int Matcher::vector_ideal_reg(int size) {
1126   assert(MaxVectorSize >= size, "");
1127   switch(size) {
1128     case  8: return Op_VecD;
1129     case 16: return Op_VecX;
1130   }
1131   ShouldNotReachHere();
1132   return 0;
1133 }
1134 
1135 const int Matcher::vector_shift_count_ideal_reg(int size) {
1136   return vector_ideal_reg(size);
1137 }
1138 
1139 // Limits on vector size (number of elements) loaded into vector.
1140 const int Matcher::max_vector_size(const BasicType bt) {
1141   assert(is_java_primitive(bt), "only primitive type vectors");
1142   return vector_width_in_bytes(bt)/type2aelembytes(bt);
1143 }
1144 
1145 const int Matcher::min_vector_size(const BasicType bt) {
1146   assert(is_java_primitive(bt), "only primitive type vectors");
1147   return 8/type2aelembytes(bt);
1148 }
1149 
1150 // ARM doesn't support misaligned vectors store/load.
1151 const bool Matcher::misaligned_vectors_ok() {
1152   return false;
1153 }
1154 
1155 // ARM doesn't support AES intrinsics
1156 const bool Matcher::pass_original_key_for_aes() {
1157   return false;
1158 }
1159 
1160 const bool Matcher::convL2FSupported(void) {
1161 #ifdef AARCH64
1162   return true;
1163 #else
1164   return false;
1165 #endif
1166 }
1167 
1168 // Is this branch offset short enough that a short branch can be used?
1169 //
1170 // NOTE: If the platform does not provide any short branch variants, then
1171 //       this method should return false for offset 0.
1172 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
1173   // The passed offset is relative to address of the branch.
1174   // On ARM a branch displacement is calculated relative to address
1175   // of the branch + 8.
1176   //
1177   // offset -= 8;
1178   // return (Assembler::is_simm24(offset));
1179   return false;
1180 }
1181 
1182 const bool Matcher::isSimpleConstant64(jlong value) {
1183   // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
1184 #ifdef AARCH64
1185   return (value == 0);
1186 #else
1187   return false;
1188 #endif
1189 }
1190 
1191 // No scaling for the parameter the ClearArray node.
1192 const bool Matcher::init_array_count_is_in_bytes = true;
1193 
1194 #ifdef AARCH64
1195 const int Matcher::long_cmove_cost() { return 1; }
1196 #else
1197 // Needs 2 CMOV's for longs.
1198 const int Matcher::long_cmove_cost() { return 2; }
1199 #endif
1200 
1201 #ifdef AARCH64
1202 const int Matcher::float_cmove_cost() { return 1; }
1203 #else
1204 // CMOVF/CMOVD are expensive on ARM.
1205 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
1206 #endif
1207 
1208 // Does the CPU require late expand (see block.cpp for description of late expand)?
1209 const bool Matcher::require_postalloc_expand = false;
1210 
1211 // Do we need to mask the count passed to shift instructions or does
1212 // the cpu only look at the lower 5/6 bits anyway?
1213 // FIXME: does this handle vector shifts as well?
1214 #ifdef AARCH64
1215 const bool Matcher::need_masked_shift_count = false;
1216 #else
1217 const bool Matcher::need_masked_shift_count = true;
1218 #endif
1219 
1220 const bool Matcher::convi2l_type_required = true;
1221 
1222 // Should the Matcher clone shifts on addressing modes, expecting them
1223 // to be subsumed into complex addressing expressions or compute them
1224 // into registers?
1225 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
1226   return clone_base_plus_offset_address(m, mstack, address_visited);
1227 }
1228 
1229 void Compile::reshape_address(AddPNode* addp) {
1230 }
1231 
1232 bool Matcher::narrow_oop_use_complex_address() {
1233   NOT_LP64(ShouldNotCallThis());
1234   assert(UseCompressedOops, "only for compressed oops code");
1235   return false;
1236 }
1237 
1238 bool Matcher::narrow_klass_use_complex_address() {
1239   NOT_LP64(ShouldNotCallThis());
1240   assert(UseCompressedClassPointers, "only for compressed klass code");
1241   return false;
1242 }
1243 
1244 bool Matcher::const_oop_prefer_decode() {
1245   NOT_LP64(ShouldNotCallThis());
1246   return true;
1247 }
1248 
1249 bool Matcher::const_klass_prefer_decode() {
1250   NOT_LP64(ShouldNotCallThis());
1251   return true;
1252 }
1253 
1254 // Is it better to copy float constants, or load them directly from memory?
1255 // Intel can load a float constant from a direct address, requiring no
1256 // extra registers.  Most RISCs will have to materialize an address into a
1257 // register first, so they would do better to copy the constant from stack.
1258 const bool Matcher::rematerialize_float_constants = false;
1259 
1260 // If CPU can load and store mis-aligned doubles directly then no fixup is
1261 // needed.  Else we split the double into 2 integer pieces and move it
1262 // piece-by-piece.  Only happens when passing doubles into C code as the
1263 // Java calling convention forces doubles to be aligned.
1264 #ifdef AARCH64
1265 // On stack replacement support:
1266 // We don't need Load[DL]_unaligned support, because interpreter stack
1267 // has correct alignment
1268 const bool Matcher::misaligned_doubles_ok = true;
1269 #else
1270 const bool Matcher::misaligned_doubles_ok = false;
1271 #endif
1272 
1273 // No-op on ARM.
1274 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {
1275 }
1276 
1277 // Advertise here if the CPU requires explicit rounding operations
1278 // to implement the UseStrictFP mode.
1279 const bool Matcher::strict_fp_requires_explicit_rounding = false;
1280 
1281 // Are floats converted to double when stored to stack during deoptimization?
1282 // ARM does not handle callee-save floats.
1283 bool Matcher::float_in_double() {
1284   return false;
1285 }
1286 
1287 // Do ints take an entire long register or just half?
1288 // Note that we if-def off of _LP64.
1289 // The relevant question is how the int is callee-saved.  In _LP64
1290 // the whole long is written but de-opt'ing will have to extract
1291 // the relevant 32 bits, in not-_LP64 only the low 32 bits is written.
1292 #ifdef _LP64
1293 const bool Matcher::int_in_long = true;
1294 #else
1295 const bool Matcher::int_in_long = false;
1296 #endif
1297 
1298 // Return whether or not this register is ever used as an argument.  This
1299 // function is used on startup to build the trampoline stubs in generateOptoStub.
1300 // Registers not mentioned will be killed by the VM call in the trampoline, and
1301 // arguments in those registers not be available to the callee.
1302 bool Matcher::can_be_java_arg( int reg ) {
1303 #ifdef AARCH64
1304   if (reg >= R_R0_num && reg < R_R8_num) return true;
1305   if (reg >= R_V0_num && reg <= R_V7b_num && ((reg & 3) < 2)) return true;
1306 #else
1307   if (reg == R_R0_num ||
1308       reg == R_R1_num ||
1309       reg == R_R2_num ||
1310       reg == R_R3_num) return true;
1311 
1312   if (reg >= R_S0_num &&
1313       reg <= R_S13_num) return true;
1314 #endif
1315   return false;
1316 }
1317 
1318 bool Matcher::is_spillable_arg( int reg ) {
1319   return can_be_java_arg(reg);
1320 }
1321 
1322 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
1323   return false;
1324 }
1325 
1326 // Register for DIVI projection of divmodI
1327 RegMask Matcher::divI_proj_mask() {
1328   ShouldNotReachHere();
1329   return RegMask();
1330 }
1331 
1332 // Register for MODI projection of divmodI
1333 RegMask Matcher::modI_proj_mask() {
1334   ShouldNotReachHere();
1335   return RegMask();
1336 }
1337 
1338 // Register for DIVL projection of divmodL
1339 RegMask Matcher::divL_proj_mask() {
1340   ShouldNotReachHere();
1341   return RegMask();
1342 }
1343 
1344 // Register for MODL projection of divmodL
1345 RegMask Matcher::modL_proj_mask() {
1346   ShouldNotReachHere();
1347   return RegMask();
1348 }
1349 
1350 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
1351   return FP_REGP_mask();
1352 }
1353 
1354 bool maybe_far_call(const CallNode *n) {
1355   return !MacroAssembler::_reachable_from_cache(n->as_Call()->entry_point());
1356 }
1357 
1358 bool maybe_far_call(const MachCallNode *n) {
1359   return !MacroAssembler::_reachable_from_cache(n->as_MachCall()->entry_point());
1360 }
1361 
1362 %}
1363 
1364 //----------ENCODING BLOCK-----------------------------------------------------
1365 // This block specifies the encoding classes used by the compiler to output
1366 // byte streams.  Encoding classes are parameterized macros used by
1367 // Machine Instruction Nodes in order to generate the bit encoding of the
1368 // instruction.  Operands specify their base encoding interface with the
1369 // interface keyword.  There are currently supported four interfaces,
1370 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
1371 // operand to generate a function which returns its register number when
1372 // queried.   CONST_INTER causes an operand to generate a function which
1373 // returns the value of the constant when queried.  MEMORY_INTER causes an
1374 // operand to generate four functions which return the Base Register, the
1375 // Index Register, the Scale Value, and the Offset Value of the operand when
1376 // queried.  COND_INTER causes an operand to generate six functions which
1377 // return the encoding code (ie - encoding bits for the instruction)
1378 // associated with each basic boolean condition for a conditional instruction.
1379 //
1380 // Instructions specify two basic values for encoding.  Again, a function
1381 // is available to check if the constant displacement is an oop. They use the
1382 // ins_encode keyword to specify their encoding classes (which must be
1383 // a sequence of enc_class names, and their parameters, specified in
1384 // the encoding block), and they use the
1385 // opcode keyword to specify, in order, their primary, secondary, and
1386 // tertiary opcode.  Only the opcode sections which a particular instruction
1387 // needs for encoding need to be specified.
1388 encode %{
1389   enc_class call_epilog %{
1390     // nothing
1391   %}
1392 
1393   enc_class Java_To_Runtime (method meth) %{
1394     // CALL directly to the runtime
1395     emit_call_reloc(cbuf, as_MachCall(), $meth, runtime_call_Relocation::spec());
1396   %}
1397 
1398   enc_class Java_Static_Call (method meth) %{
1399     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
1400     // who we intended to call.
1401 
1402     if ( !_method) {
1403       emit_call_reloc(cbuf, as_MachCall(), $meth, runtime_call_Relocation::spec());
1404     } else {
1405       int method_index = resolved_method_index(cbuf);
1406       RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
1407                                                   : static_call_Relocation::spec(method_index);
1408       emit_call_reloc(cbuf, as_MachCall(), $meth, rspec);
1409 
1410       // Emit stubs for static call.
1411       address stub = CompiledStaticCall::emit_to_interp_stub(cbuf);
1412       if (stub == NULL) {
1413         ciEnv::current()->record_failure("CodeCache is full");
1414         return;
1415       }
1416     }
1417   %}
1418 
1419   enc_class save_last_PC %{
1420     // preserve mark
1421     address mark = cbuf.insts()->mark();
1422     debug_only(int off0 = cbuf.insts_size());
1423     MacroAssembler _masm(&cbuf);
1424     int ret_addr_offset = as_MachCall()->ret_addr_offset();
1425     __ adr(LR, mark + ret_addr_offset);
1426     __ str(LR, Address(Rthread, JavaThread::last_Java_pc_offset()));
1427     debug_only(int off1 = cbuf.insts_size());
1428     assert(off1 - off0 == 2 * Assembler::InstructionSize, "correct size prediction");
1429     // restore mark
1430     cbuf.insts()->set_mark(mark);
1431   %}
1432 
1433   enc_class preserve_SP %{
1434     // preserve mark
1435     address mark = cbuf.insts()->mark();
1436     debug_only(int off0 = cbuf.insts_size());
1437     MacroAssembler _masm(&cbuf);
1438     // FP is preserved across all calls, even compiled calls.
1439     // Use it to preserve SP in places where the callee might change the SP.
1440     __ mov(Rmh_SP_save, SP);
1441     debug_only(int off1 = cbuf.insts_size());
1442     assert(off1 - off0 == 4, "correct size prediction");
1443     // restore mark
1444     cbuf.insts()->set_mark(mark);
1445   %}
1446 
1447   enc_class restore_SP %{
1448     MacroAssembler _masm(&cbuf);
1449     __ mov(SP, Rmh_SP_save);
1450   %}
1451 
1452   enc_class Java_Dynamic_Call (method meth) %{
1453     MacroAssembler _masm(&cbuf);
1454     Register R8_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode());
1455     assert(R8_ic_reg == Ricklass, "should be");
1456     __ set_inst_mark();
1457 #ifdef AARCH64
1458 // TODO: see C1 LIR_Assembler::ic_call()
1459     InlinedAddress oop_literal((address)Universe::non_oop_word());
1460     int offset = __ offset();
1461     int fixed_size = mov_oop_size * 4;
1462     if (VM_Version::prefer_moves_over_load_literal()) {
1463       uintptr_t val = (uintptr_t)Universe::non_oop_word();
1464       __ movz(R8_ic_reg, (val >>  0) & 0xffff,  0);
1465       __ movk(R8_ic_reg, (val >> 16) & 0xffff, 16);
1466       __ movk(R8_ic_reg, (val >> 32) & 0xffff, 32);
1467       __ movk(R8_ic_reg, (val >> 48) & 0xffff, 48);
1468     } else {
1469       __ ldr_literal(R8_ic_reg, oop_literal);
1470     }
1471     assert(__ offset() - offset == fixed_size, "bad mov_oop size");
1472 #else
1473     __ movw(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) & 0xffff);
1474     __ movt(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) >> 16);
1475 #endif
1476     address  virtual_call_oop_addr = __ inst_mark();
1477     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
1478     // who we intended to call.
1479     int method_index = resolved_method_index(cbuf);
1480     __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index));
1481     emit_call_reloc(cbuf, as_MachCall(), $meth, RelocationHolder::none);
1482 #ifdef AARCH64
1483     if (!VM_Version::prefer_moves_over_load_literal()) {
1484       Label skip_literal;
1485       __ b(skip_literal);
1486       int off2 = __ offset();
1487       __ bind_literal(oop_literal);
1488       if (__ offset() - off2 == wordSize) {
1489         // no padding, so insert nop for worst-case sizing
1490         __ nop();
1491       }
1492       __ bind(skip_literal);
1493     }
1494 #endif
1495   %}
1496 
1497   enc_class LdReplImmI(immI src, regD dst, iRegI tmp, int cnt, int wth) %{
1498     // FIXME: load from constant table?
1499     // Load a constant replicated "count" times with width "width"
1500     int count = $cnt$$constant;
1501     int width = $wth$$constant;
1502     assert(count*width == 4, "sanity");
1503     int val = $src$$constant;
1504     if (width < 4) {
1505       int bit_width = width * 8;
1506       val &= (((int)1) << bit_width) - 1; // mask off sign bits
1507       for (int i = 0; i < count - 1; i++) {
1508         val |= (val << bit_width);
1509       }
1510     }
1511     MacroAssembler _masm(&cbuf);
1512 
1513     if (val == -1) {
1514       __ mvn($tmp$$Register, 0);
1515     } else if (val == 0) {
1516       __ mov($tmp$$Register, 0);
1517     } else {
1518       __ movw($tmp$$Register, val & 0xffff);
1519       __ movt($tmp$$Register, (unsigned int)val >> 16);
1520     }
1521     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
1522   %}
1523 
1524   enc_class LdReplImmF(immF src, regD dst, iRegI tmp) %{
1525     // Replicate float con 2 times and pack into vector (8 bytes) in regD.
1526     float fval = $src$$constant;
1527     int val = *((int*)&fval);
1528     MacroAssembler _masm(&cbuf);
1529 
1530     if (val == -1) {
1531       __ mvn($tmp$$Register, 0);
1532     } else if (val == 0) {
1533       __ mov($tmp$$Register, 0);
1534     } else {
1535       __ movw($tmp$$Register, val & 0xffff);
1536       __ movt($tmp$$Register, (unsigned int)val >> 16);
1537     }
1538     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
1539   %}
1540 
1541   enc_class enc_String_Compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result, iRegI tmp1, iRegI tmp2) %{
1542     Label Ldone, Lloop;
1543     MacroAssembler _masm(&cbuf);
1544 
1545     Register   str1_reg = $str1$$Register;
1546     Register   str2_reg = $str2$$Register;
1547     Register   cnt1_reg = $cnt1$$Register; // int
1548     Register   cnt2_reg = $cnt2$$Register; // int
1549     Register   tmp1_reg = $tmp1$$Register;
1550     Register   tmp2_reg = $tmp2$$Register;
1551     Register result_reg = $result$$Register;
1552 
1553     assert_different_registers(str1_reg, str2_reg, cnt1_reg, cnt2_reg, tmp1_reg, tmp2_reg);
1554 
1555     // Compute the minimum of the string lengths(str1_reg) and the
1556     // difference of the string lengths (stack)
1557 
1558     // See if the lengths are different, and calculate min in str1_reg.
1559     // Stash diff in tmp2 in case we need it for a tie-breaker.
1560     __ subs_32(tmp2_reg, cnt1_reg, cnt2_reg);
1561 #ifdef AARCH64
1562     Label Lskip;
1563     __ _lsl_w(cnt1_reg, cnt1_reg, exact_log2(sizeof(jchar))); // scale the limit
1564     __ b(Lskip, mi);
1565     __ _lsl_w(cnt1_reg, cnt2_reg, exact_log2(sizeof(jchar))); // scale the limit
1566     __ bind(Lskip);
1567 #else
1568     __ mov(cnt1_reg, AsmOperand(cnt1_reg, lsl, exact_log2(sizeof(jchar)))); // scale the limit
1569     __ mov(cnt1_reg, AsmOperand(cnt2_reg, lsl, exact_log2(sizeof(jchar))), pl); // scale the limit
1570 #endif
1571 
1572     // reallocate cnt1_reg, cnt2_reg, result_reg
1573     // Note:  limit_reg holds the string length pre-scaled by 2
1574     Register limit_reg = cnt1_reg;
1575     Register  chr2_reg = cnt2_reg;
1576     Register  chr1_reg = tmp1_reg;
1577     // str{12} are the base pointers
1578 
1579     // Is the minimum length zero?
1580     __ cmp_32(limit_reg, 0);
1581     if (result_reg != tmp2_reg) {
1582       __ mov(result_reg, tmp2_reg, eq);
1583     }
1584     __ b(Ldone, eq);
1585 
1586     // Load first characters
1587     __ ldrh(chr1_reg, Address(str1_reg, 0));
1588     __ ldrh(chr2_reg, Address(str2_reg, 0));
1589 
1590     // Compare first characters
1591     __ subs(chr1_reg, chr1_reg, chr2_reg);
1592     if (result_reg != chr1_reg) {
1593       __ mov(result_reg, chr1_reg, ne);
1594     }
1595     __ b(Ldone, ne);
1596 
1597     {
1598       // Check after comparing first character to see if strings are equivalent
1599       // Check if the strings start at same location
1600       __ cmp(str1_reg, str2_reg);
1601       // Check if the length difference is zero
1602       __ cond_cmp(tmp2_reg, 0, eq);
1603       __ mov(result_reg, 0, eq); // result is zero
1604       __ b(Ldone, eq);
1605       // Strings might not be equal
1606     }
1607 
1608     __ subs(chr1_reg, limit_reg, 1 * sizeof(jchar));
1609     if (result_reg != tmp2_reg) {
1610       __ mov(result_reg, tmp2_reg, eq);
1611     }
1612     __ b(Ldone, eq);
1613 
1614     // Shift str1_reg and str2_reg to the end of the arrays, negate limit
1615     __ add(str1_reg, str1_reg, limit_reg);
1616     __ add(str2_reg, str2_reg, limit_reg);
1617     __ neg(limit_reg, chr1_reg);  // limit = -(limit-2)
1618 
1619     // Compare the rest of the characters
1620     __ bind(Lloop);
1621     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
1622     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
1623     __ subs(chr1_reg, chr1_reg, chr2_reg);
1624     if (result_reg != chr1_reg) {
1625       __ mov(result_reg, chr1_reg, ne);
1626     }
1627     __ b(Ldone, ne);
1628 
1629     __ adds(limit_reg, limit_reg, sizeof(jchar));
1630     __ b(Lloop, ne);
1631 
1632     // If strings are equal up to min length, return the length difference.
1633     if (result_reg != tmp2_reg) {
1634       __ mov(result_reg, tmp2_reg);
1635     }
1636 
1637     // Otherwise, return the difference between the first mismatched chars.
1638     __ bind(Ldone);
1639   %}
1640 
1641   enc_class enc_String_Equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2) %{
1642     Label Lword_loop, Lpost_word, Lchar, Lchar_loop, Ldone, Lequal;
1643     MacroAssembler _masm(&cbuf);
1644 
1645     Register   str1_reg = $str1$$Register;
1646     Register   str2_reg = $str2$$Register;
1647     Register    cnt_reg = $cnt$$Register; // int
1648     Register   tmp1_reg = $tmp1$$Register;
1649     Register   tmp2_reg = $tmp2$$Register;
1650     Register result_reg = $result$$Register;
1651 
1652     assert_different_registers(str1_reg, str2_reg, cnt_reg, tmp1_reg, tmp2_reg, result_reg);
1653 
1654     __ cmp(str1_reg, str2_reg); //same char[] ?
1655     __ b(Lequal, eq);
1656 
1657     __ cbz_32(cnt_reg, Lequal); // count == 0
1658 
1659     //rename registers
1660     Register limit_reg = cnt_reg;
1661     Register  chr1_reg = tmp1_reg;
1662     Register  chr2_reg = tmp2_reg;
1663 
1664     __ logical_shift_left(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
1665 
1666     //check for alignment and position the pointers to the ends
1667     __ orr(chr1_reg, str1_reg, str2_reg);
1668     __ tst(chr1_reg, 0x3);
1669 
1670     // notZero means at least one not 4-byte aligned.
1671     // We could optimize the case when both arrays are not aligned
1672     // but it is not frequent case and it requires additional checks.
1673     __ b(Lchar, ne);
1674 
1675     // Compare char[] arrays aligned to 4 bytes.
1676     __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg,
1677                           chr1_reg, chr2_reg, Ldone);
1678 
1679     __ b(Lequal); // equal
1680 
1681     // char by char compare
1682     __ bind(Lchar);
1683     __ mov(result_reg, 0);
1684     __ add(str1_reg, limit_reg, str1_reg);
1685     __ add(str2_reg, limit_reg, str2_reg);
1686     __ neg(limit_reg, limit_reg); //negate count
1687 
1688     // Lchar_loop
1689     __ bind(Lchar_loop);
1690     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
1691     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
1692     __ cmp(chr1_reg, chr2_reg);
1693     __ b(Ldone, ne);
1694     __ adds(limit_reg, limit_reg, sizeof(jchar));
1695     __ b(Lchar_loop, ne);
1696 
1697     __ bind(Lequal);
1698     __ mov(result_reg, 1);  //equal
1699 
1700     __ bind(Ldone);
1701   %}
1702 
1703   enc_class enc_Array_Equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result) %{
1704     Label Lvector, Ldone, Lloop, Lequal;
1705     MacroAssembler _masm(&cbuf);
1706 
1707     Register   ary1_reg = $ary1$$Register;
1708     Register   ary2_reg = $ary2$$Register;
1709     Register   tmp1_reg = $tmp1$$Register;
1710     Register   tmp2_reg = $tmp2$$Register;
1711     Register   tmp3_reg = $tmp3$$Register;
1712     Register result_reg = $result$$Register;
1713 
1714     assert_different_registers(ary1_reg, ary2_reg, tmp1_reg, tmp2_reg, tmp3_reg, result_reg);
1715 
1716     int length_offset  = arrayOopDesc::length_offset_in_bytes();
1717     int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
1718 
1719     // return true if the same array
1720 #ifdef AARCH64
1721     __ cmp(ary1_reg, ary2_reg);
1722     __ b(Lequal, eq);
1723 
1724     __ mov(result_reg, 0);
1725 
1726     __ cbz(ary1_reg, Ldone); // not equal
1727 
1728     __ cbz(ary2_reg, Ldone); // not equal
1729 #else
1730     __ teq(ary1_reg, ary2_reg);
1731     __ mov(result_reg, 1, eq);
1732     __ b(Ldone, eq); // equal
1733 
1734     __ tst(ary1_reg, ary1_reg);
1735     __ mov(result_reg, 0, eq);
1736     __ b(Ldone, eq);    // not equal
1737 
1738     __ tst(ary2_reg, ary2_reg);
1739     __ mov(result_reg, 0, eq);
1740     __ b(Ldone, eq);    // not equal
1741 #endif
1742 
1743     //load the lengths of arrays
1744     __ ldr_s32(tmp1_reg, Address(ary1_reg, length_offset)); // int
1745     __ ldr_s32(tmp2_reg, Address(ary2_reg, length_offset)); // int
1746 
1747     // return false if the two arrays are not equal length
1748 #ifdef AARCH64
1749     __ cmp_w(tmp1_reg, tmp2_reg);
1750     __ b(Ldone, ne);    // not equal
1751 
1752     __ cbz_w(tmp1_reg, Lequal); // zero-length arrays are equal
1753 #else
1754     __ teq_32(tmp1_reg, tmp2_reg);
1755     __ mov(result_reg, 0, ne);
1756     __ b(Ldone, ne);    // not equal
1757 
1758     __ tst(tmp1_reg, tmp1_reg);
1759     __ mov(result_reg, 1, eq);
1760     __ b(Ldone, eq);    // zero-length arrays are equal
1761 #endif
1762 
1763     // load array addresses
1764     __ add(ary1_reg, ary1_reg, base_offset);
1765     __ add(ary2_reg, ary2_reg, base_offset);
1766 
1767     // renaming registers
1768     Register chr1_reg  =  tmp3_reg;   // for characters in ary1
1769     Register chr2_reg  =  tmp2_reg;   // for characters in ary2
1770     Register limit_reg =  tmp1_reg;   // length
1771 
1772     // set byte count
1773     __ logical_shift_left_32(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
1774 
1775     // Compare char[] arrays aligned to 4 bytes.
1776     __ char_arrays_equals(ary1_reg, ary2_reg, limit_reg, result_reg,
1777                           chr1_reg, chr2_reg, Ldone);
1778     __ bind(Lequal);
1779     __ mov(result_reg, 1);  //equal
1780 
1781     __ bind(Ldone);
1782     %}
1783 %}
1784 
1785 //----------FRAME--------------------------------------------------------------
1786 // Definition of frame structure and management information.
1787 //
1788 //  S T A C K   L A Y O U T    Allocators stack-slot number
1789 //                             |   (to get allocators register number
1790 //  G  Owned by    |        |  v    add VMRegImpl::stack0)
1791 //  r   CALLER     |        |
1792 //  o     |        +--------+      pad to even-align allocators stack-slot
1793 //  w     V        |  pad0  |        numbers; owned by CALLER
1794 //  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
1795 //  h     ^        |   in   |  5
1796 //        |        |  args  |  4   Holes in incoming args owned by SELF
1797 //  |     |        |        |  3
1798 //  |     |        +--------+
1799 //  V     |        | old out|      Empty on Intel, window on Sparc
1800 //        |    old |preserve|      Must be even aligned.
1801 //        |     SP-+--------+----> Matcher::_old_SP, 8 (or 16 in LP64)-byte aligned
1802 //        |        |   in   |  3   area for Intel ret address
1803 //     Owned by    |preserve|      Empty on Sparc.
1804 //       SELF      +--------+
1805 //        |        |  pad2  |  2   pad to align old SP
1806 //        |        +--------+  1
1807 //        |        | locks  |  0
1808 //        |        +--------+----> VMRegImpl::stack0, 8 (or 16 in LP64)-byte aligned
1809 //        |        |  pad1  | 11   pad to align new SP
1810 //        |        +--------+
1811 //        |        |        | 10
1812 //        |        | spills |  9   spills
1813 //        V        |        |  8   (pad0 slot for callee)
1814 //      -----------+--------+----> Matcher::_out_arg_limit, unaligned
1815 //        ^        |  out   |  7
1816 //        |        |  args  |  6   Holes in outgoing args owned by CALLEE
1817 //     Owned by    +--------+
1818 //      CALLEE     | new out|  6   Empty on Intel, window on Sparc
1819 //        |    new |preserve|      Must be even-aligned.
1820 //        |     SP-+--------+----> Matcher::_new_SP, even aligned
1821 //        |        |        |
1822 //
1823 // Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
1824 //         known from SELF's arguments and the Java calling convention.
1825 //         Region 6-7 is determined per call site.
1826 // Note 2: If the calling convention leaves holes in the incoming argument
1827 //         area, those holes are owned by SELF.  Holes in the outgoing area
1828 //         are owned by the CALLEE.  Holes should not be nessecary in the
1829 //         incoming area, as the Java calling convention is completely under
1830 //         the control of the AD file.  Doubles can be sorted and packed to
1831 //         avoid holes.  Holes in the outgoing arguments may be nessecary for
1832 //         varargs C calling conventions.
1833 // Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
1834 //         even aligned with pad0 as needed.
1835 //         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
1836 //         region 6-11 is even aligned; it may be padded out more so that
1837 //         the region from SP to FP meets the minimum stack alignment.
1838 
1839 frame %{
1840   // What direction does stack grow in (assumed to be same for native & Java)
1841   stack_direction(TOWARDS_LOW);
1842 
1843   // These two registers define part of the calling convention
1844   // between compiled code and the interpreter.
1845   inline_cache_reg(R_Ricklass);          // Inline Cache Register or Method* for I2C
1846   interpreter_method_oop_reg(R_Rmethod); // Method Oop Register when calling interpreter
1847 
1848   // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
1849   cisc_spilling_operand_name(indOffset);
1850 
1851   // Number of stack slots consumed by a Monitor enter
1852   sync_stack_slots(1 * VMRegImpl::slots_per_word);
1853 
1854   // Compiled code's Frame Pointer
1855 #ifdef AARCH64
1856   frame_pointer(R_SP);
1857 #else
1858   frame_pointer(R_R13);
1859 #endif
1860 
1861   // Stack alignment requirement
1862   stack_alignment(StackAlignmentInBytes);
1863   //  LP64: Alignment size in bytes (128-bit -> 16 bytes)
1864   // !LP64: Alignment size in bytes (64-bit  ->  8 bytes)
1865 
1866   // Number of stack slots between incoming argument block and the start of
1867   // a new frame.  The PROLOG must add this many slots to the stack.  The
1868   // EPILOG must remove this many slots.
1869   // FP + LR
1870   in_preserve_stack_slots(2 * VMRegImpl::slots_per_word);
1871 
1872   // Number of outgoing stack slots killed above the out_preserve_stack_slots
1873   // for calls to C.  Supports the var-args backing area for register parms.
1874   // ADLC doesn't support parsing expressions, so I folded the math by hand.
1875   varargs_C_out_slots_killed( 0);
1876 
1877   // The after-PROLOG location of the return address.  Location of
1878   // return address specifies a type (REG or STACK) and a number
1879   // representing the register number (i.e. - use a register name) or
1880   // stack slot.
1881   // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
1882   // Otherwise, it is above the locks and verification slot and alignment word
1883   return_addr(STACK - 1*VMRegImpl::slots_per_word +
1884               round_to((Compile::current()->in_preserve_stack_slots() +
1885                         Compile::current()->fixed_slots()),
1886                        stack_alignment_in_slots()));
1887 
1888   // Body of function which returns an OptoRegs array locating
1889   // arguments either in registers or in stack slots for calling
1890   // java
1891   calling_convention %{
1892     (void) SharedRuntime::java_calling_convention(sig_bt, regs, length, is_outgoing);
1893 
1894   %}
1895 
1896   // Body of function which returns an OptoRegs array locating
1897   // arguments either in registers or in stack slots for callin
1898   // C.
1899   c_calling_convention %{
1900     // This is obviously always outgoing
1901     (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
1902   %}
1903 
1904   // Location of compiled Java return values.  Same as C
1905   return_value %{
1906     return c2::return_value(ideal_reg);
1907   %}
1908 
1909 %}
1910 
1911 //----------ATTRIBUTES---------------------------------------------------------
1912 //----------Instruction Attributes---------------------------------------------
1913 ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute
1914 ins_attrib ins_size(32);           // Required size attribute (in bits)
1915 ins_attrib ins_short_branch(0);    // Required flag: is this instruction a
1916                                    // non-matching short branch variant of some
1917                                                             // long branch?
1918 
1919 //----------OPERANDS-----------------------------------------------------------
1920 // Operand definitions must precede instruction definitions for correct parsing
1921 // in the ADLC because operands constitute user defined types which are used in
1922 // instruction definitions.
1923 
1924 //----------Simple Operands----------------------------------------------------
1925 // Immediate Operands
1926 // Integer Immediate: 32-bit
1927 operand immI() %{
1928   match(ConI);
1929 
1930   op_cost(0);
1931   // formats are generated automatically for constants and base registers
1932   format %{ %}
1933   interface(CONST_INTER);
1934 %}
1935 
1936 // Integer Immediate: 8-bit unsigned - for VMOV
1937 operand immU8() %{
1938   predicate(0 <= n->get_int() && (n->get_int() <= 255));
1939   match(ConI);
1940   op_cost(0);
1941 
1942   format %{ %}
1943   interface(CONST_INTER);
1944 %}
1945 
1946 // Integer Immediate: 16-bit
1947 operand immI16() %{
1948   predicate((n->get_int() >> 16) == 0 && VM_Version::supports_movw());
1949   match(ConI);
1950   op_cost(0);
1951 
1952   format %{ %}
1953   interface(CONST_INTER);
1954 %}
1955 
1956 #ifndef AARCH64
1957 // Integer Immediate: offset for half and double word loads and stores
1958 operand immIHD() %{
1959   predicate(is_memoryHD(n->get_int()));
1960   match(ConI);
1961   op_cost(0);
1962   format %{ %}
1963   interface(CONST_INTER);
1964 %}
1965 
1966 // Integer Immediate: offset for fp loads and stores
1967 operand immIFP() %{
1968   predicate(is_memoryfp(n->get_int()) && ((n->get_int() & 3) == 0));
1969   match(ConI);
1970   op_cost(0);
1971 
1972   format %{ %}
1973   interface(CONST_INTER);
1974 %}
1975 #endif
1976 
1977 // Valid scale values for addressing modes and shifts
1978 operand immU5() %{
1979   predicate(0 <= n->get_int() && (n->get_int() <= 31));
1980   match(ConI);
1981   op_cost(0);
1982 
1983   format %{ %}
1984   interface(CONST_INTER);
1985 %}
1986 
1987 // Integer Immediate: 6-bit
1988 operand immU6Big() %{
1989   predicate(n->get_int() >= 32 && n->get_int() <= 63);
1990   match(ConI);
1991   op_cost(0);
1992   format %{ %}
1993   interface(CONST_INTER);
1994 %}
1995 
1996 // Integer Immediate: 0-bit
1997 operand immI0() %{
1998   predicate(n->get_int() == 0);
1999   match(ConI);
2000   op_cost(0);
2001 
2002   format %{ %}
2003   interface(CONST_INTER);
2004 %}
2005 
2006 // Integer Immediate: the value 1
2007 operand immI_1() %{
2008   predicate(n->get_int() == 1);
2009   match(ConI);
2010   op_cost(0);
2011 
2012   format %{ %}
2013   interface(CONST_INTER);
2014 %}
2015 
2016 // Integer Immediate: the value 2
2017 operand immI_2() %{
2018   predicate(n->get_int() == 2);
2019   match(ConI);
2020   op_cost(0);
2021 
2022   format %{ %}
2023   interface(CONST_INTER);
2024 %}
2025 
2026 // Integer Immediate: the value 3
2027 operand immI_3() %{
2028   predicate(n->get_int() == 3);
2029   match(ConI);
2030   op_cost(0);
2031 
2032   format %{ %}
2033   interface(CONST_INTER);
2034 %}
2035 
2036 // Integer Immediate: the value 4
2037 operand immI_4() %{
2038   predicate(n->get_int() == 4);
2039   match(ConI);
2040   op_cost(0);
2041 
2042   format %{ %}
2043   interface(CONST_INTER);
2044 %}
2045 
2046 // Integer Immediate: the value 8
2047 operand immI_8() %{
2048   predicate(n->get_int() == 8);
2049   match(ConI);
2050   op_cost(0);
2051 
2052   format %{ %}
2053   interface(CONST_INTER);
2054 %}
2055 
2056 // Int Immediate non-negative
2057 operand immU31()
2058 %{
2059   predicate(n->get_int() >= 0);
2060   match(ConI);
2061 
2062   op_cost(0);
2063   format %{ %}
2064   interface(CONST_INTER);
2065 %}
2066 
2067 // Integer Immediate: the values 32-63
2068 operand immI_32_63() %{
2069   predicate(n->get_int() >= 32 && n->get_int() <= 63);
2070   match(ConI);
2071   op_cost(0);
2072 
2073   format %{ %}
2074   interface(CONST_INTER);
2075 %}
2076 
2077 // Immediates for special shifts (sign extend)
2078 
2079 // Integer Immediate: the value 16
2080 operand immI_16() %{
2081   predicate(n->get_int() == 16);
2082   match(ConI);
2083   op_cost(0);
2084 
2085   format %{ %}
2086   interface(CONST_INTER);
2087 %}
2088 
2089 // Integer Immediate: the value 24
2090 operand immI_24() %{
2091   predicate(n->get_int() == 24);
2092   match(ConI);
2093   op_cost(0);
2094 
2095   format %{ %}
2096   interface(CONST_INTER);
2097 %}
2098 
2099 // Integer Immediate: the value 255
2100 operand immI_255() %{
2101   predicate( n->get_int() == 255 );
2102   match(ConI);
2103   op_cost(0);
2104 
2105   format %{ %}
2106   interface(CONST_INTER);
2107 %}
2108 
2109 // Integer Immediate: the value 65535
2110 operand immI_65535() %{
2111   predicate(n->get_int() == 65535);
2112   match(ConI);
2113   op_cost(0);
2114 
2115   format %{ %}
2116   interface(CONST_INTER);
2117 %}
2118 
2119 // Integer Immediates for arithmetic instructions
2120 
2121 operand aimmI() %{
2122   predicate(is_aimm(n->get_int()));
2123   match(ConI);
2124   op_cost(0);
2125 
2126   format %{ %}
2127   interface(CONST_INTER);
2128 %}
2129 
2130 operand aimmIneg() %{
2131   predicate(is_aimm(-n->get_int()));
2132   match(ConI);
2133   op_cost(0);
2134 
2135   format %{ %}
2136   interface(CONST_INTER);
2137 %}
2138 
2139 operand aimmU31() %{
2140   predicate((0 <= n->get_int()) && is_aimm(n->get_int()));
2141   match(ConI);
2142   op_cost(0);
2143 
2144   format %{ %}
2145   interface(CONST_INTER);
2146 %}
2147 
2148 // Integer Immediates for logical instructions
2149 
2150 operand limmI() %{
2151   predicate(is_limmI(n->get_int()));
2152   match(ConI);
2153   op_cost(0);
2154 
2155   format %{ %}
2156   interface(CONST_INTER);
2157 %}
2158 
2159 operand limmIlow8() %{
2160   predicate(is_limmI_low(n->get_int(), 8));
2161   match(ConI);
2162   op_cost(0);
2163 
2164   format %{ %}
2165   interface(CONST_INTER);
2166 %}
2167 
2168 operand limmU31() %{
2169   predicate(0 <= n->get_int() && is_limmI(n->get_int()));
2170   match(ConI);
2171   op_cost(0);
2172 
2173   format %{ %}
2174   interface(CONST_INTER);
2175 %}
2176 
2177 operand limmIn() %{
2178   predicate(is_limmI(~n->get_int()));
2179   match(ConI);
2180   op_cost(0);
2181 
2182   format %{ %}
2183   interface(CONST_INTER);
2184 %}
2185 
2186 #ifdef AARCH64
2187 // Long Immediate: for logical instruction
2188 operand limmL() %{
2189   predicate(is_limmL(n->get_long()));
2190   match(ConL);
2191   op_cost(0);
2192 
2193   format %{ %}
2194   interface(CONST_INTER);
2195 %}
2196 
2197 operand limmLn() %{
2198   predicate(is_limmL(~n->get_long()));
2199   match(ConL);
2200   op_cost(0);
2201 
2202   format %{ %}
2203   interface(CONST_INTER);
2204 %}
2205 
2206 // Long Immediate: for arithmetic instruction
2207 operand aimmL() %{
2208   predicate(is_aimm(n->get_long()));
2209   match(ConL);
2210   op_cost(0);
2211 
2212   format %{ %}
2213   interface(CONST_INTER);
2214 %}
2215 
2216 operand aimmLneg() %{
2217   predicate(is_aimm(-n->get_long()));
2218   match(ConL);
2219   op_cost(0);
2220 
2221   format %{ %}
2222   interface(CONST_INTER);
2223 %}
2224 #endif // AARCH64
2225 
2226 // Long Immediate: the value FF
2227 operand immL_FF() %{
2228   predicate( n->get_long() == 0xFFL );
2229   match(ConL);
2230   op_cost(0);
2231 
2232   format %{ %}
2233   interface(CONST_INTER);
2234 %}
2235 
2236 // Long Immediate: the value FFFF
2237 operand immL_FFFF() %{
2238   predicate( n->get_long() == 0xFFFFL );
2239   match(ConL);
2240   op_cost(0);
2241 
2242   format %{ %}
2243   interface(CONST_INTER);
2244 %}
2245 
2246 // Pointer Immediate: 32 or 64-bit
2247 operand immP() %{
2248   match(ConP);
2249 
2250   op_cost(5);
2251   // formats are generated automatically for constants and base registers
2252   format %{ %}
2253   interface(CONST_INTER);
2254 %}
2255 
2256 operand immP0() %{
2257   predicate(n->get_ptr() == 0);
2258   match(ConP);
2259   op_cost(0);
2260 
2261   format %{ %}
2262   interface(CONST_INTER);
2263 %}
2264 
2265 operand immP_poll() %{
2266   predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
2267   match(ConP);
2268 
2269   // formats are generated automatically for constants and base registers
2270   format %{ %}
2271   interface(CONST_INTER);
2272 %}
2273 
2274 // Pointer Immediate
2275 operand immN()
2276 %{
2277   match(ConN);
2278 
2279   op_cost(10);
2280   format %{ %}
2281   interface(CONST_INTER);
2282 %}
2283 
2284 operand immNKlass()
2285 %{
2286   match(ConNKlass);
2287 
2288   op_cost(10);
2289   format %{ %}
2290   interface(CONST_INTER);
2291 %}
2292 
2293 // NULL Pointer Immediate
2294 operand immN0()
2295 %{
2296   predicate(n->get_narrowcon() == 0);
2297   match(ConN);
2298 
2299   op_cost(0);
2300   format %{ %}
2301   interface(CONST_INTER);
2302 %}
2303 
2304 operand immL() %{
2305   match(ConL);
2306   op_cost(40);
2307   // formats are generated automatically for constants and base registers
2308   format %{ %}
2309   interface(CONST_INTER);
2310 %}
2311 
2312 operand immL0() %{
2313   predicate(n->get_long() == 0L);
2314   match(ConL);
2315   op_cost(0);
2316   // formats are generated automatically for constants and base registers
2317   format %{ %}
2318   interface(CONST_INTER);
2319 %}
2320 
2321 // Long Immediate: 16-bit
2322 operand immL16() %{
2323   predicate(n->get_long() >= 0 && n->get_long() < (1<<16)  && VM_Version::supports_movw());
2324   match(ConL);
2325   op_cost(0);
2326 
2327   format %{ %}
2328   interface(CONST_INTER);
2329 %}
2330 
2331 // Long Immediate: low 32-bit mask
2332 operand immL_32bits() %{
2333   predicate(n->get_long() == 0xFFFFFFFFL);
2334   match(ConL);
2335   op_cost(0);
2336 
2337   format %{ %}
2338   interface(CONST_INTER);
2339 %}
2340 
2341 // Double Immediate
2342 operand immD() %{
2343   match(ConD);
2344 
2345   op_cost(40);
2346   format %{ %}
2347   interface(CONST_INTER);
2348 %}
2349 
2350 // Double Immediate: +0.0d.
2351 operand immD0() %{
2352   predicate(jlong_cast(n->getd()) == 0);
2353 
2354   match(ConD);
2355   op_cost(0);
2356   format %{ %}
2357   interface(CONST_INTER);
2358 %}
2359 
2360 operand imm8D() %{
2361   predicate(Assembler::double_num(n->getd()).can_be_imm8());
2362   match(ConD);
2363 
2364   op_cost(0);
2365   format %{ %}
2366   interface(CONST_INTER);
2367 %}
2368 
2369 // Float Immediate
2370 operand immF() %{
2371   match(ConF);
2372 
2373   op_cost(20);
2374   format %{ %}
2375   interface(CONST_INTER);
2376 %}
2377 
2378 // Float Immediate: +0.0f
2379 operand immF0() %{
2380   predicate(jint_cast(n->getf()) == 0);
2381   match(ConF);
2382 
2383   op_cost(0);
2384   format %{ %}
2385   interface(CONST_INTER);
2386 %}
2387 
2388 // Float Immediate: encoded as 8 bits
2389 operand imm8F() %{
2390   predicate(Assembler::float_num(n->getf()).can_be_imm8());
2391   match(ConF);
2392 
2393   op_cost(0);
2394   format %{ %}
2395   interface(CONST_INTER);
2396 %}
2397 
2398 // Integer Register Operands
2399 // Integer Register
2400 operand iRegI() %{
2401   constraint(ALLOC_IN_RC(int_reg));
2402   match(RegI);
2403   match(R0RegI);
2404   match(R1RegI);
2405   match(R2RegI);
2406   match(R3RegI);
2407 #ifdef AARCH64
2408   match(ZRRegI);
2409 #else
2410   match(R12RegI);
2411 #endif
2412 
2413   format %{ %}
2414   interface(REG_INTER);
2415 %}
2416 
2417 // Pointer Register
2418 operand iRegP() %{
2419   constraint(ALLOC_IN_RC(ptr_reg));
2420   match(RegP);
2421   match(R0RegP);
2422   match(R1RegP);
2423   match(R2RegP);
2424   match(RExceptionRegP);
2425   match(R8RegP);
2426   match(R9RegP);
2427   match(RthreadRegP); // FIXME: move to sp_ptr_RegP?
2428   match(R12RegP);
2429   match(LRRegP);
2430 
2431   match(sp_ptr_RegP);
2432   match(store_ptr_RegP);
2433 
2434   format %{ %}
2435   interface(REG_INTER);
2436 %}
2437 
2438 // GPRs + Rthread + SP
2439 operand sp_ptr_RegP() %{
2440   constraint(ALLOC_IN_RC(sp_ptr_reg));
2441   match(RegP);
2442   match(iRegP);
2443   match(SPRegP); // FIXME: check cost
2444 
2445   format %{ %}
2446   interface(REG_INTER);
2447 %}
2448 
2449 #ifdef AARCH64
2450 // Like sp_ptr_reg, but exclude regs (Aarch64 SP) that can't be
2451 // stored directly.  Includes ZR, so can't be used as a destination.
2452 operand store_ptr_RegP() %{
2453   constraint(ALLOC_IN_RC(store_ptr_reg));
2454   match(RegP);
2455   match(iRegP);
2456   match(ZRRegP);
2457 
2458   format %{ %}
2459   interface(REG_INTER);
2460 %}
2461 
2462 operand store_RegI() %{
2463   constraint(ALLOC_IN_RC(store_reg));
2464   match(RegI);
2465   match(iRegI);
2466   match(ZRRegI);
2467 
2468   format %{ %}
2469   interface(REG_INTER);
2470 %}
2471 
2472 operand store_RegL() %{
2473   constraint(ALLOC_IN_RC(store_ptr_reg));
2474   match(RegL);
2475   match(iRegL);
2476   match(ZRRegL);
2477 
2478   format %{ %}
2479   interface(REG_INTER);
2480 %}
2481 
2482 operand store_RegN() %{
2483   constraint(ALLOC_IN_RC(store_reg));
2484   match(RegN);
2485   match(iRegN);
2486   match(ZRRegN);
2487 
2488   format %{ %}
2489   interface(REG_INTER);
2490 %}
2491 #endif
2492 
2493 operand R0RegP() %{
2494   constraint(ALLOC_IN_RC(R0_regP));
2495   match(iRegP);
2496 
2497   format %{ %}
2498   interface(REG_INTER);
2499 %}
2500 
2501 operand R1RegP() %{
2502   constraint(ALLOC_IN_RC(R1_regP));
2503   match(iRegP);
2504 
2505   format %{ %}
2506   interface(REG_INTER);
2507 %}
2508 
2509 operand R2RegP() %{
2510   constraint(ALLOC_IN_RC(R2_regP));
2511   match(iRegP);
2512 
2513   format %{ %}
2514   interface(REG_INTER);
2515 %}
2516 
2517 operand RExceptionRegP() %{
2518   constraint(ALLOC_IN_RC(Rexception_regP));
2519   match(iRegP);
2520 
2521   format %{ %}
2522   interface(REG_INTER);
2523 %}
2524 
2525 operand RthreadRegP() %{
2526   constraint(ALLOC_IN_RC(Rthread_regP));
2527   match(iRegP);
2528 
2529   format %{ %}
2530   interface(REG_INTER);
2531 %}
2532 
2533 operand IPRegP() %{
2534   constraint(ALLOC_IN_RC(IP_regP));
2535   match(iRegP);
2536 
2537   format %{ %}
2538   interface(REG_INTER);
2539 %}
2540 
2541 operand LRRegP() %{
2542   constraint(ALLOC_IN_RC(LR_regP));
2543   match(iRegP);
2544 
2545   format %{ %}
2546   interface(REG_INTER);
2547 %}
2548 
2549 operand R0RegI() %{
2550   constraint(ALLOC_IN_RC(R0_regI));
2551   match(iRegI);
2552 
2553   format %{ %}
2554   interface(REG_INTER);
2555 %}
2556 
2557 operand R1RegI() %{
2558   constraint(ALLOC_IN_RC(R1_regI));
2559   match(iRegI);
2560 
2561   format %{ %}
2562   interface(REG_INTER);
2563 %}
2564 
2565 operand R2RegI() %{
2566   constraint(ALLOC_IN_RC(R2_regI));
2567   match(iRegI);
2568 
2569   format %{ %}
2570   interface(REG_INTER);
2571 %}
2572 
2573 operand R3RegI() %{
2574   constraint(ALLOC_IN_RC(R3_regI));
2575   match(iRegI);
2576 
2577   format %{ %}
2578   interface(REG_INTER);
2579 %}
2580 
2581 #ifndef AARCH64
2582 operand R12RegI() %{
2583   constraint(ALLOC_IN_RC(R12_regI));
2584   match(iRegI);
2585 
2586   format %{ %}
2587   interface(REG_INTER);
2588 %}
2589 #endif
2590 
2591 // Long Register
2592 operand iRegL() %{
2593   constraint(ALLOC_IN_RC(long_reg));
2594   match(RegL);
2595 #ifdef AARCH64
2596   match(iRegLd);
2597 #else
2598   match(R0R1RegL);
2599   match(R2R3RegL);
2600 #endif
2601 //match(iRegLex);
2602 
2603   format %{ %}
2604   interface(REG_INTER);
2605 %}
2606 
2607 operand iRegLd() %{
2608   constraint(ALLOC_IN_RC(long_reg_align));
2609   match(iRegL); // FIXME: allows unaligned R11/R12?
2610 
2611   format %{ %}
2612   interface(REG_INTER);
2613 %}
2614 
2615 #ifndef AARCH64
2616 // first long arg, or return value
2617 operand R0R1RegL() %{
2618   constraint(ALLOC_IN_RC(R0R1_regL));
2619   match(iRegL);
2620 
2621   format %{ %}
2622   interface(REG_INTER);
2623 %}
2624 
2625 operand R2R3RegL() %{
2626   constraint(ALLOC_IN_RC(R2R3_regL));
2627   match(iRegL);
2628 
2629   format %{ %}
2630   interface(REG_INTER);
2631 %}
2632 #endif
2633 
2634 // Condition Code Flag Register
2635 operand flagsReg() %{
2636   constraint(ALLOC_IN_RC(int_flags));
2637   match(RegFlags);
2638 
2639   format %{ "apsr" %}
2640   interface(REG_INTER);
2641 %}
2642 
2643 // Result of compare to 0 (TST)
2644 operand flagsReg_EQNELTGE() %{
2645   constraint(ALLOC_IN_RC(int_flags));
2646   match(RegFlags);
2647 
2648   format %{ "apsr_EQNELTGE" %}
2649   interface(REG_INTER);
2650 %}
2651 
2652 // Condition Code Register, unsigned comparisons.
2653 operand flagsRegU() %{
2654   constraint(ALLOC_IN_RC(int_flags));
2655   match(RegFlags);
2656 #ifdef TODO
2657   match(RegFlagsP);
2658 #endif
2659 
2660   format %{ "apsr_U" %}
2661   interface(REG_INTER);
2662 %}
2663 
2664 // Condition Code Register, pointer comparisons.
2665 operand flagsRegP() %{
2666   constraint(ALLOC_IN_RC(int_flags));
2667   match(RegFlags);
2668 
2669   format %{ "apsr_P" %}
2670   interface(REG_INTER);
2671 %}
2672 
2673 // Condition Code Register, long comparisons.
2674 #ifndef AARCH64
2675 operand flagsRegL_LTGE() %{
2676   constraint(ALLOC_IN_RC(int_flags));
2677   match(RegFlags);
2678 
2679   format %{ "apsr_L_LTGE" %}
2680   interface(REG_INTER);
2681 %}
2682 
2683 operand flagsRegL_EQNE() %{
2684   constraint(ALLOC_IN_RC(int_flags));
2685   match(RegFlags);
2686 
2687   format %{ "apsr_L_EQNE" %}
2688   interface(REG_INTER);
2689 %}
2690 
2691 operand flagsRegL_LEGT() %{
2692   constraint(ALLOC_IN_RC(int_flags));
2693   match(RegFlags);
2694 
2695   format %{ "apsr_L_LEGT" %}
2696   interface(REG_INTER);
2697 %}
2698 #endif
2699 
2700 // Condition Code Register, floating comparisons, unordered same as "less".
2701 operand flagsRegF() %{
2702   constraint(ALLOC_IN_RC(float_flags));
2703   match(RegFlags);
2704 
2705   format %{ "fpscr_F" %}
2706   interface(REG_INTER);
2707 %}
2708 
2709 // Vectors
2710 operand vecD() %{
2711   constraint(ALLOC_IN_RC(actual_dflt_reg));
2712   match(VecD);
2713 
2714   format %{ %}
2715   interface(REG_INTER);
2716 %}
2717 
2718 operand vecX() %{
2719   constraint(ALLOC_IN_RC(vectorx_reg));
2720   match(VecX);
2721 
2722   format %{ %}
2723   interface(REG_INTER);
2724 %}
2725 
2726 operand regD() %{
2727   constraint(ALLOC_IN_RC(actual_dflt_reg));
2728   match(RegD);
2729   match(regD_low);
2730 
2731   format %{ %}
2732   interface(REG_INTER);
2733 %}
2734 
2735 operand regF() %{
2736   constraint(ALLOC_IN_RC(sflt_reg));
2737   match(RegF);
2738 
2739   format %{ %}
2740   interface(REG_INTER);
2741 %}
2742 
2743 operand regD_low() %{
2744   constraint(ALLOC_IN_RC(dflt_low_reg));
2745   match(RegD);
2746 
2747   format %{ %}
2748   interface(REG_INTER);
2749 %}
2750 
2751 // Special Registers
2752 
2753 // Method Register
2754 operand inline_cache_regP(iRegP reg) %{
2755   constraint(ALLOC_IN_RC(Ricklass_regP));
2756   match(reg);
2757   format %{ %}
2758   interface(REG_INTER);
2759 %}
2760 
2761 operand interpreter_method_oop_regP(iRegP reg) %{
2762   constraint(ALLOC_IN_RC(Rmethod_regP));
2763   match(reg);
2764   format %{ %}
2765   interface(REG_INTER);
2766 %}
2767 
2768 
2769 //----------Complex Operands---------------------------------------------------
2770 // Indirect Memory Reference
2771 operand indirect(sp_ptr_RegP reg) %{
2772   constraint(ALLOC_IN_RC(sp_ptr_reg));
2773   match(reg);
2774 
2775   op_cost(100);
2776   format %{ "[$reg]" %}
2777   interface(MEMORY_INTER) %{
2778     base($reg);
2779 #ifdef AARCH64
2780     index(0xff); // 0xff => no index
2781 #else
2782     index(0xf); // PC => no index
2783 #endif
2784     scale(0x0);
2785     disp(0x0);
2786   %}
2787 %}
2788 
2789 #ifdef AARCH64
2790 // Indirect with scaled*1 uimm12 offset
2791 operand indOffsetU12ScaleB(sp_ptr_RegP reg, immUL12 offset) %{
2792   constraint(ALLOC_IN_RC(sp_ptr_reg));
2793   match(AddP reg offset);
2794 
2795   op_cost(100);
2796   format %{ "[$reg + $offset]" %}
2797   interface(MEMORY_INTER) %{
2798     base($reg);
2799 #ifdef AARCH64
2800     index(0xff); // 0xff => no index
2801 #else
2802     index(0xf); // PC => no index
2803 #endif
2804     scale(0x0);
2805     disp($offset);
2806   %}
2807 %}
2808 
2809 // Indirect with scaled*2 uimm12 offset
2810 operand indOffsetU12ScaleS(sp_ptr_RegP reg, immUL12x2 offset) %{
2811   constraint(ALLOC_IN_RC(sp_ptr_reg));
2812   match(AddP reg offset);
2813 
2814   op_cost(100);
2815   format %{ "[$reg + $offset]" %}
2816   interface(MEMORY_INTER) %{
2817     base($reg);
2818 #ifdef AARCH64
2819     index(0xff); // 0xff => no index
2820 #else
2821     index(0xf); // PC => no index
2822 #endif
2823     scale(0x0);
2824     disp($offset);
2825   %}
2826 %}
2827 
2828 // Indirect with scaled*4 uimm12 offset
2829 operand indOffsetU12ScaleI(sp_ptr_RegP reg, immUL12x4 offset) %{
2830   constraint(ALLOC_IN_RC(sp_ptr_reg));
2831   match(AddP reg offset);
2832 
2833   op_cost(100);
2834   format %{ "[$reg + $offset]" %}
2835   interface(MEMORY_INTER) %{
2836     base($reg);
2837 #ifdef AARCH64
2838     index(0xff); // 0xff => no index
2839 #else
2840     index(0xf); // PC => no index
2841 #endif
2842     scale(0x0);
2843     disp($offset);
2844   %}
2845 %}
2846 
2847 // Indirect with scaled*8 uimm12 offset
2848 operand indOffsetU12ScaleL(sp_ptr_RegP reg, immUL12x8 offset) %{
2849   constraint(ALLOC_IN_RC(sp_ptr_reg));
2850   match(AddP reg offset);
2851 
2852   op_cost(100);
2853   format %{ "[$reg + $offset]" %}
2854   interface(MEMORY_INTER) %{
2855     base($reg);
2856 #ifdef AARCH64
2857     index(0xff); // 0xff => no index
2858 #else
2859     index(0xf); // PC => no index
2860 #endif
2861     scale(0x0);
2862     disp($offset);
2863   %}
2864 %}
2865 
2866 // Indirect with scaled*16 uimm12 offset
2867 operand indOffsetU12ScaleQ(sp_ptr_RegP reg, immUL12x16 offset) %{
2868   constraint(ALLOC_IN_RC(sp_ptr_reg));
2869   match(AddP reg offset);
2870 
2871   op_cost(100);
2872   format %{ "[$reg + $offset]" %}
2873   interface(MEMORY_INTER) %{
2874     base($reg);
2875 #ifdef AARCH64
2876     index(0xff); // 0xff => no index
2877 #else
2878     index(0xf); // PC => no index
2879 #endif
2880     scale(0x0);
2881     disp($offset);
2882   %}
2883 %}
2884 
2885 #else // ! AARCH64
2886 
2887 // Indirect with Offset in ]-4096, 4096[
2888 operand indOffset12(sp_ptr_RegP reg, immI12 offset) %{
2889   constraint(ALLOC_IN_RC(sp_ptr_reg));
2890   match(AddP reg offset);
2891 
2892   op_cost(100);
2893   format %{ "[$reg + $offset]" %}
2894   interface(MEMORY_INTER) %{
2895     base($reg);
2896 #ifdef AARCH64
2897     index(0xff); // 0xff => no index
2898 #else
2899     index(0xf); // PC => no index
2900 #endif
2901     scale(0x0);
2902     disp($offset);
2903   %}
2904 %}
2905 
2906 // Indirect with offset for float load/store
2907 operand indOffsetFP(sp_ptr_RegP reg, immIFP offset) %{
2908   constraint(ALLOC_IN_RC(sp_ptr_reg));
2909   match(AddP reg offset);
2910 
2911   op_cost(100);
2912   format %{ "[$reg + $offset]" %}
2913   interface(MEMORY_INTER) %{
2914     base($reg);
2915 #ifdef AARCH64
2916     index(0xff); // 0xff => no index
2917 #else
2918     index(0xf); // PC => no index
2919 #endif
2920     scale(0x0);
2921     disp($offset);
2922   %}
2923 %}
2924 
2925 // Indirect with Offset for half and double words
2926 operand indOffsetHD(sp_ptr_RegP reg, immIHD offset) %{
2927   constraint(ALLOC_IN_RC(sp_ptr_reg));
2928   match(AddP reg offset);
2929 
2930   op_cost(100);
2931   format %{ "[$reg + $offset]" %}
2932   interface(MEMORY_INTER) %{
2933     base($reg);
2934 #ifdef AARCH64
2935     index(0xff); // 0xff => no index
2936 #else
2937     index(0xf); // PC => no index
2938 #endif
2939     scale(0x0);
2940     disp($offset);
2941   %}
2942 %}
2943 
2944 // Indirect with Offset and Offset+4 in ]-1024, 1024[
2945 operand indOffsetFPx2(sp_ptr_RegP reg, immX10x2 offset) %{
2946   constraint(ALLOC_IN_RC(sp_ptr_reg));
2947   match(AddP reg offset);
2948 
2949   op_cost(100);
2950   format %{ "[$reg + $offset]" %}
2951   interface(MEMORY_INTER) %{
2952     base($reg);
2953 #ifdef AARCH64
2954     index(0xff); // 0xff => no index
2955 #else
2956     index(0xf); // PC => no index
2957 #endif
2958     scale(0x0);
2959     disp($offset);
2960   %}
2961 %}
2962 
2963 // Indirect with Offset and Offset+4 in ]-4096, 4096[
2964 operand indOffset12x2(sp_ptr_RegP reg, immI12x2 offset) %{
2965   constraint(ALLOC_IN_RC(sp_ptr_reg));
2966   match(AddP reg offset);
2967 
2968   op_cost(100);
2969   format %{ "[$reg + $offset]" %}
2970   interface(MEMORY_INTER) %{
2971     base($reg);
2972 #ifdef AARCH64
2973     index(0xff); // 0xff => no index
2974 #else
2975     index(0xf); // PC => no index
2976 #endif
2977     scale(0x0);
2978     disp($offset);
2979   %}
2980 %}
2981 #endif // !AARCH64
2982 
2983 // Indirect with Register Index
2984 operand indIndex(iRegP addr, iRegX index) %{
2985   constraint(ALLOC_IN_RC(ptr_reg));
2986   match(AddP addr index);
2987 
2988   op_cost(100);
2989   format %{ "[$addr + $index]" %}
2990   interface(MEMORY_INTER) %{
2991     base($addr);
2992     index($index);
2993     scale(0x0);
2994     disp(0x0);
2995   %}
2996 %}
2997 
2998 #ifdef AARCH64
2999 // Indirect Memory Times Scale Plus Index Register
3000 operand indIndexScaleS(iRegP addr, iRegX index, immI_1 scale) %{
3001   constraint(ALLOC_IN_RC(ptr_reg));
3002   match(AddP addr (LShiftX index scale));
3003 
3004   op_cost(100);
3005   format %{"[$addr + $index << $scale]" %}
3006   interface(MEMORY_INTER) %{
3007     base($addr);
3008     index($index);
3009     scale($scale);
3010     disp(0x0);
3011   %}
3012 %}
3013 
3014 // Indirect Memory Times Scale Plus 32-bit Index Register
3015 operand indIndexIScaleS(iRegP addr, iRegI index, immI_1 scale) %{
3016   constraint(ALLOC_IN_RC(ptr_reg));
3017   match(AddP addr (LShiftX (ConvI2L index) scale));
3018 
3019   op_cost(100);
3020   format %{"[$addr + $index.w << $scale]" %}
3021   interface(MEMORY_INTER) %{
3022     base($addr);
3023     index($index);
3024     scale($scale);
3025     disp(0x7fffffff); // sxtw
3026   %}
3027 %}
3028 
3029 // Indirect Memory Times Scale Plus Index Register
3030 operand indIndexScaleI(iRegP addr, iRegX index, immI_2 scale) %{
3031   constraint(ALLOC_IN_RC(ptr_reg));
3032   match(AddP addr (LShiftX index scale));
3033 
3034   op_cost(100);
3035   format %{"[$addr + $index << $scale]" %}
3036   interface(MEMORY_INTER) %{
3037     base($addr);
3038     index($index);
3039     scale($scale);
3040     disp(0x0);
3041   %}
3042 %}
3043 
3044 // Indirect Memory Times Scale Plus 32-bit Index Register
3045 operand indIndexIScaleI(iRegP addr, iRegI index, immI_2 scale) %{
3046   constraint(ALLOC_IN_RC(ptr_reg));
3047   match(AddP addr (LShiftX (ConvI2L index) scale));
3048 
3049   op_cost(100);
3050   format %{"[$addr + $index.w << $scale]" %}
3051   interface(MEMORY_INTER) %{
3052     base($addr);
3053     index($index);
3054     scale($scale);
3055     disp(0x7fffffff); // sxtw
3056   %}
3057 %}
3058 
3059 // Indirect Memory Times Scale Plus Index Register
3060 operand indIndexScaleL(iRegP addr, iRegX index, immI_3 scale) %{
3061   constraint(ALLOC_IN_RC(ptr_reg));
3062   match(AddP addr (LShiftX index scale));
3063 
3064   op_cost(100);
3065   format %{"[$addr + $index << $scale]" %}
3066   interface(MEMORY_INTER) %{
3067     base($addr);
3068     index($index);
3069     scale($scale);
3070     disp(0x0);
3071   %}
3072 %}
3073 
3074 // Indirect Memory Times Scale Plus 32-bit Index Register
3075 operand indIndexIScaleL(iRegP addr, iRegI index, immI_3 scale) %{
3076   constraint(ALLOC_IN_RC(ptr_reg));
3077   match(AddP addr (LShiftX (ConvI2L index) scale));
3078 
3079   op_cost(100);
3080   format %{"[$addr + $index.w << $scale]" %}
3081   interface(MEMORY_INTER) %{
3082     base($addr);
3083     index($index);
3084     scale($scale);
3085     disp(0x7fffffff); // sxtw
3086   %}
3087 %}
3088 
3089 // Indirect Memory Times Scale Plus Index Register
3090 operand indIndexScaleQ(iRegP addr, iRegX index, immI_4 scale) %{
3091   constraint(ALLOC_IN_RC(ptr_reg));
3092   match(AddP addr (LShiftX index scale));
3093 
3094   op_cost(100);
3095   format %{"[$addr + $index << $scale]" %}
3096   interface(MEMORY_INTER) %{
3097     base($addr);
3098     index($index);
3099     scale($scale);
3100     disp(0x0);
3101   %}
3102 %}
3103 
3104 // Indirect Memory Times Scale Plus 32-bit Index Register
3105 operand indIndexIScaleQ(iRegP addr, iRegI index, immI_4 scale) %{
3106   constraint(ALLOC_IN_RC(ptr_reg));
3107   match(AddP addr (LShiftX (ConvI2L index) scale));
3108 
3109   op_cost(100);
3110   format %{"[$addr + $index.w << $scale]" %}
3111   interface(MEMORY_INTER) %{
3112     base($addr);
3113     index($index);
3114     scale($scale);
3115     disp(0x7fffffff); // sxtw
3116   %}
3117 %}
3118 #else
3119 // Indirect Memory Times Scale Plus Index Register
3120 operand indIndexScale(iRegP addr, iRegX index, immU5 scale) %{
3121   constraint(ALLOC_IN_RC(ptr_reg));
3122   match(AddP addr (LShiftX index scale));
3123 
3124   op_cost(100);
3125   format %{"[$addr + $index << $scale]" %}
3126   interface(MEMORY_INTER) %{
3127     base($addr);
3128     index($index);
3129     scale($scale);
3130     disp(0x0);
3131   %}
3132 %}
3133 #endif
3134 
3135 // Operands for expressing Control Flow
3136 // NOTE:  Label is a predefined operand which should not be redefined in
3137 //        the AD file.  It is generically handled within the ADLC.
3138 
3139 //----------Conditional Branch Operands----------------------------------------
3140 // Comparison Op  - This is the operation of the comparison, and is limited to
3141 //                  the following set of codes:
3142 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
3143 //
3144 // Other attributes of the comparison, such as unsignedness, are specified
3145 // by the comparison instruction that sets a condition code flags register.
3146 // That result is represented by a flags operand whose subtype is appropriate
3147 // to the unsignedness (etc.) of the comparison.
3148 //
3149 // Later, the instruction which matches both the Comparison Op (a Bool) and
3150 // the flags (produced by the Cmp) specifies the coding of the comparison op
3151 // by matching a specific subtype of Bool operand below, such as cmpOpU.
3152 
3153 operand cmpOp() %{
3154   match(Bool);
3155 
3156   format %{ "" %}
3157   interface(COND_INTER) %{
3158     equal(0x0);
3159     not_equal(0x1);
3160     less(0xb);
3161     greater_equal(0xa);
3162     less_equal(0xd);
3163     greater(0xc);
3164     overflow(0x0); // unsupported/unimplemented
3165     no_overflow(0x0); // unsupported/unimplemented
3166   %}
3167 %}
3168 
3169 // integer comparison with 0, signed
3170 operand cmpOp0() %{
3171   match(Bool);
3172 
3173   format %{ "" %}
3174   interface(COND_INTER) %{
3175     equal(0x0);
3176     not_equal(0x1);
3177     less(0x4);
3178     greater_equal(0x5);
3179     less_equal(0xd); // unsupported
3180     greater(0xc); // unsupported
3181     overflow(0x0); // unsupported/unimplemented
3182     no_overflow(0x0); // unsupported/unimplemented
3183   %}
3184 %}
3185 
3186 // Comparison Op, unsigned
3187 operand cmpOpU() %{
3188   match(Bool);
3189 
3190   format %{ "u" %}
3191   interface(COND_INTER) %{
3192     equal(0x0);
3193     not_equal(0x1);
3194     less(0x3);
3195     greater_equal(0x2);
3196     less_equal(0x9);
3197     greater(0x8);
3198     overflow(0x0); // unsupported/unimplemented
3199     no_overflow(0x0); // unsupported/unimplemented
3200   %}
3201 %}
3202 
3203 // Comparison Op, pointer (same as unsigned)
3204 operand cmpOpP() %{
3205   match(Bool);
3206 
3207   format %{ "p" %}
3208   interface(COND_INTER) %{
3209     equal(0x0);
3210     not_equal(0x1);
3211     less(0x3);
3212     greater_equal(0x2);
3213     less_equal(0x9);
3214     greater(0x8);
3215     overflow(0x0); // unsupported/unimplemented
3216     no_overflow(0x0); // unsupported/unimplemented
3217   %}
3218 %}
3219 
3220 operand cmpOpL() %{
3221   match(Bool);
3222 
3223   format %{ "L" %}
3224   interface(COND_INTER) %{
3225     equal(0x0);
3226     not_equal(0x1);
3227     less(0xb);
3228     greater_equal(0xa);
3229     less_equal(0xd);
3230     greater(0xc);
3231     overflow(0x0); // unsupported/unimplemented
3232     no_overflow(0x0); // unsupported/unimplemented
3233   %}
3234 %}
3235 
3236 operand cmpOpL_commute() %{
3237   match(Bool);
3238 
3239   format %{ "L" %}
3240   interface(COND_INTER) %{
3241     equal(0x0);
3242     not_equal(0x1);
3243     less(0xc);
3244     greater_equal(0xd);
3245     less_equal(0xa);
3246     greater(0xb);
3247     overflow(0x0); // unsupported/unimplemented
3248     no_overflow(0x0); // unsupported/unimplemented
3249   %}
3250 %}
3251 
3252 //----------OPERAND CLASSES----------------------------------------------------
3253 // Operand Classes are groups of operands that are used to simplify
3254 // instruction definitions by not requiring the AD writer to specify separate
3255 // instructions for every form of operand when the instruction accepts
3256 // multiple operand types with the same basic encoding and format.  The classic
3257 // case of this is memory operands.
3258 #ifdef AARCH64
3259 opclass memoryB(indirect, indIndex, indOffsetU12ScaleB);
3260 opclass memoryS(indirect, indIndex, indIndexScaleS, indIndexIScaleS, indOffsetU12ScaleS);
3261 opclass memoryI(indirect, indIndex, indIndexScaleI, indIndexIScaleI, indOffsetU12ScaleI);
3262 opclass memoryL(indirect, indIndex, indIndexScaleL, indIndexIScaleL, indOffsetU12ScaleL);
3263 opclass memoryP(indirect, indIndex, indIndexScaleL, indIndexIScaleL, indOffsetU12ScaleL);
3264 opclass memoryQ(indirect, indIndex, indIndexScaleQ, indIndexIScaleQ, indOffsetU12ScaleQ);
3265 opclass memoryF(indirect, indIndex, indIndexScaleI, indIndexIScaleI, indOffsetU12ScaleI);
3266 opclass memoryD(indirect, indIndex, indIndexScaleL, indIndexIScaleL, indOffsetU12ScaleL);
3267 
3268 opclass memoryScaledS(indIndexScaleS, indIndexIScaleS);
3269 opclass memoryScaledI(indIndexScaleI, indIndexIScaleI);
3270 opclass memoryScaledL(indIndexScaleL, indIndexIScaleL);
3271 opclass memoryScaledP(indIndexScaleL, indIndexIScaleL);
3272 opclass memoryScaledQ(indIndexScaleQ, indIndexIScaleQ);
3273 opclass memoryScaledF(indIndexScaleI, indIndexIScaleI);
3274 opclass memoryScaledD(indIndexScaleL, indIndexIScaleL);
3275 // when ldrex/strex is used:
3276 opclass memoryex ( indirect );
3277 opclass indIndexMemory( indIndex );
3278 opclass memoryvld ( indirect /* , write back mode not implemented */ );
3279 
3280 #else
3281 
3282 opclass memoryI ( indirect, indOffset12, indIndex, indIndexScale );
3283 opclass memoryP ( indirect, indOffset12, indIndex, indIndexScale );
3284 opclass memoryF ( indirect, indOffsetFP );
3285 opclass memoryF2 ( indirect, indOffsetFPx2 );
3286 opclass memoryD ( indirect, indOffsetFP );
3287 opclass memoryfp( indirect, indOffsetFP );
3288 opclass memoryB ( indirect, indIndex, indOffsetHD );
3289 opclass memoryS ( indirect, indIndex, indOffsetHD );
3290 opclass memoryL ( indirect, indIndex, indOffsetHD );
3291 
3292 opclass memoryScaledI(indIndexScale);
3293 opclass memoryScaledP(indIndexScale);
3294 
3295 // when ldrex/strex is used:
3296 opclass memoryex ( indirect );
3297 opclass indIndexMemory( indIndex );
3298 opclass memorylong ( indirect, indOffset12x2 );
3299 opclass memoryvld ( indirect /* , write back mode not implemented */ );
3300 #endif
3301 
3302 //----------PIPELINE-----------------------------------------------------------
3303 pipeline %{
3304 
3305 //----------ATTRIBUTES---------------------------------------------------------
3306 attributes %{
3307   fixed_size_instructions;           // Fixed size instructions
3308   max_instructions_per_bundle = 4;   // Up to 4 instructions per bundle
3309   instruction_unit_size = 4;         // An instruction is 4 bytes long
3310   instruction_fetch_unit_size = 16;  // The processor fetches one line
3311   instruction_fetch_units = 1;       // of 16 bytes
3312 
3313   // List of nop instructions
3314   nops( Nop_A0, Nop_A1, Nop_MS, Nop_FA, Nop_BR );
3315 %}
3316 
3317 //----------RESOURCES----------------------------------------------------------
3318 // Resources are the functional units available to the machine
3319 resources(A0, A1, MS, BR, FA, FM, IDIV, FDIV, IALU = A0 | A1);
3320 
3321 //----------PIPELINE DESCRIPTION-----------------------------------------------
3322 // Pipeline Description specifies the stages in the machine's pipeline
3323 
3324 pipe_desc(A, P, F, B, I, J, S, R, E, C, M, W, X, T, D);
3325 
3326 //----------PIPELINE CLASSES---------------------------------------------------
3327 // Pipeline Classes describe the stages in which input and output are
3328 // referenced by the hardware pipeline.
3329 
3330 // Integer ALU reg-reg operation
3331 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
3332     single_instruction;
3333     dst   : E(write);
3334     src1  : R(read);
3335     src2  : R(read);
3336     IALU  : R;
3337 %}
3338 
3339 // Integer ALU reg-reg long operation
3340 pipe_class ialu_reg_reg_2(iRegL dst, iRegL src1, iRegL src2) %{
3341     instruction_count(2);
3342     dst   : E(write);
3343     src1  : R(read);
3344     src2  : R(read);
3345     IALU  : R;
3346     IALU  : R;
3347 %}
3348 
3349 // Integer ALU reg-reg long dependent operation
3350 pipe_class ialu_reg_reg_2_dep(iRegL dst, iRegL src1, iRegL src2, flagsReg cr) %{
3351     instruction_count(1); multiple_bundles;
3352     dst   : E(write);
3353     src1  : R(read);
3354     src2  : R(read);
3355     cr    : E(write);
3356     IALU  : R(2);
3357 %}
3358 
3359 // Integer ALU reg-imm operaion
3360 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) %{
3361     single_instruction;
3362     dst   : E(write);
3363     src1  : R(read);
3364     IALU  : R;
3365 %}
3366 
3367 // Integer ALU reg-reg operation with condition code
3368 pipe_class ialu_cc_reg_reg(iRegI dst, iRegI src1, iRegI src2, flagsReg cr) %{
3369     single_instruction;
3370     dst   : E(write);
3371     cr    : E(write);
3372     src1  : R(read);
3373     src2  : R(read);
3374     IALU  : R;
3375 %}
3376 
3377 // Integer ALU zero-reg operation
3378 pipe_class ialu_zero_reg(iRegI dst, immI0 zero, iRegI src2) %{
3379     single_instruction;
3380     dst   : E(write);
3381     src2  : R(read);
3382     IALU  : R;
3383 %}
3384 
3385 // Integer ALU zero-reg operation with condition code only
3386 pipe_class ialu_cconly_zero_reg(flagsReg cr, iRegI src) %{
3387     single_instruction;
3388     cr    : E(write);
3389     src   : R(read);
3390     IALU  : R;
3391 %}
3392 
3393 // Integer ALU reg-reg operation with condition code only
3394 pipe_class ialu_cconly_reg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
3395     single_instruction;
3396     cr    : E(write);
3397     src1  : R(read);
3398     src2  : R(read);
3399     IALU  : R;
3400 %}
3401 
3402 // Integer ALU reg-imm operation with condition code only
3403 pipe_class ialu_cconly_reg_imm(flagsReg cr, iRegI src1) %{
3404     single_instruction;
3405     cr    : E(write);
3406     src1  : R(read);
3407     IALU  : R;
3408 %}
3409 
3410 // Integer ALU reg-reg-zero operation with condition code only
3411 pipe_class ialu_cconly_reg_reg_zero(flagsReg cr, iRegI src1, iRegI src2, immI0 zero) %{
3412     single_instruction;
3413     cr    : E(write);
3414     src1  : R(read);
3415     src2  : R(read);
3416     IALU  : R;
3417 %}
3418 
3419 // Integer ALU reg-imm-zero operation with condition code only
3420 pipe_class ialu_cconly_reg_imm_zero(flagsReg cr, iRegI src1, immI0 zero) %{
3421     single_instruction;
3422     cr    : E(write);
3423     src1  : R(read);
3424     IALU  : R;
3425 %}
3426 
3427 // Integer ALU reg-reg operation with condition code, src1 modified
3428 pipe_class ialu_cc_rwreg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
3429     single_instruction;
3430     cr    : E(write);
3431     src1  : E(write);
3432     src1  : R(read);
3433     src2  : R(read);
3434     IALU  : R;
3435 %}
3436 
3437 pipe_class cmpL_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg cr ) %{
3438     multiple_bundles;
3439     dst   : E(write)+4;
3440     cr    : E(write);
3441     src1  : R(read);
3442     src2  : R(read);
3443     IALU  : R(3);
3444     BR    : R(2);
3445 %}
3446 
3447 // Integer ALU operation
3448 pipe_class ialu_none(iRegI dst) %{
3449     single_instruction;
3450     dst   : E(write);
3451     IALU  : R;
3452 %}
3453 
3454 // Integer ALU reg operation
3455 pipe_class ialu_reg(iRegI dst, iRegI src) %{
3456     single_instruction; may_have_no_code;
3457     dst   : E(write);
3458     src   : R(read);
3459     IALU  : R;
3460 %}
3461 
3462 // Integer ALU reg conditional operation
3463 // This instruction has a 1 cycle stall, and cannot execute
3464 // in the same cycle as the instruction setting the condition
3465 // code. We kludge this by pretending to read the condition code
3466 // 1 cycle earlier, and by marking the functional units as busy
3467 // for 2 cycles with the result available 1 cycle later than
3468 // is really the case.
3469 pipe_class ialu_reg_flags( iRegI op2_out, iRegI op2_in, iRegI op1, flagsReg cr ) %{
3470     single_instruction;
3471     op2_out : C(write);
3472     op1     : R(read);
3473     cr      : R(read);       // This is really E, with a 1 cycle stall
3474     BR      : R(2);
3475     MS      : R(2);
3476 %}
3477 
3478 // Integer ALU reg operation
3479 pipe_class ialu_move_reg_L_to_I(iRegI dst, iRegL src) %{
3480     single_instruction; may_have_no_code;
3481     dst   : E(write);
3482     src   : R(read);
3483     IALU  : R;
3484 %}
3485 pipe_class ialu_move_reg_I_to_L(iRegL dst, iRegI src) %{
3486     single_instruction; may_have_no_code;
3487     dst   : E(write);
3488     src   : R(read);
3489     IALU  : R;
3490 %}
3491 
3492 // Two integer ALU reg operations
3493 pipe_class ialu_reg_2(iRegL dst, iRegL src) %{
3494     instruction_count(2);
3495     dst   : E(write);
3496     src   : R(read);
3497     A0    : R;
3498     A1    : R;
3499 %}
3500 
3501 // Two integer ALU reg operations
3502 pipe_class ialu_move_reg_L_to_L(iRegL dst, iRegL src) %{
3503     instruction_count(2); may_have_no_code;
3504     dst   : E(write);
3505     src   : R(read);
3506     A0    : R;
3507     A1    : R;
3508 %}
3509 
3510 // Integer ALU imm operation
3511 pipe_class ialu_imm(iRegI dst) %{
3512     single_instruction;
3513     dst   : E(write);
3514     IALU  : R;
3515 %}
3516 
3517 pipe_class ialu_imm_n(iRegI dst) %{
3518     single_instruction;
3519     dst   : E(write);
3520     IALU  : R;
3521 %}
3522 
3523 // Integer ALU reg-reg with carry operation
3524 pipe_class ialu_reg_reg_cy(iRegI dst, iRegI src1, iRegI src2, iRegI cy) %{
3525     single_instruction;
3526     dst   : E(write);
3527     src1  : R(read);
3528     src2  : R(read);
3529     IALU  : R;
3530 %}
3531 
3532 // Integer ALU cc operation
3533 pipe_class ialu_cc(iRegI dst, flagsReg cc) %{
3534     single_instruction;
3535     dst   : E(write);
3536     cc    : R(read);
3537     IALU  : R;
3538 %}
3539 
3540 // Integer ALU cc / second IALU operation
3541 pipe_class ialu_reg_ialu( iRegI dst, iRegI src ) %{
3542     instruction_count(1); multiple_bundles;
3543     dst   : E(write)+1;
3544     src   : R(read);
3545     IALU  : R;
3546 %}
3547 
3548 // Integer ALU cc / second IALU operation
3549 pipe_class ialu_reg_reg_ialu( iRegI dst, iRegI p, iRegI q ) %{
3550     instruction_count(1); multiple_bundles;
3551     dst   : E(write)+1;
3552     p     : R(read);
3553     q     : R(read);
3554     IALU  : R;
3555 %}
3556 
3557 // Integer ALU hi-lo-reg operation
3558 pipe_class ialu_hi_lo_reg(iRegI dst, immI src) %{
3559     instruction_count(1); multiple_bundles;
3560     dst   : E(write)+1;
3561     IALU  : R(2);
3562 %}
3563 
3564 // Long Constant
3565 pipe_class loadConL( iRegL dst, immL src ) %{
3566     instruction_count(2); multiple_bundles;
3567     dst   : E(write)+1;
3568     IALU  : R(2);
3569     IALU  : R(2);
3570 %}
3571 
3572 // Pointer Constant
3573 pipe_class loadConP( iRegP dst, immP src ) %{
3574     instruction_count(0); multiple_bundles;
3575     fixed_latency(6);
3576 %}
3577 
3578 // Polling Address
3579 pipe_class loadConP_poll( iRegP dst, immP_poll src ) %{
3580     dst   : E(write);
3581     IALU  : R;
3582 %}
3583 
3584 // Long Constant small
3585 pipe_class loadConLlo( iRegL dst, immL src ) %{
3586     instruction_count(2);
3587     dst   : E(write);
3588     IALU  : R;
3589     IALU  : R;
3590 %}
3591 
3592 // [PHH] This is wrong for 64-bit.  See LdImmF/D.
3593 pipe_class loadConFD(regF dst, immF src, iRegP tmp) %{
3594     instruction_count(1); multiple_bundles;
3595     src   : R(read);
3596     dst   : M(write)+1;
3597     IALU  : R;
3598     MS    : E;
3599 %}
3600 
3601 // Integer ALU nop operation
3602 pipe_class ialu_nop() %{
3603     single_instruction;
3604     IALU  : R;
3605 %}
3606 
3607 // Integer ALU nop operation
3608 pipe_class ialu_nop_A0() %{
3609     single_instruction;
3610     A0    : R;
3611 %}
3612 
3613 // Integer ALU nop operation
3614 pipe_class ialu_nop_A1() %{
3615     single_instruction;
3616     A1    : R;
3617 %}
3618 
3619 // Integer Multiply reg-reg operation
3620 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
3621     single_instruction;
3622     dst   : E(write);
3623     src1  : R(read);
3624     src2  : R(read);
3625     MS    : R(5);
3626 %}
3627 
3628 pipe_class mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
3629     single_instruction;
3630     dst   : E(write)+4;
3631     src1  : R(read);
3632     src2  : R(read);
3633     MS    : R(6);
3634 %}
3635 
3636 // Integer Divide reg-reg
3637 pipe_class sdiv_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI temp, flagsReg cr) %{
3638     instruction_count(1); multiple_bundles;
3639     dst   : E(write);
3640     temp  : E(write);
3641     src1  : R(read);
3642     src2  : R(read);
3643     temp  : R(read);
3644     MS    : R(38);
3645 %}
3646 
3647 // Long Divide
3648 pipe_class divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
3649     dst  : E(write)+71;
3650     src1 : R(read);
3651     src2 : R(read)+1;
3652     MS   : R(70);
3653 %}
3654 
3655 // Floating Point Add Float
3656 pipe_class faddF_reg_reg(regF dst, regF src1, regF src2) %{
3657     single_instruction;
3658     dst   : X(write);
3659     src1  : E(read);
3660     src2  : E(read);
3661     FA    : R;
3662 %}
3663 
3664 // Floating Point Add Double
3665 pipe_class faddD_reg_reg(regD dst, regD src1, regD src2) %{
3666     single_instruction;
3667     dst   : X(write);
3668     src1  : E(read);
3669     src2  : E(read);
3670     FA    : R;
3671 %}
3672 
3673 // Floating Point Conditional Move based on integer flags
3674 pipe_class int_conditional_float_move (cmpOp cmp, flagsReg cr, regF dst, regF src) %{
3675     single_instruction;
3676     dst   : X(write);
3677     src   : E(read);
3678     cr    : R(read);
3679     FA    : R(2);
3680     BR    : R(2);
3681 %}
3682 
3683 // Floating Point Conditional Move based on integer flags
3684 pipe_class int_conditional_double_move (cmpOp cmp, flagsReg cr, regD dst, regD src) %{
3685     single_instruction;
3686     dst   : X(write);
3687     src   : E(read);
3688     cr    : R(read);
3689     FA    : R(2);
3690     BR    : R(2);
3691 %}
3692 
3693 // Floating Point Multiply Float
3694 pipe_class fmulF_reg_reg(regF dst, regF src1, regF src2) %{
3695     single_instruction;
3696     dst   : X(write);
3697     src1  : E(read);
3698     src2  : E(read);
3699     FM    : R;
3700 %}
3701 
3702 // Floating Point Multiply Double
3703 pipe_class fmulD_reg_reg(regD dst, regD src1, regD src2) %{
3704     single_instruction;
3705     dst   : X(write);
3706     src1  : E(read);
3707     src2  : E(read);
3708     FM    : R;
3709 %}
3710 
3711 // Floating Point Divide Float
3712 pipe_class fdivF_reg_reg(regF dst, regF src1, regF src2) %{
3713     single_instruction;
3714     dst   : X(write);
3715     src1  : E(read);
3716     src2  : E(read);
3717     FM    : R;
3718     FDIV  : C(14);
3719 %}
3720 
3721 // Floating Point Divide Double
3722 pipe_class fdivD_reg_reg(regD dst, regD src1, regD src2) %{
3723     single_instruction;
3724     dst   : X(write);
3725     src1  : E(read);
3726     src2  : E(read);
3727     FM    : R;
3728     FDIV  : C(17);
3729 %}
3730 
3731 // Floating Point Move/Negate/Abs Float
3732 pipe_class faddF_reg(regF dst, regF src) %{
3733     single_instruction;
3734     dst   : W(write);
3735     src   : E(read);
3736     FA    : R(1);
3737 %}
3738 
3739 // Floating Point Move/Negate/Abs Double
3740 pipe_class faddD_reg(regD dst, regD src) %{
3741     single_instruction;
3742     dst   : W(write);
3743     src   : E(read);
3744     FA    : R;
3745 %}
3746 
3747 // Floating Point Convert F->D
3748 pipe_class fcvtF2D(regD dst, regF src) %{
3749     single_instruction;
3750     dst   : X(write);
3751     src   : E(read);
3752     FA    : R;
3753 %}
3754 
3755 // Floating Point Convert I->D
3756 pipe_class fcvtI2D(regD dst, regF src) %{
3757     single_instruction;
3758     dst   : X(write);
3759     src   : E(read);
3760     FA    : R;
3761 %}
3762 
3763 // Floating Point Convert LHi->D
3764 pipe_class fcvtLHi2D(regD dst, regD src) %{
3765     single_instruction;
3766     dst   : X(write);
3767     src   : E(read);
3768     FA    : R;
3769 %}
3770 
3771 // Floating Point Convert L->D
3772 pipe_class fcvtL2D(regD dst, iRegL src) %{
3773     single_instruction;
3774     dst   : X(write);
3775     src   : E(read);
3776     FA    : R;
3777 %}
3778 
3779 // Floating Point Convert L->F
3780 pipe_class fcvtL2F(regF dst, iRegL src) %{
3781     single_instruction;
3782     dst   : X(write);
3783     src   : E(read);
3784     FA    : R;
3785 %}
3786 
3787 // Floating Point Convert D->F
3788 pipe_class fcvtD2F(regD dst, regF src) %{
3789     single_instruction;
3790     dst   : X(write);
3791     src   : E(read);
3792     FA    : R;
3793 %}
3794 
3795 // Floating Point Convert I->L
3796 pipe_class fcvtI2L(regD dst, regF src) %{
3797     single_instruction;
3798     dst   : X(write);
3799     src   : E(read);
3800     FA    : R;
3801 %}
3802 
3803 // Floating Point Convert D->F
3804 pipe_class fcvtD2I(iRegI dst, regD src, flagsReg cr) %{
3805     instruction_count(1); multiple_bundles;
3806     dst   : X(write)+6;
3807     src   : E(read);
3808     FA    : R;
3809 %}
3810 
3811 // Floating Point Convert D->L
3812 pipe_class fcvtD2L(regD dst, regD src, flagsReg cr) %{
3813     instruction_count(1); multiple_bundles;
3814     dst   : X(write)+6;
3815     src   : E(read);
3816     FA    : R;
3817 %}
3818 
3819 // Floating Point Convert F->I
3820 pipe_class fcvtF2I(regF dst, regF src, flagsReg cr) %{
3821     instruction_count(1); multiple_bundles;
3822     dst   : X(write)+6;
3823     src   : E(read);
3824     FA    : R;
3825 %}
3826 
3827 // Floating Point Convert F->L
3828 pipe_class fcvtF2L(regD dst, regF src, flagsReg cr) %{
3829     instruction_count(1); multiple_bundles;
3830     dst   : X(write)+6;
3831     src   : E(read);
3832     FA    : R;
3833 %}
3834 
3835 // Floating Point Convert I->F
3836 pipe_class fcvtI2F(regF dst, regF src) %{
3837     single_instruction;
3838     dst   : X(write);
3839     src   : E(read);
3840     FA    : R;
3841 %}
3842 
3843 // Floating Point Compare
3844 pipe_class faddF_fcc_reg_reg_zero(flagsRegF cr, regF src1, regF src2, immI0 zero) %{
3845     single_instruction;
3846     cr    : X(write);
3847     src1  : E(read);
3848     src2  : E(read);
3849     FA    : R;
3850 %}
3851 
3852 // Floating Point Compare
3853 pipe_class faddD_fcc_reg_reg_zero(flagsRegF cr, regD src1, regD src2, immI0 zero) %{
3854     single_instruction;
3855     cr    : X(write);
3856     src1  : E(read);
3857     src2  : E(read);
3858     FA    : R;
3859 %}
3860 
3861 // Floating Add Nop
3862 pipe_class fadd_nop() %{
3863     single_instruction;
3864     FA  : R;
3865 %}
3866 
3867 // Integer Store to Memory
3868 pipe_class istore_mem_reg(memoryI mem, iRegI src) %{
3869     single_instruction;
3870     mem   : R(read);
3871     src   : C(read);
3872     MS    : R;
3873 %}
3874 
3875 // Integer Store to Memory
3876 pipe_class istore_mem_spORreg(memoryI mem, sp_ptr_RegP src) %{
3877     single_instruction;
3878     mem   : R(read);
3879     src   : C(read);
3880     MS    : R;
3881 %}
3882 
3883 // Float Store
3884 pipe_class fstoreF_mem_reg(memoryF mem, RegF src) %{
3885     single_instruction;
3886     mem : R(read);
3887     src : C(read);
3888     MS  : R;
3889 %}
3890 
3891 // Float Store
3892 pipe_class fstoreF_mem_zero(memoryF mem, immF0 src) %{
3893     single_instruction;
3894     mem : R(read);
3895     MS  : R;
3896 %}
3897 
3898 // Double Store
3899 pipe_class fstoreD_mem_reg(memoryD mem, RegD src) %{
3900     instruction_count(1);
3901     mem : R(read);
3902     src : C(read);
3903     MS  : R;
3904 %}
3905 
3906 // Double Store
3907 pipe_class fstoreD_mem_zero(memoryD mem, immD0 src) %{
3908     single_instruction;
3909     mem : R(read);
3910     MS  : R;
3911 %}
3912 
3913 // Integer Load (when sign bit propagation not needed)
3914 pipe_class iload_mem(iRegI dst, memoryI mem) %{
3915     single_instruction;
3916     mem : R(read);
3917     dst : C(write);
3918     MS  : R;
3919 %}
3920 
3921 // Integer Load (when sign bit propagation or masking is needed)
3922 pipe_class iload_mask_mem(iRegI dst, memoryI mem) %{
3923     single_instruction;
3924     mem : R(read);
3925     dst : M(write);
3926     MS  : R;
3927 %}
3928 
3929 // Float Load
3930 pipe_class floadF_mem(regF dst, memoryF mem) %{
3931     single_instruction;
3932     mem : R(read);
3933     dst : M(write);
3934     MS  : R;
3935 %}
3936 
3937 // Float Load
3938 pipe_class floadD_mem(regD dst, memoryD mem) %{
3939     instruction_count(1); multiple_bundles; // Again, unaligned argument is only multiple case
3940     mem : R(read);
3941     dst : M(write);
3942     MS  : R;
3943 %}
3944 
3945 // Memory Nop
3946 pipe_class mem_nop() %{
3947     single_instruction;
3948     MS  : R;
3949 %}
3950 
3951 pipe_class sethi(iRegP dst, immI src) %{
3952     single_instruction;
3953     dst  : E(write);
3954     IALU : R;
3955 %}
3956 
3957 pipe_class loadPollP(iRegP poll) %{
3958     single_instruction;
3959     poll : R(read);
3960     MS   : R;
3961 %}
3962 
3963 pipe_class br(Universe br, label labl) %{
3964     single_instruction_with_delay_slot;
3965     BR  : R;
3966 %}
3967 
3968 pipe_class br_cc(Universe br, cmpOp cmp, flagsReg cr, label labl) %{
3969     single_instruction_with_delay_slot;
3970     cr    : E(read);
3971     BR    : R;
3972 %}
3973 
3974 pipe_class br_reg(Universe br, cmpOp cmp, iRegI op1, label labl) %{
3975     single_instruction_with_delay_slot;
3976     op1 : E(read);
3977     BR  : R;
3978     MS  : R;
3979 %}
3980 
3981 pipe_class br_nop() %{
3982     single_instruction;
3983     BR  : R;
3984 %}
3985 
3986 pipe_class simple_call(method meth) %{
3987     instruction_count(2); multiple_bundles; force_serialization;
3988     fixed_latency(100);
3989     BR  : R(1);
3990     MS  : R(1);
3991     A0  : R(1);
3992 %}
3993 
3994 pipe_class compiled_call(method meth) %{
3995     instruction_count(1); multiple_bundles; force_serialization;
3996     fixed_latency(100);
3997     MS  : R(1);
3998 %}
3999 
4000 pipe_class call(method meth) %{
4001     instruction_count(0); multiple_bundles; force_serialization;
4002     fixed_latency(100);
4003 %}
4004 
4005 pipe_class tail_call(Universe ignore, label labl) %{
4006     single_instruction; has_delay_slot;
4007     fixed_latency(100);
4008     BR  : R(1);
4009     MS  : R(1);
4010 %}
4011 
4012 pipe_class ret(Universe ignore) %{
4013     single_instruction; has_delay_slot;
4014     BR  : R(1);
4015     MS  : R(1);
4016 %}
4017 
4018 // The real do-nothing guy
4019 pipe_class empty( ) %{
4020     instruction_count(0);
4021 %}
4022 
4023 pipe_class long_memory_op() %{
4024     instruction_count(0); multiple_bundles; force_serialization;
4025     fixed_latency(25);
4026     MS  : R(1);
4027 %}
4028 
4029 // Check-cast
4030 pipe_class partial_subtype_check_pipe(Universe ignore, iRegP array, iRegP match ) %{
4031     array : R(read);
4032     match  : R(read);
4033     IALU   : R(2);
4034     BR     : R(2);
4035     MS     : R;
4036 %}
4037 
4038 // Convert FPU flags into +1,0,-1
4039 pipe_class floating_cmp( iRegI dst, regF src1, regF src2 ) %{
4040     src1  : E(read);
4041     src2  : E(read);
4042     dst   : E(write);
4043     FA    : R;
4044     MS    : R(2);
4045     BR    : R(2);
4046 %}
4047 
4048 // Compare for p < q, and conditionally add y
4049 pipe_class cadd_cmpltmask( iRegI p, iRegI q, iRegI y ) %{
4050     p     : E(read);
4051     q     : E(read);
4052     y     : E(read);
4053     IALU  : R(3)
4054 %}
4055 
4056 // Perform a compare, then move conditionally in a branch delay slot.
4057 pipe_class min_max( iRegI src2, iRegI srcdst ) %{
4058     src2   : E(read);
4059     srcdst : E(read);
4060     IALU   : R;
4061     BR     : R;
4062 %}
4063 
4064 // Define the class for the Nop node
4065 define %{
4066    MachNop = ialu_nop;
4067 %}
4068 
4069 %}
4070 
4071 //----------INSTRUCTIONS-------------------------------------------------------
4072 
4073 //------------Special Nop instructions for bundling - no match rules-----------
4074 // Nop using the A0 functional unit
4075 instruct Nop_A0() %{
4076   ins_pipe(ialu_nop_A0);
4077 %}
4078 
4079 // Nop using the A1 functional unit
4080 instruct Nop_A1( ) %{
4081   ins_pipe(ialu_nop_A1);
4082 %}
4083 
4084 // Nop using the memory functional unit
4085 instruct Nop_MS( ) %{
4086   ins_pipe(mem_nop);
4087 %}
4088 
4089 // Nop using the floating add functional unit
4090 instruct Nop_FA( ) %{
4091   ins_pipe(fadd_nop);
4092 %}
4093 
4094 // Nop using the branch functional unit
4095 instruct Nop_BR( ) %{
4096   ins_pipe(br_nop);
4097 %}
4098 
4099 //----------Load/Store/Move Instructions---------------------------------------
4100 //----------Load Instructions--------------------------------------------------
4101 // Load Byte (8bit signed)
4102 instruct loadB(iRegI dst, memoryB mem) %{
4103   match(Set dst (LoadB mem));
4104   ins_cost(MEMORY_REF_COST);
4105 
4106   size(4);
4107   format %{ "LDRSB   $dst,$mem\t! byte -> int" %}
4108   ins_encode %{
4109     // High 32 bits are harmlessly set on Aarch64
4110     __ ldrsb($dst$$Register, $mem$$Address);
4111   %}
4112   ins_pipe(iload_mask_mem);
4113 %}
4114 
4115 // Load Byte (8bit signed) into a Long Register
4116 instruct loadB2L(iRegL dst, memoryB mem) %{
4117   match(Set dst (ConvI2L (LoadB mem)));
4118   ins_cost(MEMORY_REF_COST);
4119 
4120 #ifdef AARCH64
4121   size(4);
4122   format %{ "LDRSB $dst,$mem\t! byte -> long"  %}
4123   ins_encode %{
4124     __ ldrsb($dst$$Register, $mem$$Address);
4125   %}
4126 #else
4127   size(8);
4128   format %{ "LDRSB $dst.lo,$mem\t! byte -> long\n\t"
4129             "ASR   $dst.hi,$dst.lo,31" %}
4130   ins_encode %{
4131     __ ldrsb($dst$$Register, $mem$$Address);
4132     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
4133   %}
4134 #endif
4135   ins_pipe(iload_mask_mem);
4136 %}
4137 
4138 // Load Unsigned Byte (8bit UNsigned) into an int reg
4139 instruct loadUB(iRegI dst, memoryB mem) %{
4140   match(Set dst (LoadUB mem));
4141   ins_cost(MEMORY_REF_COST);
4142 
4143   size(4);
4144   format %{ "LDRB   $dst,$mem\t! ubyte -> int" %}
4145   ins_encode %{
4146     __ ldrb($dst$$Register, $mem$$Address);
4147   %}
4148   ins_pipe(iload_mem);
4149 %}
4150 
4151 // Load Unsigned Byte (8bit UNsigned) into a Long Register
4152 instruct loadUB2L(iRegL dst, memoryB mem) %{
4153   match(Set dst (ConvI2L (LoadUB mem)));
4154   ins_cost(MEMORY_REF_COST);
4155 
4156 #ifdef AARCH64
4157   size(4);
4158   format %{ "LDRB  $dst,$mem\t! ubyte -> long"  %}
4159   ins_encode %{
4160     __ ldrb($dst$$Register, $mem$$Address);
4161   %}
4162 #else
4163   size(8);
4164   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
4165             "MOV   $dst.hi,0" %}
4166   ins_encode %{
4167     __ ldrb($dst$$Register, $mem$$Address);
4168     __ mov($dst$$Register->successor(), 0);
4169   %}
4170 #endif
4171   ins_pipe(iload_mem);
4172 %}
4173 
4174 // Load Unsigned Byte (8 bit UNsigned) with immediate mask into Long Register
4175 instruct loadUB2L_limmI(iRegL dst, memoryB mem, limmIlow8 mask) %{
4176   match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
4177 
4178 #ifdef AARCH64
4179   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
4180   size(8);
4181   format %{ "LDRB  $dst,$mem\t! ubyte -> long\n\t"
4182             "AND  $dst,$dst,$mask" %}
4183   ins_encode %{
4184     __ ldrb($dst$$Register, $mem$$Address);
4185     __ andr($dst$$Register, $dst$$Register, limmI_low($mask$$constant, 8));
4186   %}
4187 #else
4188   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
4189   size(12);
4190   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
4191             "MOV   $dst.hi,0\n\t"
4192             "AND  $dst.lo,$dst.lo,$mask" %}
4193   ins_encode %{
4194     __ ldrb($dst$$Register, $mem$$Address);
4195     __ mov($dst$$Register->successor(), 0);
4196     __ andr($dst$$Register, $dst$$Register, limmI_low($mask$$constant, 8));
4197   %}
4198 #endif
4199   ins_pipe(iload_mem);
4200 %}
4201 
4202 // Load Short (16bit signed)
4203 #ifdef AARCH64
4204 // XXX This variant shouldn't be necessary if 6217251 is implemented
4205 instruct loadSoff(iRegI dst, memoryScaledS mem, aimmX off, iRegP tmp) %{
4206   match(Set dst (LoadS (AddP mem off)));
4207   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
4208   effect(TEMP tmp);
4209   size(4 * 2);
4210 
4211   format %{ "LDRSH   $dst,$mem+$off\t! short temp=$tmp" %}
4212   ins_encode %{
4213     Register base = reg_to_register_object($mem$$base);
4214     __ add($tmp$$Register, base, $off$$constant);
4215     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4216     __ ldrsh($dst$$Register, nmem);
4217   %}
4218   ins_pipe(iload_mask_mem);
4219 %}
4220 #endif
4221 
4222 instruct loadS(iRegI dst, memoryS mem) %{
4223   match(Set dst (LoadS mem));
4224   ins_cost(MEMORY_REF_COST);
4225 
4226   size(4);
4227   format %{ "LDRSH   $dst,$mem\t! short" %}
4228   ins_encode %{
4229     __ ldrsh($dst$$Register, $mem$$Address);
4230   %}
4231   ins_pipe(iload_mask_mem);
4232 %}
4233 
4234 // Load Short (16 bit signed) to Byte (8 bit signed)
4235 instruct loadS2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
4236   match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
4237   ins_cost(MEMORY_REF_COST);
4238 
4239   size(4);
4240 
4241   format %{ "LDRSB   $dst,$mem\t! short -> byte" %}
4242   ins_encode %{
4243     // High 32 bits are harmlessly set on Aarch64
4244     __ ldrsb($dst$$Register, $mem$$Address);
4245   %}
4246   ins_pipe(iload_mask_mem);
4247 %}
4248 
4249 // Load Short (16bit signed) into a Long Register
4250 instruct loadS2L(iRegL dst, memoryS mem) %{
4251   match(Set dst (ConvI2L (LoadS mem)));
4252   ins_cost(MEMORY_REF_COST);
4253 
4254 #ifdef AARCH64
4255   size(4);
4256   format %{ "LDRSH $dst,$mem\t! short -> long"  %}
4257   ins_encode %{
4258     __ ldrsh($dst$$Register, $mem$$Address);
4259   %}
4260 #else
4261   size(8);
4262   format %{ "LDRSH $dst.lo,$mem\t! short -> long\n\t"
4263             "ASR   $dst.hi,$dst.lo,31" %}
4264   ins_encode %{
4265     __ ldrsh($dst$$Register, $mem$$Address);
4266     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
4267   %}
4268 #endif
4269   ins_pipe(iload_mask_mem);
4270 %}
4271 
4272 // Load Unsigned Short/Char (16bit UNsigned)
4273 
4274 #ifdef AARCH64
4275 // XXX This variant shouldn't be necessary if 6217251 is implemented
4276 instruct loadUSoff(iRegI dst, memoryScaledS mem, aimmX off, iRegP tmp) %{
4277   match(Set dst (LoadUS (AddP mem off)));
4278   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
4279   effect(TEMP tmp);
4280   size(4 * 2);
4281 
4282   format %{ "LDRH   $dst,$mem+$off\t! ushort/char temp=$tmp" %}
4283   ins_encode %{
4284     Register base = reg_to_register_object($mem$$base);
4285     __ add($tmp$$Register, base, $off$$constant);
4286     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4287     __ ldrh($dst$$Register, nmem);
4288   %}
4289   ins_pipe(iload_mem);
4290 %}
4291 #endif
4292 
4293 instruct loadUS(iRegI dst, memoryS mem) %{
4294   match(Set dst (LoadUS mem));
4295   ins_cost(MEMORY_REF_COST);
4296 
4297   size(4);
4298   format %{ "LDRH   $dst,$mem\t! ushort/char" %}
4299   ins_encode %{
4300     __ ldrh($dst$$Register, $mem$$Address);
4301   %}
4302   ins_pipe(iload_mem);
4303 %}
4304 
4305 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
4306 instruct loadUS2B(iRegI dst, memoryB mem, immI_24 twentyfour) %{
4307   match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
4308   ins_cost(MEMORY_REF_COST);
4309 
4310   size(4);
4311   format %{ "LDRSB   $dst,$mem\t! ushort -> byte" %}
4312   ins_encode %{
4313     __ ldrsb($dst$$Register, $mem$$Address);
4314   %}
4315   ins_pipe(iload_mask_mem);
4316 %}
4317 
4318 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register
4319 instruct loadUS2L(iRegL dst, memoryS mem) %{
4320   match(Set dst (ConvI2L (LoadUS mem)));
4321   ins_cost(MEMORY_REF_COST);
4322 
4323 #ifdef AARCH64
4324   size(4);
4325   format %{ "LDRH  $dst,$mem\t! short -> long"  %}
4326   ins_encode %{
4327     __ ldrh($dst$$Register, $mem$$Address);
4328   %}
4329 #else
4330   size(8);
4331   format %{ "LDRH  $dst.lo,$mem\t! short -> long\n\t"
4332             "MOV   $dst.hi, 0" %}
4333   ins_encode %{
4334     __ ldrh($dst$$Register, $mem$$Address);
4335     __ mov($dst$$Register->successor(), 0);
4336   %}
4337 #endif
4338   ins_pipe(iload_mem);
4339 %}
4340 
4341 // Load Unsigned Short/Char (16bit UNsigned) with mask 0xFF into a Long Register
4342 instruct loadUS2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
4343   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
4344   ins_cost(MEMORY_REF_COST);
4345 
4346 #ifdef AARCH64
4347   size(4);
4348   format %{ "LDRB  $dst,$mem"  %}
4349   ins_encode %{
4350     __ ldrb($dst$$Register, $mem$$Address);
4351   %}
4352 #else
4353   size(8);
4354   format %{ "LDRB  $dst.lo,$mem\t! \n\t"
4355             "MOV   $dst.hi, 0" %}
4356   ins_encode %{
4357     __ ldrb($dst$$Register, $mem$$Address);
4358     __ mov($dst$$Register->successor(), 0);
4359   %}
4360 #endif
4361   ins_pipe(iload_mem);
4362 %}
4363 
4364 // Load Unsigned Short/Char (16bit UNsigned) with a immediate mask into a Long Register
4365 instruct loadUS2L_limmI(iRegL dst, memoryS mem, limmI mask) %{
4366   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
4367 #ifdef AARCH64
4368   ins_cost(MEMORY_REF_COST + 1*DEFAULT_COST);
4369 
4370   size(8);
4371   format %{ "LDRH   $dst,$mem\t! ushort/char & mask -> long\n\t"
4372             "AND    $dst,$dst,$mask" %}
4373   ins_encode %{
4374     __ ldrh($dst$$Register, $mem$$Address);
4375     __ andr($dst$$Register, $dst$$Register, (uintx)$mask$$constant);
4376   %}
4377 #else
4378   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
4379 
4380   size(12);
4381   format %{ "LDRH   $dst,$mem\t! ushort/char & mask -> long\n\t"
4382             "MOV    $dst.hi, 0\n\t"
4383             "AND    $dst,$dst,$mask" %}
4384   ins_encode %{
4385     __ ldrh($dst$$Register, $mem$$Address);
4386     __ mov($dst$$Register->successor(), 0);
4387     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
4388   %}
4389 #endif
4390   ins_pipe(iload_mem);
4391 %}
4392 
4393 // Load Integer
4394 
4395 #ifdef AARCH64
4396 // XXX This variant shouldn't be necessary if 6217251 is implemented
4397 instruct loadIoff(iRegI dst, memoryScaledI mem, aimmX off, iRegP tmp) %{
4398   match(Set dst (LoadI (AddP mem off)));
4399   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
4400   effect(TEMP tmp);
4401   size(4 * 2);
4402 
4403   format %{ "ldr_s32 $dst,$mem+$off\t! int temp=$tmp" %}
4404   ins_encode %{
4405     Register base = reg_to_register_object($mem$$base);
4406     __ add($tmp$$Register, base, $off$$constant);
4407     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4408     __ ldr_s32($dst$$Register, nmem);
4409   %}
4410   ins_pipe(iload_mem);
4411 %}
4412 #endif
4413 
4414 instruct loadI(iRegI dst, memoryI mem) %{
4415   match(Set dst (LoadI mem));
4416   ins_cost(MEMORY_REF_COST);
4417 
4418   size(4);
4419   format %{ "ldr_s32 $dst,$mem\t! int" %}
4420   ins_encode %{
4421     __ ldr_s32($dst$$Register, $mem$$Address);
4422   %}
4423   ins_pipe(iload_mem);
4424 %}
4425 
4426 // Load Integer to Byte (8 bit signed)
4427 instruct loadI2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
4428   match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
4429   ins_cost(MEMORY_REF_COST);
4430 
4431   size(4);
4432 
4433   format %{ "LDRSB   $dst,$mem\t! int -> byte" %}
4434   ins_encode %{
4435     __ ldrsb($dst$$Register, $mem$$Address);
4436   %}
4437   ins_pipe(iload_mask_mem);
4438 %}
4439 
4440 // Load Integer to Unsigned Byte (8 bit UNsigned)
4441 instruct loadI2UB(iRegI dst, memoryB mem, immI_255 mask) %{
4442   match(Set dst (AndI (LoadI mem) mask));
4443   ins_cost(MEMORY_REF_COST);
4444 
4445   size(4);
4446 
4447   format %{ "LDRB   $dst,$mem\t! int -> ubyte" %}
4448   ins_encode %{
4449     __ ldrb($dst$$Register, $mem$$Address);
4450   %}
4451   ins_pipe(iload_mask_mem);
4452 %}
4453 
4454 // Load Integer to Short (16 bit signed)
4455 instruct loadI2S(iRegI dst, memoryS mem, immI_16 sixteen) %{
4456   match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
4457   ins_cost(MEMORY_REF_COST);
4458 
4459   size(4);
4460   format %{ "LDRSH   $dst,$mem\t! int -> short" %}
4461   ins_encode %{
4462     __ ldrsh($dst$$Register, $mem$$Address);
4463   %}
4464   ins_pipe(iload_mask_mem);
4465 %}
4466 
4467 // Load Integer to Unsigned Short (16 bit UNsigned)
4468 instruct loadI2US(iRegI dst, memoryS mem, immI_65535 mask) %{
4469   match(Set dst (AndI (LoadI mem) mask));
4470   ins_cost(MEMORY_REF_COST);
4471 
4472   size(4);
4473   format %{ "LDRH   $dst,$mem\t! int -> ushort/char" %}
4474   ins_encode %{
4475     __ ldrh($dst$$Register, $mem$$Address);
4476   %}
4477   ins_pipe(iload_mask_mem);
4478 %}
4479 
4480 // Load Integer into a Long Register
4481 instruct loadI2L(iRegL dst, memoryI mem) %{
4482   match(Set dst (ConvI2L (LoadI mem)));
4483 #ifdef AARCH64
4484   ins_cost(MEMORY_REF_COST);
4485 
4486   size(4);
4487   format %{ "LDRSW $dst.lo,$mem\t! int -> long"  %}
4488   ins_encode %{
4489     __ ldr_s32($dst$$Register, $mem$$Address);
4490   %}
4491 #else
4492   ins_cost(MEMORY_REF_COST);
4493 
4494   size(8);
4495   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
4496             "ASR   $dst.hi,$dst.lo,31\t! int->long" %}
4497   ins_encode %{
4498     __ ldr($dst$$Register, $mem$$Address);
4499     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
4500   %}
4501 #endif
4502   ins_pipe(iload_mask_mem);
4503 %}
4504 
4505 // Load Integer with mask 0xFF into a Long Register
4506 instruct loadI2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
4507   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4508 #ifdef AARCH64
4509   ins_cost(MEMORY_REF_COST);
4510 
4511   size(4);
4512   format %{ "LDRB   $dst.lo,$mem\t! int & 0xFF -> long"  %}
4513   ins_encode %{
4514     __ ldrb($dst$$Register, $mem$$Address);
4515   %}
4516 #else
4517   ins_cost(MEMORY_REF_COST);
4518 
4519   size(8);
4520   format %{ "LDRB   $dst.lo,$mem\t! int & 0xFF -> long\n\t"
4521             "MOV    $dst.hi, 0" %}
4522   ins_encode %{
4523     __ ldrb($dst$$Register, $mem$$Address);
4524     __ mov($dst$$Register->successor(), 0);
4525   %}
4526 #endif
4527   ins_pipe(iload_mem);
4528 %}
4529 
4530 // Load Integer with mask 0xFFFF into a Long Register
4531 instruct loadI2L_immI_65535(iRegL dst, memoryS mem, immI_65535 mask) %{
4532   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4533   ins_cost(MEMORY_REF_COST);
4534 
4535 #ifdef AARCH64
4536   size(4);
4537   format %{ "LDRH   $dst,$mem\t! int & 0xFFFF -> long" %}
4538   ins_encode %{
4539     __ ldrh($dst$$Register, $mem$$Address);
4540   %}
4541 #else
4542   size(8);
4543   format %{ "LDRH   $dst,$mem\t! int & 0xFFFF -> long\n\t"
4544             "MOV    $dst.hi, 0" %}
4545   ins_encode %{
4546     __ ldrh($dst$$Register, $mem$$Address);
4547     __ mov($dst$$Register->successor(), 0);
4548   %}
4549 #endif
4550   ins_pipe(iload_mask_mem);
4551 %}
4552 
4553 #ifdef AARCH64
4554 // Load Integer with an immediate mask into a Long Register
4555 instruct loadI2L_limmI(iRegL dst, memoryI mem, limmI mask) %{
4556   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4557   ins_cost(MEMORY_REF_COST + 1*DEFAULT_COST);
4558 
4559   size(8);
4560   format %{ "LDRSW $dst,$mem\t! int -> long\n\t"
4561             "AND   $dst,$dst,$mask" %}
4562 
4563   ins_encode %{
4564     __ ldr_s32($dst$$Register, $mem$$Address);
4565     __ andr($dst$$Register, $dst$$Register, (uintx)$mask$$constant);
4566   %}
4567   ins_pipe(iload_mem);
4568 %}
4569 #else
4570 // Load Integer with a 31-bit immediate mask into a Long Register
4571 instruct loadI2L_limmU31(iRegL dst, memoryI mem, limmU31 mask) %{
4572   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4573   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
4574 
4575   size(12);
4576   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
4577             "MOV    $dst.hi, 0\n\t"
4578             "AND   $dst,$dst,$mask" %}
4579 
4580   ins_encode %{
4581     __ ldr($dst$$Register, $mem$$Address);
4582     __ mov($dst$$Register->successor(), 0);
4583     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
4584   %}
4585   ins_pipe(iload_mem);
4586 %}
4587 #endif
4588 
4589 #ifdef AARCH64
4590 // Load Integer with mask into a Long Register
4591 // FIXME: use signedRegI mask, remove tmp?
4592 instruct loadI2L_immI(iRegL dst, memoryI mem, immI mask, iRegI tmp) %{
4593   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4594   effect(TEMP dst, TEMP tmp);
4595 
4596   ins_cost(MEMORY_REF_COST + 3*DEFAULT_COST);
4597   format %{ "LDRSW    $mem,$dst\t! int & 31-bit mask -> long\n\t"
4598             "MOV_SLOW $tmp,$mask\n\t"
4599             "AND      $dst,$tmp,$dst" %}
4600   ins_encode %{
4601     __ ldrsw($dst$$Register, $mem$$Address);
4602     __ mov_slow($tmp$$Register, $mask$$constant);
4603     __ andr($dst$$Register, $dst$$Register, $tmp$$Register);
4604   %}
4605   ins_pipe(iload_mem);
4606 %}
4607 #else
4608 // Load Integer with a 31-bit mask into a Long Register
4609 // FIXME: use iRegI mask, remove tmp?
4610 instruct loadI2L_immU31(iRegL dst, memoryI mem, immU31 mask, iRegI tmp) %{
4611   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4612   effect(TEMP dst, TEMP tmp);
4613 
4614   ins_cost(MEMORY_REF_COST + 4*DEFAULT_COST);
4615   size(20);
4616   format %{ "LDR      $mem,$dst\t! int & 31-bit mask -> long\n\t"
4617             "MOV      $dst.hi, 0\n\t"
4618             "MOV_SLOW $tmp,$mask\n\t"
4619             "AND      $dst,$tmp,$dst" %}
4620   ins_encode %{
4621     __ ldr($dst$$Register, $mem$$Address);
4622     __ mov($dst$$Register->successor(), 0);
4623     __ mov_slow($tmp$$Register, $mask$$constant);
4624     __ andr($dst$$Register, $dst$$Register, $tmp$$Register);
4625   %}
4626   ins_pipe(iload_mem);
4627 %}
4628 #endif
4629 
4630 // Load Unsigned Integer into a Long Register
4631 instruct loadUI2L(iRegL dst, memoryI mem, immL_32bits mask) %{
4632   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
4633   ins_cost(MEMORY_REF_COST);
4634 
4635 #ifdef AARCH64
4636 //size(4);
4637   format %{ "LDR_w $dst,$mem\t! uint -> long" %}
4638   ins_encode %{
4639     __ ldr_w($dst$$Register, $mem$$Address);
4640   %}
4641 #else
4642   size(8);
4643   format %{ "LDR   $dst.lo,$mem\t! uint -> long\n\t"
4644             "MOV   $dst.hi,0" %}
4645   ins_encode %{
4646     __ ldr($dst$$Register, $mem$$Address);
4647     __ mov($dst$$Register->successor(), 0);
4648   %}
4649 #endif
4650   ins_pipe(iload_mem);
4651 %}
4652 
4653 // Load Long
4654 
4655 #ifdef AARCH64
4656 // XXX This variant shouldn't be necessary if 6217251 is implemented
4657 instruct loadLoff(iRegLd dst, memoryScaledL mem, aimmX off, iRegP tmp) %{
4658   match(Set dst (LoadL (AddP mem off)));
4659   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
4660   effect(TEMP tmp);
4661   size(4 * 2);
4662 
4663   format %{ "LDR    $dst,$mem+$off\t! long temp=$tmp" %}
4664   ins_encode %{
4665     Register base = reg_to_register_object($mem$$base);
4666     __ add($tmp$$Register, base, $off$$constant);
4667     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4668     __ ldr($dst$$Register, nmem);
4669   %}
4670   ins_pipe(iload_mem);
4671 %}
4672 #endif
4673 
4674 instruct loadL(iRegLd dst, memoryL mem ) %{
4675 #ifdef AARCH64
4676   // already atomic for Aarch64
4677 #else
4678   predicate(!((LoadLNode*)n)->require_atomic_access());
4679 #endif
4680   match(Set dst (LoadL mem));
4681   effect(TEMP dst);
4682   ins_cost(MEMORY_REF_COST);
4683 
4684   size(4);
4685   format %{ "ldr_64  $dst,$mem\t! long" %}
4686   ins_encode %{
4687     __ ldr_64($dst$$Register, $mem$$Address);
4688   %}
4689   ins_pipe(iload_mem);
4690 %}
4691 
4692 #ifndef AARCH64
4693 instruct loadL_2instr(iRegL dst, memorylong mem ) %{
4694   predicate(!((LoadLNode*)n)->require_atomic_access());
4695   match(Set dst (LoadL mem));
4696   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
4697 
4698   size(8);
4699   format %{ "LDR    $dst.lo,$mem \t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
4700             "LDR    $dst.hi,$mem+4 or $mem" %}
4701   ins_encode %{
4702     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4703     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
4704 
4705     if ($dst$$Register == reg_to_register_object($mem$$base)) {
4706       __ ldr($dst$$Register->successor(), Amemhi);
4707       __ ldr($dst$$Register, Amemlo);
4708     } else {
4709       __ ldr($dst$$Register, Amemlo);
4710       __ ldr($dst$$Register->successor(), Amemhi);
4711     }
4712   %}
4713   ins_pipe(iload_mem);
4714 %}
4715 
4716 instruct loadL_volatile(iRegL dst, indirect mem ) %{
4717   predicate(((LoadLNode*)n)->require_atomic_access());
4718   match(Set dst (LoadL mem));
4719   ins_cost(MEMORY_REF_COST);
4720 
4721   size(4);
4722   format %{ "LDMIA    $dst,$mem\t! long" %}
4723   ins_encode %{
4724     // FIXME: why is ldmia considered atomic?  Should be ldrexd
4725     RegisterSet set($dst$$Register);
4726     set = set | reg_to_register_object($dst$$reg + 1);
4727     __ ldmia(reg_to_register_object($mem$$base), set);
4728   %}
4729   ins_pipe(iload_mem);
4730 %}
4731 
4732 instruct loadL_volatile_fp(iRegL dst, memoryD mem ) %{
4733   predicate(((LoadLNode*)n)->require_atomic_access());
4734   match(Set dst (LoadL mem));
4735   ins_cost(MEMORY_REF_COST);
4736 
4737   size(8);
4738   format %{ "FLDD      S14, $mem"
4739             "FMRRD    $dst, S14\t! long \n't" %}
4740   ins_encode %{
4741     __ fldd(S14, $mem$$Address);
4742     __ fmrrd($dst$$Register, $dst$$Register->successor(), S14);
4743   %}
4744   ins_pipe(iload_mem);
4745 %}
4746 
4747 instruct loadL_unaligned(iRegL dst, memorylong mem ) %{
4748   match(Set dst (LoadL_unaligned mem));
4749   ins_cost(MEMORY_REF_COST);
4750 
4751   size(8);
4752   format %{ "LDR    $dst.lo,$mem\t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
4753             "LDR    $dst.hi,$mem+4" %}
4754   ins_encode %{
4755     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4756     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
4757 
4758     if ($dst$$Register == reg_to_register_object($mem$$base)) {
4759       __ ldr($dst$$Register->successor(), Amemhi);
4760       __ ldr($dst$$Register, Amemlo);
4761     } else {
4762       __ ldr($dst$$Register, Amemlo);
4763       __ ldr($dst$$Register->successor(), Amemhi);
4764     }
4765   %}
4766   ins_pipe(iload_mem);
4767 %}
4768 #endif // !AARCH64
4769 
4770 // Load Range
4771 instruct loadRange(iRegI dst, memoryI mem) %{
4772   match(Set dst (LoadRange mem));
4773   ins_cost(MEMORY_REF_COST);
4774 
4775   size(4);
4776   format %{ "LDR_u32 $dst,$mem\t! range" %}
4777   ins_encode %{
4778     __ ldr_u32($dst$$Register, $mem$$Address);
4779   %}
4780   ins_pipe(iload_mem);
4781 %}
4782 
4783 // Load Pointer
4784 
4785 #ifdef AARCH64
4786 // XXX This variant shouldn't be necessary if 6217251 is implemented
4787 instruct loadPoff(iRegP dst, memoryScaledP mem, aimmX off, iRegP tmp) %{
4788   match(Set dst (LoadP (AddP mem off)));
4789   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
4790   effect(TEMP tmp);
4791   size(4 * 2);
4792 
4793   format %{ "LDR    $dst,$mem+$off\t! ptr temp=$tmp" %}
4794   ins_encode %{
4795     Register base = reg_to_register_object($mem$$base);
4796     __ add($tmp$$Register, base, $off$$constant);
4797     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4798     __ ldr($dst$$Register, nmem);
4799   %}
4800   ins_pipe(iload_mem);
4801 %}
4802 #endif
4803 
4804 instruct loadP(iRegP dst, memoryP mem) %{
4805   match(Set dst (LoadP mem));
4806   ins_cost(MEMORY_REF_COST);
4807   size(4);
4808 
4809   format %{ "LDR   $dst,$mem\t! ptr" %}
4810   ins_encode %{
4811     __ ldr($dst$$Register, $mem$$Address);
4812   %}
4813   ins_pipe(iload_mem);
4814 %}
4815 
4816 #ifdef XXX
4817 // FIXME XXXX
4818 //instruct loadSP(iRegP dst, memoryP mem) %{
4819 instruct loadSP(SPRegP dst, memoryP mem, iRegP tmp) %{
4820   match(Set dst (LoadP mem));
4821   effect(TEMP tmp);
4822   ins_cost(MEMORY_REF_COST+1);
4823   size(8);
4824 
4825   format %{ "LDR   $tmp,$mem\t! ptr\n\t"
4826             "MOV   $dst,$tmp\t! ptr" %}
4827   ins_encode %{
4828     __ ldr($tmp$$Register, $mem$$Address);
4829     __ mov($dst$$Register, $tmp$$Register);
4830   %}
4831   ins_pipe(iload_mem);
4832 %}
4833 #endif
4834 
4835 #ifdef _LP64
4836 // Load Compressed Pointer
4837 
4838 // XXX This variant shouldn't be necessary if 6217251 is implemented
4839 instruct loadNoff(iRegN dst, memoryScaledI mem, aimmX off, iRegP tmp) %{
4840   match(Set dst (LoadN (AddP mem off)));
4841   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
4842   effect(TEMP tmp);
4843   size(4 * 2);
4844 
4845   format %{ "ldr_u32 $dst,$mem+$off\t! compressed ptr temp=$tmp" %}
4846   ins_encode %{
4847     Register base = reg_to_register_object($mem$$base);
4848     __ add($tmp$$Register, base, $off$$constant);
4849     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4850     __ ldr_u32($dst$$Register, nmem);
4851   %}
4852   ins_pipe(iload_mem);
4853 %}
4854 
4855 instruct loadN(iRegN dst, memoryI mem) %{
4856   match(Set dst (LoadN mem));
4857   ins_cost(MEMORY_REF_COST);
4858   size(4);
4859 
4860   format %{ "ldr_u32 $dst,$mem\t! compressed ptr" %}
4861   ins_encode %{
4862     __ ldr_u32($dst$$Register, $mem$$Address);
4863   %}
4864   ins_pipe(iload_mem);
4865 %}
4866 #endif
4867 
4868 // Load Klass Pointer
4869 instruct loadKlass(iRegP dst, memoryI mem) %{
4870   match(Set dst (LoadKlass mem));
4871   ins_cost(MEMORY_REF_COST);
4872   size(4);
4873 
4874   format %{ "LDR   $dst,$mem\t! klass ptr" %}
4875   ins_encode %{
4876     __ ldr($dst$$Register, $mem$$Address);
4877   %}
4878   ins_pipe(iload_mem);
4879 %}
4880 
4881 #ifdef _LP64
4882 // Load narrow Klass Pointer
4883 instruct loadNKlass(iRegN dst, memoryI mem) %{
4884   match(Set dst (LoadNKlass mem));
4885   ins_cost(MEMORY_REF_COST);
4886   size(4);
4887 
4888   format %{ "ldr_u32 $dst,$mem\t! compressed klass ptr" %}
4889   ins_encode %{
4890     __ ldr_u32($dst$$Register, $mem$$Address);
4891   %}
4892   ins_pipe(iload_mem);
4893 %}
4894 #endif
4895 
4896 #ifdef AARCH64
4897 // XXX This variant shouldn't be necessary if 6217251 is implemented
4898 instruct loadDoff(regD dst, memoryScaledD mem, aimmX off, iRegP tmp) %{
4899   match(Set dst (LoadD (AddP mem off)));
4900   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
4901   effect(TEMP tmp);
4902   size(4 * 2);
4903 
4904   format %{ "ldr    $dst,$mem+$off\t! double temp=$tmp" %}
4905   ins_encode %{
4906     Register base = reg_to_register_object($mem$$base);
4907     __ add($tmp$$Register, base, $off$$constant);
4908     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4909     __ ldr_d($dst$$FloatRegister, nmem);
4910   %}
4911   ins_pipe(floadD_mem);
4912 %}
4913 #endif
4914 
4915 instruct loadD(regD dst, memoryD mem) %{
4916   match(Set dst (LoadD mem));
4917   ins_cost(MEMORY_REF_COST);
4918 
4919   size(4);
4920   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
4921   // only LDREXD and STREXD are 64-bit single-copy atomic
4922   format %{ "FLDD   $dst,$mem" %}
4923   ins_encode %{
4924     __ ldr_double($dst$$FloatRegister, $mem$$Address);
4925   %}
4926   ins_pipe(floadD_mem);
4927 %}
4928 
4929 #ifndef AARCH64
4930 // Load Double - UNaligned
4931 instruct loadD_unaligned(regD_low dst, memoryF2 mem ) %{
4932   match(Set dst (LoadD_unaligned mem));
4933   ins_cost(MEMORY_REF_COST*2+DEFAULT_COST);
4934   size(8);
4935   format %{ "FLDS    $dst.lo,$mem\t! misaligned double\n"
4936           "\tFLDS    $dst.hi,$mem+4\t!" %}
4937   ins_encode %{
4938     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4939     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
4940       __ flds($dst$$FloatRegister, Amemlo);
4941       __ flds($dst$$FloatRegister->successor(), Amemhi);
4942   %}
4943   ins_pipe(iload_mem);
4944 %}
4945 #endif
4946 
4947 #ifdef AARCH64
4948 // XXX This variant shouldn't be necessary if 6217251 is implemented
4949 instruct loadFoff(regF dst, memoryScaledF mem, aimmX off, iRegP tmp) %{
4950   match(Set dst (LoadF (AddP mem off)));
4951   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
4952   effect(TEMP tmp);
4953   size(4 * 2);
4954 
4955   format %{ "ldr    $dst,$mem+$off\t! float temp=$tmp" %}
4956   ins_encode %{
4957     Register base = reg_to_register_object($mem$$base);
4958     __ add($tmp$$Register, base, $off$$constant);
4959     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4960     __ ldr_s($dst$$FloatRegister, nmem);
4961   %}
4962   ins_pipe(floadF_mem);
4963 %}
4964 #endif
4965 
4966 instruct loadF(regF dst, memoryF mem) %{
4967   match(Set dst (LoadF mem));
4968 
4969   ins_cost(MEMORY_REF_COST);
4970   size(4);
4971   format %{ "FLDS    $dst,$mem" %}
4972   ins_encode %{
4973     __ ldr_float($dst$$FloatRegister, $mem$$Address);
4974   %}
4975   ins_pipe(floadF_mem);
4976 %}
4977 
4978 #ifdef AARCH64
4979 instruct load_limmI(iRegI dst, limmI src) %{
4980   match(Set dst src);
4981   ins_cost(DEFAULT_COST + 1); // + 1 because MOV is preferred
4982   format %{ "ORR_w  $dst, ZR, $src\t! int"  %}
4983   ins_encode %{
4984     __ orr_w($dst$$Register, ZR, (uintx)$src$$constant);
4985   %}
4986   ins_pipe(ialu_imm);
4987 %}
4988 #endif
4989 
4990 // // Load Constant
4991 instruct loadConI( iRegI dst, immI src ) %{
4992   match(Set dst src);
4993   ins_cost(DEFAULT_COST * 3/2);
4994   format %{ "MOV_SLOW    $dst, $src" %}
4995   ins_encode %{
4996     __ mov_slow($dst$$Register, $src$$constant);
4997   %}
4998   ins_pipe(ialu_hi_lo_reg);
4999 %}
5000 
5001 instruct loadConIMov( iRegI dst, immIMov src ) %{
5002   match(Set dst src);
5003   size(4);
5004   format %{ "MOV    $dst, $src" %}
5005   ins_encode %{
5006     __ mov($dst$$Register, $src$$constant);
5007   %}
5008   ins_pipe(ialu_imm);
5009 %}
5010 
5011 #ifndef AARCH64
5012 instruct loadConIMovn( iRegI dst, immIRotn src ) %{
5013   match(Set dst src);
5014   size(4);
5015   format %{ "MVN    $dst, ~$src" %}
5016   ins_encode %{
5017     __ mvn($dst$$Register, ~$src$$constant);
5018   %}
5019   ins_pipe(ialu_imm_n);
5020 %}
5021 #endif
5022 
5023 instruct loadConI16( iRegI dst, immI16 src ) %{
5024   match(Set dst src);
5025   size(4);
5026 #ifdef AARCH64
5027   format %{ "MOVZ_w  $dst, $src" %}
5028 #else
5029   format %{ "MOVW    $dst, $src" %}
5030 #endif
5031   ins_encode %{
5032 #ifdef AARCH64
5033     __ mov_w($dst$$Register, $src$$constant);
5034 #else
5035     __ movw($dst$$Register, $src$$constant);
5036 #endif
5037   %}
5038   ins_pipe(ialu_imm_n);
5039 %}
5040 
5041 instruct loadConP(iRegP dst, immP src) %{
5042   match(Set dst src);
5043   ins_cost(DEFAULT_COST * 3/2);
5044   format %{ "MOV_SLOW    $dst,$src\t!ptr" %}
5045   ins_encode %{
5046     relocInfo::relocType constant_reloc = _opnds[1]->constant_reloc();
5047     intptr_t val = $src$$constant;
5048     if (constant_reloc == relocInfo::oop_type) {
5049       __ mov_oop($dst$$Register, (jobject)val);
5050     } else if (constant_reloc == relocInfo::metadata_type) {
5051       __ mov_metadata($dst$$Register, (Metadata*)val);
5052     } else {
5053       __ mov_slow($dst$$Register, val);
5054     }
5055   %}
5056   ins_pipe(loadConP);
5057 %}
5058 
5059 
5060 instruct loadConP_poll(iRegP dst, immP_poll src) %{
5061   match(Set dst src);
5062   ins_cost(DEFAULT_COST);
5063   format %{ "MOV_SLOW    $dst,$src\t!ptr" %}
5064   ins_encode %{
5065       __ mov_slow($dst$$Register, $src$$constant);
5066   %}
5067   ins_pipe(loadConP_poll);
5068 %}
5069 
5070 #ifdef AARCH64
5071 instruct loadConP0(iRegP dst, immP0 src) %{
5072   match(Set dst src);
5073   ins_cost(DEFAULT_COST);
5074   format %{ "MOV    $dst,ZR\t!ptr" %}
5075   ins_encode %{
5076     __ mov($dst$$Register, ZR);
5077   %}
5078   ins_pipe(ialu_none);
5079 %}
5080 
5081 instruct loadConN(iRegN dst, immN src) %{
5082   match(Set dst src);
5083   ins_cost(DEFAULT_COST * 3/2);
5084   format %{ "SET    $dst,$src\t! compressed ptr" %}
5085   ins_encode %{
5086     Register dst = $dst$$Register;
5087     // FIXME: use $constanttablebase?
5088     __ set_narrow_oop(dst, (jobject)$src$$constant);
5089   %}
5090   ins_pipe(ialu_hi_lo_reg);
5091 %}
5092 
5093 instruct loadConN0(iRegN dst, immN0 src) %{
5094   match(Set dst src);
5095   ins_cost(DEFAULT_COST);
5096   format %{ "MOV    $dst,ZR\t! compressed ptr" %}
5097   ins_encode %{
5098     __ mov($dst$$Register, ZR);
5099   %}
5100   ins_pipe(ialu_none);
5101 %}
5102 
5103 instruct loadConNKlass(iRegN dst, immNKlass src) %{
5104   match(Set dst src);
5105   ins_cost(DEFAULT_COST * 3/2);
5106   format %{ "SET    $dst,$src\t! compressed klass ptr" %}
5107   ins_encode %{
5108     Register dst = $dst$$Register;
5109     // FIXME: use $constanttablebase?
5110     __ set_narrow_klass(dst, (Klass*)$src$$constant);
5111   %}
5112   ins_pipe(ialu_hi_lo_reg);
5113 %}
5114 
5115 instruct load_limmL(iRegL dst, limmL src) %{
5116   match(Set dst src);
5117   ins_cost(DEFAULT_COST);
5118   format %{ "ORR    $dst, ZR, $src\t! long"  %}
5119   ins_encode %{
5120     __ orr($dst$$Register, ZR, (uintx)$src$$constant);
5121   %}
5122   ins_pipe(loadConL);
5123 %}
5124 instruct load_immLMov(iRegL dst, immLMov src) %{
5125   match(Set dst src);
5126   ins_cost(DEFAULT_COST);
5127   format %{ "MOV    $dst, $src\t! long"  %}
5128   ins_encode %{
5129     __ mov($dst$$Register, $src$$constant);
5130   %}
5131   ins_pipe(loadConL);
5132 %}
5133 instruct loadConL(iRegL dst, immL src) %{
5134   match(Set dst src);
5135   ins_cost(DEFAULT_COST * 4); // worst case
5136   format %{ "mov_slow   $dst, $src\t! long"  %}
5137   ins_encode %{
5138     // FIXME: use $constanttablebase?
5139     __ mov_slow($dst$$Register, $src$$constant);
5140   %}
5141   ins_pipe(loadConL);
5142 %}
5143 #else
5144 instruct loadConL(iRegL dst, immL src) %{
5145   match(Set dst src);
5146   ins_cost(DEFAULT_COST * 4);
5147   format %{ "MOV_SLOW   $dst.lo, $src & 0x0FFFFFFFFL \t! long\n\t"
5148             "MOV_SLOW   $dst.hi, $src >> 32" %}
5149   ins_encode %{
5150     __ mov_slow(reg_to_register_object($dst$$reg), $src$$constant & 0x0FFFFFFFFL);
5151     __ mov_slow(reg_to_register_object($dst$$reg + 1), ((julong)($src$$constant)) >> 32);
5152   %}
5153   ins_pipe(loadConL);
5154 %}
5155 
5156 instruct loadConL16( iRegL dst, immL16 src ) %{
5157   match(Set dst src);
5158   ins_cost(DEFAULT_COST * 2);
5159 
5160   size(8);
5161   format %{ "MOVW    $dst.lo, $src \n\t"
5162             "MOVW    $dst.hi, 0 \n\t" %}
5163   ins_encode %{
5164     __ movw($dst$$Register, $src$$constant);
5165     __ movw($dst$$Register->successor(), 0);
5166   %}
5167   ins_pipe(ialu_imm);
5168 %}
5169 #endif
5170 
5171 instruct loadConF_imm8(regF dst, imm8F src) %{
5172   match(Set dst src);
5173   ins_cost(DEFAULT_COST);
5174   size(4);
5175 
5176   format %{ "FCONSTS      $dst, $src"%}
5177 
5178   ins_encode %{
5179     __ fconsts($dst$$FloatRegister, Assembler::float_num($src$$constant).imm8());
5180   %}
5181   ins_pipe(loadConFD); // FIXME
5182 %}
5183 
5184 #ifdef AARCH64
5185 instruct loadIConF(iRegI dst, immF src) %{
5186   match(Set dst src);
5187   ins_cost(DEFAULT_COST * 2);
5188 
5189   format %{ "MOV_SLOW  $dst, $src\t! loadIConF"  %}
5190 
5191   ins_encode %{
5192     // FIXME revisit once 6961697 is in
5193     union {
5194       jfloat f;
5195       int i;
5196     } v;
5197     v.f = $src$$constant;
5198     __ mov_slow($dst$$Register, v.i);
5199   %}
5200   ins_pipe(ialu_imm);
5201 %}
5202 #endif
5203 
5204 instruct loadConF(regF dst, immF src, iRegI tmp) %{
5205   match(Set dst src);
5206   ins_cost(DEFAULT_COST * 2);
5207   effect(TEMP tmp);
5208   size(3*4);
5209 
5210   format %{ "MOV_SLOW  $tmp, $src\n\t"
5211             "FMSR      $dst, $tmp"%}
5212 
5213   ins_encode %{
5214     // FIXME revisit once 6961697 is in
5215     union {
5216       jfloat f;
5217       int i;
5218     } v;
5219     v.f = $src$$constant;
5220     __ mov_slow($tmp$$Register, v.i);
5221     __ fmsr($dst$$FloatRegister, $tmp$$Register);
5222   %}
5223   ins_pipe(loadConFD); // FIXME
5224 %}
5225 
5226 instruct loadConD_imm8(regD dst, imm8D src) %{
5227   match(Set dst src);
5228   ins_cost(DEFAULT_COST);
5229   size(4);
5230 
5231   format %{ "FCONSTD      $dst, $src"%}
5232 
5233   ins_encode %{
5234     __ fconstd($dst$$FloatRegister, Assembler::double_num($src$$constant).imm8());
5235   %}
5236   ins_pipe(loadConFD); // FIXME
5237 %}
5238 
5239 instruct loadConD(regD dst, immD src, iRegP tmp) %{
5240   match(Set dst src);
5241   effect(TEMP tmp);
5242   ins_cost(MEMORY_REF_COST);
5243   format %{ "FLDD  $dst, [$constanttablebase + $constantoffset]\t! load from constant table: double=$src" %}
5244 
5245   ins_encode %{
5246     Register r = $constanttablebase;
5247     int offset  = $constantoffset($src);
5248     if (!is_memoryD(offset)) {                // can't use a predicate
5249                                               // in load constant instructs
5250       __ add_slow($tmp$$Register, r, offset);
5251       r = $tmp$$Register;
5252       offset = 0;
5253     }
5254     __ ldr_double($dst$$FloatRegister, Address(r, offset));
5255   %}
5256   ins_pipe(loadConFD);
5257 %}
5258 
5259 // Prefetch instructions.
5260 // Must be safe to execute with invalid address (cannot fault).
5261 
5262 instruct prefetchAlloc_mp( memoryP mem ) %{
5263   predicate(os::is_MP());
5264   match( PrefetchAllocation mem );
5265   ins_cost(MEMORY_REF_COST);
5266   size(4);
5267 
5268   format %{ "PLDW $mem\t! Prefetch allocation" %}
5269   ins_encode %{
5270 #ifdef AARCH64
5271     __ prfm(pstl1keep, $mem$$Address);
5272 #else
5273     __ pldw($mem$$Address);
5274 #endif
5275   %}
5276   ins_pipe(iload_mem);
5277 %}
5278 
5279 instruct prefetchAlloc_sp( memoryP mem ) %{
5280   predicate(!os::is_MP());
5281   match( PrefetchAllocation mem );
5282   ins_cost(MEMORY_REF_COST);
5283   size(4);
5284 
5285   format %{ "PLD $mem\t! Prefetch allocation" %}
5286   ins_encode %{
5287 #ifdef AARCH64
5288     __ prfm(pstl1keep, $mem$$Address);
5289 #else
5290     __ pld($mem$$Address);
5291 #endif
5292   %}
5293   ins_pipe(iload_mem);
5294 %}
5295 
5296 //----------Store Instructions-------------------------------------------------
5297 // Store Byte
5298 instruct storeB(memoryB mem, store_RegI src) %{
5299   match(Set mem (StoreB mem src));
5300   ins_cost(MEMORY_REF_COST);
5301 
5302   size(4);
5303   format %{ "STRB    $src,$mem\t! byte" %}
5304   ins_encode %{
5305     __ strb($src$$Register, $mem$$Address);
5306   %}
5307   ins_pipe(istore_mem_reg);
5308 %}
5309 
5310 instruct storeCM(memoryB mem, store_RegI src) %{
5311   match(Set mem (StoreCM mem src));
5312   ins_cost(MEMORY_REF_COST);
5313 
5314   size(4);
5315   format %{ "STRB    $src,$mem\t! CMS card-mark byte" %}
5316   ins_encode %{
5317     __ strb($src$$Register, $mem$$Address);
5318   %}
5319   ins_pipe(istore_mem_reg);
5320 %}
5321 
5322 // Store Char/Short
5323 
5324 #ifdef AARCH64
5325 // XXX This variant shouldn't be necessary if 6217251 is implemented
5326 instruct storeCoff(store_RegI src, memoryScaledS mem, aimmX off, iRegP tmp) %{
5327   match(Set mem (StoreC (AddP mem off) src));
5328   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
5329   effect(TEMP tmp);
5330   size(4 * 2);
5331 
5332   format %{ "STRH    $src,$mem+$off\t! short temp=$tmp" %}
5333   ins_encode %{
5334     Register base = reg_to_register_object($mem$$base);
5335     __ add($tmp$$Register, base, $off$$constant);
5336     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
5337     __ strh($src$$Register, nmem);
5338   %}
5339   ins_pipe(istore_mem_reg);
5340 %}
5341 #endif
5342 
5343 instruct storeC(memoryS mem, store_RegI src) %{
5344   match(Set mem (StoreC mem src));
5345   ins_cost(MEMORY_REF_COST);
5346 
5347   size(4);
5348   format %{ "STRH    $src,$mem\t! short" %}
5349   ins_encode %{
5350     __ strh($src$$Register, $mem$$Address);
5351   %}
5352   ins_pipe(istore_mem_reg);
5353 %}
5354 
5355 // Store Integer
5356 
5357 #ifdef AARCH64
5358 // XXX This variant shouldn't be necessary if 6217251 is implemented
5359 instruct storeIoff(store_RegI src, memoryScaledI mem, aimmX off, iRegP tmp) %{
5360   match(Set mem (StoreI (AddP mem off) src));
5361   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
5362   effect(TEMP tmp);
5363   size(4 * 2);
5364 
5365   format %{ "str_32 $src,$mem+$off\t! int temp=$tmp" %}
5366   ins_encode %{
5367     Register base = reg_to_register_object($mem$$base);
5368     __ add($tmp$$Register, base, $off$$constant);
5369     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
5370     __ str_32($src$$Register, nmem);
5371   %}
5372   ins_pipe(istore_mem_reg);
5373 %}
5374 #endif
5375 
5376 instruct storeI(memoryI mem, store_RegI src) %{
5377   match(Set mem (StoreI mem src));
5378   ins_cost(MEMORY_REF_COST);
5379 
5380   size(4);
5381   format %{ "str_32 $src,$mem" %}
5382   ins_encode %{
5383     __ str_32($src$$Register, $mem$$Address);
5384   %}
5385   ins_pipe(istore_mem_reg);
5386 %}
5387 
5388 // Store Long
5389 
5390 #ifdef AARCH64
5391 // XXX This variant shouldn't be necessary if 6217251 is implemented
5392 instruct storeLoff(store_RegLd src, memoryScaledL mem, aimmX off, iRegP tmp) %{
5393   match(Set mem (StoreL (AddP mem off) src));
5394   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
5395   effect(TEMP tmp);
5396   size(4 * 2);
5397 
5398   format %{ "str_64 $src,$mem+$off\t! long temp=$tmp" %}
5399   ins_encode %{
5400     Register base = reg_to_register_object($mem$$base);
5401     __ add($tmp$$Register, base, $off$$constant);
5402     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
5403     __ str_64($src$$Register, nmem);
5404   %}
5405   ins_pipe(istore_mem_reg);
5406 %}
5407 #endif
5408 
5409 instruct storeL(memoryL mem, store_RegLd src) %{
5410 #ifdef AARCH64
5411   // already atomic for Aarch64
5412 #else
5413   predicate(!((StoreLNode*)n)->require_atomic_access());
5414 #endif
5415   match(Set mem (StoreL mem src));
5416   ins_cost(MEMORY_REF_COST);
5417 
5418   size(4);
5419   format %{ "str_64  $src,$mem\t! long\n\t" %}
5420 
5421   ins_encode %{
5422     __ str_64($src$$Register, $mem$$Address);
5423   %}
5424   ins_pipe(istore_mem_reg);
5425 %}
5426 
5427 #ifndef AARCH64
5428 instruct storeL_2instr(memorylong mem, iRegL src) %{
5429   predicate(!((StoreLNode*)n)->require_atomic_access());
5430   match(Set mem (StoreL mem src));
5431   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
5432 
5433   size(8);
5434   format %{ "STR    $src.lo,$mem\t! long\n\t"
5435             "STR    $src.hi,$mem+4" %}
5436 
5437   ins_encode %{
5438     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
5439     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
5440     __ str($src$$Register, Amemlo);
5441     __ str($src$$Register->successor(), Amemhi);
5442   %}
5443   ins_pipe(istore_mem_reg);
5444 %}
5445 
5446 instruct storeL_volatile(indirect mem, iRegL src) %{
5447   predicate(((StoreLNode*)n)->require_atomic_access());
5448   match(Set mem (StoreL mem src));
5449   ins_cost(MEMORY_REF_COST);
5450   size(4);
5451   format %{ "STMIA    $src,$mem\t! long" %}
5452   ins_encode %{
5453     // FIXME: why is stmia considered atomic?  Should be strexd
5454     RegisterSet set($src$$Register);
5455     set = set | reg_to_register_object($src$$reg + 1);
5456     __ stmia(reg_to_register_object($mem$$base), set);
5457   %}
5458   ins_pipe(istore_mem_reg);
5459 %}
5460 #endif // !AARCH64
5461 
5462 #ifndef AARCH64
5463 instruct storeL_volatile_fp(memoryD mem, iRegL src) %{
5464   predicate(((StoreLNode*)n)->require_atomic_access());
5465   match(Set mem (StoreL mem src));
5466   ins_cost(MEMORY_REF_COST);
5467   size(8);
5468   format %{ "FMDRR    S14, $src\t! long \n\t"
5469             "FSTD     S14, $mem" %}
5470   ins_encode %{
5471     __ fmdrr(S14, $src$$Register, $src$$Register->successor());
5472     __ fstd(S14, $mem$$Address);
5473   %}
5474   ins_pipe(istore_mem_reg);
5475 %}
5476 #endif
5477 
5478 #ifdef XXX
5479 // Move SP Pointer
5480 //instruct movSP(sp_ptr_RegP dst, SPRegP src) %{
5481 //instruct movSP(iRegP dst, SPRegP src) %{
5482 instruct movSP(store_ptr_RegP dst, SPRegP src) %{
5483   match(Set dst src);
5484 //predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con == TypeFunc::FramePtr);
5485   ins_cost(MEMORY_REF_COST);
5486   size(4);
5487 
5488   format %{ "MOV    $dst,$src\t! SP ptr\n\t" %}
5489   ins_encode %{
5490     assert(false, "XXX1 got here");
5491     __ mov($dst$$Register, SP);
5492     __ mov($dst$$Register, $src$$Register);
5493   %}
5494   ins_pipe(ialu_reg);
5495 %}
5496 #endif
5497 
5498 #ifdef AARCH64
5499 // FIXME
5500 // Store SP Pointer
5501 instruct storeSP(memoryP mem, SPRegP src, iRegP tmp) %{
5502   match(Set mem (StoreP mem src));
5503   predicate(_kids[1]->_leaf->is_Proj() && _kids[1]->_leaf->as_Proj()->_con == TypeFunc::FramePtr);
5504   // Multiple StoreP rules, different only in register mask.
5505   // Matcher makes the last always valid.  The others will
5506   // only be valid if they cost less than the last valid
5507   // rule.  So cost(rule1) < cost(rule2) < cost(last)
5508   // Unlike immediates, register constraints are not checked
5509   // at match time.
5510   ins_cost(MEMORY_REF_COST+DEFAULT_COST+4);
5511   effect(TEMP tmp);
5512   size(8);
5513 
5514   format %{ "MOV    $tmp,$src\t! SP ptr\n\t"
5515             "STR    $tmp,$mem\t! SP ptr" %}
5516   ins_encode %{
5517     assert($src$$Register == SP, "SP expected");
5518     __ mov($tmp$$Register, $src$$Register);
5519     __ str($tmp$$Register, $mem$$Address);
5520   %}
5521   ins_pipe(istore_mem_spORreg); // FIXME
5522 %}
5523 #endif // AARCH64
5524 
5525 // Store Pointer
5526 
5527 #ifdef AARCH64
5528 // XXX This variant shouldn't be necessary if 6217251 is implemented
5529 instruct storePoff(store_ptr_RegP src, memoryScaledP mem, aimmX off, iRegP tmp) %{
5530   predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con != TypeFunc::FramePtr);
5531   match(Set mem (StoreP (AddP mem off) src));
5532   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
5533   effect(TEMP tmp);
5534   size(4 * 2);
5535 
5536   format %{ "STR    $src,$mem+$off\t! ptr temp=$tmp" %}
5537   ins_encode %{
5538     Register base = reg_to_register_object($mem$$base);
5539     __ add($tmp$$Register, base, $off$$constant);
5540     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
5541     __ str($src$$Register, nmem);
5542   %}
5543   ins_pipe(istore_mem_reg);
5544 %}
5545 #endif
5546 
5547 instruct storeP(memoryP mem, store_ptr_RegP src) %{
5548   match(Set mem (StoreP mem src));
5549 #ifdef AARCH64
5550   predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con != TypeFunc::FramePtr);
5551 #endif
5552   ins_cost(MEMORY_REF_COST);
5553   size(4);
5554 
5555   format %{ "STR    $src,$mem\t! ptr" %}
5556   ins_encode %{
5557     __ str($src$$Register, $mem$$Address);
5558   %}
5559   ins_pipe(istore_mem_spORreg);
5560 %}
5561 
5562 #ifdef AARCH64
5563 // Store NULL Pointer
5564 instruct storeP0(memoryP mem, immP0 src) %{
5565   match(Set mem (StoreP mem src));
5566   ins_cost(MEMORY_REF_COST);
5567   size(4);
5568 
5569   format %{ "STR    ZR,$mem\t! ptr" %}
5570   ins_encode %{
5571     __ str(ZR, $mem$$Address);
5572   %}
5573   ins_pipe(istore_mem_spORreg);
5574 %}
5575 #endif // AARCH64
5576 
5577 #ifdef _LP64
5578 // Store Compressed Pointer
5579 
5580 #ifdef AARCH64
5581 // XXX This variant shouldn't be necessary if 6217251 is implemented
5582 instruct storeNoff(store_RegN src, memoryScaledI mem, aimmX off, iRegP tmp) %{
5583   match(Set mem (StoreN (AddP mem off) src));
5584   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
5585   effect(TEMP tmp);
5586   size(4 * 2);
5587 
5588   format %{ "str_32 $src,$mem+$off\t! compressed ptr temp=$tmp" %}
5589   ins_encode %{
5590     Register base = reg_to_register_object($mem$$base);
5591     __ add($tmp$$Register, base, $off$$constant);
5592     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
5593     __ str_32($src$$Register, nmem);
5594   %}
5595   ins_pipe(istore_mem_reg);
5596 %}
5597 #endif
5598 
5599 instruct storeN(memoryI mem, store_RegN src) %{
5600   match(Set mem (StoreN mem src));
5601   ins_cost(MEMORY_REF_COST);
5602   size(4);
5603 
5604   format %{ "str_32 $src,$mem\t! compressed ptr" %}
5605   ins_encode %{
5606     __ str_32($src$$Register, $mem$$Address);
5607   %}
5608   ins_pipe(istore_mem_reg);
5609 %}
5610 
5611 #ifdef AARCH64
5612 // Store NULL Pointer
5613 instruct storeN0(memoryI mem, immN0 src) %{
5614   match(Set mem (StoreN mem src));
5615   ins_cost(MEMORY_REF_COST);
5616   size(4);
5617 
5618   format %{ "str_32 ZR,$mem\t! compressed ptr" %}
5619   ins_encode %{
5620     __ str_32(ZR, $mem$$Address);
5621   %}
5622   ins_pipe(istore_mem_reg);
5623 %}
5624 #endif
5625 
5626 // Store Compressed Klass Pointer
5627 instruct storeNKlass(memoryI mem, store_RegN src) %{
5628   match(Set mem (StoreNKlass mem src));
5629   ins_cost(MEMORY_REF_COST);
5630   size(4);
5631 
5632   format %{ "str_32 $src,$mem\t! compressed klass ptr" %}
5633   ins_encode %{
5634     __ str_32($src$$Register, $mem$$Address);
5635   %}
5636   ins_pipe(istore_mem_reg);
5637 %}
5638 #endif
5639 
5640 // Store Double
5641 
5642 #ifdef AARCH64
5643 // XXX This variant shouldn't be necessary if 6217251 is implemented
5644 instruct storeDoff(regD src, memoryScaledD mem, aimmX off, iRegP tmp) %{
5645   match(Set mem (StoreD (AddP mem off) src));
5646   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
5647   effect(TEMP tmp);
5648   size(4 * 2);
5649 
5650   format %{ "STR    $src,$mem+$off\t! double temp=$tmp" %}
5651   ins_encode %{
5652     Register base = reg_to_register_object($mem$$base);
5653     __ add($tmp$$Register, base, $off$$constant);
5654     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
5655     __ str_d($src$$FloatRegister, nmem);
5656   %}
5657   ins_pipe(fstoreD_mem_reg);
5658 %}
5659 #endif
5660 
5661 instruct storeD(memoryD mem, regD src) %{
5662   match(Set mem (StoreD mem src));
5663   ins_cost(MEMORY_REF_COST);
5664 
5665   size(4);
5666   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
5667   // only LDREXD and STREXD are 64-bit single-copy atomic
5668   format %{ "FSTD   $src,$mem" %}
5669   ins_encode %{
5670     __ str_double($src$$FloatRegister, $mem$$Address);
5671   %}
5672   ins_pipe(fstoreD_mem_reg);
5673 %}
5674 
5675 #ifdef AARCH64
5676 instruct movI2F(regF dst, iRegI src) %{
5677   match(Set dst src);
5678   size(4);
5679 
5680   format %{ "FMOV_sw $dst,$src\t! movI2F" %}
5681   ins_encode %{
5682     __ fmov_sw($dst$$FloatRegister, $src$$Register);
5683   %}
5684   ins_pipe(ialu_reg); // FIXME
5685 %}
5686 
5687 instruct movF2I(iRegI dst, regF src) %{
5688   match(Set dst src);
5689   size(4);
5690 
5691   format %{ "FMOV_ws $dst,$src\t! movF2I" %}
5692   ins_encode %{
5693     __ fmov_ws($dst$$Register, $src$$FloatRegister);
5694   %}
5695   ins_pipe(ialu_reg); // FIXME
5696 %}
5697 #endif
5698 
5699 // Store Float
5700 
5701 #ifdef AARCH64
5702 // XXX This variant shouldn't be necessary if 6217251 is implemented
5703 instruct storeFoff(regF src, memoryScaledF mem, aimmX off, iRegP tmp) %{
5704   match(Set mem (StoreF (AddP mem off) src));
5705   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
5706   effect(TEMP tmp);
5707   size(4 * 2);
5708 
5709   format %{ "str_s  $src,$mem+$off\t! float temp=$tmp" %}
5710   ins_encode %{
5711     Register base = reg_to_register_object($mem$$base);
5712     __ add($tmp$$Register, base, $off$$constant);
5713     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
5714     __ str_s($src$$FloatRegister, nmem);
5715   %}
5716   ins_pipe(fstoreF_mem_reg);
5717 %}
5718 #endif
5719 
5720 instruct storeF( memoryF mem, regF src) %{
5721   match(Set mem (StoreF mem src));
5722   ins_cost(MEMORY_REF_COST);
5723 
5724   size(4);
5725   format %{ "FSTS    $src,$mem" %}
5726   ins_encode %{
5727     __ str_float($src$$FloatRegister, $mem$$Address);
5728   %}
5729   ins_pipe(fstoreF_mem_reg);
5730 %}
5731 
5732 #ifdef AARCH64
5733 // Convert oop pointer into compressed form
5734 instruct encodeHeapOop(iRegN dst, iRegP src, flagsReg ccr) %{
5735   predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
5736   match(Set dst (EncodeP src));
5737   effect(KILL ccr);
5738   format %{ "encode_heap_oop $dst, $src" %}
5739   ins_encode %{
5740     __ encode_heap_oop($dst$$Register, $src$$Register);
5741   %}
5742   ins_pipe(ialu_reg);
5743 %}
5744 
5745 instruct encodeHeapOop_not_null(iRegN dst, iRegP src) %{
5746   predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
5747   match(Set dst (EncodeP src));
5748   format %{ "encode_heap_oop_not_null $dst, $src" %}
5749   ins_encode %{
5750     __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
5751   %}
5752   ins_pipe(ialu_reg);
5753 %}
5754 
5755 instruct decodeHeapOop(iRegP dst, iRegN src, flagsReg ccr) %{
5756   predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
5757             n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant);
5758   match(Set dst (DecodeN src));
5759   effect(KILL ccr);
5760   format %{ "decode_heap_oop $dst, $src" %}
5761   ins_encode %{
5762     __ decode_heap_oop($dst$$Register, $src$$Register);
5763   %}
5764   ins_pipe(ialu_reg);
5765 %}
5766 
5767 instruct decodeHeapOop_not_null(iRegP dst, iRegN src) %{
5768   predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
5769             n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant);
5770   match(Set dst (DecodeN src));
5771   format %{ "decode_heap_oop_not_null $dst, $src" %}
5772   ins_encode %{
5773     __ decode_heap_oop_not_null($dst$$Register, $src$$Register);
5774   %}
5775   ins_pipe(ialu_reg);
5776 %}
5777 
5778 instruct encodeKlass_not_null(iRegN dst, iRegP src) %{
5779   match(Set dst (EncodePKlass src));
5780   format %{ "encode_klass_not_null $dst, $src" %}
5781   ins_encode %{
5782     __ encode_klass_not_null($dst$$Register, $src$$Register);
5783   %}
5784   ins_pipe(ialu_reg);
5785 %}
5786 
5787 instruct decodeKlass_not_null(iRegP dst, iRegN src) %{
5788   match(Set dst (DecodeNKlass src));
5789   format %{ "decode_klass_not_null $dst, $src" %}
5790   ins_encode %{
5791     __ decode_klass_not_null($dst$$Register, $src$$Register);
5792   %}
5793   ins_pipe(ialu_reg);
5794 %}
5795 #endif // AARCH64
5796 
5797 //----------MemBar Instructions-----------------------------------------------
5798 // Memory barrier flavors
5799 
5800 // TODO: take advantage of Aarch64 load-acquire, store-release, etc
5801 // pattern-match out unnecessary membars
5802 instruct membar_storestore() %{
5803   match(MemBarStoreStore);
5804   ins_cost(4*MEMORY_REF_COST);
5805 
5806   size(4);
5807   format %{ "MEMBAR-storestore" %}
5808   ins_encode %{
5809     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore), noreg);
5810   %}
5811   ins_pipe(long_memory_op);
5812 %}
5813 
5814 instruct membar_acquire() %{
5815   match(MemBarAcquire);
5816   match(LoadFence);
5817   ins_cost(4*MEMORY_REF_COST);
5818 
5819   size(4);
5820   format %{ "MEMBAR-acquire" %}
5821   ins_encode %{
5822     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), noreg);
5823   %}
5824   ins_pipe(long_memory_op);
5825 %}
5826 
5827 instruct membar_acquire_lock() %{
5828   match(MemBarAcquireLock);
5829   ins_cost(0);
5830 
5831   size(0);
5832   format %{ "!MEMBAR-acquire (CAS in prior FastLock so empty encoding)" %}
5833   ins_encode( );
5834   ins_pipe(empty);
5835 %}
5836 
5837 instruct membar_release() %{
5838   match(MemBarRelease);
5839   match(StoreFence);
5840   ins_cost(4*MEMORY_REF_COST);
5841 
5842   size(4);
5843   format %{ "MEMBAR-release" %}
5844   ins_encode %{
5845     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), noreg);
5846   %}
5847   ins_pipe(long_memory_op);
5848 %}
5849 
5850 instruct membar_release_lock() %{
5851   match(MemBarReleaseLock);
5852   ins_cost(0);
5853 
5854   size(0);
5855   format %{ "!MEMBAR-release (CAS in succeeding FastUnlock so empty encoding)" %}
5856   ins_encode( );
5857   ins_pipe(empty);
5858 %}
5859 
5860 instruct membar_volatile() %{
5861   match(MemBarVolatile);
5862   ins_cost(4*MEMORY_REF_COST);
5863 
5864   size(4);
5865   format %{ "MEMBAR-volatile" %}
5866   ins_encode %{
5867     __ membar(MacroAssembler::StoreLoad, noreg);
5868   %}
5869   ins_pipe(long_memory_op);
5870 %}
5871 
5872 instruct unnecessary_membar_volatile() %{
5873   match(MemBarVolatile);
5874   predicate(Matcher::post_store_load_barrier(n));
5875   ins_cost(0);
5876 
5877   size(0);
5878   format %{ "!MEMBAR-volatile (unnecessary so empty encoding)" %}
5879   ins_encode( );
5880   ins_pipe(empty);
5881 %}
5882 
5883 //----------Register Move Instructions-----------------------------------------
5884 // instruct roundDouble_nop(regD dst) %{
5885 //   match(Set dst (RoundDouble dst));
5886 //   ins_pipe(empty);
5887 // %}
5888 
5889 
5890 // instruct roundFloat_nop(regF dst) %{
5891 //   match(Set dst (RoundFloat dst));
5892 //   ins_pipe(empty);
5893 // %}
5894 
5895 
5896 #ifdef AARCH64
5897 // 0 constant in register
5898 instruct zrImmI0(ZRRegI dst, immI0 imm) %{
5899   match(Set dst imm);
5900   size(0);
5901   ins_cost(0);
5902 
5903   format %{ "! ZR (int 0)" %}
5904   ins_encode( /*empty encoding*/ );
5905   ins_pipe(ialu_none);
5906 %}
5907 
5908 // 0 constant in register
5909 instruct zrImmL0(ZRRegL dst, immL0 imm) %{
5910   match(Set dst imm);
5911   size(0);
5912   ins_cost(0);
5913 
5914   format %{ "! ZR (long 0)" %}
5915   ins_encode( /*empty encoding*/ );
5916   ins_pipe(ialu_none);
5917 %}
5918 
5919 #ifdef XXX
5920 // 0 constant in register
5921 instruct zrImmN0(ZRRegN dst, immN0 imm) %{
5922   match(Set dst imm);
5923   size(0);
5924   ins_cost(0);
5925 
5926   format %{ "! ZR (compressed pointer NULL)" %}
5927   ins_encode( /*empty encoding*/ );
5928   ins_pipe(ialu_none);
5929 %}
5930 
5931 // 0 constant in register
5932 instruct zrImmP0(ZRRegP dst, immP0 imm) %{
5933   match(Set dst imm);
5934   size(0);
5935   ins_cost(0);
5936 
5937   format %{ "! ZR (NULL)" %}
5938   ins_encode( /*empty encoding*/ );
5939   ins_pipe(ialu_none);
5940 %}
5941 #endif
5942 #endif // AARCH64
5943 
5944 // Cast Index to Pointer for unsafe natives
5945 instruct castX2P(iRegX src, iRegP dst) %{
5946   match(Set dst (CastX2P src));
5947 
5948   format %{ "MOV    $dst,$src\t! IntX->Ptr if $dst != $src" %}
5949   ins_encode %{
5950     if ($dst$$Register !=  $src$$Register) {
5951       __ mov($dst$$Register, $src$$Register);
5952     }
5953   %}
5954   ins_pipe(ialu_reg);
5955 %}
5956 
5957 // Cast Pointer to Index for unsafe natives
5958 instruct castP2X(iRegP src, iRegX dst) %{
5959   match(Set dst (CastP2X src));
5960 
5961   format %{ "MOV    $dst,$src\t! Ptr->IntX if $dst != $src" %}
5962   ins_encode %{
5963     if ($dst$$Register !=  $src$$Register) {
5964       __ mov($dst$$Register, $src$$Register);
5965     }
5966   %}
5967   ins_pipe(ialu_reg);
5968 %}
5969 
5970 #ifndef AARCH64
5971 //----------Conditional Move---------------------------------------------------
5972 // Conditional move
5973 instruct cmovIP_reg(cmpOpP cmp, flagsRegP pcc, iRegI dst, iRegI src) %{
5974   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
5975   ins_cost(150);
5976   size(4);
5977   format %{ "MOV$cmp  $dst,$src\t! int" %}
5978   ins_encode %{
5979     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
5980   %}
5981   ins_pipe(ialu_reg);
5982 %}
5983 #endif
5984 
5985 #ifdef AARCH64
5986 instruct cmovI_reg3(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src1, iRegI src2) %{
5987   match(Set dst (CMoveI (Binary cmp icc) (Binary src2 src1)));
5988   ins_cost(150);
5989   size(4);
5990   format %{ "CSEL $dst,$src1,$src2,$cmp\t! int" %}
5991   ins_encode %{
5992     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
5993   %}
5994   ins_pipe(ialu_reg);
5995 %}
5996 
5997 instruct cmovL_reg3(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src1, iRegL src2) %{
5998   match(Set dst (CMoveL (Binary cmp icc) (Binary src2 src1)));
5999   ins_cost(150);
6000   size(4);
6001   format %{ "CSEL $dst,$src1,$src2,$cmp\t! long" %}
6002   ins_encode %{
6003     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6004   %}
6005   ins_pipe(ialu_reg);
6006 %}
6007 
6008 instruct cmovP_reg3(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src1, iRegP src2) %{
6009   match(Set dst (CMoveP (Binary cmp icc) (Binary src2 src1)));
6010   ins_cost(150);
6011   size(4);
6012   format %{ "CSEL $dst,$src1,$src2,$cmp\t! ptr" %}
6013   ins_encode %{
6014     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6015   %}
6016   ins_pipe(ialu_reg);
6017 %}
6018 
6019 instruct cmovN_reg3(cmpOp cmp, flagsReg icc, iRegN dst, iRegN src1, iRegN src2) %{
6020   match(Set dst (CMoveN (Binary cmp icc) (Binary src2 src1)));
6021   ins_cost(150);
6022   size(4);
6023   format %{ "CSEL $dst,$src1,$src2,$cmp\t! compressed ptr" %}
6024   ins_encode %{
6025     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6026   %}
6027   ins_pipe(ialu_reg);
6028 %}
6029 
6030 instruct cmovIP_reg3(cmpOpP cmp, flagsRegP icc, iRegI dst, iRegI src1, iRegI src2) %{
6031   match(Set dst (CMoveI (Binary cmp icc) (Binary src2 src1)));
6032   ins_cost(150);
6033   size(4);
6034   format %{ "CSEL $dst,$src1,$src2,$cmp\t! int" %}
6035   ins_encode %{
6036     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6037   %}
6038   ins_pipe(ialu_reg);
6039 %}
6040 
6041 instruct cmovLP_reg3(cmpOpP cmp, flagsRegP icc, iRegL dst, iRegL src1, iRegL src2) %{
6042   match(Set dst (CMoveL (Binary cmp icc) (Binary src2 src1)));
6043   ins_cost(150);
6044   size(4);
6045   format %{ "CSEL $dst,$src1,$src2,$cmp\t! long" %}
6046   ins_encode %{
6047     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6048   %}
6049   ins_pipe(ialu_reg);
6050 %}
6051 
6052 instruct cmovPP_reg3(cmpOpP cmp, flagsRegP icc, iRegP dst, iRegP src1, iRegP src2) %{
6053   match(Set dst (CMoveP (Binary cmp icc) (Binary src2 src1)));
6054   ins_cost(150);
6055   size(4);
6056   format %{ "CSEL $dst,$src1,$src2,$cmp\t! ptr" %}
6057   ins_encode %{
6058     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6059   %}
6060   ins_pipe(ialu_reg);
6061 %}
6062 
6063 instruct cmovNP_reg3(cmpOpP cmp, flagsRegP icc, iRegN dst, iRegN src1, iRegN src2) %{
6064   match(Set dst (CMoveN (Binary cmp icc) (Binary src2 src1)));
6065   ins_cost(150);
6066   size(4);
6067   format %{ "CSEL $dst,$src1,$src2,$cmp\t! compressed ptr" %}
6068   ins_encode %{
6069     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6070   %}
6071   ins_pipe(ialu_reg);
6072 %}
6073 
6074 instruct cmovIU_reg3(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src1, iRegI src2) %{
6075   match(Set dst (CMoveI (Binary cmp icc) (Binary src2 src1)));
6076   ins_cost(150);
6077   size(4);
6078   format %{ "CSEL $dst,$src1,$src2,$cmp\t! int" %}
6079   ins_encode %{
6080     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6081   %}
6082   ins_pipe(ialu_reg);
6083 %}
6084 
6085 instruct cmovLU_reg3(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src1, iRegL src2) %{
6086   match(Set dst (CMoveL (Binary cmp icc) (Binary src2 src1)));
6087   ins_cost(150);
6088   size(4);
6089   format %{ "CSEL $dst,$src1,$src2,$cmp\t! long" %}
6090   ins_encode %{
6091     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6092   %}
6093   ins_pipe(ialu_reg);
6094 %}
6095 
6096 instruct cmovPU_reg3(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src1, iRegP src2) %{
6097   match(Set dst (CMoveP (Binary cmp icc) (Binary src2 src1)));
6098   ins_cost(150);
6099   size(4);
6100   format %{ "CSEL $dst,$src1,$src2,$cmp\t! ptr" %}
6101   ins_encode %{
6102     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6103   %}
6104   ins_pipe(ialu_reg);
6105 %}
6106 
6107 instruct cmovNU_reg3(cmpOpU cmp, flagsRegU icc, iRegN dst, iRegN src1, iRegN src2) %{
6108   match(Set dst (CMoveN (Binary cmp icc) (Binary src2 src1)));
6109   ins_cost(150);
6110   size(4);
6111   format %{ "CSEL $dst,$src1,$src2,$cmp\t! compressed ptr" %}
6112   ins_encode %{
6113     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6114   %}
6115   ins_pipe(ialu_reg);
6116 %}
6117 
6118 instruct cmovIZ_reg3(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, iRegI src1, iRegI src2) %{
6119   match(Set dst (CMoveI (Binary cmp icc) (Binary src2 src1)));
6120   ins_cost(150);
6121   size(4);
6122   format %{ "CSEL $dst,$src1,$src2,$cmp\t! int" %}
6123   ins_encode %{
6124     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6125   %}
6126   ins_pipe(ialu_reg);
6127 %}
6128 
6129 instruct cmovLZ_reg3(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, iRegL src1, iRegL src2) %{
6130   match(Set dst (CMoveL (Binary cmp icc) (Binary src2 src1)));
6131   ins_cost(150);
6132   size(4);
6133   format %{ "CSEL $dst,$src1,$src2,$cmp\t! long" %}
6134   ins_encode %{
6135     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6136   %}
6137   ins_pipe(ialu_reg);
6138 %}
6139 
6140 instruct cmovPZ_reg3(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, iRegP src1, iRegP src2) %{
6141   match(Set dst (CMoveP (Binary cmp icc) (Binary src2 src1)));
6142   ins_cost(150);
6143   size(4);
6144   format %{ "CSEL $dst,$src1,$src2,$cmp\t! ptr" %}
6145   ins_encode %{
6146     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6147   %}
6148   ins_pipe(ialu_reg);
6149 %}
6150 
6151 instruct cmovNZ_reg3(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegN dst, iRegN src1, iRegN src2) %{
6152   match(Set dst (CMoveN (Binary cmp icc) (Binary src2 src1)));
6153   ins_cost(150);
6154   size(4);
6155   format %{ "CSEL $dst,$src1,$src2,$cmp\t! compressed ptr" %}
6156   ins_encode %{
6157     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6158   %}
6159   ins_pipe(ialu_reg);
6160 %}
6161 #endif // AARCH64
6162 
6163 #ifndef AARCH64
6164 instruct cmovIP_immMov(cmpOpP cmp, flagsRegP pcc, iRegI dst, immIMov src) %{
6165   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
6166   ins_cost(140);
6167   size(4);
6168   format %{ "MOV$cmp  $dst,$src" %}
6169   ins_encode %{
6170     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6171   %}
6172   ins_pipe(ialu_imm);
6173 %}
6174 
6175 instruct cmovIP_imm16(cmpOpP cmp, flagsRegP pcc, iRegI dst, immI16 src) %{
6176   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
6177   ins_cost(140);
6178   size(4);
6179   format %{ "MOVw$cmp  $dst,$src" %}
6180   ins_encode %{
6181     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6182   %}
6183   ins_pipe(ialu_imm);
6184 %}
6185 #endif
6186 
6187 instruct cmovI_reg(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src) %{
6188   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
6189   ins_cost(150);
6190   size(4);
6191   format %{ "MOV$cmp  $dst,$src" %}
6192   ins_encode %{
6193     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6194   %}
6195   ins_pipe(ialu_reg);
6196 %}
6197 
6198 #ifdef AARCH64
6199 instruct cmovL_reg(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src) %{
6200   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
6201   ins_cost(150);
6202   size(4);
6203   format %{ "MOV$cmp  $dst,$src\t! long" %}
6204   ins_encode %{
6205     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6206   %}
6207   ins_pipe(ialu_reg);
6208 %}
6209 #endif
6210 
6211 #ifndef AARCH64
6212 instruct cmovI_immMov(cmpOp cmp, flagsReg icc, iRegI dst, immIMov src) %{
6213   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
6214   ins_cost(140);
6215   size(4);
6216   format %{ "MOV$cmp  $dst,$src" %}
6217   ins_encode %{
6218     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6219   %}
6220   ins_pipe(ialu_imm);
6221 %}
6222 
6223 instruct cmovII_imm16(cmpOp cmp, flagsReg icc, iRegI dst, immI16 src) %{
6224   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
6225   ins_cost(140);
6226   size(4);
6227   format %{ "MOVw$cmp  $dst,$src" %}
6228   ins_encode %{
6229     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6230   %}
6231   ins_pipe(ialu_imm);
6232 %}
6233 #endif
6234 
6235 instruct cmovII_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, iRegI src) %{
6236   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
6237   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
6238             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
6239             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
6240             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
6241   ins_cost(150);
6242   size(4);
6243   format %{ "MOV$cmp  $dst,$src" %}
6244   ins_encode %{
6245     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6246   %}
6247   ins_pipe(ialu_reg);
6248 %}
6249 
6250 #ifndef AARCH64
6251 instruct cmovII_immMov_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immIMov src) %{
6252   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
6253   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
6254             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
6255             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
6256             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
6257   ins_cost(140);
6258   size(4);
6259   format %{ "MOV$cmp  $dst,$src" %}
6260   ins_encode %{
6261     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6262   %}
6263   ins_pipe(ialu_imm);
6264 %}
6265 
6266 instruct cmovII_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immI16 src) %{
6267   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
6268   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
6269             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
6270             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
6271             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
6272   ins_cost(140);
6273   size(4);
6274   format %{ "MOVW$cmp  $dst,$src" %}
6275   ins_encode %{
6276     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6277   %}
6278   ins_pipe(ialu_imm);
6279 %}
6280 #endif
6281 
6282 instruct cmovIIu_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
6283   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
6284   ins_cost(150);
6285   size(4);
6286   format %{ "MOV$cmp  $dst,$src" %}
6287   ins_encode %{
6288     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6289   %}
6290   ins_pipe(ialu_reg);
6291 %}
6292 
6293 #ifndef AARCH64
6294 instruct cmovIIu_immMov(cmpOpU cmp, flagsRegU icc, iRegI dst, immIMov src) %{
6295   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
6296   ins_cost(140);
6297   size(4);
6298   format %{ "MOV$cmp  $dst,$src" %}
6299   ins_encode %{
6300     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6301   %}
6302   ins_pipe(ialu_imm);
6303 %}
6304 
6305 instruct cmovIIu_imm16(cmpOpU cmp, flagsRegU icc, iRegI dst, immI16 src) %{
6306   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
6307   ins_cost(140);
6308   size(4);
6309   format %{ "MOVW$cmp  $dst,$src" %}
6310   ins_encode %{
6311     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6312   %}
6313   ins_pipe(ialu_imm);
6314 %}
6315 #endif
6316 
6317 // Conditional move
6318 instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{
6319   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
6320   ins_cost(150);
6321   size(4);
6322   format %{ "MOV$cmp  $dst,$src" %}
6323   ins_encode %{
6324     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6325   %}
6326   ins_pipe(ialu_reg);
6327 %}
6328 
6329 instruct cmovPP_imm(cmpOpP cmp, flagsRegP pcc, iRegP dst, immP0 src) %{
6330   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
6331   ins_cost(140);
6332   size(4);
6333 #ifdef AARCH64
6334   format %{ "MOV$cmp  $dst,ZR" %}
6335 #else
6336   format %{ "MOV$cmp  $dst,$src" %}
6337 #endif
6338   ins_encode %{
6339 #ifdef AARCH64
6340     __ mov($dst$$Register,             ZR, (AsmCondition)($cmp$$cmpcode));
6341 #else
6342     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6343 #endif
6344   %}
6345   ins_pipe(ialu_imm);
6346 %}
6347 
6348 // This instruction also works with CmpN so we don't need cmovPN_reg.
6349 instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{
6350   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
6351   ins_cost(150);
6352 
6353   size(4);
6354   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
6355   ins_encode %{
6356     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6357   %}
6358   ins_pipe(ialu_reg);
6359 %}
6360 
6361 instruct cmovPI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, iRegP src) %{
6362   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
6363   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
6364             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
6365             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
6366             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
6367   ins_cost(150);
6368 
6369   size(4);
6370   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
6371   ins_encode %{
6372     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6373   %}
6374   ins_pipe(ialu_reg);
6375 %}
6376 
6377 instruct cmovPIu_reg(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src) %{
6378   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
6379   ins_cost(150);
6380 
6381   size(4);
6382   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
6383   ins_encode %{
6384     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6385   %}
6386   ins_pipe(ialu_reg);
6387 %}
6388 
6389 instruct cmovPI_imm(cmpOp cmp, flagsReg icc, iRegP dst, immP0 src) %{
6390   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
6391   ins_cost(140);
6392 
6393   size(4);
6394 #ifdef AARCH64
6395   format %{ "MOV$cmp  $dst,ZR\t! ptr" %}
6396 #else
6397   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
6398 #endif
6399   ins_encode %{
6400 #ifdef AARCH64
6401     __ mov($dst$$Register,             ZR, (AsmCondition)($cmp$$cmpcode));
6402 #else
6403     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6404 #endif
6405   %}
6406   ins_pipe(ialu_imm);
6407 %}
6408 
6409 instruct cmovPI_imm_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, immP0 src) %{
6410   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
6411   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
6412             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
6413             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
6414             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
6415   ins_cost(140);
6416 
6417   size(4);
6418 #ifdef AARCH64
6419   format %{ "MOV$cmp  $dst,ZR\t! ptr" %}
6420 #else
6421   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
6422 #endif
6423   ins_encode %{
6424 #ifdef AARCH64
6425     __ mov($dst$$Register,             ZR, (AsmCondition)($cmp$$cmpcode));
6426 #else
6427     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6428 #endif
6429   %}
6430   ins_pipe(ialu_imm);
6431 %}
6432 
6433 instruct cmovPIu_imm(cmpOpU cmp, flagsRegU icc, iRegP dst, immP0 src) %{
6434   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
6435   ins_cost(140);
6436 
6437   size(4);
6438 #ifdef AARCH64
6439   format %{ "MOV$cmp  $dst,ZR\t! ptr" %}
6440 #else
6441   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
6442 #endif
6443   ins_encode %{
6444 #ifdef AARCH64
6445     __ mov($dst$$Register,             ZR, (AsmCondition)($cmp$$cmpcode));
6446 #else
6447     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6448 #endif
6449   %}
6450   ins_pipe(ialu_imm);
6451 %}
6452 
6453 #ifdef AARCH64
6454 // Conditional move
6455 instruct cmovF_reg(cmpOp cmp, flagsReg icc, regF dst, regF src1, regF src2) %{
6456   match(Set dst (CMoveF (Binary cmp icc) (Binary src2 src1)));
6457   ins_cost(150);
6458   size(4);
6459   format %{ "FCSEL_s $dst,$src1,$src2,$cmp" %}
6460   ins_encode %{
6461     __ fcsel_s($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6462   %}
6463   ins_pipe(int_conditional_float_move);
6464 %}
6465 
6466 instruct cmovD_reg(cmpOp cmp, flagsReg icc, regD dst, regD src1, regD src2) %{
6467   match(Set dst (CMoveD (Binary cmp icc) (Binary src2 src1)));
6468   ins_cost(150);
6469   size(4);
6470   format %{ "FCSEL_d $dst,$src1,$src2,$cmp" %}
6471   ins_encode %{
6472     __ fcsel_d($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6473   %}
6474   ins_pipe(int_conditional_float_move);
6475 %}
6476 
6477 instruct cmovFP_reg(cmpOpP cmp, flagsRegP icc, regF dst, regF src1, regF src2) %{
6478   match(Set dst (CMoveF (Binary cmp icc) (Binary src2 src1)));
6479   ins_cost(150);
6480   size(4);
6481   format %{ "FCSEL_s $dst,$src1,$src2,$cmp" %}
6482   ins_encode %{
6483     __ fcsel_s($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6484   %}
6485   ins_pipe(int_conditional_float_move);
6486 %}
6487 
6488 instruct cmovDP_reg(cmpOpP cmp, flagsRegP icc, regD dst, regD src1, regD src2) %{
6489   match(Set dst (CMoveD (Binary cmp icc) (Binary src2 src1)));
6490   ins_cost(150);
6491   size(4);
6492   format %{ "FCSEL_d $dst,$src1,$src2,$cmp" %}
6493   ins_encode %{
6494     __ fcsel_d($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6495   %}
6496   ins_pipe(int_conditional_float_move);
6497 %}
6498 
6499 instruct cmovFU_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src1, regF src2) %{
6500   match(Set dst (CMoveF (Binary cmp icc) (Binary src2 src1)));
6501   ins_cost(150);
6502   size(4);
6503   format %{ "FCSEL_s $dst,$src1,$src2,$cmp" %}
6504   ins_encode %{
6505     __ fcsel_s($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6506   %}
6507   ins_pipe(int_conditional_float_move);
6508 %}
6509 
6510 instruct cmovDU_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src1, regD src2) %{
6511   match(Set dst (CMoveD (Binary cmp icc) (Binary src2 src1)));
6512   ins_cost(150);
6513   size(4);
6514   format %{ "FCSEL_d $dst,$src1,$src2,$cmp" %}
6515   ins_encode %{
6516     __ fcsel_d($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6517   %}
6518   ins_pipe(int_conditional_float_move);
6519 %}
6520 
6521 instruct cmovFZ_reg(cmpOp0 cmp, flagsReg_EQNELTGE icc, regF dst, regF src1, regF src2) %{
6522   match(Set dst (CMoveF (Binary cmp icc) (Binary src2 src1)));
6523   ins_cost(150);
6524   size(4);
6525   format %{ "FCSEL_s $dst,$src1,$src2,$cmp" %}
6526   ins_encode %{
6527     __ fcsel_s($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6528   %}
6529   ins_pipe(int_conditional_float_move);
6530 %}
6531 
6532 instruct cmovDZ_reg(cmpOp0 cmp, flagsReg_EQNELTGE icc, regD dst, regD src1, regD src2) %{
6533   match(Set dst (CMoveD (Binary cmp icc) (Binary src2 src1)));
6534   ins_cost(150);
6535   size(4);
6536   format %{ "FCSEL_d $dst,$src1,$src2,$cmp" %}
6537   ins_encode %{
6538     __ fcsel_d($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6539   %}
6540   ins_pipe(int_conditional_float_move);
6541 %}
6542 
6543 #else // !AARCH64
6544 
6545 // Conditional move
6546 instruct cmovFP_reg(cmpOpP cmp, flagsRegP pcc, regF dst, regF src) %{
6547   match(Set dst (CMoveF (Binary cmp pcc) (Binary dst src)));
6548   ins_cost(150);
6549   size(4);
6550   format %{ "FCPYS$cmp $dst,$src" %}
6551   ins_encode %{
6552     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6553   %}
6554   ins_pipe(int_conditional_float_move);
6555 %}
6556 
6557 instruct cmovFI_reg(cmpOp cmp, flagsReg icc, regF dst, regF src) %{
6558   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
6559   ins_cost(150);
6560 
6561   size(4);
6562   format %{ "FCPYS$cmp $dst,$src" %}
6563   ins_encode %{
6564     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6565   %}
6566   ins_pipe(int_conditional_float_move);
6567 %}
6568 
6569 instruct cmovFI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regF dst, regF src) %{
6570   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
6571   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
6572             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
6573             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
6574             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
6575   ins_cost(150);
6576 
6577   size(4);
6578   format %{ "FCPYS$cmp $dst,$src" %}
6579   ins_encode %{
6580     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6581   %}
6582   ins_pipe(int_conditional_float_move);
6583 %}
6584 
6585 instruct cmovFIu_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src) %{
6586   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
6587   ins_cost(150);
6588 
6589   size(4);
6590   format %{ "FCPYS$cmp $dst,$src" %}
6591   ins_encode %{
6592     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6593   %}
6594   ins_pipe(int_conditional_float_move);
6595 %}
6596 
6597 // Conditional move
6598 instruct cmovDP_reg(cmpOpP cmp, flagsRegP pcc, regD dst, regD src) %{
6599   match(Set dst (CMoveD (Binary cmp pcc) (Binary dst src)));
6600   ins_cost(150);
6601   size(4);
6602   format %{ "FCPYD$cmp $dst,$src" %}
6603   ins_encode %{
6604     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6605   %}
6606   ins_pipe(int_conditional_double_move);
6607 %}
6608 
6609 instruct cmovDI_reg(cmpOp cmp, flagsReg icc, regD dst, regD src) %{
6610   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
6611   ins_cost(150);
6612 
6613   size(4);
6614   format %{ "FCPYD$cmp $dst,$src" %}
6615   ins_encode %{
6616     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6617   %}
6618   ins_pipe(int_conditional_double_move);
6619 %}
6620 
6621 instruct cmovDI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regD dst, regD src) %{
6622   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
6623   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
6624   ins_cost(150);
6625 
6626   size(4);
6627   format %{ "FCPYD$cmp $dst,$src" %}
6628   ins_encode %{
6629     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6630   %}
6631   ins_pipe(int_conditional_double_move);
6632 %}
6633 
6634 instruct cmovDIu_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src) %{
6635   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
6636   ins_cost(150);
6637 
6638   size(4);
6639   format %{ "FCPYD$cmp $dst,$src" %}
6640   ins_encode %{
6641     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6642   %}
6643   ins_pipe(int_conditional_double_move);
6644 %}
6645 
6646 // Conditional move
6647 instruct cmovLP_reg(cmpOpP cmp, flagsRegP pcc, iRegL dst, iRegL src) %{
6648   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
6649   ins_cost(150);
6650 
6651   size(8);
6652   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
6653             "MOV$cmp  $dst.hi,$src.hi" %}
6654   ins_encode %{
6655     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6656     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
6657   %}
6658   ins_pipe(ialu_reg);
6659 %}
6660 
6661 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6662 // (hi($con$$constant), lo($con$$constant)) becomes
6663 instruct cmovLP_immRot(cmpOpP cmp, flagsRegP pcc, iRegL dst, immLlowRot src) %{
6664   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
6665   ins_cost(140);
6666 
6667   size(8);
6668   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
6669             "MOV$cmp  $dst.hi,0" %}
6670   ins_encode %{
6671     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6672     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
6673   %}
6674   ins_pipe(ialu_imm);
6675 %}
6676 
6677 instruct cmovLP_imm16(cmpOpP cmp, flagsRegP pcc, iRegL dst, immL16 src) %{
6678   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
6679   ins_cost(140);
6680 
6681   size(8);
6682   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
6683             "MOV$cmp  $dst.hi,0" %}
6684   ins_encode %{
6685     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6686     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
6687   %}
6688   ins_pipe(ialu_imm);
6689 %}
6690 
6691 instruct cmovLI_reg(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src) %{
6692   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
6693   ins_cost(150);
6694 
6695   size(8);
6696   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
6697             "MOV$cmp  $dst.hi,$src.hi" %}
6698   ins_encode %{
6699     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6700     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
6701   %}
6702   ins_pipe(ialu_reg);
6703 %}
6704 
6705 instruct cmovLI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, iRegL src) %{
6706   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
6707   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
6708             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
6709             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
6710             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
6711   ins_cost(150);
6712 
6713   size(8);
6714   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
6715             "MOV$cmp  $dst.hi,$src.hi" %}
6716   ins_encode %{
6717     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6718     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
6719   %}
6720   ins_pipe(ialu_reg);
6721 %}
6722 
6723 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6724 // (hi($con$$constant), lo($con$$constant)) becomes
6725 instruct cmovLI_immRot(cmpOp cmp, flagsReg icc, iRegL dst, immLlowRot src) %{
6726   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
6727   ins_cost(140);
6728 
6729   size(8);
6730   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
6731             "MOV$cmp  $dst.hi,0" %}
6732   ins_encode %{
6733     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6734     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
6735   %}
6736   ins_pipe(ialu_imm);
6737 %}
6738 
6739 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6740 // (hi($con$$constant), lo($con$$constant)) becomes
6741 instruct cmovLI_immRot_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immLlowRot src) %{
6742   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
6743   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
6744             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
6745             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
6746             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
6747   ins_cost(140);
6748 
6749   size(8);
6750   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
6751             "MOV$cmp  $dst.hi,0" %}
6752   ins_encode %{
6753     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6754     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
6755   %}
6756   ins_pipe(ialu_imm);
6757 %}
6758 
6759 instruct cmovLI_imm16(cmpOp cmp, flagsReg icc, iRegL dst, immL16 src) %{
6760   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
6761   ins_cost(140);
6762 
6763   size(8);
6764   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
6765             "MOV$cmp  $dst.hi,0" %}
6766   ins_encode %{
6767     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6768     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
6769   %}
6770   ins_pipe(ialu_imm);
6771 %}
6772 
6773 instruct cmovLI_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immL16 src) %{
6774   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
6775   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
6776             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
6777             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
6778             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
6779   ins_cost(140);
6780 
6781   size(8);
6782   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
6783             "MOV$cmp  $dst.hi,0" %}
6784   ins_encode %{
6785     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6786     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
6787   %}
6788   ins_pipe(ialu_imm);
6789 %}
6790 
6791 instruct cmovLIu_reg(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src) %{
6792   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
6793   ins_cost(150);
6794 
6795   size(8);
6796   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
6797             "MOV$cmp  $dst.hi,$src.hi" %}
6798   ins_encode %{
6799     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6800     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
6801   %}
6802   ins_pipe(ialu_reg);
6803 %}
6804 #endif // !AARCH64
6805 
6806 
6807 //----------OS and Locking Instructions----------------------------------------
6808 
6809 // This name is KNOWN by the ADLC and cannot be changed.
6810 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
6811 // for this guy.
6812 instruct tlsLoadP(RthreadRegP dst) %{
6813   match(Set dst (ThreadLocal));
6814 
6815   size(0);
6816   ins_cost(0);
6817   format %{ "! TLS is in $dst" %}
6818   ins_encode( /*empty encoding*/ );
6819   ins_pipe(ialu_none);
6820 %}
6821 
6822 instruct checkCastPP( iRegP dst ) %{
6823   match(Set dst (CheckCastPP dst));
6824 
6825   size(0);
6826   format %{ "! checkcastPP of $dst" %}
6827   ins_encode( /*empty encoding*/ );
6828   ins_pipe(empty);
6829 %}
6830 
6831 
6832 instruct castPP( iRegP dst ) %{
6833   match(Set dst (CastPP dst));
6834   format %{ "! castPP of $dst" %}
6835   ins_encode( /*empty encoding*/ );
6836   ins_pipe(empty);
6837 %}
6838 
6839 instruct castII( iRegI dst ) %{
6840   match(Set dst (CastII dst));
6841   format %{ "! castII of $dst" %}
6842   ins_encode( /*empty encoding*/ );
6843   ins_cost(0);
6844   ins_pipe(empty);
6845 %}
6846 
6847 //----------Arithmetic Instructions--------------------------------------------
6848 // Addition Instructions
6849 // Register Addition
6850 instruct addI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6851   match(Set dst (AddI src1 src2));
6852 
6853   size(4);
6854   format %{ "add_32 $dst,$src1,$src2\t! int" %}
6855   ins_encode %{
6856     __ add_32($dst$$Register, $src1$$Register, $src2$$Register);
6857   %}
6858   ins_pipe(ialu_reg_reg);
6859 %}
6860 
6861 #ifndef AARCH64
6862 instruct addshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6863   match(Set dst (AddI (LShiftI src1 src2) src3));
6864 
6865   size(4);
6866   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
6867   ins_encode %{
6868     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
6869   %}
6870   ins_pipe(ialu_reg_reg);
6871 %}
6872 #endif
6873 
6874 #ifdef AARCH64
6875 #ifdef TODO
6876 instruct addshlL_reg_imm_reg(iRegL dst, iRegL src1, immU6 src2, iRegL src3) %{
6877   match(Set dst (AddL (LShiftL src1 src2) src3));
6878 
6879   size(4);
6880   format %{ "ADD    $dst,$src3,$src1<<$src2\t! long" %}
6881   ins_encode %{
6882     __ add($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
6883   %}
6884   ins_pipe(ialu_reg_reg);
6885 %}
6886 #endif
6887 #endif
6888 
6889 instruct addshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
6890   match(Set dst (AddI (LShiftI src1 src2) src3));
6891 
6892   size(4);
6893   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
6894   ins_encode %{
6895     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
6896   %}
6897   ins_pipe(ialu_reg_reg);
6898 %}
6899 
6900 #ifndef AARCH64
6901 instruct addsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6902   match(Set dst (AddI (RShiftI src1 src2) src3));
6903 
6904   size(4);
6905   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
6906   ins_encode %{
6907     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
6908   %}
6909   ins_pipe(ialu_reg_reg);
6910 %}
6911 #endif
6912 
6913 instruct addsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
6914   match(Set dst (AddI (RShiftI src1 src2) src3));
6915 
6916   size(4);
6917   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
6918   ins_encode %{
6919     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
6920   %}
6921   ins_pipe(ialu_reg_reg);
6922 %}
6923 
6924 #ifndef AARCH64
6925 instruct addshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6926   match(Set dst (AddI (URShiftI src1 src2) src3));
6927 
6928   size(4);
6929   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
6930   ins_encode %{
6931     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
6932   %}
6933   ins_pipe(ialu_reg_reg);
6934 %}
6935 #endif
6936 
6937 instruct addshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
6938   match(Set dst (AddI (URShiftI src1 src2) src3));
6939 
6940   size(4);
6941   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
6942   ins_encode %{
6943     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
6944   %}
6945   ins_pipe(ialu_reg_reg);
6946 %}
6947 
6948 // Immediate Addition
6949 instruct addI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
6950   match(Set dst (AddI src1 src2));
6951 
6952   size(4);
6953   format %{ "add_32 $dst,$src1,$src2\t! int" %}
6954   ins_encode %{
6955     __ add_32($dst$$Register, $src1$$Register, $src2$$constant);
6956   %}
6957   ins_pipe(ialu_reg_imm);
6958 %}
6959 
6960 // Pointer Register Addition
6961 instruct addP_reg_reg(iRegP dst, iRegP src1, iRegX src2) %{
6962   match(Set dst (AddP src1 src2));
6963 
6964   size(4);
6965   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
6966   ins_encode %{
6967     __ add($dst$$Register, $src1$$Register, $src2$$Register);
6968   %}
6969   ins_pipe(ialu_reg_reg);
6970 %}
6971 
6972 #ifdef AARCH64
6973 // unshifted I2L operand
6974 operand unshiftedI2L(iRegI src2) %{
6975 //constraint(ALLOC_IN_RC(sp_ptr_reg));
6976   match(ConvI2L src2);
6977 
6978   op_cost(1);
6979   format %{ "$src2.w" %}
6980   interface(MEMORY_INTER) %{
6981     base($src2);
6982     index(0xff);
6983     scale(0x0);
6984     disp(0x0);
6985   %}
6986 %}
6987 
6988 // shifted I2L operand
6989 operand shiftedI2L(iRegI src2, immI_0_4 src3) %{
6990 //constraint(ALLOC_IN_RC(sp_ptr_reg));
6991   match(LShiftX (ConvI2L src2) src3);
6992 
6993   op_cost(1);
6994   format %{ "$src2.w << $src3" %}
6995   interface(MEMORY_INTER) %{
6996     base($src2);
6997     index(0xff);
6998     scale($src3);
6999     disp(0x0);
7000   %}
7001 %}
7002 
7003 opclass shiftedRegI(shiftedI2L, unshiftedI2L);
7004 
7005 instruct shlL_reg_regI(iRegL dst, iRegI src1, immU6 src2) %{
7006   match(Set dst (LShiftL (ConvI2L src1) src2));
7007 
7008   size(4);
7009   format %{ "LSL    $dst,$src1.w,$src2\t! ptr" %}
7010   ins_encode %{
7011     int c = $src2$$constant;
7012     int r = 64 - c;
7013     int s = 31;
7014     if (s >= r) {
7015       s = r - 1;
7016     }
7017     __ sbfm($dst$$Register, $src1$$Register, r, s);
7018   %}
7019   ins_pipe(ialu_reg_reg);
7020 %}
7021 
7022 instruct addP_reg_regI(iRegP dst, iRegP src1, shiftedRegI src2) %{
7023   match(Set dst (AddP src1 src2));
7024 
7025   ins_cost(DEFAULT_COST * 3/2);
7026   size(4);
7027   format %{ "ADD    $dst,$src1,$src2, sxtw\t! ptr" %}
7028   ins_encode %{
7029     Register base = reg_to_register_object($src2$$base);
7030     __ add($dst$$Register, $src1$$Register, base, ex_sxtw, $src2$$scale);
7031   %}
7032   ins_pipe(ialu_reg_reg);
7033 %}
7034 #endif
7035 
7036 // shifted iRegX operand
7037 operand shiftedX(iRegX src2, shimmX src3) %{
7038 //constraint(ALLOC_IN_RC(sp_ptr_reg));
7039   match(LShiftX src2 src3);
7040 
7041   op_cost(1);
7042   format %{ "$src2 << $src3" %}
7043   interface(MEMORY_INTER) %{
7044     base($src2);
7045     index(0xff);
7046     scale($src3);
7047     disp(0x0);
7048   %}
7049 %}
7050 
7051 instruct addshlP_reg_reg_imm(iRegP dst, iRegP src1, shiftedX src2) %{
7052   match(Set dst (AddP src1 src2));
7053 
7054   ins_cost(DEFAULT_COST * 3/2);
7055   size(4);
7056   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
7057   ins_encode %{
7058     Register base = reg_to_register_object($src2$$base);
7059     __ add($dst$$Register, $src1$$Register, AsmOperand(base, lsl, $src2$$scale));
7060   %}
7061   ins_pipe(ialu_reg_reg);
7062 %}
7063 
7064 // Pointer Immediate Addition
7065 instruct addP_reg_aimmX(iRegP dst, iRegP src1, aimmX src2) %{
7066   match(Set dst (AddP src1 src2));
7067 
7068   size(4);
7069   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
7070   ins_encode %{
7071     __ add($dst$$Register, $src1$$Register, $src2$$constant);
7072   %}
7073   ins_pipe(ialu_reg_imm);
7074 %}
7075 
7076 // Long Addition
7077 #ifdef AARCH64
7078 instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
7079   match(Set dst (AddL src1 src2));
7080   size(4);
7081   format %{ "ADD     $dst,$src1,$src2\t! long" %}
7082   ins_encode %{
7083     __ add($dst$$Register, $src1$$Register, $src2$$Register);
7084   %}
7085   ins_pipe(ialu_reg_reg);
7086 %}
7087 
7088 instruct addL_reg_regI(iRegL dst, iRegL src1, shiftedRegI src2) %{
7089   match(Set dst (AddL src1 src2));
7090 
7091   ins_cost(DEFAULT_COST * 3/2);
7092   size(4);
7093   format %{ "ADD    $dst,$src1,$src2, sxtw\t! long" %}
7094   ins_encode %{
7095     Register base = reg_to_register_object($src2$$base);
7096     __ add($dst$$Register, $src1$$Register, base, ex_sxtw, $src2$$scale);
7097   %}
7098   ins_pipe(ialu_reg_reg);
7099 %}
7100 #else
7101 instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg ccr) %{
7102   match(Set dst (AddL src1 src2));
7103   effect(KILL ccr);
7104   size(8);
7105   format %{ "ADDS    $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
7106             "ADC     $dst.hi,$src1.hi,$src2.hi" %}
7107   ins_encode %{
7108     __ adds($dst$$Register, $src1$$Register, $src2$$Register);
7109     __ adc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
7110   %}
7111   ins_pipe(ialu_reg_reg);
7112 %}
7113 #endif
7114 
7115 #ifdef AARCH64
7116 // Immediate Addition
7117 instruct addL_reg_aimm(iRegL dst, iRegL src1, aimmL src2) %{
7118   match(Set dst (AddL src1 src2));
7119 
7120   size(4);
7121   format %{ "ADD    $dst,$src1,$src2\t! long" %}
7122   ins_encode %{
7123     __ add($dst$$Register, $src1$$Register, $src2$$constant);
7124   %}
7125   ins_pipe(ialu_reg_imm);
7126 %}
7127 
7128 instruct addL_reg_immLneg(iRegL dst, iRegL src1, aimmLneg src2) %{
7129   match(Set dst (SubL src1 src2));
7130 
7131   size(4);
7132   format %{ "ADD    $dst,$src1,-($src2)\t! long" %}
7133   ins_encode %{
7134     __ add($dst$$Register, $src1$$Register, -$src2$$constant);
7135   %}
7136   ins_pipe(ialu_reg_imm);
7137 %}
7138 #else
7139 // TODO
7140 #endif
7141 
7142 #ifndef AARCH64
7143 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7144 // (hi($con$$constant), lo($con$$constant)) becomes
7145 instruct addL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg ccr) %{
7146   match(Set dst (AddL src1 con));
7147   effect(KILL ccr);
7148   size(8);
7149   format %{ "ADDS    $dst.lo,$src1.lo,$con\t! long\n\t"
7150             "ADC     $dst.hi,$src1.hi,0" %}
7151   ins_encode %{
7152     __ adds($dst$$Register, $src1$$Register, $con$$constant);
7153     __ adc($dst$$Register->successor(), $src1$$Register->successor(), 0);
7154   %}
7155   ins_pipe(ialu_reg_imm);
7156 %}
7157 #endif
7158 
7159 //----------Conditional_store--------------------------------------------------
7160 // Conditional-store of the updated heap-top.
7161 // Used during allocation of the shared heap.
7162 // Sets flags (EQ) on success.
7163 
7164 // TODO: optimize out barriers with AArch64 load-acquire/store-release
7165 // LoadP-locked.
7166 instruct loadPLocked(iRegP dst, memoryex mem) %{
7167   match(Set dst (LoadPLocked mem));
7168   size(4);
7169   format %{ "LDREX  $dst,$mem" %}
7170   ins_encode %{
7171 #ifdef AARCH64
7172     Register base = reg_to_register_object($mem$$base);
7173     __ ldxr($dst$$Register, base);
7174 #else
7175     __ ldrex($dst$$Register,$mem$$Address);
7176 #endif
7177   %}
7178   ins_pipe(iload_mem);
7179 %}
7180 
7181 instruct storePConditional( memoryex heap_top_ptr, iRegP oldval, iRegP newval, iRegI tmp, flagsRegP pcc ) %{
7182   predicate(_kids[1]->_kids[0]->_leaf->Opcode() == Op_LoadPLocked); // only works in conjunction with a LoadPLocked node
7183   match(Set pcc (StorePConditional heap_top_ptr (Binary oldval newval)));
7184   effect( TEMP tmp );
7185   size(8);
7186   format %{ "STREX  $tmp,$newval,$heap_top_ptr\n\t"
7187             "CMP    $tmp, 0" %}
7188   ins_encode %{
7189 #ifdef AARCH64
7190     Register base = reg_to_register_object($heap_top_ptr$$base);
7191     __ stxr($tmp$$Register, $newval$$Register, base);
7192 #else
7193     __ strex($tmp$$Register, $newval$$Register, $heap_top_ptr$$Address);
7194 #endif
7195     __ cmp($tmp$$Register, 0);
7196   %}
7197   ins_pipe( long_memory_op );
7198 %}
7199 
7200 // Conditional-store of an intx value.
7201 instruct storeXConditional( memoryex mem, iRegX oldval, iRegX newval, iRegX tmp, flagsReg icc ) %{
7202 #ifdef AARCH64
7203   match(Set icc (StoreLConditional mem (Binary oldval newval)));
7204   effect( TEMP tmp );
7205   size(28);
7206   format %{ "loop:\n\t"
7207             "LDXR     $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem], DOESN'T set $newval=[$mem] in any case\n\t"
7208             "SUBS     $tmp, $tmp, $oldval\n\t"
7209             "B.ne     done\n\t"
7210             "STXR     $tmp, $newval, $mem\n\t"
7211             "CBNZ_w   $tmp, loop\n\t"
7212             "CMP      $tmp, 0\n\t"
7213             "done:\n\t"
7214             "membar   LoadStore|LoadLoad" %}
7215 #else
7216   match(Set icc (StoreIConditional mem (Binary oldval newval)));
7217   effect( TEMP tmp );
7218   size(28);
7219   format %{ "loop: \n\t"
7220             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem], DOESN'T set $newval=[$mem] in any case\n\t"
7221             "XORS     $tmp,$tmp, $oldval\n\t"
7222             "STREX.eq $tmp, $newval, $mem\n\t"
7223             "CMP.eq   $tmp, 1 \n\t"
7224             "B.eq     loop \n\t"
7225             "TEQ      $tmp, 0\n\t"
7226             "membar   LoadStore|LoadLoad" %}
7227 #endif
7228   ins_encode %{
7229     Label loop;
7230     __ bind(loop);
7231 #ifdef AARCH64
7232 // FIXME: use load-acquire/store-release, remove membar?
7233     Label done;
7234     Register base = reg_to_register_object($mem$$base);
7235     __ ldxr($tmp$$Register, base);
7236     __ subs($tmp$$Register, $tmp$$Register, $oldval$$Register);
7237     __ b(done, ne);
7238     __ stxr($tmp$$Register, $newval$$Register, base);
7239     __ cbnz_w($tmp$$Register, loop);
7240     __ cmp($tmp$$Register, 0);
7241     __ bind(done);
7242 #else
7243     __ ldrex($tmp$$Register, $mem$$Address);
7244     __ eors($tmp$$Register, $tmp$$Register, $oldval$$Register);
7245     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
7246     __ cmp($tmp$$Register, 1, eq);
7247     __ b(loop, eq);
7248     __ teq($tmp$$Register, 0);
7249 #endif
7250     // used by biased locking only. Requires a membar.
7251     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadStore | MacroAssembler::LoadLoad), noreg);
7252   %}
7253   ins_pipe( long_memory_op );
7254 %}
7255 
7256 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
7257 
7258 #ifdef AARCH64
7259 // TODO: if combined with membar, elide membar and use
7260 // load-acquire/store-release if appropriate
7261 instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegL newval, iRegI res, iRegI tmp, flagsReg ccr) %{
7262   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
7263   effect( KILL ccr, TEMP tmp);
7264   size(24);
7265   format %{ "loop:\n\t"
7266             "LDXR     $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
7267             "CMP      $tmp, $oldval\n\t"
7268             "B.ne     done\n\t"
7269             "STXR     $tmp, $newval, $mem\n\t"
7270             "CBNZ_w   $tmp, loop\n\t"
7271             "done:\n\t"
7272             "CSET_w   $res, eq" %}
7273   ins_encode %{
7274     Register base = reg_to_register_object($mem$$base);
7275     Label loop, done;
7276     __ bind(loop);
7277     __ ldxr($tmp$$Register, base);
7278     __ cmp($tmp$$Register, $oldval$$Register);
7279     __ b(done, ne);
7280     __ stxr($tmp$$Register, $newval$$Register, base);
7281     __ cbnz_w($tmp$$Register, loop);
7282     __ bind(done);
7283     __ cset_w($res$$Register, eq);
7284   %}
7285   ins_pipe( long_memory_op );
7286 %}
7287 
7288 instruct compareAndSwapI_bool(memoryex mem, iRegI oldval, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr) %{
7289   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
7290   effect( KILL ccr, TEMP tmp);
7291   size(24);
7292   format %{ "loop:\n\t"
7293             "LDXR_w   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
7294             "CMP_w    $tmp, $oldval\n\t"
7295             "B.ne     done\n\t"
7296             "STXR_w   $tmp, $newval, $mem\n\t"
7297             "CBNZ_w   $tmp, loop\n\t"
7298             "done:\n\t"
7299             "CSET_w   $res, eq" %}
7300   ins_encode %{
7301     Register base = reg_to_register_object($mem$$base);
7302     Label loop, done;
7303     __ bind(loop);
7304     __ ldxr_w($tmp$$Register, base);
7305     __ cmp_w($tmp$$Register, $oldval$$Register);
7306     __ b(done, ne);
7307     __ stxr_w($tmp$$Register, $newval$$Register,  base);
7308     __ cbnz_w($tmp$$Register, loop);
7309     __ bind(done);
7310     __ cset_w($res$$Register, eq);
7311   %}
7312   ins_pipe( long_memory_op );
7313 %}
7314 
7315 // tmp must use iRegI instead of iRegN until 8051805 is fixed.
7316 instruct compareAndSwapN_bool(memoryex mem, iRegN oldval, iRegN newval, iRegI res, iRegI tmp, flagsReg ccr) %{
7317   match(Set res (CompareAndSwapN mem (Binary oldval newval)));
7318   effect( KILL ccr, TEMP tmp);
7319   size(24);
7320   format %{ "loop:\n\t"
7321             "LDXR_w   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
7322             "CMP_w    $tmp, $oldval\n\t"
7323             "B.ne     done\n\t"
7324             "STXR_w   $tmp, $newval, $mem\n\t"
7325             "CBNZ_w   $tmp, loop\n\t"
7326             "done:\n\t"
7327             "CSET_w   $res, eq" %}
7328   ins_encode %{
7329     Register base = reg_to_register_object($mem$$base);
7330     Label loop, done;
7331     __ bind(loop);
7332     __ ldxr_w($tmp$$Register, base);
7333     __ cmp_w($tmp$$Register, $oldval$$Register);
7334     __ b(done, ne);
7335     __ stxr_w($tmp$$Register, $newval$$Register,  base);
7336     __ cbnz_w($tmp$$Register, loop);
7337     __ bind(done);
7338     __ cset_w($res$$Register, eq);
7339   %}
7340   ins_pipe( long_memory_op );
7341 %}
7342 
7343 instruct compareAndSwapP_bool(memoryex mem, iRegP oldval, iRegP newval, iRegI res, iRegI tmp, flagsReg ccr) %{
7344   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
7345   effect( KILL ccr, TEMP tmp);
7346   size(24);
7347   format %{ "loop:\n\t"
7348             "LDXR     $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
7349             "CMP      $tmp, $oldval\n\t"
7350             "B.ne     done\n\t"
7351             "STXR     $tmp, $newval, $mem\n\t"
7352             "CBNZ_w   $tmp, loop\n\t"
7353             "done:\n\t"
7354             "CSET_w   $res, eq" %}
7355   ins_encode %{
7356     Register base = reg_to_register_object($mem$$base);
7357     Label loop, done;
7358     __ bind(loop);
7359     __ ldxr($tmp$$Register, base);
7360     __ cmp($tmp$$Register, $oldval$$Register);
7361     __ b(done, ne);
7362     __ stxr($tmp$$Register, $newval$$Register,  base);
7363     __ cbnz_w($tmp$$Register, loop);
7364     __ bind(done);
7365     __ cset_w($res$$Register, eq);
7366   %}
7367   ins_pipe( long_memory_op );
7368 %}
7369 #else // !AARCH64
7370 instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegLd newval, iRegI res, iRegLd tmp, flagsReg ccr ) %{
7371   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
7372   effect( KILL ccr, TEMP tmp);
7373   size(32);
7374   format %{ "loop: \n\t"
7375             "LDREXD   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
7376             "CMP      $tmp.lo, $oldval.lo\n\t"
7377             "CMP.eq   $tmp.hi, $oldval.hi\n\t"
7378             "STREXD.eq $tmp, $newval, $mem\n\t"
7379             "MOV.ne   $tmp, 0 \n\t"
7380             "XORS.eq  $tmp,$tmp, 1 \n\t"
7381             "B.eq     loop \n\t"
7382             "MOV      $res, $tmp" %}
7383   ins_encode %{
7384     Label loop;
7385     __ bind(loop);
7386     __ ldrexd($tmp$$Register, $mem$$Address);
7387     __ cmp($tmp$$Register, $oldval$$Register);
7388     __ cmp($tmp$$Register->successor(), $oldval$$Register->successor(), eq);
7389     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address, eq);
7390     __ mov($tmp$$Register, 0, ne);
7391     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
7392     __ b(loop, eq);
7393     __ mov($res$$Register, $tmp$$Register);
7394   %}
7395   ins_pipe( long_memory_op );
7396 %}
7397 
7398 
7399 instruct compareAndSwapI_bool(memoryex mem, iRegI oldval, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
7400   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
7401   effect( KILL ccr, TEMP tmp);
7402   size(28);
7403   format %{ "loop: \n\t"
7404             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
7405             "CMP      $tmp, $oldval\n\t"
7406             "STREX.eq $tmp, $newval, $mem\n\t"
7407             "MOV.ne   $tmp, 0 \n\t"
7408             "XORS.eq  $tmp,$tmp, 1 \n\t"
7409             "B.eq     loop \n\t"
7410             "MOV      $res, $tmp" %}
7411 
7412   ins_encode %{
7413     Label loop;
7414     __ bind(loop);
7415     __ ldrex($tmp$$Register,$mem$$Address);
7416     __ cmp($tmp$$Register, $oldval$$Register);
7417     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
7418     __ mov($tmp$$Register, 0, ne);
7419     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
7420     __ b(loop, eq);
7421     __ mov($res$$Register, $tmp$$Register);
7422   %}
7423   ins_pipe( long_memory_op );
7424 %}
7425 
7426 instruct compareAndSwapP_bool(memoryex mem, iRegP oldval, iRegP newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
7427   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
7428   effect( KILL ccr, TEMP tmp);
7429   size(28);
7430   format %{ "loop: \n\t"
7431             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
7432             "CMP      $tmp, $oldval\n\t"
7433             "STREX.eq $tmp, $newval, $mem\n\t"
7434             "MOV.ne   $tmp, 0 \n\t"
7435             "EORS.eq  $tmp,$tmp, 1 \n\t"
7436             "B.eq     loop \n\t"
7437             "MOV      $res, $tmp" %}
7438 
7439   ins_encode %{
7440     Label loop;
7441     __ bind(loop);
7442     __ ldrex($tmp$$Register,$mem$$Address);
7443     __ cmp($tmp$$Register, $oldval$$Register);
7444     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
7445     __ mov($tmp$$Register, 0, ne);
7446     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
7447     __ b(loop, eq);
7448     __ mov($res$$Register, $tmp$$Register);
7449   %}
7450   ins_pipe( long_memory_op );
7451 %}
7452 #endif // !AARCH64
7453 
7454 #ifdef AARCH64
7455 instruct xaddI_aimmI_no_res(memoryex mem, aimmI add, Universe dummy, iRegI tmp1, iRegI tmp2) %{
7456   predicate(n->as_LoadStore()->result_not_used());
7457   match(Set dummy (GetAndAddI mem add));
7458   effect(TEMP tmp1, TEMP tmp2);
7459   size(16);
7460   format %{ "loop:\n\t"
7461             "LDXR_w   $tmp1, $mem\n\t"
7462             "ADD_w    $tmp1, $tmp1, $add\n\t"
7463             "STXR_w   $tmp2, $tmp1, $mem\n\t"
7464             "CBNZ_w   $tmp2, loop" %}
7465 
7466   ins_encode %{
7467     Label loop;
7468     Register base = reg_to_register_object($mem$$base);
7469     __ bind(loop);
7470     __ ldxr_w($tmp1$$Register, base);
7471     __ add_w($tmp1$$Register, $tmp1$$Register, $add$$constant);
7472     __ stxr_w($tmp2$$Register, $tmp1$$Register, base);
7473     __ cbnz_w($tmp2$$Register, loop);
7474   %}
7475   ins_pipe( long_memory_op );
7476 %}
7477 #else
7478 instruct xaddI_aimmI_no_res(memoryex mem, aimmI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
7479   predicate(n->as_LoadStore()->result_not_used());
7480   match(Set dummy (GetAndAddI mem add));
7481   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
7482   size(20);
7483   format %{ "loop: \n\t"
7484             "LDREX    $tmp1, $mem\n\t"
7485             "ADD      $tmp1, $tmp1, $add\n\t"
7486             "STREX    $tmp2, $tmp1, $mem\n\t"
7487             "CMP      $tmp2, 0 \n\t"
7488             "B.ne     loop \n\t" %}
7489 
7490   ins_encode %{
7491     Label loop;
7492     __ bind(loop);
7493     __ ldrex($tmp1$$Register,$mem$$Address);
7494     __ add($tmp1$$Register, $tmp1$$Register, $add$$constant);
7495     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
7496     __ cmp($tmp2$$Register, 0);
7497     __ b(loop, ne);
7498   %}
7499   ins_pipe( long_memory_op );
7500 %}
7501 #endif
7502 
7503 #ifdef AARCH64
7504 instruct xaddI_reg_no_res(memoryex mem, iRegI add, Universe dummy, iRegI tmp1, iRegI tmp2) %{
7505   predicate(n->as_LoadStore()->result_not_used());
7506   match(Set dummy (GetAndAddI mem add));
7507   effect(TEMP tmp1, TEMP tmp2);
7508   size(16);
7509   format %{ "loop:\n\t"
7510             "LDXR_w   $tmp1, $mem\n\t"
7511             "ADD_w    $tmp1, $tmp1, $add\n\t"
7512             "STXR_w   $tmp2, $tmp1, $mem\n\t"
7513             "CBNZ_w   $tmp2, loop" %}
7514 
7515   ins_encode %{
7516     Label loop;
7517     Register base = reg_to_register_object($mem$$base);
7518     __ bind(loop);
7519     __ ldxr_w($tmp1$$Register, base);
7520     __ add_w($tmp1$$Register, $tmp1$$Register, $add$$Register);
7521     __ stxr_w($tmp2$$Register, $tmp1$$Register, base);
7522     __ cbnz_w($tmp2$$Register, loop);
7523   %}
7524   ins_pipe( long_memory_op );
7525 %}
7526 #else
7527 instruct xaddI_reg_no_res(memoryex mem, iRegI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
7528   predicate(n->as_LoadStore()->result_not_used());
7529   match(Set dummy (GetAndAddI mem add));
7530   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
7531   size(20);
7532   format %{ "loop: \n\t"
7533             "LDREX    $tmp1, $mem\n\t"
7534             "ADD      $tmp1, $tmp1, $add\n\t"
7535             "STREX    $tmp2, $tmp1, $mem\n\t"
7536             "CMP      $tmp2, 0 \n\t"
7537             "B.ne     loop \n\t" %}
7538 
7539   ins_encode %{
7540     Label loop;
7541     __ bind(loop);
7542     __ ldrex($tmp1$$Register,$mem$$Address);
7543     __ add($tmp1$$Register, $tmp1$$Register, $add$$Register);
7544     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
7545     __ cmp($tmp2$$Register, 0);
7546     __ b(loop, ne);
7547   %}
7548   ins_pipe( long_memory_op );
7549 %}
7550 #endif
7551 
7552 #ifdef AARCH64
7553 instruct xaddI_aimmI(memoryex mem, aimmI add, iRegI res, iRegI tmp1, iRegI tmp2) %{
7554   match(Set res (GetAndAddI mem add));
7555   effect(TEMP tmp1, TEMP tmp2, TEMP res);
7556   size(16);
7557   format %{ "loop:\n\t"
7558             "LDXR_w   $res, $mem\n\t"
7559             "ADD_w    $tmp1, $res, $add\n\t"
7560             "STXR_w   $tmp2, $tmp1, $mem\n\t"
7561             "CBNZ_w   $tmp2, loop" %}
7562 
7563   ins_encode %{
7564     Label loop;
7565     Register base = reg_to_register_object($mem$$base);
7566     __ bind(loop);
7567     __ ldxr_w($res$$Register, base);
7568     __ add_w($tmp1$$Register, $res$$Register, $add$$constant);
7569     __ stxr_w($tmp2$$Register, $tmp1$$Register, base);
7570     __ cbnz_w($tmp2$$Register, loop);
7571   %}
7572   ins_pipe( long_memory_op );
7573 %}
7574 #else
7575 instruct xaddI_aimmI(memoryex mem, aimmI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
7576   match(Set res (GetAndAddI mem add));
7577   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
7578   size(20);
7579   format %{ "loop: \n\t"
7580             "LDREX    $res, $mem\n\t"
7581             "ADD      $tmp1, $res, $add\n\t"
7582             "STREX    $tmp2, $tmp1, $mem\n\t"
7583             "CMP      $tmp2, 0 \n\t"
7584             "B.ne     loop \n\t" %}
7585 
7586   ins_encode %{
7587     Label loop;
7588     __ bind(loop);
7589     __ ldrex($res$$Register,$mem$$Address);
7590     __ add($tmp1$$Register, $res$$Register, $add$$constant);
7591     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
7592     __ cmp($tmp2$$Register, 0);
7593     __ b(loop, ne);
7594   %}
7595   ins_pipe( long_memory_op );
7596 %}
7597 #endif
7598 
7599 #ifdef AARCH64
7600 instruct xaddI_reg(memoryex mem, iRegI add, iRegI res, iRegI tmp1, iRegI tmp2) %{
7601   match(Set res (GetAndAddI mem add));
7602   effect(TEMP tmp1, TEMP tmp2, TEMP res);
7603   size(16);
7604   format %{ "loop:\n\t"
7605             "LDXR_w   $res, $mem\n\t"
7606             "ADD_w    $tmp1, $res, $add\n\t"
7607             "STXR_w   $tmp2, $tmp1, $mem\n\t"
7608             "CBNZ_w   $tmp2, loop" %}
7609 
7610   ins_encode %{
7611     Label loop;
7612     Register base = reg_to_register_object($mem$$base);
7613     __ bind(loop);
7614     __ ldxr_w($res$$Register, base);
7615     __ add_w($tmp1$$Register, $res$$Register, $add$$Register);
7616     __ stxr_w($tmp2$$Register, $tmp1$$Register, base);
7617     __ cbnz_w($tmp2$$Register, loop);
7618   %}
7619   ins_pipe( long_memory_op );
7620 %}
7621 #else
7622 instruct xaddI_reg(memoryex mem, iRegI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
7623   match(Set res (GetAndAddI mem add));
7624   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
7625   size(20);
7626   format %{ "loop: \n\t"
7627             "LDREX    $res, $mem\n\t"
7628             "ADD      $tmp1, $res, $add\n\t"
7629             "STREX    $tmp2, $tmp1, $mem\n\t"
7630             "CMP      $tmp2, 0 \n\t"
7631             "B.ne     loop \n\t" %}
7632 
7633   ins_encode %{
7634     Label loop;
7635     __ bind(loop);
7636     __ ldrex($res$$Register,$mem$$Address);
7637     __ add($tmp1$$Register, $res$$Register, $add$$Register);
7638     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
7639     __ cmp($tmp2$$Register, 0);
7640     __ b(loop, ne);
7641   %}
7642   ins_pipe( long_memory_op );
7643 %}
7644 #endif
7645 
7646 #ifdef AARCH64
7647 instruct xaddL_reg_no_res(memoryex mem, iRegL add, Universe dummy, iRegL tmp1, iRegI tmp2) %{
7648   predicate(n->as_LoadStore()->result_not_used());
7649   match(Set dummy (GetAndAddL mem add));
7650   effect(TEMP tmp1, TEMP tmp2);
7651   size(16);
7652   format %{ "loop:\n\t"
7653             "LDXR     $tmp1, $mem\n\t"
7654             "ADD      $tmp1, $tmp1, $add\n\t"
7655             "STXR     $tmp2, $tmp1, $mem\n\t"
7656             "CBNZ_w   $tmp2, loop" %}
7657 
7658   ins_encode %{
7659     Label loop;
7660     Register base = reg_to_register_object($mem$$base);
7661     __ bind(loop);
7662     __ ldxr($tmp1$$Register, base);
7663     __ add($tmp1$$Register, $tmp1$$Register, $add$$Register);
7664     __ stxr($tmp2$$Register, $tmp1$$Register, base);
7665     __ cbnz_w($tmp2$$Register, loop);
7666   %}
7667   ins_pipe( long_memory_op );
7668 %}
7669 #else
7670 instruct xaddL_reg_no_res(memoryex mem, iRegL add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
7671   predicate(n->as_LoadStore()->result_not_used());
7672   match(Set dummy (GetAndAddL mem add));
7673   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
7674   size(24);
7675   format %{ "loop: \n\t"
7676             "LDREXD   $tmp1, $mem\n\t"
7677             "ADDS     $tmp1.lo, $tmp1.lo, $add.lo\n\t"
7678             "ADC      $tmp1.hi, $tmp1.hi, $add.hi\n\t"
7679             "STREXD   $tmp2, $tmp1, $mem\n\t"
7680             "CMP      $tmp2, 0 \n\t"
7681             "B.ne     loop \n\t" %}
7682 
7683   ins_encode %{
7684     Label loop;
7685     __ bind(loop);
7686     __ ldrexd($tmp1$$Register, $mem$$Address);
7687     __ adds($tmp1$$Register, $tmp1$$Register, $add$$Register);
7688     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), $add$$Register->successor());
7689     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
7690     __ cmp($tmp2$$Register, 0);
7691     __ b(loop, ne);
7692   %}
7693   ins_pipe( long_memory_op );
7694 %}
7695 #endif
7696 
7697 #ifdef AARCH64
7698 instruct xaddL_imm_no_res(memoryex mem, aimmL add, Universe dummy, iRegL tmp1, iRegI tmp2) %{
7699   predicate(n->as_LoadStore()->result_not_used());
7700   match(Set dummy (GetAndAddL mem add));
7701   effect(TEMP tmp1, TEMP tmp2);
7702   size(16);
7703   format %{ "loop:\n\t"
7704             "LDXR     $tmp1, $mem\n\t"
7705             "ADD      $tmp1, $tmp1, $add\n\t"
7706             "STXR     $tmp2, $tmp1, $mem\n\t"
7707             "CBNZ_w   $tmp2, loop" %}
7708 
7709   ins_encode %{
7710     Label loop;
7711     Register base = reg_to_register_object($mem$$base);
7712     __ bind(loop);
7713     __ ldxr($tmp1$$Register, base);
7714     __ add($tmp1$$Register, $tmp1$$Register, $add$$constant);
7715     __ stxr($tmp2$$Register, $tmp1$$Register, base);
7716     __ cbnz_w($tmp2$$Register, loop);
7717   %}
7718   ins_pipe( long_memory_op );
7719 %}
7720 #else
7721 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7722 // (hi($con$$constant), lo($con$$constant)) becomes
7723 instruct xaddL_immRot_no_res(memoryex mem, immLlowRot add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
7724   predicate(n->as_LoadStore()->result_not_used());
7725   match(Set dummy (GetAndAddL mem add));
7726   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
7727   size(24);
7728   format %{ "loop: \n\t"
7729             "LDREXD   $tmp1, $mem\n\t"
7730             "ADDS     $tmp1.lo, $tmp1.lo, $add\n\t"
7731             "ADC      $tmp1.hi, $tmp1.hi, 0\n\t"
7732             "STREXD   $tmp2, $tmp1, $mem\n\t"
7733             "CMP      $tmp2, 0 \n\t"
7734             "B.ne     loop \n\t" %}
7735 
7736   ins_encode %{
7737     Label loop;
7738     __ bind(loop);
7739     __ ldrexd($tmp1$$Register, $mem$$Address);
7740     __ adds($tmp1$$Register, $tmp1$$Register, $add$$constant);
7741     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), 0);
7742     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
7743     __ cmp($tmp2$$Register, 0);
7744     __ b(loop, ne);
7745   %}
7746   ins_pipe( long_memory_op );
7747 %}
7748 #endif
7749 
7750 #ifdef AARCH64
7751 instruct xaddL_reg(memoryex mem, iRegL add, iRegL res, iRegL tmp1, iRegI tmp2) %{
7752   match(Set res (GetAndAddL mem add));
7753   effect(TEMP tmp1, TEMP tmp2, TEMP res);
7754   size(16);
7755   format %{ "loop:\n\t"
7756             "LDXR     $res, $mem\n\t"
7757             "ADD      $tmp1, $res, $add\n\t"
7758             "STXR     $tmp2, $tmp1, $mem\n\t"
7759             "CBNZ_w   $tmp2, loop" %}
7760 
7761   ins_encode %{
7762     Label loop;
7763     Register base = reg_to_register_object($mem$$base);
7764     __ bind(loop);
7765     __ ldxr($res$$Register, base);
7766     __ add($tmp1$$Register, $res$$Register, $add$$Register);
7767     __ stxr($tmp2$$Register, $tmp1$$Register, base);
7768     __ cbnz_w($tmp2$$Register, loop);
7769   %}
7770   ins_pipe( long_memory_op );
7771 %}
7772 #else
7773 instruct xaddL_reg(memoryex mem, iRegL add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
7774   match(Set res (GetAndAddL mem add));
7775   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
7776   size(24);
7777   format %{ "loop: \n\t"
7778             "LDREXD   $res, $mem\n\t"
7779             "ADDS     $tmp1.lo, $res.lo, $add.lo\n\t"
7780             "ADC      $tmp1.hi, $res.hi, $add.hi\n\t"
7781             "STREXD   $tmp2, $tmp1, $mem\n\t"
7782             "CMP      $tmp2, 0 \n\t"
7783             "B.ne     loop \n\t" %}
7784 
7785   ins_encode %{
7786     Label loop;
7787     __ bind(loop);
7788     __ ldrexd($res$$Register, $mem$$Address);
7789     __ adds($tmp1$$Register, $res$$Register, $add$$Register);
7790     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), $add$$Register->successor());
7791     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
7792     __ cmp($tmp2$$Register, 0);
7793     __ b(loop, ne);
7794   %}
7795   ins_pipe( long_memory_op );
7796 %}
7797 #endif
7798 
7799 #ifdef AARCH64
7800 instruct xaddL_imm(memoryex mem, aimmL add, iRegL res, iRegL tmp1, iRegI tmp2) %{
7801   match(Set res (GetAndAddL mem add));
7802   effect(TEMP tmp1, TEMP tmp2, TEMP res);
7803   size(16);
7804   format %{ "loop:\n\t"
7805             "LDXR     $res, $mem\n\t"
7806             "ADD      $tmp1, $res, $add\n\t"
7807             "STXR     $tmp2, $tmp1, $mem\n\t"
7808             "CBNZ_w   $tmp2, loop" %}
7809 
7810   ins_encode %{
7811     Label loop;
7812     Register base = reg_to_register_object($mem$$base);
7813     __ bind(loop);
7814     __ ldxr($res$$Register, base);
7815     __ add($tmp1$$Register, $res$$Register, $add$$constant);
7816     __ stxr($tmp2$$Register, $tmp1$$Register, base);
7817     __ cbnz_w($tmp2$$Register, loop);
7818   %}
7819   ins_pipe( long_memory_op );
7820 %}
7821 #else
7822 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7823 // (hi($con$$constant), lo($con$$constant)) becomes
7824 instruct xaddL_immRot(memoryex mem, immLlowRot add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
7825   match(Set res (GetAndAddL mem add));
7826   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
7827   size(24);
7828   format %{ "loop: \n\t"
7829             "LDREXD   $res, $mem\n\t"
7830             "ADDS     $tmp1.lo, $res.lo, $add\n\t"
7831             "ADC      $tmp1.hi, $res.hi, 0\n\t"
7832             "STREXD   $tmp2, $tmp1, $mem\n\t"
7833             "CMP      $tmp2, 0 \n\t"
7834             "B.ne     loop \n\t" %}
7835 
7836   ins_encode %{
7837     Label loop;
7838     __ bind(loop);
7839     __ ldrexd($res$$Register, $mem$$Address);
7840     __ adds($tmp1$$Register, $res$$Register, $add$$constant);
7841     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), 0);
7842     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
7843     __ cmp($tmp2$$Register, 0);
7844     __ b(loop, ne);
7845   %}
7846   ins_pipe( long_memory_op );
7847 %}
7848 #endif
7849 
7850 #ifdef AARCH64
7851 instruct xchgI(memoryex mem, iRegI newval, iRegI res, iRegI tmp) %{
7852   match(Set res (GetAndSetI mem newval));
7853   effect(TEMP tmp, TEMP res);
7854   size(12);
7855   format %{ "loop:\n\t"
7856             "LDXR_w   $res, $mem\n\t"
7857             "STXR_w   $tmp, $newval, $mem\n\t"
7858             "CBNZ_w   $tmp, loop" %}
7859 
7860   ins_encode %{
7861     Label loop;
7862     Register base = reg_to_register_object($mem$$base);
7863     __ bind(loop);
7864     __ ldxr_w($res$$Register, base);
7865     __ stxr_w($tmp$$Register, $newval$$Register, base);
7866     __ cbnz_w($tmp$$Register, loop);
7867   %}
7868   ins_pipe( long_memory_op );
7869 %}
7870 
7871 #ifdef XXX
7872 // Disabled until 8051805 is fixed.
7873 instruct xchgN(memoryex mem, iRegN newval, iRegN res, iRegN tmp) %{
7874   match(Set res (GetAndSetN mem newval));
7875   effect(TEMP tmp, TEMP res);
7876   size(12);
7877   format %{ "loop:\n\t"
7878             "LDXR_w   $res, $mem\n\t"
7879             "STXR_w   $tmp, $newval, $mem\n\t"
7880             "CBNZ_w   $tmp, loop" %}
7881 
7882   ins_encode %{
7883     Label loop;
7884     Register base = reg_to_register_object($mem$$base);
7885     __ bind(loop);
7886     __ ldxr_w($res$$Register, base);
7887     __ stxr_w($tmp$$Register, $newval$$Register, base);
7888     __ cbnz_w($tmp$$Register, loop);
7889   %}
7890   ins_pipe( long_memory_op );
7891 %}
7892 #endif
7893 #else
7894 instruct xchgI(memoryex mem, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr) %{
7895   match(Set res (GetAndSetI mem newval));
7896   effect(KILL ccr, TEMP tmp, TEMP res);
7897   size(16);
7898   format %{ "loop: \n\t"
7899             "LDREX    $res, $mem\n\t"
7900             "STREX    $tmp, $newval, $mem\n\t"
7901             "CMP      $tmp, 0 \n\t"
7902             "B.ne     loop \n\t" %}
7903 
7904   ins_encode %{
7905     Label loop;
7906     __ bind(loop);
7907     __ ldrex($res$$Register,$mem$$Address);
7908     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
7909     __ cmp($tmp$$Register, 0);
7910     __ b(loop, ne);
7911   %}
7912   ins_pipe( long_memory_op );
7913 %}
7914 #endif
7915 
7916 #ifdef AARCH64
7917 instruct xchgL(memoryex mem, iRegL newval, iRegL res, iRegI tmp) %{
7918   match(Set res (GetAndSetL mem newval));
7919   effect(TEMP tmp, TEMP res);
7920   size(12);
7921   format %{ "loop:\n\t"
7922             "LDXR     $res, $mem\n\t"
7923             "STXR     $tmp, $newval, $mem\n\t"
7924             "CBNZ_w   $tmp, loop" %}
7925 
7926   ins_encode %{
7927     Label loop;
7928     Register base = reg_to_register_object($mem$$base);
7929     __ bind(loop);
7930     __ ldxr($res$$Register, base);
7931     __ stxr($tmp$$Register, $newval$$Register, base);
7932     __ cbnz_w($tmp$$Register, loop);
7933   %}
7934   ins_pipe( long_memory_op );
7935 %}
7936 #else
7937 instruct xchgL(memoryex mem, iRegLd newval, iRegLd res, iRegI tmp, flagsReg ccr) %{
7938   match(Set res (GetAndSetL mem newval));
7939   effect( KILL ccr, TEMP tmp, TEMP res);
7940   size(16);
7941   format %{ "loop: \n\t"
7942             "LDREXD   $res, $mem\n\t"
7943             "STREXD   $tmp, $newval, $mem\n\t"
7944             "CMP      $tmp, 0 \n\t"
7945             "B.ne     loop \n\t" %}
7946 
7947   ins_encode %{
7948     Label loop;
7949     __ bind(loop);
7950     __ ldrexd($res$$Register, $mem$$Address);
7951     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address);
7952     __ cmp($tmp$$Register, 0);
7953     __ b(loop, ne);
7954   %}
7955   ins_pipe( long_memory_op );
7956 %}
7957 #endif // !AARCH64
7958 
7959 #ifdef AARCH64
7960 instruct xchgP(memoryex mem, iRegP newval, iRegP res, iRegI tmp) %{
7961   match(Set res (GetAndSetP mem newval));
7962   effect(TEMP tmp, TEMP res);
7963   size(12);
7964   format %{ "loop:\n\t"
7965             "LDREX    $res, $mem\n\t"
7966             "STREX    $tmp, $newval, $mem\n\t"
7967             "CBNZ_w   $tmp, loop" %}
7968 
7969   ins_encode %{
7970     Label loop;
7971     Register base = reg_to_register_object($mem$$base);
7972     __ bind(loop);
7973     __ ldrex($res$$Register, base);
7974     __ strex($tmp$$Register, $newval$$Register, base);
7975     __ cbnz_w($tmp$$Register, loop);
7976   %}
7977   ins_pipe( long_memory_op );
7978 %}
7979 #else
7980 instruct xchgP(memoryex mem, iRegP newval, iRegP res, iRegI tmp, flagsReg ccr) %{
7981   match(Set res (GetAndSetP mem newval));
7982   effect(KILL ccr, TEMP tmp, TEMP res);
7983   size(16);
7984   format %{ "loop: \n\t"
7985             "LDREX    $res, $mem\n\t"
7986             "STREX    $tmp, $newval, $mem\n\t"
7987             "CMP      $tmp, 0 \n\t"
7988             "B.ne     loop \n\t" %}
7989 
7990   ins_encode %{
7991     Label loop;
7992     __ bind(loop);
7993     __ ldrex($res$$Register,$mem$$Address);
7994     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
7995     __ cmp($tmp$$Register, 0);
7996     __ b(loop, ne);
7997   %}
7998   ins_pipe( long_memory_op );
7999 %}
8000 #endif // !AARCH64
8001 
8002 //---------------------
8003 // Subtraction Instructions
8004 // Register Subtraction
8005 instruct subI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
8006   match(Set dst (SubI src1 src2));
8007 
8008   size(4);
8009   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
8010   ins_encode %{
8011     __ sub_32($dst$$Register, $src1$$Register, $src2$$Register);
8012   %}
8013   ins_pipe(ialu_reg_reg);
8014 %}
8015 
8016 #ifndef AARCH64
8017 instruct subshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
8018   match(Set dst (SubI src1 (LShiftI src2 src3)));
8019 
8020   size(4);
8021   format %{ "SUB    $dst,$src1,$src2<<$src3" %}
8022   ins_encode %{
8023     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
8024   %}
8025   ins_pipe(ialu_reg_reg);
8026 %}
8027 #endif
8028 
8029 instruct subshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
8030   match(Set dst (SubI src1 (LShiftI src2 src3)));
8031 
8032   size(4);
8033   format %{ "sub_32 $dst,$src1,$src2<<$src3\t! int" %}
8034   ins_encode %{
8035     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
8036   %}
8037   ins_pipe(ialu_reg_reg);
8038 %}
8039 
8040 #ifndef AARCH64
8041 instruct subsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
8042   match(Set dst (SubI src1 (RShiftI src2 src3)));
8043 
8044   size(4);
8045   format %{ "SUB    $dst,$src1,$src2>>$src3" %}
8046   ins_encode %{
8047     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
8048   %}
8049   ins_pipe(ialu_reg_reg);
8050 %}
8051 #endif
8052 
8053 instruct subsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
8054   match(Set dst (SubI src1 (RShiftI src2 src3)));
8055 
8056   size(4);
8057   format %{ "sub_32 $dst,$src1,$src2>>$src3\t! int" %}
8058   ins_encode %{
8059     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
8060   %}
8061   ins_pipe(ialu_reg_reg);
8062 %}
8063 
8064 #ifndef AARCH64
8065 instruct subshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
8066   match(Set dst (SubI src1 (URShiftI src2 src3)));
8067 
8068   size(4);
8069   format %{ "SUB    $dst,$src1,$src2>>>$src3" %}
8070   ins_encode %{
8071     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
8072   %}
8073   ins_pipe(ialu_reg_reg);
8074 %}
8075 #endif
8076 
8077 instruct subshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
8078   match(Set dst (SubI src1 (URShiftI src2 src3)));
8079 
8080   size(4);
8081   format %{ "sub_32 $dst,$src1,$src2>>>$src3\t! int" %}
8082   ins_encode %{
8083     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
8084   %}
8085   ins_pipe(ialu_reg_reg);
8086 %}
8087 
8088 #ifndef AARCH64
8089 instruct rsbshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
8090   match(Set dst (SubI (LShiftI src1 src2) src3));
8091 
8092   size(4);
8093   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
8094   ins_encode %{
8095     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
8096   %}
8097   ins_pipe(ialu_reg_reg);
8098 %}
8099 
8100 instruct rsbshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
8101   match(Set dst (SubI (LShiftI src1 src2) src3));
8102 
8103   size(4);
8104   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
8105   ins_encode %{
8106     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
8107   %}
8108   ins_pipe(ialu_reg_reg);
8109 %}
8110 
8111 instruct rsbsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
8112   match(Set dst (SubI (RShiftI src1 src2) src3));
8113 
8114   size(4);
8115   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
8116   ins_encode %{
8117     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
8118   %}
8119   ins_pipe(ialu_reg_reg);
8120 %}
8121 
8122 instruct rsbsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
8123   match(Set dst (SubI (RShiftI src1 src2) src3));
8124 
8125   size(4);
8126   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
8127   ins_encode %{
8128     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
8129   %}
8130   ins_pipe(ialu_reg_reg);
8131 %}
8132 
8133 instruct rsbshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
8134   match(Set dst (SubI (URShiftI src1 src2) src3));
8135 
8136   size(4);
8137   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
8138   ins_encode %{
8139     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
8140   %}
8141   ins_pipe(ialu_reg_reg);
8142 %}
8143 
8144 instruct rsbshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
8145   match(Set dst (SubI (URShiftI src1 src2) src3));
8146 
8147   size(4);
8148   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
8149   ins_encode %{
8150     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
8151   %}
8152   ins_pipe(ialu_reg_reg);
8153 %}
8154 #endif
8155 
8156 // Immediate Subtraction
8157 instruct subI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
8158   match(Set dst (SubI src1 src2));
8159 
8160   size(4);
8161   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
8162   ins_encode %{
8163     __ sub_32($dst$$Register, $src1$$Register, $src2$$constant);
8164   %}
8165   ins_pipe(ialu_reg_imm);
8166 %}
8167 
8168 instruct subI_reg_immRotneg(iRegI dst, iRegI src1, aimmIneg src2) %{
8169   match(Set dst (AddI src1 src2));
8170 
8171   size(4);
8172   format %{ "sub_32 $dst,$src1,-($src2)\t! int" %}
8173   ins_encode %{
8174     __ sub_32($dst$$Register, $src1$$Register, -$src2$$constant);
8175   %}
8176   ins_pipe(ialu_reg_imm);
8177 %}
8178 
8179 #ifndef AARCH64
8180 instruct subI_immRot_reg(iRegI dst, immIRot src1, iRegI src2) %{
8181   match(Set dst (SubI src1 src2));
8182 
8183   size(4);
8184   format %{ "RSB    $dst,$src2,src1" %}
8185   ins_encode %{
8186     __ rsb($dst$$Register, $src2$$Register, $src1$$constant);
8187   %}
8188   ins_pipe(ialu_zero_reg);
8189 %}
8190 #endif
8191 
8192 // Register Subtraction
8193 #ifdef AARCH64
8194 instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
8195   match(Set dst (SubL src1 src2));
8196 
8197   size(4);
8198   format %{ "SUB    $dst,$src1,$src2\t! long" %}
8199   ins_encode %{
8200     __ sub($dst$$Register, $src1$$Register, $src2$$Register);
8201   %}
8202   ins_pipe(ialu_reg_reg);
8203 %}
8204 #else
8205 instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg icc ) %{
8206   match(Set dst (SubL src1 src2));
8207   effect (KILL icc);
8208 
8209   size(8);
8210   format %{ "SUBS   $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
8211             "SBC    $dst.hi,$src1.hi,$src2.hi" %}
8212   ins_encode %{
8213     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
8214     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
8215   %}
8216   ins_pipe(ialu_reg_reg);
8217 %}
8218 #endif
8219 
8220 #ifdef AARCH64
8221 // Immediate Subtraction
8222 instruct subL_reg_aimm(iRegL dst, iRegL src1, aimmL src2) %{
8223   match(Set dst (SubL src1 src2));
8224 
8225   size(4);
8226   format %{ "SUB    $dst,$src1,$src2\t! long" %}
8227   ins_encode %{
8228     __ sub($dst$$Register, $src1$$Register, $src2$$constant);
8229   %}
8230   ins_pipe(ialu_reg_imm);
8231 %}
8232 
8233 instruct subL_reg_immLneg(iRegL dst, iRegL src1, aimmLneg src2) %{
8234   match(Set dst (AddL src1 src2));
8235 
8236   size(4);
8237   format %{ "SUB    $dst,$src1,-($src2)\t! long" %}
8238   ins_encode %{
8239     __ sub($dst$$Register, $src1$$Register, -$src2$$constant);
8240   %}
8241   ins_pipe(ialu_reg_imm);
8242 %}
8243 #else
8244 // TODO
8245 #endif
8246 
8247 #ifndef AARCH64
8248 // Immediate Subtraction
8249 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
8250 // (hi($con$$constant), lo($con$$constant)) becomes
8251 instruct subL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg icc) %{
8252   match(Set dst (SubL src1 con));
8253   effect (KILL icc);
8254 
8255   size(8);
8256   format %{ "SUB    $dst.lo,$src1.lo,$con\t! long\n\t"
8257             "SBC    $dst.hi,$src1.hi,0" %}
8258   ins_encode %{
8259     __ subs($dst$$Register, $src1$$Register, $con$$constant);
8260     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), 0);
8261   %}
8262   ins_pipe(ialu_reg_imm);
8263 %}
8264 
8265 // Long negation
8266 instruct negL_reg_reg(iRegL dst, immL0 zero, iRegL src2, flagsReg icc) %{
8267   match(Set dst (SubL zero src2));
8268   effect (KILL icc);
8269 
8270   size(8);
8271   format %{ "RSBS   $dst.lo,$src2.lo,0\t! long\n\t"
8272             "RSC    $dst.hi,$src2.hi,0" %}
8273   ins_encode %{
8274     __ rsbs($dst$$Register, $src2$$Register, 0);
8275     __ rsc($dst$$Register->successor(), $src2$$Register->successor(), 0);
8276   %}
8277   ins_pipe(ialu_zero_reg);
8278 %}
8279 #endif // !AARCH64
8280 
8281 // Multiplication Instructions
8282 // Integer Multiplication
8283 // Register Multiplication
8284 instruct mulI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
8285   match(Set dst (MulI src1 src2));
8286 
8287   size(4);
8288   format %{ "mul_32 $dst,$src1,$src2" %}
8289   ins_encode %{
8290     __ mul_32($dst$$Register, $src1$$Register, $src2$$Register);
8291   %}
8292   ins_pipe(imul_reg_reg);
8293 %}
8294 
8295 #ifdef AARCH64
8296 instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
8297   match(Set dst (MulL src1 src2));
8298   size(4);
8299   format %{ "MUL  $dst,$src1,$src2\t! long" %}
8300   ins_encode %{
8301     __ mul($dst$$Register, $src1$$Register, $src2$$Register);
8302   %}
8303   ins_pipe(imul_reg_reg);
8304 %}
8305 #else
8306 instruct mulL_lo1_hi2(iRegL dst, iRegL src1, iRegL src2) %{
8307   effect(DEF dst, USE src1, USE src2);
8308   size(4);
8309   format %{ "MUL  $dst.hi,$src1.lo,$src2.hi\t! long" %}
8310   ins_encode %{
8311     __ mul($dst$$Register->successor(), $src1$$Register, $src2$$Register->successor());
8312   %}
8313   ins_pipe(imul_reg_reg);
8314 %}
8315 
8316 instruct mulL_hi1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
8317   effect(USE_DEF dst, USE src1, USE src2);
8318   size(8);
8319   format %{ "MLA  $dst.hi,$src1.hi,$src2.lo,$dst.hi\t! long\n\t"
8320             "MOV  $dst.lo, 0"%}
8321   ins_encode %{
8322     __ mla($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register, $dst$$Register->successor());
8323     __ mov($dst$$Register, 0);
8324   %}
8325   ins_pipe(imul_reg_reg);
8326 %}
8327 
8328 instruct mulL_lo1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
8329   effect(USE_DEF dst, USE src1, USE src2);
8330   size(4);
8331   format %{ "UMLAL  $dst.lo,$dst.hi,$src1,$src2\t! long" %}
8332   ins_encode %{
8333     __ umlal($dst$$Register, $dst$$Register->successor(), $src1$$Register, $src2$$Register);
8334   %}
8335   ins_pipe(imul_reg_reg);
8336 %}
8337 
8338 instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
8339   match(Set dst (MulL src1 src2));
8340 
8341   expand %{
8342     mulL_lo1_hi2(dst, src1, src2);
8343     mulL_hi1_lo2(dst, src1, src2);
8344     mulL_lo1_lo2(dst, src1, src2);
8345   %}
8346 %}
8347 #endif // !AARCH64
8348 
8349 // Integer Division
8350 // Register Division
8351 #ifdef AARCH64
8352 instruct divI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
8353   match(Set dst (DivI src1 src2));
8354 
8355   size(4);
8356   format %{ "SDIV    $dst,$src1,$src2\t! 32-bit" %}
8357   ins_encode %{
8358     __ sdiv_w($dst$$Register, $src1$$Register, $src2$$Register);
8359   %}
8360   ins_pipe(ialu_reg_reg); // FIXME
8361 %}
8362 #else
8363 instruct divI_reg_reg(R1RegI dst, R0RegI src1, R2RegI src2, LRRegP lr, flagsReg ccr) %{
8364   match(Set dst (DivI src1 src2));
8365   effect( KILL ccr, KILL src1, KILL src2, KILL lr);
8366   ins_cost((2+71)*DEFAULT_COST);
8367 
8368   format %{ "DIV   $dst,$src1,$src2 ! call to StubRoutines::Arm::idiv_irem_entry()" %}
8369   ins_encode %{
8370     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
8371   %}
8372   ins_pipe(sdiv_reg_reg);
8373 %}
8374 #endif
8375 
8376 // Register Long Division
8377 #ifdef AARCH64
8378 instruct divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
8379   match(Set dst (DivL src1 src2));
8380 
8381   size(4);
8382   format %{ "SDIV    $dst,$src1,$src2" %}
8383   ins_encode %{
8384     __ sdiv($dst$$Register, $src1$$Register, $src2$$Register);
8385   %}
8386   ins_pipe(ialu_reg_reg); // FIXME
8387 %}
8388 #else
8389 instruct divL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
8390   match(Set dst (DivL src1 src2));
8391   effect(CALL);
8392   ins_cost(DEFAULT_COST*71);
8393   format %{ "DIVL  $src1,$src2,$dst\t! long ! call to SharedRuntime::ldiv" %}
8394   ins_encode %{
8395     address target = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);
8396     __ call(target, relocInfo::runtime_call_type);
8397   %}
8398   ins_pipe(divL_reg_reg);
8399 %}
8400 #endif
8401 
8402 // Integer Remainder
8403 // Register Remainder
8404 #ifdef AARCH64
8405 #ifdef TODO
8406 instruct msubI_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
8407   match(Set dst (SubI src1 (MulI src2 src3)));
8408 
8409   size(4);
8410   format %{ "MSUB    $dst,$src2,$src3,$src1\t! 32-bit\n\t" %}
8411   ins_encode %{
8412     __ msub_w($dst$$Register, $src2$$Register, $src3$$Register, $src1$$Register);
8413   %}
8414   ins_pipe(ialu_reg_reg); // FIXME
8415 %}
8416 #endif
8417 
8418 instruct modI_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI temp) %{
8419   match(Set dst (ModI src1 src2));
8420   effect(TEMP temp);
8421 
8422   size(8);
8423   format %{ "SDIV    $temp,$src1,$src2\t! 32-bit\n\t"
8424             "MSUB    $dst,$src2,$temp,$src1\t! 32-bit\n\t" %}
8425   ins_encode %{
8426     __ sdiv_w($temp$$Register, $src1$$Register, $src2$$Register);
8427     __ msub_w($dst$$Register, $src2$$Register, $temp$$Register, $src1$$Register);
8428   %}
8429   ins_pipe(ialu_reg_reg); // FIXME
8430 %}
8431 #else
8432 instruct modI_reg_reg(R0RegI dst, R0RegI src1, R2RegI src2, R1RegI temp, LRRegP lr, flagsReg ccr ) %{
8433   match(Set dst (ModI src1 src2));
8434   effect( KILL ccr, KILL temp, KILL src2, KILL lr);
8435 
8436   format %{ "MODI   $dst,$src1,$src2\t ! call to StubRoutines::Arm::idiv_irem_entry" %}
8437   ins_encode %{
8438     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
8439   %}
8440   ins_pipe(sdiv_reg_reg);
8441 %}
8442 #endif
8443 
8444 // Register Long Remainder
8445 #ifdef AARCH64
8446 instruct modL_reg_reg(iRegL dst, iRegL src1, iRegL src2, iRegL temp) %{
8447   match(Set dst (ModL src1 src2));
8448   effect(TEMP temp);
8449 
8450   size(8);
8451   format %{ "SDIV    $temp,$src1,$src2\n\t"
8452             "MSUB    $dst,$src2,$temp,$src1" %}
8453   ins_encode %{
8454     __ sdiv($temp$$Register, $src1$$Register, $src2$$Register);
8455     __ msub($dst$$Register, $src2$$Register, $temp$$Register, $src1$$Register);
8456   %}
8457   ins_pipe(ialu_reg_reg); // FIXME
8458 %}
8459 #else
8460 instruct modL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
8461   match(Set dst (ModL src1 src2));
8462   effect(CALL);
8463   ins_cost(MEMORY_REF_COST); // FIXME
8464   format %{ "modL    $dst,$src1,$src2\t ! call to SharedRuntime::lrem" %}
8465   ins_encode %{
8466     address target = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
8467     __ call(target, relocInfo::runtime_call_type);
8468   %}
8469   ins_pipe(divL_reg_reg);
8470 %}
8471 #endif
8472 
8473 // Integer Shift Instructions
8474 
8475 // Register Shift Left
8476 instruct shlI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
8477   match(Set dst (LShiftI src1 src2));
8478 
8479   size(4);
8480 #ifdef AARCH64
8481   format %{ "LSLV   $dst,$src1,$src2\t! int" %}
8482   ins_encode %{
8483     __ lslv_w($dst$$Register, $src1$$Register, $src2$$Register);
8484   %}
8485 #else
8486   format %{ "LSL  $dst,$src1,$src2 \n\t" %}
8487   ins_encode %{
8488     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
8489   %}
8490 #endif
8491   ins_pipe(ialu_reg_reg);
8492 %}
8493 
8494 // Register Shift Left Immediate
8495 instruct shlI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
8496   match(Set dst (LShiftI src1 src2));
8497 
8498   size(4);
8499 #ifdef AARCH64
8500   format %{ "LSL_w  $dst,$src1,$src2\t! int" %}
8501   ins_encode %{
8502     __ _lsl($dst$$Register, $src1$$Register, $src2$$constant);
8503   %}
8504 #else
8505   format %{ "LSL    $dst,$src1,$src2\t! int" %}
8506   ins_encode %{
8507     __ logical_shift_left($dst$$Register, $src1$$Register, $src2$$constant);
8508   %}
8509 #endif
8510   ins_pipe(ialu_reg_imm);
8511 %}
8512 
8513 #ifndef AARCH64
8514 instruct shlL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
8515   effect(USE_DEF dst, USE src1, USE src2);
8516   size(4);
8517   format %{"OR  $dst.hi,$dst.hi,($src1.hi << $src2)"  %}
8518   ins_encode %{
8519     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$Register));
8520   %}
8521   ins_pipe(ialu_reg_reg);
8522 %}
8523 
8524 instruct shlL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
8525   effect(USE_DEF dst, USE src1, USE src2);
8526   size(4);
8527   format %{ "LSL  $dst.lo,$src1.lo,$src2 \n\t" %}
8528   ins_encode %{
8529     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
8530   %}
8531   ins_pipe(ialu_reg_reg);
8532 %}
8533 
8534 instruct shlL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
8535   effect(DEF dst, USE src1, USE src2, KILL ccr);
8536   size(16);
8537   format %{ "SUBS  $dst.hi,$src2,32 \n\t"
8538             "LSLpl $dst.hi,$src1.lo,$dst.hi \n\t"
8539             "RSBmi $dst.hi,$dst.hi,0 \n\t"
8540             "LSRmi $dst.hi,$src1.lo,$dst.hi" %}
8541 
8542   ins_encode %{
8543     // $src1$$Register and $dst$$Register->successor() can't be the same
8544     __ subs($dst$$Register->successor(), $src2$$Register, 32);
8545     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $dst$$Register->successor()), pl);
8546     __ rsb($dst$$Register->successor(), $dst$$Register->successor(), 0, mi);
8547     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsr, $dst$$Register->successor()), mi);
8548   %}
8549   ins_pipe(ialu_reg_reg);
8550 %}
8551 #endif // !AARCH64
8552 
8553 instruct shlL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
8554   match(Set dst (LShiftL src1 src2));
8555 
8556 #ifdef AARCH64
8557   size(4);
8558   format %{ "LSLV  $dst,$src1,$src2\t! long" %}
8559   ins_encode %{
8560     __ lslv($dst$$Register, $src1$$Register, $src2$$Register);
8561   %}
8562   ins_pipe(ialu_reg_reg);
8563 #else
8564   expand %{
8565     flagsReg ccr;
8566     shlL_reg_reg_overlap(dst, src1, src2, ccr);
8567     shlL_reg_reg_merge_hi(dst, src1, src2);
8568     shlL_reg_reg_merge_lo(dst, src1, src2);
8569   %}
8570 #endif
8571 %}
8572 
8573 #ifdef AARCH64
8574 instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6 src2) %{
8575   match(Set dst (LShiftL src1 src2));
8576 
8577   size(4);
8578   format %{ "LSL    $dst,$src1,$src2\t! long" %}
8579   ins_encode %{
8580     __ logical_shift_left($dst$$Register, $src1$$Register, $src2$$constant);
8581   %}
8582   ins_pipe(ialu_reg_imm);
8583 %}
8584 #else
8585 // Register Shift Left Immediate
8586 instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
8587   match(Set dst (LShiftL src1 src2));
8588 
8589   size(8);
8590   format %{ "LSL   $dst.hi,$src1.lo,$src2-32\t! or mov if $src2==32\n\t"
8591             "MOV   $dst.lo, 0" %}
8592   ins_encode %{
8593     if ($src2$$constant == 32) {
8594       __ mov($dst$$Register->successor(), $src1$$Register);
8595     } else {
8596       __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $src2$$constant-32));
8597     }
8598     __ mov($dst$$Register, 0);
8599   %}
8600   ins_pipe(ialu_reg_imm);
8601 %}
8602 
8603 instruct shlL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
8604   match(Set dst (LShiftL src1 src2));
8605 
8606   size(12);
8607   format %{ "LSL   $dst.hi,$src1.lo,$src2\n\t"
8608             "OR    $dst.hi, $dst.hi, $src1.lo >> 32-$src2\n\t"
8609             "LSL   $dst.lo,$src1.lo,$src2" %}
8610   ins_encode %{
8611     // The order of the following 3 instructions matters: src1.lo and
8612     // dst.hi can't overlap but src.hi and dst.hi can.
8613     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$constant));
8614     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register, lsr, 32-$src2$$constant));
8615     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
8616   %}
8617   ins_pipe(ialu_reg_imm);
8618 %}
8619 #endif // !AARCH64
8620 
8621 // Register Arithmetic Shift Right
8622 instruct sarI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
8623   match(Set dst (RShiftI src1 src2));
8624   size(4);
8625 #ifdef AARCH64
8626   format %{ "ASRV   $dst,$src1,$src2\t! int" %}
8627   ins_encode %{
8628     __ asrv_w($dst$$Register, $src1$$Register, $src2$$Register);
8629   %}
8630 #else
8631   format %{ "ASR    $dst,$src1,$src2\t! int" %}
8632   ins_encode %{
8633     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
8634   %}
8635 #endif
8636   ins_pipe(ialu_reg_reg);
8637 %}
8638 
8639 // Register Arithmetic Shift Right Immediate
8640 instruct sarI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
8641   match(Set dst (RShiftI src1 src2));
8642 
8643   size(4);
8644 #ifdef AARCH64
8645   format %{ "ASR_w  $dst,$src1,$src2" %}
8646   ins_encode %{
8647     __ _asr_w($dst$$Register, $src1$$Register, $src2$$constant);
8648   %}
8649 #else
8650   format %{ "ASR    $dst,$src1,$src2" %}
8651   ins_encode %{
8652     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
8653   %}
8654 #endif
8655   ins_pipe(ialu_reg_imm);
8656 %}
8657 
8658 #ifndef AARCH64
8659 // Register Shift Right Arithmetic Long
8660 instruct sarL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
8661   effect(USE_DEF dst, USE src1, USE src2);
8662   size(4);
8663   format %{ "OR  $dst.lo,$dst.lo,($src1.lo >> $src2)"  %}
8664   ins_encode %{
8665     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
8666   %}
8667   ins_pipe(ialu_reg_reg);
8668 %}
8669 
8670 instruct sarL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
8671   effect(USE_DEF dst, USE src1, USE src2);
8672   size(4);
8673   format %{ "ASR  $dst.hi,$src1.hi,$src2 \n\t" %}
8674   ins_encode %{
8675     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$Register));
8676   %}
8677   ins_pipe(ialu_reg_reg);
8678 %}
8679 
8680 instruct sarL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
8681   effect(DEF dst, USE src1, USE src2, KILL ccr);
8682   size(16);
8683   format %{ "SUBS  $dst.lo,$src2,32 \n\t"
8684             "ASRpl $dst.lo,$src1.hi,$dst.lo \n\t"
8685             "RSBmi $dst.lo,$dst.lo,0 \n\t"
8686             "LSLmi $dst.lo,$src1.hi,$dst.lo" %}
8687 
8688   ins_encode %{
8689     // $src1$$Register->successor() and $dst$$Register can't be the same
8690     __ subs($dst$$Register, $src2$$Register, 32);
8691     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $dst$$Register), pl);
8692     __ rsb($dst$$Register, $dst$$Register, 0, mi);
8693     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
8694   %}
8695   ins_pipe(ialu_reg_reg);
8696 %}
8697 #endif // !AARCH64
8698 
8699 instruct sarL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
8700   match(Set dst (RShiftL src1 src2));
8701 
8702 #ifdef AARCH64
8703   size(4);
8704   format %{ "ASRV  $dst,$src1,$src2\t! long" %}
8705   ins_encode %{
8706     __ asrv($dst$$Register, $src1$$Register, $src2$$Register);
8707   %}
8708   ins_pipe(ialu_reg_reg);
8709 #else
8710   expand %{
8711     flagsReg ccr;
8712     sarL_reg_reg_overlap(dst, src1, src2, ccr);
8713     sarL_reg_reg_merge_lo(dst, src1, src2);
8714     sarL_reg_reg_merge_hi(dst, src1, src2);
8715   %}
8716 #endif
8717 %}
8718 
8719 // Register Shift Left Immediate
8720 #ifdef AARCH64
8721 instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6 src2) %{
8722   match(Set dst (RShiftL src1 src2));
8723 
8724   size(4);
8725   format %{ "ASR    $dst,$src1,$src2\t! long" %}
8726   ins_encode %{
8727     __ _asr($dst$$Register, $src1$$Register, $src2$$constant);
8728   %}
8729   ins_pipe(ialu_reg_imm);
8730 %}
8731 #else
8732 instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
8733   match(Set dst (RShiftL src1 src2));
8734 
8735   size(8);
8736   format %{ "ASR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
8737             "ASR   $dst.hi,$src1.hi, $src2" %}
8738   ins_encode %{
8739     if ($src2$$constant == 32) {
8740       __ mov($dst$$Register, $src1$$Register->successor());
8741     } else{
8742       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $src2$$constant-32));
8743     }
8744     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, 0));
8745   %}
8746 
8747   ins_pipe(ialu_reg_imm);
8748 %}
8749 
8750 instruct sarL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
8751   match(Set dst (RShiftL src1 src2));
8752   size(12);
8753   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
8754             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
8755             "ASR   $dst.hi,$src1.hi,$src2" %}
8756   ins_encode %{
8757     // The order of the following 3 instructions matters: src1.lo and
8758     // dst.hi can't overlap but src.hi and dst.hi can.
8759     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
8760     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
8761     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$constant));
8762   %}
8763   ins_pipe(ialu_reg_imm);
8764 %}
8765 #endif
8766 
8767 // Register Shift Right
8768 instruct shrI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
8769   match(Set dst (URShiftI src1 src2));
8770   size(4);
8771 #ifdef AARCH64
8772   format %{ "LSRV   $dst,$src1,$src2\t! int" %}
8773   ins_encode %{
8774     __ lsrv_w($dst$$Register, $src1$$Register, $src2$$Register);
8775   %}
8776 #else
8777   format %{ "LSR    $dst,$src1,$src2\t! int" %}
8778   ins_encode %{
8779     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
8780   %}
8781 #endif
8782   ins_pipe(ialu_reg_reg);
8783 %}
8784 
8785 // Register Shift Right Immediate
8786 instruct shrI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
8787   match(Set dst (URShiftI src1 src2));
8788 
8789   size(4);
8790 #ifdef AARCH64
8791   format %{ "LSR_w  $dst,$src1,$src2" %}
8792   ins_encode %{
8793     __ _lsr_w($dst$$Register, $src1$$Register, $src2$$constant);
8794   %}
8795 #else
8796   format %{ "LSR    $dst,$src1,$src2" %}
8797   ins_encode %{
8798     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
8799   %}
8800 #endif
8801   ins_pipe(ialu_reg_imm);
8802 %}
8803 
8804 #ifndef AARCH64
8805 // Register Shift Right
8806 instruct shrL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
8807   effect(USE_DEF dst, USE src1, USE src2);
8808   size(4);
8809   format %{ "OR   $dst.lo,$dst,($src1.lo >>> $src2)"  %}
8810   ins_encode %{
8811     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
8812   %}
8813   ins_pipe(ialu_reg_reg);
8814 %}
8815 
8816 instruct shrL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
8817   effect(USE_DEF dst, USE src1, USE src2);
8818   size(4);
8819   format %{ "LSR  $dst.hi,$src1.hi,$src2 \n\t" %}
8820   ins_encode %{
8821     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$Register));
8822   %}
8823   ins_pipe(ialu_reg_reg);
8824 %}
8825 
8826 instruct shrL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
8827   effect(DEF dst, USE src1, USE src2, KILL ccr);
8828   size(16);
8829   format %{ "SUBS  $dst,$src2,32 \n\t"
8830             "LSRpl $dst,$src1.hi,$dst \n\t"
8831             "RSBmi $dst,$dst,0 \n\t"
8832             "LSLmi $dst,$src1.hi,$dst" %}
8833 
8834   ins_encode %{
8835     // $src1$$Register->successor() and $dst$$Register can't be the same
8836     __ subs($dst$$Register, $src2$$Register, 32);
8837     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $dst$$Register), pl);
8838     __ rsb($dst$$Register, $dst$$Register, 0, mi);
8839     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
8840   %}
8841   ins_pipe(ialu_reg_reg);
8842 %}
8843 #endif // !AARCH64
8844 
8845 instruct shrL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
8846   match(Set dst (URShiftL src1 src2));
8847 
8848 #ifdef AARCH64
8849   size(4);
8850   format %{ "LSRV  $dst,$src1,$src2\t! long" %}
8851   ins_encode %{
8852     __ lsrv($dst$$Register, $src1$$Register, $src2$$Register);
8853   %}
8854   ins_pipe(ialu_reg_reg);
8855 #else
8856   expand %{
8857     flagsReg ccr;
8858     shrL_reg_reg_overlap(dst, src1, src2, ccr);
8859     shrL_reg_reg_merge_lo(dst, src1, src2);
8860     shrL_reg_reg_merge_hi(dst, src1, src2);
8861   %}
8862 #endif
8863 %}
8864 
8865 // Register Shift Right Immediate
8866 #ifdef AARCH64
8867 instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6 src2) %{
8868   match(Set dst (URShiftL src1 src2));
8869 
8870   size(4);
8871   format %{ "LSR    $dst,$src1,$src2" %}
8872   ins_encode %{
8873     __ _lsr($dst$$Register, $src1$$Register, $src2$$constant);
8874   %}
8875   ins_pipe(ialu_reg_imm);
8876 %}
8877 #else
8878 instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
8879   match(Set dst (URShiftL src1 src2));
8880 
8881   size(8);
8882   format %{ "LSR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
8883             "MOV   $dst.hi, 0" %}
8884   ins_encode %{
8885     if ($src2$$constant == 32) {
8886       __ mov($dst$$Register, $src1$$Register->successor());
8887     } else {
8888       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $src2$$constant-32));
8889     }
8890     __ mov($dst$$Register->successor(), 0);
8891   %}
8892 
8893   ins_pipe(ialu_reg_imm);
8894 %}
8895 
8896 instruct shrL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
8897   match(Set dst (URShiftL src1 src2));
8898 
8899   size(12);
8900   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
8901             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
8902             "LSR   $dst.hi,$src1.hi,$src2" %}
8903   ins_encode %{
8904     // The order of the following 3 instructions matters: src1.lo and
8905     // dst.hi can't overlap but src.hi and dst.hi can.
8906     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
8907     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
8908     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$constant));
8909   %}
8910   ins_pipe(ialu_reg_imm);
8911 %}
8912 #endif // !AARCH64
8913 
8914 
8915 instruct shrP_reg_imm5(iRegX dst, iRegP src1, immU5 src2) %{
8916   match(Set dst (URShiftI (CastP2X src1) src2));
8917   size(4);
8918   format %{ "LSR    $dst,$src1,$src2\t! Cast ptr $src1 to int and shift" %}
8919   ins_encode %{
8920     __ logical_shift_right($dst$$Register, $src1$$Register, $src2$$constant);
8921   %}
8922   ins_pipe(ialu_reg_imm);
8923 %}
8924 
8925 //----------Floating Point Arithmetic Instructions-----------------------------
8926 
8927 //  Add float single precision
8928 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
8929   match(Set dst (AddF src1 src2));
8930 
8931   size(4);
8932   format %{ "FADDS  $dst,$src1,$src2" %}
8933   ins_encode %{
8934     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8935   %}
8936 
8937   ins_pipe(faddF_reg_reg);
8938 %}
8939 
8940 //  Add float double precision
8941 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
8942   match(Set dst (AddD src1 src2));
8943 
8944   size(4);
8945   format %{ "FADDD  $dst,$src1,$src2" %}
8946   ins_encode %{
8947     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8948   %}
8949 
8950   ins_pipe(faddD_reg_reg);
8951 %}
8952 
8953 //  Sub float single precision
8954 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
8955   match(Set dst (SubF src1 src2));
8956 
8957   size(4);
8958   format %{ "FSUBS  $dst,$src1,$src2" %}
8959   ins_encode %{
8960     __ sub_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8961   %}
8962   ins_pipe(faddF_reg_reg);
8963 %}
8964 
8965 //  Sub float double precision
8966 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
8967   match(Set dst (SubD src1 src2));
8968 
8969   size(4);
8970   format %{ "FSUBD  $dst,$src1,$src2" %}
8971   ins_encode %{
8972     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8973   %}
8974   ins_pipe(faddD_reg_reg);
8975 %}
8976 
8977 //  Mul float single precision
8978 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
8979   match(Set dst (MulF src1 src2));
8980 
8981   size(4);
8982   format %{ "FMULS  $dst,$src1,$src2" %}
8983   ins_encode %{
8984     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8985   %}
8986 
8987   ins_pipe(fmulF_reg_reg);
8988 %}
8989 
8990 //  Mul float double precision
8991 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
8992   match(Set dst (MulD src1 src2));
8993 
8994   size(4);
8995   format %{ "FMULD  $dst,$src1,$src2" %}
8996   ins_encode %{
8997     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8998   %}
8999 
9000   ins_pipe(fmulD_reg_reg);
9001 %}
9002 
9003 //  Div float single precision
9004 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
9005   match(Set dst (DivF src1 src2));
9006 
9007   size(4);
9008   format %{ "FDIVS  $dst,$src1,$src2" %}
9009   ins_encode %{
9010     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9011   %}
9012 
9013   ins_pipe(fdivF_reg_reg);
9014 %}
9015 
9016 //  Div float double precision
9017 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
9018   match(Set dst (DivD src1 src2));
9019 
9020   size(4);
9021   format %{ "FDIVD  $dst,$src1,$src2" %}
9022   ins_encode %{
9023     __ div_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9024   %}
9025 
9026   ins_pipe(fdivD_reg_reg);
9027 %}
9028 
9029 //  Absolute float double precision
9030 instruct absD_reg(regD dst, regD src) %{
9031   match(Set dst (AbsD src));
9032 
9033   size(4);
9034   format %{ "FABSd  $dst,$src" %}
9035   ins_encode %{
9036     __ abs_double($dst$$FloatRegister, $src$$FloatRegister);
9037   %}
9038   ins_pipe(faddD_reg);
9039 %}
9040 
9041 //  Absolute float single precision
9042 instruct absF_reg(regF dst, regF src) %{
9043   match(Set dst (AbsF src));
9044   format %{ "FABSs  $dst,$src" %}
9045   ins_encode %{
9046     __ abs_float($dst$$FloatRegister, $src$$FloatRegister);
9047   %}
9048   ins_pipe(faddF_reg);
9049 %}
9050 
9051 instruct negF_reg(regF dst, regF src) %{
9052   match(Set dst (NegF src));
9053 
9054   size(4);
9055   format %{ "FNEGs  $dst,$src" %}
9056   ins_encode %{
9057     __ neg_float($dst$$FloatRegister, $src$$FloatRegister);
9058   %}
9059   ins_pipe(faddF_reg);
9060 %}
9061 
9062 instruct negD_reg(regD dst, regD src) %{
9063   match(Set dst (NegD src));
9064 
9065   format %{ "FNEGd  $dst,$src" %}
9066   ins_encode %{
9067     __ neg_double($dst$$FloatRegister, $src$$FloatRegister);
9068   %}
9069   ins_pipe(faddD_reg);
9070 %}
9071 
9072 //  Sqrt float double precision
9073 instruct sqrtF_reg_reg(regF dst, regF src) %{
9074   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
9075 
9076   size(4);
9077   format %{ "FSQRTS $dst,$src" %}
9078   ins_encode %{
9079     __ sqrt_float($dst$$FloatRegister, $src$$FloatRegister);
9080   %}
9081   ins_pipe(fdivF_reg_reg);
9082 %}
9083 
9084 //  Sqrt float double precision
9085 instruct sqrtD_reg_reg(regD dst, regD src) %{
9086   match(Set dst (SqrtD src));
9087 
9088   size(4);
9089   format %{ "FSQRTD $dst,$src" %}
9090   ins_encode %{
9091     __ sqrt_double($dst$$FloatRegister, $src$$FloatRegister);
9092   %}
9093   ins_pipe(fdivD_reg_reg);
9094 %}
9095 
9096 //----------Logical Instructions-----------------------------------------------
9097 // And Instructions
9098 // Register And
9099 instruct andI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
9100   match(Set dst (AndI src1 src2));
9101 
9102   size(4);
9103   format %{ "and_32 $dst,$src1,$src2" %}
9104   ins_encode %{
9105     __ and_32($dst$$Register, $src1$$Register, $src2$$Register);
9106   %}
9107   ins_pipe(ialu_reg_reg);
9108 %}
9109 
9110 #ifndef AARCH64
9111 instruct andshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
9112   match(Set dst (AndI src1 (LShiftI src2 src3)));
9113 
9114   size(4);
9115   format %{ "AND    $dst,$src1,$src2<<$src3" %}
9116   ins_encode %{
9117     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
9118   %}
9119   ins_pipe(ialu_reg_reg);
9120 %}
9121 #endif
9122 
9123 instruct andshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
9124   match(Set dst (AndI src1 (LShiftI src2 src3)));
9125 
9126   size(4);
9127   format %{ "and_32 $dst,$src1,$src2<<$src3" %}
9128   ins_encode %{
9129     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
9130   %}
9131   ins_pipe(ialu_reg_reg);
9132 %}
9133 
9134 #ifndef AARCH64
9135 instruct andsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
9136   match(Set dst (AndI src1 (RShiftI src2 src3)));
9137 
9138   size(4);
9139   format %{ "AND    $dst,$src1,$src2>>$src3" %}
9140   ins_encode %{
9141     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
9142   %}
9143   ins_pipe(ialu_reg_reg);
9144 %}
9145 #endif
9146 
9147 instruct andsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
9148   match(Set dst (AndI src1 (RShiftI src2 src3)));
9149 
9150   size(4);
9151   format %{ "and_32 $dst,$src1,$src2>>$src3" %}
9152   ins_encode %{
9153     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
9154   %}
9155   ins_pipe(ialu_reg_reg);
9156 %}
9157 
9158 #ifndef AARCH64
9159 instruct andshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
9160   match(Set dst (AndI src1 (URShiftI src2 src3)));
9161 
9162   size(4);
9163   format %{ "AND    $dst,$src1,$src2>>>$src3" %}
9164   ins_encode %{
9165     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
9166   %}
9167   ins_pipe(ialu_reg_reg);
9168 %}
9169 #endif
9170 
9171 instruct andshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
9172   match(Set dst (AndI src1 (URShiftI src2 src3)));
9173 
9174   size(4);
9175   format %{ "and_32 $dst,$src1,$src2>>>$src3" %}
9176   ins_encode %{
9177     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
9178   %}
9179   ins_pipe(ialu_reg_reg);
9180 %}
9181 
9182 // Immediate And
9183 instruct andI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
9184   match(Set dst (AndI src1 src2));
9185 
9186   size(4);
9187   format %{ "and_32 $dst,$src1,$src2\t! int" %}
9188   ins_encode %{
9189     __ and_32($dst$$Register, $src1$$Register, $src2$$constant);
9190   %}
9191   ins_pipe(ialu_reg_imm);
9192 %}
9193 
9194 #ifndef AARCH64
9195 instruct andI_reg_limmn(iRegI dst, iRegI src1, limmIn src2) %{
9196   match(Set dst (AndI src1 src2));
9197 
9198   size(4);
9199   format %{ "bic    $dst,$src1,~$src2\t! int" %}
9200   ins_encode %{
9201     __ bic($dst$$Register, $src1$$Register, ~$src2$$constant);
9202   %}
9203   ins_pipe(ialu_reg_imm);
9204 %}
9205 #endif
9206 
9207 // Register And Long
9208 instruct andL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
9209   match(Set dst (AndL src1 src2));
9210 
9211   ins_cost(DEFAULT_COST);
9212 #ifdef AARCH64
9213   size(4);
9214   format %{ "AND    $dst,$src1,$src2\t! long" %}
9215   ins_encode %{
9216     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9217   %}
9218 #else
9219   size(8);
9220   format %{ "AND    $dst,$src1,$src2\t! long" %}
9221   ins_encode %{
9222     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9223     __ andr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
9224   %}
9225 #endif
9226   ins_pipe(ialu_reg_reg);
9227 %}
9228 
9229 #ifdef AARCH64
9230 // Immediate And
9231 instruct andL_reg_limm(iRegL dst, iRegL src1, limmL src2) %{
9232   match(Set dst (AndL src1 src2));
9233 
9234   size(4);
9235   format %{ "AND    $dst,$src1,$src2\t! long" %}
9236   ins_encode %{
9237     __ andr($dst$$Register, $src1$$Register, (uintx)$src2$$constant);
9238   %}
9239   ins_pipe(ialu_reg_imm);
9240 %}
9241 #else
9242 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
9243 // (hi($con$$constant), lo($con$$constant)) becomes
9244 instruct andL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
9245   match(Set dst (AndL src1 con));
9246   ins_cost(DEFAULT_COST);
9247   size(8);
9248   format %{ "AND    $dst,$src1,$con\t! long" %}
9249   ins_encode %{
9250     __ andr($dst$$Register, $src1$$Register, $con$$constant);
9251     __ andr($dst$$Register->successor(), $src1$$Register->successor(), 0);
9252   %}
9253   ins_pipe(ialu_reg_imm);
9254 %}
9255 #endif
9256 
9257 // Or Instructions
9258 // Register Or
9259 instruct orI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
9260   match(Set dst (OrI src1 src2));
9261 
9262   size(4);
9263   format %{ "orr_32 $dst,$src1,$src2\t! int" %}
9264   ins_encode %{
9265     __ orr_32($dst$$Register, $src1$$Register, $src2$$Register);
9266   %}
9267   ins_pipe(ialu_reg_reg);
9268 %}
9269 
9270 #ifndef AARCH64
9271 instruct orshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
9272   match(Set dst (OrI src1 (LShiftI src2 src3)));
9273 
9274   size(4);
9275   format %{ "OR    $dst,$src1,$src2<<$src3" %}
9276   ins_encode %{
9277     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
9278   %}
9279   ins_pipe(ialu_reg_reg);
9280 %}
9281 #endif
9282 
9283 instruct orshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
9284   match(Set dst (OrI src1 (LShiftI src2 src3)));
9285 
9286   size(4);
9287   format %{ "orr_32 $dst,$src1,$src2<<$src3" %}
9288   ins_encode %{
9289     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
9290   %}
9291   ins_pipe(ialu_reg_reg);
9292 %}
9293 
9294 #ifndef AARCH64
9295 instruct orsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
9296   match(Set dst (OrI src1 (RShiftI src2 src3)));
9297 
9298   size(4);
9299   format %{ "OR    $dst,$src1,$src2>>$src3" %}
9300   ins_encode %{
9301     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
9302   %}
9303   ins_pipe(ialu_reg_reg);
9304 %}
9305 #endif
9306 
9307 instruct orsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
9308   match(Set dst (OrI src1 (RShiftI src2 src3)));
9309 
9310   size(4);
9311   format %{ "orr_32 $dst,$src1,$src2>>$src3" %}
9312   ins_encode %{
9313     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
9314   %}
9315   ins_pipe(ialu_reg_reg);
9316 %}
9317 
9318 #ifndef AARCH64
9319 instruct orshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
9320   match(Set dst (OrI src1 (URShiftI src2 src3)));
9321 
9322   size(4);
9323   format %{ "OR    $dst,$src1,$src2>>>$src3" %}
9324   ins_encode %{
9325     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
9326   %}
9327   ins_pipe(ialu_reg_reg);
9328 %}
9329 #endif
9330 
9331 instruct orshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
9332   match(Set dst (OrI src1 (URShiftI src2 src3)));
9333 
9334   size(4);
9335   format %{ "orr_32 $dst,$src1,$src2>>>$src3" %}
9336   ins_encode %{
9337     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
9338   %}
9339   ins_pipe(ialu_reg_reg);
9340 %}
9341 
9342 // Immediate Or
9343 instruct orI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
9344   match(Set dst (OrI src1 src2));
9345 
9346   size(4);
9347   format %{ "orr_32  $dst,$src1,$src2" %}
9348   ins_encode %{
9349     __ orr_32($dst$$Register, $src1$$Register, $src2$$constant);
9350   %}
9351   ins_pipe(ialu_reg_imm);
9352 %}
9353 // TODO: orn_32 with limmIn
9354 
9355 // Register Or Long
9356 instruct orL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
9357   match(Set dst (OrL src1 src2));
9358 
9359   ins_cost(DEFAULT_COST);
9360 #ifdef AARCH64
9361   size(4);
9362   format %{ "OR     $dst,$src1,$src2\t! long" %}
9363   ins_encode %{
9364     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
9365   %}
9366 #else
9367   size(8);
9368   format %{ "OR     $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
9369             "OR     $dst.hi,$src1.hi,$src2.hi" %}
9370   ins_encode %{
9371     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
9372     __ orr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
9373   %}
9374 #endif
9375   ins_pipe(ialu_reg_reg);
9376 %}
9377 
9378 #ifdef AARCH64
9379 instruct orL_reg_limm(iRegL dst, iRegL src1, limmL src2) %{
9380   match(Set dst (OrL src1 src2));
9381 
9382   size(4);
9383   format %{ "ORR    $dst,$src1,$src2\t! long" %}
9384   ins_encode %{
9385     __ orr($dst$$Register, $src1$$Register, (uintx)$src2$$constant);
9386   %}
9387   ins_pipe(ialu_reg_imm);
9388 %}
9389 #else
9390 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
9391 // (hi($con$$constant), lo($con$$constant)) becomes
9392 instruct orL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
9393   match(Set dst (OrL src1 con));
9394   ins_cost(DEFAULT_COST);
9395   size(8);
9396   format %{ "OR     $dst.lo,$src1.lo,$con\t! long\n\t"
9397             "OR     $dst.hi,$src1.hi,$con" %}
9398   ins_encode %{
9399     __ orr($dst$$Register, $src1$$Register, $con$$constant);
9400     __ orr($dst$$Register->successor(), $src1$$Register->successor(), 0);
9401   %}
9402   ins_pipe(ialu_reg_imm);
9403 %}
9404 #endif
9405 
9406 #ifdef TODO
9407 // Use SPRegP to match Rthread (TLS register) without spilling.
9408 // Use store_ptr_RegP to match Rthread (TLS register) without spilling.
9409 // Use sp_ptr_RegP to match Rthread (TLS register) without spilling.
9410 instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
9411   match(Set dst (OrI src1 (CastP2X src2)));
9412   size(4);
9413   format %{ "OR     $dst,$src1,$src2" %}
9414   ins_encode %{
9415     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
9416   %}
9417   ins_pipe(ialu_reg_reg);
9418 %}
9419 #endif
9420 
9421 // Xor Instructions
9422 // Register Xor
9423 instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
9424   match(Set dst (XorI src1 src2));
9425 
9426   size(4);
9427   format %{ "eor_32 $dst,$src1,$src2" %}
9428   ins_encode %{
9429     __ eor_32($dst$$Register, $src1$$Register, $src2$$Register);
9430   %}
9431   ins_pipe(ialu_reg_reg);
9432 %}
9433 
9434 #ifndef AARCH64
9435 instruct xorshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
9436   match(Set dst (XorI src1 (LShiftI src2 src3)));
9437 
9438   size(4);
9439   format %{ "XOR    $dst,$src1,$src2<<$src3" %}
9440   ins_encode %{
9441     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
9442   %}
9443   ins_pipe(ialu_reg_reg);
9444 %}
9445 #endif
9446 
9447 instruct xorshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
9448   match(Set dst (XorI src1 (LShiftI src2 src3)));
9449 
9450   size(4);
9451   format %{ "eor_32 $dst,$src1,$src2<<$src3" %}
9452   ins_encode %{
9453     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
9454   %}
9455   ins_pipe(ialu_reg_reg);
9456 %}
9457 
9458 #ifndef AARCH64
9459 instruct xorsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
9460   match(Set dst (XorI src1 (RShiftI src2 src3)));
9461 
9462   size(4);
9463   format %{ "XOR    $dst,$src1,$src2>>$src3" %}
9464   ins_encode %{
9465     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
9466   %}
9467   ins_pipe(ialu_reg_reg);
9468 %}
9469 #endif
9470 
9471 instruct xorsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
9472   match(Set dst (XorI src1 (RShiftI src2 src3)));
9473 
9474   size(4);
9475   format %{ "eor_32 $dst,$src1,$src2>>$src3" %}
9476   ins_encode %{
9477     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
9478   %}
9479   ins_pipe(ialu_reg_reg);
9480 %}
9481 
9482 #ifndef AARCH64
9483 instruct xorshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
9484   match(Set dst (XorI src1 (URShiftI src2 src3)));
9485 
9486   size(4);
9487   format %{ "XOR    $dst,$src1,$src2>>>$src3" %}
9488   ins_encode %{
9489     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
9490   %}
9491   ins_pipe(ialu_reg_reg);
9492 %}
9493 #endif
9494 
9495 instruct xorshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
9496   match(Set dst (XorI src1 (URShiftI src2 src3)));
9497 
9498   size(4);
9499   format %{ "eor_32 $dst,$src1,$src2>>>$src3" %}
9500   ins_encode %{
9501     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
9502   %}
9503   ins_pipe(ialu_reg_reg);
9504 %}
9505 
9506 // Immediate Xor
9507 instruct xorI_reg_imm(iRegI dst, iRegI src1, limmI src2) %{
9508   match(Set dst (XorI src1 src2));
9509 
9510   size(4);
9511   format %{ "eor_32 $dst,$src1,$src2" %}
9512   ins_encode %{
9513     __ eor_32($dst$$Register, $src1$$Register, $src2$$constant);
9514   %}
9515   ins_pipe(ialu_reg_imm);
9516 %}
9517 
9518 // Register Xor Long
9519 instruct xorL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
9520   match(Set dst (XorL src1 src2));
9521   ins_cost(DEFAULT_COST);
9522 #ifdef AARCH64
9523   size(4);
9524   format %{ "XOR     $dst,$src1,$src2\t! long" %}
9525   ins_encode %{
9526     __ eor($dst$$Register, $src1$$Register, $src2$$Register);
9527   %}
9528 #else
9529   size(8);
9530   format %{ "XOR     $dst.hi,$src1.hi,$src2.hi\t! long\n\t"
9531             "XOR     $dst.lo,$src1.lo,$src2.lo\t! long" %}
9532   ins_encode %{
9533     __ eor($dst$$Register, $src1$$Register, $src2$$Register);
9534     __ eor($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
9535   %}
9536 #endif
9537   ins_pipe(ialu_reg_reg);
9538 %}
9539 
9540 #ifdef AARCH64
9541 instruct xorL_reg_limmL(iRegL dst, iRegL src1, limmL con) %{
9542   match(Set dst (XorL src1 con));
9543   ins_cost(DEFAULT_COST);
9544   size(4);
9545   format %{ "EOR     $dst,$src1,$con\t! long" %}
9546   ins_encode %{
9547     __ eor($dst$$Register, $src1$$Register, (uintx)$con$$constant);
9548   %}
9549   ins_pipe(ialu_reg_imm);
9550 %}
9551 #else
9552 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
9553 // (hi($con$$constant), lo($con$$constant)) becomes
9554 instruct xorL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
9555   match(Set dst (XorL src1 con));
9556   ins_cost(DEFAULT_COST);
9557   size(8);
9558   format %{ "XOR     $dst.hi,$src1.hi,$con\t! long\n\t"
9559             "XOR     $dst.lo,$src1.lo,0\t! long" %}
9560   ins_encode %{
9561     __ eor($dst$$Register, $src1$$Register, $con$$constant);
9562     __ eor($dst$$Register->successor(), $src1$$Register->successor(), 0);
9563   %}
9564   ins_pipe(ialu_reg_imm);
9565 %}
9566 #endif // AARCH64
9567 
9568 //----------Convert to Boolean-------------------------------------------------
9569 instruct convI2B( iRegI dst, iRegI src, flagsReg ccr ) %{
9570   match(Set dst (Conv2B src));
9571   effect(KILL ccr);
9572 #ifdef AARCH64
9573   size(8);
9574   ins_cost(DEFAULT_COST*2);
9575   format %{ "cmp_32 $src,ZR\n\t"
9576             "cset_w $dst, ne" %}
9577   ins_encode %{
9578     __ cmp_32($src$$Register, ZR);
9579     __ cset_w($dst$$Register, ne);
9580   %}
9581 #else
9582   size(12);
9583   ins_cost(DEFAULT_COST*2);
9584   format %{ "TST    $src,$src \n\t"
9585             "MOV    $dst, 0   \n\t"
9586             "MOV.ne $dst, 1" %}
9587   ins_encode %{ // FIXME: can do better?
9588     __ tst($src$$Register, $src$$Register);
9589     __ mov($dst$$Register, 0);
9590     __ mov($dst$$Register, 1, ne);
9591   %}
9592 #endif
9593   ins_pipe(ialu_reg_ialu);
9594 %}
9595 
9596 instruct convP2B( iRegI dst, iRegP src, flagsReg ccr ) %{
9597   match(Set dst (Conv2B src));
9598   effect(KILL ccr);
9599 #ifdef AARCH64
9600   size(8);
9601   ins_cost(DEFAULT_COST*2);
9602   format %{ "CMP    $src,ZR\n\t"
9603             "cset   $dst, ne" %}
9604   ins_encode %{
9605     __ cmp($src$$Register, ZR);
9606     __ cset($dst$$Register, ne);
9607   %}
9608 #else
9609   size(12);
9610   ins_cost(DEFAULT_COST*2);
9611   format %{ "TST    $src,$src \n\t"
9612             "MOV    $dst, 0   \n\t"
9613             "MOV.ne $dst, 1" %}
9614   ins_encode %{
9615     __ tst($src$$Register, $src$$Register);
9616     __ mov($dst$$Register, 0);
9617     __ mov($dst$$Register, 1, ne);
9618   %}
9619 #endif
9620   ins_pipe(ialu_reg_ialu);
9621 %}
9622 
9623 instruct cmpLTMask_reg_reg( iRegI dst, iRegI p, iRegI q, flagsReg ccr ) %{
9624   match(Set dst (CmpLTMask p q));
9625   effect( KILL ccr );
9626 #ifdef AARCH64
9627   size(8);
9628   ins_cost(DEFAULT_COST*2);
9629   format %{ "CMP_w   $p,$q\n\t"
9630             "CSETM_w $dst, lt" %}
9631   ins_encode %{
9632     __ cmp_w($p$$Register, $q$$Register);
9633     __ csetm_w($dst$$Register, lt);
9634   %}
9635 #else
9636   ins_cost(DEFAULT_COST*3);
9637   format %{ "CMP    $p,$q\n\t"
9638             "MOV    $dst, #0\n\t"
9639             "MOV.lt $dst, #-1" %}
9640   ins_encode %{
9641     __ cmp($p$$Register, $q$$Register);
9642     __ mov($dst$$Register, 0);
9643     __ mvn($dst$$Register, 0, lt);
9644   %}
9645 #endif
9646   ins_pipe(ialu_reg_reg_ialu);
9647 %}
9648 
9649 instruct cmpLTMask_reg_imm( iRegI dst, iRegI p, aimmI q, flagsReg ccr ) %{
9650   match(Set dst (CmpLTMask p q));
9651   effect( KILL ccr );
9652 #ifdef AARCH64
9653   size(8);
9654   ins_cost(DEFAULT_COST*2);
9655   format %{ "CMP_w   $p,$q\n\t"
9656             "CSETM_w $dst, lt" %}
9657   ins_encode %{
9658     __ cmp_w($p$$Register, $q$$constant);
9659     __ csetm_w($dst$$Register, lt);
9660   %}
9661 #else
9662   ins_cost(DEFAULT_COST*3);
9663   format %{ "CMP    $p,$q\n\t"
9664             "MOV    $dst, #0\n\t"
9665             "MOV.lt $dst, #-1" %}
9666   ins_encode %{
9667     __ cmp($p$$Register, $q$$constant);
9668     __ mov($dst$$Register, 0);
9669     __ mvn($dst$$Register, 0, lt);
9670   %}
9671 #endif
9672   ins_pipe(ialu_reg_reg_ialu);
9673 %}
9674 
9675 #ifdef AARCH64
9676 instruct cadd_cmpLTMask3( iRegI dst, iRegI p, iRegI q, iRegI y, iRegI x, flagsReg ccr ) %{
9677   match(Set dst (AddI (AndI (CmpLTMask p q) y) x));
9678   effect( TEMP dst, KILL ccr );
9679   size(12);
9680   ins_cost(DEFAULT_COST*3);
9681   format %{ "CMP_w  $p,$q\n\t"
9682             "ADD_w  $dst,$y,$x\n\t"
9683             "CSEL_w $dst,$dst,$x,lt" %}
9684   ins_encode %{
9685     __ cmp_w($p$$Register, $q$$Register);
9686     __ add_w($dst$$Register, $y$$Register, $x$$Register);
9687     __ csel_w($dst$$Register, $dst$$Register, $x$$Register, lt);
9688   %}
9689   ins_pipe( cadd_cmpltmask );
9690 %}
9691 #else
9692 instruct cadd_cmpLTMask3( iRegI p, iRegI q, iRegI y, iRegI z, flagsReg ccr ) %{
9693   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
9694   effect( KILL ccr );
9695   ins_cost(DEFAULT_COST*2);
9696   format %{ "CMP    $p,$q\n\t"
9697             "ADD.lt $z,$y,$z" %}
9698   ins_encode %{
9699     __ cmp($p$$Register, $q$$Register);
9700     __ add($z$$Register, $y$$Register, $z$$Register, lt);
9701   %}
9702   ins_pipe( cadd_cmpltmask );
9703 %}
9704 #endif
9705 
9706 #ifdef AARCH64
9707 instruct cadd_cmpLTMask4( iRegI dst, iRegI p, aimmI q, iRegI y, iRegI x, flagsReg ccr ) %{
9708   match(Set dst (AddI (AndI (CmpLTMask p q) y) x));
9709   effect( TEMP dst, KILL ccr );
9710   size(12);
9711   ins_cost(DEFAULT_COST*3);
9712   format %{ "CMP_w  $p,$q\n\t"
9713             "ADD_w  $dst,$y,$x\n\t"
9714             "CSEL_w $dst,$dst,$x,lt" %}
9715   ins_encode %{
9716     __ cmp_w($p$$Register, $q$$constant);
9717     __ add_w($dst$$Register, $y$$Register, $x$$Register);
9718     __ csel_w($dst$$Register, $dst$$Register, $x$$Register, lt);
9719   %}
9720   ins_pipe( cadd_cmpltmask );
9721 %}
9722 #else
9723 // FIXME: remove unused "dst"
9724 instruct cadd_cmpLTMask4( iRegI dst, iRegI p, aimmI q, iRegI y, iRegI z, flagsReg ccr ) %{
9725   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
9726   effect( KILL ccr );
9727   ins_cost(DEFAULT_COST*2);
9728   format %{ "CMP    $p,$q\n\t"
9729             "ADD.lt $z,$y,$z" %}
9730   ins_encode %{
9731     __ cmp($p$$Register, $q$$constant);
9732     __ add($z$$Register, $y$$Register, $z$$Register, lt);
9733   %}
9734   ins_pipe( cadd_cmpltmask );
9735 %}
9736 #endif // !AARCH64
9737 
9738 #ifdef AARCH64
9739 instruct cadd_cmpLTMask( iRegI dst, iRegI p, iRegI q, iRegI y, flagsReg ccr ) %{
9740   match(Set dst (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
9741   effect( TEMP dst, KILL ccr );
9742   size(12);
9743   ins_cost(DEFAULT_COST*3);
9744   format %{ "SUBS_w $p,$p,$q\n\t"
9745             "ADD_w  $dst,$y,$p\n\t"
9746             "CSEL_w $dst,$dst,$p,lt" %}
9747   ins_encode %{
9748     __ subs_w($p$$Register, $p$$Register, $q$$Register);
9749     __ add_w($dst$$Register, $y$$Register, $p$$Register);
9750     __ csel_w($dst$$Register, $dst$$Register, $p$$Register, lt);
9751   %}
9752   ins_pipe( cadd_cmpltmask ); // FIXME
9753 %}
9754 #else
9755 instruct cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, flagsReg ccr ) %{
9756   match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
9757   effect( KILL ccr );
9758   ins_cost(DEFAULT_COST*2);
9759   format %{ "SUBS   $p,$p,$q\n\t"
9760             "ADD.lt $p,$y,$p" %}
9761   ins_encode %{
9762     __ subs($p$$Register, $p$$Register, $q$$Register);
9763     __ add($p$$Register, $y$$Register, $p$$Register, lt);
9764   %}
9765   ins_pipe( cadd_cmpltmask );
9766 %}
9767 #endif
9768 
9769 //----------Arithmetic Conversion Instructions---------------------------------
9770 // The conversions operations are all Alpha sorted.  Please keep it that way!
9771 
9772 instruct convD2F_reg(regF dst, regD src) %{
9773   match(Set dst (ConvD2F src));
9774   size(4);
9775   format %{ "FCVTSD  $dst,$src" %}
9776   ins_encode %{
9777     __ convert_d2f($dst$$FloatRegister, $src$$FloatRegister);
9778   %}
9779   ins_pipe(fcvtD2F);
9780 %}
9781 
9782 // Convert a double to an int in a float register.
9783 // If the double is a NAN, stuff a zero in instead.
9784 
9785 #ifdef AARCH64
9786 instruct convD2I_reg_reg(iRegI dst, regD src) %{
9787   match(Set dst (ConvD2I src));
9788   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
9789   format %{ "FCVTZS_wd $dst, $src" %}
9790   ins_encode %{
9791     __ fcvtzs_wd($dst$$Register, $src$$FloatRegister);
9792   %}
9793   ins_pipe(fcvtD2I);
9794 %}
9795 
9796 instruct convD2L_reg_reg(iRegL dst, regD src) %{
9797   match(Set dst (ConvD2L src));
9798   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
9799   format %{ "FCVTZS_xd $dst, $src" %}
9800   ins_encode %{
9801     __ fcvtzs_xd($dst$$Register, $src$$FloatRegister);
9802   %}
9803   ins_pipe(fcvtD2L);
9804 %}
9805 #else
9806 instruct convD2I_reg_reg(iRegI dst, regD src, regF tmp) %{
9807   match(Set dst (ConvD2I src));
9808   effect( TEMP tmp );
9809   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
9810   format %{ "FTOSIZD  $tmp,$src\n\t"
9811             "FMRS     $dst, $tmp" %}
9812   ins_encode %{
9813     __ ftosizd($tmp$$FloatRegister, $src$$FloatRegister);
9814     __ fmrs($dst$$Register, $tmp$$FloatRegister);
9815   %}
9816   ins_pipe(fcvtD2I);
9817 %}
9818 #endif
9819 
9820 // Convert a double to a long in a double register.
9821 // If the double is a NAN, stuff a zero in instead.
9822 
9823 #ifndef AARCH64
9824 // Double to Long conversion
9825 instruct convD2L_reg(R0R1RegL dst, regD src) %{
9826   match(Set dst (ConvD2L src));
9827   effect(CALL);
9828   ins_cost(MEMORY_REF_COST); // FIXME
9829   format %{ "convD2L    $dst,$src\t ! call to SharedRuntime::d2l" %}
9830   ins_encode %{
9831 #ifndef __ABI_HARD__
9832     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
9833 #else
9834     if ($src$$FloatRegister != D0) {
9835       __ mov_double(D0, $src$$FloatRegister);
9836     }
9837 #endif
9838     address target = CAST_FROM_FN_PTR(address, SharedRuntime::d2l);
9839     __ call(target, relocInfo::runtime_call_type);
9840   %}
9841   ins_pipe(fcvtD2L);
9842 %}
9843 #endif
9844 
9845 instruct convF2D_reg(regD dst, regF src) %{
9846   match(Set dst (ConvF2D src));
9847   size(4);
9848   format %{ "FCVTDS  $dst,$src" %}
9849   ins_encode %{
9850     __ convert_f2d($dst$$FloatRegister, $src$$FloatRegister);
9851   %}
9852   ins_pipe(fcvtF2D);
9853 %}
9854 
9855 #ifdef AARCH64
9856 instruct convF2I_reg_reg(iRegI dst, regF src) %{
9857   match(Set dst (ConvF2I src));
9858   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
9859   size(4);
9860   format %{ "FCVTZS_ws $dst, $src" %}
9861   ins_encode %{
9862     __ fcvtzs_ws($dst$$Register, $src$$FloatRegister);
9863   %}
9864   ins_pipe(fcvtF2I);
9865 %}
9866 
9867 instruct convF2L_reg_reg(iRegL dst, regF src) %{
9868   match(Set dst (ConvF2L src));
9869   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
9870   size(4);
9871   format %{ "FCVTZS_xs $dst, $src" %}
9872   ins_encode %{
9873     __ fcvtzs_xs($dst$$Register, $src$$FloatRegister);
9874   %}
9875   ins_pipe(fcvtF2L);
9876 %}
9877 #else
9878 instruct convF2I_reg_reg(iRegI dst, regF src, regF tmp) %{
9879   match(Set dst (ConvF2I src));
9880   effect( TEMP tmp );
9881   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
9882   size(8);
9883   format %{ "FTOSIZS  $tmp,$src\n\t"
9884             "FMRS     $dst, $tmp" %}
9885   ins_encode %{
9886     __ ftosizs($tmp$$FloatRegister, $src$$FloatRegister);
9887     __ fmrs($dst$$Register, $tmp$$FloatRegister);
9888   %}
9889   ins_pipe(fcvtF2I);
9890 %}
9891 
9892 // Float to Long conversion
9893 instruct convF2L_reg(R0R1RegL dst, regF src, R0RegI arg1) %{
9894   match(Set dst (ConvF2L src));
9895   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
9896   effect(CALL);
9897   format %{ "convF2L  $dst,$src\t! call to SharedRuntime::f2l" %}
9898   ins_encode %{
9899 #ifndef __ABI_HARD__
9900     __ fmrs($arg1$$Register, $src$$FloatRegister);
9901 #else
9902     if($src$$FloatRegister != S0) {
9903       __ mov_float(S0, $src$$FloatRegister);
9904     }
9905 #endif
9906     address target = CAST_FROM_FN_PTR(address, SharedRuntime::f2l);
9907     __ call(target, relocInfo::runtime_call_type);
9908   %}
9909   ins_pipe(fcvtF2L);
9910 %}
9911 #endif
9912 
9913 #ifdef AARCH64
9914 instruct convI2D_reg_reg(iRegI src, regD dst) %{
9915   match(Set dst (ConvI2D src));
9916   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
9917   size(4);
9918   format %{ "SCVTF_dw $dst,$src" %}
9919   ins_encode %{
9920       __ scvtf_dw($dst$$FloatRegister, $src$$Register);
9921   %}
9922   ins_pipe(fcvtI2D);
9923 %}
9924 #else
9925 instruct convI2D_reg_reg(iRegI src, regD_low dst) %{
9926   match(Set dst (ConvI2D src));
9927   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
9928   size(8);
9929   format %{ "FMSR     $dst,$src \n\t"
9930             "FSITOD   $dst $dst"%}
9931   ins_encode %{
9932       __ fmsr($dst$$FloatRegister, $src$$Register);
9933       __ fsitod($dst$$FloatRegister, $dst$$FloatRegister);
9934   %}
9935   ins_pipe(fcvtI2D);
9936 %}
9937 #endif
9938 
9939 instruct convI2F_reg_reg( regF dst, iRegI src ) %{
9940   match(Set dst (ConvI2F src));
9941   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
9942 #ifdef AARCH64
9943   size(4);
9944   format %{ "SCVTF_sw $dst,$src" %}
9945   ins_encode %{
9946       __ scvtf_sw($dst$$FloatRegister, $src$$Register);
9947   %}
9948 #else
9949   size(8);
9950   format %{ "FMSR     $dst,$src \n\t"
9951             "FSITOS   $dst, $dst"%}
9952   ins_encode %{
9953       __ fmsr($dst$$FloatRegister, $src$$Register);
9954       __ fsitos($dst$$FloatRegister, $dst$$FloatRegister);
9955   %}
9956 #endif
9957   ins_pipe(fcvtI2F);
9958 %}
9959 
9960 instruct convI2L_reg(iRegL dst, iRegI src) %{
9961   match(Set dst (ConvI2L src));
9962 #ifdef AARCH64
9963   size(4);
9964   format %{ "SXTW   $dst,$src\t! int->long" %}
9965   ins_encode %{
9966     __ sxtw($dst$$Register, $src$$Register);
9967   %}
9968 #else
9969   size(8);
9970   format %{ "MOV    $dst.lo, $src \n\t"
9971             "ASR    $dst.hi,$src,31\t! int->long" %}
9972   ins_encode %{
9973     __ mov($dst$$Register, $src$$Register);
9974     __ mov($dst$$Register->successor(), AsmOperand($src$$Register, asr, 31));
9975   %}
9976 #endif
9977   ins_pipe(ialu_reg_reg);
9978 %}
9979 
9980 // Zero-extend convert int to long
9981 instruct convI2L_reg_zex(iRegL dst, iRegI src, immL_32bits mask ) %{
9982   match(Set dst (AndL (ConvI2L src) mask) );
9983 #ifdef AARCH64
9984   size(4);
9985   format %{ "mov_w  $dst,$src\t! zero-extend int to long"  %}
9986   ins_encode %{
9987     __ mov_w($dst$$Register, $src$$Register);
9988   %}
9989 #else
9990   size(8);
9991   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend int to long\n\t"
9992             "MOV    $dst.hi, 0"%}
9993   ins_encode %{
9994     __ mov($dst$$Register, $src$$Register);
9995     __ mov($dst$$Register->successor(), 0);
9996   %}
9997 #endif
9998   ins_pipe(ialu_reg_reg);
9999 %}
10000 
10001 // Zero-extend long
10002 instruct zerox_long(iRegL dst, iRegL src, immL_32bits mask ) %{
10003   match(Set dst (AndL src mask) );
10004 #ifdef AARCH64
10005   size(4);
10006   format %{ "mov_w  $dst,$src\t! zero-extend long"  %}
10007   ins_encode %{
10008     __ mov_w($dst$$Register, $src$$Register);
10009   %}
10010 #else
10011   size(8);
10012   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend long\n\t"
10013             "MOV    $dst.hi, 0"%}
10014   ins_encode %{
10015     __ mov($dst$$Register, $src$$Register);
10016     __ mov($dst$$Register->successor(), 0);
10017   %}
10018 #endif
10019   ins_pipe(ialu_reg_reg);
10020 %}
10021 
10022 instruct MoveF2I_reg_reg(iRegI dst, regF src) %{
10023   match(Set dst (MoveF2I src));
10024   effect(DEF dst, USE src);
10025   ins_cost(MEMORY_REF_COST); // FIXME
10026 
10027   size(4);
10028   format %{ "FMRS   $dst,$src\t! MoveF2I" %}
10029   ins_encode %{
10030     __ fmrs($dst$$Register, $src$$FloatRegister);
10031   %}
10032   ins_pipe(iload_mem); // FIXME
10033 %}
10034 
10035 instruct MoveI2F_reg_reg(regF dst, iRegI src) %{
10036   match(Set dst (MoveI2F src));
10037   ins_cost(MEMORY_REF_COST); // FIXME
10038 
10039   size(4);
10040   format %{ "FMSR   $dst,$src\t! MoveI2F" %}
10041   ins_encode %{
10042     __ fmsr($dst$$FloatRegister, $src$$Register);
10043   %}
10044   ins_pipe(iload_mem); // FIXME
10045 %}
10046 
10047 instruct MoveD2L_reg_reg(iRegL dst, regD src) %{
10048   match(Set dst (MoveD2L src));
10049   effect(DEF dst, USE src);
10050   ins_cost(MEMORY_REF_COST); // FIXME
10051 
10052   size(4);
10053 #ifdef AARCH64
10054   format %{ "FMOV_xd  $dst,$src\t! MoveD2L" %}
10055   ins_encode %{
10056     __ fmov_xd($dst$$Register, $src$$FloatRegister);
10057   %}
10058 #else
10059   format %{ "FMRRD    $dst,$src\t! MoveD2L" %}
10060   ins_encode %{
10061     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
10062   %}
10063 #endif
10064   ins_pipe(iload_mem); // FIXME
10065 %}
10066 
10067 instruct MoveL2D_reg_reg(regD dst, iRegL src) %{
10068   match(Set dst (MoveL2D src));
10069   effect(DEF dst, USE src);
10070   ins_cost(MEMORY_REF_COST); // FIXME
10071 
10072   size(4);
10073 #ifdef AARCH64
10074   format %{ "FMOV_dx $dst,$src\t! MoveL2D" %}
10075   ins_encode %{
10076     __ fmov_dx($dst$$FloatRegister, $src$$Register);
10077   %}
10078 #else
10079   format %{ "FMDRR   $dst,$src\t! MoveL2D" %}
10080   ins_encode %{
10081     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
10082   %}
10083 #endif
10084   ins_pipe(ialu_reg_reg); // FIXME
10085 %}
10086 
10087 //-----------
10088 // Long to Double conversion
10089 
10090 #ifdef AARCH64
10091 instruct convL2D(regD dst, iRegL src) %{
10092   match(Set dst (ConvL2D src));
10093   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
10094   size(4);
10095   format %{ "SCVTF_dx $dst, $src" %}
10096   ins_encode %{
10097     __ scvtf_dx($dst$$FloatRegister, $src$$Register);
10098   %}
10099   ins_pipe(fcvtL2D);
10100 %}
10101 
10102 instruct convL2F(regF dst, iRegL src) %{
10103   match(Set dst (ConvL2F src));
10104   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
10105   size(4);
10106   format %{ "SCVTF_sx $dst, $src" %}
10107   ins_encode %{
10108     __ scvtf_sx($dst$$FloatRegister, $src$$Register);
10109   %}
10110   ins_pipe(fcvtL2F);
10111 %}
10112 #else
10113 // Magic constant, 0x43300000
10114 instruct loadConI_x43300000(iRegI dst) %{
10115   effect(DEF dst);
10116   size(8);
10117   format %{ "MOV_SLOW  $dst,0x43300000\t! 2^52" %}
10118   ins_encode %{
10119     __ mov_slow($dst$$Register, 0x43300000);
10120   %}
10121   ins_pipe(ialu_none);
10122 %}
10123 
10124 // Magic constant, 0x41f00000
10125 instruct loadConI_x41f00000(iRegI dst) %{
10126   effect(DEF dst);
10127   size(8);
10128   format %{ "MOV_SLOW  $dst, 0x41f00000\t! 2^32" %}
10129   ins_encode %{
10130     __ mov_slow($dst$$Register, 0x41f00000);
10131   %}
10132   ins_pipe(ialu_none);
10133 %}
10134 
10135 instruct loadConI_x0(iRegI dst) %{
10136   effect(DEF dst);
10137   size(4);
10138   format %{ "MOV  $dst, 0x0\t! 0" %}
10139   ins_encode %{
10140     __ mov($dst$$Register, 0);
10141   %}
10142   ins_pipe(ialu_none);
10143 %}
10144 
10145 // Construct a double from two float halves
10146 instruct regDHi_regDLo_to_regD(regD_low dst, regD_low src1, regD_low src2) %{
10147   effect(DEF dst, USE src1, USE src2);
10148   size(8);
10149   format %{ "FCPYS  $dst.hi,$src1.hi\n\t"
10150             "FCPYS  $dst.lo,$src2.lo" %}
10151   ins_encode %{
10152     __ fcpys($dst$$FloatRegister->successor(), $src1$$FloatRegister->successor());
10153     __ fcpys($dst$$FloatRegister, $src2$$FloatRegister);
10154   %}
10155   ins_pipe(faddD_reg_reg);
10156 %}
10157 
10158 #ifndef AARCH64
10159 // Convert integer in high half of a double register (in the lower half of
10160 // the double register file) to double
10161 instruct convI2D_regDHi_regD(regD dst, regD_low src) %{
10162   effect(DEF dst, USE src);
10163   size(4);
10164   format %{ "FSITOD  $dst,$src" %}
10165   ins_encode %{
10166     __ fsitod($dst$$FloatRegister, $src$$FloatRegister->successor());
10167   %}
10168   ins_pipe(fcvtLHi2D);
10169 %}
10170 #endif
10171 
10172 // Add float double precision
10173 instruct addD_regD_regD(regD dst, regD src1, regD src2) %{
10174   effect(DEF dst, USE src1, USE src2);
10175   size(4);
10176   format %{ "FADDD  $dst,$src1,$src2" %}
10177   ins_encode %{
10178     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10179   %}
10180   ins_pipe(faddD_reg_reg);
10181 %}
10182 
10183 // Sub float double precision
10184 instruct subD_regD_regD(regD dst, regD src1, regD src2) %{
10185   effect(DEF dst, USE src1, USE src2);
10186   size(4);
10187   format %{ "FSUBD  $dst,$src1,$src2" %}
10188   ins_encode %{
10189     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10190   %}
10191   ins_pipe(faddD_reg_reg);
10192 %}
10193 
10194 // Mul float double precision
10195 instruct mulD_regD_regD(regD dst, regD src1, regD src2) %{
10196   effect(DEF dst, USE src1, USE src2);
10197   size(4);
10198   format %{ "FMULD  $dst,$src1,$src2" %}
10199   ins_encode %{
10200     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10201   %}
10202   ins_pipe(fmulD_reg_reg);
10203 %}
10204 
10205 instruct regL_to_regD(regD dst, iRegL src) %{
10206   // No match rule to avoid chain rule match.
10207   effect(DEF dst, USE src);
10208   ins_cost(MEMORY_REF_COST);
10209   size(4);
10210   format %{ "FMDRR   $dst,$src\t! regL to regD" %}
10211   ins_encode %{
10212     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
10213   %}
10214   ins_pipe(ialu_reg_reg); // FIXME
10215 %}
10216 
10217 instruct regI_regI_to_regD(regD dst, iRegI src1, iRegI src2) %{
10218   // No match rule to avoid chain rule match.
10219   effect(DEF dst, USE src1, USE src2);
10220   ins_cost(MEMORY_REF_COST);
10221   size(4);
10222   format %{ "FMDRR   $dst,$src1,$src2\t! regI,regI to regD" %}
10223   ins_encode %{
10224     __ fmdrr($dst$$FloatRegister, $src1$$Register, $src2$$Register);
10225   %}
10226   ins_pipe(ialu_reg_reg); // FIXME
10227 %}
10228 
10229 instruct convL2D_reg_slow_fxtof(regD dst, iRegL src) %{
10230   match(Set dst (ConvL2D src));
10231   ins_cost(DEFAULT_COST*8 + MEMORY_REF_COST*6); // FIXME
10232 
10233   expand %{
10234     regD_low   tmpsrc;
10235     iRegI      ix43300000;
10236     iRegI      ix41f00000;
10237     iRegI      ix0;
10238     regD_low   dx43300000;
10239     regD       dx41f00000;
10240     regD       tmp1;
10241     regD_low   tmp2;
10242     regD       tmp3;
10243     regD       tmp4;
10244 
10245     regL_to_regD(tmpsrc, src);
10246 
10247     loadConI_x43300000(ix43300000);
10248     loadConI_x41f00000(ix41f00000);
10249     loadConI_x0(ix0);
10250 
10251     regI_regI_to_regD(dx43300000, ix0, ix43300000);
10252     regI_regI_to_regD(dx41f00000, ix0, ix41f00000);
10253 
10254     convI2D_regDHi_regD(tmp1, tmpsrc);
10255     regDHi_regDLo_to_regD(tmp2, dx43300000, tmpsrc);
10256     subD_regD_regD(tmp3, tmp2, dx43300000);
10257     mulD_regD_regD(tmp4, tmp1, dx41f00000);
10258     addD_regD_regD(dst, tmp3, tmp4);
10259   %}
10260 %}
10261 #endif // !AARCH64
10262 
10263 instruct convL2I_reg(iRegI dst, iRegL src) %{
10264   match(Set dst (ConvL2I src));
10265   size(4);
10266 #ifdef AARCH64
10267   format %{ "MOV_w  $dst,$src\t! long->int" %}
10268   ins_encode %{
10269     __ mov_w($dst$$Register, $src$$Register);
10270   %}
10271 #else
10272   format %{ "MOV    $dst,$src.lo\t! long->int" %}
10273   ins_encode %{
10274     __ mov($dst$$Register, $src$$Register);
10275   %}
10276 #endif
10277   ins_pipe(ialu_move_reg_I_to_L);
10278 %}
10279 
10280 #ifndef AARCH64
10281 // Register Shift Right Immediate
10282 instruct shrL_reg_imm6_L2I(iRegI dst, iRegL src, immI_32_63 cnt) %{
10283   match(Set dst (ConvL2I (RShiftL src cnt)));
10284   size(4);
10285   format %{ "ASR    $dst,$src.hi,($cnt - 32)\t! long->int or mov if $cnt==32" %}
10286   ins_encode %{
10287     if ($cnt$$constant == 32) {
10288       __ mov($dst$$Register, $src$$Register->successor());
10289     } else {
10290       __ mov($dst$$Register, AsmOperand($src$$Register->successor(), asr, $cnt$$constant - 32));
10291     }
10292   %}
10293   ins_pipe(ialu_reg_imm);
10294 %}
10295 #endif
10296 
10297 
10298 //----------Control Flow Instructions------------------------------------------
10299 // Compare Instructions
10300 // Compare Integers
10301 instruct compI_iReg(flagsReg icc, iRegI op1, iRegI op2) %{
10302   match(Set icc (CmpI op1 op2));
10303   effect( DEF icc, USE op1, USE op2 );
10304 
10305   size(4);
10306   format %{ "cmp_32 $op1,$op2\t! int" %}
10307   ins_encode %{
10308     __ cmp_32($op1$$Register, $op2$$Register);
10309   %}
10310   ins_pipe(ialu_cconly_reg_reg);
10311 %}
10312 
10313 #ifdef _LP64
10314 // Compare compressed pointers
10315 instruct compN_reg2(flagsRegU icc, iRegN op1, iRegN op2) %{
10316   match(Set icc (CmpN op1 op2));
10317   effect( DEF icc, USE op1, USE op2 );
10318 
10319   size(4);
10320   format %{ "cmp_32 $op1,$op2\t! int" %}
10321   ins_encode %{
10322     __ cmp_32($op1$$Register, $op2$$Register);
10323   %}
10324   ins_pipe(ialu_cconly_reg_reg);
10325 %}
10326 #endif
10327 
10328 instruct compU_iReg(flagsRegU icc, iRegI op1, iRegI op2) %{
10329   match(Set icc (CmpU op1 op2));
10330 
10331   size(4);
10332   format %{ "cmp_32 $op1,$op2\t! unsigned int" %}
10333   ins_encode %{
10334     __ cmp_32($op1$$Register, $op2$$Register);
10335   %}
10336   ins_pipe(ialu_cconly_reg_reg);
10337 %}
10338 
10339 instruct compI_iReg_immneg(flagsReg icc, iRegI op1, aimmIneg op2) %{
10340   match(Set icc (CmpI op1 op2));
10341   effect( DEF icc, USE op1 );
10342 
10343   size(4);
10344   format %{ "cmn_32 $op1,-$op2\t! int" %}
10345   ins_encode %{
10346     __ cmn_32($op1$$Register, -$op2$$constant);
10347   %}
10348   ins_pipe(ialu_cconly_reg_imm);
10349 %}
10350 
10351 instruct compI_iReg_imm(flagsReg icc, iRegI op1, aimmI op2) %{
10352   match(Set icc (CmpI op1 op2));
10353   effect( DEF icc, USE op1 );
10354 
10355   size(4);
10356   format %{ "cmp_32 $op1,$op2\t! int" %}
10357   ins_encode %{
10358     __ cmp_32($op1$$Register, $op2$$constant);
10359   %}
10360   ins_pipe(ialu_cconly_reg_imm);
10361 %}
10362 
10363 instruct testI_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immI0 zero ) %{
10364   match(Set icc (CmpI (AndI op1 op2) zero));
10365   size(4);
10366   format %{ "tst_32 $op2,$op1" %}
10367 
10368   ins_encode %{
10369     __ tst_32($op1$$Register, $op2$$Register);
10370   %}
10371   ins_pipe(ialu_cconly_reg_reg_zero);
10372 %}
10373 
10374 #ifndef AARCH64
10375 instruct testshlI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
10376   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
10377   size(4);
10378   format %{ "TST   $op2,$op1<<$op3" %}
10379 
10380   ins_encode %{
10381     __ tst($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$Register));
10382   %}
10383   ins_pipe(ialu_cconly_reg_reg_zero);
10384 %}
10385 #endif
10386 
10387 instruct testshlI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
10388   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
10389   size(4);
10390   format %{ "tst_32 $op2,$op1<<$op3" %}
10391 
10392   ins_encode %{
10393     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$constant));
10394   %}
10395   ins_pipe(ialu_cconly_reg_reg_zero);
10396 %}
10397 
10398 #ifndef AARCH64
10399 instruct testsarI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
10400   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
10401   size(4);
10402   format %{ "TST   $op2,$op1<<$op3" %}
10403 
10404   ins_encode %{
10405     __ tst($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$Register));
10406   %}
10407   ins_pipe(ialu_cconly_reg_reg_zero);
10408 %}
10409 #endif
10410 
10411 instruct testsarI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
10412   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
10413   size(4);
10414   format %{ "tst_32 $op2,$op1<<$op3" %}
10415 
10416   ins_encode %{
10417     __ tst_32($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$constant));
10418   %}
10419   ins_pipe(ialu_cconly_reg_reg_zero);
10420 %}
10421 
10422 #ifndef AARCH64
10423 instruct testshrI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
10424   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
10425   size(4);
10426   format %{ "TST   $op2,$op1<<$op3" %}
10427 
10428   ins_encode %{
10429     __ tst($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$Register));
10430   %}
10431   ins_pipe(ialu_cconly_reg_reg_zero);
10432 %}
10433 #endif
10434 
10435 instruct testshrI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
10436   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
10437   size(4);
10438   format %{ "tst_32 $op2,$op1<<$op3" %}
10439 
10440   ins_encode %{
10441     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$constant));
10442   %}
10443   ins_pipe(ialu_cconly_reg_reg_zero);
10444 %}
10445 
10446 instruct testI_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, limmI op2, immI0 zero ) %{
10447   match(Set icc (CmpI (AndI op1 op2) zero));
10448   size(4);
10449   format %{ "tst_32 $op2,$op1" %}
10450 
10451   ins_encode %{
10452     __ tst_32($op1$$Register, $op2$$constant);
10453   %}
10454   ins_pipe(ialu_cconly_reg_imm_zero);
10455 %}
10456 
10457 #ifdef AARCH64
10458 instruct compL_reg_reg(flagsReg xcc, iRegL op1, iRegL op2)
10459 %{
10460   match(Set xcc (CmpL op1 op2));
10461   effect( DEF xcc, USE op1, USE op2 );
10462 
10463   size(4);
10464   format %{ "CMP     $op1,$op2\t! long" %}
10465   ins_encode %{
10466     __ cmp($op1$$Register, $op2$$Register);
10467   %}
10468   ins_pipe(ialu_cconly_reg_reg);
10469 %}
10470 #else
10471 instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
10472   match(Set xcc (CmpL op1 op2));
10473   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
10474 
10475   size(8);
10476   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! long\n\t"
10477             "SBCS    $tmp,$op1.hi,$op2.hi" %}
10478   ins_encode %{
10479     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
10480     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
10481   %}
10482   ins_pipe(ialu_cconly_reg_reg);
10483 %}
10484 #endif
10485 
10486 #ifdef AARCH64
10487 instruct compL_reg_con(flagsReg xcc, iRegL op1, aimmL con) %{
10488   match(Set xcc (CmpL op1 con));
10489   effect( DEF xcc, USE op1, USE con );
10490 
10491   size(8);
10492   format %{ "CMP     $op1,$con\t\t! long"  %}
10493   ins_encode %{
10494     __ cmp($op1$$Register, $con$$constant);
10495   %}
10496 
10497   ins_pipe(ialu_cconly_reg_imm);
10498 %}
10499 #else
10500 instruct compL_reg_reg_EQNE(flagsRegL_EQNE xcc, iRegL op1, iRegL op2) %{
10501   match(Set xcc (CmpL op1 op2));
10502   effect( DEF xcc, USE op1, USE op2 );
10503 
10504   size(8);
10505   format %{ "TEQ    $op1.hi,$op2.hi\t\t! long\n\t"
10506             "TEQ.eq $op1.lo,$op2.lo" %}
10507   ins_encode %{
10508     __ teq($op1$$Register->successor(), $op2$$Register->successor());
10509     __ teq($op1$$Register, $op2$$Register, eq);
10510   %}
10511   ins_pipe(ialu_cconly_reg_reg);
10512 %}
10513 
10514 instruct compL_reg_reg_LEGT(flagsRegL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
10515   match(Set xcc (CmpL op1 op2));
10516   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
10517 
10518   size(8);
10519   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! long\n\t"
10520             "SBCS    $tmp,$op2.hi,$op1.hi" %}
10521   ins_encode %{
10522     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
10523     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
10524   %}
10525   ins_pipe(ialu_cconly_reg_reg);
10526 %}
10527 
10528 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
10529 // (hi($con$$constant), lo($con$$constant)) becomes
10530 instruct compL_reg_con_LTGE(flagsRegL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
10531   match(Set xcc (CmpL op1 con));
10532   effect( DEF xcc, USE op1, USE con, TEMP tmp );
10533 
10534   size(8);
10535   format %{ "SUBS    $tmp,$op1.low,$con\t\t! long\n\t"
10536             "SBCS    $tmp,$op1.hi,0" %}
10537   ins_encode %{
10538     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
10539     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
10540   %}
10541 
10542   ins_pipe(ialu_cconly_reg_reg);
10543 %}
10544 
10545 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
10546 // (hi($con$$constant), lo($con$$constant)) becomes
10547 instruct compL_reg_con_EQNE(flagsRegL_EQNE xcc, iRegL op1, immLlowRot con) %{
10548   match(Set xcc (CmpL op1 con));
10549   effect( DEF xcc, USE op1, USE con );
10550 
10551   size(8);
10552   format %{ "TEQ    $op1.hi,0\t\t! long\n\t"
10553             "TEQ.eq $op1.lo,$con" %}
10554   ins_encode %{
10555     __ teq($op1$$Register->successor(), 0);
10556     __ teq($op1$$Register, $con$$constant, eq);
10557   %}
10558 
10559   ins_pipe(ialu_cconly_reg_reg);
10560 %}
10561 
10562 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
10563 // (hi($con$$constant), lo($con$$constant)) becomes
10564 instruct compL_reg_con_LEGT(flagsRegL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
10565   match(Set xcc (CmpL op1 con));
10566   effect( DEF xcc, USE op1, USE con, TEMP tmp );
10567 
10568   size(8);
10569   format %{ "RSBS    $tmp,$op1.low,$con\t\t! long\n\t"
10570             "RSCS    $tmp,$op1.hi,0" %}
10571   ins_encode %{
10572     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
10573     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
10574   %}
10575 
10576   ins_pipe(ialu_cconly_reg_reg);
10577 %}
10578 #endif
10579 
10580 /* instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ */
10581 /*   match(Set xcc (CmpL (AndL op1 op2) zero)); */
10582 /*   ins_encode %{ */
10583 /*     __ stop("testL_reg_reg unimplemented"); */
10584 /*   %} */
10585 /*   ins_pipe(ialu_cconly_reg_reg); */
10586 /* %} */
10587 
10588 /* // useful for checking the alignment of a pointer: */
10589 /* instruct testL_reg_con(flagsRegL xcc, iRegL op1, immLlowRot con, immL0 zero) %{ */
10590 /*   match(Set xcc (CmpL (AndL op1 con) zero)); */
10591 /*   ins_encode %{ */
10592 /*     __ stop("testL_reg_con unimplemented"); */
10593 /*   %} */
10594 /*   ins_pipe(ialu_cconly_reg_reg); */
10595 /* %} */
10596 
10597 instruct compU_iReg_imm(flagsRegU icc, iRegI op1, aimmU31 op2 ) %{
10598   match(Set icc (CmpU op1 op2));
10599 
10600   size(4);
10601   format %{ "cmp_32 $op1,$op2\t! unsigned" %}
10602   ins_encode %{
10603     __ cmp_32($op1$$Register, $op2$$constant);
10604   %}
10605   ins_pipe(ialu_cconly_reg_imm);
10606 %}
10607 
10608 // Compare Pointers
10609 instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{
10610   match(Set pcc (CmpP op1 op2));
10611 
10612   size(4);
10613   format %{ "CMP    $op1,$op2\t! ptr" %}
10614   ins_encode %{
10615     __ cmp($op1$$Register, $op2$$Register);
10616   %}
10617   ins_pipe(ialu_cconly_reg_reg);
10618 %}
10619 
10620 instruct compP_iRegP_imm(flagsRegP pcc, iRegP op1, aimmP op2 ) %{
10621   match(Set pcc (CmpP op1 op2));
10622 
10623   size(4);
10624   format %{ "CMP    $op1,$op2\t! ptr" %}
10625   ins_encode %{
10626     assert($op2$$constant == 0 || _opnds[2]->constant_reloc() == relocInfo::none, "reloc in cmp?");
10627     __ cmp($op1$$Register, $op2$$constant);
10628   %}
10629   ins_pipe(ialu_cconly_reg_imm);
10630 %}
10631 
10632 //----------Max and Min--------------------------------------------------------
10633 // Min Instructions
10634 // Conditional move for min
10635 instruct cmovI_reg_lt( iRegI op2, iRegI op1, flagsReg icc ) %{
10636   effect( USE_DEF op2, USE op1, USE icc );
10637 
10638   size(4);
10639   format %{ "MOV.lt  $op2,$op1\t! min" %}
10640   ins_encode %{
10641     __ mov($op2$$Register, $op1$$Register, lt);
10642   %}
10643   ins_pipe(ialu_reg_flags);
10644 %}
10645 
10646 // Min Register with Register.
10647 instruct minI_eReg(iRegI op1, iRegI op2) %{
10648   match(Set op2 (MinI op1 op2));
10649   ins_cost(DEFAULT_COST*2);
10650   expand %{
10651     flagsReg icc;
10652     compI_iReg(icc,op1,op2);
10653     cmovI_reg_lt(op2,op1,icc);
10654   %}
10655 %}
10656 
10657 // Max Instructions
10658 // Conditional move for max
10659 instruct cmovI_reg_gt( iRegI op2, iRegI op1, flagsReg icc ) %{
10660   effect( USE_DEF op2, USE op1, USE icc );
10661   format %{ "MOV.gt  $op2,$op1\t! max" %}
10662   ins_encode %{
10663     __ mov($op2$$Register, $op1$$Register, gt);
10664   %}
10665   ins_pipe(ialu_reg_flags);
10666 %}
10667 
10668 // Max Register with Register
10669 instruct maxI_eReg(iRegI op1, iRegI op2) %{
10670   match(Set op2 (MaxI op1 op2));
10671   ins_cost(DEFAULT_COST*2);
10672   expand %{
10673     flagsReg icc;
10674     compI_iReg(icc,op1,op2);
10675     cmovI_reg_gt(op2,op1,icc);
10676   %}
10677 %}
10678 
10679 
10680 //----------Float Compares----------------------------------------------------
10681 // Compare floating, generate condition code
10682 instruct cmpF_cc(flagsRegF fcc, flagsReg icc, regF src1, regF src2) %{
10683   match(Set icc (CmpF src1 src2));
10684   effect(KILL fcc);
10685 
10686 #ifdef AARCH64
10687   size(4);
10688   format %{ "FCMP_s  $src1,$src2" %}
10689   ins_encode %{
10690     __ fcmp_s($src1$$FloatRegister, $src2$$FloatRegister);
10691   %}
10692 #else
10693   size(8);
10694   format %{ "FCMPs  $src1,$src2\n\t"
10695             "FMSTAT" %}
10696   ins_encode %{
10697     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
10698     __ fmstat();
10699   %}
10700 #endif
10701   ins_pipe(faddF_fcc_reg_reg_zero);
10702 %}
10703 
10704 instruct cmpF0_cc(flagsRegF fcc, flagsReg icc, regF src1, immF0 src2) %{
10705   match(Set icc (CmpF src1 src2));
10706   effect(KILL fcc);
10707 
10708 #ifdef AARCH64
10709   size(4);
10710   format %{ "FCMP0_s $src1" %}
10711   ins_encode %{
10712     __ fcmp0_s($src1$$FloatRegister);
10713   %}
10714 #else
10715   size(8);
10716   format %{ "FCMPs  $src1,$src2\n\t"
10717             "FMSTAT" %}
10718   ins_encode %{
10719     __ fcmpzs($src1$$FloatRegister);
10720     __ fmstat();
10721   %}
10722 #endif
10723   ins_pipe(faddF_fcc_reg_reg_zero);
10724 %}
10725 
10726 instruct cmpD_cc(flagsRegF fcc, flagsReg icc, regD src1, regD src2) %{
10727   match(Set icc (CmpD src1 src2));
10728   effect(KILL fcc);
10729 
10730 #ifdef AARCH64
10731   size(4);
10732   format %{ "FCMP_d $src1,$src2" %}
10733   ins_encode %{
10734     __ fcmp_d($src1$$FloatRegister, $src2$$FloatRegister);
10735   %}
10736 #else
10737   size(8);
10738   format %{ "FCMPd  $src1,$src2 \n\t"
10739             "FMSTAT" %}
10740   ins_encode %{
10741     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
10742     __ fmstat();
10743   %}
10744 #endif
10745   ins_pipe(faddD_fcc_reg_reg_zero);
10746 %}
10747 
10748 instruct cmpD0_cc(flagsRegF fcc, flagsReg icc, regD src1, immD0 src2) %{
10749   match(Set icc (CmpD src1 src2));
10750   effect(KILL fcc);
10751 
10752 #ifdef AARCH64
10753   size(8);
10754   format %{ "FCMP0_d $src1" %}
10755   ins_encode %{
10756     __ fcmp0_d($src1$$FloatRegister);
10757   %}
10758 #else
10759   size(8);
10760   format %{ "FCMPZd  $src1,$src2 \n\t"
10761             "FMSTAT" %}
10762   ins_encode %{
10763     __ fcmpzd($src1$$FloatRegister);
10764     __ fmstat();
10765   %}
10766 #endif
10767   ins_pipe(faddD_fcc_reg_reg_zero);
10768 %}
10769 
10770 #ifdef AARCH64
10771 // Compare floating, generate -1,0,1
10772 instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsReg icc) %{
10773   match(Set dst (CmpF3 src1 src2));
10774   // effect(KILL fcc); // nobody cares if flagsRegF is killed
10775   effect(KILL icc);
10776   ins_cost(DEFAULT_COST*3); // FIXME
10777   size(12);
10778   format %{ "FCMP_s $src1,$src2\n\t"
10779             "CSET   $dst, gt\n\t"
10780             "CSINV  $dst, $dst, ZR, ge" %}
10781   ins_encode %{
10782     Register dst = $dst$$Register;
10783     __ fcmp_s($src1$$FloatRegister, $src2$$FloatRegister);
10784     __ cset(dst, gt);            // 1 if '>', else 0
10785     __ csinv(dst, dst, ZR, ge);  // previous value if '>=', else -1
10786   %}
10787   ins_pipe( floating_cmp ); // FIXME
10788 %}
10789 
10790 // Compare floating, generate -1,0,1
10791 instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsReg icc) %{
10792   match(Set dst (CmpD3 src1 src2));
10793   // effect(KILL fcc); // nobody cares if flagsRegF is killed
10794   effect(KILL icc);
10795   ins_cost(DEFAULT_COST*3); // FIXME
10796   size(12);
10797   format %{ "FCMP_d $src1,$src2\n\t"
10798             "CSET   $dst, gt\n\t"
10799             "CSINV  $dst, $dst, ZR, ge" %}
10800   ins_encode %{
10801     Register dst = $dst$$Register;
10802     __ fcmp_d($src1$$FloatRegister, $src2$$FloatRegister);
10803     __ cset(dst, gt);            // 1 if '>', else 0
10804     __ csinv(dst, dst, ZR, ge);  // previous value if '>=', else -1
10805   %}
10806   ins_pipe( floating_cmp ); // FIXME
10807 %}
10808 
10809 // Compare floating, generate -1,0,1
10810 instruct cmpF0_reg(iRegI dst, regF src1, immF0 src2, flagsReg icc) %{
10811   match(Set dst (CmpF3 src1 src2));
10812   // effect(KILL fcc); // nobody cares if flagsRegF is killed
10813   effect(KILL icc);
10814   ins_cost(DEFAULT_COST*3); // FIXME
10815   size(12);
10816   format %{ "FCMP0_s $src1\n\t"
10817             "CSET   $dst, gt\n\t"
10818             "CSINV  $dst, $dst, ZR, ge" %}
10819   ins_encode %{
10820     Register dst = $dst$$Register;
10821     __ fcmp0_s($src1$$FloatRegister);
10822     __ cset(dst, gt);            // 1 if '>', else 0
10823     __ csinv(dst, dst, ZR, ge);  // previous value if '>=', else -1
10824   %}
10825   ins_pipe( floating_cmp ); // FIXME
10826 %}
10827 
10828 // Compare floating, generate -1,0,1
10829 instruct cmpD0_reg(iRegI dst, regD src1, immD0 src2, flagsReg icc) %{
10830   match(Set dst (CmpD3 src1 src2));
10831   // effect(KILL fcc); // nobody cares if flagsRegF is killed
10832   effect(KILL icc);
10833   ins_cost(DEFAULT_COST*3); // FIXME
10834   size(12);
10835   format %{ "FCMP0_d $src1\n\t"
10836             "CSET   $dst, gt\n\t"
10837             "CSINV  $dst, $dst, ZR, ge" %}
10838   ins_encode %{
10839     Register dst = $dst$$Register;
10840     __ fcmp0_d($src1$$FloatRegister);
10841     __ cset(dst, gt);            // 1 if '>', else 0
10842     __ csinv(dst, dst, ZR, ge);  // previous value if '>=', else -1
10843   %}
10844   ins_pipe( floating_cmp ); // FIXME
10845 %}
10846 #else
10847 // Compare floating, generate -1,0,1
10848 instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsRegF fcc) %{
10849   match(Set dst (CmpF3 src1 src2));
10850   effect(KILL fcc);
10851   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
10852   size(20);
10853   // same number of instructions as code using conditional moves but
10854   // doesn't kill integer condition register
10855   format %{ "FCMPs  $dst,$src1,$src2 \n\t"
10856             "VMRS   $dst, FPSCR \n\t"
10857             "OR     $dst, $dst, 0x08000000 \n\t"
10858             "EOR    $dst, $dst, $dst << 3 \n\t"
10859             "MOV    $dst, $dst >> 30" %}
10860   ins_encode %{
10861     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
10862     __ floating_cmp($dst$$Register);
10863   %}
10864   ins_pipe( floating_cmp );
10865 %}
10866 
10867 instruct cmpF0_reg(iRegI dst, regF src1, immF0 src2, flagsRegF fcc) %{
10868   match(Set dst (CmpF3 src1 src2));
10869   effect(KILL fcc);
10870   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
10871   size(20);
10872   // same number of instructions as code using conditional moves but
10873   // doesn't kill integer condition register
10874   format %{ "FCMPZs $dst,$src1,$src2 \n\t"
10875             "VMRS   $dst, FPSCR \n\t"
10876             "OR     $dst, $dst, 0x08000000 \n\t"
10877             "EOR    $dst, $dst, $dst << 3 \n\t"
10878             "MOV    $dst, $dst >> 30" %}
10879   ins_encode %{
10880     __ fcmpzs($src1$$FloatRegister);
10881     __ floating_cmp($dst$$Register);
10882   %}
10883   ins_pipe( floating_cmp );
10884 %}
10885 
10886 instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsRegF fcc) %{
10887   match(Set dst (CmpD3 src1 src2));
10888   effect(KILL fcc);
10889   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
10890   size(20);
10891   // same number of instructions as code using conditional moves but
10892   // doesn't kill integer condition register
10893   format %{ "FCMPd  $dst,$src1,$src2 \n\t"
10894             "VMRS   $dst, FPSCR \n\t"
10895             "OR     $dst, $dst, 0x08000000 \n\t"
10896             "EOR    $dst, $dst, $dst << 3 \n\t"
10897             "MOV    $dst, $dst >> 30" %}
10898   ins_encode %{
10899     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
10900     __ floating_cmp($dst$$Register);
10901   %}
10902   ins_pipe( floating_cmp );
10903 %}
10904 
10905 instruct cmpD0_reg(iRegI dst, regD src1, immD0 src2, flagsRegF fcc) %{
10906   match(Set dst (CmpD3 src1 src2));
10907   effect(KILL fcc);
10908   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
10909   size(20);
10910   // same number of instructions as code using conditional moves but
10911   // doesn't kill integer condition register
10912   format %{ "FCMPZd $dst,$src1,$src2 \n\t"
10913             "VMRS   $dst, FPSCR \n\t"
10914             "OR     $dst, $dst, 0x08000000 \n\t"
10915             "EOR    $dst, $dst, $dst << 3 \n\t"
10916             "MOV    $dst, $dst >> 30" %}
10917   ins_encode %{
10918     __ fcmpzd($src1$$FloatRegister);
10919     __ floating_cmp($dst$$Register);
10920   %}
10921   ins_pipe( floating_cmp );
10922 %}
10923 #endif // !AARCH64
10924 
10925 //----------Branches---------------------------------------------------------
10926 // Jump
10927 // (compare 'operand indIndex' and 'instruct addP_reg_reg' above)
10928 // FIXME
10929 instruct jumpXtnd(iRegX switch_val, iRegP tmp) %{
10930   match(Jump switch_val);
10931   effect(TEMP tmp);
10932   ins_cost(350);
10933   format %{  "ADD    $tmp, $constanttablebase, $switch_val\n\t"
10934              "LDR    $tmp,[$tmp + $constantoffset]\n\t"
10935              "BX     $tmp" %}
10936   size(20);
10937   ins_encode %{
10938     Register table_reg;
10939     Register label_reg = $tmp$$Register;
10940     if (constant_offset() == 0) {
10941       table_reg = $constanttablebase;
10942       __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
10943     } else {
10944       table_reg = $tmp$$Register;
10945       int offset = $constantoffset;
10946       if (is_memoryP(offset)) {
10947         __ add(table_reg, $constanttablebase, $switch_val$$Register);
10948         __ ldr(label_reg, Address(table_reg, offset));
10949       } else {
10950         __ mov_slow(table_reg, $constantoffset);
10951         __ add(table_reg, $constanttablebase, table_reg);
10952         __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
10953       }
10954     }
10955     __ jump(label_reg); // ldr + b better than ldr to PC for branch predictor?
10956     //    __ ldr(PC, Address($table$$Register, $switch_val$$Register));
10957   %}
10958   ins_pipe(ialu_reg_reg);
10959 %}
10960 
10961 // // Direct Branch.
10962 instruct branch(label labl) %{
10963   match(Goto);
10964   effect(USE labl);
10965 
10966   size(4);
10967   ins_cost(BRANCH_COST);
10968   format %{ "B     $labl" %}
10969   ins_encode %{
10970     __ b(*($labl$$label));
10971   %}
10972   ins_pipe(br);
10973 %}
10974 
10975 // Conditional Direct Branch
10976 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{
10977   match(If cmp icc);
10978   effect(USE labl);
10979 
10980   size(4);
10981   ins_cost(BRANCH_COST);
10982   format %{ "B$cmp   $icc,$labl" %}
10983   ins_encode %{
10984     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
10985   %}
10986   ins_pipe(br_cc);
10987 %}
10988 
10989 #ifdef ARM
10990 instruct branchCon_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, label labl) %{
10991   match(If cmp icc);
10992   effect(USE labl);
10993   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
10994 
10995   size(4);
10996   ins_cost(BRANCH_COST);
10997   format %{ "B$cmp   $icc,$labl" %}
10998   ins_encode %{
10999     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
11000   %}
11001   ins_pipe(br_cc);
11002 %}
11003 #endif
11004 
11005 #ifdef AARCH64
11006 instruct cbzI(cmpOp cmp, iRegI op1, immI0 op2, label labl) %{
11007   match(If cmp (CmpI op1 op2));
11008   effect(USE labl);
11009   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
11010             _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
11011   size(4);
11012   ins_cost(BRANCH_COST);
11013   format %{ "CB{N}Z $op1, $labl\t! int $cmp" %}
11014   ins_encode %{
11015     if ($cmp$$cmpcode == eq) {
11016       __ cbz_w($op1$$Register, *($labl$$label));
11017     } else {
11018       __ cbnz_w($op1$$Register, *($labl$$label));
11019     }
11020   %}
11021   ins_pipe(br_cc); // FIXME
11022 %}
11023 
11024 instruct cbzP(cmpOpP cmp, iRegP op1, immP0 op2, label labl) %{
11025   match(If cmp (CmpP op1 op2));
11026   effect(USE labl);
11027   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
11028             _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
11029   size(4);
11030   ins_cost(BRANCH_COST);
11031   format %{ "CB{N}Z $op1, $labl\t! ptr $cmp" %}
11032   ins_encode %{
11033     if ($cmp$$cmpcode == eq) {
11034       __ cbz($op1$$Register, *($labl$$label));
11035     } else {
11036       __ cbnz($op1$$Register, *($labl$$label));
11037     }
11038   %}
11039   ins_pipe(br_cc); // FIXME
11040 %}
11041 
11042 instruct cbzL(cmpOpL cmp, iRegL op1, immL0 op2, label labl) %{
11043   match(If cmp (CmpL op1 op2));
11044   effect(USE labl);
11045   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
11046             _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
11047   size(4);
11048   ins_cost(BRANCH_COST);
11049   format %{ "CB{N}Z $op1, $labl\t! long $cmp" %}
11050   ins_encode %{
11051     if ($cmp$$cmpcode == eq) {
11052       __ cbz($op1$$Register, *($labl$$label));
11053     } else {
11054       __ cbnz($op1$$Register, *($labl$$label));
11055     }
11056   %}
11057   ins_pipe(br_cc); // FIXME
11058 %}
11059 #endif
11060 
11061 instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{
11062   match(If cmp icc);
11063   effect(USE labl);
11064 
11065   size(4);
11066   ins_cost(BRANCH_COST);
11067   format %{ "B$cmp  $icc,$labl" %}
11068   ins_encode %{
11069     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
11070   %}
11071   ins_pipe(br_cc);
11072 %}
11073 
11074 instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{
11075   match(If cmp pcc);
11076   effect(USE labl);
11077 
11078   size(4);
11079   ins_cost(BRANCH_COST);
11080   format %{ "B$cmp  $pcc,$labl" %}
11081   ins_encode %{
11082     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
11083   %}
11084   ins_pipe(br_cc);
11085 %}
11086 
11087 #ifndef AARCH64
11088 instruct branchConL_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, label labl) %{
11089   match(If cmp xcc);
11090   effect(USE labl);
11091   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
11092 
11093   size(4);
11094   ins_cost(BRANCH_COST);
11095   format %{ "B$cmp  $xcc,$labl" %}
11096   ins_encode %{
11097     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
11098   %}
11099   ins_pipe(br_cc);
11100 %}
11101 
11102 instruct branchConL_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, label labl) %{
11103   match(If cmp xcc);
11104   effect(USE labl);
11105   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
11106 
11107   size(4);
11108   ins_cost(BRANCH_COST);
11109   format %{ "B$cmp  $xcc,$labl" %}
11110   ins_encode %{
11111     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
11112   %}
11113   ins_pipe(br_cc);
11114 %}
11115 
11116 instruct branchConL_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, label labl) %{
11117   match(If cmp xcc);
11118   effect(USE labl);
11119   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le );
11120 
11121   size(4);
11122   ins_cost(BRANCH_COST);
11123   format %{ "B$cmp  $xcc,$labl" %}
11124   ins_encode %{
11125     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
11126   %}
11127   ins_pipe(br_cc);
11128 %}
11129 #endif
11130 
11131 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
11132   match(CountedLoopEnd cmp icc);
11133   effect(USE labl);
11134 
11135   size(4);
11136   ins_cost(BRANCH_COST);
11137   format %{ "B$cmp   $icc,$labl\t! Loop end" %}
11138   ins_encode %{
11139     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
11140   %}
11141   ins_pipe(br_cc);
11142 %}
11143 
11144 // instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{
11145 //   match(CountedLoopEnd cmp icc);
11146 //   ins_pipe(br_cc);
11147 // %}
11148 
11149 // ============================================================================
11150 // Long Compare
11151 //
11152 // Currently we hold longs in 2 registers.  Comparing such values efficiently
11153 // is tricky.  The flavor of compare used depends on whether we are testing
11154 // for LT, LE, or EQ.  For a simple LT test we can check just the sign bit.
11155 // The GE test is the negated LT test.  The LE test can be had by commuting
11156 // the operands (yielding a GE test) and then negating; negate again for the
11157 // GT test.  The EQ test is done by ORcc'ing the high and low halves, and the
11158 // NE test is negated from that.
11159 
11160 // Due to a shortcoming in the ADLC, it mixes up expressions like:
11161 // (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)).  Note the
11162 // difference between 'Y' and '0L'.  The tree-matches for the CmpI sections
11163 // are collapsed internally in the ADLC's dfa-gen code.  The match for
11164 // (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the
11165 // foo match ends up with the wrong leaf.  One fix is to not match both
11166 // reg-reg and reg-zero forms of long-compare.  This is unfortunate because
11167 // both forms beat the trinary form of long-compare and both are very useful
11168 // on Intel which has so few registers.
11169 
11170 // instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{
11171 //   match(If cmp xcc);
11172 //   ins_pipe(br_cc);
11173 // %}
11174 
11175 // Manifest a CmpL3 result in an integer register.  Very painful.
11176 // This is the test to avoid.
11177 #ifdef AARCH64
11178 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr) %{
11179   match(Set dst (CmpL3 src1 src2));
11180   // effect(KILL fcc); // nobody cares if flagsRegF is killed
11181   effect(KILL ccr);
11182   ins_cost(DEFAULT_COST*3); // FIXME
11183   size(12);
11184   format %{ "CMP    $src1,$src2\n\t"
11185             "CSET   $dst, gt\n\t"
11186             "CSINV  $dst, $dst, ZR, ge" %}
11187   ins_encode %{
11188     Register dst = $dst$$Register;
11189     __ cmp($src1$$Register, $src2$$Register);
11190     __ cset(dst, gt);            // 1 if '>', else 0
11191     __ csinv(dst, dst, ZR, ge);  // previous value if '>=', else -1
11192   %}
11193   ins_pipe( ialu_cconly_reg_reg ); // FIXME
11194 %}
11195 // TODO cmpL3_reg_imm
11196 #else
11197 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
11198   match(Set dst (CmpL3 src1 src2) );
11199   effect( KILL ccr );
11200   ins_cost(6*DEFAULT_COST); // FIXME
11201   size(32);
11202   format %{
11203       "CMP    $src1.hi, $src2.hi\t\t! long\n"
11204     "\tMOV.gt $dst, 1\n"
11205     "\tmvn.lt $dst, 0\n"
11206     "\tB.ne   done\n"
11207     "\tSUBS   $dst, $src1.lo, $src2.lo\n"
11208     "\tMOV.hi $dst, 1\n"
11209     "\tmvn.lo $dst, 0\n"
11210     "done:"     %}
11211   ins_encode %{
11212     Label done;
11213     __ cmp($src1$$Register->successor(), $src2$$Register->successor());
11214     __ mov($dst$$Register, 1, gt);
11215     __ mvn($dst$$Register, 0, lt);
11216     __ b(done, ne);
11217     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
11218     __ mov($dst$$Register, 1, hi);
11219     __ mvn($dst$$Register, 0, lo);
11220     __ bind(done);
11221   %}
11222   ins_pipe(cmpL_reg);
11223 %}
11224 #endif
11225 
11226 #ifndef AARCH64
11227 // Conditional move
11228 instruct cmovLL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, iRegL src) %{
11229   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
11230   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
11231 
11232   ins_cost(150);
11233   size(8);
11234   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
11235             "MOV$cmp  $dst,$src.hi" %}
11236   ins_encode %{
11237     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
11238     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
11239   %}
11240   ins_pipe(ialu_reg);
11241 %}
11242 
11243 instruct cmovLL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, iRegL src) %{
11244   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
11245   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
11246 
11247   ins_cost(150);
11248   size(8);
11249   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
11250             "MOV$cmp  $dst,$src.hi" %}
11251   ins_encode %{
11252     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
11253     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
11254   %}
11255   ins_pipe(ialu_reg);
11256 %}
11257 
11258 instruct cmovLL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, iRegL src) %{
11259   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
11260   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
11261 
11262   ins_cost(150);
11263   size(8);
11264   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
11265             "MOV$cmp  $dst,$src.hi" %}
11266   ins_encode %{
11267     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
11268     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
11269   %}
11270   ins_pipe(ialu_reg);
11271 %}
11272 
11273 instruct cmovLL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, immL0 src) %{
11274   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
11275   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
11276   ins_cost(140);
11277   size(8);
11278   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
11279             "MOV$cmp  $dst,0" %}
11280   ins_encode %{
11281     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
11282     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
11283   %}
11284   ins_pipe(ialu_imm);
11285 %}
11286 
11287 instruct cmovLL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, immL0 src) %{
11288   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
11289   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
11290   ins_cost(140);
11291   size(8);
11292   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
11293             "MOV$cmp  $dst,0" %}
11294   ins_encode %{
11295     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
11296     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
11297   %}
11298   ins_pipe(ialu_imm);
11299 %}
11300 
11301 instruct cmovLL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, immL0 src) %{
11302   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
11303   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
11304   ins_cost(140);
11305   size(8);
11306   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
11307             "MOV$cmp  $dst,0" %}
11308   ins_encode %{
11309     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
11310     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
11311   %}
11312   ins_pipe(ialu_imm);
11313 %}
11314 #endif // !AARCH64
11315 
11316 #ifndef AARCH64
11317 instruct cmovIL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, iRegI src) %{
11318   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
11319   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
11320 
11321   ins_cost(150);
11322   size(4);
11323   format %{ "MOV$cmp  $dst,$src" %}
11324   ins_encode %{
11325     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
11326   %}
11327   ins_pipe(ialu_reg);
11328 %}
11329 
11330 instruct cmovIL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, iRegI src) %{
11331   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
11332   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
11333 
11334   ins_cost(150);
11335   size(4);
11336   format %{ "MOV$cmp  $dst,$src" %}
11337   ins_encode %{
11338     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
11339   %}
11340   ins_pipe(ialu_reg);
11341 %}
11342 
11343 instruct cmovIL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, iRegI src) %{
11344   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
11345   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
11346 
11347   ins_cost(150);
11348   size(4);
11349   format %{ "MOV$cmp  $dst,$src" %}
11350   ins_encode %{
11351     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
11352   %}
11353   ins_pipe(ialu_reg);
11354 %}
11355 #endif // !AARCH64
11356 
11357 #ifndef AARCH64
11358 instruct cmovIL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immI16 src) %{
11359   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
11360   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
11361 
11362   ins_cost(140);
11363   format %{ "MOVW$cmp  $dst,$src" %}
11364   ins_encode %{
11365     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
11366   %}
11367   ins_pipe(ialu_imm);
11368 %}
11369 
11370 instruct cmovIL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, immI16 src) %{
11371   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
11372   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
11373 
11374   ins_cost(140);
11375   format %{ "MOVW$cmp  $dst,$src" %}
11376   ins_encode %{
11377     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
11378   %}
11379   ins_pipe(ialu_imm);
11380 %}
11381 
11382 instruct cmovIL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immI16 src) %{
11383   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
11384   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
11385 
11386   ins_cost(140);
11387   format %{ "MOVW$cmp  $dst,$src" %}
11388   ins_encode %{
11389     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
11390   %}
11391   ins_pipe(ialu_imm);
11392 %}
11393 
11394 instruct cmovPL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, iRegP src) %{
11395   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
11396   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
11397 
11398   ins_cost(150);
11399   size(4);
11400   format %{ "MOV$cmp  $dst,$src" %}
11401   ins_encode %{
11402     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
11403   %}
11404   ins_pipe(ialu_reg);
11405 %}
11406 
11407 instruct cmovPL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, iRegP src) %{
11408   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
11409   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
11410 
11411   ins_cost(150);
11412   size(4);
11413   format %{ "MOV$cmp  $dst,$src" %}
11414   ins_encode %{
11415     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
11416   %}
11417   ins_pipe(ialu_reg);
11418 %}
11419 
11420 instruct cmovPL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, iRegP src) %{
11421   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
11422   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
11423 
11424   ins_cost(150);
11425   size(4);
11426   format %{ "MOV$cmp  $dst,$src" %}
11427   ins_encode %{
11428     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
11429   %}
11430   ins_pipe(ialu_reg);
11431 %}
11432 
11433 instruct cmovPL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, immP0 src) %{
11434   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
11435   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
11436 
11437   ins_cost(140);
11438   format %{ "MOVW$cmp  $dst,$src" %}
11439   ins_encode %{
11440     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
11441   %}
11442   ins_pipe(ialu_imm);
11443 %}
11444 
11445 instruct cmovPL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, immP0 src) %{
11446   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
11447   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
11448 
11449   ins_cost(140);
11450   format %{ "MOVW$cmp  $dst,$src" %}
11451   ins_encode %{
11452     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
11453   %}
11454   ins_pipe(ialu_imm);
11455 %}
11456 
11457 instruct cmovPL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, immP0 src) %{
11458   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
11459   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
11460 
11461   ins_cost(140);
11462   format %{ "MOVW$cmp  $dst,$src" %}
11463   ins_encode %{
11464     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
11465   %}
11466   ins_pipe(ialu_imm);
11467 %}
11468 
11469 instruct cmovFL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regF dst, regF src) %{
11470   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
11471   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
11472   ins_cost(150);
11473   size(4);
11474   format %{ "FCPYS$cmp $dst,$src" %}
11475   ins_encode %{
11476     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
11477   %}
11478   ins_pipe(int_conditional_float_move);
11479 %}
11480 
11481 instruct cmovFL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regF dst, regF src) %{
11482   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
11483   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
11484   ins_cost(150);
11485   size(4);
11486   format %{ "FCPYS$cmp $dst,$src" %}
11487   ins_encode %{
11488     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
11489   %}
11490   ins_pipe(int_conditional_float_move);
11491 %}
11492 
11493 instruct cmovFL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regF dst, regF src) %{
11494   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
11495   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
11496   ins_cost(150);
11497   size(4);
11498   format %{ "FCPYS$cmp $dst,$src" %}
11499   ins_encode %{
11500     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
11501   %}
11502   ins_pipe(int_conditional_float_move);
11503 %}
11504 
11505 instruct cmovDL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regD dst, regD src) %{
11506   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
11507   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
11508 
11509   ins_cost(150);
11510   size(4);
11511   format %{ "FCPYD$cmp $dst,$src" %}
11512   ins_encode %{
11513     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
11514   %}
11515   ins_pipe(int_conditional_float_move);
11516 %}
11517 
11518 instruct cmovDL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regD dst, regD src) %{
11519   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
11520   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
11521 
11522   ins_cost(150);
11523   size(4);
11524   format %{ "FCPYD$cmp $dst,$src" %}
11525   ins_encode %{
11526     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
11527   %}
11528   ins_pipe(int_conditional_float_move);
11529 %}
11530 
11531 instruct cmovDL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regD dst, regD src) %{
11532   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
11533   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
11534 
11535   ins_cost(150);
11536   size(4);
11537   format %{ "FCPYD$cmp $dst,$src" %}
11538   ins_encode %{
11539     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
11540   %}
11541   ins_pipe(int_conditional_float_move);
11542 %}
11543 #endif // !AARCH64
11544 
11545 // ============================================================================
11546 // Safepoint Instruction
11547 #ifdef AARCH64
11548 instruct safePoint_poll(iRegP poll, flagsReg icc, RtempRegP tmp) %{
11549   match(SafePoint poll);
11550   // The handler stub kills Rtemp
11551   effect(USE poll, KILL tmp, KILL icc);
11552 
11553   size(4);
11554   format %{ "LDR   ZR,[$poll]\t! Safepoint: poll for GC" %}
11555   ins_encode %{
11556     __ relocate(relocInfo::poll_type);
11557     __ ldr(ZR, Address($poll$$Register));
11558   %}
11559   ins_pipe(loadPollP);
11560 %}
11561 #else
11562 // rather than KILL R12, it would be better to use any reg as
11563 // TEMP. Can't do that at this point because it crashes the compiler
11564 instruct safePoint_poll(iRegP poll, R12RegI tmp, flagsReg icc) %{
11565   match(SafePoint poll);
11566   effect(USE poll, KILL tmp, KILL icc);
11567 
11568   size(4);
11569   format %{ "LDR   $tmp,[$poll]\t! Safepoint: poll for GC" %}
11570   ins_encode %{
11571     __ relocate(relocInfo::poll_type);
11572     __ ldr($tmp$$Register, Address($poll$$Register));
11573   %}
11574   ins_pipe(loadPollP);
11575 %}
11576 #endif
11577 
11578 
11579 // ============================================================================
11580 // Call Instructions
11581 // Call Java Static Instruction
11582 instruct CallStaticJavaDirect( method meth ) %{
11583   match(CallStaticJava);
11584   predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke());
11585   effect(USE meth);
11586 
11587   ins_cost(CALL_COST);
11588   format %{ "CALL,static ==> " %}
11589   ins_encode( Java_Static_Call( meth ), call_epilog );
11590   ins_pipe(simple_call);
11591 %}
11592 
11593 // Call Java Static Instruction (method handle version)
11594 instruct CallStaticJavaHandle( method meth ) %{
11595   match(CallStaticJava);
11596   predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke());
11597   effect(USE meth);
11598   // FP is saved by all callees (for interpreter stack correction).
11599   // We use it here for a similar purpose, in {preserve,restore}_FP.
11600 
11601   ins_cost(CALL_COST);
11602   format %{ "CALL,static/MethodHandle ==> " %}
11603   ins_encode( preserve_SP, Java_Static_Call( meth ), restore_SP, call_epilog );
11604   ins_pipe(simple_call);
11605 %}
11606 
11607 // Call Java Dynamic Instruction
11608 instruct CallDynamicJavaDirect( method meth ) %{
11609   match(CallDynamicJava);
11610   effect(USE meth);
11611 
11612   ins_cost(CALL_COST);
11613   format %{ "MOV_OOP    (empty),R_R8\n\t"
11614             "CALL,dynamic  ; NOP ==> " %}
11615   ins_encode( Java_Dynamic_Call( meth ), call_epilog );
11616   ins_pipe(call);
11617 %}
11618 
11619 // Call Runtime Instruction
11620 instruct CallRuntimeDirect(method meth) %{
11621   match(CallRuntime);
11622   effect(USE meth);
11623   ins_cost(CALL_COST);
11624   format %{ "CALL,runtime" %}
11625 #ifdef AARCH64
11626   ins_encode( save_last_PC, Java_To_Runtime( meth ),
11627               call_epilog );
11628 #else
11629   ins_encode( Java_To_Runtime( meth ),
11630               call_epilog );
11631 #endif
11632   ins_pipe(simple_call);
11633 %}
11634 
11635 // Call runtime without safepoint - same as CallRuntime
11636 instruct CallLeafDirect(method meth) %{
11637   match(CallLeaf);
11638   effect(USE meth);
11639   ins_cost(CALL_COST);
11640   format %{ "CALL,runtime leaf" %}
11641   // TODO: ned save_last_PC here?
11642   ins_encode( Java_To_Runtime( meth ),
11643               call_epilog );
11644   ins_pipe(simple_call);
11645 %}
11646 
11647 // Call runtime without safepoint - same as CallLeaf
11648 instruct CallLeafNoFPDirect(method meth) %{
11649   match(CallLeafNoFP);
11650   effect(USE meth);
11651   ins_cost(CALL_COST);
11652   format %{ "CALL,runtime leaf nofp" %}
11653   // TODO: ned save_last_PC here?
11654   ins_encode( Java_To_Runtime( meth ),
11655               call_epilog );
11656   ins_pipe(simple_call);
11657 %}
11658 
11659 // Tail Call; Jump from runtime stub to Java code.
11660 // Also known as an 'interprocedural jump'.
11661 // Target of jump will eventually return to caller.
11662 // TailJump below removes the return address.
11663 instruct TailCalljmpInd(IPRegP jump_target, inline_cache_regP method_oop) %{
11664   match(TailCall jump_target method_oop );
11665 
11666   ins_cost(CALL_COST);
11667   format %{ "MOV    Rexception_pc, LR\n\t"
11668             "jump   $jump_target  \t! $method_oop holds method oop" %}
11669   ins_encode %{
11670     __ mov(Rexception_pc, LR);   // this is used only to call
11671                                  // StubRoutines::forward_exception_entry()
11672                                  // which expects PC of exception in
11673                                  // R5. FIXME?
11674     __ jump($jump_target$$Register);
11675   %}
11676   ins_pipe(tail_call);
11677 %}
11678 
11679 
11680 // Return Instruction
11681 instruct Ret() %{
11682   match(Return);
11683 
11684   format %{ "ret LR" %}
11685 
11686   ins_encode %{
11687     __ ret(LR);
11688   %}
11689 
11690   ins_pipe(br);
11691 %}
11692 
11693 
11694 // Tail Jump; remove the return address; jump to target.
11695 // TailCall above leaves the return address around.
11696 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
11697 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
11698 // "restore" before this instruction (in Epilogue), we need to materialize it
11699 // in %i0.
11700 instruct tailjmpInd(IPRegP jump_target, RExceptionRegP ex_oop) %{
11701   match( TailJump jump_target ex_oop );
11702   ins_cost(CALL_COST);
11703   format %{ "MOV    Rexception_pc, LR\n\t"
11704             "jump   $jump_target \t! $ex_oop holds exc. oop" %}
11705   ins_encode %{
11706     __ mov(Rexception_pc, LR);
11707     __ jump($jump_target$$Register);
11708   %}
11709   ins_pipe(tail_call);
11710 %}
11711 
11712 // Create exception oop: created by stack-crawling runtime code.
11713 // Created exception is now available to this handler, and is setup
11714 // just prior to jumping to this handler.  No code emitted.
11715 instruct CreateException( RExceptionRegP ex_oop )
11716 %{
11717   match(Set ex_oop (CreateEx));
11718   ins_cost(0);
11719 
11720   size(0);
11721   // use the following format syntax
11722   format %{ "! exception oop is in Rexception_obj; no code emitted" %}
11723   ins_encode();
11724   ins_pipe(empty);
11725 %}
11726 
11727 
11728 // Rethrow exception:
11729 // The exception oop will come in the first argument position.
11730 // Then JUMP (not call) to the rethrow stub code.
11731 instruct RethrowException()
11732 %{
11733   match(Rethrow);
11734   ins_cost(CALL_COST);
11735 
11736   // use the following format syntax
11737   format %{ "b    rethrow_stub" %}
11738   ins_encode %{
11739     Register scratch = R1_tmp;
11740     assert_different_registers(scratch, c_rarg0, LR);
11741     __ jump(OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type, scratch);
11742   %}
11743   ins_pipe(tail_call);
11744 %}
11745 
11746 
11747 // Die now
11748 instruct ShouldNotReachHere( )
11749 %{
11750   match(Halt);
11751   ins_cost(CALL_COST);
11752 
11753   size(4);
11754   // Use the following format syntax
11755   format %{ "breakpoint   ; ShouldNotReachHere" %}
11756   ins_encode %{
11757     __ breakpoint();
11758   %}
11759   ins_pipe(tail_call);
11760 %}
11761 
11762 // ============================================================================
11763 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
11764 // array for an instance of the superklass.  Set a hidden internal cache on a
11765 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
11766 // not zero for a miss or zero for a hit.  The encoding ALSO sets flags.
11767 instruct partialSubtypeCheck( R0RegP index, R1RegP sub, R2RegP super, flagsRegP pcc, LRRegP lr ) %{
11768   match(Set index (PartialSubtypeCheck sub super));
11769   effect( KILL pcc, KILL lr );
11770   ins_cost(DEFAULT_COST*10);
11771   format %{ "CALL   PartialSubtypeCheck" %}
11772   ins_encode %{
11773     __ call(StubRoutines::Arm::partial_subtype_check(), relocInfo::runtime_call_type);
11774   %}
11775   ins_pipe(partial_subtype_check_pipe);
11776 %}
11777 
11778 /* instruct partialSubtypeCheck_vs_zero( flagsRegP pcc, o1RegP sub, o2RegP super, immP0 zero, o0RegP idx, o7RegP o7 ) %{ */
11779 /*   match(Set pcc (CmpP (PartialSubtypeCheck sub super) zero)); */
11780 /*   ins_pipe(partial_subtype_check_pipe); */
11781 /* %} */
11782 
11783 
11784 // ============================================================================
11785 // inlined locking and unlocking
11786 
11787 #ifdef AARCH64
11788 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch, iRegP scratch3 )
11789 #else
11790 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch )
11791 #endif
11792 %{
11793   match(Set pcc (FastLock object box));
11794 
11795 #ifdef AARCH64
11796   effect(TEMP scratch, TEMP scratch2, TEMP scratch3);
11797 #else
11798   effect(TEMP scratch, TEMP scratch2);
11799 #endif
11800   ins_cost(100);
11801 
11802 #ifdef AARCH64
11803   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2, $scratch3" %}
11804   ins_encode %{
11805     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register, $scratch3$$Register);
11806   %}
11807 #else
11808   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2" %}
11809   ins_encode %{
11810     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
11811   %}
11812 #endif
11813   ins_pipe(long_memory_op);
11814 %}
11815 
11816 
11817 #ifdef AARCH64
11818 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch, iRegP scratch3 ) %{
11819   match(Set pcc (FastUnlock object box));
11820   effect(TEMP scratch, TEMP scratch2, TEMP scratch3);
11821   ins_cost(100);
11822 
11823   format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2, $scratch3" %}
11824   ins_encode %{
11825     __ fast_unlock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register, $scratch3$$Register);
11826   %}
11827   ins_pipe(long_memory_op);
11828 %}
11829 #else
11830 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch ) %{
11831   match(Set pcc (FastUnlock object box));
11832   effect(TEMP scratch, TEMP scratch2);
11833   ins_cost(100);
11834 
11835   format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2" %}
11836   ins_encode %{
11837     __ fast_unlock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
11838   %}
11839   ins_pipe(long_memory_op);
11840 %}
11841 #endif
11842 
11843 #ifdef AARCH64
11844 // TODO: add version that takes immI cnt?
11845 instruct clear_array(iRegX cnt, iRegP base, iRegP ptr, iRegX temp, Universe dummy, flagsReg cpsr) %{
11846   match(Set dummy (ClearArray cnt base));
11847   effect(TEMP temp, TEMP ptr, KILL cpsr);
11848   ins_cost(300);
11849   format %{
11850       "        MOV    $temp,$cnt\n"
11851       "        ADD    $ptr,$base,$cnt\n"
11852       "        SUBS   $temp,$temp,16\t! Count down dword pair in bytes\n"
11853       "        B.lt   done16\n"
11854       "loop:   STP    ZR,ZR,[$ptr,-16]!\n"
11855       "        SUBS   $temp,$temp,16\t! Count down dword pair in bytes\n"
11856       "        B.ge   loop\t! Clearing loop\n"
11857       "done16: ADDS   $temp,$temp,8\t! Room for 1 more long?\n"
11858       "        B.lt   done\n"
11859       "        STR    ZR,[$base+$temp]\n"
11860       "done:"
11861   %}
11862   ins_encode %{
11863     // TODO: preload?
11864     __ mov($temp$$Register, $cnt$$Register);
11865     __ add($ptr$$Register, $base$$Register, $cnt$$Register);
11866     Label loop, done, done16;
11867     __ subs($temp$$Register, $temp$$Register, 16);
11868     __ b(done16, lt);
11869     __ bind(loop);
11870     __ stp(ZR, ZR, Address($ptr$$Register, -16, pre_indexed));
11871     __ subs($temp$$Register, $temp$$Register, 16);
11872     __ b(loop, ge);
11873     __ bind(done16);
11874     __ adds($temp$$Register, $temp$$Register, 8);
11875     __ b(done, lt);
11876     // $temp should be 0 here
11877     __ str(ZR, Address($base$$Register, $temp$$Register));
11878     __ bind(done);
11879   %}
11880   ins_pipe(long_memory_op);
11881 %}
11882 #else
11883 // Count and Base registers are fixed because the allocator cannot
11884 // kill unknown registers.  The encodings are generic.
11885 instruct clear_array(iRegX cnt, iRegP base, iRegI temp, iRegX zero, Universe dummy, flagsReg cpsr) %{
11886   match(Set dummy (ClearArray cnt base));
11887   effect(TEMP temp, TEMP zero, KILL cpsr);
11888   ins_cost(300);
11889   format %{ "MOV    $zero,0\n"
11890       "        MOV    $temp,$cnt\n"
11891       "loop:   SUBS   $temp,$temp,4\t! Count down a dword of bytes\n"
11892       "        STR.ge $zero,[$base+$temp]\t! delay slot"
11893       "        B.gt   loop\t\t! Clearing loop\n" %}
11894   ins_encode %{
11895     __ mov($zero$$Register, 0);
11896     __ mov($temp$$Register, $cnt$$Register);
11897     Label(loop);
11898     __ bind(loop);
11899     __ subs($temp$$Register, $temp$$Register, 4);
11900     __ str($zero$$Register, Address($base$$Register, $temp$$Register), ge);
11901     __ b(loop, gt);
11902   %}
11903   ins_pipe(long_memory_op);
11904 %}
11905 #endif
11906 
11907 #ifdef XXX
11908 // FIXME: Why R0/R1/R2/R3?
11909 instruct string_compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result,
11910                         iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
11911   predicate(!CompactStrings);
11912   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11913   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, TEMP tmp1, TEMP tmp2);
11914   ins_cost(300);
11915   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // TEMP $tmp1, $tmp2" %}
11916   ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result, tmp1, tmp2) );
11917 
11918   ins_pipe(long_memory_op);
11919 %}
11920 
11921 // FIXME: Why R0/R1/R2?
11922 instruct string_equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2,
11923                        flagsReg ccr) %{
11924   predicate(!CompactStrings);
11925   match(Set result (StrEquals (Binary str1 str2) cnt));
11926   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp1, TEMP tmp2, TEMP result, KILL ccr);
11927 
11928   ins_cost(300);
11929   format %{ "String Equals $str1,$str2,$cnt -> $result   // TEMP $tmp1, $tmp2" %}
11930   ins_encode( enc_String_Equals(str1, str2, cnt, result, tmp1, tmp2) );
11931   ins_pipe(long_memory_op);
11932 %}
11933 
11934 // FIXME: Why R0/R1?
11935 instruct array_equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result,
11936                       flagsReg ccr) %{
11937   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
11938   match(Set result (AryEq ary1 ary2));
11939   effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP result, KILL ccr);
11940 
11941   ins_cost(300);
11942   format %{ "Array Equals $ary1,$ary2 -> $result   // TEMP $tmp1,$tmp2,$tmp3" %}
11943   ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, result));
11944   ins_pipe(long_memory_op);
11945 %}
11946 #endif
11947 
11948 //---------- Zeros Count Instructions ------------------------------------------
11949 
11950 instruct countLeadingZerosI(iRegI dst, iRegI src) %{
11951   match(Set dst (CountLeadingZerosI src));
11952   size(4);
11953   format %{ "CLZ_32 $dst,$src" %}
11954   ins_encode %{
11955     __ clz_32($dst$$Register, $src$$Register);
11956   %}
11957   ins_pipe(ialu_reg);
11958 %}
11959 
11960 #ifdef AARCH64
11961 instruct countLeadingZerosL(iRegI dst, iRegL src) %{
11962   match(Set dst (CountLeadingZerosL src));
11963   size(4);
11964   format %{ "CLZ $dst,$src" %}
11965   ins_encode %{
11966     __ clz($dst$$Register, $src$$Register);
11967   %}
11968   ins_pipe(ialu_reg);
11969 %}
11970 #else
11971 instruct countLeadingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
11972   match(Set dst (CountLeadingZerosL src));
11973   effect(TEMP tmp, TEMP dst, KILL ccr);
11974   size(16);
11975   format %{ "CLZ    $dst,$src.hi\n\t"
11976             "TEQ    $dst,32\n\t"
11977             "CLZ.eq $tmp,$src.lo\n\t"
11978             "ADD.eq $dst, $dst, $tmp\n\t" %}
11979   ins_encode %{
11980     __ clz($dst$$Register, $src$$Register->successor());
11981     __ teq($dst$$Register, 32);
11982     __ clz($tmp$$Register, $src$$Register, eq);
11983     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
11984   %}
11985   ins_pipe(ialu_reg);
11986 %}
11987 #endif
11988 
11989 instruct countTrailingZerosI(iRegI dst, iRegI src, iRegI tmp) %{
11990   match(Set dst (CountTrailingZerosI src));
11991   effect(TEMP tmp);
11992   size(8);
11993   format %{ "RBIT_32 $tmp, $src\n\t"
11994             "CLZ_32  $dst,$tmp" %}
11995   ins_encode %{
11996     __ rbit_32($tmp$$Register, $src$$Register);
11997     __ clz_32($dst$$Register, $tmp$$Register);
11998   %}
11999   ins_pipe(ialu_reg);
12000 %}
12001 
12002 #ifdef AARCH64
12003 instruct countTrailingZerosL(iRegI dst, iRegL src, iRegL tmp) %{
12004   match(Set dst (CountTrailingZerosL src));
12005   effect(TEMP tmp);
12006   size(8);
12007   format %{ "RBIT $tmp, $src\n\t"
12008             "CLZ  $dst,$tmp" %}
12009   ins_encode %{
12010     __ rbit($tmp$$Register, $src$$Register);
12011     __ clz($dst$$Register, $tmp$$Register);
12012   %}
12013   ins_pipe(ialu_reg);
12014 %}
12015 #else
12016 instruct countTrailingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
12017   match(Set dst (CountTrailingZerosL src));
12018   effect(TEMP tmp, TEMP dst, KILL ccr);
12019   size(24);
12020   format %{ "RBIT   $tmp,$src.lo\n\t"
12021             "CLZ    $dst,$tmp\n\t"
12022             "TEQ    $dst,32\n\t"
12023             "RBIT   $tmp,$src.hi\n\t"
12024             "CLZ.eq $tmp,$tmp\n\t"
12025             "ADD.eq $dst,$dst,$tmp\n\t" %}
12026   ins_encode %{
12027     __ rbit($tmp$$Register, $src$$Register);
12028     __ clz($dst$$Register, $tmp$$Register);
12029     __ teq($dst$$Register, 32);
12030     __ rbit($tmp$$Register, $src$$Register->successor());
12031     __ clz($tmp$$Register, $tmp$$Register, eq);
12032     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
12033   %}
12034   ins_pipe(ialu_reg);
12035 %}
12036 #endif
12037 
12038 
12039 //---------- Population Count Instructions -------------------------------------
12040 
12041 #ifdef AARCH64
12042 instruct popCountI(iRegI dst, iRegI src, regD_low tmp) %{
12043   predicate(UsePopCountInstruction);
12044   match(Set dst (PopCountI src));
12045   effect(TEMP tmp);
12046   size(20);
12047 
12048   format %{ "MOV_W      $dst,$src\n\t"
12049             "FMOV_dx    $tmp,$dst\n\t"
12050             "VCNT       $tmp.8B,$tmp.8B\n\t"
12051             "ADDV       $tmp.B,$tmp.8B\n\t"
12052             "FMRS       $dst,$tmp" %}
12053 
12054   ins_encode %{
12055     __ mov_w($dst$$Register, $src$$Register);
12056     __ fmov_dx($tmp$$FloatRegister, $dst$$Register);
12057     int quad = 0;
12058     int cnt_size = 0; // VELEM_SIZE_8
12059     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister, quad, cnt_size);
12060     int add_size = 0; // VELEM_SIZE_8
12061     __ addv($tmp$$FloatRegister, $tmp$$FloatRegister, quad, add_size);
12062     __ fmrs($dst$$Register, $tmp$$FloatRegister);
12063   %}
12064   ins_pipe(ialu_reg); // FIXME
12065 %}
12066 #else
12067 instruct popCountI(iRegI dst, iRegI src, regD_low tmp) %{
12068   predicate(UsePopCountInstruction);
12069   match(Set dst (PopCountI src));
12070   effect(TEMP tmp);
12071 
12072   format %{ "FMSR       $tmp,$src\n\t"
12073             "VCNT.8     $tmp,$tmp\n\t"
12074             "VPADDL.U8  $tmp,$tmp\n\t"
12075             "VPADDL.U16 $tmp,$tmp\n\t"
12076             "FMRS       $dst,$tmp" %}
12077   size(20);
12078 
12079   ins_encode %{
12080     __ fmsr($tmp$$FloatRegister, $src$$Register);
12081     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
12082     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
12083     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
12084     __ fmrs($dst$$Register, $tmp$$FloatRegister);
12085   %}
12086   ins_pipe(ialu_reg); // FIXME
12087 %}
12088 #endif
12089 
12090 #ifdef AARCH64
12091 instruct popCountL(iRegI dst, iRegL src, regD tmp) %{
12092   predicate(UsePopCountInstruction);
12093   match(Set dst (PopCountL src));
12094   effect(TEMP tmp);
12095   size(16);
12096 
12097   format %{ "FMOV_dx    $tmp,$src\n\t"
12098             "VCNT       $tmp.8B,$tmp.8B\n\t"
12099             "ADDV       $tmp.B,$tmp.8B\n\t"
12100             "FMOV_ws    $dst,$tmp" %}
12101 
12102   ins_encode %{
12103     __ fmov_dx($tmp$$FloatRegister, $src$$Register);
12104     int quad = 0;
12105     int cnt_size = 0;
12106     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister, quad, cnt_size);
12107     int add_size = 0;
12108     __ addv($tmp$$FloatRegister, $tmp$$FloatRegister, quad, add_size);
12109     __ fmov_ws($dst$$Register, $tmp$$FloatRegister);
12110   %}
12111   ins_pipe(ialu_reg); // FIXME
12112 %}
12113 #else
12114 // Note: Long.bitCount(long) returns an int.
12115 instruct popCountL(iRegI dst, iRegL src, regD_low tmp) %{
12116   predicate(UsePopCountInstruction);
12117   match(Set dst (PopCountL src));
12118   effect(TEMP tmp);
12119 
12120   format %{ "FMDRR       $tmp,$src.lo,$src.hi\n\t"
12121             "VCNT.8      $tmp,$tmp\n\t"
12122             "VPADDL.U8   $tmp,$tmp\n\t"
12123             "VPADDL.U16  $tmp,$tmp\n\t"
12124             "VPADDL.U32  $tmp,$tmp\n\t"
12125             "FMRS        $dst,$tmp" %}
12126 
12127   size(32);
12128 
12129   ins_encode %{
12130     __ fmdrr($tmp$$FloatRegister, $src$$Register, $src$$Register->successor());
12131     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
12132     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
12133     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
12134     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 32, 0);
12135     __ fmrs($dst$$Register, $tmp$$FloatRegister);
12136   %}
12137   ins_pipe(ialu_reg);
12138 %}
12139 #endif
12140 
12141 
12142 // ============================================================================
12143 //------------Bytes reverse--------------------------------------------------
12144 
12145 instruct bytes_reverse_int(iRegI dst, iRegI src) %{
12146   match(Set dst (ReverseBytesI src));
12147 
12148   size(4);
12149   format %{ "REV32 $dst,$src" %}
12150   ins_encode %{
12151 #ifdef AARCH64
12152     __ rev_w($dst$$Register, $src$$Register);
12153     // high 32 bits zeroed, not sign extended
12154 #else
12155     __ rev($dst$$Register, $src$$Register);
12156 #endif
12157   %}
12158   ins_pipe( iload_mem ); // FIXME
12159 %}
12160 
12161 instruct bytes_reverse_long(iRegL dst, iRegL src) %{
12162   match(Set dst (ReverseBytesL src));
12163 #ifdef AARCH64
12164 //size(4);
12165   format %{ "REV $dst,$src"  %}
12166   ins_encode %{
12167     __ rev($dst$$Register, $src$$Register);
12168   %}
12169   ins_pipe(ialu_reg_reg); // FIXME
12170 #else
12171   effect(TEMP dst);
12172   size(8);
12173   format %{ "REV $dst.lo,$src.lo\n\t"
12174             "REV $dst.hi,$src.hi" %}
12175   ins_encode %{
12176     __ rev($dst$$Register, $src$$Register->successor());
12177     __ rev($dst$$Register->successor(), $src$$Register);
12178   %}
12179   ins_pipe( iload_mem ); // FIXME
12180 #endif
12181 %}
12182 
12183 instruct bytes_reverse_unsigned_short(iRegI dst, iRegI src) %{
12184   match(Set dst (ReverseBytesUS src));
12185 #ifdef AARCH64
12186   size(4);
12187   format %{ "REV16_W $dst,$src" %}
12188   ins_encode %{
12189     __ rev16_w($dst$$Register, $src$$Register);
12190     // high 32 bits zeroed
12191   %}
12192 #else
12193   size(4);
12194   format %{ "REV16 $dst,$src" %}
12195   ins_encode %{
12196     __ rev16($dst$$Register, $src$$Register);
12197   %}
12198 #endif
12199   ins_pipe( iload_mem ); // FIXME
12200 %}
12201 
12202 instruct bytes_reverse_short(iRegI dst, iRegI src) %{
12203   match(Set dst (ReverseBytesS src));
12204 #ifdef AARCH64
12205   size(8);
12206   format %{ "REV16_W $dst,$src\n\t"
12207             "SIGN_EXT16 $dst" %}
12208   ins_encode %{
12209     __ rev16_w($dst$$Register, $src$$Register);
12210     __ sign_extend($dst$$Register, $dst$$Register, 16);
12211   %}
12212 #else
12213   size(4);
12214   format %{ "REVSH $dst,$src" %}
12215   ins_encode %{
12216     __ revsh($dst$$Register, $src$$Register);
12217   %}
12218 #endif
12219   ins_pipe( iload_mem ); // FIXME
12220 %}
12221 
12222 
12223 // ====================VECTOR INSTRUCTIONS=====================================
12224 
12225 // Load Aligned Packed values into a Double Register
12226 instruct loadV8(vecD dst, memoryD mem) %{
12227   predicate(n->as_LoadVector()->memory_size() == 8);
12228   match(Set dst (LoadVector mem));
12229   ins_cost(MEMORY_REF_COST);
12230   size(4);
12231   format %{ "FLDD   $mem,$dst\t! load vector (8 bytes)" %}
12232   ins_encode %{
12233     __ ldr_double($dst$$FloatRegister, $mem$$Address);
12234   %}
12235   ins_pipe(floadD_mem);
12236 %}
12237 
12238 // Load Aligned Packed values into a Double Register Pair
12239 instruct loadV16(vecX dst, memoryvld mem) %{
12240   predicate(n->as_LoadVector()->memory_size() == 16);
12241   match(Set dst (LoadVector mem));
12242   ins_cost(MEMORY_REF_COST);
12243   size(4);
12244   format %{ "VLD1   $mem,$dst.Q\t! load vector (16 bytes)" %}
12245   ins_encode %{
12246     __ vld1($dst$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
12247   %}
12248   ins_pipe(floadD_mem); // FIXME
12249 %}
12250 
12251 // Store Vector in Double register to memory
12252 instruct storeV8(memoryD mem, vecD src) %{
12253   predicate(n->as_StoreVector()->memory_size() == 8);
12254   match(Set mem (StoreVector mem src));
12255   ins_cost(MEMORY_REF_COST);
12256   size(4);
12257   format %{ "FSTD   $src,$mem\t! store vector (8 bytes)" %}
12258   ins_encode %{
12259     __ str_double($src$$FloatRegister, $mem$$Address);
12260   %}
12261   ins_pipe(fstoreD_mem_reg);
12262 %}
12263 
12264 // Store Vector in Double Register Pair to memory
12265 instruct storeV16(memoryvld mem, vecX src) %{
12266   predicate(n->as_StoreVector()->memory_size() == 16);
12267   match(Set mem (StoreVector mem src));
12268   ins_cost(MEMORY_REF_COST);
12269   size(4);
12270   format %{ "VST1   $src,$mem\t! store vector (16 bytes)" %}
12271   ins_encode %{
12272     __ vst1($src$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
12273   %}
12274   ins_pipe(fstoreD_mem_reg); // FIXME
12275 %}
12276 
12277 #ifndef AARCH64
12278 // Replicate scalar to packed byte values in Double register
12279 instruct Repl8B_reg(vecD dst, iRegI src, iRegI tmp) %{
12280   predicate(n->as_Vector()->length() == 8);
12281   match(Set dst (ReplicateB src));
12282   ins_cost(DEFAULT_COST*4);
12283   effect(TEMP tmp);
12284   size(16);
12285 
12286   // FIXME: could use PKH instruction instead?
12287   format %{ "LSL      $tmp, $src, 24 \n\t"
12288             "OR       $tmp, $tmp, ($tmp >> 8) \n\t"
12289             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
12290             "FMDRR    $dst,$tmp,$tmp\t" %}
12291   ins_encode %{
12292     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 24));
12293     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 8));
12294     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
12295     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
12296   %}
12297   ins_pipe(ialu_reg); // FIXME
12298 %}
12299 #endif /* !AARCH64 */
12300 
12301 // Replicate scalar to packed byte values in Double register
12302 instruct Repl8B_reg_simd(vecD dst, iRegI src) %{
12303   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
12304   match(Set dst (ReplicateB src));
12305   size(4);
12306 
12307   format %{ "VDUP.8 $dst,$src\t" %}
12308   ins_encode %{
12309     bool quad = false;
12310     __ vdupI($dst$$FloatRegister, $src$$Register,
12311              MacroAssembler::VELEM_SIZE_8, quad);
12312   %}
12313   ins_pipe(ialu_reg); // FIXME
12314 %}
12315 
12316 // Replicate scalar to packed byte values in Double register pair
12317 instruct Repl16B_reg(vecX dst, iRegI src) %{
12318   predicate(n->as_Vector()->length_in_bytes() == 16);
12319   match(Set dst (ReplicateB src));
12320   size(4);
12321 
12322   format %{ "VDUP.8 $dst.Q,$src\t" %}
12323   ins_encode %{
12324     bool quad = true;
12325     __ vdupI($dst$$FloatRegister, $src$$Register,
12326              MacroAssembler::VELEM_SIZE_8, quad);
12327   %}
12328   ins_pipe(ialu_reg); // FIXME
12329 %}
12330 
12331 #ifndef AARCH64
12332 // Replicate scalar constant to packed byte values in Double register
12333 instruct Repl8B_immI(vecD dst, immI src, iRegI tmp) %{
12334   predicate(n->as_Vector()->length() == 8);
12335   match(Set dst (ReplicateB src));
12336   ins_cost(DEFAULT_COST*2);
12337   effect(TEMP tmp);
12338   size(12);
12339 
12340   format %{ "MOV      $tmp, Repl4($src))\n\t"
12341             "FMDRR    $dst,$tmp,$tmp\t" %}
12342   ins_encode( LdReplImmI(src, dst, tmp, (4), (1)) );
12343   ins_pipe(loadConFD); // FIXME
12344 %}
12345 #endif /* !AARCH64 */
12346 
12347 // Replicate scalar constant to packed byte values in Double register
12348 // TODO: support negative constants with MVNI?
12349 instruct Repl8B_immU8(vecD dst, immU8 src) %{
12350   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
12351   match(Set dst (ReplicateB src));
12352   size(4);
12353 
12354   format %{ "VMOV.U8  $dst,$src" %}
12355   ins_encode %{
12356     bool quad = false;
12357     __ vmovI($dst$$FloatRegister, $src$$constant,
12358              MacroAssembler::VELEM_SIZE_8, quad);
12359   %}
12360   ins_pipe(loadConFD); // FIXME
12361 %}
12362 
12363 // Replicate scalar constant to packed byte values in Double register pair
12364 instruct Repl16B_immU8(vecX dst, immU8 src) %{
12365   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
12366   match(Set dst (ReplicateB src));
12367   size(4);
12368 
12369   format %{ "VMOV.U8  $dst.Q,$src" %}
12370   ins_encode %{
12371     bool quad = true;
12372     __ vmovI($dst$$FloatRegister, $src$$constant,
12373              MacroAssembler::VELEM_SIZE_8, quad);
12374   %}
12375   ins_pipe(loadConFD); // FIXME
12376 %}
12377 
12378 #ifndef AARCH64
12379 // Replicate scalar to packed short/char values into Double register
12380 instruct Repl4S_reg(vecD dst, iRegI src, iRegI tmp) %{
12381   predicate(n->as_Vector()->length() == 4);
12382   match(Set dst (ReplicateS src));
12383   ins_cost(DEFAULT_COST*3);
12384   effect(TEMP tmp);
12385   size(12);
12386 
12387   // FIXME: could use PKH instruction instead?
12388   format %{ "LSL      $tmp, $src, 16 \n\t"
12389             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
12390             "FMDRR    $dst,$tmp,$tmp\t" %}
12391   ins_encode %{
12392     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 16));
12393     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
12394     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
12395   %}
12396   ins_pipe(ialu_reg); // FIXME
12397 %}
12398 #endif /* !AARCH64 */
12399 
12400 // Replicate scalar to packed byte values in Double register
12401 instruct Repl4S_reg_simd(vecD dst, iRegI src) %{
12402   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
12403   match(Set dst (ReplicateS src));
12404   size(4);
12405 
12406   format %{ "VDUP.16 $dst,$src\t" %}
12407   ins_encode %{
12408     bool quad = false;
12409     __ vdupI($dst$$FloatRegister, $src$$Register,
12410              MacroAssembler::VELEM_SIZE_16, quad);
12411   %}
12412   ins_pipe(ialu_reg); // FIXME
12413 %}
12414 
12415 // Replicate scalar to packed byte values in Double register pair
12416 instruct Repl8S_reg(vecX dst, iRegI src) %{
12417   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
12418   match(Set dst (ReplicateS src));
12419   size(4);
12420 
12421   format %{ "VDUP.16 $dst.Q,$src\t" %}
12422   ins_encode %{
12423     bool quad = true;
12424     __ vdupI($dst$$FloatRegister, $src$$Register,
12425              MacroAssembler::VELEM_SIZE_16, quad);
12426   %}
12427   ins_pipe(ialu_reg); // FIXME
12428 %}
12429 
12430 
12431 #ifndef AARCH64
12432 // Replicate scalar constant to packed short/char values in Double register
12433 instruct Repl4S_immI(vecD dst, immI src, iRegP tmp) %{
12434   predicate(n->as_Vector()->length() == 4);
12435   match(Set dst (ReplicateS src));
12436   effect(TEMP tmp);
12437   size(12);
12438   ins_cost(DEFAULT_COST*4); // FIXME
12439 
12440   format %{ "MOV      $tmp, Repl2($src))\n\t"
12441             "FMDRR    $dst,$tmp,$tmp\t" %}
12442   ins_encode( LdReplImmI(src, dst, tmp, (2), (2)) );
12443   ins_pipe(loadConFD); // FIXME
12444 %}
12445 #endif /* !AARCH64 */
12446 
12447 // Replicate scalar constant to packed byte values in Double register
12448 instruct Repl4S_immU8(vecD dst, immU8 src) %{
12449   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
12450   match(Set dst (ReplicateS src));
12451   size(4);
12452 
12453   format %{ "VMOV.U16  $dst,$src" %}
12454   ins_encode %{
12455     bool quad = false;
12456     __ vmovI($dst$$FloatRegister, $src$$constant,
12457              MacroAssembler::VELEM_SIZE_16, quad);
12458   %}
12459   ins_pipe(loadConFD); // FIXME
12460 %}
12461 
12462 // Replicate scalar constant to packed byte values in Double register pair
12463 instruct Repl8S_immU8(vecX dst, immU8 src) %{
12464   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
12465   match(Set dst (ReplicateS src));
12466   size(4);
12467 
12468   format %{ "VMOV.U16  $dst.Q,$src" %}
12469   ins_encode %{
12470     bool quad = true;
12471     __ vmovI($dst$$FloatRegister, $src$$constant,
12472              MacroAssembler::VELEM_SIZE_16, quad);
12473   %}
12474   ins_pipe(loadConFD); // FIXME
12475 %}
12476 
12477 #ifndef AARCH64
12478 // Replicate scalar to packed int values in Double register
12479 instruct Repl2I_reg(vecD dst, iRegI src) %{
12480   predicate(n->as_Vector()->length() == 2);
12481   match(Set dst (ReplicateI src));
12482   size(4);
12483 
12484   format %{ "FMDRR    $dst,$src,$src\t" %}
12485   ins_encode %{
12486     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
12487   %}
12488   ins_pipe(ialu_reg); // FIXME
12489 %}
12490 
12491 // Replicate scalar to packed int values in Double register pair
12492 instruct Repl4I_reg(vecX dst, iRegI src) %{
12493   predicate(n->as_Vector()->length() == 4);
12494   match(Set dst (ReplicateI src));
12495   ins_cost(DEFAULT_COST*2);
12496   size(8);
12497 
12498   format %{ "FMDRR    $dst.lo,$src,$src\n\t"
12499             "FMDRR    $dst.hi,$src,$src" %}
12500 
12501   ins_encode %{
12502     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
12503     __ fmdrr($dst$$FloatRegister->successor()->successor(),
12504              $src$$Register, $src$$Register);
12505   %}
12506   ins_pipe(ialu_reg); // FIXME
12507 %}
12508 #endif /* !AARCH64 */
12509 
12510 // Replicate scalar to packed int values in Double register
12511 instruct Repl2I_reg_simd(vecD dst, iRegI src) %{
12512   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
12513   match(Set dst (ReplicateI src));
12514   size(4);
12515 
12516   format %{ "VDUP.32 $dst.D,$src\t" %}
12517   ins_encode %{
12518     bool quad = false;
12519     __ vdupI($dst$$FloatRegister, $src$$Register,
12520              MacroAssembler::VELEM_SIZE_32, quad);
12521   %}
12522   ins_pipe(ialu_reg); // FIXME
12523 %}
12524 
12525 // Replicate scalar to packed int values in Double register pair
12526 instruct Repl4I_reg_simd(vecX dst, iRegI src) %{
12527   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
12528   match(Set dst (ReplicateI src));
12529   size(4);
12530 
12531   format %{ "VDUP.32 $dst.Q,$src\t" %}
12532   ins_encode %{
12533     bool quad = true;
12534     __ vdupI($dst$$FloatRegister, $src$$Register,
12535              MacroAssembler::VELEM_SIZE_32, quad);
12536   %}
12537   ins_pipe(ialu_reg); // FIXME
12538 %}
12539 
12540 
12541 #ifndef AARCH64
12542 // Replicate scalar zero constant to packed int values in Double register
12543 instruct Repl2I_immI(vecD dst, immI src, iRegI tmp) %{
12544   predicate(n->as_Vector()->length() == 2);
12545   match(Set dst (ReplicateI src));
12546   effect(TEMP tmp);
12547   size(12);
12548   ins_cost(DEFAULT_COST*4); // FIXME
12549 
12550   format %{ "MOV      $tmp, Repl1($src))\n\t"
12551             "FMDRR    $dst,$tmp,$tmp\t" %}
12552   ins_encode( LdReplImmI(src, dst, tmp, (1), (4)) );
12553   ins_pipe(loadConFD); // FIXME
12554 %}
12555 #endif /* !AARCH64 */
12556 
12557 // Replicate scalar constant to packed byte values in Double register
12558 instruct Repl2I_immU8(vecD dst, immU8 src) %{
12559   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
12560   match(Set dst (ReplicateI src));
12561   size(4);
12562 
12563   format %{ "VMOV.I32  $dst.D,$src" %}
12564   ins_encode %{
12565     bool quad = false;
12566     __ vmovI($dst$$FloatRegister, $src$$constant,
12567              MacroAssembler::VELEM_SIZE_32, quad);
12568   %}
12569   ins_pipe(loadConFD); // FIXME
12570 %}
12571 
12572 // Replicate scalar constant to packed byte values in Double register pair
12573 instruct Repl4I_immU8(vecX dst, immU8 src) %{
12574   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
12575   match(Set dst (ReplicateI src));
12576   size(4);
12577 
12578   format %{ "VMOV.I32  $dst.Q,$src" %}
12579   ins_encode %{
12580     bool quad = true;
12581     __ vmovI($dst$$FloatRegister, $src$$constant,
12582              MacroAssembler::VELEM_SIZE_32, quad);
12583   %}
12584   ins_pipe(loadConFD); // FIXME
12585 %}
12586 
12587 #ifdef AARCH64
12588 // Replicate scalar to packed byte values in Double register pair
12589 instruct Repl2L_reg(vecX dst, iRegL src) %{
12590   predicate(n->as_Vector()->length() == 2);
12591   match(Set dst (ReplicateL src));
12592   size(4*1);
12593   ins_cost(DEFAULT_COST*1); // FIXME
12594 
12595   format %{ "VDUP.2D $dst.Q,$src\t" %}
12596   ins_encode %{
12597     bool quad = true;
12598     __ vdupI($dst$$FloatRegister, $src$$Register,
12599              MacroAssembler::VELEM_SIZE_64, quad);
12600   %}
12601   ins_pipe(ialu_reg); // FIXME
12602 %}
12603 #else /* !AARCH64 */
12604 // Replicate scalar to packed byte values in Double register pair
12605 instruct Repl2L_reg(vecX dst, iRegL src) %{
12606   predicate(n->as_Vector()->length() == 2);
12607   match(Set dst (ReplicateL src));
12608   size(8);
12609   ins_cost(DEFAULT_COST*2); // FIXME
12610 
12611   format %{ "FMDRR $dst.D,$src.lo,$src.hi\t\n"
12612             "FMDRR $dst.D.next,$src.lo,$src.hi" %}
12613   ins_encode %{
12614     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
12615     __ fmdrr($dst$$FloatRegister->successor()->successor(),
12616              $src$$Register, $src$$Register->successor());
12617   %}
12618   ins_pipe(ialu_reg); // FIXME
12619 %}
12620 
12621 
12622 // Replicate scalar to packed float values in Double register
12623 instruct Repl2F_regI(vecD dst, iRegI src) %{
12624   predicate(n->as_Vector()->length() == 2);
12625   match(Set dst (ReplicateF src));
12626   size(4);
12627 
12628   format %{ "FMDRR    $dst.D,$src,$src\t" %}
12629   ins_encode %{
12630     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
12631   %}
12632   ins_pipe(ialu_reg); // FIXME
12633 %}
12634 
12635 // Replicate scalar to packed float values in Double register
12636 instruct Repl2F_reg_vfp(vecD dst, regF src) %{
12637   predicate(n->as_Vector()->length() == 2);
12638   match(Set dst (ReplicateF src));
12639   size(4*2);
12640   ins_cost(DEFAULT_COST*2); // FIXME
12641 
12642   expand %{
12643     iRegI tmp;
12644     MoveF2I_reg_reg(tmp, src);
12645     Repl2F_regI(dst,tmp);
12646   %}
12647 %}
12648 #endif /* !AARCH64 */
12649 
12650 // Replicate scalar to packed float values in Double register
12651 instruct Repl2F_reg_simd(vecD dst, regF src) %{
12652   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
12653   match(Set dst (ReplicateF src));
12654   size(4);
12655   ins_cost(DEFAULT_COST); // FIXME
12656 
12657   format %{ "VDUP.32  $dst.D,$src.D\t" %}
12658   ins_encode %{
12659     bool quad = false;
12660     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
12661   %}
12662   ins_pipe(ialu_reg); // FIXME
12663 %}
12664 
12665 #ifndef AARCH64
12666 // Replicate scalar to packed float values in Double register pair
12667 instruct Repl4F_reg(vecX dst, regF src, iRegI tmp) %{
12668   predicate(n->as_Vector()->length() == 4);
12669   match(Set dst (ReplicateF src));
12670   effect(TEMP tmp);
12671   size(4*3);
12672   ins_cost(DEFAULT_COST*3); // FIXME
12673 
12674   format %{ "FMRS     $tmp,$src\n\t"
12675             "FMDRR    $dst.D,$tmp,$tmp\n\t"
12676             "FMDRR    $dst.D.next,$tmp,$tmp\t" %}
12677   ins_encode %{
12678     __ fmrs($tmp$$Register, $src$$FloatRegister);
12679     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
12680     __ fmdrr($dst$$FloatRegister->successor()->successor(),
12681              $tmp$$Register, $tmp$$Register);
12682   %}
12683   ins_pipe(ialu_reg); // FIXME
12684 %}
12685 #endif /* !AARCH64 */
12686 
12687 // Replicate scalar to packed float values in Double register pair
12688 instruct Repl4F_reg_simd(vecX dst, regF src) %{
12689   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
12690   match(Set dst (ReplicateF src));
12691   size(4);
12692   ins_cost(DEFAULT_COST); // FIXME
12693 
12694   format %{ "VDUP.32  $dst.Q,$src.D\t" %}
12695   ins_encode %{
12696     bool quad = true;
12697     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
12698   %}
12699   ins_pipe(ialu_reg); // FIXME
12700 %}
12701 
12702 #ifndef AARCH64
12703 // Replicate scalar zero constant to packed float values in Double register
12704 instruct Repl2F_immI(vecD dst, immF src, iRegI tmp) %{
12705   predicate(n->as_Vector()->length() == 2);
12706   match(Set dst (ReplicateF src));
12707   effect(TEMP tmp);
12708   size(12);
12709   ins_cost(DEFAULT_COST*4); // FIXME
12710 
12711   format %{ "MOV      $tmp, Repl1($src))\n\t"
12712             "FMDRR    $dst,$tmp,$tmp\t" %}
12713   ins_encode( LdReplImmF(src, dst, tmp) );
12714   ins_pipe(loadConFD); // FIXME
12715 %}
12716 #endif /* !AAARCH64 */
12717 
12718 // Replicate scalar to packed double float values in Double register pair
12719 instruct Repl2D_reg(vecX dst, regD src) %{
12720 #ifdef AARCH64
12721   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
12722   match(Set dst (ReplicateD src));
12723   size(4*1);
12724   ins_cost(DEFAULT_COST*1); // FIXME
12725 
12726   format %{ "VDUP     $dst.2D,$src\t" %}
12727   ins_encode %{
12728     bool quad = true;
12729     __ vdupD($dst$$FloatRegister, $src$$FloatRegister, quad);
12730   %}
12731 #else
12732   predicate(n->as_Vector()->length() == 2);
12733   match(Set dst (ReplicateD src));
12734   size(4*2);
12735   ins_cost(DEFAULT_COST*2); // FIXME
12736 
12737   format %{ "FCPYD    $dst.D.a,$src\n\t"
12738             "FCPYD    $dst.D.b,$src\t" %}
12739   ins_encode %{
12740     FloatRegister dsta = $dst$$FloatRegister;
12741     FloatRegister src = $src$$FloatRegister;
12742     __ fcpyd(dsta, src);
12743     FloatRegister dstb = dsta->successor()->successor();
12744     __ fcpyd(dstb, src);
12745   %}
12746 #endif
12747   ins_pipe(ialu_reg); // FIXME
12748 %}
12749 
12750 // ====================VECTOR ARITHMETIC=======================================
12751 
12752 // --------------------------------- ADD --------------------------------------
12753 
12754 // Bytes vector add
12755 instruct vadd8B_reg(vecD dst, vecD src1, vecD src2) %{
12756   predicate(n->as_Vector()->length() == 8);
12757   match(Set dst (AddVB src1 src2));
12758   format %{ "VADD.I8 $dst,$src1,$src2\t! add packed8B" %}
12759   size(4);
12760   ins_encode %{
12761     bool quad = false;
12762     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
12763              MacroAssembler::VELEM_SIZE_8, quad);
12764   %}
12765   ins_pipe( ialu_reg_reg ); // FIXME
12766 %}
12767 
12768 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
12769   predicate(n->as_Vector()->length() == 16);
12770   match(Set dst (AddVB src1 src2));
12771   size(4);
12772   format %{ "VADD.I8 $dst.Q,$src1.Q,$src2.Q\t! add packed16B" %}
12773   ins_encode %{
12774     bool quad = true;
12775     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
12776              MacroAssembler::VELEM_SIZE_8, quad);
12777   %}
12778   ins_pipe( ialu_reg_reg ); // FIXME
12779 %}
12780 
12781 // Shorts/Chars vector add
12782 instruct vadd4S_reg(vecD dst, vecD src1, vecD src2) %{
12783   predicate(n->as_Vector()->length() == 4);
12784   match(Set dst (AddVS src1 src2));
12785   size(4);
12786   format %{ "VADD.I16 $dst,$src1,$src2\t! add packed4S" %}
12787   ins_encode %{
12788     bool quad = false;
12789     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
12790              MacroAssembler::VELEM_SIZE_16, quad);
12791   %}
12792   ins_pipe( ialu_reg_reg ); // FIXME
12793 %}
12794 
12795 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
12796   predicate(n->as_Vector()->length() == 8);
12797   match(Set dst (AddVS src1 src2));
12798   size(4);
12799   format %{ "VADD.I16 $dst.Q,$src1.Q,$src2.Q\t! add packed8S" %}
12800   ins_encode %{
12801     bool quad = true;
12802     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
12803              MacroAssembler::VELEM_SIZE_16, quad);
12804   %}
12805   ins_pipe( ialu_reg_reg ); // FIXME
12806 %}
12807 
12808 // Integers vector add
12809 instruct vadd2I_reg(vecD dst, vecD src1, vecD src2) %{
12810   predicate(n->as_Vector()->length() == 2);
12811   match(Set dst (AddVI src1 src2));
12812   size(4);
12813   format %{ "VADD.I32 $dst.D,$src1.D,$src2.D\t! add packed2I" %}
12814   ins_encode %{
12815     bool quad = false;
12816     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
12817              MacroAssembler::VELEM_SIZE_32, quad);
12818   %}
12819   ins_pipe( ialu_reg_reg ); // FIXME
12820 %}
12821 
12822 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
12823   predicate(n->as_Vector()->length() == 4);
12824   match(Set dst (AddVI src1 src2));
12825   size(4);
12826   format %{ "VADD.I32 $dst.Q,$src1.Q,$src2.Q\t! add packed4I" %}
12827   ins_encode %{
12828     bool quad = true;
12829     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
12830              MacroAssembler::VELEM_SIZE_32, quad);
12831   %}
12832   ins_pipe( ialu_reg_reg ); // FIXME
12833 %}
12834 
12835 // Longs vector add
12836 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
12837   predicate(n->as_Vector()->length() == 2);
12838   match(Set dst (AddVL src1 src2));
12839   size(4);
12840   format %{ "VADD.I64 $dst.Q,$src1.Q,$src2.Q\t! add packed2L" %}
12841   ins_encode %{
12842     bool quad = true;
12843     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
12844              MacroAssembler::VELEM_SIZE_64, quad);
12845   %}
12846   ins_pipe( ialu_reg_reg ); // FIXME
12847 %}
12848 
12849 // Floats vector add
12850 instruct vadd2F_reg(vecD dst, vecD src1, vecD src2) %{
12851   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
12852   match(Set dst (AddVF src1 src2));
12853   size(4);
12854   format %{ "VADD.F32 $dst,$src1,$src2\t! add packed2F" %}
12855   ins_encode %{
12856     bool quad = false;
12857     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
12858              MacroAssembler::VFA_SIZE_F32, quad);
12859   %}
12860   ins_pipe( faddD_reg_reg ); // FIXME
12861 %}
12862 
12863 #ifndef AARCH64
12864 instruct vadd2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
12865   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
12866   match(Set dst (AddVF src1 src2));
12867   ins_cost(DEFAULT_COST*2); // FIXME
12868 
12869   size(4*2);
12870   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
12871             "FADDS  $dst.b,$src1.b,$src2.b" %}
12872   ins_encode %{
12873     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
12874     __ add_float($dst$$FloatRegister->successor(),
12875              $src1$$FloatRegister->successor(),
12876              $src2$$FloatRegister->successor());
12877   %}
12878 
12879   ins_pipe(faddF_reg_reg); // FIXME
12880 %}
12881 #endif
12882 
12883 instruct vadd4F_reg_simd(vecX dst, vecX src1, vecX src2) %{
12884   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
12885   match(Set dst (AddVF src1 src2));
12886   size(4);
12887   format %{ "VADD.F32 $dst.Q,$src1.Q,$src2.Q\t! add packed4F" %}
12888   ins_encode %{
12889     bool quad = true;
12890     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
12891              MacroAssembler::VFA_SIZE_F32, quad);
12892   %}
12893   ins_pipe( faddD_reg_reg ); // FIXME
12894 %}
12895 
12896 #ifdef AARCH64
12897 instruct vadd2D_reg_simd(vecX dst, vecX src1, vecX src2) %{
12898   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
12899   match(Set dst (AddVD src1 src2));
12900   size(4);
12901   format %{ "VADD.F64 $dst.Q,$src1.Q,$src2.Q\t! add packed2D" %}
12902   ins_encode %{
12903     bool quad = true;
12904     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
12905              MacroAssembler::VFA_SIZE_F64, quad);
12906   %}
12907   ins_pipe( faddD_reg_reg ); // FIXME
12908 %}
12909 #else
12910 instruct vadd4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
12911   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
12912   match(Set dst (AddVF src1 src2));
12913   size(4*4);
12914   ins_cost(DEFAULT_COST*4); // FIXME
12915 
12916   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
12917             "FADDS  $dst.b,$src1.b,$src2.b\n\t"
12918             "FADDS  $dst.c,$src1.c,$src2.c\n\t"
12919             "FADDS  $dst.d,$src1.d,$src2.d" %}
12920 
12921   ins_encode %{
12922     FloatRegister dsta = $dst$$FloatRegister;
12923     FloatRegister src1a = $src1$$FloatRegister;
12924     FloatRegister src2a = $src2$$FloatRegister;
12925     __ add_float(dsta, src1a, src2a);
12926     FloatRegister dstb = dsta->successor();
12927     FloatRegister src1b = src1a->successor();
12928     FloatRegister src2b = src2a->successor();
12929     __ add_float(dstb, src1b, src2b);
12930     FloatRegister dstc = dstb->successor();
12931     FloatRegister src1c = src1b->successor();
12932     FloatRegister src2c = src2b->successor();
12933     __ add_float(dstc, src1c, src2c);
12934     FloatRegister dstd = dstc->successor();
12935     FloatRegister src1d = src1c->successor();
12936     FloatRegister src2d = src2c->successor();
12937     __ add_float(dstd, src1d, src2d);
12938   %}
12939 
12940   ins_pipe(faddF_reg_reg); // FIXME
12941 %}
12942 
12943 instruct vadd2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
12944   predicate(n->as_Vector()->length() == 2);
12945   match(Set dst (AddVD src1 src2));
12946   size(4*2);
12947   ins_cost(DEFAULT_COST*2); // FIXME
12948 
12949   format %{ "FADDD  $dst.a,$src1.a,$src2.a\n\t"
12950             "FADDD  $dst.b,$src1.b,$src2.b" %}
12951 
12952   ins_encode %{
12953     FloatRegister dsta = $dst$$FloatRegister;
12954     FloatRegister src1a = $src1$$FloatRegister;
12955     FloatRegister src2a = $src2$$FloatRegister;
12956     __ add_double(dsta, src1a, src2a);
12957     FloatRegister dstb = dsta->successor()->successor();
12958     FloatRegister src1b = src1a->successor()->successor();
12959     FloatRegister src2b = src2a->successor()->successor();
12960     __ add_double(dstb, src1b, src2b);
12961   %}
12962 
12963   ins_pipe(faddF_reg_reg); // FIXME
12964 %}
12965 #endif
12966 
12967 
12968 // Bytes vector sub
12969 instruct vsub8B_reg(vecD dst, vecD src1, vecD src2) %{
12970   predicate(n->as_Vector()->length() == 8);
12971   match(Set dst (SubVB src1 src2));
12972   size(4);
12973   format %{ "VSUB.I8 $dst,$src1,$src2\t! sub packed8B" %}
12974   ins_encode %{
12975     bool quad = false;
12976     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
12977              MacroAssembler::VELEM_SIZE_8, quad);
12978   %}
12979   ins_pipe( ialu_reg_reg ); // FIXME
12980 %}
12981 
12982 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
12983   predicate(n->as_Vector()->length() == 16);
12984   match(Set dst (SubVB src1 src2));
12985   size(4);
12986   format %{ "VSUB.I8 $dst.Q,$src1.Q,$src2.Q\t! sub packed16B" %}
12987   ins_encode %{
12988     bool quad = true;
12989     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
12990              MacroAssembler::VELEM_SIZE_8, quad);
12991   %}
12992   ins_pipe( ialu_reg_reg ); // FIXME
12993 %}
12994 
12995 // Shorts/Chars vector sub
12996 instruct vsub4S_reg(vecD dst, vecD src1, vecD src2) %{
12997   predicate(n->as_Vector()->length() == 4);
12998   match(Set dst (SubVS src1 src2));
12999   size(4);
13000   format %{ "VSUB.I16 $dst,$src1,$src2\t! sub packed4S" %}
13001   ins_encode %{
13002     bool quad = false;
13003     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13004              MacroAssembler::VELEM_SIZE_16, quad);
13005   %}
13006   ins_pipe( ialu_reg_reg ); // FIXME
13007 %}
13008 
13009 instruct vsub16S_reg(vecX dst, vecX src1, vecX src2) %{
13010   predicate(n->as_Vector()->length() == 8);
13011   match(Set dst (SubVS src1 src2));
13012   size(4);
13013   format %{ "VSUB.I16 $dst.Q,$src1.Q,$src2.Q\t! sub packed8S" %}
13014   ins_encode %{
13015     bool quad = true;
13016     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13017              MacroAssembler::VELEM_SIZE_16, quad);
13018   %}
13019   ins_pipe( ialu_reg_reg ); // FIXME
13020 %}
13021 
13022 // Integers vector sub
13023 instruct vsub2I_reg(vecD dst, vecD src1, vecD src2) %{
13024   predicate(n->as_Vector()->length() == 2);
13025   match(Set dst (SubVI src1 src2));
13026   size(4);
13027   format %{ "VSUB.I32 $dst,$src1,$src2\t! sub packed2I" %}
13028   ins_encode %{
13029     bool quad = false;
13030     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13031              MacroAssembler::VELEM_SIZE_32, quad);
13032   %}
13033   ins_pipe( ialu_reg_reg ); // FIXME
13034 %}
13035 
13036 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
13037   predicate(n->as_Vector()->length() == 4);
13038   match(Set dst (SubVI src1 src2));
13039   size(4);
13040   format %{ "VSUB.I32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4I" %}
13041   ins_encode %{
13042     bool quad = true;
13043     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13044              MacroAssembler::VELEM_SIZE_32, quad);
13045   %}
13046   ins_pipe( ialu_reg_reg ); // FIXME
13047 %}
13048 
13049 // Longs vector sub
13050 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
13051   predicate(n->as_Vector()->length() == 2);
13052   match(Set dst (SubVL src1 src2));
13053   size(4);
13054   format %{ "VSUB.I64 $dst.Q,$src1.Q,$src2.Q\t! sub packed2L" %}
13055   ins_encode %{
13056     bool quad = true;
13057     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13058              MacroAssembler::VELEM_SIZE_64, quad);
13059   %}
13060   ins_pipe( ialu_reg_reg ); // FIXME
13061 %}
13062 
13063 // Floats vector sub
13064 instruct vsub2F_reg(vecD dst, vecD src1, vecD src2) %{
13065   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
13066   match(Set dst (SubVF src1 src2));
13067   size(4);
13068   format %{ "VSUB.F32 $dst,$src1,$src2\t! sub packed2F" %}
13069   ins_encode %{
13070     bool quad = false;
13071     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13072              MacroAssembler::VFA_SIZE_F32, quad);
13073   %}
13074   ins_pipe( faddF_reg_reg ); // FIXME
13075 %}
13076 
13077 #ifndef AARCH64
13078 instruct vsub2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
13079   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
13080   match(Set dst (SubVF src1 src2));
13081   size(4*2);
13082   ins_cost(DEFAULT_COST*2); // FIXME
13083 
13084   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
13085             "FSUBS  $dst.b,$src1.b,$src2.b" %}
13086 
13087   ins_encode %{
13088     FloatRegister dsta = $dst$$FloatRegister;
13089     FloatRegister src1a = $src1$$FloatRegister;
13090     FloatRegister src2a = $src2$$FloatRegister;
13091     __ sub_float(dsta, src1a, src2a);
13092     FloatRegister dstb = dsta->successor();
13093     FloatRegister src1b = src1a->successor();
13094     FloatRegister src2b = src2a->successor();
13095     __ sub_float(dstb, src1b, src2b);
13096   %}
13097 
13098   ins_pipe(faddF_reg_reg); // FIXME
13099 %}
13100 #endif
13101 
13102 
13103 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
13104   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
13105   match(Set dst (SubVF src1 src2));
13106   size(4);
13107   format %{ "VSUB.F32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4F" %}
13108   ins_encode %{
13109     bool quad = true;
13110     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13111              MacroAssembler::VFA_SIZE_F32, quad);
13112   %}
13113   ins_pipe( faddF_reg_reg ); // FIXME
13114 %}
13115 
13116 #ifdef AARCH64
13117 instruct vsub2D_reg_simd(vecX dst, vecX src1, vecX src2) %{
13118   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
13119   match(Set dst (SubVD src1 src2));
13120   size(4);
13121   format %{ "VSUB.F64 $dst.Q,$src1.Q,$src2.Q\t! add packed2D" %}
13122   ins_encode %{
13123     bool quad = true;
13124     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13125              MacroAssembler::VFA_SIZE_F64, quad);
13126   %}
13127   ins_pipe( faddD_reg_reg ); // FIXME
13128 %}
13129 #else
13130 instruct vsub4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
13131   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
13132   match(Set dst (SubVF src1 src2));
13133   size(4*4);
13134   ins_cost(DEFAULT_COST*4); // FIXME
13135 
13136   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
13137             "FSUBS  $dst.b,$src1.b,$src2.b\n\t"
13138             "FSUBS  $dst.c,$src1.c,$src2.c\n\t"
13139             "FSUBS  $dst.d,$src1.d,$src2.d" %}
13140 
13141   ins_encode %{
13142     FloatRegister dsta = $dst$$FloatRegister;
13143     FloatRegister src1a = $src1$$FloatRegister;
13144     FloatRegister src2a = $src2$$FloatRegister;
13145     __ sub_float(dsta, src1a, src2a);
13146     FloatRegister dstb = dsta->successor();
13147     FloatRegister src1b = src1a->successor();
13148     FloatRegister src2b = src2a->successor();
13149     __ sub_float(dstb, src1b, src2b);
13150     FloatRegister dstc = dstb->successor();
13151     FloatRegister src1c = src1b->successor();
13152     FloatRegister src2c = src2b->successor();
13153     __ sub_float(dstc, src1c, src2c);
13154     FloatRegister dstd = dstc->successor();
13155     FloatRegister src1d = src1c->successor();
13156     FloatRegister src2d = src2c->successor();
13157     __ sub_float(dstd, src1d, src2d);
13158   %}
13159 
13160   ins_pipe(faddF_reg_reg); // FIXME
13161 %}
13162 
13163 instruct vsub2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
13164   predicate(n->as_Vector()->length() == 2);
13165   match(Set dst (SubVD src1 src2));
13166   size(4*2);
13167   ins_cost(DEFAULT_COST*2); // FIXME
13168 
13169   format %{ "FSUBD  $dst.a,$src1.a,$src2.a\n\t"
13170             "FSUBD  $dst.b,$src1.b,$src2.b" %}
13171 
13172   ins_encode %{
13173     FloatRegister dsta = $dst$$FloatRegister;
13174     FloatRegister src1a = $src1$$FloatRegister;
13175     FloatRegister src2a = $src2$$FloatRegister;
13176     __ sub_double(dsta, src1a, src2a);
13177     FloatRegister dstb = dsta->successor()->successor();
13178     FloatRegister src1b = src1a->successor()->successor();
13179     FloatRegister src2b = src2a->successor()->successor();
13180     __ sub_double(dstb, src1b, src2b);
13181   %}
13182 
13183   ins_pipe(faddF_reg_reg); // FIXME
13184 %}
13185 #endif
13186 
13187 // Shorts/Chars vector mul
13188 instruct vmul4S_reg(vecD dst, vecD src1, vecD src2) %{
13189   predicate(n->as_Vector()->length() == 4);
13190   match(Set dst (MulVS src1 src2));
13191   size(4);
13192   format %{ "VMUL.I16 $dst,$src1,$src2\t! mul packed4S" %}
13193   ins_encode %{
13194     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13195              MacroAssembler::VELEM_SIZE_16, 0);
13196   %}
13197   ins_pipe( ialu_reg_reg ); // FIXME
13198 %}
13199 
13200 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2) %{
13201   predicate(n->as_Vector()->length() == 8);
13202   match(Set dst (MulVS src1 src2));
13203   size(4);
13204   format %{ "VMUL.I16 $dst.Q,$src1.Q,$src2.Q\t! mul packed8S" %}
13205   ins_encode %{
13206     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13207              MacroAssembler::VELEM_SIZE_16, 1);
13208   %}
13209   ins_pipe( ialu_reg_reg ); // FIXME
13210 %}
13211 
13212 // Integers vector mul
13213 instruct vmul2I_reg(vecD dst, vecD src1, vecD src2) %{
13214   predicate(n->as_Vector()->length() == 2);
13215   match(Set dst (MulVI src1 src2));
13216   size(4);
13217   format %{ "VMUL.I32 $dst,$src1,$src2\t! mul packed2I" %}
13218   ins_encode %{
13219     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13220              MacroAssembler::VELEM_SIZE_32, 0);
13221   %}
13222   ins_pipe( ialu_reg_reg ); // FIXME
13223 %}
13224 
13225 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
13226   predicate(n->as_Vector()->length() == 4);
13227   match(Set dst (MulVI src1 src2));
13228   size(4);
13229   format %{ "VMUL.I32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4I" %}
13230   ins_encode %{
13231     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13232              MacroAssembler::VELEM_SIZE_32, 1);
13233   %}
13234   ins_pipe( ialu_reg_reg ); // FIXME
13235 %}
13236 
13237 // Floats vector mul
13238 instruct vmul2F_reg(vecD dst, vecD src1, vecD src2) %{
13239   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
13240   match(Set dst (MulVF src1 src2));
13241   size(4);
13242   format %{ "VMUL.F32 $dst,$src1,$src2\t! mul packed2F" %}
13243   ins_encode %{
13244     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13245              MacroAssembler::VFA_SIZE_F32, 0);
13246   %}
13247   ins_pipe( fmulF_reg_reg ); // FIXME
13248 %}
13249 
13250 #ifndef AARCH64
13251 instruct vmul2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
13252   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
13253   match(Set dst (MulVF src1 src2));
13254   size(4*2);
13255   ins_cost(DEFAULT_COST*2); // FIXME
13256 
13257   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
13258             "FMULS  $dst.b,$src1.b,$src2.b" %}
13259   ins_encode %{
13260     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
13261     __ mul_float($dst$$FloatRegister->successor(),
13262              $src1$$FloatRegister->successor(),
13263              $src2$$FloatRegister->successor());
13264   %}
13265 
13266   ins_pipe(fmulF_reg_reg); // FIXME
13267 %}
13268 #endif
13269 
13270 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
13271   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
13272   match(Set dst (MulVF src1 src2));
13273   size(4);
13274   format %{ "VMUL.F32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4F" %}
13275   ins_encode %{
13276     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13277              MacroAssembler::VFA_SIZE_F32, 1);
13278   %}
13279   ins_pipe( fmulF_reg_reg ); // FIXME
13280 %}
13281 
13282 #ifndef AARCH64
13283 instruct vmul4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
13284   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
13285   match(Set dst (MulVF src1 src2));
13286   size(4*4);
13287   ins_cost(DEFAULT_COST*4); // FIXME
13288 
13289   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
13290             "FMULS  $dst.b,$src1.b,$src2.b\n\t"
13291             "FMULS  $dst.c,$src1.c,$src2.c\n\t"
13292             "FMULS  $dst.d,$src1.d,$src2.d" %}
13293 
13294   ins_encode %{
13295     FloatRegister dsta = $dst$$FloatRegister;
13296     FloatRegister src1a = $src1$$FloatRegister;
13297     FloatRegister src2a = $src2$$FloatRegister;
13298     __ mul_float(dsta, src1a, src2a);
13299     FloatRegister dstb = dsta->successor();
13300     FloatRegister src1b = src1a->successor();
13301     FloatRegister src2b = src2a->successor();
13302     __ mul_float(dstb, src1b, src2b);
13303     FloatRegister dstc = dstb->successor();
13304     FloatRegister src1c = src1b->successor();
13305     FloatRegister src2c = src2b->successor();
13306     __ mul_float(dstc, src1c, src2c);
13307     FloatRegister dstd = dstc->successor();
13308     FloatRegister src1d = src1c->successor();
13309     FloatRegister src2d = src2c->successor();
13310     __ mul_float(dstd, src1d, src2d);
13311   %}
13312 
13313   ins_pipe(fmulF_reg_reg); // FIXME
13314 %}
13315 #endif
13316 
13317 #ifdef AARCH64
13318 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{
13319   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
13320   match(Set dst (MulVD src1 src2));
13321   size(4*1);
13322   ins_cost(DEFAULT_COST*1); // FIXME
13323 
13324   format %{ "FMUL.2D $dst,$src1,$src2\t! double[2]" %}
13325   ins_encode %{
13326     int quad = 1;
13327     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13328              MacroAssembler::VFA_SIZE_F64, quad);
13329   %}
13330 
13331   ins_pipe(fdivF_reg_reg); // FIXME
13332 %}
13333 #else
13334 instruct vmul2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
13335   predicate(n->as_Vector()->length() == 2);
13336   match(Set dst (MulVD src1 src2));
13337   size(4*2);
13338   ins_cost(DEFAULT_COST*2); // FIXME
13339 
13340   format %{ "FMULD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
13341             "FMULD  $dst.D.b,$src1.D.b,$src2.D.b" %}
13342   ins_encode %{
13343     FloatRegister dsta = $dst$$FloatRegister;
13344     FloatRegister src1a = $src1$$FloatRegister;
13345     FloatRegister src2a = $src2$$FloatRegister;
13346     __ mul_double(dsta, src1a, src2a);
13347     FloatRegister dstb = dsta->successor()->successor();
13348     FloatRegister src1b = src1a->successor()->successor();
13349     FloatRegister src2b = src2a->successor()->successor();
13350     __ mul_double(dstb, src1b, src2b);
13351   %}
13352 
13353   ins_pipe(fmulD_reg_reg); // FIXME
13354 %}
13355 #endif
13356 
13357 
13358 // Floats vector div
13359 instruct vdiv2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
13360   predicate(n->as_Vector()->length() == 2);
13361   match(Set dst (DivVF src1 src2));
13362 #ifdef AARCH64
13363   size(4*1);
13364   ins_cost(DEFAULT_COST*1); // FIXME
13365 
13366   format %{ "FDIV.2S $dst,$src1,$src2\t! float[2]" %}
13367   ins_encode %{
13368     int quad = 0;
13369     __ vdivF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13370              MacroAssembler::VFA_SIZE_F32, quad);
13371   %}
13372 
13373   ins_pipe(fdivF_reg_reg); // FIXME
13374 #else
13375   size(4*2);
13376   ins_cost(DEFAULT_COST*2); // FIXME
13377 
13378   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
13379             "FDIVS  $dst.b,$src1.b,$src2.b" %}
13380   ins_encode %{
13381     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
13382     __ div_float($dst$$FloatRegister->successor(),
13383              $src1$$FloatRegister->successor(),
13384              $src2$$FloatRegister->successor());
13385   %}
13386 
13387   ins_pipe(fdivF_reg_reg); // FIXME
13388 #endif
13389 %}
13390 
13391 instruct vdiv4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
13392   predicate(n->as_Vector()->length() == 4);
13393   match(Set dst (DivVF src1 src2));
13394 #ifdef AARCH64
13395   size(4*1);
13396   ins_cost(DEFAULT_COST*1); // FIXME
13397 
13398   format %{ "FDIV.4S $dst,$src1,$src2\t! float[4]" %}
13399   ins_encode %{
13400     int quad = 1;
13401     __ vdivF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13402              MacroAssembler::VFA_SIZE_F32, quad);
13403   %}
13404 
13405   ins_pipe(fdivF_reg_reg); // FIXME
13406 #else
13407   size(4*4);
13408   ins_cost(DEFAULT_COST*4); // FIXME
13409 
13410   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
13411             "FDIVS  $dst.b,$src1.b,$src2.b\n\t"
13412             "FDIVS  $dst.c,$src1.c,$src2.c\n\t"
13413             "FDIVS  $dst.d,$src1.d,$src2.d" %}
13414 
13415   ins_encode %{
13416     FloatRegister dsta = $dst$$FloatRegister;
13417     FloatRegister src1a = $src1$$FloatRegister;
13418     FloatRegister src2a = $src2$$FloatRegister;
13419     __ div_float(dsta, src1a, src2a);
13420     FloatRegister dstb = dsta->successor();
13421     FloatRegister src1b = src1a->successor();
13422     FloatRegister src2b = src2a->successor();
13423     __ div_float(dstb, src1b, src2b);
13424     FloatRegister dstc = dstb->successor();
13425     FloatRegister src1c = src1b->successor();
13426     FloatRegister src2c = src2b->successor();
13427     __ div_float(dstc, src1c, src2c);
13428     FloatRegister dstd = dstc->successor();
13429     FloatRegister src1d = src1c->successor();
13430     FloatRegister src2d = src2c->successor();
13431     __ div_float(dstd, src1d, src2d);
13432   %}
13433 
13434   ins_pipe(fdivF_reg_reg); // FIXME
13435 #endif
13436 %}
13437 
13438 #ifdef AARCH64
13439 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{
13440   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
13441   match(Set dst (DivVD src1 src2));
13442   size(4*1);
13443   ins_cost(DEFAULT_COST*1); // FIXME
13444 
13445   format %{ "FDIV.2D $dst,$src1,$src2\t! double[2]" %}
13446   ins_encode %{
13447     int quad = 1;
13448     __ vdivF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13449              MacroAssembler::VFA_SIZE_F64, quad);
13450   %}
13451 
13452   ins_pipe(fdivF_reg_reg); // FIXME
13453 %}
13454 #else
13455 instruct vdiv2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
13456   predicate(n->as_Vector()->length() == 2);
13457   match(Set dst (DivVD src1 src2));
13458   size(4*2);
13459   ins_cost(DEFAULT_COST*2); // FIXME
13460 
13461   format %{ "FDIVD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
13462             "FDIVD  $dst.D.b,$src1.D.b,$src2.D.b" %}
13463   ins_encode %{
13464     FloatRegister dsta = $dst$$FloatRegister;
13465     FloatRegister src1a = $src1$$FloatRegister;
13466     FloatRegister src2a = $src2$$FloatRegister;
13467     __ div_double(dsta, src1a, src2a);
13468     FloatRegister dstb = dsta->successor()->successor();
13469     FloatRegister src1b = src1a->successor()->successor();
13470     FloatRegister src2b = src2a->successor()->successor();
13471     __ div_double(dstb, src1b, src2b);
13472   %}
13473 
13474   ins_pipe(fdivD_reg_reg); // FIXME
13475 %}
13476 #endif
13477 
13478 // --------------------------------- NEG --------------------------------------
13479 
13480 instruct vneg8B_reg(vecD dst, vecD src) %{
13481   predicate(n->as_Vector()->length_in_bytes() == 8);
13482   effect(DEF dst, USE src);
13483   size(4);
13484   ins_cost(DEFAULT_COST); // FIXME
13485   format %{ "VNEG.S8 $dst.D,$src.D\t! neg packed8B" %}
13486   ins_encode %{
13487     bool quad = false;
13488     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
13489               MacroAssembler::VELEM_SIZE_8, quad);
13490   %}
13491   ins_pipe( ialu_reg_reg ); // FIXME
13492 %}
13493 
13494 instruct vneg16B_reg(vecX dst, vecX src) %{
13495   predicate(n->as_Vector()->length_in_bytes() == 16);
13496   effect(DEF dst, USE src);
13497   size(4);
13498   ins_cost(DEFAULT_COST); // FIXME
13499   format %{ "VNEG.S8 $dst.Q,$src.Q\t! neg0 packed16B" %}
13500   ins_encode %{
13501     bool _float = false;
13502     bool quad = true;
13503     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
13504               MacroAssembler::VELEM_SIZE_8, quad);
13505   %}
13506   ins_pipe( ialu_reg_reg ); // FIXME
13507 %}
13508 
13509 // ------------------------------ Shift ---------------------------------------
13510 
13511 instruct vslcntD(vecD dst, iRegI cnt) %{
13512   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
13513   match(Set dst (LShiftCntV cnt));
13514   size(4);
13515   ins_cost(DEFAULT_COST); // FIXME
13516   expand %{
13517     Repl8B_reg_simd(dst, cnt);
13518   %}
13519 %}
13520 
13521 instruct vslcntX(vecX dst, iRegI cnt) %{
13522   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
13523   match(Set dst (LShiftCntV cnt));
13524   size(4);
13525   ins_cost(DEFAULT_COST); // FIXME
13526   expand %{
13527     Repl16B_reg(dst, cnt);
13528   %}
13529 %}
13530 
13531 // Low bits of vector "shift" elements are used, so it
13532 // doesn't matter if we treat it as ints or bytes here.
13533 instruct vsrcntD(vecD dst, iRegI cnt) %{
13534   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
13535   match(Set dst (RShiftCntV cnt));
13536   size(4*2);
13537   ins_cost(DEFAULT_COST*2); // FIXME
13538 
13539   format %{ "VDUP.8 $dst.D,$cnt\n\t"
13540             "VNEG.S8 $dst.D,$dst.D\t! neg packed8B" %}
13541   ins_encode %{
13542     bool quad = false;
13543     __ vdupI($dst$$FloatRegister, $cnt$$Register,
13544              MacroAssembler::VELEM_SIZE_8, quad);
13545     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
13546               MacroAssembler::VELEM_SIZE_8, quad);
13547   %}
13548   ins_pipe( ialu_reg_reg ); // FIXME
13549 %}
13550 
13551 instruct vsrcntX(vecX dst, iRegI cnt) %{
13552   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
13553   match(Set dst (RShiftCntV cnt));
13554   size(4*2);
13555   ins_cost(DEFAULT_COST*2); // FIXME
13556   format %{ "VDUP.8 $dst.Q,$cnt\n\t"
13557             "VNEG.S8 $dst.Q,$dst.Q\t! neg packed16B" %}
13558   ins_encode %{
13559     bool quad = true;
13560     __ vdupI($dst$$FloatRegister, $cnt$$Register,
13561              MacroAssembler::VELEM_SIZE_8, quad);
13562     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
13563               MacroAssembler::VELEM_SIZE_8, quad);
13564   %}
13565   ins_pipe( ialu_reg_reg ); // FIXME
13566 %}
13567 
13568 // Byte vector logical left/right shift based on sign
13569 instruct vsh8B_reg(vecD dst, vecD src, vecD shift) %{
13570   predicate(n->as_Vector()->length() == 8);
13571   effect(DEF dst, USE src, USE shift);
13572   size(4);
13573   ins_cost(DEFAULT_COST); // FIXME
13574   format %{
13575     "VSHL.U8 $dst.D,$src.D,$shift.D\t! logical left/right shift packed8B"
13576   %}
13577   ins_encode %{
13578     bool quad = false;
13579     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
13580               MacroAssembler::VELEM_SIZE_8, quad);
13581   %}
13582   ins_pipe( ialu_reg_reg ); // FIXME
13583 %}
13584 
13585 instruct vsh16B_reg(vecX dst, vecX src, vecX shift) %{
13586   predicate(n->as_Vector()->length() == 16);
13587   effect(DEF dst, USE src, USE shift);
13588   size(4);
13589   ins_cost(DEFAULT_COST); // FIXME
13590   format %{
13591     "VSHL.U8 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed16B"
13592   %}
13593   ins_encode %{
13594     bool quad = true;
13595     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
13596               MacroAssembler::VELEM_SIZE_8, quad);
13597   %}
13598   ins_pipe( ialu_reg_reg ); // FIXME
13599 %}
13600 
13601 // Shorts/Char vector logical left/right shift based on sign
13602 instruct vsh4S_reg(vecD dst, vecD src, vecD shift) %{
13603   predicate(n->as_Vector()->length() == 4);
13604   effect(DEF dst, USE src, USE shift);
13605   size(4);
13606   ins_cost(DEFAULT_COST); // FIXME
13607   format %{
13608     "VSHL.U16 $dst.D,$src.D,$shift.D\t! logical left/right shift packed4S"
13609   %}
13610   ins_encode %{
13611     bool quad = false;
13612     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
13613               MacroAssembler::VELEM_SIZE_16, quad);
13614   %}
13615   ins_pipe( ialu_reg_reg ); // FIXME
13616 %}
13617 
13618 instruct vsh8S_reg(vecX dst, vecX src, vecX shift) %{
13619   predicate(n->as_Vector()->length() == 8);
13620   effect(DEF dst, USE src, USE shift);
13621   size(4);
13622   ins_cost(DEFAULT_COST); // FIXME
13623   format %{
13624     "VSHL.U16 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed8S"
13625   %}
13626   ins_encode %{
13627     bool quad = true;
13628     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
13629               MacroAssembler::VELEM_SIZE_16, quad);
13630   %}
13631   ins_pipe( ialu_reg_reg ); // FIXME
13632 %}
13633 
13634 // Integers vector logical left/right shift based on sign
13635 instruct vsh2I_reg(vecD dst, vecD src, vecD shift) %{
13636   predicate(n->as_Vector()->length() == 2);
13637   effect(DEF dst, USE src, USE shift);
13638   size(4);
13639   ins_cost(DEFAULT_COST); // FIXME
13640   format %{
13641     "VSHL.U32 $dst.D,$src.D,$shift.D\t! logical left/right shift packed2I"
13642   %}
13643   ins_encode %{
13644     bool quad = false;
13645     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
13646               MacroAssembler::VELEM_SIZE_32, quad);
13647   %}
13648   ins_pipe( ialu_reg_reg ); // FIXME
13649 %}
13650 
13651 instruct vsh4I_reg(vecX dst, vecX src, vecX shift) %{
13652   predicate(n->as_Vector()->length() == 4);
13653   effect(DEF dst, USE src, USE shift);
13654   size(4);
13655   ins_cost(DEFAULT_COST); // FIXME
13656   format %{
13657     "VSHL.U32 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed4I"
13658   %}
13659   ins_encode %{
13660     bool quad = true;
13661     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
13662               MacroAssembler::VELEM_SIZE_32, quad);
13663   %}
13664   ins_pipe( ialu_reg_reg ); // FIXME
13665 %}
13666 
13667 // Longs vector logical left/right shift based on sign
13668 instruct vsh2L_reg(vecX dst, vecX src, vecX shift) %{
13669   predicate(n->as_Vector()->length() == 2);
13670   effect(DEF dst, USE src, USE shift);
13671   size(4);
13672   ins_cost(DEFAULT_COST); // FIXME
13673   format %{
13674     "VSHL.U64 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed2L"
13675   %}
13676   ins_encode %{
13677     bool quad = true;
13678     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
13679               MacroAssembler::VELEM_SIZE_64, quad);
13680   %}
13681   ins_pipe( ialu_reg_reg ); // FIXME
13682 %}
13683 
13684 // ------------------------------ LeftShift -----------------------------------
13685 
13686 // Byte vector left shift
13687 instruct vsl8B_reg(vecD dst, vecD src, vecD shift) %{
13688   predicate(n->as_Vector()->length() == 8);
13689   match(Set dst (LShiftVB src shift));
13690   size(4*1);
13691   ins_cost(DEFAULT_COST*1); // FIXME
13692   expand %{
13693     vsh8B_reg(dst, src, shift);
13694   %}
13695 %}
13696 
13697 instruct vsl16B_reg(vecX dst, vecX src, vecX shift) %{
13698   predicate(n->as_Vector()->length() == 16);
13699   match(Set dst (LShiftVB src shift));
13700   size(4*1);
13701   ins_cost(DEFAULT_COST*1); // FIXME
13702   expand %{
13703     vsh16B_reg(dst, src, shift);
13704   %}
13705 %}
13706 
13707 instruct vsl8B_immI(vecD dst, vecD src, immI shift) %{
13708   predicate(n->as_Vector()->length() == 8);
13709   match(Set dst (LShiftVB src shift));
13710   size(4);
13711   ins_cost(DEFAULT_COST); // FIXME
13712   format %{
13713     "VSHL.I8 $dst.D,$src.D,$shift\t! logical left shift packed8B"
13714   %}
13715   ins_encode %{
13716     bool quad = false;
13717     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
13718              quad);
13719   %}
13720   ins_pipe( ialu_reg_reg ); // FIXME
13721 %}
13722 
13723 instruct vsl16B_immI(vecX dst, vecX src, immI shift) %{
13724   predicate(n->as_Vector()->length() == 16);
13725   match(Set dst (LShiftVB src shift));
13726   size(4);
13727   ins_cost(DEFAULT_COST); // FIXME
13728   format %{
13729     "VSHL.I8 $dst.Q,$src.Q,$shift\t! logical left shift packed16B"
13730   %}
13731   ins_encode %{
13732     bool quad = true;
13733     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
13734              quad);
13735   %}
13736   ins_pipe( ialu_reg_reg ); // FIXME
13737 %}
13738 
13739 // Shorts/Chars vector logical left/right shift
13740 instruct vsl4S_reg(vecD dst, vecD src, vecD shift) %{
13741   predicate(n->as_Vector()->length() == 4);
13742   match(Set dst (LShiftVS src shift));
13743   match(Set dst (URShiftVS src shift));
13744   size(4*1);
13745   ins_cost(DEFAULT_COST*1); // FIXME
13746   expand %{
13747     vsh4S_reg(dst, src, shift);
13748   %}
13749 %}
13750 
13751 instruct vsl8S_reg(vecX dst, vecX src, vecX shift) %{
13752   predicate(n->as_Vector()->length() == 8);
13753   match(Set dst (LShiftVS src shift));
13754   match(Set dst (URShiftVS src shift));
13755   size(4*1);
13756   ins_cost(DEFAULT_COST*1); // FIXME
13757   expand %{
13758     vsh8S_reg(dst, src, shift);
13759   %}
13760 %}
13761 
13762 instruct vsl4S_immI(vecD dst, vecD src, immI shift) %{
13763   predicate(n->as_Vector()->length() == 4);
13764   match(Set dst (LShiftVS src shift));
13765   size(4);
13766   ins_cost(DEFAULT_COST); // FIXME
13767   format %{
13768     "VSHL.I16 $dst.D,$src.D,$shift\t! logical left shift packed4S"
13769   %}
13770   ins_encode %{
13771     bool quad = false;
13772     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
13773              quad);
13774   %}
13775   ins_pipe( ialu_reg_reg ); // FIXME
13776 %}
13777 
13778 instruct vsl8S_immI(vecX dst, vecX src, immI shift) %{
13779   predicate(n->as_Vector()->length() == 8);
13780   match(Set dst (LShiftVS src shift));
13781   size(4);
13782   ins_cost(DEFAULT_COST); // FIXME
13783   format %{
13784     "VSHL.I16 $dst.Q,$src.Q,$shift\t! logical left shift packed8S"
13785   %}
13786   ins_encode %{
13787     bool quad = true;
13788     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
13789              quad);
13790   %}
13791   ins_pipe( ialu_reg_reg ); // FIXME
13792 %}
13793 
13794 // Integers vector logical left/right shift
13795 instruct vsl2I_reg(vecD dst, vecD src, vecD shift) %{
13796   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
13797   match(Set dst (LShiftVI src shift));
13798   match(Set dst (URShiftVI src shift));
13799   size(4*1);
13800   ins_cost(DEFAULT_COST*1); // FIXME
13801   expand %{
13802     vsh2I_reg(dst, src, shift);
13803   %}
13804 %}
13805 
13806 instruct vsl4I_reg(vecX dst, vecX src, vecX shift) %{
13807   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
13808   match(Set dst (LShiftVI src shift));
13809   match(Set dst (URShiftVI src shift));
13810   size(4*1);
13811   ins_cost(DEFAULT_COST*1); // FIXME
13812   expand %{
13813     vsh4I_reg(dst, src, shift);
13814   %}
13815 %}
13816 
13817 instruct vsl2I_immI(vecD dst, vecD src, immI shift) %{
13818   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
13819   match(Set dst (LShiftVI src shift));
13820   size(4);
13821   ins_cost(DEFAULT_COST); // FIXME
13822   format %{
13823     "VSHL.I32 $dst.D,$src.D,$shift\t! logical left shift packed2I"
13824   %}
13825   ins_encode %{
13826     bool quad = false;
13827     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
13828              quad);
13829   %}
13830   ins_pipe( ialu_reg_reg ); // FIXME
13831 %}
13832 
13833 instruct vsl4I_immI(vecX dst, vecX src, immI shift) %{
13834   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
13835   match(Set dst (LShiftVI src shift));
13836   size(4);
13837   ins_cost(DEFAULT_COST); // FIXME
13838   format %{
13839     "VSHL.I32 $dst.Q,$src.Q,$shift\t! logical left shift packed4I"
13840   %}
13841   ins_encode %{
13842     bool quad = true;
13843     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
13844              quad);
13845   %}
13846   ins_pipe( ialu_reg_reg ); // FIXME
13847 %}
13848 
13849 // Longs vector logical left/right shift
13850 instruct vsl2L_reg(vecX dst, vecX src, vecX shift) %{
13851   predicate(n->as_Vector()->length() == 2);
13852   match(Set dst (LShiftVL src shift));
13853   match(Set dst (URShiftVL src shift));
13854   size(4*1);
13855   ins_cost(DEFAULT_COST*1); // FIXME
13856   expand %{
13857     vsh2L_reg(dst, src, shift);
13858   %}
13859 %}
13860 
13861 instruct vsl2L_immI(vecX dst, vecX src, immI shift) %{
13862   predicate(n->as_Vector()->length() == 2);
13863   match(Set dst (LShiftVL src shift));
13864   size(4);
13865   ins_cost(DEFAULT_COST); // FIXME
13866   format %{
13867     "VSHL.I64 $dst.Q,$src.Q,$shift\t! logical left shift packed2L"
13868   %}
13869   ins_encode %{
13870     bool quad = true;
13871     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
13872              quad);
13873   %}
13874   ins_pipe( ialu_reg_reg ); // FIXME
13875 %}
13876 
13877 // ----------------------- LogicalRightShift -----------------------------------
13878 
13879 // Bytes/Shorts vector logical right shift produces incorrect Java result
13880 // for negative data because java code convert short value into int with
13881 // sign extension before a shift.
13882 
13883 // Chars vector logical right shift
13884 instruct vsrl4S_immI(vecD dst, vecD src, immI shift) %{
13885   predicate(n->as_Vector()->length() == 4);
13886   match(Set dst (URShiftVS src shift));
13887   size(4);
13888   ins_cost(DEFAULT_COST); // FIXME
13889   format %{
13890     "VSHR.U16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
13891   %}
13892   ins_encode %{
13893     bool quad = false;
13894     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
13895              quad);
13896   %}
13897   ins_pipe( ialu_reg_reg ); // FIXME
13898 %}
13899 
13900 instruct vsrl8S_immI(vecX dst, vecX src, immI shift) %{
13901   predicate(n->as_Vector()->length() == 8);
13902   match(Set dst (URShiftVS src shift));
13903   size(4);
13904   ins_cost(DEFAULT_COST); // FIXME
13905   format %{
13906     "VSHR.U16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
13907   %}
13908   ins_encode %{
13909     bool quad = true;
13910     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
13911              quad);
13912   %}
13913   ins_pipe( ialu_reg_reg ); // FIXME
13914 %}
13915 
13916 // Integers vector logical right shift
13917 instruct vsrl2I_immI(vecD dst, vecD src, immI shift) %{
13918   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
13919   match(Set dst (URShiftVI src shift));
13920   size(4);
13921   ins_cost(DEFAULT_COST); // FIXME
13922   format %{
13923     "VSHR.U32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
13924   %}
13925   ins_encode %{
13926     bool quad = false;
13927     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
13928              quad);
13929   %}
13930   ins_pipe( ialu_reg_reg ); // FIXME
13931 %}
13932 
13933 instruct vsrl4I_immI(vecX dst, vecX src, immI shift) %{
13934   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
13935   match(Set dst (URShiftVI src shift));
13936   size(4);
13937   ins_cost(DEFAULT_COST); // FIXME
13938   format %{
13939     "VSHR.U32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
13940   %}
13941   ins_encode %{
13942     bool quad = true;
13943     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
13944              quad);
13945   %}
13946   ins_pipe( ialu_reg_reg ); // FIXME
13947 %}
13948 
13949 // Longs vector logical right shift
13950 instruct vsrl2L_immI(vecX dst, vecX src, immI shift) %{
13951   predicate(n->as_Vector()->length() == 2);
13952   match(Set dst (URShiftVL src shift));
13953   size(4);
13954   ins_cost(DEFAULT_COST); // FIXME
13955   format %{
13956     "VSHR.U64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
13957   %}
13958   ins_encode %{
13959     bool quad = true;
13960     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
13961              quad);
13962   %}
13963   ins_pipe( ialu_reg_reg ); // FIXME
13964 %}
13965 
13966 // ------------------- ArithmeticRightShift -----------------------------------
13967 
13968 // Bytes vector arithmetic left/right shift based on sign
13969 instruct vsha8B_reg(vecD dst, vecD src, vecD shift) %{
13970   predicate(n->as_Vector()->length() == 8);
13971   effect(DEF dst, USE src, USE shift);
13972   size(4);
13973   ins_cost(DEFAULT_COST); // FIXME
13974   format %{
13975     "VSHL.S8 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed8B"
13976   %}
13977   ins_encode %{
13978     bool quad = false;
13979     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
13980               MacroAssembler::VELEM_SIZE_8, quad);
13981   %}
13982   ins_pipe( ialu_reg_reg ); // FIXME
13983 %}
13984 
13985 instruct vsha16B_reg(vecX dst, vecX src, vecX shift) %{
13986   predicate(n->as_Vector()->length() == 16);
13987   effect(DEF dst, USE src, USE shift);
13988   size(4);
13989   ins_cost(DEFAULT_COST); // FIXME
13990   format %{
13991     "VSHL.S8 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed16B"
13992   %}
13993   ins_encode %{
13994     bool quad = true;
13995     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
13996               MacroAssembler::VELEM_SIZE_8, quad);
13997   %}
13998   ins_pipe( ialu_reg_reg ); // FIXME
13999 %}
14000 
14001 // Shorts vector arithmetic left/right shift based on sign
14002 instruct vsha4S_reg(vecD dst, vecD src, vecD shift) %{
14003   predicate(n->as_Vector()->length() == 4);
14004   effect(DEF dst, USE src, USE shift);
14005   size(4);
14006   ins_cost(DEFAULT_COST); // FIXME
14007   format %{
14008     "VSHL.S16 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed4S"
14009   %}
14010   ins_encode %{
14011     bool quad = false;
14012     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
14013               MacroAssembler::VELEM_SIZE_16, quad);
14014   %}
14015   ins_pipe( ialu_reg_reg ); // FIXME
14016 %}
14017 
14018 instruct vsha8S_reg(vecX dst, vecX src, vecX shift) %{
14019   predicate(n->as_Vector()->length() == 8);
14020   effect(DEF dst, USE src, USE shift);
14021   size(4);
14022   ins_cost(DEFAULT_COST); // FIXME
14023   format %{
14024     "VSHL.S16 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed8S"
14025   %}
14026   ins_encode %{
14027     bool quad = true;
14028     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
14029               MacroAssembler::VELEM_SIZE_16, quad);
14030   %}
14031   ins_pipe( ialu_reg_reg ); // FIXME
14032 %}
14033 
14034 // Integers vector arithmetic left/right shift based on sign
14035 instruct vsha2I_reg(vecD dst, vecD src, vecD shift) %{
14036   predicate(n->as_Vector()->length() == 2);
14037   effect(DEF dst, USE src, USE shift);
14038   size(4);
14039   ins_cost(DEFAULT_COST); // FIXME
14040   format %{
14041     "VSHL.S32 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed2I"
14042   %}
14043   ins_encode %{
14044     bool quad = false;
14045     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
14046               MacroAssembler::VELEM_SIZE_32, quad);
14047   %}
14048   ins_pipe( ialu_reg_reg ); // FIXME
14049 %}
14050 
14051 instruct vsha4I_reg(vecX dst, vecX src, vecX shift) %{
14052   predicate(n->as_Vector()->length() == 4);
14053   effect(DEF dst, USE src, USE shift);
14054   size(4);
14055   ins_cost(DEFAULT_COST); // FIXME
14056   format %{
14057     "VSHL.S32 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed4I"
14058   %}
14059   ins_encode %{
14060     bool quad = true;
14061     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
14062               MacroAssembler::VELEM_SIZE_32, quad);
14063   %}
14064   ins_pipe( ialu_reg_reg ); // FIXME
14065 %}
14066 
14067 // Longs vector arithmetic left/right shift based on sign
14068 instruct vsha2L_reg(vecX dst, vecX src, vecX shift) %{
14069   predicate(n->as_Vector()->length() == 2);
14070   effect(DEF dst, USE src, USE shift);
14071   size(4);
14072   ins_cost(DEFAULT_COST); // FIXME
14073   format %{
14074     "VSHL.S64 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed2L"
14075   %}
14076   ins_encode %{
14077     bool quad = true;
14078     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
14079               MacroAssembler::VELEM_SIZE_64, quad);
14080   %}
14081   ins_pipe( ialu_reg_reg ); // FIXME
14082 %}
14083 
14084 // Byte vector arithmetic right shift
14085 
14086 instruct vsra8B_reg(vecD dst, vecD src, vecD shift) %{
14087   predicate(n->as_Vector()->length() == 8);
14088   match(Set dst (RShiftVB src shift));
14089   size(4);
14090   ins_cost(DEFAULT_COST); // FIXME
14091   expand %{
14092     vsha8B_reg(dst, src, shift);
14093   %}
14094 %}
14095 
14096 instruct vsrl16B_reg(vecX dst, vecX src, vecX shift) %{
14097   predicate(n->as_Vector()->length() == 16);
14098   match(Set dst (RShiftVB src shift));
14099   size(4);
14100   ins_cost(DEFAULT_COST); // FIXME
14101   expand %{
14102     vsha16B_reg(dst, src, shift);
14103   %}
14104 %}
14105 
14106 instruct vsrl8B_immI(vecD dst, vecD src, immI shift) %{
14107   predicate(n->as_Vector()->length() == 8);
14108   match(Set dst (RShiftVB src shift));
14109   size(4);
14110   ins_cost(DEFAULT_COST); // FIXME
14111   format %{
14112     "VSHR.S8 $dst.D,$src.D,$shift\t! logical right shift packed8B"
14113   %}
14114   ins_encode %{
14115     bool quad = false;
14116     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
14117              quad);
14118   %}
14119   ins_pipe( ialu_reg_reg ); // FIXME
14120 %}
14121 
14122 instruct vsrl16B_immI(vecX dst, vecX src, immI shift) %{
14123   predicate(n->as_Vector()->length() == 16);
14124   match(Set dst (RShiftVB src shift));
14125   size(4);
14126   ins_cost(DEFAULT_COST); // FIXME
14127   format %{
14128     "VSHR.S8 $dst.Q,$src.Q,$shift\t! logical right shift packed16B"
14129   %}
14130   ins_encode %{
14131     bool quad = true;
14132     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
14133              quad);
14134   %}
14135   ins_pipe( ialu_reg_reg ); // FIXME
14136 %}
14137 
14138 // Shorts vector arithmetic right shift
14139 instruct vsra4S_reg(vecD dst, vecD src, vecD shift) %{
14140   predicate(n->as_Vector()->length() == 4);
14141   match(Set dst (RShiftVS src shift));
14142   size(4);
14143   ins_cost(DEFAULT_COST); // FIXME
14144   expand %{
14145     vsha4S_reg(dst, src, shift);
14146   %}
14147 %}
14148 
14149 instruct vsra8S_reg(vecX dst, vecX src, vecX shift) %{
14150   predicate(n->as_Vector()->length() == 8);
14151   match(Set dst (RShiftVS src shift));
14152   size(4);
14153   ins_cost(DEFAULT_COST); // FIXME
14154   expand %{
14155     vsha8S_reg(dst, src, shift);
14156   %}
14157 %}
14158 
14159 instruct vsra4S_immI(vecD dst, vecD src, immI shift) %{
14160   predicate(n->as_Vector()->length() == 4);
14161   match(Set dst (RShiftVS src shift));
14162   size(4);
14163   ins_cost(DEFAULT_COST); // FIXME
14164   format %{
14165     "VSHR.S16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
14166   %}
14167   ins_encode %{
14168     bool quad = false;
14169     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
14170              quad);
14171   %}
14172   ins_pipe( ialu_reg_reg ); // FIXME
14173 %}
14174 
14175 instruct vsra8S_immI(vecX dst, vecX src, immI shift) %{
14176   predicate(n->as_Vector()->length() == 8);
14177   match(Set dst (RShiftVS src shift));
14178   size(4);
14179   ins_cost(DEFAULT_COST); // FIXME
14180   format %{
14181     "VSHR.S16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
14182   %}
14183   ins_encode %{
14184     bool quad = true;
14185     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
14186              quad);
14187   %}
14188   ins_pipe( ialu_reg_reg ); // FIXME
14189 %}
14190 
14191 // Integers vector arithmetic right shift
14192 instruct vsra2I_reg(vecD dst, vecD src, vecD shift) %{
14193   predicate(n->as_Vector()->length() == 2);
14194   match(Set dst (RShiftVI src shift));
14195   size(4);
14196   ins_cost(DEFAULT_COST); // FIXME
14197   expand %{
14198     vsha2I_reg(dst, src, shift);
14199   %}
14200 %}
14201 
14202 instruct vsra4I_reg(vecX dst, vecX src, vecX shift) %{
14203   predicate(n->as_Vector()->length() == 4);
14204   match(Set dst (RShiftVI src shift));
14205   size(4);
14206   ins_cost(DEFAULT_COST); // FIXME
14207   expand %{
14208     vsha4I_reg(dst, src, shift);
14209   %}
14210 %}
14211 
14212 instruct vsra2I_immI(vecD dst, vecD src, immI shift) %{
14213   predicate(n->as_Vector()->length() == 2);
14214   match(Set dst (RShiftVI src shift));
14215   size(4);
14216   ins_cost(DEFAULT_COST); // FIXME
14217   format %{
14218     "VSHR.S32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
14219   %}
14220   ins_encode %{
14221     bool quad = false;
14222     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
14223              quad);
14224   %}
14225   ins_pipe( ialu_reg_reg ); // FIXME
14226 %}
14227 
14228 instruct vsra4I_immI(vecX dst, vecX src, immI shift) %{
14229   predicate(n->as_Vector()->length() == 4);
14230   match(Set dst (RShiftVI src shift));
14231   size(4);
14232   ins_cost(DEFAULT_COST); // FIXME
14233   format %{
14234     "VSHR.S32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
14235   %}
14236   ins_encode %{
14237     bool quad = true;
14238     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
14239              quad);
14240   %}
14241   ins_pipe( ialu_reg_reg ); // FIXME
14242 %}
14243 
14244 // Longs vector arithmetic right shift
14245 instruct vsra2L_reg(vecX dst, vecX src, vecX shift) %{
14246   predicate(n->as_Vector()->length() == 2);
14247   match(Set dst (RShiftVL src shift));
14248   size(4);
14249   ins_cost(DEFAULT_COST); // FIXME
14250   expand %{
14251     vsha2L_reg(dst, src, shift);
14252   %}
14253 %}
14254 
14255 instruct vsra2L_immI(vecX dst, vecX src, immI shift) %{
14256   predicate(n->as_Vector()->length() == 2);
14257   match(Set dst (RShiftVL src shift));
14258   size(4);
14259   ins_cost(DEFAULT_COST); // FIXME
14260   format %{
14261     "VSHR.S64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
14262   %}
14263   ins_encode %{
14264     bool quad = true;
14265     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
14266              quad);
14267   %}
14268   ins_pipe( ialu_reg_reg ); // FIXME
14269 %}
14270 
14271 // --------------------------------- AND --------------------------------------
14272 
14273 instruct vandD(vecD dst, vecD src1, vecD src2) %{
14274   predicate(n->as_Vector()->length_in_bytes() == 8);
14275   match(Set dst (AndV src1 src2));
14276   format %{ "VAND    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
14277   ins_encode %{
14278     bool quad = false;
14279     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
14280              quad);
14281   %}
14282   ins_pipe( ialu_reg_reg ); // FIXME
14283 %}
14284 
14285 instruct vandX(vecX dst, vecX src1, vecX src2) %{
14286   predicate(n->as_Vector()->length_in_bytes() == 16);
14287   match(Set dst (AndV src1 src2));
14288   format %{ "VAND    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
14289   ins_encode %{
14290     bool quad = true;
14291     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
14292              quad);
14293   %}
14294   ins_pipe( ialu_reg_reg ); // FIXME
14295 %}
14296 
14297 // --------------------------------- OR ---------------------------------------
14298 
14299 instruct vorD(vecD dst, vecD src1, vecD src2) %{
14300   predicate(n->as_Vector()->length_in_bytes() == 8);
14301   match(Set dst (OrV src1 src2));
14302   format %{ "VOR     $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
14303   ins_encode %{
14304     bool quad = false;
14305     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
14306             quad);
14307   %}
14308   ins_pipe( ialu_reg_reg ); // FIXME
14309 %}
14310 
14311 instruct vorX(vecX dst, vecX src1, vecX src2) %{
14312   predicate(n->as_Vector()->length_in_bytes() == 16);
14313   match(Set dst (OrV src1 src2));
14314   format %{ "VOR     $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
14315   ins_encode %{
14316     bool quad = true;
14317     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
14318             quad);
14319   %}
14320   ins_pipe( ialu_reg_reg ); // FIXME
14321 %}
14322 
14323 // --------------------------------- XOR --------------------------------------
14324 
14325 instruct vxorD(vecD dst, vecD src1, vecD src2) %{
14326   predicate(n->as_Vector()->length_in_bytes() == 8);
14327   match(Set dst (XorV src1 src2));
14328   format %{ "VXOR    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
14329   ins_encode %{
14330     bool quad = false;
14331     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
14332              quad);
14333   %}
14334   ins_pipe( ialu_reg_reg ); // FIXME
14335 %}
14336 
14337 instruct vxorX(vecX dst, vecX src1, vecX src2) %{
14338   predicate(n->as_Vector()->length_in_bytes() == 16);
14339   match(Set dst (XorV src1 src2));
14340   format %{ "VXOR    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
14341   ins_encode %{
14342     bool quad = true;
14343     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
14344              quad);
14345   %}
14346   ins_pipe( ialu_reg_reg ); // FIXME
14347 %}
14348 
14349 
14350 //----------PEEPHOLE RULES-----------------------------------------------------
14351 // These must follow all instruction definitions as they use the names
14352 // defined in the instructions definitions.
14353 //
14354 // peepmatch ( root_instr_name [preceding_instruction]* );
14355 //
14356 // peepconstraint %{
14357 // (instruction_number.operand_name relational_op instruction_number.operand_name
14358 //  [, ...] );
14359 // // instruction numbers are zero-based using left to right order in peepmatch
14360 //
14361 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
14362 // // provide an instruction_number.operand_name for each operand that appears
14363 // // in the replacement instruction's match rule
14364 //
14365 // ---------VM FLAGS---------------------------------------------------------
14366 //
14367 // All peephole optimizations can be turned off using -XX:-OptoPeephole
14368 //
14369 // Each peephole rule is given an identifying number starting with zero and
14370 // increasing by one in the order seen by the parser.  An individual peephole
14371 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
14372 // on the command-line.
14373 //
14374 // ---------CURRENT LIMITATIONS----------------------------------------------
14375 //
14376 // Only match adjacent instructions in same basic block
14377 // Only equality constraints
14378 // Only constraints between operands, not (0.dest_reg == EAX_enc)
14379 // Only one replacement instruction
14380 //
14381 // ---------EXAMPLE----------------------------------------------------------
14382 //
14383 // // pertinent parts of existing instructions in architecture description
14384 // instruct movI(eRegI dst, eRegI src) %{
14385 //   match(Set dst (CopyI src));
14386 // %}
14387 //
14388 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
14389 //   match(Set dst (AddI dst src));
14390 //   effect(KILL cr);
14391 // %}
14392 //
14393 // // Change (inc mov) to lea
14394 // peephole %{
14395 //   // increment preceeded by register-register move
14396 //   peepmatch ( incI_eReg movI );
14397 //   // require that the destination register of the increment
14398 //   // match the destination register of the move
14399 //   peepconstraint ( 0.dst == 1.dst );
14400 //   // construct a replacement instruction that sets
14401 //   // the destination to ( move's source register + one )
14402 //   peepreplace ( incI_eReg_immI1( 0.dst 1.src 0.src ) );
14403 // %}
14404 //
14405 
14406 // // Change load of spilled value to only a spill
14407 // instruct storeI(memory mem, eRegI src) %{
14408 //   match(Set mem (StoreI mem src));
14409 // %}
14410 //
14411 // instruct loadI(eRegI dst, memory mem) %{
14412 //   match(Set dst (LoadI mem));
14413 // %}
14414 //
14415 // peephole %{
14416 //   peepmatch ( loadI storeI );
14417 //   peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14418 //   peepreplace ( storeI( 1.mem 1.mem 1.src ) );
14419 // %}
14420 
14421 //----------SMARTSPILL RULES---------------------------------------------------
14422 // These must follow all instruction definitions as they use the names
14423 // defined in the instructions definitions.
14424 //
14425 // ARM will probably not have any of these rules due to RISC instruction set.
14426 
14427 //----------PIPELINE-----------------------------------------------------------
14428 // Rules which define the behavior of the target architectures pipeline.