1 //
   2 // Copyright (c) 2008, 2018, 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 uint 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 uint 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 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 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               align_up((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 
2699 operand flagsRegUL_LTGE() %{
2700   constraint(ALLOC_IN_RC(int_flags));
2701   match(RegFlags);
2702 
2703   format %{ "apsr_UL_LTGE" %}
2704   interface(REG_INTER);
2705 %}
2706 
2707 operand flagsRegUL_EQNE() %{
2708   constraint(ALLOC_IN_RC(int_flags));
2709   match(RegFlags);
2710 
2711   format %{ "apsr_UL_EQNE" %}
2712   interface(REG_INTER);
2713 %}
2714 
2715 operand flagsRegUL_LEGT() %{
2716   constraint(ALLOC_IN_RC(int_flags));
2717   match(RegFlags);
2718 
2719   format %{ "apsr_UL_LEGT" %}
2720   interface(REG_INTER);
2721 %}
2722 #endif
2723 
2724 // Condition Code Register, floating comparisons, unordered same as "less".
2725 operand flagsRegF() %{
2726   constraint(ALLOC_IN_RC(float_flags));
2727   match(RegFlags);
2728 
2729   format %{ "fpscr_F" %}
2730   interface(REG_INTER);
2731 %}
2732 
2733 // Vectors
2734 operand vecD() %{
2735   constraint(ALLOC_IN_RC(actual_dflt_reg));
2736   match(VecD);
2737 
2738   format %{ %}
2739   interface(REG_INTER);
2740 %}
2741 
2742 operand vecX() %{
2743   constraint(ALLOC_IN_RC(vectorx_reg));
2744   match(VecX);
2745 
2746   format %{ %}
2747   interface(REG_INTER);
2748 %}
2749 
2750 operand regD() %{
2751   constraint(ALLOC_IN_RC(actual_dflt_reg));
2752   match(RegD);
2753   match(regD_low);
2754 
2755   format %{ %}
2756   interface(REG_INTER);
2757 %}
2758 
2759 operand regF() %{
2760   constraint(ALLOC_IN_RC(sflt_reg));
2761   match(RegF);
2762 
2763   format %{ %}
2764   interface(REG_INTER);
2765 %}
2766 
2767 operand regD_low() %{
2768   constraint(ALLOC_IN_RC(dflt_low_reg));
2769   match(RegD);
2770 
2771   format %{ %}
2772   interface(REG_INTER);
2773 %}
2774 
2775 // Special Registers
2776 
2777 // Method Register
2778 operand inline_cache_regP(iRegP reg) %{
2779   constraint(ALLOC_IN_RC(Ricklass_regP));
2780   match(reg);
2781   format %{ %}
2782   interface(REG_INTER);
2783 %}
2784 
2785 operand interpreter_method_oop_regP(iRegP reg) %{
2786   constraint(ALLOC_IN_RC(Rmethod_regP));
2787   match(reg);
2788   format %{ %}
2789   interface(REG_INTER);
2790 %}
2791 
2792 
2793 //----------Complex Operands---------------------------------------------------
2794 // Indirect Memory Reference
2795 operand indirect(sp_ptr_RegP reg) %{
2796   constraint(ALLOC_IN_RC(sp_ptr_reg));
2797   match(reg);
2798 
2799   op_cost(100);
2800   format %{ "[$reg]" %}
2801   interface(MEMORY_INTER) %{
2802     base($reg);
2803 #ifdef AARCH64
2804     index(0xff); // 0xff => no index
2805 #else
2806     index(0xf); // PC => no index
2807 #endif
2808     scale(0x0);
2809     disp(0x0);
2810   %}
2811 %}
2812 
2813 #ifdef AARCH64
2814 // Indirect with scaled*1 uimm12 offset
2815 operand indOffsetU12ScaleB(sp_ptr_RegP reg, immUL12 offset) %{
2816   constraint(ALLOC_IN_RC(sp_ptr_reg));
2817   match(AddP reg offset);
2818 
2819   op_cost(100);
2820   format %{ "[$reg + $offset]" %}
2821   interface(MEMORY_INTER) %{
2822     base($reg);
2823 #ifdef AARCH64
2824     index(0xff); // 0xff => no index
2825 #else
2826     index(0xf); // PC => no index
2827 #endif
2828     scale(0x0);
2829     disp($offset);
2830   %}
2831 %}
2832 
2833 // Indirect with scaled*2 uimm12 offset
2834 operand indOffsetU12ScaleS(sp_ptr_RegP reg, immUL12x2 offset) %{
2835   constraint(ALLOC_IN_RC(sp_ptr_reg));
2836   match(AddP reg offset);
2837 
2838   op_cost(100);
2839   format %{ "[$reg + $offset]" %}
2840   interface(MEMORY_INTER) %{
2841     base($reg);
2842 #ifdef AARCH64
2843     index(0xff); // 0xff => no index
2844 #else
2845     index(0xf); // PC => no index
2846 #endif
2847     scale(0x0);
2848     disp($offset);
2849   %}
2850 %}
2851 
2852 // Indirect with scaled*4 uimm12 offset
2853 operand indOffsetU12ScaleI(sp_ptr_RegP reg, immUL12x4 offset) %{
2854   constraint(ALLOC_IN_RC(sp_ptr_reg));
2855   match(AddP reg offset);
2856 
2857   op_cost(100);
2858   format %{ "[$reg + $offset]" %}
2859   interface(MEMORY_INTER) %{
2860     base($reg);
2861 #ifdef AARCH64
2862     index(0xff); // 0xff => no index
2863 #else
2864     index(0xf); // PC => no index
2865 #endif
2866     scale(0x0);
2867     disp($offset);
2868   %}
2869 %}
2870 
2871 // Indirect with scaled*8 uimm12 offset
2872 operand indOffsetU12ScaleL(sp_ptr_RegP reg, immUL12x8 offset) %{
2873   constraint(ALLOC_IN_RC(sp_ptr_reg));
2874   match(AddP reg offset);
2875 
2876   op_cost(100);
2877   format %{ "[$reg + $offset]" %}
2878   interface(MEMORY_INTER) %{
2879     base($reg);
2880 #ifdef AARCH64
2881     index(0xff); // 0xff => no index
2882 #else
2883     index(0xf); // PC => no index
2884 #endif
2885     scale(0x0);
2886     disp($offset);
2887   %}
2888 %}
2889 
2890 // Indirect with scaled*16 uimm12 offset
2891 operand indOffsetU12ScaleQ(sp_ptr_RegP reg, immUL12x16 offset) %{
2892   constraint(ALLOC_IN_RC(sp_ptr_reg));
2893   match(AddP reg offset);
2894 
2895   op_cost(100);
2896   format %{ "[$reg + $offset]" %}
2897   interface(MEMORY_INTER) %{
2898     base($reg);
2899 #ifdef AARCH64
2900     index(0xff); // 0xff => no index
2901 #else
2902     index(0xf); // PC => no index
2903 #endif
2904     scale(0x0);
2905     disp($offset);
2906   %}
2907 %}
2908 
2909 #else // ! AARCH64
2910 
2911 // Indirect with Offset in ]-4096, 4096[
2912 operand indOffset12(sp_ptr_RegP reg, immI12 offset) %{
2913   constraint(ALLOC_IN_RC(sp_ptr_reg));
2914   match(AddP reg offset);
2915 
2916   op_cost(100);
2917   format %{ "[$reg + $offset]" %}
2918   interface(MEMORY_INTER) %{
2919     base($reg);
2920 #ifdef AARCH64
2921     index(0xff); // 0xff => no index
2922 #else
2923     index(0xf); // PC => no index
2924 #endif
2925     scale(0x0);
2926     disp($offset);
2927   %}
2928 %}
2929 
2930 // Indirect with offset for float load/store
2931 operand indOffsetFP(sp_ptr_RegP reg, immIFP offset) %{
2932   constraint(ALLOC_IN_RC(sp_ptr_reg));
2933   match(AddP reg offset);
2934 
2935   op_cost(100);
2936   format %{ "[$reg + $offset]" %}
2937   interface(MEMORY_INTER) %{
2938     base($reg);
2939 #ifdef AARCH64
2940     index(0xff); // 0xff => no index
2941 #else
2942     index(0xf); // PC => no index
2943 #endif
2944     scale(0x0);
2945     disp($offset);
2946   %}
2947 %}
2948 
2949 // Indirect with Offset for half and double words
2950 operand indOffsetHD(sp_ptr_RegP reg, immIHD offset) %{
2951   constraint(ALLOC_IN_RC(sp_ptr_reg));
2952   match(AddP reg offset);
2953 
2954   op_cost(100);
2955   format %{ "[$reg + $offset]" %}
2956   interface(MEMORY_INTER) %{
2957     base($reg);
2958 #ifdef AARCH64
2959     index(0xff); // 0xff => no index
2960 #else
2961     index(0xf); // PC => no index
2962 #endif
2963     scale(0x0);
2964     disp($offset);
2965   %}
2966 %}
2967 
2968 // Indirect with Offset and Offset+4 in ]-1024, 1024[
2969 operand indOffsetFPx2(sp_ptr_RegP reg, immX10x2 offset) %{
2970   constraint(ALLOC_IN_RC(sp_ptr_reg));
2971   match(AddP reg offset);
2972 
2973   op_cost(100);
2974   format %{ "[$reg + $offset]" %}
2975   interface(MEMORY_INTER) %{
2976     base($reg);
2977 #ifdef AARCH64
2978     index(0xff); // 0xff => no index
2979 #else
2980     index(0xf); // PC => no index
2981 #endif
2982     scale(0x0);
2983     disp($offset);
2984   %}
2985 %}
2986 
2987 // Indirect with Offset and Offset+4 in ]-4096, 4096[
2988 operand indOffset12x2(sp_ptr_RegP reg, immI12x2 offset) %{
2989   constraint(ALLOC_IN_RC(sp_ptr_reg));
2990   match(AddP reg offset);
2991 
2992   op_cost(100);
2993   format %{ "[$reg + $offset]" %}
2994   interface(MEMORY_INTER) %{
2995     base($reg);
2996 #ifdef AARCH64
2997     index(0xff); // 0xff => no index
2998 #else
2999     index(0xf); // PC => no index
3000 #endif
3001     scale(0x0);
3002     disp($offset);
3003   %}
3004 %}
3005 #endif // !AARCH64
3006 
3007 // Indirect with Register Index
3008 operand indIndex(iRegP addr, iRegX index) %{
3009   constraint(ALLOC_IN_RC(ptr_reg));
3010   match(AddP addr index);
3011 
3012   op_cost(100);
3013   format %{ "[$addr + $index]" %}
3014   interface(MEMORY_INTER) %{
3015     base($addr);
3016     index($index);
3017     scale(0x0);
3018     disp(0x0);
3019   %}
3020 %}
3021 
3022 #ifdef AARCH64
3023 // Indirect Memory Times Scale Plus Index Register
3024 operand indIndexScaleS(iRegP addr, iRegX index, immI_1 scale) %{
3025   constraint(ALLOC_IN_RC(ptr_reg));
3026   match(AddP addr (LShiftX index scale));
3027 
3028   op_cost(100);
3029   format %{"[$addr + $index << $scale]" %}
3030   interface(MEMORY_INTER) %{
3031     base($addr);
3032     index($index);
3033     scale($scale);
3034     disp(0x0);
3035   %}
3036 %}
3037 
3038 // Indirect Memory Times Scale Plus 32-bit Index Register
3039 operand indIndexIScaleS(iRegP addr, iRegI index, immI_1 scale) %{
3040   constraint(ALLOC_IN_RC(ptr_reg));
3041   match(AddP addr (LShiftX (ConvI2L index) scale));
3042 
3043   op_cost(100);
3044   format %{"[$addr + $index.w << $scale]" %}
3045   interface(MEMORY_INTER) %{
3046     base($addr);
3047     index($index);
3048     scale($scale);
3049     disp(0x7fffffff); // sxtw
3050   %}
3051 %}
3052 
3053 // Indirect Memory Times Scale Plus Index Register
3054 operand indIndexScaleI(iRegP addr, iRegX index, immI_2 scale) %{
3055   constraint(ALLOC_IN_RC(ptr_reg));
3056   match(AddP addr (LShiftX index scale));
3057 
3058   op_cost(100);
3059   format %{"[$addr + $index << $scale]" %}
3060   interface(MEMORY_INTER) %{
3061     base($addr);
3062     index($index);
3063     scale($scale);
3064     disp(0x0);
3065   %}
3066 %}
3067 
3068 // Indirect Memory Times Scale Plus 32-bit Index Register
3069 operand indIndexIScaleI(iRegP addr, iRegI index, immI_2 scale) %{
3070   constraint(ALLOC_IN_RC(ptr_reg));
3071   match(AddP addr (LShiftX (ConvI2L index) scale));
3072 
3073   op_cost(100);
3074   format %{"[$addr + $index.w << $scale]" %}
3075   interface(MEMORY_INTER) %{
3076     base($addr);
3077     index($index);
3078     scale($scale);
3079     disp(0x7fffffff); // sxtw
3080   %}
3081 %}
3082 
3083 // Indirect Memory Times Scale Plus Index Register
3084 operand indIndexScaleL(iRegP addr, iRegX index, immI_3 scale) %{
3085   constraint(ALLOC_IN_RC(ptr_reg));
3086   match(AddP addr (LShiftX index scale));
3087 
3088   op_cost(100);
3089   format %{"[$addr + $index << $scale]" %}
3090   interface(MEMORY_INTER) %{
3091     base($addr);
3092     index($index);
3093     scale($scale);
3094     disp(0x0);
3095   %}
3096 %}
3097 
3098 // Indirect Memory Times Scale Plus 32-bit Index Register
3099 operand indIndexIScaleL(iRegP addr, iRegI index, immI_3 scale) %{
3100   constraint(ALLOC_IN_RC(ptr_reg));
3101   match(AddP addr (LShiftX (ConvI2L index) scale));
3102 
3103   op_cost(100);
3104   format %{"[$addr + $index.w << $scale]" %}
3105   interface(MEMORY_INTER) %{
3106     base($addr);
3107     index($index);
3108     scale($scale);
3109     disp(0x7fffffff); // sxtw
3110   %}
3111 %}
3112 
3113 // Indirect Memory Times Scale Plus Index Register
3114 operand indIndexScaleQ(iRegP addr, iRegX index, immI_4 scale) %{
3115   constraint(ALLOC_IN_RC(ptr_reg));
3116   match(AddP addr (LShiftX index scale));
3117 
3118   op_cost(100);
3119   format %{"[$addr + $index << $scale]" %}
3120   interface(MEMORY_INTER) %{
3121     base($addr);
3122     index($index);
3123     scale($scale);
3124     disp(0x0);
3125   %}
3126 %}
3127 
3128 // Indirect Memory Times Scale Plus 32-bit Index Register
3129 operand indIndexIScaleQ(iRegP addr, iRegI index, immI_4 scale) %{
3130   constraint(ALLOC_IN_RC(ptr_reg));
3131   match(AddP addr (LShiftX (ConvI2L index) scale));
3132 
3133   op_cost(100);
3134   format %{"[$addr + $index.w << $scale]" %}
3135   interface(MEMORY_INTER) %{
3136     base($addr);
3137     index($index);
3138     scale($scale);
3139     disp(0x7fffffff); // sxtw
3140   %}
3141 %}
3142 #else
3143 // Indirect Memory Times Scale Plus Index Register
3144 operand indIndexScale(iRegP addr, iRegX index, immU5 scale) %{
3145   constraint(ALLOC_IN_RC(ptr_reg));
3146   match(AddP addr (LShiftX index scale));
3147 
3148   op_cost(100);
3149   format %{"[$addr + $index << $scale]" %}
3150   interface(MEMORY_INTER) %{
3151     base($addr);
3152     index($index);
3153     scale($scale);
3154     disp(0x0);
3155   %}
3156 %}
3157 #endif
3158 
3159 // Operands for expressing Control Flow
3160 // NOTE:  Label is a predefined operand which should not be redefined in
3161 //        the AD file.  It is generically handled within the ADLC.
3162 
3163 //----------Conditional Branch Operands----------------------------------------
3164 // Comparison Op  - This is the operation of the comparison, and is limited to
3165 //                  the following set of codes:
3166 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
3167 //
3168 // Other attributes of the comparison, such as unsignedness, are specified
3169 // by the comparison instruction that sets a condition code flags register.
3170 // That result is represented by a flags operand whose subtype is appropriate
3171 // to the unsignedness (etc.) of the comparison.
3172 //
3173 // Later, the instruction which matches both the Comparison Op (a Bool) and
3174 // the flags (produced by the Cmp) specifies the coding of the comparison op
3175 // by matching a specific subtype of Bool operand below, such as cmpOpU.
3176 
3177 operand cmpOp() %{
3178   match(Bool);
3179 
3180   format %{ "" %}
3181   interface(COND_INTER) %{
3182     equal(0x0);
3183     not_equal(0x1);
3184     less(0xb);
3185     greater_equal(0xa);
3186     less_equal(0xd);
3187     greater(0xc);
3188     overflow(0x0); // unsupported/unimplemented
3189     no_overflow(0x0); // unsupported/unimplemented
3190   %}
3191 %}
3192 
3193 // integer comparison with 0, signed
3194 operand cmpOp0() %{
3195   match(Bool);
3196 
3197   format %{ "" %}
3198   interface(COND_INTER) %{
3199     equal(0x0);
3200     not_equal(0x1);
3201     less(0x4);
3202     greater_equal(0x5);
3203     less_equal(0xd); // unsupported
3204     greater(0xc); // unsupported
3205     overflow(0x0); // unsupported/unimplemented
3206     no_overflow(0x0); // unsupported/unimplemented
3207   %}
3208 %}
3209 
3210 // Comparison Op, unsigned
3211 operand cmpOpU() %{
3212   match(Bool);
3213 
3214   format %{ "u" %}
3215   interface(COND_INTER) %{
3216     equal(0x0);
3217     not_equal(0x1);
3218     less(0x3);
3219     greater_equal(0x2);
3220     less_equal(0x9);
3221     greater(0x8);
3222     overflow(0x0); // unsupported/unimplemented
3223     no_overflow(0x0); // unsupported/unimplemented
3224   %}
3225 %}
3226 
3227 // Comparison Op, pointer (same as unsigned)
3228 operand cmpOpP() %{
3229   match(Bool);
3230 
3231   format %{ "p" %}
3232   interface(COND_INTER) %{
3233     equal(0x0);
3234     not_equal(0x1);
3235     less(0x3);
3236     greater_equal(0x2);
3237     less_equal(0x9);
3238     greater(0x8);
3239     overflow(0x0); // unsupported/unimplemented
3240     no_overflow(0x0); // unsupported/unimplemented
3241   %}
3242 %}
3243 
3244 operand cmpOpL() %{
3245   match(Bool);
3246 
3247   format %{ "L" %}
3248   interface(COND_INTER) %{
3249     equal(0x0);
3250     not_equal(0x1);
3251     less(0xb);
3252     greater_equal(0xa);
3253     less_equal(0xd);
3254     greater(0xc);
3255     overflow(0x0); // unsupported/unimplemented
3256     no_overflow(0x0); // unsupported/unimplemented
3257   %}
3258 %}
3259 
3260 operand cmpOpL_commute() %{
3261   match(Bool);
3262 
3263   format %{ "L" %}
3264   interface(COND_INTER) %{
3265     equal(0x0);
3266     not_equal(0x1);
3267     less(0xc);
3268     greater_equal(0xd);
3269     less_equal(0xa);
3270     greater(0xb);
3271     overflow(0x0); // unsupported/unimplemented
3272     no_overflow(0x0); // unsupported/unimplemented
3273   %}
3274 %}
3275 
3276 operand cmpOpUL() %{
3277   match(Bool);
3278 
3279   format %{ "UL" %}
3280   interface(COND_INTER) %{
3281     equal(0x0);
3282     not_equal(0x1);
3283     less(0x3);
3284     greater_equal(0x2);
3285     less_equal(0x9);
3286     greater(0x8);
3287     overflow(0x0); // unsupported/unimplemented
3288     no_overflow(0x0); // unsupported/unimplemented
3289   %}
3290 %}
3291 
3292 operand cmpOpUL_commute() %{
3293   match(Bool);
3294 
3295   format %{ "UL" %}
3296   interface(COND_INTER) %{
3297     equal(0x0);
3298     not_equal(0x1);
3299     less(0x8);
3300     greater_equal(0x9);
3301     less_equal(0x2);
3302     greater(0x3);
3303     overflow(0x0); // unsupported/unimplemented
3304     no_overflow(0x0); // unsupported/unimplemented
3305   %}
3306 %}
3307 
3308 
3309 //----------OPERAND CLASSES----------------------------------------------------
3310 // Operand Classes are groups of operands that are used to simplify
3311 // instruction definitions by not requiring the AD writer to specify separate
3312 // instructions for every form of operand when the instruction accepts
3313 // multiple operand types with the same basic encoding and format.  The classic
3314 // case of this is memory operands.
3315 #ifdef AARCH64
3316 opclass memoryB(indirect, indIndex, indOffsetU12ScaleB);
3317 opclass memoryS(indirect, indIndex, indIndexScaleS, indIndexIScaleS, indOffsetU12ScaleS);
3318 opclass memoryI(indirect, indIndex, indIndexScaleI, indIndexIScaleI, indOffsetU12ScaleI);
3319 opclass memoryL(indirect, indIndex, indIndexScaleL, indIndexIScaleL, indOffsetU12ScaleL);
3320 opclass memoryP(indirect, indIndex, indIndexScaleL, indIndexIScaleL, indOffsetU12ScaleL);
3321 opclass memoryQ(indirect, indIndex, indIndexScaleQ, indIndexIScaleQ, indOffsetU12ScaleQ);
3322 opclass memoryF(indirect, indIndex, indIndexScaleI, indIndexIScaleI, indOffsetU12ScaleI);
3323 opclass memoryD(indirect, indIndex, indIndexScaleL, indIndexIScaleL, indOffsetU12ScaleL);
3324 
3325 opclass memoryScaledS(indIndexScaleS, indIndexIScaleS);
3326 opclass memoryScaledI(indIndexScaleI, indIndexIScaleI);
3327 opclass memoryScaledL(indIndexScaleL, indIndexIScaleL);
3328 opclass memoryScaledP(indIndexScaleL, indIndexIScaleL);
3329 opclass memoryScaledQ(indIndexScaleQ, indIndexIScaleQ);
3330 opclass memoryScaledF(indIndexScaleI, indIndexIScaleI);
3331 opclass memoryScaledD(indIndexScaleL, indIndexIScaleL);
3332 // when ldrex/strex is used:
3333 opclass memoryex ( indirect );
3334 opclass indIndexMemory( indIndex );
3335 opclass memoryvld ( indirect /* , write back mode not implemented */ );
3336 
3337 #else
3338 
3339 opclass memoryI ( indirect, indOffset12, indIndex, indIndexScale );
3340 opclass memoryP ( indirect, indOffset12, indIndex, indIndexScale );
3341 opclass memoryF ( indirect, indOffsetFP );
3342 opclass memoryF2 ( indirect, indOffsetFPx2 );
3343 opclass memoryD ( indirect, indOffsetFP );
3344 opclass memoryfp( indirect, indOffsetFP );
3345 opclass memoryB ( indirect, indIndex, indOffsetHD );
3346 opclass memoryS ( indirect, indIndex, indOffsetHD );
3347 opclass memoryL ( indirect, indIndex, indOffsetHD );
3348 
3349 opclass memoryScaledI(indIndexScale);
3350 opclass memoryScaledP(indIndexScale);
3351 
3352 // when ldrex/strex is used:
3353 opclass memoryex ( indirect );
3354 opclass indIndexMemory( indIndex );
3355 opclass memorylong ( indirect, indOffset12x2 );
3356 opclass memoryvld ( indirect /* , write back mode not implemented */ );
3357 #endif
3358 
3359 //----------PIPELINE-----------------------------------------------------------
3360 pipeline %{
3361 
3362 //----------ATTRIBUTES---------------------------------------------------------
3363 attributes %{
3364   fixed_size_instructions;           // Fixed size instructions
3365   max_instructions_per_bundle = 4;   // Up to 4 instructions per bundle
3366   instruction_unit_size = 4;         // An instruction is 4 bytes long
3367   instruction_fetch_unit_size = 16;  // The processor fetches one line
3368   instruction_fetch_units = 1;       // of 16 bytes
3369 
3370   // List of nop instructions
3371   nops( Nop_A0, Nop_A1, Nop_MS, Nop_FA, Nop_BR );
3372 %}
3373 
3374 //----------RESOURCES----------------------------------------------------------
3375 // Resources are the functional units available to the machine
3376 resources(A0, A1, MS, BR, FA, FM, IDIV, FDIV, IALU = A0 | A1);
3377 
3378 //----------PIPELINE DESCRIPTION-----------------------------------------------
3379 // Pipeline Description specifies the stages in the machine's pipeline
3380 
3381 pipe_desc(A, P, F, B, I, J, S, R, E, C, M, W, X, T, D);
3382 
3383 //----------PIPELINE CLASSES---------------------------------------------------
3384 // Pipeline Classes describe the stages in which input and output are
3385 // referenced by the hardware pipeline.
3386 
3387 // Integer ALU reg-reg operation
3388 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
3389     single_instruction;
3390     dst   : E(write);
3391     src1  : R(read);
3392     src2  : R(read);
3393     IALU  : R;
3394 %}
3395 
3396 // Integer ALU reg-reg long operation
3397 pipe_class ialu_reg_reg_2(iRegL dst, iRegL src1, iRegL src2) %{
3398     instruction_count(2);
3399     dst   : E(write);
3400     src1  : R(read);
3401     src2  : R(read);
3402     IALU  : R;
3403     IALU  : R;
3404 %}
3405 
3406 // Integer ALU reg-reg long dependent operation
3407 pipe_class ialu_reg_reg_2_dep(iRegL dst, iRegL src1, iRegL src2, flagsReg cr) %{
3408     instruction_count(1); multiple_bundles;
3409     dst   : E(write);
3410     src1  : R(read);
3411     src2  : R(read);
3412     cr    : E(write);
3413     IALU  : R(2);
3414 %}
3415 
3416 // Integer ALU reg-imm operaion
3417 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) %{
3418     single_instruction;
3419     dst   : E(write);
3420     src1  : R(read);
3421     IALU  : R;
3422 %}
3423 
3424 // Integer ALU reg-reg operation with condition code
3425 pipe_class ialu_cc_reg_reg(iRegI dst, iRegI src1, iRegI src2, flagsReg cr) %{
3426     single_instruction;
3427     dst   : E(write);
3428     cr    : E(write);
3429     src1  : R(read);
3430     src2  : R(read);
3431     IALU  : R;
3432 %}
3433 
3434 // Integer ALU zero-reg operation
3435 pipe_class ialu_zero_reg(iRegI dst, immI0 zero, iRegI src2) %{
3436     single_instruction;
3437     dst   : E(write);
3438     src2  : R(read);
3439     IALU  : R;
3440 %}
3441 
3442 // Integer ALU zero-reg operation with condition code only
3443 pipe_class ialu_cconly_zero_reg(flagsReg cr, iRegI src) %{
3444     single_instruction;
3445     cr    : E(write);
3446     src   : R(read);
3447     IALU  : R;
3448 %}
3449 
3450 // Integer ALU reg-reg operation with condition code only
3451 pipe_class ialu_cconly_reg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
3452     single_instruction;
3453     cr    : E(write);
3454     src1  : R(read);
3455     src2  : R(read);
3456     IALU  : R;
3457 %}
3458 
3459 // Integer ALU reg-imm operation with condition code only
3460 pipe_class ialu_cconly_reg_imm(flagsReg cr, iRegI src1) %{
3461     single_instruction;
3462     cr    : E(write);
3463     src1  : R(read);
3464     IALU  : R;
3465 %}
3466 
3467 // Integer ALU reg-reg-zero operation with condition code only
3468 pipe_class ialu_cconly_reg_reg_zero(flagsReg cr, iRegI src1, iRegI src2, immI0 zero) %{
3469     single_instruction;
3470     cr    : E(write);
3471     src1  : R(read);
3472     src2  : R(read);
3473     IALU  : R;
3474 %}
3475 
3476 // Integer ALU reg-imm-zero operation with condition code only
3477 pipe_class ialu_cconly_reg_imm_zero(flagsReg cr, iRegI src1, immI0 zero) %{
3478     single_instruction;
3479     cr    : E(write);
3480     src1  : R(read);
3481     IALU  : R;
3482 %}
3483 
3484 // Integer ALU reg-reg operation with condition code, src1 modified
3485 pipe_class ialu_cc_rwreg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
3486     single_instruction;
3487     cr    : E(write);
3488     src1  : E(write);
3489     src1  : R(read);
3490     src2  : R(read);
3491     IALU  : R;
3492 %}
3493 
3494 pipe_class cmpL_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg cr ) %{
3495     multiple_bundles;
3496     dst   : E(write)+4;
3497     cr    : E(write);
3498     src1  : R(read);
3499     src2  : R(read);
3500     IALU  : R(3);
3501     BR    : R(2);
3502 %}
3503 
3504 // Integer ALU operation
3505 pipe_class ialu_none(iRegI dst) %{
3506     single_instruction;
3507     dst   : E(write);
3508     IALU  : R;
3509 %}
3510 
3511 // Integer ALU reg operation
3512 pipe_class ialu_reg(iRegI dst, iRegI src) %{
3513     single_instruction; may_have_no_code;
3514     dst   : E(write);
3515     src   : R(read);
3516     IALU  : R;
3517 %}
3518 
3519 // Integer ALU reg conditional operation
3520 // This instruction has a 1 cycle stall, and cannot execute
3521 // in the same cycle as the instruction setting the condition
3522 // code. We kludge this by pretending to read the condition code
3523 // 1 cycle earlier, and by marking the functional units as busy
3524 // for 2 cycles with the result available 1 cycle later than
3525 // is really the case.
3526 pipe_class ialu_reg_flags( iRegI op2_out, iRegI op2_in, iRegI op1, flagsReg cr ) %{
3527     single_instruction;
3528     op2_out : C(write);
3529     op1     : R(read);
3530     cr      : R(read);       // This is really E, with a 1 cycle stall
3531     BR      : R(2);
3532     MS      : R(2);
3533 %}
3534 
3535 // Integer ALU reg operation
3536 pipe_class ialu_move_reg_L_to_I(iRegI dst, iRegL src) %{
3537     single_instruction; may_have_no_code;
3538     dst   : E(write);
3539     src   : R(read);
3540     IALU  : R;
3541 %}
3542 pipe_class ialu_move_reg_I_to_L(iRegL dst, iRegI src) %{
3543     single_instruction; may_have_no_code;
3544     dst   : E(write);
3545     src   : R(read);
3546     IALU  : R;
3547 %}
3548 
3549 // Two integer ALU reg operations
3550 pipe_class ialu_reg_2(iRegL dst, iRegL src) %{
3551     instruction_count(2);
3552     dst   : E(write);
3553     src   : R(read);
3554     A0    : R;
3555     A1    : R;
3556 %}
3557 
3558 // Two integer ALU reg operations
3559 pipe_class ialu_move_reg_L_to_L(iRegL dst, iRegL src) %{
3560     instruction_count(2); may_have_no_code;
3561     dst   : E(write);
3562     src   : R(read);
3563     A0    : R;
3564     A1    : R;
3565 %}
3566 
3567 // Integer ALU imm operation
3568 pipe_class ialu_imm(iRegI dst) %{
3569     single_instruction;
3570     dst   : E(write);
3571     IALU  : R;
3572 %}
3573 
3574 pipe_class ialu_imm_n(iRegI dst) %{
3575     single_instruction;
3576     dst   : E(write);
3577     IALU  : R;
3578 %}
3579 
3580 // Integer ALU reg-reg with carry operation
3581 pipe_class ialu_reg_reg_cy(iRegI dst, iRegI src1, iRegI src2, iRegI cy) %{
3582     single_instruction;
3583     dst   : E(write);
3584     src1  : R(read);
3585     src2  : R(read);
3586     IALU  : R;
3587 %}
3588 
3589 // Integer ALU cc operation
3590 pipe_class ialu_cc(iRegI dst, flagsReg cc) %{
3591     single_instruction;
3592     dst   : E(write);
3593     cc    : R(read);
3594     IALU  : R;
3595 %}
3596 
3597 // Integer ALU cc / second IALU operation
3598 pipe_class ialu_reg_ialu( iRegI dst, iRegI src ) %{
3599     instruction_count(1); multiple_bundles;
3600     dst   : E(write)+1;
3601     src   : R(read);
3602     IALU  : R;
3603 %}
3604 
3605 // Integer ALU cc / second IALU operation
3606 pipe_class ialu_reg_reg_ialu( iRegI dst, iRegI p, iRegI q ) %{
3607     instruction_count(1); multiple_bundles;
3608     dst   : E(write)+1;
3609     p     : R(read);
3610     q     : R(read);
3611     IALU  : R;
3612 %}
3613 
3614 // Integer ALU hi-lo-reg operation
3615 pipe_class ialu_hi_lo_reg(iRegI dst, immI src) %{
3616     instruction_count(1); multiple_bundles;
3617     dst   : E(write)+1;
3618     IALU  : R(2);
3619 %}
3620 
3621 // Long Constant
3622 pipe_class loadConL( iRegL dst, immL src ) %{
3623     instruction_count(2); multiple_bundles;
3624     dst   : E(write)+1;
3625     IALU  : R(2);
3626     IALU  : R(2);
3627 %}
3628 
3629 // Pointer Constant
3630 pipe_class loadConP( iRegP dst, immP src ) %{
3631     instruction_count(0); multiple_bundles;
3632     fixed_latency(6);
3633 %}
3634 
3635 // Polling Address
3636 pipe_class loadConP_poll( iRegP dst, immP_poll src ) %{
3637     dst   : E(write);
3638     IALU  : R;
3639 %}
3640 
3641 // Long Constant small
3642 pipe_class loadConLlo( iRegL dst, immL src ) %{
3643     instruction_count(2);
3644     dst   : E(write);
3645     IALU  : R;
3646     IALU  : R;
3647 %}
3648 
3649 // [PHH] This is wrong for 64-bit.  See LdImmF/D.
3650 pipe_class loadConFD(regF dst, immF src, iRegP tmp) %{
3651     instruction_count(1); multiple_bundles;
3652     src   : R(read);
3653     dst   : M(write)+1;
3654     IALU  : R;
3655     MS    : E;
3656 %}
3657 
3658 // Integer ALU nop operation
3659 pipe_class ialu_nop() %{
3660     single_instruction;
3661     IALU  : R;
3662 %}
3663 
3664 // Integer ALU nop operation
3665 pipe_class ialu_nop_A0() %{
3666     single_instruction;
3667     A0    : R;
3668 %}
3669 
3670 // Integer ALU nop operation
3671 pipe_class ialu_nop_A1() %{
3672     single_instruction;
3673     A1    : R;
3674 %}
3675 
3676 // Integer Multiply reg-reg operation
3677 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
3678     single_instruction;
3679     dst   : E(write);
3680     src1  : R(read);
3681     src2  : R(read);
3682     MS    : R(5);
3683 %}
3684 
3685 pipe_class mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
3686     single_instruction;
3687     dst   : E(write)+4;
3688     src1  : R(read);
3689     src2  : R(read);
3690     MS    : R(6);
3691 %}
3692 
3693 // Integer Divide reg-reg
3694 pipe_class sdiv_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI temp, flagsReg cr) %{
3695     instruction_count(1); multiple_bundles;
3696     dst   : E(write);
3697     temp  : E(write);
3698     src1  : R(read);
3699     src2  : R(read);
3700     temp  : R(read);
3701     MS    : R(38);
3702 %}
3703 
3704 // Long Divide
3705 pipe_class divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
3706     dst  : E(write)+71;
3707     src1 : R(read);
3708     src2 : R(read)+1;
3709     MS   : R(70);
3710 %}
3711 
3712 // Floating Point Add Float
3713 pipe_class faddF_reg_reg(regF dst, regF src1, regF src2) %{
3714     single_instruction;
3715     dst   : X(write);
3716     src1  : E(read);
3717     src2  : E(read);
3718     FA    : R;
3719 %}
3720 
3721 // Floating Point Add Double
3722 pipe_class faddD_reg_reg(regD dst, regD src1, regD src2) %{
3723     single_instruction;
3724     dst   : X(write);
3725     src1  : E(read);
3726     src2  : E(read);
3727     FA    : R;
3728 %}
3729 
3730 // Floating Point Conditional Move based on integer flags
3731 pipe_class int_conditional_float_move (cmpOp cmp, flagsReg cr, regF dst, regF src) %{
3732     single_instruction;
3733     dst   : X(write);
3734     src   : E(read);
3735     cr    : R(read);
3736     FA    : R(2);
3737     BR    : R(2);
3738 %}
3739 
3740 // Floating Point Conditional Move based on integer flags
3741 pipe_class int_conditional_double_move (cmpOp cmp, flagsReg cr, regD dst, regD src) %{
3742     single_instruction;
3743     dst   : X(write);
3744     src   : E(read);
3745     cr    : R(read);
3746     FA    : R(2);
3747     BR    : R(2);
3748 %}
3749 
3750 // Floating Point Multiply Float
3751 pipe_class fmulF_reg_reg(regF dst, regF src1, regF src2) %{
3752     single_instruction;
3753     dst   : X(write);
3754     src1  : E(read);
3755     src2  : E(read);
3756     FM    : R;
3757 %}
3758 
3759 // Floating Point Multiply Double
3760 pipe_class fmulD_reg_reg(regD dst, regD src1, regD src2) %{
3761     single_instruction;
3762     dst   : X(write);
3763     src1  : E(read);
3764     src2  : E(read);
3765     FM    : R;
3766 %}
3767 
3768 // Floating Point Divide Float
3769 pipe_class fdivF_reg_reg(regF dst, regF src1, regF src2) %{
3770     single_instruction;
3771     dst   : X(write);
3772     src1  : E(read);
3773     src2  : E(read);
3774     FM    : R;
3775     FDIV  : C(14);
3776 %}
3777 
3778 // Floating Point Divide Double
3779 pipe_class fdivD_reg_reg(regD dst, regD src1, regD src2) %{
3780     single_instruction;
3781     dst   : X(write);
3782     src1  : E(read);
3783     src2  : E(read);
3784     FM    : R;
3785     FDIV  : C(17);
3786 %}
3787 
3788 // Floating Point Move/Negate/Abs Float
3789 pipe_class faddF_reg(regF dst, regF src) %{
3790     single_instruction;
3791     dst   : W(write);
3792     src   : E(read);
3793     FA    : R(1);
3794 %}
3795 
3796 // Floating Point Move/Negate/Abs Double
3797 pipe_class faddD_reg(regD dst, regD src) %{
3798     single_instruction;
3799     dst   : W(write);
3800     src   : E(read);
3801     FA    : R;
3802 %}
3803 
3804 // Floating Point Convert F->D
3805 pipe_class fcvtF2D(regD dst, regF src) %{
3806     single_instruction;
3807     dst   : X(write);
3808     src   : E(read);
3809     FA    : R;
3810 %}
3811 
3812 // Floating Point Convert I->D
3813 pipe_class fcvtI2D(regD dst, regF src) %{
3814     single_instruction;
3815     dst   : X(write);
3816     src   : E(read);
3817     FA    : R;
3818 %}
3819 
3820 // Floating Point Convert LHi->D
3821 pipe_class fcvtLHi2D(regD dst, regD src) %{
3822     single_instruction;
3823     dst   : X(write);
3824     src   : E(read);
3825     FA    : R;
3826 %}
3827 
3828 // Floating Point Convert L->D
3829 pipe_class fcvtL2D(regD dst, iRegL src) %{
3830     single_instruction;
3831     dst   : X(write);
3832     src   : E(read);
3833     FA    : R;
3834 %}
3835 
3836 // Floating Point Convert L->F
3837 pipe_class fcvtL2F(regF dst, iRegL src) %{
3838     single_instruction;
3839     dst   : X(write);
3840     src   : E(read);
3841     FA    : R;
3842 %}
3843 
3844 // Floating Point Convert D->F
3845 pipe_class fcvtD2F(regD dst, regF src) %{
3846     single_instruction;
3847     dst   : X(write);
3848     src   : E(read);
3849     FA    : R;
3850 %}
3851 
3852 // Floating Point Convert I->L
3853 pipe_class fcvtI2L(regD dst, regF src) %{
3854     single_instruction;
3855     dst   : X(write);
3856     src   : E(read);
3857     FA    : R;
3858 %}
3859 
3860 // Floating Point Convert D->F
3861 pipe_class fcvtD2I(iRegI dst, regD src, flagsReg cr) %{
3862     instruction_count(1); multiple_bundles;
3863     dst   : X(write)+6;
3864     src   : E(read);
3865     FA    : R;
3866 %}
3867 
3868 // Floating Point Convert D->L
3869 pipe_class fcvtD2L(regD dst, regD src, flagsReg cr) %{
3870     instruction_count(1); multiple_bundles;
3871     dst   : X(write)+6;
3872     src   : E(read);
3873     FA    : R;
3874 %}
3875 
3876 // Floating Point Convert F->I
3877 pipe_class fcvtF2I(regF dst, regF src, flagsReg cr) %{
3878     instruction_count(1); multiple_bundles;
3879     dst   : X(write)+6;
3880     src   : E(read);
3881     FA    : R;
3882 %}
3883 
3884 // Floating Point Convert F->L
3885 pipe_class fcvtF2L(regD dst, regF src, flagsReg cr) %{
3886     instruction_count(1); multiple_bundles;
3887     dst   : X(write)+6;
3888     src   : E(read);
3889     FA    : R;
3890 %}
3891 
3892 // Floating Point Convert I->F
3893 pipe_class fcvtI2F(regF dst, regF src) %{
3894     single_instruction;
3895     dst   : X(write);
3896     src   : E(read);
3897     FA    : R;
3898 %}
3899 
3900 // Floating Point Compare
3901 pipe_class faddF_fcc_reg_reg_zero(flagsRegF cr, regF src1, regF src2, immI0 zero) %{
3902     single_instruction;
3903     cr    : X(write);
3904     src1  : E(read);
3905     src2  : E(read);
3906     FA    : R;
3907 %}
3908 
3909 // Floating Point Compare
3910 pipe_class faddD_fcc_reg_reg_zero(flagsRegF cr, regD src1, regD src2, immI0 zero) %{
3911     single_instruction;
3912     cr    : X(write);
3913     src1  : E(read);
3914     src2  : E(read);
3915     FA    : R;
3916 %}
3917 
3918 // Floating Add Nop
3919 pipe_class fadd_nop() %{
3920     single_instruction;
3921     FA  : R;
3922 %}
3923 
3924 // Integer Store to Memory
3925 pipe_class istore_mem_reg(memoryI mem, iRegI src) %{
3926     single_instruction;
3927     mem   : R(read);
3928     src   : C(read);
3929     MS    : R;
3930 %}
3931 
3932 // Integer Store to Memory
3933 pipe_class istore_mem_spORreg(memoryI mem, sp_ptr_RegP src) %{
3934     single_instruction;
3935     mem   : R(read);
3936     src   : C(read);
3937     MS    : R;
3938 %}
3939 
3940 // Float Store
3941 pipe_class fstoreF_mem_reg(memoryF mem, RegF src) %{
3942     single_instruction;
3943     mem : R(read);
3944     src : C(read);
3945     MS  : R;
3946 %}
3947 
3948 // Float Store
3949 pipe_class fstoreF_mem_zero(memoryF mem, immF0 src) %{
3950     single_instruction;
3951     mem : R(read);
3952     MS  : R;
3953 %}
3954 
3955 // Double Store
3956 pipe_class fstoreD_mem_reg(memoryD mem, RegD src) %{
3957     instruction_count(1);
3958     mem : R(read);
3959     src : C(read);
3960     MS  : R;
3961 %}
3962 
3963 // Double Store
3964 pipe_class fstoreD_mem_zero(memoryD mem, immD0 src) %{
3965     single_instruction;
3966     mem : R(read);
3967     MS  : R;
3968 %}
3969 
3970 // Integer Load (when sign bit propagation not needed)
3971 pipe_class iload_mem(iRegI dst, memoryI mem) %{
3972     single_instruction;
3973     mem : R(read);
3974     dst : C(write);
3975     MS  : R;
3976 %}
3977 
3978 // Integer Load (when sign bit propagation or masking is needed)
3979 pipe_class iload_mask_mem(iRegI dst, memoryI mem) %{
3980     single_instruction;
3981     mem : R(read);
3982     dst : M(write);
3983     MS  : R;
3984 %}
3985 
3986 // Float Load
3987 pipe_class floadF_mem(regF dst, memoryF mem) %{
3988     single_instruction;
3989     mem : R(read);
3990     dst : M(write);
3991     MS  : R;
3992 %}
3993 
3994 // Float Load
3995 pipe_class floadD_mem(regD dst, memoryD mem) %{
3996     instruction_count(1); multiple_bundles; // Again, unaligned argument is only multiple case
3997     mem : R(read);
3998     dst : M(write);
3999     MS  : R;
4000 %}
4001 
4002 // Memory Nop
4003 pipe_class mem_nop() %{
4004     single_instruction;
4005     MS  : R;
4006 %}
4007 
4008 pipe_class sethi(iRegP dst, immI src) %{
4009     single_instruction;
4010     dst  : E(write);
4011     IALU : R;
4012 %}
4013 
4014 pipe_class loadPollP(iRegP poll) %{
4015     single_instruction;
4016     poll : R(read);
4017     MS   : R;
4018 %}
4019 
4020 pipe_class br(Universe br, label labl) %{
4021     single_instruction_with_delay_slot;
4022     BR  : R;
4023 %}
4024 
4025 pipe_class br_cc(Universe br, cmpOp cmp, flagsReg cr, label labl) %{
4026     single_instruction_with_delay_slot;
4027     cr    : E(read);
4028     BR    : R;
4029 %}
4030 
4031 pipe_class br_reg(Universe br, cmpOp cmp, iRegI op1, label labl) %{
4032     single_instruction_with_delay_slot;
4033     op1 : E(read);
4034     BR  : R;
4035     MS  : R;
4036 %}
4037 
4038 pipe_class br_nop() %{
4039     single_instruction;
4040     BR  : R;
4041 %}
4042 
4043 pipe_class simple_call(method meth) %{
4044     instruction_count(2); multiple_bundles; force_serialization;
4045     fixed_latency(100);
4046     BR  : R(1);
4047     MS  : R(1);
4048     A0  : R(1);
4049 %}
4050 
4051 pipe_class compiled_call(method meth) %{
4052     instruction_count(1); multiple_bundles; force_serialization;
4053     fixed_latency(100);
4054     MS  : R(1);
4055 %}
4056 
4057 pipe_class call(method meth) %{
4058     instruction_count(0); multiple_bundles; force_serialization;
4059     fixed_latency(100);
4060 %}
4061 
4062 pipe_class tail_call(Universe ignore, label labl) %{
4063     single_instruction; has_delay_slot;
4064     fixed_latency(100);
4065     BR  : R(1);
4066     MS  : R(1);
4067 %}
4068 
4069 pipe_class ret(Universe ignore) %{
4070     single_instruction; has_delay_slot;
4071     BR  : R(1);
4072     MS  : R(1);
4073 %}
4074 
4075 // The real do-nothing guy
4076 pipe_class empty( ) %{
4077     instruction_count(0);
4078 %}
4079 
4080 pipe_class long_memory_op() %{
4081     instruction_count(0); multiple_bundles; force_serialization;
4082     fixed_latency(25);
4083     MS  : R(1);
4084 %}
4085 
4086 // Check-cast
4087 pipe_class partial_subtype_check_pipe(Universe ignore, iRegP array, iRegP match ) %{
4088     array : R(read);
4089     match  : R(read);
4090     IALU   : R(2);
4091     BR     : R(2);
4092     MS     : R;
4093 %}
4094 
4095 // Convert FPU flags into +1,0,-1
4096 pipe_class floating_cmp( iRegI dst, regF src1, regF src2 ) %{
4097     src1  : E(read);
4098     src2  : E(read);
4099     dst   : E(write);
4100     FA    : R;
4101     MS    : R(2);
4102     BR    : R(2);
4103 %}
4104 
4105 // Compare for p < q, and conditionally add y
4106 pipe_class cadd_cmpltmask( iRegI p, iRegI q, iRegI y ) %{
4107     p     : E(read);
4108     q     : E(read);
4109     y     : E(read);
4110     IALU  : R(3)
4111 %}
4112 
4113 // Perform a compare, then move conditionally in a branch delay slot.
4114 pipe_class min_max( iRegI src2, iRegI srcdst ) %{
4115     src2   : E(read);
4116     srcdst : E(read);
4117     IALU   : R;
4118     BR     : R;
4119 %}
4120 
4121 // Define the class for the Nop node
4122 define %{
4123    MachNop = ialu_nop;
4124 %}
4125 
4126 %}
4127 
4128 //----------INSTRUCTIONS-------------------------------------------------------
4129 
4130 //------------Special Nop instructions for bundling - no match rules-----------
4131 // Nop using the A0 functional unit
4132 instruct Nop_A0() %{
4133   ins_pipe(ialu_nop_A0);
4134 %}
4135 
4136 // Nop using the A1 functional unit
4137 instruct Nop_A1( ) %{
4138   ins_pipe(ialu_nop_A1);
4139 %}
4140 
4141 // Nop using the memory functional unit
4142 instruct Nop_MS( ) %{
4143   ins_pipe(mem_nop);
4144 %}
4145 
4146 // Nop using the floating add functional unit
4147 instruct Nop_FA( ) %{
4148   ins_pipe(fadd_nop);
4149 %}
4150 
4151 // Nop using the branch functional unit
4152 instruct Nop_BR( ) %{
4153   ins_pipe(br_nop);
4154 %}
4155 
4156 //----------Load/Store/Move Instructions---------------------------------------
4157 //----------Load Instructions--------------------------------------------------
4158 // Load Byte (8bit signed)
4159 instruct loadB(iRegI dst, memoryB mem) %{
4160   match(Set dst (LoadB mem));
4161   ins_cost(MEMORY_REF_COST);
4162 
4163   size(4);
4164   format %{ "LDRSB   $dst,$mem\t! byte -> int" %}
4165   ins_encode %{
4166     // High 32 bits are harmlessly set on Aarch64
4167     __ ldrsb($dst$$Register, $mem$$Address);
4168   %}
4169   ins_pipe(iload_mask_mem);
4170 %}
4171 
4172 // Load Byte (8bit signed) into a Long Register
4173 instruct loadB2L(iRegL dst, memoryB mem) %{
4174   match(Set dst (ConvI2L (LoadB mem)));
4175   ins_cost(MEMORY_REF_COST);
4176 
4177 #ifdef AARCH64
4178   size(4);
4179   format %{ "LDRSB $dst,$mem\t! byte -> long"  %}
4180   ins_encode %{
4181     __ ldrsb($dst$$Register, $mem$$Address);
4182   %}
4183 #else
4184   size(8);
4185   format %{ "LDRSB $dst.lo,$mem\t! byte -> long\n\t"
4186             "ASR   $dst.hi,$dst.lo,31" %}
4187   ins_encode %{
4188     __ ldrsb($dst$$Register, $mem$$Address);
4189     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
4190   %}
4191 #endif
4192   ins_pipe(iload_mask_mem);
4193 %}
4194 
4195 // Load Unsigned Byte (8bit UNsigned) into an int reg
4196 instruct loadUB(iRegI dst, memoryB mem) %{
4197   match(Set dst (LoadUB mem));
4198   ins_cost(MEMORY_REF_COST);
4199 
4200   size(4);
4201   format %{ "LDRB   $dst,$mem\t! ubyte -> int" %}
4202   ins_encode %{
4203     __ ldrb($dst$$Register, $mem$$Address);
4204   %}
4205   ins_pipe(iload_mem);
4206 %}
4207 
4208 // Load Unsigned Byte (8bit UNsigned) into a Long Register
4209 instruct loadUB2L(iRegL dst, memoryB mem) %{
4210   match(Set dst (ConvI2L (LoadUB mem)));
4211   ins_cost(MEMORY_REF_COST);
4212 
4213 #ifdef AARCH64
4214   size(4);
4215   format %{ "LDRB  $dst,$mem\t! ubyte -> long"  %}
4216   ins_encode %{
4217     __ ldrb($dst$$Register, $mem$$Address);
4218   %}
4219 #else
4220   size(8);
4221   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
4222             "MOV   $dst.hi,0" %}
4223   ins_encode %{
4224     __ ldrb($dst$$Register, $mem$$Address);
4225     __ mov($dst$$Register->successor(), 0);
4226   %}
4227 #endif
4228   ins_pipe(iload_mem);
4229 %}
4230 
4231 // Load Unsigned Byte (8 bit UNsigned) with immediate mask into Long Register
4232 instruct loadUB2L_limmI(iRegL dst, memoryB mem, limmIlow8 mask) %{
4233   match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
4234 
4235 #ifdef AARCH64
4236   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
4237   size(8);
4238   format %{ "LDRB  $dst,$mem\t! ubyte -> long\n\t"
4239             "AND  $dst,$dst,$mask" %}
4240   ins_encode %{
4241     __ ldrb($dst$$Register, $mem$$Address);
4242     __ andr($dst$$Register, $dst$$Register, limmI_low($mask$$constant, 8));
4243   %}
4244 #else
4245   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
4246   size(12);
4247   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
4248             "MOV   $dst.hi,0\n\t"
4249             "AND  $dst.lo,$dst.lo,$mask" %}
4250   ins_encode %{
4251     __ ldrb($dst$$Register, $mem$$Address);
4252     __ mov($dst$$Register->successor(), 0);
4253     __ andr($dst$$Register, $dst$$Register, limmI_low($mask$$constant, 8));
4254   %}
4255 #endif
4256   ins_pipe(iload_mem);
4257 %}
4258 
4259 // Load Short (16bit signed)
4260 #ifdef AARCH64
4261 // XXX This variant shouldn't be necessary if 6217251 is implemented
4262 instruct loadSoff(iRegI dst, memoryScaledS mem, aimmX off, iRegP tmp) %{
4263   match(Set dst (LoadS (AddP mem off)));
4264   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
4265   effect(TEMP tmp);
4266   size(4 * 2);
4267 
4268   format %{ "LDRSH   $dst,$mem+$off\t! short temp=$tmp" %}
4269   ins_encode %{
4270     Register base = reg_to_register_object($mem$$base);
4271     __ add($tmp$$Register, base, $off$$constant);
4272     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4273     __ ldrsh($dst$$Register, nmem);
4274   %}
4275   ins_pipe(iload_mask_mem);
4276 %}
4277 #endif
4278 
4279 instruct loadS(iRegI dst, memoryS mem) %{
4280   match(Set dst (LoadS mem));
4281   ins_cost(MEMORY_REF_COST);
4282 
4283   size(4);
4284   format %{ "LDRSH   $dst,$mem\t! short" %}
4285   ins_encode %{
4286     __ ldrsh($dst$$Register, $mem$$Address);
4287   %}
4288   ins_pipe(iload_mask_mem);
4289 %}
4290 
4291 // Load Short (16 bit signed) to Byte (8 bit signed)
4292 instruct loadS2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
4293   match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
4294   ins_cost(MEMORY_REF_COST);
4295 
4296   size(4);
4297 
4298   format %{ "LDRSB   $dst,$mem\t! short -> byte" %}
4299   ins_encode %{
4300     // High 32 bits are harmlessly set on Aarch64
4301     __ ldrsb($dst$$Register, $mem$$Address);
4302   %}
4303   ins_pipe(iload_mask_mem);
4304 %}
4305 
4306 // Load Short (16bit signed) into a Long Register
4307 instruct loadS2L(iRegL dst, memoryS mem) %{
4308   match(Set dst (ConvI2L (LoadS mem)));
4309   ins_cost(MEMORY_REF_COST);
4310 
4311 #ifdef AARCH64
4312   size(4);
4313   format %{ "LDRSH $dst,$mem\t! short -> long"  %}
4314   ins_encode %{
4315     __ ldrsh($dst$$Register, $mem$$Address);
4316   %}
4317 #else
4318   size(8);
4319   format %{ "LDRSH $dst.lo,$mem\t! short -> long\n\t"
4320             "ASR   $dst.hi,$dst.lo,31" %}
4321   ins_encode %{
4322     __ ldrsh($dst$$Register, $mem$$Address);
4323     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
4324   %}
4325 #endif
4326   ins_pipe(iload_mask_mem);
4327 %}
4328 
4329 // Load Unsigned Short/Char (16bit UNsigned)
4330 
4331 #ifdef AARCH64
4332 // XXX This variant shouldn't be necessary if 6217251 is implemented
4333 instruct loadUSoff(iRegI dst, memoryScaledS mem, aimmX off, iRegP tmp) %{
4334   match(Set dst (LoadUS (AddP mem off)));
4335   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
4336   effect(TEMP tmp);
4337   size(4 * 2);
4338 
4339   format %{ "LDRH   $dst,$mem+$off\t! ushort/char temp=$tmp" %}
4340   ins_encode %{
4341     Register base = reg_to_register_object($mem$$base);
4342     __ add($tmp$$Register, base, $off$$constant);
4343     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4344     __ ldrh($dst$$Register, nmem);
4345   %}
4346   ins_pipe(iload_mem);
4347 %}
4348 #endif
4349 
4350 instruct loadUS(iRegI dst, memoryS mem) %{
4351   match(Set dst (LoadUS mem));
4352   ins_cost(MEMORY_REF_COST);
4353 
4354   size(4);
4355   format %{ "LDRH   $dst,$mem\t! ushort/char" %}
4356   ins_encode %{
4357     __ ldrh($dst$$Register, $mem$$Address);
4358   %}
4359   ins_pipe(iload_mem);
4360 %}
4361 
4362 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
4363 instruct loadUS2B(iRegI dst, memoryB mem, immI_24 twentyfour) %{
4364   match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
4365   ins_cost(MEMORY_REF_COST);
4366 
4367   size(4);
4368   format %{ "LDRSB   $dst,$mem\t! ushort -> byte" %}
4369   ins_encode %{
4370     __ ldrsb($dst$$Register, $mem$$Address);
4371   %}
4372   ins_pipe(iload_mask_mem);
4373 %}
4374 
4375 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register
4376 instruct loadUS2L(iRegL dst, memoryS mem) %{
4377   match(Set dst (ConvI2L (LoadUS mem)));
4378   ins_cost(MEMORY_REF_COST);
4379 
4380 #ifdef AARCH64
4381   size(4);
4382   format %{ "LDRH  $dst,$mem\t! short -> long"  %}
4383   ins_encode %{
4384     __ ldrh($dst$$Register, $mem$$Address);
4385   %}
4386 #else
4387   size(8);
4388   format %{ "LDRH  $dst.lo,$mem\t! short -> long\n\t"
4389             "MOV   $dst.hi, 0" %}
4390   ins_encode %{
4391     __ ldrh($dst$$Register, $mem$$Address);
4392     __ mov($dst$$Register->successor(), 0);
4393   %}
4394 #endif
4395   ins_pipe(iload_mem);
4396 %}
4397 
4398 // Load Unsigned Short/Char (16bit UNsigned) with mask 0xFF into a Long Register
4399 instruct loadUS2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
4400   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
4401   ins_cost(MEMORY_REF_COST);
4402 
4403 #ifdef AARCH64
4404   size(4);
4405   format %{ "LDRB  $dst,$mem"  %}
4406   ins_encode %{
4407     __ ldrb($dst$$Register, $mem$$Address);
4408   %}
4409 #else
4410   size(8);
4411   format %{ "LDRB  $dst.lo,$mem\t! \n\t"
4412             "MOV   $dst.hi, 0" %}
4413   ins_encode %{
4414     __ ldrb($dst$$Register, $mem$$Address);
4415     __ mov($dst$$Register->successor(), 0);
4416   %}
4417 #endif
4418   ins_pipe(iload_mem);
4419 %}
4420 
4421 // Load Unsigned Short/Char (16bit UNsigned) with a immediate mask into a Long Register
4422 instruct loadUS2L_limmI(iRegL dst, memoryS mem, limmI mask) %{
4423   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
4424 #ifdef AARCH64
4425   ins_cost(MEMORY_REF_COST + 1*DEFAULT_COST);
4426 
4427   size(8);
4428   format %{ "LDRH   $dst,$mem\t! ushort/char & mask -> long\n\t"
4429             "AND    $dst,$dst,$mask" %}
4430   ins_encode %{
4431     __ ldrh($dst$$Register, $mem$$Address);
4432     __ andr($dst$$Register, $dst$$Register, (uintx)$mask$$constant);
4433   %}
4434 #else
4435   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
4436 
4437   size(12);
4438   format %{ "LDRH   $dst,$mem\t! ushort/char & mask -> long\n\t"
4439             "MOV    $dst.hi, 0\n\t"
4440             "AND    $dst,$dst,$mask" %}
4441   ins_encode %{
4442     __ ldrh($dst$$Register, $mem$$Address);
4443     __ mov($dst$$Register->successor(), 0);
4444     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
4445   %}
4446 #endif
4447   ins_pipe(iload_mem);
4448 %}
4449 
4450 // Load Integer
4451 
4452 #ifdef AARCH64
4453 // XXX This variant shouldn't be necessary if 6217251 is implemented
4454 instruct loadIoff(iRegI dst, memoryScaledI mem, aimmX off, iRegP tmp) %{
4455   match(Set dst (LoadI (AddP mem off)));
4456   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
4457   effect(TEMP tmp);
4458   size(4 * 2);
4459 
4460   format %{ "ldr_s32 $dst,$mem+$off\t! int temp=$tmp" %}
4461   ins_encode %{
4462     Register base = reg_to_register_object($mem$$base);
4463     __ add($tmp$$Register, base, $off$$constant);
4464     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4465     __ ldr_s32($dst$$Register, nmem);
4466   %}
4467   ins_pipe(iload_mem);
4468 %}
4469 #endif
4470 
4471 instruct loadI(iRegI dst, memoryI mem) %{
4472   match(Set dst (LoadI mem));
4473   ins_cost(MEMORY_REF_COST);
4474 
4475   size(4);
4476   format %{ "ldr_s32 $dst,$mem\t! int" %}
4477   ins_encode %{
4478     __ ldr_s32($dst$$Register, $mem$$Address);
4479   %}
4480   ins_pipe(iload_mem);
4481 %}
4482 
4483 // Load Integer to Byte (8 bit signed)
4484 instruct loadI2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
4485   match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
4486   ins_cost(MEMORY_REF_COST);
4487 
4488   size(4);
4489 
4490   format %{ "LDRSB   $dst,$mem\t! int -> byte" %}
4491   ins_encode %{
4492     __ ldrsb($dst$$Register, $mem$$Address);
4493   %}
4494   ins_pipe(iload_mask_mem);
4495 %}
4496 
4497 // Load Integer to Unsigned Byte (8 bit UNsigned)
4498 instruct loadI2UB(iRegI dst, memoryB mem, immI_255 mask) %{
4499   match(Set dst (AndI (LoadI mem) mask));
4500   ins_cost(MEMORY_REF_COST);
4501 
4502   size(4);
4503 
4504   format %{ "LDRB   $dst,$mem\t! int -> ubyte" %}
4505   ins_encode %{
4506     __ ldrb($dst$$Register, $mem$$Address);
4507   %}
4508   ins_pipe(iload_mask_mem);
4509 %}
4510 
4511 // Load Integer to Short (16 bit signed)
4512 instruct loadI2S(iRegI dst, memoryS mem, immI_16 sixteen) %{
4513   match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
4514   ins_cost(MEMORY_REF_COST);
4515 
4516   size(4);
4517   format %{ "LDRSH   $dst,$mem\t! int -> short" %}
4518   ins_encode %{
4519     __ ldrsh($dst$$Register, $mem$$Address);
4520   %}
4521   ins_pipe(iload_mask_mem);
4522 %}
4523 
4524 // Load Integer to Unsigned Short (16 bit UNsigned)
4525 instruct loadI2US(iRegI dst, memoryS mem, immI_65535 mask) %{
4526   match(Set dst (AndI (LoadI mem) mask));
4527   ins_cost(MEMORY_REF_COST);
4528 
4529   size(4);
4530   format %{ "LDRH   $dst,$mem\t! int -> ushort/char" %}
4531   ins_encode %{
4532     __ ldrh($dst$$Register, $mem$$Address);
4533   %}
4534   ins_pipe(iload_mask_mem);
4535 %}
4536 
4537 // Load Integer into a Long Register
4538 instruct loadI2L(iRegL dst, memoryI mem) %{
4539   match(Set dst (ConvI2L (LoadI mem)));
4540 #ifdef AARCH64
4541   ins_cost(MEMORY_REF_COST);
4542 
4543   size(4);
4544   format %{ "LDRSW $dst.lo,$mem\t! int -> long"  %}
4545   ins_encode %{
4546     __ ldr_s32($dst$$Register, $mem$$Address);
4547   %}
4548 #else
4549   ins_cost(MEMORY_REF_COST);
4550 
4551   size(8);
4552   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
4553             "ASR   $dst.hi,$dst.lo,31\t! int->long" %}
4554   ins_encode %{
4555     __ ldr($dst$$Register, $mem$$Address);
4556     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
4557   %}
4558 #endif
4559   ins_pipe(iload_mask_mem);
4560 %}
4561 
4562 // Load Integer with mask 0xFF into a Long Register
4563 instruct loadI2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
4564   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4565 #ifdef AARCH64
4566   ins_cost(MEMORY_REF_COST);
4567 
4568   size(4);
4569   format %{ "LDRB   $dst.lo,$mem\t! int & 0xFF -> long"  %}
4570   ins_encode %{
4571     __ ldrb($dst$$Register, $mem$$Address);
4572   %}
4573 #else
4574   ins_cost(MEMORY_REF_COST);
4575 
4576   size(8);
4577   format %{ "LDRB   $dst.lo,$mem\t! int & 0xFF -> long\n\t"
4578             "MOV    $dst.hi, 0" %}
4579   ins_encode %{
4580     __ ldrb($dst$$Register, $mem$$Address);
4581     __ mov($dst$$Register->successor(), 0);
4582   %}
4583 #endif
4584   ins_pipe(iload_mem);
4585 %}
4586 
4587 // Load Integer with mask 0xFFFF into a Long Register
4588 instruct loadI2L_immI_65535(iRegL dst, memoryS mem, immI_65535 mask) %{
4589   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4590   ins_cost(MEMORY_REF_COST);
4591 
4592 #ifdef AARCH64
4593   size(4);
4594   format %{ "LDRH   $dst,$mem\t! int & 0xFFFF -> long" %}
4595   ins_encode %{
4596     __ ldrh($dst$$Register, $mem$$Address);
4597   %}
4598 #else
4599   size(8);
4600   format %{ "LDRH   $dst,$mem\t! int & 0xFFFF -> long\n\t"
4601             "MOV    $dst.hi, 0" %}
4602   ins_encode %{
4603     __ ldrh($dst$$Register, $mem$$Address);
4604     __ mov($dst$$Register->successor(), 0);
4605   %}
4606 #endif
4607   ins_pipe(iload_mask_mem);
4608 %}
4609 
4610 #ifdef AARCH64
4611 // Load Integer with an immediate mask into a Long Register
4612 instruct loadI2L_limmI(iRegL dst, memoryI mem, limmI mask) %{
4613   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4614   ins_cost(MEMORY_REF_COST + 1*DEFAULT_COST);
4615 
4616   size(8);
4617   format %{ "LDRSW $dst,$mem\t! int -> long\n\t"
4618             "AND   $dst,$dst,$mask" %}
4619 
4620   ins_encode %{
4621     __ ldr_s32($dst$$Register, $mem$$Address);
4622     __ andr($dst$$Register, $dst$$Register, (uintx)$mask$$constant);
4623   %}
4624   ins_pipe(iload_mem);
4625 %}
4626 #else
4627 // Load Integer with a 31-bit immediate mask into a Long Register
4628 instruct loadI2L_limmU31(iRegL dst, memoryI mem, limmU31 mask) %{
4629   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4630   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
4631 
4632   size(12);
4633   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
4634             "MOV    $dst.hi, 0\n\t"
4635             "AND   $dst,$dst,$mask" %}
4636 
4637   ins_encode %{
4638     __ ldr($dst$$Register, $mem$$Address);
4639     __ mov($dst$$Register->successor(), 0);
4640     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
4641   %}
4642   ins_pipe(iload_mem);
4643 %}
4644 #endif
4645 
4646 #ifdef AARCH64
4647 // Load Integer with mask into a Long Register
4648 // FIXME: use signedRegI mask, remove tmp?
4649 instruct loadI2L_immI(iRegL dst, memoryI mem, immI mask, iRegI tmp) %{
4650   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4651   effect(TEMP dst, TEMP tmp);
4652 
4653   ins_cost(MEMORY_REF_COST + 3*DEFAULT_COST);
4654   format %{ "LDRSW    $mem,$dst\t! int & 31-bit mask -> long\n\t"
4655             "MOV_SLOW $tmp,$mask\n\t"
4656             "AND      $dst,$tmp,$dst" %}
4657   ins_encode %{
4658     __ ldrsw($dst$$Register, $mem$$Address);
4659     __ mov_slow($tmp$$Register, $mask$$constant);
4660     __ andr($dst$$Register, $dst$$Register, $tmp$$Register);
4661   %}
4662   ins_pipe(iload_mem);
4663 %}
4664 #else
4665 // Load Integer with a 31-bit mask into a Long Register
4666 // FIXME: use iRegI mask, remove tmp?
4667 instruct loadI2L_immU31(iRegL dst, memoryI mem, immU31 mask, iRegI tmp) %{
4668   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
4669   effect(TEMP dst, TEMP tmp);
4670 
4671   ins_cost(MEMORY_REF_COST + 4*DEFAULT_COST);
4672   size(20);
4673   format %{ "LDR      $mem,$dst\t! int & 31-bit mask -> long\n\t"
4674             "MOV      $dst.hi, 0\n\t"
4675             "MOV_SLOW $tmp,$mask\n\t"
4676             "AND      $dst,$tmp,$dst" %}
4677   ins_encode %{
4678     __ ldr($dst$$Register, $mem$$Address);
4679     __ mov($dst$$Register->successor(), 0);
4680     __ mov_slow($tmp$$Register, $mask$$constant);
4681     __ andr($dst$$Register, $dst$$Register, $tmp$$Register);
4682   %}
4683   ins_pipe(iload_mem);
4684 %}
4685 #endif
4686 
4687 // Load Unsigned Integer into a Long Register
4688 instruct loadUI2L(iRegL dst, memoryI mem, immL_32bits mask) %{
4689   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
4690   ins_cost(MEMORY_REF_COST);
4691 
4692 #ifdef AARCH64
4693 //size(4);
4694   format %{ "LDR_w $dst,$mem\t! uint -> long" %}
4695   ins_encode %{
4696     __ ldr_w($dst$$Register, $mem$$Address);
4697   %}
4698 #else
4699   size(8);
4700   format %{ "LDR   $dst.lo,$mem\t! uint -> long\n\t"
4701             "MOV   $dst.hi,0" %}
4702   ins_encode %{
4703     __ ldr($dst$$Register, $mem$$Address);
4704     __ mov($dst$$Register->successor(), 0);
4705   %}
4706 #endif
4707   ins_pipe(iload_mem);
4708 %}
4709 
4710 // Load Long
4711 
4712 #ifdef AARCH64
4713 // XXX This variant shouldn't be necessary if 6217251 is implemented
4714 instruct loadLoff(iRegLd dst, memoryScaledL mem, aimmX off, iRegP tmp) %{
4715   match(Set dst (LoadL (AddP mem off)));
4716   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
4717   effect(TEMP tmp);
4718   size(4 * 2);
4719 
4720   format %{ "LDR    $dst,$mem+$off\t! long temp=$tmp" %}
4721   ins_encode %{
4722     Register base = reg_to_register_object($mem$$base);
4723     __ add($tmp$$Register, base, $off$$constant);
4724     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4725     __ ldr($dst$$Register, nmem);
4726   %}
4727   ins_pipe(iload_mem);
4728 %}
4729 #endif
4730 
4731 instruct loadL(iRegLd dst, memoryL mem ) %{
4732 #ifdef AARCH64
4733   // already atomic for Aarch64
4734 #else
4735   predicate(!((LoadLNode*)n)->require_atomic_access());
4736 #endif
4737   match(Set dst (LoadL mem));
4738   effect(TEMP dst);
4739   ins_cost(MEMORY_REF_COST);
4740 
4741   size(4);
4742   format %{ "ldr_64  $dst,$mem\t! long" %}
4743   ins_encode %{
4744     __ ldr_64($dst$$Register, $mem$$Address);
4745   %}
4746   ins_pipe(iload_mem);
4747 %}
4748 
4749 #ifndef AARCH64
4750 instruct loadL_2instr(iRegL dst, memorylong mem ) %{
4751   predicate(!((LoadLNode*)n)->require_atomic_access());
4752   match(Set dst (LoadL mem));
4753   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
4754 
4755   size(8);
4756   format %{ "LDR    $dst.lo,$mem \t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
4757             "LDR    $dst.hi,$mem+4 or $mem" %}
4758   ins_encode %{
4759     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4760     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
4761 
4762     if ($dst$$Register == reg_to_register_object($mem$$base)) {
4763       __ ldr($dst$$Register->successor(), Amemhi);
4764       __ ldr($dst$$Register, Amemlo);
4765     } else {
4766       __ ldr($dst$$Register, Amemlo);
4767       __ ldr($dst$$Register->successor(), Amemhi);
4768     }
4769   %}
4770   ins_pipe(iload_mem);
4771 %}
4772 
4773 instruct loadL_volatile(iRegL dst, indirect mem ) %{
4774   predicate(((LoadLNode*)n)->require_atomic_access());
4775   match(Set dst (LoadL mem));
4776   ins_cost(MEMORY_REF_COST);
4777 
4778   size(4);
4779   format %{ "LDMIA    $dst,$mem\t! long" %}
4780   ins_encode %{
4781     // FIXME: why is ldmia considered atomic?  Should be ldrexd
4782     RegisterSet set($dst$$Register);
4783     set = set | reg_to_register_object($dst$$reg + 1);
4784     __ ldmia(reg_to_register_object($mem$$base), set);
4785   %}
4786   ins_pipe(iload_mem);
4787 %}
4788 
4789 instruct loadL_volatile_fp(iRegL dst, memoryD mem ) %{
4790   predicate(((LoadLNode*)n)->require_atomic_access());
4791   match(Set dst (LoadL mem));
4792   ins_cost(MEMORY_REF_COST);
4793 
4794   size(8);
4795   format %{ "FLDD      S14, $mem"
4796             "FMRRD    $dst, S14\t! long \n't" %}
4797   ins_encode %{
4798     __ fldd(S14, $mem$$Address);
4799     __ fmrrd($dst$$Register, $dst$$Register->successor(), S14);
4800   %}
4801   ins_pipe(iload_mem);
4802 %}
4803 
4804 instruct loadL_unaligned(iRegL dst, memorylong mem ) %{
4805   match(Set dst (LoadL_unaligned mem));
4806   ins_cost(MEMORY_REF_COST);
4807 
4808   size(8);
4809   format %{ "LDR    $dst.lo,$mem\t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
4810             "LDR    $dst.hi,$mem+4" %}
4811   ins_encode %{
4812     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4813     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
4814 
4815     if ($dst$$Register == reg_to_register_object($mem$$base)) {
4816       __ ldr($dst$$Register->successor(), Amemhi);
4817       __ ldr($dst$$Register, Amemlo);
4818     } else {
4819       __ ldr($dst$$Register, Amemlo);
4820       __ ldr($dst$$Register->successor(), Amemhi);
4821     }
4822   %}
4823   ins_pipe(iload_mem);
4824 %}
4825 #endif // !AARCH64
4826 
4827 // Load Range
4828 instruct loadRange(iRegI dst, memoryI mem) %{
4829   match(Set dst (LoadRange mem));
4830   ins_cost(MEMORY_REF_COST);
4831 
4832   size(4);
4833   format %{ "LDR_u32 $dst,$mem\t! range" %}
4834   ins_encode %{
4835     __ ldr_u32($dst$$Register, $mem$$Address);
4836   %}
4837   ins_pipe(iload_mem);
4838 %}
4839 
4840 // Load Pointer
4841 
4842 #ifdef AARCH64
4843 // XXX This variant shouldn't be necessary if 6217251 is implemented
4844 instruct loadPoff(iRegP dst, memoryScaledP mem, aimmX off, iRegP tmp) %{
4845   match(Set dst (LoadP (AddP mem off)));
4846   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
4847   effect(TEMP tmp);
4848   size(4 * 2);
4849 
4850   format %{ "LDR    $dst,$mem+$off\t! ptr temp=$tmp" %}
4851   ins_encode %{
4852     Register base = reg_to_register_object($mem$$base);
4853     __ add($tmp$$Register, base, $off$$constant);
4854     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4855     __ ldr($dst$$Register, nmem);
4856   %}
4857   ins_pipe(iload_mem);
4858 %}
4859 #endif
4860 
4861 instruct loadP(iRegP dst, memoryP mem) %{
4862   match(Set dst (LoadP mem));
4863   ins_cost(MEMORY_REF_COST);
4864   size(4);
4865 
4866   format %{ "LDR   $dst,$mem\t! ptr" %}
4867   ins_encode %{
4868     __ ldr($dst$$Register, $mem$$Address);
4869   %}
4870   ins_pipe(iload_mem);
4871 %}
4872 
4873 #ifdef XXX
4874 // FIXME XXXX
4875 //instruct loadSP(iRegP dst, memoryP mem) %{
4876 instruct loadSP(SPRegP dst, memoryP mem, iRegP tmp) %{
4877   match(Set dst (LoadP mem));
4878   effect(TEMP tmp);
4879   ins_cost(MEMORY_REF_COST+1);
4880   size(8);
4881 
4882   format %{ "LDR   $tmp,$mem\t! ptr\n\t"
4883             "MOV   $dst,$tmp\t! ptr" %}
4884   ins_encode %{
4885     __ ldr($tmp$$Register, $mem$$Address);
4886     __ mov($dst$$Register, $tmp$$Register);
4887   %}
4888   ins_pipe(iload_mem);
4889 %}
4890 #endif
4891 
4892 #ifdef _LP64
4893 // Load Compressed Pointer
4894 
4895 // XXX This variant shouldn't be necessary if 6217251 is implemented
4896 instruct loadNoff(iRegN dst, memoryScaledI mem, aimmX off, iRegP tmp) %{
4897   match(Set dst (LoadN (AddP mem off)));
4898   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
4899   effect(TEMP tmp);
4900   size(4 * 2);
4901 
4902   format %{ "ldr_u32 $dst,$mem+$off\t! compressed ptr temp=$tmp" %}
4903   ins_encode %{
4904     Register base = reg_to_register_object($mem$$base);
4905     __ add($tmp$$Register, base, $off$$constant);
4906     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4907     __ ldr_u32($dst$$Register, nmem);
4908   %}
4909   ins_pipe(iload_mem);
4910 %}
4911 
4912 instruct loadN(iRegN dst, memoryI mem) %{
4913   match(Set dst (LoadN mem));
4914   ins_cost(MEMORY_REF_COST);
4915   size(4);
4916 
4917   format %{ "ldr_u32 $dst,$mem\t! compressed ptr" %}
4918   ins_encode %{
4919     __ ldr_u32($dst$$Register, $mem$$Address);
4920   %}
4921   ins_pipe(iload_mem);
4922 %}
4923 #endif
4924 
4925 // Load Klass Pointer
4926 instruct loadKlass(iRegP dst, memoryI mem) %{
4927   match(Set dst (LoadKlass mem));
4928   ins_cost(MEMORY_REF_COST);
4929   size(4);
4930 
4931   format %{ "LDR   $dst,$mem\t! klass ptr" %}
4932   ins_encode %{
4933     __ ldr($dst$$Register, $mem$$Address);
4934   %}
4935   ins_pipe(iload_mem);
4936 %}
4937 
4938 #ifdef _LP64
4939 // Load narrow Klass Pointer
4940 instruct loadNKlass(iRegN dst, memoryI mem) %{
4941   match(Set dst (LoadNKlass mem));
4942   ins_cost(MEMORY_REF_COST);
4943   size(4);
4944 
4945   format %{ "ldr_u32 $dst,$mem\t! compressed klass ptr" %}
4946   ins_encode %{
4947     __ ldr_u32($dst$$Register, $mem$$Address);
4948   %}
4949   ins_pipe(iload_mem);
4950 %}
4951 #endif
4952 
4953 #ifdef AARCH64
4954 // XXX This variant shouldn't be necessary if 6217251 is implemented
4955 instruct loadDoff(regD dst, memoryScaledD mem, aimmX off, iRegP tmp) %{
4956   match(Set dst (LoadD (AddP mem off)));
4957   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
4958   effect(TEMP tmp);
4959   size(4 * 2);
4960 
4961   format %{ "ldr    $dst,$mem+$off\t! double temp=$tmp" %}
4962   ins_encode %{
4963     Register base = reg_to_register_object($mem$$base);
4964     __ add($tmp$$Register, base, $off$$constant);
4965     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4966     __ ldr_d($dst$$FloatRegister, nmem);
4967   %}
4968   ins_pipe(floadD_mem);
4969 %}
4970 #endif
4971 
4972 instruct loadD(regD dst, memoryD mem) %{
4973   match(Set dst (LoadD mem));
4974   ins_cost(MEMORY_REF_COST);
4975 
4976   size(4);
4977   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
4978   // only LDREXD and STREXD are 64-bit single-copy atomic
4979   format %{ "FLDD   $dst,$mem" %}
4980   ins_encode %{
4981     __ ldr_double($dst$$FloatRegister, $mem$$Address);
4982   %}
4983   ins_pipe(floadD_mem);
4984 %}
4985 
4986 #ifndef AARCH64
4987 // Load Double - UNaligned
4988 instruct loadD_unaligned(regD_low dst, memoryF2 mem ) %{
4989   match(Set dst (LoadD_unaligned mem));
4990   ins_cost(MEMORY_REF_COST*2+DEFAULT_COST);
4991   size(8);
4992   format %{ "FLDS    $dst.lo,$mem\t! misaligned double\n"
4993           "\tFLDS    $dst.hi,$mem+4\t!" %}
4994   ins_encode %{
4995     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4996     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
4997       __ flds($dst$$FloatRegister, Amemlo);
4998       __ flds($dst$$FloatRegister->successor(), Amemhi);
4999   %}
5000   ins_pipe(iload_mem);
5001 %}
5002 #endif
5003 
5004 #ifdef AARCH64
5005 // XXX This variant shouldn't be necessary if 6217251 is implemented
5006 instruct loadFoff(regF dst, memoryScaledF mem, aimmX off, iRegP tmp) %{
5007   match(Set dst (LoadF (AddP mem off)));
5008   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
5009   effect(TEMP tmp);
5010   size(4 * 2);
5011 
5012   format %{ "ldr    $dst,$mem+$off\t! float temp=$tmp" %}
5013   ins_encode %{
5014     Register base = reg_to_register_object($mem$$base);
5015     __ add($tmp$$Register, base, $off$$constant);
5016     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
5017     __ ldr_s($dst$$FloatRegister, nmem);
5018   %}
5019   ins_pipe(floadF_mem);
5020 %}
5021 #endif
5022 
5023 instruct loadF(regF dst, memoryF mem) %{
5024   match(Set dst (LoadF mem));
5025 
5026   ins_cost(MEMORY_REF_COST);
5027   size(4);
5028   format %{ "FLDS    $dst,$mem" %}
5029   ins_encode %{
5030     __ ldr_float($dst$$FloatRegister, $mem$$Address);
5031   %}
5032   ins_pipe(floadF_mem);
5033 %}
5034 
5035 #ifdef AARCH64
5036 instruct load_limmI(iRegI dst, limmI src) %{
5037   match(Set dst src);
5038   ins_cost(DEFAULT_COST + 1); // + 1 because MOV is preferred
5039   format %{ "ORR_w  $dst, ZR, $src\t! int"  %}
5040   ins_encode %{
5041     __ orr_w($dst$$Register, ZR, (uintx)$src$$constant);
5042   %}
5043   ins_pipe(ialu_imm);
5044 %}
5045 #endif
5046 
5047 // // Load Constant
5048 instruct loadConI( iRegI dst, immI src ) %{
5049   match(Set dst src);
5050   ins_cost(DEFAULT_COST * 3/2);
5051   format %{ "MOV_SLOW    $dst, $src" %}
5052   ins_encode %{
5053     __ mov_slow($dst$$Register, $src$$constant);
5054   %}
5055   ins_pipe(ialu_hi_lo_reg);
5056 %}
5057 
5058 instruct loadConIMov( iRegI dst, immIMov src ) %{
5059   match(Set dst src);
5060   size(4);
5061   format %{ "MOV    $dst, $src" %}
5062   ins_encode %{
5063     __ mov($dst$$Register, $src$$constant);
5064   %}
5065   ins_pipe(ialu_imm);
5066 %}
5067 
5068 #ifndef AARCH64
5069 instruct loadConIMovn( iRegI dst, immIRotn src ) %{
5070   match(Set dst src);
5071   size(4);
5072   format %{ "MVN    $dst, ~$src" %}
5073   ins_encode %{
5074     __ mvn($dst$$Register, ~$src$$constant);
5075   %}
5076   ins_pipe(ialu_imm_n);
5077 %}
5078 #endif
5079 
5080 instruct loadConI16( iRegI dst, immI16 src ) %{
5081   match(Set dst src);
5082   size(4);
5083 #ifdef AARCH64
5084   format %{ "MOVZ_w  $dst, $src" %}
5085 #else
5086   format %{ "MOVW    $dst, $src" %}
5087 #endif
5088   ins_encode %{
5089 #ifdef AARCH64
5090     __ mov_w($dst$$Register, $src$$constant);
5091 #else
5092     __ movw($dst$$Register, $src$$constant);
5093 #endif
5094   %}
5095   ins_pipe(ialu_imm_n);
5096 %}
5097 
5098 instruct loadConP(iRegP dst, immP src) %{
5099   match(Set dst src);
5100   ins_cost(DEFAULT_COST * 3/2);
5101   format %{ "MOV_SLOW    $dst,$src\t!ptr" %}
5102   ins_encode %{
5103     relocInfo::relocType constant_reloc = _opnds[1]->constant_reloc();
5104     intptr_t val = $src$$constant;
5105     if (constant_reloc == relocInfo::oop_type) {
5106       __ mov_oop($dst$$Register, (jobject)val);
5107     } else if (constant_reloc == relocInfo::metadata_type) {
5108       __ mov_metadata($dst$$Register, (Metadata*)val);
5109     } else {
5110       __ mov_slow($dst$$Register, val);
5111     }
5112   %}
5113   ins_pipe(loadConP);
5114 %}
5115 
5116 
5117 instruct loadConP_poll(iRegP dst, immP_poll src) %{
5118   match(Set dst src);
5119   ins_cost(DEFAULT_COST);
5120   format %{ "MOV_SLOW    $dst,$src\t!ptr" %}
5121   ins_encode %{
5122       __ mov_slow($dst$$Register, $src$$constant);
5123   %}
5124   ins_pipe(loadConP_poll);
5125 %}
5126 
5127 #ifdef AARCH64
5128 instruct loadConP0(iRegP dst, immP0 src) %{
5129   match(Set dst src);
5130   ins_cost(DEFAULT_COST);
5131   format %{ "MOV    $dst,ZR\t!ptr" %}
5132   ins_encode %{
5133     __ mov($dst$$Register, ZR);
5134   %}
5135   ins_pipe(ialu_none);
5136 %}
5137 
5138 instruct loadConN(iRegN dst, immN src) %{
5139   match(Set dst src);
5140   ins_cost(DEFAULT_COST * 3/2);
5141   format %{ "SET    $dst,$src\t! compressed ptr" %}
5142   ins_encode %{
5143     Register dst = $dst$$Register;
5144     // FIXME: use $constanttablebase?
5145     __ set_narrow_oop(dst, (jobject)$src$$constant);
5146   %}
5147   ins_pipe(ialu_hi_lo_reg);
5148 %}
5149 
5150 instruct loadConN0(iRegN dst, immN0 src) %{
5151   match(Set dst src);
5152   ins_cost(DEFAULT_COST);
5153   format %{ "MOV    $dst,ZR\t! compressed ptr" %}
5154   ins_encode %{
5155     __ mov($dst$$Register, ZR);
5156   %}
5157   ins_pipe(ialu_none);
5158 %}
5159 
5160 instruct loadConNKlass(iRegN dst, immNKlass src) %{
5161   match(Set dst src);
5162   ins_cost(DEFAULT_COST * 3/2);
5163   format %{ "SET    $dst,$src\t! compressed klass ptr" %}
5164   ins_encode %{
5165     Register dst = $dst$$Register;
5166     // FIXME: use $constanttablebase?
5167     __ set_narrow_klass(dst, (Klass*)$src$$constant);
5168   %}
5169   ins_pipe(ialu_hi_lo_reg);
5170 %}
5171 
5172 instruct load_limmL(iRegL dst, limmL src) %{
5173   match(Set dst src);
5174   ins_cost(DEFAULT_COST);
5175   format %{ "ORR    $dst, ZR, $src\t! long"  %}
5176   ins_encode %{
5177     __ orr($dst$$Register, ZR, (uintx)$src$$constant);
5178   %}
5179   ins_pipe(loadConL);
5180 %}
5181 instruct load_immLMov(iRegL dst, immLMov src) %{
5182   match(Set dst src);
5183   ins_cost(DEFAULT_COST);
5184   format %{ "MOV    $dst, $src\t! long"  %}
5185   ins_encode %{
5186     __ mov($dst$$Register, $src$$constant);
5187   %}
5188   ins_pipe(loadConL);
5189 %}
5190 instruct loadConL(iRegL dst, immL src) %{
5191   match(Set dst src);
5192   ins_cost(DEFAULT_COST * 4); // worst case
5193   format %{ "mov_slow   $dst, $src\t! long"  %}
5194   ins_encode %{
5195     // FIXME: use $constanttablebase?
5196     __ mov_slow($dst$$Register, $src$$constant);
5197   %}
5198   ins_pipe(loadConL);
5199 %}
5200 #else
5201 instruct loadConL(iRegL dst, immL src) %{
5202   match(Set dst src);
5203   ins_cost(DEFAULT_COST * 4);
5204   format %{ "MOV_SLOW   $dst.lo, $src & 0x0FFFFFFFFL \t! long\n\t"
5205             "MOV_SLOW   $dst.hi, $src >> 32" %}
5206   ins_encode %{
5207     __ mov_slow(reg_to_register_object($dst$$reg), $src$$constant & 0x0FFFFFFFFL);
5208     __ mov_slow(reg_to_register_object($dst$$reg + 1), ((julong)($src$$constant)) >> 32);
5209   %}
5210   ins_pipe(loadConL);
5211 %}
5212 
5213 instruct loadConL16( iRegL dst, immL16 src ) %{
5214   match(Set dst src);
5215   ins_cost(DEFAULT_COST * 2);
5216 
5217   size(8);
5218   format %{ "MOVW    $dst.lo, $src \n\t"
5219             "MOVW    $dst.hi, 0 \n\t" %}
5220   ins_encode %{
5221     __ movw($dst$$Register, $src$$constant);
5222     __ movw($dst$$Register->successor(), 0);
5223   %}
5224   ins_pipe(ialu_imm);
5225 %}
5226 #endif
5227 
5228 instruct loadConF_imm8(regF dst, imm8F src) %{
5229   match(Set dst src);
5230   ins_cost(DEFAULT_COST);
5231   size(4);
5232 
5233   format %{ "FCONSTS      $dst, $src"%}
5234 
5235   ins_encode %{
5236     __ fconsts($dst$$FloatRegister, Assembler::float_num($src$$constant).imm8());
5237   %}
5238   ins_pipe(loadConFD); // FIXME
5239 %}
5240 
5241 #ifdef AARCH64
5242 instruct loadIConF(iRegI dst, immF src) %{
5243   match(Set dst src);
5244   ins_cost(DEFAULT_COST * 2);
5245 
5246   format %{ "MOV_SLOW  $dst, $src\t! loadIConF"  %}
5247 
5248   ins_encode %{
5249     // FIXME revisit once 6961697 is in
5250     union {
5251       jfloat f;
5252       int i;
5253     } v;
5254     v.f = $src$$constant;
5255     __ mov_slow($dst$$Register, v.i);
5256   %}
5257   ins_pipe(ialu_imm);
5258 %}
5259 #endif
5260 
5261 instruct loadConF(regF dst, immF src, iRegI tmp) %{
5262   match(Set dst src);
5263   ins_cost(DEFAULT_COST * 2);
5264   effect(TEMP tmp);
5265   size(3*4);
5266 
5267   format %{ "MOV_SLOW  $tmp, $src\n\t"
5268             "FMSR      $dst, $tmp"%}
5269 
5270   ins_encode %{
5271     // FIXME revisit once 6961697 is in
5272     union {
5273       jfloat f;
5274       int i;
5275     } v;
5276     v.f = $src$$constant;
5277     __ mov_slow($tmp$$Register, v.i);
5278     __ fmsr($dst$$FloatRegister, $tmp$$Register);
5279   %}
5280   ins_pipe(loadConFD); // FIXME
5281 %}
5282 
5283 instruct loadConD_imm8(regD dst, imm8D src) %{
5284   match(Set dst src);
5285   ins_cost(DEFAULT_COST);
5286   size(4);
5287 
5288   format %{ "FCONSTD      $dst, $src"%}
5289 
5290   ins_encode %{
5291     __ fconstd($dst$$FloatRegister, Assembler::double_num($src$$constant).imm8());
5292   %}
5293   ins_pipe(loadConFD); // FIXME
5294 %}
5295 
5296 instruct loadConD(regD dst, immD src, iRegP tmp) %{
5297   match(Set dst src);
5298   effect(TEMP tmp);
5299   ins_cost(MEMORY_REF_COST);
5300   format %{ "FLDD  $dst, [$constanttablebase + $constantoffset]\t! load from constant table: double=$src" %}
5301 
5302   ins_encode %{
5303     Register r = $constanttablebase;
5304     int offset  = $constantoffset($src);
5305     if (!is_memoryD(offset)) {                // can't use a predicate
5306                                               // in load constant instructs
5307       __ add_slow($tmp$$Register, r, offset);
5308       r = $tmp$$Register;
5309       offset = 0;
5310     }
5311     __ ldr_double($dst$$FloatRegister, Address(r, offset));
5312   %}
5313   ins_pipe(loadConFD);
5314 %}
5315 
5316 // Prefetch instructions.
5317 // Must be safe to execute with invalid address (cannot fault).
5318 
5319 instruct prefetchAlloc( memoryP mem ) %{
5320   match( PrefetchAllocation mem );
5321   ins_cost(MEMORY_REF_COST);
5322   size(4);
5323 
5324   format %{ "PLDW $mem\t! Prefetch allocation" %}
5325   ins_encode %{
5326 #ifdef AARCH64
5327     __ prfm(pstl1keep, $mem$$Address);
5328 #else
5329     __ pldw($mem$$Address);
5330 #endif
5331   %}
5332   ins_pipe(iload_mem);
5333 %}
5334 
5335 //----------Store Instructions-------------------------------------------------
5336 // Store Byte
5337 instruct storeB(memoryB mem, store_RegI src) %{
5338   match(Set mem (StoreB mem src));
5339   ins_cost(MEMORY_REF_COST);
5340 
5341   size(4);
5342   format %{ "STRB    $src,$mem\t! byte" %}
5343   ins_encode %{
5344     __ strb($src$$Register, $mem$$Address);
5345   %}
5346   ins_pipe(istore_mem_reg);
5347 %}
5348 
5349 instruct storeCM(memoryB mem, store_RegI src) %{
5350   match(Set mem (StoreCM mem src));
5351   ins_cost(MEMORY_REF_COST);
5352 
5353   size(4);
5354   format %{ "STRB    $src,$mem\t! CMS card-mark byte" %}
5355   ins_encode %{
5356     __ strb($src$$Register, $mem$$Address);
5357   %}
5358   ins_pipe(istore_mem_reg);
5359 %}
5360 
5361 // Store Char/Short
5362 
5363 #ifdef AARCH64
5364 // XXX This variant shouldn't be necessary if 6217251 is implemented
5365 instruct storeCoff(store_RegI src, memoryScaledS mem, aimmX off, iRegP tmp) %{
5366   match(Set mem (StoreC (AddP mem off) src));
5367   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
5368   effect(TEMP tmp);
5369   size(4 * 2);
5370 
5371   format %{ "STRH    $src,$mem+$off\t! short temp=$tmp" %}
5372   ins_encode %{
5373     Register base = reg_to_register_object($mem$$base);
5374     __ add($tmp$$Register, base, $off$$constant);
5375     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
5376     __ strh($src$$Register, nmem);
5377   %}
5378   ins_pipe(istore_mem_reg);
5379 %}
5380 #endif
5381 
5382 instruct storeC(memoryS mem, store_RegI src) %{
5383   match(Set mem (StoreC mem src));
5384   ins_cost(MEMORY_REF_COST);
5385 
5386   size(4);
5387   format %{ "STRH    $src,$mem\t! short" %}
5388   ins_encode %{
5389     __ strh($src$$Register, $mem$$Address);
5390   %}
5391   ins_pipe(istore_mem_reg);
5392 %}
5393 
5394 // Store Integer
5395 
5396 #ifdef AARCH64
5397 // XXX This variant shouldn't be necessary if 6217251 is implemented
5398 instruct storeIoff(store_RegI src, memoryScaledI mem, aimmX off, iRegP tmp) %{
5399   match(Set mem (StoreI (AddP mem off) src));
5400   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
5401   effect(TEMP tmp);
5402   size(4 * 2);
5403 
5404   format %{ "str_32 $src,$mem+$off\t! int temp=$tmp" %}
5405   ins_encode %{
5406     Register base = reg_to_register_object($mem$$base);
5407     __ add($tmp$$Register, base, $off$$constant);
5408     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
5409     __ str_32($src$$Register, nmem);
5410   %}
5411   ins_pipe(istore_mem_reg);
5412 %}
5413 #endif
5414 
5415 instruct storeI(memoryI mem, store_RegI src) %{
5416   match(Set mem (StoreI mem src));
5417   ins_cost(MEMORY_REF_COST);
5418 
5419   size(4);
5420   format %{ "str_32 $src,$mem" %}
5421   ins_encode %{
5422     __ str_32($src$$Register, $mem$$Address);
5423   %}
5424   ins_pipe(istore_mem_reg);
5425 %}
5426 
5427 // Store Long
5428 
5429 #ifdef AARCH64
5430 // XXX This variant shouldn't be necessary if 6217251 is implemented
5431 instruct storeLoff(store_RegLd src, memoryScaledL mem, aimmX off, iRegP tmp) %{
5432   match(Set mem (StoreL (AddP mem off) src));
5433   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
5434   effect(TEMP tmp);
5435   size(4 * 2);
5436 
5437   format %{ "str_64 $src,$mem+$off\t! long temp=$tmp" %}
5438   ins_encode %{
5439     Register base = reg_to_register_object($mem$$base);
5440     __ add($tmp$$Register, base, $off$$constant);
5441     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
5442     __ str_64($src$$Register, nmem);
5443   %}
5444   ins_pipe(istore_mem_reg);
5445 %}
5446 #endif
5447 
5448 instruct storeL(memoryL mem, store_RegLd src) %{
5449 #ifdef AARCH64
5450   // already atomic for Aarch64
5451 #else
5452   predicate(!((StoreLNode*)n)->require_atomic_access());
5453 #endif
5454   match(Set mem (StoreL mem src));
5455   ins_cost(MEMORY_REF_COST);
5456 
5457   size(4);
5458   format %{ "str_64  $src,$mem\t! long\n\t" %}
5459 
5460   ins_encode %{
5461     __ str_64($src$$Register, $mem$$Address);
5462   %}
5463   ins_pipe(istore_mem_reg);
5464 %}
5465 
5466 #ifndef AARCH64
5467 instruct storeL_2instr(memorylong mem, iRegL src) %{
5468   predicate(!((StoreLNode*)n)->require_atomic_access());
5469   match(Set mem (StoreL mem src));
5470   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
5471 
5472   size(8);
5473   format %{ "STR    $src.lo,$mem\t! long\n\t"
5474             "STR    $src.hi,$mem+4" %}
5475 
5476   ins_encode %{
5477     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
5478     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
5479     __ str($src$$Register, Amemlo);
5480     __ str($src$$Register->successor(), Amemhi);
5481   %}
5482   ins_pipe(istore_mem_reg);
5483 %}
5484 
5485 instruct storeL_volatile(indirect mem, iRegL src) %{
5486   predicate(((StoreLNode*)n)->require_atomic_access());
5487   match(Set mem (StoreL mem src));
5488   ins_cost(MEMORY_REF_COST);
5489   size(4);
5490   format %{ "STMIA    $src,$mem\t! long" %}
5491   ins_encode %{
5492     // FIXME: why is stmia considered atomic?  Should be strexd
5493     RegisterSet set($src$$Register);
5494     set = set | reg_to_register_object($src$$reg + 1);
5495     __ stmia(reg_to_register_object($mem$$base), set);
5496   %}
5497   ins_pipe(istore_mem_reg);
5498 %}
5499 #endif // !AARCH64
5500 
5501 #ifndef AARCH64
5502 instruct storeL_volatile_fp(memoryD mem, iRegL src) %{
5503   predicate(((StoreLNode*)n)->require_atomic_access());
5504   match(Set mem (StoreL mem src));
5505   ins_cost(MEMORY_REF_COST);
5506   size(8);
5507   format %{ "FMDRR    S14, $src\t! long \n\t"
5508             "FSTD     S14, $mem" %}
5509   ins_encode %{
5510     __ fmdrr(S14, $src$$Register, $src$$Register->successor());
5511     __ fstd(S14, $mem$$Address);
5512   %}
5513   ins_pipe(istore_mem_reg);
5514 %}
5515 #endif
5516 
5517 #ifdef XXX
5518 // Move SP Pointer
5519 //instruct movSP(sp_ptr_RegP dst, SPRegP src) %{
5520 //instruct movSP(iRegP dst, SPRegP src) %{
5521 instruct movSP(store_ptr_RegP dst, SPRegP src) %{
5522   match(Set dst src);
5523 //predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con == TypeFunc::FramePtr);
5524   ins_cost(MEMORY_REF_COST);
5525   size(4);
5526 
5527   format %{ "MOV    $dst,$src\t! SP ptr\n\t" %}
5528   ins_encode %{
5529     assert(false, "XXX1 got here");
5530     __ mov($dst$$Register, SP);
5531     __ mov($dst$$Register, $src$$Register);
5532   %}
5533   ins_pipe(ialu_reg);
5534 %}
5535 #endif
5536 
5537 #ifdef AARCH64
5538 // FIXME
5539 // Store SP Pointer
5540 instruct storeSP(memoryP mem, SPRegP src, iRegP tmp) %{
5541   match(Set mem (StoreP mem src));
5542   predicate(_kids[1]->_leaf->is_Proj() && _kids[1]->_leaf->as_Proj()->_con == TypeFunc::FramePtr);
5543   // Multiple StoreP rules, different only in register mask.
5544   // Matcher makes the last always valid.  The others will
5545   // only be valid if they cost less than the last valid
5546   // rule.  So cost(rule1) < cost(rule2) < cost(last)
5547   // Unlike immediates, register constraints are not checked
5548   // at match time.
5549   ins_cost(MEMORY_REF_COST+DEFAULT_COST+4);
5550   effect(TEMP tmp);
5551   size(8);
5552 
5553   format %{ "MOV    $tmp,$src\t! SP ptr\n\t"
5554             "STR    $tmp,$mem\t! SP ptr" %}
5555   ins_encode %{
5556     assert($src$$Register == SP, "SP expected");
5557     __ mov($tmp$$Register, $src$$Register);
5558     __ str($tmp$$Register, $mem$$Address);
5559   %}
5560   ins_pipe(istore_mem_spORreg); // FIXME
5561 %}
5562 #endif // AARCH64
5563 
5564 // Store Pointer
5565 
5566 #ifdef AARCH64
5567 // XXX This variant shouldn't be necessary if 6217251 is implemented
5568 instruct storePoff(store_ptr_RegP src, memoryScaledP mem, aimmX off, iRegP tmp) %{
5569   predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con != TypeFunc::FramePtr);
5570   match(Set mem (StoreP (AddP mem off) src));
5571   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
5572   effect(TEMP tmp);
5573   size(4 * 2);
5574 
5575   format %{ "STR    $src,$mem+$off\t! ptr temp=$tmp" %}
5576   ins_encode %{
5577     Register base = reg_to_register_object($mem$$base);
5578     __ add($tmp$$Register, base, $off$$constant);
5579     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
5580     __ str($src$$Register, nmem);
5581   %}
5582   ins_pipe(istore_mem_reg);
5583 %}
5584 #endif
5585 
5586 instruct storeP(memoryP mem, store_ptr_RegP src) %{
5587   match(Set mem (StoreP mem src));
5588 #ifdef AARCH64
5589   predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con != TypeFunc::FramePtr);
5590 #endif
5591   ins_cost(MEMORY_REF_COST);
5592   size(4);
5593 
5594   format %{ "STR    $src,$mem\t! ptr" %}
5595   ins_encode %{
5596     __ str($src$$Register, $mem$$Address);
5597   %}
5598   ins_pipe(istore_mem_spORreg);
5599 %}
5600 
5601 #ifdef AARCH64
5602 // Store NULL Pointer
5603 instruct storeP0(memoryP mem, immP0 src) %{
5604   match(Set mem (StoreP mem src));
5605   ins_cost(MEMORY_REF_COST);
5606   size(4);
5607 
5608   format %{ "STR    ZR,$mem\t! ptr" %}
5609   ins_encode %{
5610     __ str(ZR, $mem$$Address);
5611   %}
5612   ins_pipe(istore_mem_spORreg);
5613 %}
5614 #endif // AARCH64
5615 
5616 #ifdef _LP64
5617 // Store Compressed Pointer
5618 
5619 #ifdef AARCH64
5620 // XXX This variant shouldn't be necessary if 6217251 is implemented
5621 instruct storeNoff(store_RegN src, memoryScaledI mem, aimmX off, iRegP tmp) %{
5622   match(Set mem (StoreN (AddP mem off) src));
5623   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
5624   effect(TEMP tmp);
5625   size(4 * 2);
5626 
5627   format %{ "str_32 $src,$mem+$off\t! compressed ptr temp=$tmp" %}
5628   ins_encode %{
5629     Register base = reg_to_register_object($mem$$base);
5630     __ add($tmp$$Register, base, $off$$constant);
5631     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
5632     __ str_32($src$$Register, nmem);
5633   %}
5634   ins_pipe(istore_mem_reg);
5635 %}
5636 #endif
5637 
5638 instruct storeN(memoryI mem, store_RegN src) %{
5639   match(Set mem (StoreN mem src));
5640   ins_cost(MEMORY_REF_COST);
5641   size(4);
5642 
5643   format %{ "str_32 $src,$mem\t! compressed ptr" %}
5644   ins_encode %{
5645     __ str_32($src$$Register, $mem$$Address);
5646   %}
5647   ins_pipe(istore_mem_reg);
5648 %}
5649 
5650 #ifdef AARCH64
5651 // Store NULL Pointer
5652 instruct storeN0(memoryI mem, immN0 src) %{
5653   match(Set mem (StoreN mem src));
5654   ins_cost(MEMORY_REF_COST);
5655   size(4);
5656 
5657   format %{ "str_32 ZR,$mem\t! compressed ptr" %}
5658   ins_encode %{
5659     __ str_32(ZR, $mem$$Address);
5660   %}
5661   ins_pipe(istore_mem_reg);
5662 %}
5663 #endif
5664 
5665 // Store Compressed Klass Pointer
5666 instruct storeNKlass(memoryI mem, store_RegN src) %{
5667   match(Set mem (StoreNKlass mem src));
5668   ins_cost(MEMORY_REF_COST);
5669   size(4);
5670 
5671   format %{ "str_32 $src,$mem\t! compressed klass ptr" %}
5672   ins_encode %{
5673     __ str_32($src$$Register, $mem$$Address);
5674   %}
5675   ins_pipe(istore_mem_reg);
5676 %}
5677 #endif
5678 
5679 // Store Double
5680 
5681 #ifdef AARCH64
5682 // XXX This variant shouldn't be necessary if 6217251 is implemented
5683 instruct storeDoff(regD src, memoryScaledD mem, aimmX off, iRegP tmp) %{
5684   match(Set mem (StoreD (AddP mem off) src));
5685   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
5686   effect(TEMP tmp);
5687   size(4 * 2);
5688 
5689   format %{ "STR    $src,$mem+$off\t! double temp=$tmp" %}
5690   ins_encode %{
5691     Register base = reg_to_register_object($mem$$base);
5692     __ add($tmp$$Register, base, $off$$constant);
5693     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
5694     __ str_d($src$$FloatRegister, nmem);
5695   %}
5696   ins_pipe(fstoreD_mem_reg);
5697 %}
5698 #endif
5699 
5700 instruct storeD(memoryD mem, regD src) %{
5701   match(Set mem (StoreD mem src));
5702   ins_cost(MEMORY_REF_COST);
5703 
5704   size(4);
5705   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
5706   // only LDREXD and STREXD are 64-bit single-copy atomic
5707   format %{ "FSTD   $src,$mem" %}
5708   ins_encode %{
5709     __ str_double($src$$FloatRegister, $mem$$Address);
5710   %}
5711   ins_pipe(fstoreD_mem_reg);
5712 %}
5713 
5714 #ifdef AARCH64
5715 instruct movI2F(regF dst, iRegI src) %{
5716   match(Set dst src);
5717   size(4);
5718 
5719   format %{ "FMOV_sw $dst,$src\t! movI2F" %}
5720   ins_encode %{
5721     __ fmov_sw($dst$$FloatRegister, $src$$Register);
5722   %}
5723   ins_pipe(ialu_reg); // FIXME
5724 %}
5725 
5726 instruct movF2I(iRegI dst, regF src) %{
5727   match(Set dst src);
5728   size(4);
5729 
5730   format %{ "FMOV_ws $dst,$src\t! movF2I" %}
5731   ins_encode %{
5732     __ fmov_ws($dst$$Register, $src$$FloatRegister);
5733   %}
5734   ins_pipe(ialu_reg); // FIXME
5735 %}
5736 #endif
5737 
5738 // Store Float
5739 
5740 #ifdef AARCH64
5741 // XXX This variant shouldn't be necessary if 6217251 is implemented
5742 instruct storeFoff(regF src, memoryScaledF mem, aimmX off, iRegP tmp) %{
5743   match(Set mem (StoreF (AddP mem off) src));
5744   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
5745   effect(TEMP tmp);
5746   size(4 * 2);
5747 
5748   format %{ "str_s  $src,$mem+$off\t! float temp=$tmp" %}
5749   ins_encode %{
5750     Register base = reg_to_register_object($mem$$base);
5751     __ add($tmp$$Register, base, $off$$constant);
5752     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
5753     __ str_s($src$$FloatRegister, nmem);
5754   %}
5755   ins_pipe(fstoreF_mem_reg);
5756 %}
5757 #endif
5758 
5759 instruct storeF( memoryF mem, regF src) %{
5760   match(Set mem (StoreF mem src));
5761   ins_cost(MEMORY_REF_COST);
5762 
5763   size(4);
5764   format %{ "FSTS    $src,$mem" %}
5765   ins_encode %{
5766     __ str_float($src$$FloatRegister, $mem$$Address);
5767   %}
5768   ins_pipe(fstoreF_mem_reg);
5769 %}
5770 
5771 #ifdef AARCH64
5772 // Convert oop pointer into compressed form
5773 instruct encodeHeapOop(iRegN dst, iRegP src, flagsReg ccr) %{
5774   predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
5775   match(Set dst (EncodeP src));
5776   effect(KILL ccr);
5777   format %{ "encode_heap_oop $dst, $src" %}
5778   ins_encode %{
5779     __ encode_heap_oop($dst$$Register, $src$$Register);
5780   %}
5781   ins_pipe(ialu_reg);
5782 %}
5783 
5784 instruct encodeHeapOop_not_null(iRegN dst, iRegP src) %{
5785   predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
5786   match(Set dst (EncodeP src));
5787   format %{ "encode_heap_oop_not_null $dst, $src" %}
5788   ins_encode %{
5789     __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
5790   %}
5791   ins_pipe(ialu_reg);
5792 %}
5793 
5794 instruct decodeHeapOop(iRegP dst, iRegN src, flagsReg ccr) %{
5795   predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
5796             n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant);
5797   match(Set dst (DecodeN src));
5798   effect(KILL ccr);
5799   format %{ "decode_heap_oop $dst, $src" %}
5800   ins_encode %{
5801     __ decode_heap_oop($dst$$Register, $src$$Register);
5802   %}
5803   ins_pipe(ialu_reg);
5804 %}
5805 
5806 instruct decodeHeapOop_not_null(iRegP dst, iRegN src) %{
5807   predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
5808             n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant);
5809   match(Set dst (DecodeN src));
5810   format %{ "decode_heap_oop_not_null $dst, $src" %}
5811   ins_encode %{
5812     __ decode_heap_oop_not_null($dst$$Register, $src$$Register);
5813   %}
5814   ins_pipe(ialu_reg);
5815 %}
5816 
5817 instruct encodeKlass_not_null(iRegN dst, iRegP src) %{
5818   match(Set dst (EncodePKlass src));
5819   format %{ "encode_klass_not_null $dst, $src" %}
5820   ins_encode %{
5821     __ encode_klass_not_null($dst$$Register, $src$$Register);
5822   %}
5823   ins_pipe(ialu_reg);
5824 %}
5825 
5826 instruct decodeKlass_not_null(iRegP dst, iRegN src) %{
5827   match(Set dst (DecodeNKlass src));
5828   format %{ "decode_klass_not_null $dst, $src" %}
5829   ins_encode %{
5830     __ decode_klass_not_null($dst$$Register, $src$$Register);
5831   %}
5832   ins_pipe(ialu_reg);
5833 %}
5834 #endif // AARCH64
5835 
5836 //----------MemBar Instructions-----------------------------------------------
5837 // Memory barrier flavors
5838 
5839 // TODO: take advantage of Aarch64 load-acquire, store-release, etc
5840 // pattern-match out unnecessary membars
5841 instruct membar_storestore() %{
5842   match(MemBarStoreStore);
5843   ins_cost(4*MEMORY_REF_COST);
5844 
5845   size(4);
5846   format %{ "MEMBAR-storestore" %}
5847   ins_encode %{
5848     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore), noreg);
5849   %}
5850   ins_pipe(long_memory_op);
5851 %}
5852 
5853 instruct membar_acquire() %{
5854   match(MemBarAcquire);
5855   match(LoadFence);
5856   ins_cost(4*MEMORY_REF_COST);
5857 
5858   size(4);
5859   format %{ "MEMBAR-acquire" %}
5860   ins_encode %{
5861     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), noreg);
5862   %}
5863   ins_pipe(long_memory_op);
5864 %}
5865 
5866 instruct membar_acquire_lock() %{
5867   match(MemBarAcquireLock);
5868   ins_cost(0);
5869 
5870   size(0);
5871   format %{ "!MEMBAR-acquire (CAS in prior FastLock so empty encoding)" %}
5872   ins_encode( );
5873   ins_pipe(empty);
5874 %}
5875 
5876 instruct membar_release() %{
5877   match(MemBarRelease);
5878   match(StoreFence);
5879   ins_cost(4*MEMORY_REF_COST);
5880 
5881   size(4);
5882   format %{ "MEMBAR-release" %}
5883   ins_encode %{
5884     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), noreg);
5885   %}
5886   ins_pipe(long_memory_op);
5887 %}
5888 
5889 instruct membar_release_lock() %{
5890   match(MemBarReleaseLock);
5891   ins_cost(0);
5892 
5893   size(0);
5894   format %{ "!MEMBAR-release (CAS in succeeding FastUnlock so empty encoding)" %}
5895   ins_encode( );
5896   ins_pipe(empty);
5897 %}
5898 
5899 instruct membar_volatile() %{
5900   match(MemBarVolatile);
5901   ins_cost(4*MEMORY_REF_COST);
5902 
5903   size(4);
5904   format %{ "MEMBAR-volatile" %}
5905   ins_encode %{
5906     __ membar(MacroAssembler::StoreLoad, noreg);
5907   %}
5908   ins_pipe(long_memory_op);
5909 %}
5910 
5911 instruct unnecessary_membar_volatile() %{
5912   match(MemBarVolatile);
5913   predicate(Matcher::post_store_load_barrier(n));
5914   ins_cost(0);
5915 
5916   size(0);
5917   format %{ "!MEMBAR-volatile (unnecessary so empty encoding)" %}
5918   ins_encode( );
5919   ins_pipe(empty);
5920 %}
5921 
5922 //----------Register Move Instructions-----------------------------------------
5923 // instruct roundDouble_nop(regD dst) %{
5924 //   match(Set dst (RoundDouble dst));
5925 //   ins_pipe(empty);
5926 // %}
5927 
5928 
5929 // instruct roundFloat_nop(regF dst) %{
5930 //   match(Set dst (RoundFloat dst));
5931 //   ins_pipe(empty);
5932 // %}
5933 
5934 
5935 #ifdef AARCH64
5936 // 0 constant in register
5937 instruct zrImmI0(ZRRegI dst, immI0 imm) %{
5938   match(Set dst imm);
5939   size(0);
5940   ins_cost(0);
5941 
5942   format %{ "! ZR (int 0)" %}
5943   ins_encode( /*empty encoding*/ );
5944   ins_pipe(ialu_none);
5945 %}
5946 
5947 // 0 constant in register
5948 instruct zrImmL0(ZRRegL dst, immL0 imm) %{
5949   match(Set dst imm);
5950   size(0);
5951   ins_cost(0);
5952 
5953   format %{ "! ZR (long 0)" %}
5954   ins_encode( /*empty encoding*/ );
5955   ins_pipe(ialu_none);
5956 %}
5957 
5958 #ifdef XXX
5959 // 0 constant in register
5960 instruct zrImmN0(ZRRegN dst, immN0 imm) %{
5961   match(Set dst imm);
5962   size(0);
5963   ins_cost(0);
5964 
5965   format %{ "! ZR (compressed pointer NULL)" %}
5966   ins_encode( /*empty encoding*/ );
5967   ins_pipe(ialu_none);
5968 %}
5969 
5970 // 0 constant in register
5971 instruct zrImmP0(ZRRegP dst, immP0 imm) %{
5972   match(Set dst imm);
5973   size(0);
5974   ins_cost(0);
5975 
5976   format %{ "! ZR (NULL)" %}
5977   ins_encode( /*empty encoding*/ );
5978   ins_pipe(ialu_none);
5979 %}
5980 #endif
5981 #endif // AARCH64
5982 
5983 // Cast Index to Pointer for unsafe natives
5984 instruct castX2P(iRegX src, iRegP dst) %{
5985   match(Set dst (CastX2P src));
5986 
5987   format %{ "MOV    $dst,$src\t! IntX->Ptr if $dst != $src" %}
5988   ins_encode %{
5989     if ($dst$$Register !=  $src$$Register) {
5990       __ mov($dst$$Register, $src$$Register);
5991     }
5992   %}
5993   ins_pipe(ialu_reg);
5994 %}
5995 
5996 // Cast Pointer to Index for unsafe natives
5997 instruct castP2X(iRegP src, iRegX dst) %{
5998   match(Set dst (CastP2X src));
5999 
6000   format %{ "MOV    $dst,$src\t! Ptr->IntX if $dst != $src" %}
6001   ins_encode %{
6002     if ($dst$$Register !=  $src$$Register) {
6003       __ mov($dst$$Register, $src$$Register);
6004     }
6005   %}
6006   ins_pipe(ialu_reg);
6007 %}
6008 
6009 #ifndef AARCH64
6010 //----------Conditional Move---------------------------------------------------
6011 // Conditional move
6012 instruct cmovIP_reg(cmpOpP cmp, flagsRegP pcc, iRegI dst, iRegI src) %{
6013   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
6014   ins_cost(150);
6015   size(4);
6016   format %{ "MOV$cmp  $dst,$src\t! int" %}
6017   ins_encode %{
6018     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6019   %}
6020   ins_pipe(ialu_reg);
6021 %}
6022 #endif
6023 
6024 #ifdef AARCH64
6025 instruct cmovI_reg3(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src1, iRegI src2) %{
6026   match(Set dst (CMoveI (Binary cmp icc) (Binary src2 src1)));
6027   ins_cost(150);
6028   size(4);
6029   format %{ "CSEL $dst,$src1,$src2,$cmp\t! int" %}
6030   ins_encode %{
6031     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6032   %}
6033   ins_pipe(ialu_reg);
6034 %}
6035 
6036 instruct cmovL_reg3(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src1, iRegL src2) %{
6037   match(Set dst (CMoveL (Binary cmp icc) (Binary src2 src1)));
6038   ins_cost(150);
6039   size(4);
6040   format %{ "CSEL $dst,$src1,$src2,$cmp\t! long" %}
6041   ins_encode %{
6042     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6043   %}
6044   ins_pipe(ialu_reg);
6045 %}
6046 
6047 instruct cmovP_reg3(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src1, iRegP src2) %{
6048   match(Set dst (CMoveP (Binary cmp icc) (Binary src2 src1)));
6049   ins_cost(150);
6050   size(4);
6051   format %{ "CSEL $dst,$src1,$src2,$cmp\t! ptr" %}
6052   ins_encode %{
6053     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6054   %}
6055   ins_pipe(ialu_reg);
6056 %}
6057 
6058 instruct cmovN_reg3(cmpOp cmp, flagsReg icc, iRegN dst, iRegN src1, iRegN src2) %{
6059   match(Set dst (CMoveN (Binary cmp icc) (Binary src2 src1)));
6060   ins_cost(150);
6061   size(4);
6062   format %{ "CSEL $dst,$src1,$src2,$cmp\t! compressed ptr" %}
6063   ins_encode %{
6064     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6065   %}
6066   ins_pipe(ialu_reg);
6067 %}
6068 
6069 instruct cmovIP_reg3(cmpOpP cmp, flagsRegP icc, iRegI dst, iRegI src1, iRegI src2) %{
6070   match(Set dst (CMoveI (Binary cmp icc) (Binary src2 src1)));
6071   ins_cost(150);
6072   size(4);
6073   format %{ "CSEL $dst,$src1,$src2,$cmp\t! int" %}
6074   ins_encode %{
6075     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6076   %}
6077   ins_pipe(ialu_reg);
6078 %}
6079 
6080 instruct cmovLP_reg3(cmpOpP cmp, flagsRegP icc, iRegL dst, iRegL src1, iRegL src2) %{
6081   match(Set dst (CMoveL (Binary cmp icc) (Binary src2 src1)));
6082   ins_cost(150);
6083   size(4);
6084   format %{ "CSEL $dst,$src1,$src2,$cmp\t! long" %}
6085   ins_encode %{
6086     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6087   %}
6088   ins_pipe(ialu_reg);
6089 %}
6090 
6091 instruct cmovPP_reg3(cmpOpP cmp, flagsRegP icc, iRegP dst, iRegP src1, iRegP src2) %{
6092   match(Set dst (CMoveP (Binary cmp icc) (Binary src2 src1)));
6093   ins_cost(150);
6094   size(4);
6095   format %{ "CSEL $dst,$src1,$src2,$cmp\t! ptr" %}
6096   ins_encode %{
6097     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6098   %}
6099   ins_pipe(ialu_reg);
6100 %}
6101 
6102 instruct cmovNP_reg3(cmpOpP cmp, flagsRegP icc, iRegN dst, iRegN src1, iRegN src2) %{
6103   match(Set dst (CMoveN (Binary cmp icc) (Binary src2 src1)));
6104   ins_cost(150);
6105   size(4);
6106   format %{ "CSEL $dst,$src1,$src2,$cmp\t! compressed ptr" %}
6107   ins_encode %{
6108     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6109   %}
6110   ins_pipe(ialu_reg);
6111 %}
6112 
6113 instruct cmovIU_reg3(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src1, iRegI src2) %{
6114   match(Set dst (CMoveI (Binary cmp icc) (Binary src2 src1)));
6115   ins_cost(150);
6116   size(4);
6117   format %{ "CSEL $dst,$src1,$src2,$cmp\t! int" %}
6118   ins_encode %{
6119     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6120   %}
6121   ins_pipe(ialu_reg);
6122 %}
6123 
6124 instruct cmovLU_reg3(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src1, iRegL src2) %{
6125   match(Set dst (CMoveL (Binary cmp icc) (Binary src2 src1)));
6126   ins_cost(150);
6127   size(4);
6128   format %{ "CSEL $dst,$src1,$src2,$cmp\t! long" %}
6129   ins_encode %{
6130     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6131   %}
6132   ins_pipe(ialu_reg);
6133 %}
6134 
6135 instruct cmovPU_reg3(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src1, iRegP src2) %{
6136   match(Set dst (CMoveP (Binary cmp icc) (Binary src2 src1)));
6137   ins_cost(150);
6138   size(4);
6139   format %{ "CSEL $dst,$src1,$src2,$cmp\t! ptr" %}
6140   ins_encode %{
6141     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6142   %}
6143   ins_pipe(ialu_reg);
6144 %}
6145 
6146 instruct cmovNU_reg3(cmpOpU cmp, flagsRegU icc, iRegN dst, iRegN src1, iRegN src2) %{
6147   match(Set dst (CMoveN (Binary cmp icc) (Binary src2 src1)));
6148   ins_cost(150);
6149   size(4);
6150   format %{ "CSEL $dst,$src1,$src2,$cmp\t! compressed ptr" %}
6151   ins_encode %{
6152     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6153   %}
6154   ins_pipe(ialu_reg);
6155 %}
6156 
6157 instruct cmovIZ_reg3(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, iRegI src1, iRegI src2) %{
6158   match(Set dst (CMoveI (Binary cmp icc) (Binary src2 src1)));
6159   ins_cost(150);
6160   size(4);
6161   format %{ "CSEL $dst,$src1,$src2,$cmp\t! int" %}
6162   ins_encode %{
6163     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6164   %}
6165   ins_pipe(ialu_reg);
6166 %}
6167 
6168 instruct cmovLZ_reg3(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, iRegL src1, iRegL src2) %{
6169   match(Set dst (CMoveL (Binary cmp icc) (Binary src2 src1)));
6170   ins_cost(150);
6171   size(4);
6172   format %{ "CSEL $dst,$src1,$src2,$cmp\t! long" %}
6173   ins_encode %{
6174     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6175   %}
6176   ins_pipe(ialu_reg);
6177 %}
6178 
6179 instruct cmovPZ_reg3(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, iRegP src1, iRegP src2) %{
6180   match(Set dst (CMoveP (Binary cmp icc) (Binary src2 src1)));
6181   ins_cost(150);
6182   size(4);
6183   format %{ "CSEL $dst,$src1,$src2,$cmp\t! ptr" %}
6184   ins_encode %{
6185     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6186   %}
6187   ins_pipe(ialu_reg);
6188 %}
6189 
6190 instruct cmovNZ_reg3(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegN dst, iRegN src1, iRegN src2) %{
6191   match(Set dst (CMoveN (Binary cmp icc) (Binary src2 src1)));
6192   ins_cost(150);
6193   size(4);
6194   format %{ "CSEL $dst,$src1,$src2,$cmp\t! compressed ptr" %}
6195   ins_encode %{
6196     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
6197   %}
6198   ins_pipe(ialu_reg);
6199 %}
6200 #endif // AARCH64
6201 
6202 #ifndef AARCH64
6203 instruct cmovIP_immMov(cmpOpP cmp, flagsRegP pcc, iRegI dst, immIMov src) %{
6204   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
6205   ins_cost(140);
6206   size(4);
6207   format %{ "MOV$cmp  $dst,$src" %}
6208   ins_encode %{
6209     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6210   %}
6211   ins_pipe(ialu_imm);
6212 %}
6213 
6214 instruct cmovIP_imm16(cmpOpP cmp, flagsRegP pcc, iRegI dst, immI16 src) %{
6215   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
6216   ins_cost(140);
6217   size(4);
6218   format %{ "MOVw$cmp  $dst,$src" %}
6219   ins_encode %{
6220     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6221   %}
6222   ins_pipe(ialu_imm);
6223 %}
6224 #endif
6225 
6226 instruct cmovI_reg(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src) %{
6227   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
6228   ins_cost(150);
6229   size(4);
6230   format %{ "MOV$cmp  $dst,$src" %}
6231   ins_encode %{
6232     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6233   %}
6234   ins_pipe(ialu_reg);
6235 %}
6236 
6237 #ifdef AARCH64
6238 instruct cmovL_reg(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src) %{
6239   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
6240   ins_cost(150);
6241   size(4);
6242   format %{ "MOV$cmp  $dst,$src\t! long" %}
6243   ins_encode %{
6244     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6245   %}
6246   ins_pipe(ialu_reg);
6247 %}
6248 #endif
6249 
6250 #ifndef AARCH64
6251 instruct cmovI_immMov(cmpOp cmp, flagsReg icc, iRegI dst, immIMov src) %{
6252   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
6253   ins_cost(140);
6254   size(4);
6255   format %{ "MOV$cmp  $dst,$src" %}
6256   ins_encode %{
6257     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6258   %}
6259   ins_pipe(ialu_imm);
6260 %}
6261 
6262 instruct cmovII_imm16(cmpOp cmp, flagsReg icc, iRegI dst, immI16 src) %{
6263   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
6264   ins_cost(140);
6265   size(4);
6266   format %{ "MOVw$cmp  $dst,$src" %}
6267   ins_encode %{
6268     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6269   %}
6270   ins_pipe(ialu_imm);
6271 %}
6272 #endif
6273 
6274 instruct cmovII_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, iRegI src) %{
6275   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
6276   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
6277             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
6278             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
6279             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
6280   ins_cost(150);
6281   size(4);
6282   format %{ "MOV$cmp  $dst,$src" %}
6283   ins_encode %{
6284     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6285   %}
6286   ins_pipe(ialu_reg);
6287 %}
6288 
6289 #ifndef AARCH64
6290 instruct cmovII_immMov_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immIMov src) %{
6291   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
6292   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
6293             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
6294             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
6295             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
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 cmovII_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immI16 src) %{
6306   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
6307   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
6308             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
6309             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
6310             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
6311   ins_cost(140);
6312   size(4);
6313   format %{ "MOVW$cmp  $dst,$src" %}
6314   ins_encode %{
6315     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6316   %}
6317   ins_pipe(ialu_imm);
6318 %}
6319 #endif
6320 
6321 instruct cmovIIu_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
6322   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
6323   ins_cost(150);
6324   size(4);
6325   format %{ "MOV$cmp  $dst,$src" %}
6326   ins_encode %{
6327     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6328   %}
6329   ins_pipe(ialu_reg);
6330 %}
6331 
6332 #ifndef AARCH64
6333 instruct cmovIIu_immMov(cmpOpU cmp, flagsRegU icc, iRegI dst, immIMov src) %{
6334   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
6335   ins_cost(140);
6336   size(4);
6337   format %{ "MOV$cmp  $dst,$src" %}
6338   ins_encode %{
6339     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6340   %}
6341   ins_pipe(ialu_imm);
6342 %}
6343 
6344 instruct cmovIIu_imm16(cmpOpU cmp, flagsRegU icc, iRegI dst, immI16 src) %{
6345   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
6346   ins_cost(140);
6347   size(4);
6348   format %{ "MOVW$cmp  $dst,$src" %}
6349   ins_encode %{
6350     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6351   %}
6352   ins_pipe(ialu_imm);
6353 %}
6354 #endif
6355 
6356 // Conditional move
6357 instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{
6358   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
6359   ins_cost(150);
6360   size(4);
6361   format %{ "MOV$cmp  $dst,$src" %}
6362   ins_encode %{
6363     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6364   %}
6365   ins_pipe(ialu_reg);
6366 %}
6367 
6368 instruct cmovPP_imm(cmpOpP cmp, flagsRegP pcc, iRegP dst, immP0 src) %{
6369   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
6370   ins_cost(140);
6371   size(4);
6372 #ifdef AARCH64
6373   format %{ "MOV$cmp  $dst,ZR" %}
6374 #else
6375   format %{ "MOV$cmp  $dst,$src" %}
6376 #endif
6377   ins_encode %{
6378 #ifdef AARCH64
6379     __ mov($dst$$Register,             ZR, (AsmCondition)($cmp$$cmpcode));
6380 #else
6381     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6382 #endif
6383   %}
6384   ins_pipe(ialu_imm);
6385 %}
6386 
6387 // This instruction also works with CmpN so we don't need cmovPN_reg.
6388 instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{
6389   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
6390   ins_cost(150);
6391 
6392   size(4);
6393   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
6394   ins_encode %{
6395     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6396   %}
6397   ins_pipe(ialu_reg);
6398 %}
6399 
6400 instruct cmovPI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, iRegP src) %{
6401   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
6402   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
6403             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
6404             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
6405             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
6406   ins_cost(150);
6407 
6408   size(4);
6409   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
6410   ins_encode %{
6411     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6412   %}
6413   ins_pipe(ialu_reg);
6414 %}
6415 
6416 instruct cmovPIu_reg(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src) %{
6417   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
6418   ins_cost(150);
6419 
6420   size(4);
6421   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
6422   ins_encode %{
6423     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6424   %}
6425   ins_pipe(ialu_reg);
6426 %}
6427 
6428 instruct cmovPI_imm(cmpOp cmp, flagsReg icc, iRegP dst, immP0 src) %{
6429   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
6430   ins_cost(140);
6431 
6432   size(4);
6433 #ifdef AARCH64
6434   format %{ "MOV$cmp  $dst,ZR\t! ptr" %}
6435 #else
6436   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
6437 #endif
6438   ins_encode %{
6439 #ifdef AARCH64
6440     __ mov($dst$$Register,             ZR, (AsmCondition)($cmp$$cmpcode));
6441 #else
6442     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6443 #endif
6444   %}
6445   ins_pipe(ialu_imm);
6446 %}
6447 
6448 instruct cmovPI_imm_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, immP0 src) %{
6449   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
6450   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
6451             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
6452             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
6453             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
6454   ins_cost(140);
6455 
6456   size(4);
6457 #ifdef AARCH64
6458   format %{ "MOV$cmp  $dst,ZR\t! ptr" %}
6459 #else
6460   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
6461 #endif
6462   ins_encode %{
6463 #ifdef AARCH64
6464     __ mov($dst$$Register,             ZR, (AsmCondition)($cmp$$cmpcode));
6465 #else
6466     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6467 #endif
6468   %}
6469   ins_pipe(ialu_imm);
6470 %}
6471 
6472 instruct cmovPIu_imm(cmpOpU cmp, flagsRegU icc, iRegP dst, immP0 src) %{
6473   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
6474   ins_cost(140);
6475 
6476   size(4);
6477 #ifdef AARCH64
6478   format %{ "MOV$cmp  $dst,ZR\t! ptr" %}
6479 #else
6480   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
6481 #endif
6482   ins_encode %{
6483 #ifdef AARCH64
6484     __ mov($dst$$Register,             ZR, (AsmCondition)($cmp$$cmpcode));
6485 #else
6486     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6487 #endif
6488   %}
6489   ins_pipe(ialu_imm);
6490 %}
6491 
6492 #ifdef AARCH64
6493 // Conditional move
6494 instruct cmovF_reg(cmpOp cmp, flagsReg icc, regF dst, regF src1, regF src2) %{
6495   match(Set dst (CMoveF (Binary cmp icc) (Binary src2 src1)));
6496   ins_cost(150);
6497   size(4);
6498   format %{ "FCSEL_s $dst,$src1,$src2,$cmp" %}
6499   ins_encode %{
6500     __ fcsel_s($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6501   %}
6502   ins_pipe(int_conditional_float_move);
6503 %}
6504 
6505 instruct cmovD_reg(cmpOp cmp, flagsReg icc, regD dst, regD src1, regD src2) %{
6506   match(Set dst (CMoveD (Binary cmp icc) (Binary src2 src1)));
6507   ins_cost(150);
6508   size(4);
6509   format %{ "FCSEL_d $dst,$src1,$src2,$cmp" %}
6510   ins_encode %{
6511     __ fcsel_d($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6512   %}
6513   ins_pipe(int_conditional_float_move);
6514 %}
6515 
6516 instruct cmovFP_reg(cmpOpP cmp, flagsRegP icc, regF dst, regF src1, regF src2) %{
6517   match(Set dst (CMoveF (Binary cmp icc) (Binary src2 src1)));
6518   ins_cost(150);
6519   size(4);
6520   format %{ "FCSEL_s $dst,$src1,$src2,$cmp" %}
6521   ins_encode %{
6522     __ fcsel_s($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6523   %}
6524   ins_pipe(int_conditional_float_move);
6525 %}
6526 
6527 instruct cmovDP_reg(cmpOpP cmp, flagsRegP icc, regD dst, regD src1, regD src2) %{
6528   match(Set dst (CMoveD (Binary cmp icc) (Binary src2 src1)));
6529   ins_cost(150);
6530   size(4);
6531   format %{ "FCSEL_d $dst,$src1,$src2,$cmp" %}
6532   ins_encode %{
6533     __ fcsel_d($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6534   %}
6535   ins_pipe(int_conditional_float_move);
6536 %}
6537 
6538 instruct cmovFU_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src1, regF src2) %{
6539   match(Set dst (CMoveF (Binary cmp icc) (Binary src2 src1)));
6540   ins_cost(150);
6541   size(4);
6542   format %{ "FCSEL_s $dst,$src1,$src2,$cmp" %}
6543   ins_encode %{
6544     __ fcsel_s($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6545   %}
6546   ins_pipe(int_conditional_float_move);
6547 %}
6548 
6549 instruct cmovDU_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src1, regD src2) %{
6550   match(Set dst (CMoveD (Binary cmp icc) (Binary src2 src1)));
6551   ins_cost(150);
6552   size(4);
6553   format %{ "FCSEL_d $dst,$src1,$src2,$cmp" %}
6554   ins_encode %{
6555     __ fcsel_d($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6556   %}
6557   ins_pipe(int_conditional_float_move);
6558 %}
6559 
6560 instruct cmovFZ_reg(cmpOp0 cmp, flagsReg_EQNELTGE icc, regF dst, regF src1, regF src2) %{
6561   match(Set dst (CMoveF (Binary cmp icc) (Binary src2 src1)));
6562   ins_cost(150);
6563   size(4);
6564   format %{ "FCSEL_s $dst,$src1,$src2,$cmp" %}
6565   ins_encode %{
6566     __ fcsel_s($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6567   %}
6568   ins_pipe(int_conditional_float_move);
6569 %}
6570 
6571 instruct cmovDZ_reg(cmpOp0 cmp, flagsReg_EQNELTGE icc, regD dst, regD src1, regD src2) %{
6572   match(Set dst (CMoveD (Binary cmp icc) (Binary src2 src1)));
6573   ins_cost(150);
6574   size(4);
6575   format %{ "FCSEL_d $dst,$src1,$src2,$cmp" %}
6576   ins_encode %{
6577     __ fcsel_d($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6578   %}
6579   ins_pipe(int_conditional_float_move);
6580 %}
6581 
6582 #else // !AARCH64
6583 
6584 // Conditional move
6585 instruct cmovFP_reg(cmpOpP cmp, flagsRegP pcc, regF dst, regF src) %{
6586   match(Set dst (CMoveF (Binary cmp pcc) (Binary dst src)));
6587   ins_cost(150);
6588   size(4);
6589   format %{ "FCPYS$cmp $dst,$src" %}
6590   ins_encode %{
6591     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6592   %}
6593   ins_pipe(int_conditional_float_move);
6594 %}
6595 
6596 instruct cmovFI_reg(cmpOp cmp, flagsReg icc, regF dst, regF src) %{
6597   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
6598   ins_cost(150);
6599 
6600   size(4);
6601   format %{ "FCPYS$cmp $dst,$src" %}
6602   ins_encode %{
6603     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6604   %}
6605   ins_pipe(int_conditional_float_move);
6606 %}
6607 
6608 instruct cmovFI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regF dst, regF src) %{
6609   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
6610   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
6611             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
6612             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
6613             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
6614   ins_cost(150);
6615 
6616   size(4);
6617   format %{ "FCPYS$cmp $dst,$src" %}
6618   ins_encode %{
6619     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6620   %}
6621   ins_pipe(int_conditional_float_move);
6622 %}
6623 
6624 instruct cmovFIu_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src) %{
6625   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
6626   ins_cost(150);
6627 
6628   size(4);
6629   format %{ "FCPYS$cmp $dst,$src" %}
6630   ins_encode %{
6631     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6632   %}
6633   ins_pipe(int_conditional_float_move);
6634 %}
6635 
6636 // Conditional move
6637 instruct cmovDP_reg(cmpOpP cmp, flagsRegP pcc, regD dst, regD src) %{
6638   match(Set dst (CMoveD (Binary cmp pcc) (Binary dst src)));
6639   ins_cost(150);
6640   size(4);
6641   format %{ "FCPYD$cmp $dst,$src" %}
6642   ins_encode %{
6643     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6644   %}
6645   ins_pipe(int_conditional_double_move);
6646 %}
6647 
6648 instruct cmovDI_reg(cmpOp cmp, flagsReg icc, regD dst, regD src) %{
6649   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
6650   ins_cost(150);
6651 
6652   size(4);
6653   format %{ "FCPYD$cmp $dst,$src" %}
6654   ins_encode %{
6655     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6656   %}
6657   ins_pipe(int_conditional_double_move);
6658 %}
6659 
6660 instruct cmovDI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regD dst, regD src) %{
6661   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
6662   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);
6663   ins_cost(150);
6664 
6665   size(4);
6666   format %{ "FCPYD$cmp $dst,$src" %}
6667   ins_encode %{
6668     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6669   %}
6670   ins_pipe(int_conditional_double_move);
6671 %}
6672 
6673 instruct cmovDIu_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src) %{
6674   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
6675   ins_cost(150);
6676 
6677   size(4);
6678   format %{ "FCPYD$cmp $dst,$src" %}
6679   ins_encode %{
6680     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
6681   %}
6682   ins_pipe(int_conditional_double_move);
6683 %}
6684 
6685 // Conditional move
6686 instruct cmovLP_reg(cmpOpP cmp, flagsRegP pcc, iRegL dst, iRegL src) %{
6687   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
6688   ins_cost(150);
6689 
6690   size(8);
6691   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
6692             "MOV$cmp  $dst.hi,$src.hi" %}
6693   ins_encode %{
6694     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6695     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
6696   %}
6697   ins_pipe(ialu_reg);
6698 %}
6699 
6700 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6701 // (hi($con$$constant), lo($con$$constant)) becomes
6702 instruct cmovLP_immRot(cmpOpP cmp, flagsRegP pcc, iRegL dst, immLlowRot src) %{
6703   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
6704   ins_cost(140);
6705 
6706   size(8);
6707   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
6708             "MOV$cmp  $dst.hi,0" %}
6709   ins_encode %{
6710     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6711     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
6712   %}
6713   ins_pipe(ialu_imm);
6714 %}
6715 
6716 instruct cmovLP_imm16(cmpOpP cmp, flagsRegP pcc, iRegL dst, immL16 src) %{
6717   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
6718   ins_cost(140);
6719 
6720   size(8);
6721   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
6722             "MOV$cmp  $dst.hi,0" %}
6723   ins_encode %{
6724     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6725     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
6726   %}
6727   ins_pipe(ialu_imm);
6728 %}
6729 
6730 instruct cmovLI_reg(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src) %{
6731   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
6732   ins_cost(150);
6733 
6734   size(8);
6735   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
6736             "MOV$cmp  $dst.hi,$src.hi" %}
6737   ins_encode %{
6738     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6739     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
6740   %}
6741   ins_pipe(ialu_reg);
6742 %}
6743 
6744 instruct cmovLI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, iRegL src) %{
6745   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
6746   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
6747             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
6748             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
6749             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
6750   ins_cost(150);
6751 
6752   size(8);
6753   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
6754             "MOV$cmp  $dst.hi,$src.hi" %}
6755   ins_encode %{
6756     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6757     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
6758   %}
6759   ins_pipe(ialu_reg);
6760 %}
6761 
6762 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6763 // (hi($con$$constant), lo($con$$constant)) becomes
6764 instruct cmovLI_immRot(cmpOp cmp, flagsReg icc, iRegL dst, immLlowRot src) %{
6765   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
6766   ins_cost(140);
6767 
6768   size(8);
6769   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
6770             "MOV$cmp  $dst.hi,0" %}
6771   ins_encode %{
6772     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6773     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
6774   %}
6775   ins_pipe(ialu_imm);
6776 %}
6777 
6778 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6779 // (hi($con$$constant), lo($con$$constant)) becomes
6780 instruct cmovLI_immRot_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immLlowRot src) %{
6781   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
6782   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
6783             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
6784             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
6785             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
6786   ins_cost(140);
6787 
6788   size(8);
6789   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
6790             "MOV$cmp  $dst.hi,0" %}
6791   ins_encode %{
6792     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6793     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
6794   %}
6795   ins_pipe(ialu_imm);
6796 %}
6797 
6798 instruct cmovLI_imm16(cmpOp cmp, flagsReg icc, iRegL dst, immL16 src) %{
6799   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
6800   ins_cost(140);
6801 
6802   size(8);
6803   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
6804             "MOV$cmp  $dst.hi,0" %}
6805   ins_encode %{
6806     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6807     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
6808   %}
6809   ins_pipe(ialu_imm);
6810 %}
6811 
6812 instruct cmovLI_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immL16 src) %{
6813   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
6814   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
6815             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
6816             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
6817             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
6818   ins_cost(140);
6819 
6820   size(8);
6821   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
6822             "MOV$cmp  $dst.hi,0" %}
6823   ins_encode %{
6824     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
6825     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
6826   %}
6827   ins_pipe(ialu_imm);
6828 %}
6829 
6830 instruct cmovLIu_reg(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src) %{
6831   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
6832   ins_cost(150);
6833 
6834   size(8);
6835   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
6836             "MOV$cmp  $dst.hi,$src.hi" %}
6837   ins_encode %{
6838     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
6839     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
6840   %}
6841   ins_pipe(ialu_reg);
6842 %}
6843 #endif // !AARCH64
6844 
6845 
6846 //----------OS and Locking Instructions----------------------------------------
6847 
6848 // This name is KNOWN by the ADLC and cannot be changed.
6849 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
6850 // for this guy.
6851 instruct tlsLoadP(RthreadRegP dst) %{
6852   match(Set dst (ThreadLocal));
6853 
6854   size(0);
6855   ins_cost(0);
6856   format %{ "! TLS is in $dst" %}
6857   ins_encode( /*empty encoding*/ );
6858   ins_pipe(ialu_none);
6859 %}
6860 
6861 instruct checkCastPP( iRegP dst ) %{
6862   match(Set dst (CheckCastPP dst));
6863 
6864   size(0);
6865   format %{ "! checkcastPP of $dst" %}
6866   ins_encode( /*empty encoding*/ );
6867   ins_pipe(empty);
6868 %}
6869 
6870 
6871 instruct castPP( iRegP dst ) %{
6872   match(Set dst (CastPP dst));
6873   format %{ "! castPP of $dst" %}
6874   ins_encode( /*empty encoding*/ );
6875   ins_pipe(empty);
6876 %}
6877 
6878 instruct castII( iRegI dst ) %{
6879   match(Set dst (CastII dst));
6880   format %{ "! castII of $dst" %}
6881   ins_encode( /*empty encoding*/ );
6882   ins_cost(0);
6883   ins_pipe(empty);
6884 %}
6885 
6886 //----------Arithmetic Instructions--------------------------------------------
6887 // Addition Instructions
6888 // Register Addition
6889 instruct addI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6890   match(Set dst (AddI src1 src2));
6891 
6892   size(4);
6893   format %{ "add_32 $dst,$src1,$src2\t! int" %}
6894   ins_encode %{
6895     __ add_32($dst$$Register, $src1$$Register, $src2$$Register);
6896   %}
6897   ins_pipe(ialu_reg_reg);
6898 %}
6899 
6900 #ifndef AARCH64
6901 instruct addshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6902   match(Set dst (AddI (LShiftI 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, lsl, $src2$$Register));
6908   %}
6909   ins_pipe(ialu_reg_reg);
6910 %}
6911 #endif
6912 
6913 #ifdef AARCH64
6914 #ifdef TODO
6915 instruct addshlL_reg_imm_reg(iRegL dst, iRegL src1, immU6 src2, iRegL src3) %{
6916   match(Set dst (AddL (LShiftL src1 src2) src3));
6917 
6918   size(4);
6919   format %{ "ADD    $dst,$src3,$src1<<$src2\t! long" %}
6920   ins_encode %{
6921     __ add($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
6922   %}
6923   ins_pipe(ialu_reg_reg);
6924 %}
6925 #endif
6926 #endif
6927 
6928 instruct addshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
6929   match(Set dst (AddI (LShiftI src1 src2) src3));
6930 
6931   size(4);
6932   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
6933   ins_encode %{
6934     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
6935   %}
6936   ins_pipe(ialu_reg_reg);
6937 %}
6938 
6939 #ifndef AARCH64
6940 instruct addsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6941   match(Set dst (AddI (RShiftI src1 src2) src3));
6942 
6943   size(4);
6944   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
6945   ins_encode %{
6946     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
6947   %}
6948   ins_pipe(ialu_reg_reg);
6949 %}
6950 #endif
6951 
6952 instruct addsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
6953   match(Set dst (AddI (RShiftI src1 src2) src3));
6954 
6955   size(4);
6956   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
6957   ins_encode %{
6958     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
6959   %}
6960   ins_pipe(ialu_reg_reg);
6961 %}
6962 
6963 #ifndef AARCH64
6964 instruct addshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6965   match(Set dst (AddI (URShiftI src1 src2) src3));
6966 
6967   size(4);
6968   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
6969   ins_encode %{
6970     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
6971   %}
6972   ins_pipe(ialu_reg_reg);
6973 %}
6974 #endif
6975 
6976 instruct addshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
6977   match(Set dst (AddI (URShiftI src1 src2) src3));
6978 
6979   size(4);
6980   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
6981   ins_encode %{
6982     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
6983   %}
6984   ins_pipe(ialu_reg_reg);
6985 %}
6986 
6987 // Immediate Addition
6988 instruct addI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
6989   match(Set dst (AddI src1 src2));
6990 
6991   size(4);
6992   format %{ "add_32 $dst,$src1,$src2\t! int" %}
6993   ins_encode %{
6994     __ add_32($dst$$Register, $src1$$Register, $src2$$constant);
6995   %}
6996   ins_pipe(ialu_reg_imm);
6997 %}
6998 
6999 // Pointer Register Addition
7000 instruct addP_reg_reg(iRegP dst, iRegP src1, iRegX src2) %{
7001   match(Set dst (AddP src1 src2));
7002 
7003   size(4);
7004   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
7005   ins_encode %{
7006     __ add($dst$$Register, $src1$$Register, $src2$$Register);
7007   %}
7008   ins_pipe(ialu_reg_reg);
7009 %}
7010 
7011 #ifdef AARCH64
7012 // unshifted I2L operand
7013 operand unshiftedI2L(iRegI src2) %{
7014 //constraint(ALLOC_IN_RC(sp_ptr_reg));
7015   match(ConvI2L src2);
7016 
7017   op_cost(1);
7018   format %{ "$src2.w" %}
7019   interface(MEMORY_INTER) %{
7020     base($src2);
7021     index(0xff);
7022     scale(0x0);
7023     disp(0x0);
7024   %}
7025 %}
7026 
7027 // shifted I2L operand
7028 operand shiftedI2L(iRegI src2, immI_0_4 src3) %{
7029 //constraint(ALLOC_IN_RC(sp_ptr_reg));
7030   match(LShiftX (ConvI2L src2) src3);
7031 
7032   op_cost(1);
7033   format %{ "$src2.w << $src3" %}
7034   interface(MEMORY_INTER) %{
7035     base($src2);
7036     index(0xff);
7037     scale($src3);
7038     disp(0x0);
7039   %}
7040 %}
7041 
7042 opclass shiftedRegI(shiftedI2L, unshiftedI2L);
7043 
7044 instruct shlL_reg_regI(iRegL dst, iRegI src1, immU6 src2) %{
7045   match(Set dst (LShiftL (ConvI2L src1) src2));
7046 
7047   size(4);
7048   format %{ "LSL    $dst,$src1.w,$src2\t! ptr" %}
7049   ins_encode %{
7050     int c = $src2$$constant;
7051     int r = 64 - c;
7052     int s = 31;
7053     if (s >= r) {
7054       s = r - 1;
7055     }
7056     __ sbfm($dst$$Register, $src1$$Register, r, s);
7057   %}
7058   ins_pipe(ialu_reg_reg);
7059 %}
7060 
7061 instruct addP_reg_regI(iRegP dst, iRegP src1, shiftedRegI src2) %{
7062   match(Set dst (AddP src1 src2));
7063 
7064   ins_cost(DEFAULT_COST * 3/2);
7065   size(4);
7066   format %{ "ADD    $dst,$src1,$src2, sxtw\t! ptr" %}
7067   ins_encode %{
7068     Register base = reg_to_register_object($src2$$base);
7069     __ add($dst$$Register, $src1$$Register, base, ex_sxtw, $src2$$scale);
7070   %}
7071   ins_pipe(ialu_reg_reg);
7072 %}
7073 #endif
7074 
7075 // shifted iRegX operand
7076 operand shiftedX(iRegX src2, shimmX src3) %{
7077 //constraint(ALLOC_IN_RC(sp_ptr_reg));
7078   match(LShiftX src2 src3);
7079 
7080   op_cost(1);
7081   format %{ "$src2 << $src3" %}
7082   interface(MEMORY_INTER) %{
7083     base($src2);
7084     index(0xff);
7085     scale($src3);
7086     disp(0x0);
7087   %}
7088 %}
7089 
7090 instruct addshlP_reg_reg_imm(iRegP dst, iRegP src1, shiftedX src2) %{
7091   match(Set dst (AddP src1 src2));
7092 
7093   ins_cost(DEFAULT_COST * 3/2);
7094   size(4);
7095   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
7096   ins_encode %{
7097     Register base = reg_to_register_object($src2$$base);
7098     __ add($dst$$Register, $src1$$Register, AsmOperand(base, lsl, $src2$$scale));
7099   %}
7100   ins_pipe(ialu_reg_reg);
7101 %}
7102 
7103 // Pointer Immediate Addition
7104 instruct addP_reg_aimmX(iRegP dst, iRegP src1, aimmX src2) %{
7105   match(Set dst (AddP src1 src2));
7106 
7107   size(4);
7108   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
7109   ins_encode %{
7110     __ add($dst$$Register, $src1$$Register, $src2$$constant);
7111   %}
7112   ins_pipe(ialu_reg_imm);
7113 %}
7114 
7115 // Long Addition
7116 #ifdef AARCH64
7117 instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
7118   match(Set dst (AddL src1 src2));
7119   size(4);
7120   format %{ "ADD     $dst,$src1,$src2\t! long" %}
7121   ins_encode %{
7122     __ add($dst$$Register, $src1$$Register, $src2$$Register);
7123   %}
7124   ins_pipe(ialu_reg_reg);
7125 %}
7126 
7127 instruct addL_reg_regI(iRegL dst, iRegL src1, shiftedRegI src2) %{
7128   match(Set dst (AddL src1 src2));
7129 
7130   ins_cost(DEFAULT_COST * 3/2);
7131   size(4);
7132   format %{ "ADD    $dst,$src1,$src2, sxtw\t! long" %}
7133   ins_encode %{
7134     Register base = reg_to_register_object($src2$$base);
7135     __ add($dst$$Register, $src1$$Register, base, ex_sxtw, $src2$$scale);
7136   %}
7137   ins_pipe(ialu_reg_reg);
7138 %}
7139 #else
7140 instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg ccr) %{
7141   match(Set dst (AddL src1 src2));
7142   effect(KILL ccr);
7143   size(8);
7144   format %{ "ADDS    $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
7145             "ADC     $dst.hi,$src1.hi,$src2.hi" %}
7146   ins_encode %{
7147     __ adds($dst$$Register, $src1$$Register, $src2$$Register);
7148     __ adc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
7149   %}
7150   ins_pipe(ialu_reg_reg);
7151 %}
7152 #endif
7153 
7154 #ifdef AARCH64
7155 // Immediate Addition
7156 instruct addL_reg_aimm(iRegL dst, iRegL src1, aimmL src2) %{
7157   match(Set dst (AddL src1 src2));
7158 
7159   size(4);
7160   format %{ "ADD    $dst,$src1,$src2\t! long" %}
7161   ins_encode %{
7162     __ add($dst$$Register, $src1$$Register, $src2$$constant);
7163   %}
7164   ins_pipe(ialu_reg_imm);
7165 %}
7166 
7167 instruct addL_reg_immLneg(iRegL dst, iRegL src1, aimmLneg src2) %{
7168   match(Set dst (SubL src1 src2));
7169 
7170   size(4);
7171   format %{ "ADD    $dst,$src1,-($src2)\t! long" %}
7172   ins_encode %{
7173     __ add($dst$$Register, $src1$$Register, -$src2$$constant);
7174   %}
7175   ins_pipe(ialu_reg_imm);
7176 %}
7177 #else
7178 // TODO
7179 #endif
7180 
7181 #ifndef AARCH64
7182 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7183 // (hi($con$$constant), lo($con$$constant)) becomes
7184 instruct addL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg ccr) %{
7185   match(Set dst (AddL src1 con));
7186   effect(KILL ccr);
7187   size(8);
7188   format %{ "ADDS    $dst.lo,$src1.lo,$con\t! long\n\t"
7189             "ADC     $dst.hi,$src1.hi,0" %}
7190   ins_encode %{
7191     __ adds($dst$$Register, $src1$$Register, $con$$constant);
7192     __ adc($dst$$Register->successor(), $src1$$Register->successor(), 0);
7193   %}
7194   ins_pipe(ialu_reg_imm);
7195 %}
7196 #endif
7197 
7198 //----------Conditional_store--------------------------------------------------
7199 // Conditional-store of the updated heap-top.
7200 // Used during allocation of the shared heap.
7201 // Sets flags (EQ) on success.
7202 
7203 // TODO: optimize out barriers with AArch64 load-acquire/store-release
7204 // LoadP-locked.
7205 instruct loadPLocked(iRegP dst, memoryex mem) %{
7206   match(Set dst (LoadPLocked mem));
7207   size(4);
7208   format %{ "LDREX  $dst,$mem" %}
7209   ins_encode %{
7210 #ifdef AARCH64
7211     Register base = reg_to_register_object($mem$$base);
7212     __ ldxr($dst$$Register, base);
7213 #else
7214     __ ldrex($dst$$Register,$mem$$Address);
7215 #endif
7216   %}
7217   ins_pipe(iload_mem);
7218 %}
7219 
7220 instruct storePConditional( memoryex heap_top_ptr, iRegP oldval, iRegP newval, iRegI tmp, flagsRegP pcc ) %{
7221   predicate(_kids[1]->_kids[0]->_leaf->Opcode() == Op_LoadPLocked); // only works in conjunction with a LoadPLocked node
7222   match(Set pcc (StorePConditional heap_top_ptr (Binary oldval newval)));
7223   effect( TEMP tmp );
7224   size(8);
7225   format %{ "STREX  $tmp,$newval,$heap_top_ptr\n\t"
7226             "CMP    $tmp, 0" %}
7227   ins_encode %{
7228 #ifdef AARCH64
7229     Register base = reg_to_register_object($heap_top_ptr$$base);
7230     __ stxr($tmp$$Register, $newval$$Register, base);
7231 #else
7232     __ strex($tmp$$Register, $newval$$Register, $heap_top_ptr$$Address);
7233 #endif
7234     __ cmp($tmp$$Register, 0);
7235   %}
7236   ins_pipe( long_memory_op );
7237 %}
7238 
7239 // Conditional-store of an intx value.
7240 instruct storeXConditional( memoryex mem, iRegX oldval, iRegX newval, iRegX tmp, flagsReg icc ) %{
7241 #ifdef AARCH64
7242   match(Set icc (StoreLConditional mem (Binary oldval newval)));
7243   effect( TEMP tmp );
7244   size(28);
7245   format %{ "loop:\n\t"
7246             "LDXR     $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem], DOESN'T set $newval=[$mem] in any case\n\t"
7247             "SUBS     $tmp, $tmp, $oldval\n\t"
7248             "B.ne     done\n\t"
7249             "STXR     $tmp, $newval, $mem\n\t"
7250             "CBNZ_w   $tmp, loop\n\t"
7251             "CMP      $tmp, 0\n\t"
7252             "done:\n\t"
7253             "membar   LoadStore|LoadLoad" %}
7254 #else
7255   match(Set icc (StoreIConditional mem (Binary oldval newval)));
7256   effect( TEMP tmp );
7257   size(28);
7258   format %{ "loop: \n\t"
7259             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem], DOESN'T set $newval=[$mem] in any case\n\t"
7260             "XORS     $tmp,$tmp, $oldval\n\t"
7261             "STREX.eq $tmp, $newval, $mem\n\t"
7262             "CMP.eq   $tmp, 1 \n\t"
7263             "B.eq     loop \n\t"
7264             "TEQ      $tmp, 0\n\t"
7265             "membar   LoadStore|LoadLoad" %}
7266 #endif
7267   ins_encode %{
7268     Label loop;
7269     __ bind(loop);
7270 #ifdef AARCH64
7271 // FIXME: use load-acquire/store-release, remove membar?
7272     Label done;
7273     Register base = reg_to_register_object($mem$$base);
7274     __ ldxr($tmp$$Register, base);
7275     __ subs($tmp$$Register, $tmp$$Register, $oldval$$Register);
7276     __ b(done, ne);
7277     __ stxr($tmp$$Register, $newval$$Register, base);
7278     __ cbnz_w($tmp$$Register, loop);
7279     __ cmp($tmp$$Register, 0);
7280     __ bind(done);
7281 #else
7282     __ ldrex($tmp$$Register, $mem$$Address);
7283     __ eors($tmp$$Register, $tmp$$Register, $oldval$$Register);
7284     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
7285     __ cmp($tmp$$Register, 1, eq);
7286     __ b(loop, eq);
7287     __ teq($tmp$$Register, 0);
7288 #endif
7289     // used by biased locking only. Requires a membar.
7290     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadStore | MacroAssembler::LoadLoad), noreg);
7291   %}
7292   ins_pipe( long_memory_op );
7293 %}
7294 
7295 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
7296 
7297 #ifdef AARCH64
7298 // TODO: if combined with membar, elide membar and use
7299 // load-acquire/store-release if appropriate
7300 instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegL newval, iRegI res, iRegI tmp, flagsReg ccr) %{
7301   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
7302   effect( KILL ccr, TEMP tmp);
7303   size(24);
7304   format %{ "loop:\n\t"
7305             "LDXR     $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
7306             "CMP      $tmp, $oldval\n\t"
7307             "B.ne     done\n\t"
7308             "STXR     $tmp, $newval, $mem\n\t"
7309             "CBNZ_w   $tmp, loop\n\t"
7310             "done:\n\t"
7311             "CSET_w   $res, eq" %}
7312   ins_encode %{
7313     Register base = reg_to_register_object($mem$$base);
7314     Label loop, done;
7315     __ bind(loop);
7316     __ ldxr($tmp$$Register, base);
7317     __ cmp($tmp$$Register, $oldval$$Register);
7318     __ b(done, ne);
7319     __ stxr($tmp$$Register, $newval$$Register, base);
7320     __ cbnz_w($tmp$$Register, loop);
7321     __ bind(done);
7322     __ cset_w($res$$Register, eq);
7323   %}
7324   ins_pipe( long_memory_op );
7325 %}
7326 
7327 instruct compareAndSwapI_bool(memoryex mem, iRegI oldval, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr) %{
7328   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
7329   effect( KILL ccr, TEMP tmp);
7330   size(24);
7331   format %{ "loop:\n\t"
7332             "LDXR_w   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
7333             "CMP_w    $tmp, $oldval\n\t"
7334             "B.ne     done\n\t"
7335             "STXR_w   $tmp, $newval, $mem\n\t"
7336             "CBNZ_w   $tmp, loop\n\t"
7337             "done:\n\t"
7338             "CSET_w   $res, eq" %}
7339   ins_encode %{
7340     Register base = reg_to_register_object($mem$$base);
7341     Label loop, done;
7342     __ bind(loop);
7343     __ ldxr_w($tmp$$Register, base);
7344     __ cmp_w($tmp$$Register, $oldval$$Register);
7345     __ b(done, ne);
7346     __ stxr_w($tmp$$Register, $newval$$Register,  base);
7347     __ cbnz_w($tmp$$Register, loop);
7348     __ bind(done);
7349     __ cset_w($res$$Register, eq);
7350   %}
7351   ins_pipe( long_memory_op );
7352 %}
7353 
7354 // tmp must use iRegI instead of iRegN until 8051805 is fixed.
7355 instruct compareAndSwapN_bool(memoryex mem, iRegN oldval, iRegN newval, iRegI res, iRegI tmp, flagsReg ccr) %{
7356   match(Set res (CompareAndSwapN mem (Binary oldval newval)));
7357   effect( KILL ccr, TEMP tmp);
7358   size(24);
7359   format %{ "loop:\n\t"
7360             "LDXR_w   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
7361             "CMP_w    $tmp, $oldval\n\t"
7362             "B.ne     done\n\t"
7363             "STXR_w   $tmp, $newval, $mem\n\t"
7364             "CBNZ_w   $tmp, loop\n\t"
7365             "done:\n\t"
7366             "CSET_w   $res, eq" %}
7367   ins_encode %{
7368     Register base = reg_to_register_object($mem$$base);
7369     Label loop, done;
7370     __ bind(loop);
7371     __ ldxr_w($tmp$$Register, base);
7372     __ cmp_w($tmp$$Register, $oldval$$Register);
7373     __ b(done, ne);
7374     __ stxr_w($tmp$$Register, $newval$$Register,  base);
7375     __ cbnz_w($tmp$$Register, loop);
7376     __ bind(done);
7377     __ cset_w($res$$Register, eq);
7378   %}
7379   ins_pipe( long_memory_op );
7380 %}
7381 
7382 instruct compareAndSwapP_bool(memoryex mem, iRegP oldval, iRegP newval, iRegI res, iRegI tmp, flagsReg ccr) %{
7383   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
7384   effect( KILL ccr, TEMP tmp);
7385   size(24);
7386   format %{ "loop:\n\t"
7387             "LDXR     $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
7388             "CMP      $tmp, $oldval\n\t"
7389             "B.ne     done\n\t"
7390             "STXR     $tmp, $newval, $mem\n\t"
7391             "CBNZ_w   $tmp, loop\n\t"
7392             "done:\n\t"
7393             "CSET_w   $res, eq" %}
7394   ins_encode %{
7395     Register base = reg_to_register_object($mem$$base);
7396     Label loop, done;
7397     __ bind(loop);
7398     __ ldxr($tmp$$Register, base);
7399     __ cmp($tmp$$Register, $oldval$$Register);
7400     __ b(done, ne);
7401     __ stxr($tmp$$Register, $newval$$Register,  base);
7402     __ cbnz_w($tmp$$Register, loop);
7403     __ bind(done);
7404     __ cset_w($res$$Register, eq);
7405   %}
7406   ins_pipe( long_memory_op );
7407 %}
7408 #else // !AARCH64
7409 instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegLd newval, iRegI res, iRegLd tmp, flagsReg ccr ) %{
7410   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
7411   effect( KILL ccr, TEMP tmp);
7412   size(32);
7413   format %{ "loop: \n\t"
7414             "LDREXD   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
7415             "CMP      $tmp.lo, $oldval.lo\n\t"
7416             "CMP.eq   $tmp.hi, $oldval.hi\n\t"
7417             "STREXD.eq $tmp, $newval, $mem\n\t"
7418             "MOV.ne   $tmp, 0 \n\t"
7419             "XORS.eq  $tmp,$tmp, 1 \n\t"
7420             "B.eq     loop \n\t"
7421             "MOV      $res, $tmp" %}
7422   ins_encode %{
7423     Label loop;
7424     __ bind(loop);
7425     __ ldrexd($tmp$$Register, $mem$$Address);
7426     __ cmp($tmp$$Register, $oldval$$Register);
7427     __ cmp($tmp$$Register->successor(), $oldval$$Register->successor(), eq);
7428     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address, eq);
7429     __ mov($tmp$$Register, 0, ne);
7430     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
7431     __ b(loop, eq);
7432     __ mov($res$$Register, $tmp$$Register);
7433   %}
7434   ins_pipe( long_memory_op );
7435 %}
7436 
7437 
7438 instruct compareAndSwapI_bool(memoryex mem, iRegI oldval, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
7439   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
7440   effect( KILL ccr, TEMP tmp);
7441   size(28);
7442   format %{ "loop: \n\t"
7443             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
7444             "CMP      $tmp, $oldval\n\t"
7445             "STREX.eq $tmp, $newval, $mem\n\t"
7446             "MOV.ne   $tmp, 0 \n\t"
7447             "XORS.eq  $tmp,$tmp, 1 \n\t"
7448             "B.eq     loop \n\t"
7449             "MOV      $res, $tmp" %}
7450 
7451   ins_encode %{
7452     Label loop;
7453     __ bind(loop);
7454     __ ldrex($tmp$$Register,$mem$$Address);
7455     __ cmp($tmp$$Register, $oldval$$Register);
7456     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
7457     __ mov($tmp$$Register, 0, ne);
7458     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
7459     __ b(loop, eq);
7460     __ mov($res$$Register, $tmp$$Register);
7461   %}
7462   ins_pipe( long_memory_op );
7463 %}
7464 
7465 instruct compareAndSwapP_bool(memoryex mem, iRegP oldval, iRegP newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
7466   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
7467   effect( KILL ccr, TEMP tmp);
7468   size(28);
7469   format %{ "loop: \n\t"
7470             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
7471             "CMP      $tmp, $oldval\n\t"
7472             "STREX.eq $tmp, $newval, $mem\n\t"
7473             "MOV.ne   $tmp, 0 \n\t"
7474             "EORS.eq  $tmp,$tmp, 1 \n\t"
7475             "B.eq     loop \n\t"
7476             "MOV      $res, $tmp" %}
7477 
7478   ins_encode %{
7479     Label loop;
7480     __ bind(loop);
7481     __ ldrex($tmp$$Register,$mem$$Address);
7482     __ cmp($tmp$$Register, $oldval$$Register);
7483     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
7484     __ mov($tmp$$Register, 0, ne);
7485     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
7486     __ b(loop, eq);
7487     __ mov($res$$Register, $tmp$$Register);
7488   %}
7489   ins_pipe( long_memory_op );
7490 %}
7491 #endif // !AARCH64
7492 
7493 #ifdef AARCH64
7494 instruct xaddI_aimmI_no_res(memoryex mem, aimmI add, Universe dummy, iRegI tmp1, iRegI tmp2) %{
7495   predicate(n->as_LoadStore()->result_not_used());
7496   match(Set dummy (GetAndAddI mem add));
7497   effect(TEMP tmp1, TEMP tmp2);
7498   size(16);
7499   format %{ "loop:\n\t"
7500             "LDXR_w   $tmp1, $mem\n\t"
7501             "ADD_w    $tmp1, $tmp1, $add\n\t"
7502             "STXR_w   $tmp2, $tmp1, $mem\n\t"
7503             "CBNZ_w   $tmp2, loop" %}
7504 
7505   ins_encode %{
7506     Label loop;
7507     Register base = reg_to_register_object($mem$$base);
7508     __ bind(loop);
7509     __ ldxr_w($tmp1$$Register, base);
7510     __ add_w($tmp1$$Register, $tmp1$$Register, $add$$constant);
7511     __ stxr_w($tmp2$$Register, $tmp1$$Register, base);
7512     __ cbnz_w($tmp2$$Register, loop);
7513   %}
7514   ins_pipe( long_memory_op );
7515 %}
7516 #else
7517 instruct xaddI_aimmI_no_res(memoryex mem, aimmI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
7518   predicate(n->as_LoadStore()->result_not_used());
7519   match(Set dummy (GetAndAddI mem add));
7520   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
7521   size(20);
7522   format %{ "loop: \n\t"
7523             "LDREX    $tmp1, $mem\n\t"
7524             "ADD      $tmp1, $tmp1, $add\n\t"
7525             "STREX    $tmp2, $tmp1, $mem\n\t"
7526             "CMP      $tmp2, 0 \n\t"
7527             "B.ne     loop \n\t" %}
7528 
7529   ins_encode %{
7530     Label loop;
7531     __ bind(loop);
7532     __ ldrex($tmp1$$Register,$mem$$Address);
7533     __ add($tmp1$$Register, $tmp1$$Register, $add$$constant);
7534     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
7535     __ cmp($tmp2$$Register, 0);
7536     __ b(loop, ne);
7537   %}
7538   ins_pipe( long_memory_op );
7539 %}
7540 #endif
7541 
7542 #ifdef AARCH64
7543 instruct xaddI_reg_no_res(memoryex mem, iRegI add, Universe dummy, iRegI tmp1, iRegI tmp2) %{
7544   predicate(n->as_LoadStore()->result_not_used());
7545   match(Set dummy (GetAndAddI mem add));
7546   effect(TEMP tmp1, TEMP tmp2);
7547   size(16);
7548   format %{ "loop:\n\t"
7549             "LDXR_w   $tmp1, $mem\n\t"
7550             "ADD_w    $tmp1, $tmp1, $add\n\t"
7551             "STXR_w   $tmp2, $tmp1, $mem\n\t"
7552             "CBNZ_w   $tmp2, loop" %}
7553 
7554   ins_encode %{
7555     Label loop;
7556     Register base = reg_to_register_object($mem$$base);
7557     __ bind(loop);
7558     __ ldxr_w($tmp1$$Register, base);
7559     __ add_w($tmp1$$Register, $tmp1$$Register, $add$$Register);
7560     __ stxr_w($tmp2$$Register, $tmp1$$Register, base);
7561     __ cbnz_w($tmp2$$Register, loop);
7562   %}
7563   ins_pipe( long_memory_op );
7564 %}
7565 #else
7566 instruct xaddI_reg_no_res(memoryex mem, iRegI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
7567   predicate(n->as_LoadStore()->result_not_used());
7568   match(Set dummy (GetAndAddI mem add));
7569   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
7570   size(20);
7571   format %{ "loop: \n\t"
7572             "LDREX    $tmp1, $mem\n\t"
7573             "ADD      $tmp1, $tmp1, $add\n\t"
7574             "STREX    $tmp2, $tmp1, $mem\n\t"
7575             "CMP      $tmp2, 0 \n\t"
7576             "B.ne     loop \n\t" %}
7577 
7578   ins_encode %{
7579     Label loop;
7580     __ bind(loop);
7581     __ ldrex($tmp1$$Register,$mem$$Address);
7582     __ add($tmp1$$Register, $tmp1$$Register, $add$$Register);
7583     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
7584     __ cmp($tmp2$$Register, 0);
7585     __ b(loop, ne);
7586   %}
7587   ins_pipe( long_memory_op );
7588 %}
7589 #endif
7590 
7591 #ifdef AARCH64
7592 instruct xaddI_aimmI(memoryex mem, aimmI add, iRegI res, iRegI tmp1, iRegI tmp2) %{
7593   match(Set res (GetAndAddI mem add));
7594   effect(TEMP tmp1, TEMP tmp2, TEMP res);
7595   size(16);
7596   format %{ "loop:\n\t"
7597             "LDXR_w   $res, $mem\n\t"
7598             "ADD_w    $tmp1, $res, $add\n\t"
7599             "STXR_w   $tmp2, $tmp1, $mem\n\t"
7600             "CBNZ_w   $tmp2, loop" %}
7601 
7602   ins_encode %{
7603     Label loop;
7604     Register base = reg_to_register_object($mem$$base);
7605     __ bind(loop);
7606     __ ldxr_w($res$$Register, base);
7607     __ add_w($tmp1$$Register, $res$$Register, $add$$constant);
7608     __ stxr_w($tmp2$$Register, $tmp1$$Register, base);
7609     __ cbnz_w($tmp2$$Register, loop);
7610   %}
7611   ins_pipe( long_memory_op );
7612 %}
7613 #else
7614 instruct xaddI_aimmI(memoryex mem, aimmI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
7615   match(Set res (GetAndAddI mem add));
7616   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
7617   size(20);
7618   format %{ "loop: \n\t"
7619             "LDREX    $res, $mem\n\t"
7620             "ADD      $tmp1, $res, $add\n\t"
7621             "STREX    $tmp2, $tmp1, $mem\n\t"
7622             "CMP      $tmp2, 0 \n\t"
7623             "B.ne     loop \n\t" %}
7624 
7625   ins_encode %{
7626     Label loop;
7627     __ bind(loop);
7628     __ ldrex($res$$Register,$mem$$Address);
7629     __ add($tmp1$$Register, $res$$Register, $add$$constant);
7630     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
7631     __ cmp($tmp2$$Register, 0);
7632     __ b(loop, ne);
7633   %}
7634   ins_pipe( long_memory_op );
7635 %}
7636 #endif
7637 
7638 #ifdef AARCH64
7639 instruct xaddI_reg(memoryex mem, iRegI add, iRegI res, iRegI tmp1, iRegI tmp2) %{
7640   match(Set res (GetAndAddI mem add));
7641   effect(TEMP tmp1, TEMP tmp2, TEMP res);
7642   size(16);
7643   format %{ "loop:\n\t"
7644             "LDXR_w   $res, $mem\n\t"
7645             "ADD_w    $tmp1, $res, $add\n\t"
7646             "STXR_w   $tmp2, $tmp1, $mem\n\t"
7647             "CBNZ_w   $tmp2, loop" %}
7648 
7649   ins_encode %{
7650     Label loop;
7651     Register base = reg_to_register_object($mem$$base);
7652     __ bind(loop);
7653     __ ldxr_w($res$$Register, base);
7654     __ add_w($tmp1$$Register, $res$$Register, $add$$Register);
7655     __ stxr_w($tmp2$$Register, $tmp1$$Register, base);
7656     __ cbnz_w($tmp2$$Register, loop);
7657   %}
7658   ins_pipe( long_memory_op );
7659 %}
7660 #else
7661 instruct xaddI_reg(memoryex mem, iRegI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
7662   match(Set res (GetAndAddI mem add));
7663   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
7664   size(20);
7665   format %{ "loop: \n\t"
7666             "LDREX    $res, $mem\n\t"
7667             "ADD      $tmp1, $res, $add\n\t"
7668             "STREX    $tmp2, $tmp1, $mem\n\t"
7669             "CMP      $tmp2, 0 \n\t"
7670             "B.ne     loop \n\t" %}
7671 
7672   ins_encode %{
7673     Label loop;
7674     __ bind(loop);
7675     __ ldrex($res$$Register,$mem$$Address);
7676     __ add($tmp1$$Register, $res$$Register, $add$$Register);
7677     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
7678     __ cmp($tmp2$$Register, 0);
7679     __ b(loop, ne);
7680   %}
7681   ins_pipe( long_memory_op );
7682 %}
7683 #endif
7684 
7685 #ifdef AARCH64
7686 instruct xaddL_reg_no_res(memoryex mem, iRegL add, Universe dummy, iRegL tmp1, iRegI tmp2) %{
7687   predicate(n->as_LoadStore()->result_not_used());
7688   match(Set dummy (GetAndAddL mem add));
7689   effect(TEMP tmp1, TEMP tmp2);
7690   size(16);
7691   format %{ "loop:\n\t"
7692             "LDXR     $tmp1, $mem\n\t"
7693             "ADD      $tmp1, $tmp1, $add\n\t"
7694             "STXR     $tmp2, $tmp1, $mem\n\t"
7695             "CBNZ_w   $tmp2, loop" %}
7696 
7697   ins_encode %{
7698     Label loop;
7699     Register base = reg_to_register_object($mem$$base);
7700     __ bind(loop);
7701     __ ldxr($tmp1$$Register, base);
7702     __ add($tmp1$$Register, $tmp1$$Register, $add$$Register);
7703     __ stxr($tmp2$$Register, $tmp1$$Register, base);
7704     __ cbnz_w($tmp2$$Register, loop);
7705   %}
7706   ins_pipe( long_memory_op );
7707 %}
7708 #else
7709 instruct xaddL_reg_no_res(memoryex mem, iRegL add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
7710   predicate(n->as_LoadStore()->result_not_used());
7711   match(Set dummy (GetAndAddL mem add));
7712   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
7713   size(24);
7714   format %{ "loop: \n\t"
7715             "LDREXD   $tmp1, $mem\n\t"
7716             "ADDS     $tmp1.lo, $tmp1.lo, $add.lo\n\t"
7717             "ADC      $tmp1.hi, $tmp1.hi, $add.hi\n\t"
7718             "STREXD   $tmp2, $tmp1, $mem\n\t"
7719             "CMP      $tmp2, 0 \n\t"
7720             "B.ne     loop \n\t" %}
7721 
7722   ins_encode %{
7723     Label loop;
7724     __ bind(loop);
7725     __ ldrexd($tmp1$$Register, $mem$$Address);
7726     __ adds($tmp1$$Register, $tmp1$$Register, $add$$Register);
7727     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), $add$$Register->successor());
7728     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
7729     __ cmp($tmp2$$Register, 0);
7730     __ b(loop, ne);
7731   %}
7732   ins_pipe( long_memory_op );
7733 %}
7734 #endif
7735 
7736 #ifdef AARCH64
7737 instruct xaddL_imm_no_res(memoryex mem, aimmL add, Universe dummy, iRegL tmp1, iRegI tmp2) %{
7738   predicate(n->as_LoadStore()->result_not_used());
7739   match(Set dummy (GetAndAddL mem add));
7740   effect(TEMP tmp1, TEMP tmp2);
7741   size(16);
7742   format %{ "loop:\n\t"
7743             "LDXR     $tmp1, $mem\n\t"
7744             "ADD      $tmp1, $tmp1, $add\n\t"
7745             "STXR     $tmp2, $tmp1, $mem\n\t"
7746             "CBNZ_w   $tmp2, loop" %}
7747 
7748   ins_encode %{
7749     Label loop;
7750     Register base = reg_to_register_object($mem$$base);
7751     __ bind(loop);
7752     __ ldxr($tmp1$$Register, base);
7753     __ add($tmp1$$Register, $tmp1$$Register, $add$$constant);
7754     __ stxr($tmp2$$Register, $tmp1$$Register, base);
7755     __ cbnz_w($tmp2$$Register, loop);
7756   %}
7757   ins_pipe( long_memory_op );
7758 %}
7759 #else
7760 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7761 // (hi($con$$constant), lo($con$$constant)) becomes
7762 instruct xaddL_immRot_no_res(memoryex mem, immLlowRot add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
7763   predicate(n->as_LoadStore()->result_not_used());
7764   match(Set dummy (GetAndAddL mem add));
7765   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
7766   size(24);
7767   format %{ "loop: \n\t"
7768             "LDREXD   $tmp1, $mem\n\t"
7769             "ADDS     $tmp1.lo, $tmp1.lo, $add\n\t"
7770             "ADC      $tmp1.hi, $tmp1.hi, 0\n\t"
7771             "STREXD   $tmp2, $tmp1, $mem\n\t"
7772             "CMP      $tmp2, 0 \n\t"
7773             "B.ne     loop \n\t" %}
7774 
7775   ins_encode %{
7776     Label loop;
7777     __ bind(loop);
7778     __ ldrexd($tmp1$$Register, $mem$$Address);
7779     __ adds($tmp1$$Register, $tmp1$$Register, $add$$constant);
7780     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), 0);
7781     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
7782     __ cmp($tmp2$$Register, 0);
7783     __ b(loop, ne);
7784   %}
7785   ins_pipe( long_memory_op );
7786 %}
7787 #endif
7788 
7789 #ifdef AARCH64
7790 instruct xaddL_reg(memoryex mem, iRegL add, iRegL res, iRegL tmp1, iRegI tmp2) %{
7791   match(Set res (GetAndAddL mem add));
7792   effect(TEMP tmp1, TEMP tmp2, TEMP res);
7793   size(16);
7794   format %{ "loop:\n\t"
7795             "LDXR     $res, $mem\n\t"
7796             "ADD      $tmp1, $res, $add\n\t"
7797             "STXR     $tmp2, $tmp1, $mem\n\t"
7798             "CBNZ_w   $tmp2, loop" %}
7799 
7800   ins_encode %{
7801     Label loop;
7802     Register base = reg_to_register_object($mem$$base);
7803     __ bind(loop);
7804     __ ldxr($res$$Register, base);
7805     __ add($tmp1$$Register, $res$$Register, $add$$Register);
7806     __ stxr($tmp2$$Register, $tmp1$$Register, base);
7807     __ cbnz_w($tmp2$$Register, loop);
7808   %}
7809   ins_pipe( long_memory_op );
7810 %}
7811 #else
7812 instruct xaddL_reg(memoryex mem, iRegL add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
7813   match(Set res (GetAndAddL mem add));
7814   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
7815   size(24);
7816   format %{ "loop: \n\t"
7817             "LDREXD   $res, $mem\n\t"
7818             "ADDS     $tmp1.lo, $res.lo, $add.lo\n\t"
7819             "ADC      $tmp1.hi, $res.hi, $add.hi\n\t"
7820             "STREXD   $tmp2, $tmp1, $mem\n\t"
7821             "CMP      $tmp2, 0 \n\t"
7822             "B.ne     loop \n\t" %}
7823 
7824   ins_encode %{
7825     Label loop;
7826     __ bind(loop);
7827     __ ldrexd($res$$Register, $mem$$Address);
7828     __ adds($tmp1$$Register, $res$$Register, $add$$Register);
7829     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), $add$$Register->successor());
7830     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
7831     __ cmp($tmp2$$Register, 0);
7832     __ b(loop, ne);
7833   %}
7834   ins_pipe( long_memory_op );
7835 %}
7836 #endif
7837 
7838 #ifdef AARCH64
7839 instruct xaddL_imm(memoryex mem, aimmL add, iRegL res, iRegL tmp1, iRegI tmp2) %{
7840   match(Set res (GetAndAddL mem add));
7841   effect(TEMP tmp1, TEMP tmp2, TEMP res);
7842   size(16);
7843   format %{ "loop:\n\t"
7844             "LDXR     $res, $mem\n\t"
7845             "ADD      $tmp1, $res, $add\n\t"
7846             "STXR     $tmp2, $tmp1, $mem\n\t"
7847             "CBNZ_w   $tmp2, loop" %}
7848 
7849   ins_encode %{
7850     Label loop;
7851     Register base = reg_to_register_object($mem$$base);
7852     __ bind(loop);
7853     __ ldxr($res$$Register, base);
7854     __ add($tmp1$$Register, $res$$Register, $add$$constant);
7855     __ stxr($tmp2$$Register, $tmp1$$Register, base);
7856     __ cbnz_w($tmp2$$Register, loop);
7857   %}
7858   ins_pipe( long_memory_op );
7859 %}
7860 #else
7861 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7862 // (hi($con$$constant), lo($con$$constant)) becomes
7863 instruct xaddL_immRot(memoryex mem, immLlowRot add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
7864   match(Set res (GetAndAddL mem add));
7865   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
7866   size(24);
7867   format %{ "loop: \n\t"
7868             "LDREXD   $res, $mem\n\t"
7869             "ADDS     $tmp1.lo, $res.lo, $add\n\t"
7870             "ADC      $tmp1.hi, $res.hi, 0\n\t"
7871             "STREXD   $tmp2, $tmp1, $mem\n\t"
7872             "CMP      $tmp2, 0 \n\t"
7873             "B.ne     loop \n\t" %}
7874 
7875   ins_encode %{
7876     Label loop;
7877     __ bind(loop);
7878     __ ldrexd($res$$Register, $mem$$Address);
7879     __ adds($tmp1$$Register, $res$$Register, $add$$constant);
7880     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), 0);
7881     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
7882     __ cmp($tmp2$$Register, 0);
7883     __ b(loop, ne);
7884   %}
7885   ins_pipe( long_memory_op );
7886 %}
7887 #endif
7888 
7889 #ifdef AARCH64
7890 instruct xchgI(memoryex mem, iRegI newval, iRegI res, iRegI tmp) %{
7891   match(Set res (GetAndSetI mem newval));
7892   effect(TEMP tmp, TEMP res);
7893   size(12);
7894   format %{ "loop:\n\t"
7895             "LDXR_w   $res, $mem\n\t"
7896             "STXR_w   $tmp, $newval, $mem\n\t"
7897             "CBNZ_w   $tmp, loop" %}
7898 
7899   ins_encode %{
7900     Label loop;
7901     Register base = reg_to_register_object($mem$$base);
7902     __ bind(loop);
7903     __ ldxr_w($res$$Register, base);
7904     __ stxr_w($tmp$$Register, $newval$$Register, base);
7905     __ cbnz_w($tmp$$Register, loop);
7906   %}
7907   ins_pipe( long_memory_op );
7908 %}
7909 
7910 #ifdef XXX
7911 // Disabled until 8051805 is fixed.
7912 instruct xchgN(memoryex mem, iRegN newval, iRegN res, iRegN tmp) %{
7913   match(Set res (GetAndSetN mem newval));
7914   effect(TEMP tmp, TEMP res);
7915   size(12);
7916   format %{ "loop:\n\t"
7917             "LDXR_w   $res, $mem\n\t"
7918             "STXR_w   $tmp, $newval, $mem\n\t"
7919             "CBNZ_w   $tmp, loop" %}
7920 
7921   ins_encode %{
7922     Label loop;
7923     Register base = reg_to_register_object($mem$$base);
7924     __ bind(loop);
7925     __ ldxr_w($res$$Register, base);
7926     __ stxr_w($tmp$$Register, $newval$$Register, base);
7927     __ cbnz_w($tmp$$Register, loop);
7928   %}
7929   ins_pipe( long_memory_op );
7930 %}
7931 #endif
7932 #else
7933 instruct xchgI(memoryex mem, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr) %{
7934   match(Set res (GetAndSetI mem newval));
7935   effect(KILL ccr, TEMP tmp, TEMP res);
7936   size(16);
7937   format %{ "loop: \n\t"
7938             "LDREX    $res, $mem\n\t"
7939             "STREX    $tmp, $newval, $mem\n\t"
7940             "CMP      $tmp, 0 \n\t"
7941             "B.ne     loop \n\t" %}
7942 
7943   ins_encode %{
7944     Label loop;
7945     __ bind(loop);
7946     __ ldrex($res$$Register,$mem$$Address);
7947     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
7948     __ cmp($tmp$$Register, 0);
7949     __ b(loop, ne);
7950   %}
7951   ins_pipe( long_memory_op );
7952 %}
7953 #endif
7954 
7955 #ifdef AARCH64
7956 instruct xchgL(memoryex mem, iRegL newval, iRegL res, iRegI tmp) %{
7957   match(Set res (GetAndSetL mem newval));
7958   effect(TEMP tmp, TEMP res);
7959   size(12);
7960   format %{ "loop:\n\t"
7961             "LDXR     $res, $mem\n\t"
7962             "STXR     $tmp, $newval, $mem\n\t"
7963             "CBNZ_w   $tmp, loop" %}
7964 
7965   ins_encode %{
7966     Label loop;
7967     Register base = reg_to_register_object($mem$$base);
7968     __ bind(loop);
7969     __ ldxr($res$$Register, base);
7970     __ stxr($tmp$$Register, $newval$$Register, base);
7971     __ cbnz_w($tmp$$Register, loop);
7972   %}
7973   ins_pipe( long_memory_op );
7974 %}
7975 #else
7976 instruct xchgL(memoryex mem, iRegLd newval, iRegLd res, iRegI tmp, flagsReg ccr) %{
7977   match(Set res (GetAndSetL mem newval));
7978   effect( KILL ccr, TEMP tmp, TEMP res);
7979   size(16);
7980   format %{ "loop: \n\t"
7981             "LDREXD   $res, $mem\n\t"
7982             "STREXD   $tmp, $newval, $mem\n\t"
7983             "CMP      $tmp, 0 \n\t"
7984             "B.ne     loop \n\t" %}
7985 
7986   ins_encode %{
7987     Label loop;
7988     __ bind(loop);
7989     __ ldrexd($res$$Register, $mem$$Address);
7990     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address);
7991     __ cmp($tmp$$Register, 0);
7992     __ b(loop, ne);
7993   %}
7994   ins_pipe( long_memory_op );
7995 %}
7996 #endif // !AARCH64
7997 
7998 #ifdef AARCH64
7999 instruct xchgP(memoryex mem, iRegP newval, iRegP res, iRegI tmp) %{
8000   match(Set res (GetAndSetP mem newval));
8001   effect(TEMP tmp, TEMP res);
8002   size(12);
8003   format %{ "loop:\n\t"
8004             "LDREX    $res, $mem\n\t"
8005             "STREX    $tmp, $newval, $mem\n\t"
8006             "CBNZ_w   $tmp, loop" %}
8007 
8008   ins_encode %{
8009     Label loop;
8010     Register base = reg_to_register_object($mem$$base);
8011     __ bind(loop);
8012     __ ldrex($res$$Register, base);
8013     __ strex($tmp$$Register, $newval$$Register, base);
8014     __ cbnz_w($tmp$$Register, loop);
8015   %}
8016   ins_pipe( long_memory_op );
8017 %}
8018 #else
8019 instruct xchgP(memoryex mem, iRegP newval, iRegP res, iRegI tmp, flagsReg ccr) %{
8020   match(Set res (GetAndSetP mem newval));
8021   effect(KILL ccr, TEMP tmp, TEMP res);
8022   size(16);
8023   format %{ "loop: \n\t"
8024             "LDREX    $res, $mem\n\t"
8025             "STREX    $tmp, $newval, $mem\n\t"
8026             "CMP      $tmp, 0 \n\t"
8027             "B.ne     loop \n\t" %}
8028 
8029   ins_encode %{
8030     Label loop;
8031     __ bind(loop);
8032     __ ldrex($res$$Register,$mem$$Address);
8033     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
8034     __ cmp($tmp$$Register, 0);
8035     __ b(loop, ne);
8036   %}
8037   ins_pipe( long_memory_op );
8038 %}
8039 #endif // !AARCH64
8040 
8041 //---------------------
8042 // Subtraction Instructions
8043 // Register Subtraction
8044 instruct subI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
8045   match(Set dst (SubI src1 src2));
8046 
8047   size(4);
8048   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
8049   ins_encode %{
8050     __ sub_32($dst$$Register, $src1$$Register, $src2$$Register);
8051   %}
8052   ins_pipe(ialu_reg_reg);
8053 %}
8054 
8055 #ifndef AARCH64
8056 instruct subshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
8057   match(Set dst (SubI src1 (LShiftI src2 src3)));
8058 
8059   size(4);
8060   format %{ "SUB    $dst,$src1,$src2<<$src3" %}
8061   ins_encode %{
8062     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
8063   %}
8064   ins_pipe(ialu_reg_reg);
8065 %}
8066 #endif
8067 
8068 instruct subshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
8069   match(Set dst (SubI src1 (LShiftI src2 src3)));
8070 
8071   size(4);
8072   format %{ "sub_32 $dst,$src1,$src2<<$src3\t! int" %}
8073   ins_encode %{
8074     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
8075   %}
8076   ins_pipe(ialu_reg_reg);
8077 %}
8078 
8079 #ifndef AARCH64
8080 instruct subsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
8081   match(Set dst (SubI src1 (RShiftI src2 src3)));
8082 
8083   size(4);
8084   format %{ "SUB    $dst,$src1,$src2>>$src3" %}
8085   ins_encode %{
8086     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
8087   %}
8088   ins_pipe(ialu_reg_reg);
8089 %}
8090 #endif
8091 
8092 instruct subsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
8093   match(Set dst (SubI src1 (RShiftI src2 src3)));
8094 
8095   size(4);
8096   format %{ "sub_32 $dst,$src1,$src2>>$src3\t! int" %}
8097   ins_encode %{
8098     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
8099   %}
8100   ins_pipe(ialu_reg_reg);
8101 %}
8102 
8103 #ifndef AARCH64
8104 instruct subshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
8105   match(Set dst (SubI src1 (URShiftI src2 src3)));
8106 
8107   size(4);
8108   format %{ "SUB    $dst,$src1,$src2>>>$src3" %}
8109   ins_encode %{
8110     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
8111   %}
8112   ins_pipe(ialu_reg_reg);
8113 %}
8114 #endif
8115 
8116 instruct subshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
8117   match(Set dst (SubI src1 (URShiftI src2 src3)));
8118 
8119   size(4);
8120   format %{ "sub_32 $dst,$src1,$src2>>>$src3\t! int" %}
8121   ins_encode %{
8122     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
8123   %}
8124   ins_pipe(ialu_reg_reg);
8125 %}
8126 
8127 #ifndef AARCH64
8128 instruct rsbshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
8129   match(Set dst (SubI (LShiftI src1 src2) src3));
8130 
8131   size(4);
8132   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
8133   ins_encode %{
8134     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
8135   %}
8136   ins_pipe(ialu_reg_reg);
8137 %}
8138 
8139 instruct rsbshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
8140   match(Set dst (SubI (LShiftI src1 src2) src3));
8141 
8142   size(4);
8143   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
8144   ins_encode %{
8145     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
8146   %}
8147   ins_pipe(ialu_reg_reg);
8148 %}
8149 
8150 instruct rsbsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
8151   match(Set dst (SubI (RShiftI src1 src2) src3));
8152 
8153   size(4);
8154   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
8155   ins_encode %{
8156     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
8157   %}
8158   ins_pipe(ialu_reg_reg);
8159 %}
8160 
8161 instruct rsbsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
8162   match(Set dst (SubI (RShiftI src1 src2) src3));
8163 
8164   size(4);
8165   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
8166   ins_encode %{
8167     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
8168   %}
8169   ins_pipe(ialu_reg_reg);
8170 %}
8171 
8172 instruct rsbshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
8173   match(Set dst (SubI (URShiftI src1 src2) src3));
8174 
8175   size(4);
8176   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
8177   ins_encode %{
8178     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
8179   %}
8180   ins_pipe(ialu_reg_reg);
8181 %}
8182 
8183 instruct rsbshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
8184   match(Set dst (SubI (URShiftI src1 src2) src3));
8185 
8186   size(4);
8187   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
8188   ins_encode %{
8189     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
8190   %}
8191   ins_pipe(ialu_reg_reg);
8192 %}
8193 #endif
8194 
8195 // Immediate Subtraction
8196 instruct subI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
8197   match(Set dst (SubI src1 src2));
8198 
8199   size(4);
8200   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
8201   ins_encode %{
8202     __ sub_32($dst$$Register, $src1$$Register, $src2$$constant);
8203   %}
8204   ins_pipe(ialu_reg_imm);
8205 %}
8206 
8207 instruct subI_reg_immRotneg(iRegI dst, iRegI src1, aimmIneg src2) %{
8208   match(Set dst (AddI src1 src2));
8209 
8210   size(4);
8211   format %{ "sub_32 $dst,$src1,-($src2)\t! int" %}
8212   ins_encode %{
8213     __ sub_32($dst$$Register, $src1$$Register, -$src2$$constant);
8214   %}
8215   ins_pipe(ialu_reg_imm);
8216 %}
8217 
8218 #ifndef AARCH64
8219 instruct subI_immRot_reg(iRegI dst, immIRot src1, iRegI src2) %{
8220   match(Set dst (SubI src1 src2));
8221 
8222   size(4);
8223   format %{ "RSB    $dst,$src2,src1" %}
8224   ins_encode %{
8225     __ rsb($dst$$Register, $src2$$Register, $src1$$constant);
8226   %}
8227   ins_pipe(ialu_zero_reg);
8228 %}
8229 #endif
8230 
8231 // Register Subtraction
8232 #ifdef AARCH64
8233 instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
8234   match(Set dst (SubL src1 src2));
8235 
8236   size(4);
8237   format %{ "SUB    $dst,$src1,$src2\t! long" %}
8238   ins_encode %{
8239     __ sub($dst$$Register, $src1$$Register, $src2$$Register);
8240   %}
8241   ins_pipe(ialu_reg_reg);
8242 %}
8243 #else
8244 instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg icc ) %{
8245   match(Set dst (SubL src1 src2));
8246   effect (KILL icc);
8247 
8248   size(8);
8249   format %{ "SUBS   $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
8250             "SBC    $dst.hi,$src1.hi,$src2.hi" %}
8251   ins_encode %{
8252     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
8253     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
8254   %}
8255   ins_pipe(ialu_reg_reg);
8256 %}
8257 #endif
8258 
8259 #ifdef AARCH64
8260 // Immediate Subtraction
8261 instruct subL_reg_aimm(iRegL dst, iRegL src1, aimmL src2) %{
8262   match(Set dst (SubL src1 src2));
8263 
8264   size(4);
8265   format %{ "SUB    $dst,$src1,$src2\t! long" %}
8266   ins_encode %{
8267     __ sub($dst$$Register, $src1$$Register, $src2$$constant);
8268   %}
8269   ins_pipe(ialu_reg_imm);
8270 %}
8271 
8272 instruct subL_reg_immLneg(iRegL dst, iRegL src1, aimmLneg src2) %{
8273   match(Set dst (AddL src1 src2));
8274 
8275   size(4);
8276   format %{ "SUB    $dst,$src1,-($src2)\t! long" %}
8277   ins_encode %{
8278     __ sub($dst$$Register, $src1$$Register, -$src2$$constant);
8279   %}
8280   ins_pipe(ialu_reg_imm);
8281 %}
8282 #else
8283 // TODO
8284 #endif
8285 
8286 #ifndef AARCH64
8287 // Immediate Subtraction
8288 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
8289 // (hi($con$$constant), lo($con$$constant)) becomes
8290 instruct subL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg icc) %{
8291   match(Set dst (SubL src1 con));
8292   effect (KILL icc);
8293 
8294   size(8);
8295   format %{ "SUB    $dst.lo,$src1.lo,$con\t! long\n\t"
8296             "SBC    $dst.hi,$src1.hi,0" %}
8297   ins_encode %{
8298     __ subs($dst$$Register, $src1$$Register, $con$$constant);
8299     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), 0);
8300   %}
8301   ins_pipe(ialu_reg_imm);
8302 %}
8303 
8304 // Long negation
8305 instruct negL_reg_reg(iRegL dst, immL0 zero, iRegL src2, flagsReg icc) %{
8306   match(Set dst (SubL zero src2));
8307   effect (KILL icc);
8308 
8309   size(8);
8310   format %{ "RSBS   $dst.lo,$src2.lo,0\t! long\n\t"
8311             "RSC    $dst.hi,$src2.hi,0" %}
8312   ins_encode %{
8313     __ rsbs($dst$$Register, $src2$$Register, 0);
8314     __ rsc($dst$$Register->successor(), $src2$$Register->successor(), 0);
8315   %}
8316   ins_pipe(ialu_zero_reg);
8317 %}
8318 #endif // !AARCH64
8319 
8320 // Multiplication Instructions
8321 // Integer Multiplication
8322 // Register Multiplication
8323 instruct mulI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
8324   match(Set dst (MulI src1 src2));
8325 
8326   size(4);
8327   format %{ "mul_32 $dst,$src1,$src2" %}
8328   ins_encode %{
8329     __ mul_32($dst$$Register, $src1$$Register, $src2$$Register);
8330   %}
8331   ins_pipe(imul_reg_reg);
8332 %}
8333 
8334 #ifdef AARCH64
8335 instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
8336   match(Set dst (MulL src1 src2));
8337   size(4);
8338   format %{ "MUL  $dst,$src1,$src2\t! long" %}
8339   ins_encode %{
8340     __ mul($dst$$Register, $src1$$Register, $src2$$Register);
8341   %}
8342   ins_pipe(imul_reg_reg);
8343 %}
8344 #else
8345 instruct mulL_lo1_hi2(iRegL dst, iRegL src1, iRegL src2) %{
8346   effect(DEF dst, USE src1, USE src2);
8347   size(4);
8348   format %{ "MUL  $dst.hi,$src1.lo,$src2.hi\t! long" %}
8349   ins_encode %{
8350     __ mul($dst$$Register->successor(), $src1$$Register, $src2$$Register->successor());
8351   %}
8352   ins_pipe(imul_reg_reg);
8353 %}
8354 
8355 instruct mulL_hi1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
8356   effect(USE_DEF dst, USE src1, USE src2);
8357   size(8);
8358   format %{ "MLA  $dst.hi,$src1.hi,$src2.lo,$dst.hi\t! long\n\t"
8359             "MOV  $dst.lo, 0"%}
8360   ins_encode %{
8361     __ mla($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register, $dst$$Register->successor());
8362     __ mov($dst$$Register, 0);
8363   %}
8364   ins_pipe(imul_reg_reg);
8365 %}
8366 
8367 instruct mulL_lo1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
8368   effect(USE_DEF dst, USE src1, USE src2);
8369   size(4);
8370   format %{ "UMLAL  $dst.lo,$dst.hi,$src1,$src2\t! long" %}
8371   ins_encode %{
8372     __ umlal($dst$$Register, $dst$$Register->successor(), $src1$$Register, $src2$$Register);
8373   %}
8374   ins_pipe(imul_reg_reg);
8375 %}
8376 
8377 instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
8378   match(Set dst (MulL src1 src2));
8379 
8380   expand %{
8381     mulL_lo1_hi2(dst, src1, src2);
8382     mulL_hi1_lo2(dst, src1, src2);
8383     mulL_lo1_lo2(dst, src1, src2);
8384   %}
8385 %}
8386 #endif // !AARCH64
8387 
8388 // Integer Division
8389 // Register Division
8390 #ifdef AARCH64
8391 instruct divI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
8392   match(Set dst (DivI src1 src2));
8393 
8394   size(4);
8395   format %{ "SDIV    $dst,$src1,$src2\t! 32-bit" %}
8396   ins_encode %{
8397     __ sdiv_w($dst$$Register, $src1$$Register, $src2$$Register);
8398   %}
8399   ins_pipe(ialu_reg_reg); // FIXME
8400 %}
8401 #else
8402 instruct divI_reg_reg(R1RegI dst, R0RegI src1, R2RegI src2, LRRegP lr, flagsReg ccr) %{
8403   match(Set dst (DivI src1 src2));
8404   effect( KILL ccr, KILL src1, KILL src2, KILL lr);
8405   ins_cost((2+71)*DEFAULT_COST);
8406 
8407   format %{ "DIV   $dst,$src1,$src2 ! call to StubRoutines::Arm::idiv_irem_entry()" %}
8408   ins_encode %{
8409     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
8410   %}
8411   ins_pipe(sdiv_reg_reg);
8412 %}
8413 #endif
8414 
8415 // Register Long Division
8416 #ifdef AARCH64
8417 instruct divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
8418   match(Set dst (DivL src1 src2));
8419 
8420   size(4);
8421   format %{ "SDIV    $dst,$src1,$src2" %}
8422   ins_encode %{
8423     __ sdiv($dst$$Register, $src1$$Register, $src2$$Register);
8424   %}
8425   ins_pipe(ialu_reg_reg); // FIXME
8426 %}
8427 #else
8428 instruct divL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
8429   match(Set dst (DivL src1 src2));
8430   effect(CALL);
8431   ins_cost(DEFAULT_COST*71);
8432   format %{ "DIVL  $src1,$src2,$dst\t! long ! call to SharedRuntime::ldiv" %}
8433   ins_encode %{
8434     address target = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);
8435     __ call(target, relocInfo::runtime_call_type);
8436   %}
8437   ins_pipe(divL_reg_reg);
8438 %}
8439 #endif
8440 
8441 // Integer Remainder
8442 // Register Remainder
8443 #ifdef AARCH64
8444 #ifdef TODO
8445 instruct msubI_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
8446   match(Set dst (SubI src1 (MulI src2 src3)));
8447 
8448   size(4);
8449   format %{ "MSUB    $dst,$src2,$src3,$src1\t! 32-bit\n\t" %}
8450   ins_encode %{
8451     __ msub_w($dst$$Register, $src2$$Register, $src3$$Register, $src1$$Register);
8452   %}
8453   ins_pipe(ialu_reg_reg); // FIXME
8454 %}
8455 #endif
8456 
8457 instruct modI_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI temp) %{
8458   match(Set dst (ModI src1 src2));
8459   effect(TEMP temp);
8460 
8461   size(8);
8462   format %{ "SDIV    $temp,$src1,$src2\t! 32-bit\n\t"
8463             "MSUB    $dst,$src2,$temp,$src1\t! 32-bit\n\t" %}
8464   ins_encode %{
8465     __ sdiv_w($temp$$Register, $src1$$Register, $src2$$Register);
8466     __ msub_w($dst$$Register, $src2$$Register, $temp$$Register, $src1$$Register);
8467   %}
8468   ins_pipe(ialu_reg_reg); // FIXME
8469 %}
8470 #else
8471 instruct modI_reg_reg(R0RegI dst, R0RegI src1, R2RegI src2, R1RegI temp, LRRegP lr, flagsReg ccr ) %{
8472   match(Set dst (ModI src1 src2));
8473   effect( KILL ccr, KILL temp, KILL src2, KILL lr);
8474 
8475   format %{ "MODI   $dst,$src1,$src2\t ! call to StubRoutines::Arm::idiv_irem_entry" %}
8476   ins_encode %{
8477     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
8478   %}
8479   ins_pipe(sdiv_reg_reg);
8480 %}
8481 #endif
8482 
8483 // Register Long Remainder
8484 #ifdef AARCH64
8485 instruct modL_reg_reg(iRegL dst, iRegL src1, iRegL src2, iRegL temp) %{
8486   match(Set dst (ModL src1 src2));
8487   effect(TEMP temp);
8488 
8489   size(8);
8490   format %{ "SDIV    $temp,$src1,$src2\n\t"
8491             "MSUB    $dst,$src2,$temp,$src1" %}
8492   ins_encode %{
8493     __ sdiv($temp$$Register, $src1$$Register, $src2$$Register);
8494     __ msub($dst$$Register, $src2$$Register, $temp$$Register, $src1$$Register);
8495   %}
8496   ins_pipe(ialu_reg_reg); // FIXME
8497 %}
8498 #else
8499 instruct modL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
8500   match(Set dst (ModL src1 src2));
8501   effect(CALL);
8502   ins_cost(MEMORY_REF_COST); // FIXME
8503   format %{ "modL    $dst,$src1,$src2\t ! call to SharedRuntime::lrem" %}
8504   ins_encode %{
8505     address target = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
8506     __ call(target, relocInfo::runtime_call_type);
8507   %}
8508   ins_pipe(divL_reg_reg);
8509 %}
8510 #endif
8511 
8512 // Integer Shift Instructions
8513 
8514 // Register Shift Left
8515 instruct shlI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
8516   match(Set dst (LShiftI src1 src2));
8517 
8518   size(4);
8519 #ifdef AARCH64
8520   format %{ "LSLV   $dst,$src1,$src2\t! int" %}
8521   ins_encode %{
8522     __ lslv_w($dst$$Register, $src1$$Register, $src2$$Register);
8523   %}
8524 #else
8525   format %{ "LSL  $dst,$src1,$src2 \n\t" %}
8526   ins_encode %{
8527     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
8528   %}
8529 #endif
8530   ins_pipe(ialu_reg_reg);
8531 %}
8532 
8533 // Register Shift Left Immediate
8534 instruct shlI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
8535   match(Set dst (LShiftI src1 src2));
8536 
8537   size(4);
8538 #ifdef AARCH64
8539   format %{ "LSL_w  $dst,$src1,$src2\t! int" %}
8540   ins_encode %{
8541     __ _lsl($dst$$Register, $src1$$Register, $src2$$constant);
8542   %}
8543 #else
8544   format %{ "LSL    $dst,$src1,$src2\t! int" %}
8545   ins_encode %{
8546     __ logical_shift_left($dst$$Register, $src1$$Register, $src2$$constant);
8547   %}
8548 #endif
8549   ins_pipe(ialu_reg_imm);
8550 %}
8551 
8552 #ifndef AARCH64
8553 instruct shlL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
8554   effect(USE_DEF dst, USE src1, USE src2);
8555   size(4);
8556   format %{"OR  $dst.hi,$dst.hi,($src1.hi << $src2)"  %}
8557   ins_encode %{
8558     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$Register));
8559   %}
8560   ins_pipe(ialu_reg_reg);
8561 %}
8562 
8563 instruct shlL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
8564   effect(USE_DEF dst, USE src1, USE src2);
8565   size(4);
8566   format %{ "LSL  $dst.lo,$src1.lo,$src2 \n\t" %}
8567   ins_encode %{
8568     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
8569   %}
8570   ins_pipe(ialu_reg_reg);
8571 %}
8572 
8573 instruct shlL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
8574   effect(DEF dst, USE src1, USE src2, KILL ccr);
8575   size(16);
8576   format %{ "SUBS  $dst.hi,$src2,32 \n\t"
8577             "LSLpl $dst.hi,$src1.lo,$dst.hi \n\t"
8578             "RSBmi $dst.hi,$dst.hi,0 \n\t"
8579             "LSRmi $dst.hi,$src1.lo,$dst.hi" %}
8580 
8581   ins_encode %{
8582     // $src1$$Register and $dst$$Register->successor() can't be the same
8583     __ subs($dst$$Register->successor(), $src2$$Register, 32);
8584     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $dst$$Register->successor()), pl);
8585     __ rsb($dst$$Register->successor(), $dst$$Register->successor(), 0, mi);
8586     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsr, $dst$$Register->successor()), mi);
8587   %}
8588   ins_pipe(ialu_reg_reg);
8589 %}
8590 #endif // !AARCH64
8591 
8592 instruct shlL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
8593   match(Set dst (LShiftL src1 src2));
8594 
8595 #ifdef AARCH64
8596   size(4);
8597   format %{ "LSLV  $dst,$src1,$src2\t! long" %}
8598   ins_encode %{
8599     __ lslv($dst$$Register, $src1$$Register, $src2$$Register);
8600   %}
8601   ins_pipe(ialu_reg_reg);
8602 #else
8603   expand %{
8604     flagsReg ccr;
8605     shlL_reg_reg_overlap(dst, src1, src2, ccr);
8606     shlL_reg_reg_merge_hi(dst, src1, src2);
8607     shlL_reg_reg_merge_lo(dst, src1, src2);
8608   %}
8609 #endif
8610 %}
8611 
8612 #ifdef AARCH64
8613 instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6 src2) %{
8614   match(Set dst (LShiftL src1 src2));
8615 
8616   size(4);
8617   format %{ "LSL    $dst,$src1,$src2\t! long" %}
8618   ins_encode %{
8619     __ logical_shift_left($dst$$Register, $src1$$Register, $src2$$constant);
8620   %}
8621   ins_pipe(ialu_reg_imm);
8622 %}
8623 #else
8624 // Register Shift Left Immediate
8625 instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
8626   match(Set dst (LShiftL src1 src2));
8627 
8628   size(8);
8629   format %{ "LSL   $dst.hi,$src1.lo,$src2-32\t! or mov if $src2==32\n\t"
8630             "MOV   $dst.lo, 0" %}
8631   ins_encode %{
8632     if ($src2$$constant == 32) {
8633       __ mov($dst$$Register->successor(), $src1$$Register);
8634     } else {
8635       __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $src2$$constant-32));
8636     }
8637     __ mov($dst$$Register, 0);
8638   %}
8639   ins_pipe(ialu_reg_imm);
8640 %}
8641 
8642 instruct shlL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
8643   match(Set dst (LShiftL src1 src2));
8644 
8645   size(12);
8646   format %{ "LSL   $dst.hi,$src1.lo,$src2\n\t"
8647             "OR    $dst.hi, $dst.hi, $src1.lo >> 32-$src2\n\t"
8648             "LSL   $dst.lo,$src1.lo,$src2" %}
8649   ins_encode %{
8650     // The order of the following 3 instructions matters: src1.lo and
8651     // dst.hi can't overlap but src.hi and dst.hi can.
8652     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$constant));
8653     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register, lsr, 32-$src2$$constant));
8654     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
8655   %}
8656   ins_pipe(ialu_reg_imm);
8657 %}
8658 #endif // !AARCH64
8659 
8660 // Register Arithmetic Shift Right
8661 instruct sarI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
8662   match(Set dst (RShiftI src1 src2));
8663   size(4);
8664 #ifdef AARCH64
8665   format %{ "ASRV   $dst,$src1,$src2\t! int" %}
8666   ins_encode %{
8667     __ asrv_w($dst$$Register, $src1$$Register, $src2$$Register);
8668   %}
8669 #else
8670   format %{ "ASR    $dst,$src1,$src2\t! int" %}
8671   ins_encode %{
8672     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
8673   %}
8674 #endif
8675   ins_pipe(ialu_reg_reg);
8676 %}
8677 
8678 // Register Arithmetic Shift Right Immediate
8679 instruct sarI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
8680   match(Set dst (RShiftI src1 src2));
8681 
8682   size(4);
8683 #ifdef AARCH64
8684   format %{ "ASR_w  $dst,$src1,$src2" %}
8685   ins_encode %{
8686     __ _asr_w($dst$$Register, $src1$$Register, $src2$$constant);
8687   %}
8688 #else
8689   format %{ "ASR    $dst,$src1,$src2" %}
8690   ins_encode %{
8691     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
8692   %}
8693 #endif
8694   ins_pipe(ialu_reg_imm);
8695 %}
8696 
8697 #ifndef AARCH64
8698 // Register Shift Right Arithmetic Long
8699 instruct sarL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
8700   effect(USE_DEF dst, USE src1, USE src2);
8701   size(4);
8702   format %{ "OR  $dst.lo,$dst.lo,($src1.lo >> $src2)"  %}
8703   ins_encode %{
8704     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
8705   %}
8706   ins_pipe(ialu_reg_reg);
8707 %}
8708 
8709 instruct sarL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
8710   effect(USE_DEF dst, USE src1, USE src2);
8711   size(4);
8712   format %{ "ASR  $dst.hi,$src1.hi,$src2 \n\t" %}
8713   ins_encode %{
8714     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$Register));
8715   %}
8716   ins_pipe(ialu_reg_reg);
8717 %}
8718 
8719 instruct sarL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
8720   effect(DEF dst, USE src1, USE src2, KILL ccr);
8721   size(16);
8722   format %{ "SUBS  $dst.lo,$src2,32 \n\t"
8723             "ASRpl $dst.lo,$src1.hi,$dst.lo \n\t"
8724             "RSBmi $dst.lo,$dst.lo,0 \n\t"
8725             "LSLmi $dst.lo,$src1.hi,$dst.lo" %}
8726 
8727   ins_encode %{
8728     // $src1$$Register->successor() and $dst$$Register can't be the same
8729     __ subs($dst$$Register, $src2$$Register, 32);
8730     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $dst$$Register), pl);
8731     __ rsb($dst$$Register, $dst$$Register, 0, mi);
8732     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
8733   %}
8734   ins_pipe(ialu_reg_reg);
8735 %}
8736 #endif // !AARCH64
8737 
8738 instruct sarL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
8739   match(Set dst (RShiftL src1 src2));
8740 
8741 #ifdef AARCH64
8742   size(4);
8743   format %{ "ASRV  $dst,$src1,$src2\t! long" %}
8744   ins_encode %{
8745     __ asrv($dst$$Register, $src1$$Register, $src2$$Register);
8746   %}
8747   ins_pipe(ialu_reg_reg);
8748 #else
8749   expand %{
8750     flagsReg ccr;
8751     sarL_reg_reg_overlap(dst, src1, src2, ccr);
8752     sarL_reg_reg_merge_lo(dst, src1, src2);
8753     sarL_reg_reg_merge_hi(dst, src1, src2);
8754   %}
8755 #endif
8756 %}
8757 
8758 // Register Shift Left Immediate
8759 #ifdef AARCH64
8760 instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6 src2) %{
8761   match(Set dst (RShiftL src1 src2));
8762 
8763   size(4);
8764   format %{ "ASR    $dst,$src1,$src2\t! long" %}
8765   ins_encode %{
8766     __ _asr($dst$$Register, $src1$$Register, $src2$$constant);
8767   %}
8768   ins_pipe(ialu_reg_imm);
8769 %}
8770 #else
8771 instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
8772   match(Set dst (RShiftL src1 src2));
8773 
8774   size(8);
8775   format %{ "ASR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
8776             "ASR   $dst.hi,$src1.hi, $src2" %}
8777   ins_encode %{
8778     if ($src2$$constant == 32) {
8779       __ mov($dst$$Register, $src1$$Register->successor());
8780     } else{
8781       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $src2$$constant-32));
8782     }
8783     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, 0));
8784   %}
8785 
8786   ins_pipe(ialu_reg_imm);
8787 %}
8788 
8789 instruct sarL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
8790   match(Set dst (RShiftL src1 src2));
8791   size(12);
8792   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
8793             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
8794             "ASR   $dst.hi,$src1.hi,$src2" %}
8795   ins_encode %{
8796     // The order of the following 3 instructions matters: src1.lo and
8797     // dst.hi can't overlap but src.hi and dst.hi can.
8798     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
8799     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
8800     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$constant));
8801   %}
8802   ins_pipe(ialu_reg_imm);
8803 %}
8804 #endif
8805 
8806 // Register Shift Right
8807 instruct shrI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
8808   match(Set dst (URShiftI src1 src2));
8809   size(4);
8810 #ifdef AARCH64
8811   format %{ "LSRV   $dst,$src1,$src2\t! int" %}
8812   ins_encode %{
8813     __ lsrv_w($dst$$Register, $src1$$Register, $src2$$Register);
8814   %}
8815 #else
8816   format %{ "LSR    $dst,$src1,$src2\t! int" %}
8817   ins_encode %{
8818     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
8819   %}
8820 #endif
8821   ins_pipe(ialu_reg_reg);
8822 %}
8823 
8824 // Register Shift Right Immediate
8825 instruct shrI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
8826   match(Set dst (URShiftI src1 src2));
8827 
8828   size(4);
8829 #ifdef AARCH64
8830   format %{ "LSR_w  $dst,$src1,$src2" %}
8831   ins_encode %{
8832     __ _lsr_w($dst$$Register, $src1$$Register, $src2$$constant);
8833   %}
8834 #else
8835   format %{ "LSR    $dst,$src1,$src2" %}
8836   ins_encode %{
8837     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
8838   %}
8839 #endif
8840   ins_pipe(ialu_reg_imm);
8841 %}
8842 
8843 #ifndef AARCH64
8844 // Register Shift Right
8845 instruct shrL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
8846   effect(USE_DEF dst, USE src1, USE src2);
8847   size(4);
8848   format %{ "OR   $dst.lo,$dst,($src1.lo >>> $src2)"  %}
8849   ins_encode %{
8850     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
8851   %}
8852   ins_pipe(ialu_reg_reg);
8853 %}
8854 
8855 instruct shrL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
8856   effect(USE_DEF dst, USE src1, USE src2);
8857   size(4);
8858   format %{ "LSR  $dst.hi,$src1.hi,$src2 \n\t" %}
8859   ins_encode %{
8860     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$Register));
8861   %}
8862   ins_pipe(ialu_reg_reg);
8863 %}
8864 
8865 instruct shrL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
8866   effect(DEF dst, USE src1, USE src2, KILL ccr);
8867   size(16);
8868   format %{ "SUBS  $dst,$src2,32 \n\t"
8869             "LSRpl $dst,$src1.hi,$dst \n\t"
8870             "RSBmi $dst,$dst,0 \n\t"
8871             "LSLmi $dst,$src1.hi,$dst" %}
8872 
8873   ins_encode %{
8874     // $src1$$Register->successor() and $dst$$Register can't be the same
8875     __ subs($dst$$Register, $src2$$Register, 32);
8876     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $dst$$Register), pl);
8877     __ rsb($dst$$Register, $dst$$Register, 0, mi);
8878     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
8879   %}
8880   ins_pipe(ialu_reg_reg);
8881 %}
8882 #endif // !AARCH64
8883 
8884 instruct shrL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
8885   match(Set dst (URShiftL src1 src2));
8886 
8887 #ifdef AARCH64
8888   size(4);
8889   format %{ "LSRV  $dst,$src1,$src2\t! long" %}
8890   ins_encode %{
8891     __ lsrv($dst$$Register, $src1$$Register, $src2$$Register);
8892   %}
8893   ins_pipe(ialu_reg_reg);
8894 #else
8895   expand %{
8896     flagsReg ccr;
8897     shrL_reg_reg_overlap(dst, src1, src2, ccr);
8898     shrL_reg_reg_merge_lo(dst, src1, src2);
8899     shrL_reg_reg_merge_hi(dst, src1, src2);
8900   %}
8901 #endif
8902 %}
8903 
8904 // Register Shift Right Immediate
8905 #ifdef AARCH64
8906 instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6 src2) %{
8907   match(Set dst (URShiftL src1 src2));
8908 
8909   size(4);
8910   format %{ "LSR    $dst,$src1,$src2" %}
8911   ins_encode %{
8912     __ _lsr($dst$$Register, $src1$$Register, $src2$$constant);
8913   %}
8914   ins_pipe(ialu_reg_imm);
8915 %}
8916 #else
8917 instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
8918   match(Set dst (URShiftL src1 src2));
8919 
8920   size(8);
8921   format %{ "LSR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
8922             "MOV   $dst.hi, 0" %}
8923   ins_encode %{
8924     if ($src2$$constant == 32) {
8925       __ mov($dst$$Register, $src1$$Register->successor());
8926     } else {
8927       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $src2$$constant-32));
8928     }
8929     __ mov($dst$$Register->successor(), 0);
8930   %}
8931 
8932   ins_pipe(ialu_reg_imm);
8933 %}
8934 
8935 instruct shrL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
8936   match(Set dst (URShiftL src1 src2));
8937 
8938   size(12);
8939   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
8940             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
8941             "LSR   $dst.hi,$src1.hi,$src2" %}
8942   ins_encode %{
8943     // The order of the following 3 instructions matters: src1.lo and
8944     // dst.hi can't overlap but src.hi and dst.hi can.
8945     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
8946     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
8947     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$constant));
8948   %}
8949   ins_pipe(ialu_reg_imm);
8950 %}
8951 #endif // !AARCH64
8952 
8953 
8954 instruct shrP_reg_imm5(iRegX dst, iRegP src1, immU5 src2) %{
8955   match(Set dst (URShiftI (CastP2X src1) src2));
8956   size(4);
8957   format %{ "LSR    $dst,$src1,$src2\t! Cast ptr $src1 to int and shift" %}
8958   ins_encode %{
8959     __ logical_shift_right($dst$$Register, $src1$$Register, $src2$$constant);
8960   %}
8961   ins_pipe(ialu_reg_imm);
8962 %}
8963 
8964 //----------Floating Point Arithmetic Instructions-----------------------------
8965 
8966 //  Add float single precision
8967 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
8968   match(Set dst (AddF src1 src2));
8969 
8970   size(4);
8971   format %{ "FADDS  $dst,$src1,$src2" %}
8972   ins_encode %{
8973     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8974   %}
8975 
8976   ins_pipe(faddF_reg_reg);
8977 %}
8978 
8979 //  Add float double precision
8980 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
8981   match(Set dst (AddD src1 src2));
8982 
8983   size(4);
8984   format %{ "FADDD  $dst,$src1,$src2" %}
8985   ins_encode %{
8986     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
8987   %}
8988 
8989   ins_pipe(faddD_reg_reg);
8990 %}
8991 
8992 //  Sub float single precision
8993 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
8994   match(Set dst (SubF src1 src2));
8995 
8996   size(4);
8997   format %{ "FSUBS  $dst,$src1,$src2" %}
8998   ins_encode %{
8999     __ sub_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9000   %}
9001   ins_pipe(faddF_reg_reg);
9002 %}
9003 
9004 //  Sub float double precision
9005 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
9006   match(Set dst (SubD src1 src2));
9007 
9008   size(4);
9009   format %{ "FSUBD  $dst,$src1,$src2" %}
9010   ins_encode %{
9011     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9012   %}
9013   ins_pipe(faddD_reg_reg);
9014 %}
9015 
9016 //  Mul float single precision
9017 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
9018   match(Set dst (MulF src1 src2));
9019 
9020   size(4);
9021   format %{ "FMULS  $dst,$src1,$src2" %}
9022   ins_encode %{
9023     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9024   %}
9025 
9026   ins_pipe(fmulF_reg_reg);
9027 %}
9028 
9029 //  Mul float double precision
9030 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
9031   match(Set dst (MulD src1 src2));
9032 
9033   size(4);
9034   format %{ "FMULD  $dst,$src1,$src2" %}
9035   ins_encode %{
9036     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9037   %}
9038 
9039   ins_pipe(fmulD_reg_reg);
9040 %}
9041 
9042 //  Div float single precision
9043 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
9044   match(Set dst (DivF src1 src2));
9045 
9046   size(4);
9047   format %{ "FDIVS  $dst,$src1,$src2" %}
9048   ins_encode %{
9049     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9050   %}
9051 
9052   ins_pipe(fdivF_reg_reg);
9053 %}
9054 
9055 //  Div float double precision
9056 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
9057   match(Set dst (DivD src1 src2));
9058 
9059   size(4);
9060   format %{ "FDIVD  $dst,$src1,$src2" %}
9061   ins_encode %{
9062     __ div_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9063   %}
9064 
9065   ins_pipe(fdivD_reg_reg);
9066 %}
9067 
9068 //  Absolute float double precision
9069 instruct absD_reg(regD dst, regD src) %{
9070   match(Set dst (AbsD src));
9071 
9072   size(4);
9073   format %{ "FABSd  $dst,$src" %}
9074   ins_encode %{
9075     __ abs_double($dst$$FloatRegister, $src$$FloatRegister);
9076   %}
9077   ins_pipe(faddD_reg);
9078 %}
9079 
9080 //  Absolute float single precision
9081 instruct absF_reg(regF dst, regF src) %{
9082   match(Set dst (AbsF src));
9083   format %{ "FABSs  $dst,$src" %}
9084   ins_encode %{
9085     __ abs_float($dst$$FloatRegister, $src$$FloatRegister);
9086   %}
9087   ins_pipe(faddF_reg);
9088 %}
9089 
9090 instruct negF_reg(regF dst, regF src) %{
9091   match(Set dst (NegF src));
9092 
9093   size(4);
9094   format %{ "FNEGs  $dst,$src" %}
9095   ins_encode %{
9096     __ neg_float($dst$$FloatRegister, $src$$FloatRegister);
9097   %}
9098   ins_pipe(faddF_reg);
9099 %}
9100 
9101 instruct negD_reg(regD dst, regD src) %{
9102   match(Set dst (NegD src));
9103 
9104   format %{ "FNEGd  $dst,$src" %}
9105   ins_encode %{
9106     __ neg_double($dst$$FloatRegister, $src$$FloatRegister);
9107   %}
9108   ins_pipe(faddD_reg);
9109 %}
9110 
9111 //  Sqrt float double precision
9112 instruct sqrtF_reg_reg(regF dst, regF src) %{
9113   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
9114 
9115   size(4);
9116   format %{ "FSQRTS $dst,$src" %}
9117   ins_encode %{
9118     __ sqrt_float($dst$$FloatRegister, $src$$FloatRegister);
9119   %}
9120   ins_pipe(fdivF_reg_reg);
9121 %}
9122 
9123 //  Sqrt float double precision
9124 instruct sqrtD_reg_reg(regD dst, regD src) %{
9125   match(Set dst (SqrtD src));
9126 
9127   size(4);
9128   format %{ "FSQRTD $dst,$src" %}
9129   ins_encode %{
9130     __ sqrt_double($dst$$FloatRegister, $src$$FloatRegister);
9131   %}
9132   ins_pipe(fdivD_reg_reg);
9133 %}
9134 
9135 //----------Logical Instructions-----------------------------------------------
9136 // And Instructions
9137 // Register And
9138 instruct andI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
9139   match(Set dst (AndI src1 src2));
9140 
9141   size(4);
9142   format %{ "and_32 $dst,$src1,$src2" %}
9143   ins_encode %{
9144     __ and_32($dst$$Register, $src1$$Register, $src2$$Register);
9145   %}
9146   ins_pipe(ialu_reg_reg);
9147 %}
9148 
9149 #ifndef AARCH64
9150 instruct andshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
9151   match(Set dst (AndI src1 (LShiftI src2 src3)));
9152 
9153   size(4);
9154   format %{ "AND    $dst,$src1,$src2<<$src3" %}
9155   ins_encode %{
9156     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
9157   %}
9158   ins_pipe(ialu_reg_reg);
9159 %}
9160 #endif
9161 
9162 instruct andshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
9163   match(Set dst (AndI src1 (LShiftI src2 src3)));
9164 
9165   size(4);
9166   format %{ "and_32 $dst,$src1,$src2<<$src3" %}
9167   ins_encode %{
9168     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
9169   %}
9170   ins_pipe(ialu_reg_reg);
9171 %}
9172 
9173 #ifndef AARCH64
9174 instruct andsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
9175   match(Set dst (AndI src1 (RShiftI src2 src3)));
9176 
9177   size(4);
9178   format %{ "AND    $dst,$src1,$src2>>$src3" %}
9179   ins_encode %{
9180     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
9181   %}
9182   ins_pipe(ialu_reg_reg);
9183 %}
9184 #endif
9185 
9186 instruct andsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
9187   match(Set dst (AndI src1 (RShiftI src2 src3)));
9188 
9189   size(4);
9190   format %{ "and_32 $dst,$src1,$src2>>$src3" %}
9191   ins_encode %{
9192     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
9193   %}
9194   ins_pipe(ialu_reg_reg);
9195 %}
9196 
9197 #ifndef AARCH64
9198 instruct andshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
9199   match(Set dst (AndI src1 (URShiftI src2 src3)));
9200 
9201   size(4);
9202   format %{ "AND    $dst,$src1,$src2>>>$src3" %}
9203   ins_encode %{
9204     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
9205   %}
9206   ins_pipe(ialu_reg_reg);
9207 %}
9208 #endif
9209 
9210 instruct andshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
9211   match(Set dst (AndI src1 (URShiftI src2 src3)));
9212 
9213   size(4);
9214   format %{ "and_32 $dst,$src1,$src2>>>$src3" %}
9215   ins_encode %{
9216     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
9217   %}
9218   ins_pipe(ialu_reg_reg);
9219 %}
9220 
9221 // Immediate And
9222 instruct andI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
9223   match(Set dst (AndI src1 src2));
9224 
9225   size(4);
9226   format %{ "and_32 $dst,$src1,$src2\t! int" %}
9227   ins_encode %{
9228     __ and_32($dst$$Register, $src1$$Register, $src2$$constant);
9229   %}
9230   ins_pipe(ialu_reg_imm);
9231 %}
9232 
9233 #ifndef AARCH64
9234 instruct andI_reg_limmn(iRegI dst, iRegI src1, limmIn src2) %{
9235   match(Set dst (AndI src1 src2));
9236 
9237   size(4);
9238   format %{ "bic    $dst,$src1,~$src2\t! int" %}
9239   ins_encode %{
9240     __ bic($dst$$Register, $src1$$Register, ~$src2$$constant);
9241   %}
9242   ins_pipe(ialu_reg_imm);
9243 %}
9244 #endif
9245 
9246 // Register And Long
9247 instruct andL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
9248   match(Set dst (AndL src1 src2));
9249 
9250   ins_cost(DEFAULT_COST);
9251 #ifdef AARCH64
9252   size(4);
9253   format %{ "AND    $dst,$src1,$src2\t! long" %}
9254   ins_encode %{
9255     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9256   %}
9257 #else
9258   size(8);
9259   format %{ "AND    $dst,$src1,$src2\t! long" %}
9260   ins_encode %{
9261     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9262     __ andr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
9263   %}
9264 #endif
9265   ins_pipe(ialu_reg_reg);
9266 %}
9267 
9268 #ifdef AARCH64
9269 // Immediate And
9270 instruct andL_reg_limm(iRegL dst, iRegL src1, limmL src2) %{
9271   match(Set dst (AndL src1 src2));
9272 
9273   size(4);
9274   format %{ "AND    $dst,$src1,$src2\t! long" %}
9275   ins_encode %{
9276     __ andr($dst$$Register, $src1$$Register, (uintx)$src2$$constant);
9277   %}
9278   ins_pipe(ialu_reg_imm);
9279 %}
9280 #else
9281 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
9282 // (hi($con$$constant), lo($con$$constant)) becomes
9283 instruct andL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
9284   match(Set dst (AndL src1 con));
9285   ins_cost(DEFAULT_COST);
9286   size(8);
9287   format %{ "AND    $dst,$src1,$con\t! long" %}
9288   ins_encode %{
9289     __ andr($dst$$Register, $src1$$Register, $con$$constant);
9290     __ andr($dst$$Register->successor(), $src1$$Register->successor(), 0);
9291   %}
9292   ins_pipe(ialu_reg_imm);
9293 %}
9294 #endif
9295 
9296 // Or Instructions
9297 // Register Or
9298 instruct orI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
9299   match(Set dst (OrI src1 src2));
9300 
9301   size(4);
9302   format %{ "orr_32 $dst,$src1,$src2\t! int" %}
9303   ins_encode %{
9304     __ orr_32($dst$$Register, $src1$$Register, $src2$$Register);
9305   %}
9306   ins_pipe(ialu_reg_reg);
9307 %}
9308 
9309 #ifndef AARCH64
9310 instruct orshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
9311   match(Set dst (OrI src1 (LShiftI src2 src3)));
9312 
9313   size(4);
9314   format %{ "OR    $dst,$src1,$src2<<$src3" %}
9315   ins_encode %{
9316     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
9317   %}
9318   ins_pipe(ialu_reg_reg);
9319 %}
9320 #endif
9321 
9322 instruct orshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
9323   match(Set dst (OrI src1 (LShiftI src2 src3)));
9324 
9325   size(4);
9326   format %{ "orr_32 $dst,$src1,$src2<<$src3" %}
9327   ins_encode %{
9328     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
9329   %}
9330   ins_pipe(ialu_reg_reg);
9331 %}
9332 
9333 #ifndef AARCH64
9334 instruct orsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
9335   match(Set dst (OrI src1 (RShiftI src2 src3)));
9336 
9337   size(4);
9338   format %{ "OR    $dst,$src1,$src2>>$src3" %}
9339   ins_encode %{
9340     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
9341   %}
9342   ins_pipe(ialu_reg_reg);
9343 %}
9344 #endif
9345 
9346 instruct orsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
9347   match(Set dst (OrI src1 (RShiftI src2 src3)));
9348 
9349   size(4);
9350   format %{ "orr_32 $dst,$src1,$src2>>$src3" %}
9351   ins_encode %{
9352     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
9353   %}
9354   ins_pipe(ialu_reg_reg);
9355 %}
9356 
9357 #ifndef AARCH64
9358 instruct orshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
9359   match(Set dst (OrI src1 (URShiftI src2 src3)));
9360 
9361   size(4);
9362   format %{ "OR    $dst,$src1,$src2>>>$src3" %}
9363   ins_encode %{
9364     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
9365   %}
9366   ins_pipe(ialu_reg_reg);
9367 %}
9368 #endif
9369 
9370 instruct orshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
9371   match(Set dst (OrI src1 (URShiftI src2 src3)));
9372 
9373   size(4);
9374   format %{ "orr_32 $dst,$src1,$src2>>>$src3" %}
9375   ins_encode %{
9376     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
9377   %}
9378   ins_pipe(ialu_reg_reg);
9379 %}
9380 
9381 // Immediate Or
9382 instruct orI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
9383   match(Set dst (OrI src1 src2));
9384 
9385   size(4);
9386   format %{ "orr_32  $dst,$src1,$src2" %}
9387   ins_encode %{
9388     __ orr_32($dst$$Register, $src1$$Register, $src2$$constant);
9389   %}
9390   ins_pipe(ialu_reg_imm);
9391 %}
9392 // TODO: orn_32 with limmIn
9393 
9394 // Register Or Long
9395 instruct orL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
9396   match(Set dst (OrL src1 src2));
9397 
9398   ins_cost(DEFAULT_COST);
9399 #ifdef AARCH64
9400   size(4);
9401   format %{ "OR     $dst,$src1,$src2\t! long" %}
9402   ins_encode %{
9403     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
9404   %}
9405 #else
9406   size(8);
9407   format %{ "OR     $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
9408             "OR     $dst.hi,$src1.hi,$src2.hi" %}
9409   ins_encode %{
9410     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
9411     __ orr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
9412   %}
9413 #endif
9414   ins_pipe(ialu_reg_reg);
9415 %}
9416 
9417 #ifdef AARCH64
9418 instruct orL_reg_limm(iRegL dst, iRegL src1, limmL src2) %{
9419   match(Set dst (OrL src1 src2));
9420 
9421   size(4);
9422   format %{ "ORR    $dst,$src1,$src2\t! long" %}
9423   ins_encode %{
9424     __ orr($dst$$Register, $src1$$Register, (uintx)$src2$$constant);
9425   %}
9426   ins_pipe(ialu_reg_imm);
9427 %}
9428 #else
9429 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
9430 // (hi($con$$constant), lo($con$$constant)) becomes
9431 instruct orL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
9432   match(Set dst (OrL src1 con));
9433   ins_cost(DEFAULT_COST);
9434   size(8);
9435   format %{ "OR     $dst.lo,$src1.lo,$con\t! long\n\t"
9436             "OR     $dst.hi,$src1.hi,$con" %}
9437   ins_encode %{
9438     __ orr($dst$$Register, $src1$$Register, $con$$constant);
9439     __ orr($dst$$Register->successor(), $src1$$Register->successor(), 0);
9440   %}
9441   ins_pipe(ialu_reg_imm);
9442 %}
9443 #endif
9444 
9445 #ifdef TODO
9446 // Use SPRegP to match Rthread (TLS register) without spilling.
9447 // Use store_ptr_RegP to match Rthread (TLS register) without spilling.
9448 // Use sp_ptr_RegP to match Rthread (TLS register) without spilling.
9449 instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
9450   match(Set dst (OrI src1 (CastP2X src2)));
9451   size(4);
9452   format %{ "OR     $dst,$src1,$src2" %}
9453   ins_encode %{
9454     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
9455   %}
9456   ins_pipe(ialu_reg_reg);
9457 %}
9458 #endif
9459 
9460 // Xor Instructions
9461 // Register Xor
9462 instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
9463   match(Set dst (XorI src1 src2));
9464 
9465   size(4);
9466   format %{ "eor_32 $dst,$src1,$src2" %}
9467   ins_encode %{
9468     __ eor_32($dst$$Register, $src1$$Register, $src2$$Register);
9469   %}
9470   ins_pipe(ialu_reg_reg);
9471 %}
9472 
9473 #ifndef AARCH64
9474 instruct xorshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
9475   match(Set dst (XorI src1 (LShiftI src2 src3)));
9476 
9477   size(4);
9478   format %{ "XOR    $dst,$src1,$src2<<$src3" %}
9479   ins_encode %{
9480     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
9481   %}
9482   ins_pipe(ialu_reg_reg);
9483 %}
9484 #endif
9485 
9486 instruct xorshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
9487   match(Set dst (XorI src1 (LShiftI src2 src3)));
9488 
9489   size(4);
9490   format %{ "eor_32 $dst,$src1,$src2<<$src3" %}
9491   ins_encode %{
9492     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
9493   %}
9494   ins_pipe(ialu_reg_reg);
9495 %}
9496 
9497 #ifndef AARCH64
9498 instruct xorsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
9499   match(Set dst (XorI src1 (RShiftI src2 src3)));
9500 
9501   size(4);
9502   format %{ "XOR    $dst,$src1,$src2>>$src3" %}
9503   ins_encode %{
9504     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
9505   %}
9506   ins_pipe(ialu_reg_reg);
9507 %}
9508 #endif
9509 
9510 instruct xorsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
9511   match(Set dst (XorI src1 (RShiftI src2 src3)));
9512 
9513   size(4);
9514   format %{ "eor_32 $dst,$src1,$src2>>$src3" %}
9515   ins_encode %{
9516     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
9517   %}
9518   ins_pipe(ialu_reg_reg);
9519 %}
9520 
9521 #ifndef AARCH64
9522 instruct xorshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
9523   match(Set dst (XorI src1 (URShiftI src2 src3)));
9524 
9525   size(4);
9526   format %{ "XOR    $dst,$src1,$src2>>>$src3" %}
9527   ins_encode %{
9528     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
9529   %}
9530   ins_pipe(ialu_reg_reg);
9531 %}
9532 #endif
9533 
9534 instruct xorshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
9535   match(Set dst (XorI src1 (URShiftI src2 src3)));
9536 
9537   size(4);
9538   format %{ "eor_32 $dst,$src1,$src2>>>$src3" %}
9539   ins_encode %{
9540     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
9541   %}
9542   ins_pipe(ialu_reg_reg);
9543 %}
9544 
9545 // Immediate Xor
9546 instruct xorI_reg_imm(iRegI dst, iRegI src1, limmI src2) %{
9547   match(Set dst (XorI src1 src2));
9548 
9549   size(4);
9550   format %{ "eor_32 $dst,$src1,$src2" %}
9551   ins_encode %{
9552     __ eor_32($dst$$Register, $src1$$Register, $src2$$constant);
9553   %}
9554   ins_pipe(ialu_reg_imm);
9555 %}
9556 
9557 // Register Xor Long
9558 instruct xorL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
9559   match(Set dst (XorL src1 src2));
9560   ins_cost(DEFAULT_COST);
9561 #ifdef AARCH64
9562   size(4);
9563   format %{ "XOR     $dst,$src1,$src2\t! long" %}
9564   ins_encode %{
9565     __ eor($dst$$Register, $src1$$Register, $src2$$Register);
9566   %}
9567 #else
9568   size(8);
9569   format %{ "XOR     $dst.hi,$src1.hi,$src2.hi\t! long\n\t"
9570             "XOR     $dst.lo,$src1.lo,$src2.lo\t! long" %}
9571   ins_encode %{
9572     __ eor($dst$$Register, $src1$$Register, $src2$$Register);
9573     __ eor($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
9574   %}
9575 #endif
9576   ins_pipe(ialu_reg_reg);
9577 %}
9578 
9579 #ifdef AARCH64
9580 instruct xorL_reg_limmL(iRegL dst, iRegL src1, limmL con) %{
9581   match(Set dst (XorL src1 con));
9582   ins_cost(DEFAULT_COST);
9583   size(4);
9584   format %{ "EOR     $dst,$src1,$con\t! long" %}
9585   ins_encode %{
9586     __ eor($dst$$Register, $src1$$Register, (uintx)$con$$constant);
9587   %}
9588   ins_pipe(ialu_reg_imm);
9589 %}
9590 #else
9591 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
9592 // (hi($con$$constant), lo($con$$constant)) becomes
9593 instruct xorL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
9594   match(Set dst (XorL src1 con));
9595   ins_cost(DEFAULT_COST);
9596   size(8);
9597   format %{ "XOR     $dst.hi,$src1.hi,$con\t! long\n\t"
9598             "XOR     $dst.lo,$src1.lo,0\t! long" %}
9599   ins_encode %{
9600     __ eor($dst$$Register, $src1$$Register, $con$$constant);
9601     __ eor($dst$$Register->successor(), $src1$$Register->successor(), 0);
9602   %}
9603   ins_pipe(ialu_reg_imm);
9604 %}
9605 #endif // AARCH64
9606 
9607 //----------Convert to Boolean-------------------------------------------------
9608 instruct convI2B( iRegI dst, iRegI src, flagsReg ccr ) %{
9609   match(Set dst (Conv2B src));
9610   effect(KILL ccr);
9611 #ifdef AARCH64
9612   size(8);
9613   ins_cost(DEFAULT_COST*2);
9614   format %{ "cmp_32 $src,ZR\n\t"
9615             "cset_w $dst, ne" %}
9616   ins_encode %{
9617     __ cmp_32($src$$Register, ZR);
9618     __ cset_w($dst$$Register, ne);
9619   %}
9620 #else
9621   size(12);
9622   ins_cost(DEFAULT_COST*2);
9623   format %{ "TST    $src,$src \n\t"
9624             "MOV    $dst, 0   \n\t"
9625             "MOV.ne $dst, 1" %}
9626   ins_encode %{ // FIXME: can do better?
9627     __ tst($src$$Register, $src$$Register);
9628     __ mov($dst$$Register, 0);
9629     __ mov($dst$$Register, 1, ne);
9630   %}
9631 #endif
9632   ins_pipe(ialu_reg_ialu);
9633 %}
9634 
9635 instruct convP2B( iRegI dst, iRegP src, flagsReg ccr ) %{
9636   match(Set dst (Conv2B src));
9637   effect(KILL ccr);
9638 #ifdef AARCH64
9639   size(8);
9640   ins_cost(DEFAULT_COST*2);
9641   format %{ "CMP    $src,ZR\n\t"
9642             "cset   $dst, ne" %}
9643   ins_encode %{
9644     __ cmp($src$$Register, ZR);
9645     __ cset($dst$$Register, ne);
9646   %}
9647 #else
9648   size(12);
9649   ins_cost(DEFAULT_COST*2);
9650   format %{ "TST    $src,$src \n\t"
9651             "MOV    $dst, 0   \n\t"
9652             "MOV.ne $dst, 1" %}
9653   ins_encode %{
9654     __ tst($src$$Register, $src$$Register);
9655     __ mov($dst$$Register, 0);
9656     __ mov($dst$$Register, 1, ne);
9657   %}
9658 #endif
9659   ins_pipe(ialu_reg_ialu);
9660 %}
9661 
9662 instruct cmpLTMask_reg_reg( iRegI dst, iRegI p, iRegI q, flagsReg ccr ) %{
9663   match(Set dst (CmpLTMask p q));
9664   effect( KILL ccr );
9665 #ifdef AARCH64
9666   size(8);
9667   ins_cost(DEFAULT_COST*2);
9668   format %{ "CMP_w   $p,$q\n\t"
9669             "CSETM_w $dst, lt" %}
9670   ins_encode %{
9671     __ cmp_w($p$$Register, $q$$Register);
9672     __ csetm_w($dst$$Register, lt);
9673   %}
9674 #else
9675   ins_cost(DEFAULT_COST*3);
9676   format %{ "CMP    $p,$q\n\t"
9677             "MOV    $dst, #0\n\t"
9678             "MOV.lt $dst, #-1" %}
9679   ins_encode %{
9680     __ cmp($p$$Register, $q$$Register);
9681     __ mov($dst$$Register, 0);
9682     __ mvn($dst$$Register, 0, lt);
9683   %}
9684 #endif
9685   ins_pipe(ialu_reg_reg_ialu);
9686 %}
9687 
9688 instruct cmpLTMask_reg_imm( iRegI dst, iRegI p, aimmI q, flagsReg ccr ) %{
9689   match(Set dst (CmpLTMask p q));
9690   effect( KILL ccr );
9691 #ifdef AARCH64
9692   size(8);
9693   ins_cost(DEFAULT_COST*2);
9694   format %{ "CMP_w   $p,$q\n\t"
9695             "CSETM_w $dst, lt" %}
9696   ins_encode %{
9697     __ cmp_w($p$$Register, $q$$constant);
9698     __ csetm_w($dst$$Register, lt);
9699   %}
9700 #else
9701   ins_cost(DEFAULT_COST*3);
9702   format %{ "CMP    $p,$q\n\t"
9703             "MOV    $dst, #0\n\t"
9704             "MOV.lt $dst, #-1" %}
9705   ins_encode %{
9706     __ cmp($p$$Register, $q$$constant);
9707     __ mov($dst$$Register, 0);
9708     __ mvn($dst$$Register, 0, lt);
9709   %}
9710 #endif
9711   ins_pipe(ialu_reg_reg_ialu);
9712 %}
9713 
9714 #ifdef AARCH64
9715 instruct cadd_cmpLTMask3( iRegI dst, iRegI p, iRegI q, iRegI y, iRegI x, flagsReg ccr ) %{
9716   match(Set dst (AddI (AndI (CmpLTMask p q) y) x));
9717   effect( TEMP dst, KILL ccr );
9718   size(12);
9719   ins_cost(DEFAULT_COST*3);
9720   format %{ "CMP_w  $p,$q\n\t"
9721             "ADD_w  $dst,$y,$x\n\t"
9722             "CSEL_w $dst,$dst,$x,lt" %}
9723   ins_encode %{
9724     __ cmp_w($p$$Register, $q$$Register);
9725     __ add_w($dst$$Register, $y$$Register, $x$$Register);
9726     __ csel_w($dst$$Register, $dst$$Register, $x$$Register, lt);
9727   %}
9728   ins_pipe( cadd_cmpltmask );
9729 %}
9730 #else
9731 instruct cadd_cmpLTMask3( iRegI p, iRegI q, iRegI y, iRegI z, flagsReg ccr ) %{
9732   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
9733   effect( KILL ccr );
9734   ins_cost(DEFAULT_COST*2);
9735   format %{ "CMP    $p,$q\n\t"
9736             "ADD.lt $z,$y,$z" %}
9737   ins_encode %{
9738     __ cmp($p$$Register, $q$$Register);
9739     __ add($z$$Register, $y$$Register, $z$$Register, lt);
9740   %}
9741   ins_pipe( cadd_cmpltmask );
9742 %}
9743 #endif
9744 
9745 #ifdef AARCH64
9746 instruct cadd_cmpLTMask4( iRegI dst, iRegI p, aimmI q, iRegI y, iRegI x, flagsReg ccr ) %{
9747   match(Set dst (AddI (AndI (CmpLTMask p q) y) x));
9748   effect( TEMP dst, KILL ccr );
9749   size(12);
9750   ins_cost(DEFAULT_COST*3);
9751   format %{ "CMP_w  $p,$q\n\t"
9752             "ADD_w  $dst,$y,$x\n\t"
9753             "CSEL_w $dst,$dst,$x,lt" %}
9754   ins_encode %{
9755     __ cmp_w($p$$Register, $q$$constant);
9756     __ add_w($dst$$Register, $y$$Register, $x$$Register);
9757     __ csel_w($dst$$Register, $dst$$Register, $x$$Register, lt);
9758   %}
9759   ins_pipe( cadd_cmpltmask );
9760 %}
9761 #else
9762 // FIXME: remove unused "dst"
9763 instruct cadd_cmpLTMask4( iRegI dst, iRegI p, aimmI q, iRegI y, iRegI z, flagsReg ccr ) %{
9764   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
9765   effect( KILL ccr );
9766   ins_cost(DEFAULT_COST*2);
9767   format %{ "CMP    $p,$q\n\t"
9768             "ADD.lt $z,$y,$z" %}
9769   ins_encode %{
9770     __ cmp($p$$Register, $q$$constant);
9771     __ add($z$$Register, $y$$Register, $z$$Register, lt);
9772   %}
9773   ins_pipe( cadd_cmpltmask );
9774 %}
9775 #endif // !AARCH64
9776 
9777 #ifdef AARCH64
9778 instruct cadd_cmpLTMask( iRegI dst, iRegI p, iRegI q, iRegI y, flagsReg ccr ) %{
9779   match(Set dst (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
9780   effect( TEMP dst, KILL ccr );
9781   size(12);
9782   ins_cost(DEFAULT_COST*3);
9783   format %{ "SUBS_w $p,$p,$q\n\t"
9784             "ADD_w  $dst,$y,$p\n\t"
9785             "CSEL_w $dst,$dst,$p,lt" %}
9786   ins_encode %{
9787     __ subs_w($p$$Register, $p$$Register, $q$$Register);
9788     __ add_w($dst$$Register, $y$$Register, $p$$Register);
9789     __ csel_w($dst$$Register, $dst$$Register, $p$$Register, lt);
9790   %}
9791   ins_pipe( cadd_cmpltmask ); // FIXME
9792 %}
9793 #else
9794 instruct cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, flagsReg ccr ) %{
9795   match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
9796   effect( KILL ccr );
9797   ins_cost(DEFAULT_COST*2);
9798   format %{ "SUBS   $p,$p,$q\n\t"
9799             "ADD.lt $p,$y,$p" %}
9800   ins_encode %{
9801     __ subs($p$$Register, $p$$Register, $q$$Register);
9802     __ add($p$$Register, $y$$Register, $p$$Register, lt);
9803   %}
9804   ins_pipe( cadd_cmpltmask );
9805 %}
9806 #endif
9807 
9808 //----------Arithmetic Conversion Instructions---------------------------------
9809 // The conversions operations are all Alpha sorted.  Please keep it that way!
9810 
9811 instruct convD2F_reg(regF dst, regD src) %{
9812   match(Set dst (ConvD2F src));
9813   size(4);
9814   format %{ "FCVTSD  $dst,$src" %}
9815   ins_encode %{
9816     __ convert_d2f($dst$$FloatRegister, $src$$FloatRegister);
9817   %}
9818   ins_pipe(fcvtD2F);
9819 %}
9820 
9821 // Convert a double to an int in a float register.
9822 // If the double is a NAN, stuff a zero in instead.
9823 
9824 #ifdef AARCH64
9825 instruct convD2I_reg_reg(iRegI dst, regD src) %{
9826   match(Set dst (ConvD2I src));
9827   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
9828   format %{ "FCVTZS_wd $dst, $src" %}
9829   ins_encode %{
9830     __ fcvtzs_wd($dst$$Register, $src$$FloatRegister);
9831   %}
9832   ins_pipe(fcvtD2I);
9833 %}
9834 
9835 instruct convD2L_reg_reg(iRegL dst, regD src) %{
9836   match(Set dst (ConvD2L src));
9837   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
9838   format %{ "FCVTZS_xd $dst, $src" %}
9839   ins_encode %{
9840     __ fcvtzs_xd($dst$$Register, $src$$FloatRegister);
9841   %}
9842   ins_pipe(fcvtD2L);
9843 %}
9844 #else
9845 instruct convD2I_reg_reg(iRegI dst, regD src, regF tmp) %{
9846   match(Set dst (ConvD2I src));
9847   effect( TEMP tmp );
9848   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
9849   format %{ "FTOSIZD  $tmp,$src\n\t"
9850             "FMRS     $dst, $tmp" %}
9851   ins_encode %{
9852     __ ftosizd($tmp$$FloatRegister, $src$$FloatRegister);
9853     __ fmrs($dst$$Register, $tmp$$FloatRegister);
9854   %}
9855   ins_pipe(fcvtD2I);
9856 %}
9857 #endif
9858 
9859 // Convert a double to a long in a double register.
9860 // If the double is a NAN, stuff a zero in instead.
9861 
9862 #ifndef AARCH64
9863 // Double to Long conversion
9864 instruct convD2L_reg(R0R1RegL dst, regD src) %{
9865   match(Set dst (ConvD2L src));
9866   effect(CALL);
9867   ins_cost(MEMORY_REF_COST); // FIXME
9868   format %{ "convD2L    $dst,$src\t ! call to SharedRuntime::d2l" %}
9869   ins_encode %{
9870 #ifndef __ABI_HARD__
9871     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
9872 #else
9873     if ($src$$FloatRegister != D0) {
9874       __ mov_double(D0, $src$$FloatRegister);
9875     }
9876 #endif
9877     address target = CAST_FROM_FN_PTR(address, SharedRuntime::d2l);
9878     __ call(target, relocInfo::runtime_call_type);
9879   %}
9880   ins_pipe(fcvtD2L);
9881 %}
9882 #endif
9883 
9884 instruct convF2D_reg(regD dst, regF src) %{
9885   match(Set dst (ConvF2D src));
9886   size(4);
9887   format %{ "FCVTDS  $dst,$src" %}
9888   ins_encode %{
9889     __ convert_f2d($dst$$FloatRegister, $src$$FloatRegister);
9890   %}
9891   ins_pipe(fcvtF2D);
9892 %}
9893 
9894 #ifdef AARCH64
9895 instruct convF2I_reg_reg(iRegI dst, regF src) %{
9896   match(Set dst (ConvF2I src));
9897   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
9898   size(4);
9899   format %{ "FCVTZS_ws $dst, $src" %}
9900   ins_encode %{
9901     __ fcvtzs_ws($dst$$Register, $src$$FloatRegister);
9902   %}
9903   ins_pipe(fcvtF2I);
9904 %}
9905 
9906 instruct convF2L_reg_reg(iRegL dst, regF src) %{
9907   match(Set dst (ConvF2L src));
9908   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
9909   size(4);
9910   format %{ "FCVTZS_xs $dst, $src" %}
9911   ins_encode %{
9912     __ fcvtzs_xs($dst$$Register, $src$$FloatRegister);
9913   %}
9914   ins_pipe(fcvtF2L);
9915 %}
9916 #else
9917 instruct convF2I_reg_reg(iRegI dst, regF src, regF tmp) %{
9918   match(Set dst (ConvF2I src));
9919   effect( TEMP tmp );
9920   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
9921   size(8);
9922   format %{ "FTOSIZS  $tmp,$src\n\t"
9923             "FMRS     $dst, $tmp" %}
9924   ins_encode %{
9925     __ ftosizs($tmp$$FloatRegister, $src$$FloatRegister);
9926     __ fmrs($dst$$Register, $tmp$$FloatRegister);
9927   %}
9928   ins_pipe(fcvtF2I);
9929 %}
9930 
9931 // Float to Long conversion
9932 instruct convF2L_reg(R0R1RegL dst, regF src, R0RegI arg1) %{
9933   match(Set dst (ConvF2L src));
9934   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
9935   effect(CALL);
9936   format %{ "convF2L  $dst,$src\t! call to SharedRuntime::f2l" %}
9937   ins_encode %{
9938 #ifndef __ABI_HARD__
9939     __ fmrs($arg1$$Register, $src$$FloatRegister);
9940 #else
9941     if($src$$FloatRegister != S0) {
9942       __ mov_float(S0, $src$$FloatRegister);
9943     }
9944 #endif
9945     address target = CAST_FROM_FN_PTR(address, SharedRuntime::f2l);
9946     __ call(target, relocInfo::runtime_call_type);
9947   %}
9948   ins_pipe(fcvtF2L);
9949 %}
9950 #endif
9951 
9952 #ifdef AARCH64
9953 instruct convI2D_reg_reg(iRegI src, regD dst) %{
9954   match(Set dst (ConvI2D src));
9955   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
9956   size(4);
9957   format %{ "SCVTF_dw $dst,$src" %}
9958   ins_encode %{
9959       __ scvtf_dw($dst$$FloatRegister, $src$$Register);
9960   %}
9961   ins_pipe(fcvtI2D);
9962 %}
9963 #else
9964 instruct convI2D_reg_reg(iRegI src, regD_low dst) %{
9965   match(Set dst (ConvI2D src));
9966   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
9967   size(8);
9968   format %{ "FMSR     $dst,$src \n\t"
9969             "FSITOD   $dst $dst"%}
9970   ins_encode %{
9971       __ fmsr($dst$$FloatRegister, $src$$Register);
9972       __ fsitod($dst$$FloatRegister, $dst$$FloatRegister);
9973   %}
9974   ins_pipe(fcvtI2D);
9975 %}
9976 #endif
9977 
9978 instruct convI2F_reg_reg( regF dst, iRegI src ) %{
9979   match(Set dst (ConvI2F src));
9980   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
9981 #ifdef AARCH64
9982   size(4);
9983   format %{ "SCVTF_sw $dst,$src" %}
9984   ins_encode %{
9985       __ scvtf_sw($dst$$FloatRegister, $src$$Register);
9986   %}
9987 #else
9988   size(8);
9989   format %{ "FMSR     $dst,$src \n\t"
9990             "FSITOS   $dst, $dst"%}
9991   ins_encode %{
9992       __ fmsr($dst$$FloatRegister, $src$$Register);
9993       __ fsitos($dst$$FloatRegister, $dst$$FloatRegister);
9994   %}
9995 #endif
9996   ins_pipe(fcvtI2F);
9997 %}
9998 
9999 instruct convI2L_reg(iRegL dst, iRegI src) %{
10000   match(Set dst (ConvI2L src));
10001 #ifdef AARCH64
10002   size(4);
10003   format %{ "SXTW   $dst,$src\t! int->long" %}
10004   ins_encode %{
10005     __ sxtw($dst$$Register, $src$$Register);
10006   %}
10007 #else
10008   size(8);
10009   format %{ "MOV    $dst.lo, $src \n\t"
10010             "ASR    $dst.hi,$src,31\t! int->long" %}
10011   ins_encode %{
10012     __ mov($dst$$Register, $src$$Register);
10013     __ mov($dst$$Register->successor(), AsmOperand($src$$Register, asr, 31));
10014   %}
10015 #endif
10016   ins_pipe(ialu_reg_reg);
10017 %}
10018 
10019 // Zero-extend convert int to long
10020 instruct convI2L_reg_zex(iRegL dst, iRegI src, immL_32bits mask ) %{
10021   match(Set dst (AndL (ConvI2L src) mask) );
10022 #ifdef AARCH64
10023   size(4);
10024   format %{ "mov_w  $dst,$src\t! zero-extend int to long"  %}
10025   ins_encode %{
10026     __ mov_w($dst$$Register, $src$$Register);
10027   %}
10028 #else
10029   size(8);
10030   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend int to long\n\t"
10031             "MOV    $dst.hi, 0"%}
10032   ins_encode %{
10033     __ mov($dst$$Register, $src$$Register);
10034     __ mov($dst$$Register->successor(), 0);
10035   %}
10036 #endif
10037   ins_pipe(ialu_reg_reg);
10038 %}
10039 
10040 // Zero-extend long
10041 instruct zerox_long(iRegL dst, iRegL src, immL_32bits mask ) %{
10042   match(Set dst (AndL src mask) );
10043 #ifdef AARCH64
10044   size(4);
10045   format %{ "mov_w  $dst,$src\t! zero-extend long"  %}
10046   ins_encode %{
10047     __ mov_w($dst$$Register, $src$$Register);
10048   %}
10049 #else
10050   size(8);
10051   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend long\n\t"
10052             "MOV    $dst.hi, 0"%}
10053   ins_encode %{
10054     __ mov($dst$$Register, $src$$Register);
10055     __ mov($dst$$Register->successor(), 0);
10056   %}
10057 #endif
10058   ins_pipe(ialu_reg_reg);
10059 %}
10060 
10061 instruct MoveF2I_reg_reg(iRegI dst, regF src) %{
10062   match(Set dst (MoveF2I src));
10063   effect(DEF dst, USE src);
10064   ins_cost(MEMORY_REF_COST); // FIXME
10065 
10066   size(4);
10067   format %{ "FMRS   $dst,$src\t! MoveF2I" %}
10068   ins_encode %{
10069     __ fmrs($dst$$Register, $src$$FloatRegister);
10070   %}
10071   ins_pipe(iload_mem); // FIXME
10072 %}
10073 
10074 instruct MoveI2F_reg_reg(regF dst, iRegI src) %{
10075   match(Set dst (MoveI2F src));
10076   ins_cost(MEMORY_REF_COST); // FIXME
10077 
10078   size(4);
10079   format %{ "FMSR   $dst,$src\t! MoveI2F" %}
10080   ins_encode %{
10081     __ fmsr($dst$$FloatRegister, $src$$Register);
10082   %}
10083   ins_pipe(iload_mem); // FIXME
10084 %}
10085 
10086 instruct MoveD2L_reg_reg(iRegL dst, regD src) %{
10087   match(Set dst (MoveD2L src));
10088   effect(DEF dst, USE src);
10089   ins_cost(MEMORY_REF_COST); // FIXME
10090 
10091   size(4);
10092 #ifdef AARCH64
10093   format %{ "FMOV_xd  $dst,$src\t! MoveD2L" %}
10094   ins_encode %{
10095     __ fmov_xd($dst$$Register, $src$$FloatRegister);
10096   %}
10097 #else
10098   format %{ "FMRRD    $dst,$src\t! MoveD2L" %}
10099   ins_encode %{
10100     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
10101   %}
10102 #endif
10103   ins_pipe(iload_mem); // FIXME
10104 %}
10105 
10106 instruct MoveL2D_reg_reg(regD dst, iRegL src) %{
10107   match(Set dst (MoveL2D src));
10108   effect(DEF dst, USE src);
10109   ins_cost(MEMORY_REF_COST); // FIXME
10110 
10111   size(4);
10112 #ifdef AARCH64
10113   format %{ "FMOV_dx $dst,$src\t! MoveL2D" %}
10114   ins_encode %{
10115     __ fmov_dx($dst$$FloatRegister, $src$$Register);
10116   %}
10117 #else
10118   format %{ "FMDRR   $dst,$src\t! MoveL2D" %}
10119   ins_encode %{
10120     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
10121   %}
10122 #endif
10123   ins_pipe(ialu_reg_reg); // FIXME
10124 %}
10125 
10126 //-----------
10127 // Long to Double conversion
10128 
10129 #ifdef AARCH64
10130 instruct convL2D(regD dst, iRegL src) %{
10131   match(Set dst (ConvL2D src));
10132   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
10133   size(4);
10134   format %{ "SCVTF_dx $dst, $src" %}
10135   ins_encode %{
10136     __ scvtf_dx($dst$$FloatRegister, $src$$Register);
10137   %}
10138   ins_pipe(fcvtL2D);
10139 %}
10140 
10141 instruct convL2F(regF dst, iRegL src) %{
10142   match(Set dst (ConvL2F src));
10143   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
10144   size(4);
10145   format %{ "SCVTF_sx $dst, $src" %}
10146   ins_encode %{
10147     __ scvtf_sx($dst$$FloatRegister, $src$$Register);
10148   %}
10149   ins_pipe(fcvtL2F);
10150 %}
10151 #else
10152 // Magic constant, 0x43300000
10153 instruct loadConI_x43300000(iRegI dst) %{
10154   effect(DEF dst);
10155   size(8);
10156   format %{ "MOV_SLOW  $dst,0x43300000\t! 2^52" %}
10157   ins_encode %{
10158     __ mov_slow($dst$$Register, 0x43300000);
10159   %}
10160   ins_pipe(ialu_none);
10161 %}
10162 
10163 // Magic constant, 0x41f00000
10164 instruct loadConI_x41f00000(iRegI dst) %{
10165   effect(DEF dst);
10166   size(8);
10167   format %{ "MOV_SLOW  $dst, 0x41f00000\t! 2^32" %}
10168   ins_encode %{
10169     __ mov_slow($dst$$Register, 0x41f00000);
10170   %}
10171   ins_pipe(ialu_none);
10172 %}
10173 
10174 instruct loadConI_x0(iRegI dst) %{
10175   effect(DEF dst);
10176   size(4);
10177   format %{ "MOV  $dst, 0x0\t! 0" %}
10178   ins_encode %{
10179     __ mov($dst$$Register, 0);
10180   %}
10181   ins_pipe(ialu_none);
10182 %}
10183 
10184 // Construct a double from two float halves
10185 instruct regDHi_regDLo_to_regD(regD_low dst, regD_low src1, regD_low src2) %{
10186   effect(DEF dst, USE src1, USE src2);
10187   size(8);
10188   format %{ "FCPYS  $dst.hi,$src1.hi\n\t"
10189             "FCPYS  $dst.lo,$src2.lo" %}
10190   ins_encode %{
10191     __ fcpys($dst$$FloatRegister->successor(), $src1$$FloatRegister->successor());
10192     __ fcpys($dst$$FloatRegister, $src2$$FloatRegister);
10193   %}
10194   ins_pipe(faddD_reg_reg);
10195 %}
10196 
10197 #ifndef AARCH64
10198 // Convert integer in high half of a double register (in the lower half of
10199 // the double register file) to double
10200 instruct convI2D_regDHi_regD(regD dst, regD_low src) %{
10201   effect(DEF dst, USE src);
10202   size(4);
10203   format %{ "FSITOD  $dst,$src" %}
10204   ins_encode %{
10205     __ fsitod($dst$$FloatRegister, $src$$FloatRegister->successor());
10206   %}
10207   ins_pipe(fcvtLHi2D);
10208 %}
10209 #endif
10210 
10211 // Add float double precision
10212 instruct addD_regD_regD(regD dst, regD src1, regD src2) %{
10213   effect(DEF dst, USE src1, USE src2);
10214   size(4);
10215   format %{ "FADDD  $dst,$src1,$src2" %}
10216   ins_encode %{
10217     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10218   %}
10219   ins_pipe(faddD_reg_reg);
10220 %}
10221 
10222 // Sub float double precision
10223 instruct subD_regD_regD(regD dst, regD src1, regD src2) %{
10224   effect(DEF dst, USE src1, USE src2);
10225   size(4);
10226   format %{ "FSUBD  $dst,$src1,$src2" %}
10227   ins_encode %{
10228     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10229   %}
10230   ins_pipe(faddD_reg_reg);
10231 %}
10232 
10233 // Mul float double precision
10234 instruct mulD_regD_regD(regD dst, regD src1, regD src2) %{
10235   effect(DEF dst, USE src1, USE src2);
10236   size(4);
10237   format %{ "FMULD  $dst,$src1,$src2" %}
10238   ins_encode %{
10239     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10240   %}
10241   ins_pipe(fmulD_reg_reg);
10242 %}
10243 
10244 instruct regL_to_regD(regD dst, iRegL src) %{
10245   // No match rule to avoid chain rule match.
10246   effect(DEF dst, USE src);
10247   ins_cost(MEMORY_REF_COST);
10248   size(4);
10249   format %{ "FMDRR   $dst,$src\t! regL to regD" %}
10250   ins_encode %{
10251     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
10252   %}
10253   ins_pipe(ialu_reg_reg); // FIXME
10254 %}
10255 
10256 instruct regI_regI_to_regD(regD dst, iRegI src1, iRegI src2) %{
10257   // No match rule to avoid chain rule match.
10258   effect(DEF dst, USE src1, USE src2);
10259   ins_cost(MEMORY_REF_COST);
10260   size(4);
10261   format %{ "FMDRR   $dst,$src1,$src2\t! regI,regI to regD" %}
10262   ins_encode %{
10263     __ fmdrr($dst$$FloatRegister, $src1$$Register, $src2$$Register);
10264   %}
10265   ins_pipe(ialu_reg_reg); // FIXME
10266 %}
10267 
10268 instruct convL2D_reg_slow_fxtof(regD dst, iRegL src) %{
10269   match(Set dst (ConvL2D src));
10270   ins_cost(DEFAULT_COST*8 + MEMORY_REF_COST*6); // FIXME
10271 
10272   expand %{
10273     regD_low   tmpsrc;
10274     iRegI      ix43300000;
10275     iRegI      ix41f00000;
10276     iRegI      ix0;
10277     regD_low   dx43300000;
10278     regD       dx41f00000;
10279     regD       tmp1;
10280     regD_low   tmp2;
10281     regD       tmp3;
10282     regD       tmp4;
10283 
10284     regL_to_regD(tmpsrc, src);
10285 
10286     loadConI_x43300000(ix43300000);
10287     loadConI_x41f00000(ix41f00000);
10288     loadConI_x0(ix0);
10289 
10290     regI_regI_to_regD(dx43300000, ix0, ix43300000);
10291     regI_regI_to_regD(dx41f00000, ix0, ix41f00000);
10292 
10293     convI2D_regDHi_regD(tmp1, tmpsrc);
10294     regDHi_regDLo_to_regD(tmp2, dx43300000, tmpsrc);
10295     subD_regD_regD(tmp3, tmp2, dx43300000);
10296     mulD_regD_regD(tmp4, tmp1, dx41f00000);
10297     addD_regD_regD(dst, tmp3, tmp4);
10298   %}
10299 %}
10300 #endif // !AARCH64
10301 
10302 instruct convL2I_reg(iRegI dst, iRegL src) %{
10303   match(Set dst (ConvL2I src));
10304   size(4);
10305 #ifdef AARCH64
10306   format %{ "MOV_w  $dst,$src\t! long->int" %}
10307   ins_encode %{
10308     __ mov_w($dst$$Register, $src$$Register);
10309   %}
10310 #else
10311   format %{ "MOV    $dst,$src.lo\t! long->int" %}
10312   ins_encode %{
10313     __ mov($dst$$Register, $src$$Register);
10314   %}
10315 #endif
10316   ins_pipe(ialu_move_reg_I_to_L);
10317 %}
10318 
10319 #ifndef AARCH64
10320 // Register Shift Right Immediate
10321 instruct shrL_reg_imm6_L2I(iRegI dst, iRegL src, immI_32_63 cnt) %{
10322   match(Set dst (ConvL2I (RShiftL src cnt)));
10323   size(4);
10324   format %{ "ASR    $dst,$src.hi,($cnt - 32)\t! long->int or mov if $cnt==32" %}
10325   ins_encode %{
10326     if ($cnt$$constant == 32) {
10327       __ mov($dst$$Register, $src$$Register->successor());
10328     } else {
10329       __ mov($dst$$Register, AsmOperand($src$$Register->successor(), asr, $cnt$$constant - 32));
10330     }
10331   %}
10332   ins_pipe(ialu_reg_imm);
10333 %}
10334 #endif
10335 
10336 
10337 //----------Control Flow Instructions------------------------------------------
10338 // Compare Instructions
10339 // Compare Integers
10340 instruct compI_iReg(flagsReg icc, iRegI op1, iRegI op2) %{
10341   match(Set icc (CmpI op1 op2));
10342   effect( DEF icc, USE op1, USE op2 );
10343 
10344   size(4);
10345   format %{ "cmp_32 $op1,$op2\t! int" %}
10346   ins_encode %{
10347     __ cmp_32($op1$$Register, $op2$$Register);
10348   %}
10349   ins_pipe(ialu_cconly_reg_reg);
10350 %}
10351 
10352 #ifdef _LP64
10353 // Compare compressed pointers
10354 instruct compN_reg2(flagsRegU icc, iRegN op1, iRegN op2) %{
10355   match(Set icc (CmpN op1 op2));
10356   effect( DEF icc, USE op1, USE op2 );
10357 
10358   size(4);
10359   format %{ "cmp_32 $op1,$op2\t! int" %}
10360   ins_encode %{
10361     __ cmp_32($op1$$Register, $op2$$Register);
10362   %}
10363   ins_pipe(ialu_cconly_reg_reg);
10364 %}
10365 #endif
10366 
10367 instruct compU_iReg(flagsRegU icc, iRegI op1, iRegI op2) %{
10368   match(Set icc (CmpU op1 op2));
10369 
10370   size(4);
10371   format %{ "cmp_32 $op1,$op2\t! unsigned int" %}
10372   ins_encode %{
10373     __ cmp_32($op1$$Register, $op2$$Register);
10374   %}
10375   ins_pipe(ialu_cconly_reg_reg);
10376 %}
10377 
10378 instruct compI_iReg_immneg(flagsReg icc, iRegI op1, aimmIneg op2) %{
10379   match(Set icc (CmpI op1 op2));
10380   effect( DEF icc, USE op1 );
10381 
10382   size(4);
10383   format %{ "cmn_32 $op1,-$op2\t! int" %}
10384   ins_encode %{
10385     __ cmn_32($op1$$Register, -$op2$$constant);
10386   %}
10387   ins_pipe(ialu_cconly_reg_imm);
10388 %}
10389 
10390 instruct compI_iReg_imm(flagsReg icc, iRegI op1, aimmI op2) %{
10391   match(Set icc (CmpI op1 op2));
10392   effect( DEF icc, USE op1 );
10393 
10394   size(4);
10395   format %{ "cmp_32 $op1,$op2\t! int" %}
10396   ins_encode %{
10397     __ cmp_32($op1$$Register, $op2$$constant);
10398   %}
10399   ins_pipe(ialu_cconly_reg_imm);
10400 %}
10401 
10402 instruct testI_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immI0 zero ) %{
10403   match(Set icc (CmpI (AndI op1 op2) zero));
10404   size(4);
10405   format %{ "tst_32 $op2,$op1" %}
10406 
10407   ins_encode %{
10408     __ tst_32($op1$$Register, $op2$$Register);
10409   %}
10410   ins_pipe(ialu_cconly_reg_reg_zero);
10411 %}
10412 
10413 #ifndef AARCH64
10414 instruct testshlI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
10415   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
10416   size(4);
10417   format %{ "TST   $op2,$op1<<$op3" %}
10418 
10419   ins_encode %{
10420     __ tst($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$Register));
10421   %}
10422   ins_pipe(ialu_cconly_reg_reg_zero);
10423 %}
10424 #endif
10425 
10426 instruct testshlI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
10427   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
10428   size(4);
10429   format %{ "tst_32 $op2,$op1<<$op3" %}
10430 
10431   ins_encode %{
10432     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$constant));
10433   %}
10434   ins_pipe(ialu_cconly_reg_reg_zero);
10435 %}
10436 
10437 #ifndef AARCH64
10438 instruct testsarI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
10439   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
10440   size(4);
10441   format %{ "TST   $op2,$op1<<$op3" %}
10442 
10443   ins_encode %{
10444     __ tst($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$Register));
10445   %}
10446   ins_pipe(ialu_cconly_reg_reg_zero);
10447 %}
10448 #endif
10449 
10450 instruct testsarI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
10451   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
10452   size(4);
10453   format %{ "tst_32 $op2,$op1<<$op3" %}
10454 
10455   ins_encode %{
10456     __ tst_32($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$constant));
10457   %}
10458   ins_pipe(ialu_cconly_reg_reg_zero);
10459 %}
10460 
10461 #ifndef AARCH64
10462 instruct testshrI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
10463   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
10464   size(4);
10465   format %{ "TST   $op2,$op1<<$op3" %}
10466 
10467   ins_encode %{
10468     __ tst($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$Register));
10469   %}
10470   ins_pipe(ialu_cconly_reg_reg_zero);
10471 %}
10472 #endif
10473 
10474 instruct testshrI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
10475   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
10476   size(4);
10477   format %{ "tst_32 $op2,$op1<<$op3" %}
10478 
10479   ins_encode %{
10480     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$constant));
10481   %}
10482   ins_pipe(ialu_cconly_reg_reg_zero);
10483 %}
10484 
10485 instruct testI_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, limmI op2, immI0 zero ) %{
10486   match(Set icc (CmpI (AndI op1 op2) zero));
10487   size(4);
10488   format %{ "tst_32 $op2,$op1" %}
10489 
10490   ins_encode %{
10491     __ tst_32($op1$$Register, $op2$$constant);
10492   %}
10493   ins_pipe(ialu_cconly_reg_imm_zero);
10494 %}
10495 
10496 #ifdef AARCH64
10497 instruct compL_reg_reg(flagsReg xcc, iRegL op1, iRegL op2)
10498 %{
10499   match(Set xcc (CmpL op1 op2));
10500   effect( DEF xcc, USE op1, USE op2 );
10501 
10502   size(4);
10503   format %{ "CMP     $op1,$op2\t! long" %}
10504   ins_encode %{
10505     __ cmp($op1$$Register, $op2$$Register);
10506   %}
10507   ins_pipe(ialu_cconly_reg_reg);
10508 %}
10509 
10510 instruct compUL_iReg(flagsRegU xcc, iRegL op1, iRegL op2) %{
10511   match(Set xcc (CmpUL op1 op2));
10512 
10513   size(4);
10514   format %{ "CMP     $op1,$op2\t! unsigned long" %}
10515   ins_encode %{
10516     __ cmp($op1$$Register, $op2$$Register);
10517   %}
10518   ins_pipe(ialu_cconly_reg_reg);
10519 %}
10520 #else
10521 instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
10522   match(Set xcc (CmpL op1 op2));
10523   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
10524 
10525   size(8);
10526   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! long\n\t"
10527             "SBCS    $tmp,$op1.hi,$op2.hi" %}
10528   ins_encode %{
10529     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
10530     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
10531   %}
10532   ins_pipe(ialu_cconly_reg_reg);
10533 %}
10534 
10535 instruct compUL_reg_reg_LTGE(flagsRegUL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
10536   match(Set xcc (CmpUL op1 op2));
10537   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
10538 
10539   size(8);
10540   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! unsigned long\n\t"
10541             "SBCS    $tmp,$op1.hi,$op2.hi" %}
10542   ins_encode %{
10543     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
10544     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
10545   %}
10546   ins_pipe(ialu_cconly_reg_reg);
10547 %}
10548 #endif
10549 
10550 #ifdef AARCH64
10551 instruct compL_reg_con(flagsReg xcc, iRegL op1, aimmL con) %{
10552   match(Set xcc (CmpL op1 con));
10553   effect( DEF xcc, USE op1, USE con );
10554 
10555   size(8);
10556   format %{ "CMP     $op1,$con\t\t! long"  %}
10557   ins_encode %{
10558     __ cmp($op1$$Register, $con$$constant);
10559   %}
10560 
10561   ins_pipe(ialu_cconly_reg_imm);
10562 %}
10563 
10564 instruct compUL_reg_con(flagsRegU xcc, iRegL op1, aimmL con) %{
10565   match(Set xcc (CmpUL op1 con));
10566   effect(DEF xcc, USE op1, USE con);
10567 
10568   size(8);
10569   format %{ "CMP     $op1,$con\t\t! unsigned long"  %}
10570   ins_encode %{
10571     __ cmp($op1$$Register, $con$$constant);
10572   %}
10573 
10574   ins_pipe(ialu_cconly_reg_imm);
10575 %}
10576 #else
10577 instruct compL_reg_reg_EQNE(flagsRegL_EQNE xcc, iRegL op1, iRegL op2) %{
10578   match(Set xcc (CmpL op1 op2));
10579   effect( DEF xcc, USE op1, USE op2 );
10580 
10581   size(8);
10582   format %{ "TEQ    $op1.hi,$op2.hi\t\t! long\n\t"
10583             "TEQ.eq $op1.lo,$op2.lo" %}
10584   ins_encode %{
10585     __ teq($op1$$Register->successor(), $op2$$Register->successor());
10586     __ teq($op1$$Register, $op2$$Register, eq);
10587   %}
10588   ins_pipe(ialu_cconly_reg_reg);
10589 %}
10590 
10591 instruct compL_reg_reg_LEGT(flagsRegL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
10592   match(Set xcc (CmpL op1 op2));
10593   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
10594 
10595   size(8);
10596   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! long\n\t"
10597             "SBCS    $tmp,$op2.hi,$op1.hi" %}
10598   ins_encode %{
10599     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
10600     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
10601   %}
10602   ins_pipe(ialu_cconly_reg_reg);
10603 %}
10604 
10605 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
10606 // (hi($con$$constant), lo($con$$constant)) becomes
10607 instruct compL_reg_con_LTGE(flagsRegL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
10608   match(Set xcc (CmpL op1 con));
10609   effect( DEF xcc, USE op1, USE con, TEMP tmp );
10610 
10611   size(8);
10612   format %{ "SUBS    $tmp,$op1.low,$con\t\t! long\n\t"
10613             "SBCS    $tmp,$op1.hi,0" %}
10614   ins_encode %{
10615     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
10616     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
10617   %}
10618 
10619   ins_pipe(ialu_cconly_reg_reg);
10620 %}
10621 
10622 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
10623 // (hi($con$$constant), lo($con$$constant)) becomes
10624 instruct compL_reg_con_EQNE(flagsRegL_EQNE xcc, iRegL op1, immLlowRot con) %{
10625   match(Set xcc (CmpL op1 con));
10626   effect( DEF xcc, USE op1, USE con );
10627 
10628   size(8);
10629   format %{ "TEQ    $op1.hi,0\t\t! long\n\t"
10630             "TEQ.eq $op1.lo,$con" %}
10631   ins_encode %{
10632     __ teq($op1$$Register->successor(), 0);
10633     __ teq($op1$$Register, $con$$constant, eq);
10634   %}
10635 
10636   ins_pipe(ialu_cconly_reg_reg);
10637 %}
10638 
10639 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
10640 // (hi($con$$constant), lo($con$$constant)) becomes
10641 instruct compL_reg_con_LEGT(flagsRegL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
10642   match(Set xcc (CmpL op1 con));
10643   effect( DEF xcc, USE op1, USE con, TEMP tmp );
10644 
10645   size(8);
10646   format %{ "RSBS    $tmp,$op1.low,$con\t\t! long\n\t"
10647             "RSCS    $tmp,$op1.hi,0" %}
10648   ins_encode %{
10649     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
10650     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
10651   %}
10652 
10653   ins_pipe(ialu_cconly_reg_reg);
10654 %}
10655 
10656 instruct compUL_reg_reg_EQNE(flagsRegUL_EQNE xcc, iRegL op1, iRegL op2) %{
10657   match(Set xcc (CmpUL op1 op2));
10658   effect(DEF xcc, USE op1, USE op2);
10659 
10660   size(8);
10661   format %{ "TEQ    $op1.hi,$op2.hi\t\t! unsigned long\n\t"
10662             "TEQ.eq $op1.lo,$op2.lo" %}
10663   ins_encode %{
10664     __ teq($op1$$Register->successor(), $op2$$Register->successor());
10665     __ teq($op1$$Register, $op2$$Register, eq);
10666   %}
10667   ins_pipe(ialu_cconly_reg_reg);
10668 %}
10669 
10670 instruct compUL_reg_reg_LEGT(flagsRegUL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
10671   match(Set xcc (CmpUL op1 op2));
10672   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
10673 
10674   size(8);
10675   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! unsigned long\n\t"
10676             "SBCS    $tmp,$op2.hi,$op1.hi" %}
10677   ins_encode %{
10678     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
10679     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
10680   %}
10681   ins_pipe(ialu_cconly_reg_reg);
10682 %}
10683 
10684 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
10685 // (hi($con$$constant), lo($con$$constant)) becomes
10686 instruct compUL_reg_con_LTGE(flagsRegUL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
10687   match(Set xcc (CmpUL op1 con));
10688   effect(DEF xcc, USE op1, USE con, TEMP tmp);
10689 
10690   size(8);
10691   format %{ "SUBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
10692             "SBCS    $tmp,$op1.hi,0" %}
10693   ins_encode %{
10694     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
10695     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
10696   %}
10697 
10698   ins_pipe(ialu_cconly_reg_reg);
10699 %}
10700 
10701 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
10702 // (hi($con$$constant), lo($con$$constant)) becomes
10703 instruct compUL_reg_con_EQNE(flagsRegUL_EQNE xcc, iRegL op1, immLlowRot con) %{
10704   match(Set xcc (CmpUL op1 con));
10705   effect(DEF xcc, USE op1, USE con);
10706 
10707   size(8);
10708   format %{ "TEQ    $op1.hi,0\t\t! unsigned long\n\t"
10709             "TEQ.eq $op1.lo,$con" %}
10710   ins_encode %{
10711     __ teq($op1$$Register->successor(), 0);
10712     __ teq($op1$$Register, $con$$constant, eq);
10713   %}
10714 
10715   ins_pipe(ialu_cconly_reg_reg);
10716 %}
10717 
10718 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
10719 // (hi($con$$constant), lo($con$$constant)) becomes
10720 instruct compUL_reg_con_LEGT(flagsRegUL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
10721   match(Set xcc (CmpUL op1 con));
10722   effect(DEF xcc, USE op1, USE con, TEMP tmp);
10723 
10724   size(8);
10725   format %{ "RSBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
10726             "RSCS    $tmp,$op1.hi,0" %}
10727   ins_encode %{
10728     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
10729     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
10730   %}
10731 
10732   ins_pipe(ialu_cconly_reg_reg);
10733 %}
10734 #endif
10735 
10736 /* instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ */
10737 /*   match(Set xcc (CmpL (AndL op1 op2) zero)); */
10738 /*   ins_encode %{ */
10739 /*     __ stop("testL_reg_reg unimplemented"); */
10740 /*   %} */
10741 /*   ins_pipe(ialu_cconly_reg_reg); */
10742 /* %} */
10743 
10744 /* // useful for checking the alignment of a pointer: */
10745 /* instruct testL_reg_con(flagsRegL xcc, iRegL op1, immLlowRot con, immL0 zero) %{ */
10746 /*   match(Set xcc (CmpL (AndL op1 con) zero)); */
10747 /*   ins_encode %{ */
10748 /*     __ stop("testL_reg_con unimplemented"); */
10749 /*   %} */
10750 /*   ins_pipe(ialu_cconly_reg_reg); */
10751 /* %} */
10752 
10753 instruct compU_iReg_imm(flagsRegU icc, iRegI op1, aimmU31 op2 ) %{
10754   match(Set icc (CmpU op1 op2));
10755 
10756   size(4);
10757   format %{ "cmp_32 $op1,$op2\t! unsigned" %}
10758   ins_encode %{
10759     __ cmp_32($op1$$Register, $op2$$constant);
10760   %}
10761   ins_pipe(ialu_cconly_reg_imm);
10762 %}
10763 
10764 // Compare Pointers
10765 instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{
10766   match(Set pcc (CmpP op1 op2));
10767 
10768   size(4);
10769   format %{ "CMP    $op1,$op2\t! ptr" %}
10770   ins_encode %{
10771     __ cmp($op1$$Register, $op2$$Register);
10772   %}
10773   ins_pipe(ialu_cconly_reg_reg);
10774 %}
10775 
10776 instruct compP_iRegP_imm(flagsRegP pcc, iRegP op1, aimmP op2 ) %{
10777   match(Set pcc (CmpP op1 op2));
10778 
10779   size(4);
10780   format %{ "CMP    $op1,$op2\t! ptr" %}
10781   ins_encode %{
10782     assert($op2$$constant == 0 || _opnds[2]->constant_reloc() == relocInfo::none, "reloc in cmp?");
10783     __ cmp($op1$$Register, $op2$$constant);
10784   %}
10785   ins_pipe(ialu_cconly_reg_imm);
10786 %}
10787 
10788 //----------Max and Min--------------------------------------------------------
10789 // Min Instructions
10790 // Conditional move for min
10791 instruct cmovI_reg_lt( iRegI op2, iRegI op1, flagsReg icc ) %{
10792   effect( USE_DEF op2, USE op1, USE icc );
10793 
10794   size(4);
10795   format %{ "MOV.lt  $op2,$op1\t! min" %}
10796   ins_encode %{
10797     __ mov($op2$$Register, $op1$$Register, lt);
10798   %}
10799   ins_pipe(ialu_reg_flags);
10800 %}
10801 
10802 // Min Register with Register.
10803 instruct minI_eReg(iRegI op1, iRegI op2) %{
10804   match(Set op2 (MinI op1 op2));
10805   ins_cost(DEFAULT_COST*2);
10806   expand %{
10807     flagsReg icc;
10808     compI_iReg(icc,op1,op2);
10809     cmovI_reg_lt(op2,op1,icc);
10810   %}
10811 %}
10812 
10813 // Max Instructions
10814 // Conditional move for max
10815 instruct cmovI_reg_gt( iRegI op2, iRegI op1, flagsReg icc ) %{
10816   effect( USE_DEF op2, USE op1, USE icc );
10817   format %{ "MOV.gt  $op2,$op1\t! max" %}
10818   ins_encode %{
10819     __ mov($op2$$Register, $op1$$Register, gt);
10820   %}
10821   ins_pipe(ialu_reg_flags);
10822 %}
10823 
10824 // Max Register with Register
10825 instruct maxI_eReg(iRegI op1, iRegI op2) %{
10826   match(Set op2 (MaxI op1 op2));
10827   ins_cost(DEFAULT_COST*2);
10828   expand %{
10829     flagsReg icc;
10830     compI_iReg(icc,op1,op2);
10831     cmovI_reg_gt(op2,op1,icc);
10832   %}
10833 %}
10834 
10835 
10836 //----------Float Compares----------------------------------------------------
10837 // Compare floating, generate condition code
10838 instruct cmpF_cc(flagsRegF fcc, flagsReg icc, regF src1, regF src2) %{
10839   match(Set icc (CmpF src1 src2));
10840   effect(KILL fcc);
10841 
10842 #ifdef AARCH64
10843   size(4);
10844   format %{ "FCMP_s  $src1,$src2" %}
10845   ins_encode %{
10846     __ fcmp_s($src1$$FloatRegister, $src2$$FloatRegister);
10847   %}
10848 #else
10849   size(8);
10850   format %{ "FCMPs  $src1,$src2\n\t"
10851             "FMSTAT" %}
10852   ins_encode %{
10853     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
10854     __ fmstat();
10855   %}
10856 #endif
10857   ins_pipe(faddF_fcc_reg_reg_zero);
10858 %}
10859 
10860 instruct cmpF0_cc(flagsRegF fcc, flagsReg icc, regF src1, immF0 src2) %{
10861   match(Set icc (CmpF src1 src2));
10862   effect(KILL fcc);
10863 
10864 #ifdef AARCH64
10865   size(4);
10866   format %{ "FCMP0_s $src1" %}
10867   ins_encode %{
10868     __ fcmp0_s($src1$$FloatRegister);
10869   %}
10870 #else
10871   size(8);
10872   format %{ "FCMPs  $src1,$src2\n\t"
10873             "FMSTAT" %}
10874   ins_encode %{
10875     __ fcmpzs($src1$$FloatRegister);
10876     __ fmstat();
10877   %}
10878 #endif
10879   ins_pipe(faddF_fcc_reg_reg_zero);
10880 %}
10881 
10882 instruct cmpD_cc(flagsRegF fcc, flagsReg icc, regD src1, regD src2) %{
10883   match(Set icc (CmpD src1 src2));
10884   effect(KILL fcc);
10885 
10886 #ifdef AARCH64
10887   size(4);
10888   format %{ "FCMP_d $src1,$src2" %}
10889   ins_encode %{
10890     __ fcmp_d($src1$$FloatRegister, $src2$$FloatRegister);
10891   %}
10892 #else
10893   size(8);
10894   format %{ "FCMPd  $src1,$src2 \n\t"
10895             "FMSTAT" %}
10896   ins_encode %{
10897     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
10898     __ fmstat();
10899   %}
10900 #endif
10901   ins_pipe(faddD_fcc_reg_reg_zero);
10902 %}
10903 
10904 instruct cmpD0_cc(flagsRegF fcc, flagsReg icc, regD src1, immD0 src2) %{
10905   match(Set icc (CmpD src1 src2));
10906   effect(KILL fcc);
10907 
10908 #ifdef AARCH64
10909   size(8);
10910   format %{ "FCMP0_d $src1" %}
10911   ins_encode %{
10912     __ fcmp0_d($src1$$FloatRegister);
10913   %}
10914 #else
10915   size(8);
10916   format %{ "FCMPZd  $src1,$src2 \n\t"
10917             "FMSTAT" %}
10918   ins_encode %{
10919     __ fcmpzd($src1$$FloatRegister);
10920     __ fmstat();
10921   %}
10922 #endif
10923   ins_pipe(faddD_fcc_reg_reg_zero);
10924 %}
10925 
10926 #ifdef AARCH64
10927 // Compare floating, generate -1,0,1
10928 instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsReg icc) %{
10929   match(Set dst (CmpF3 src1 src2));
10930   // effect(KILL fcc); // nobody cares if flagsRegF is killed
10931   effect(KILL icc);
10932   ins_cost(DEFAULT_COST*3); // FIXME
10933   size(12);
10934   format %{ "FCMP_s $src1,$src2\n\t"
10935             "CSET   $dst, gt\n\t"
10936             "CSINV  $dst, $dst, ZR, ge" %}
10937   ins_encode %{
10938     Register dst = $dst$$Register;
10939     __ fcmp_s($src1$$FloatRegister, $src2$$FloatRegister);
10940     __ cset(dst, gt);            // 1 if '>', else 0
10941     __ csinv(dst, dst, ZR, ge);  // previous value if '>=', else -1
10942   %}
10943   ins_pipe( floating_cmp ); // FIXME
10944 %}
10945 
10946 // Compare floating, generate -1,0,1
10947 instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsReg icc) %{
10948   match(Set dst (CmpD3 src1 src2));
10949   // effect(KILL fcc); // nobody cares if flagsRegF is killed
10950   effect(KILL icc);
10951   ins_cost(DEFAULT_COST*3); // FIXME
10952   size(12);
10953   format %{ "FCMP_d $src1,$src2\n\t"
10954             "CSET   $dst, gt\n\t"
10955             "CSINV  $dst, $dst, ZR, ge" %}
10956   ins_encode %{
10957     Register dst = $dst$$Register;
10958     __ fcmp_d($src1$$FloatRegister, $src2$$FloatRegister);
10959     __ cset(dst, gt);            // 1 if '>', else 0
10960     __ csinv(dst, dst, ZR, ge);  // previous value if '>=', else -1
10961   %}
10962   ins_pipe( floating_cmp ); // FIXME
10963 %}
10964 
10965 // Compare floating, generate -1,0,1
10966 instruct cmpF0_reg(iRegI dst, regF src1, immF0 src2, flagsReg icc) %{
10967   match(Set dst (CmpF3 src1 src2));
10968   // effect(KILL fcc); // nobody cares if flagsRegF is killed
10969   effect(KILL icc);
10970   ins_cost(DEFAULT_COST*3); // FIXME
10971   size(12);
10972   format %{ "FCMP0_s $src1\n\t"
10973             "CSET   $dst, gt\n\t"
10974             "CSINV  $dst, $dst, ZR, ge" %}
10975   ins_encode %{
10976     Register dst = $dst$$Register;
10977     __ fcmp0_s($src1$$FloatRegister);
10978     __ cset(dst, gt);            // 1 if '>', else 0
10979     __ csinv(dst, dst, ZR, ge);  // previous value if '>=', else -1
10980   %}
10981   ins_pipe( floating_cmp ); // FIXME
10982 %}
10983 
10984 // Compare floating, generate -1,0,1
10985 instruct cmpD0_reg(iRegI dst, regD src1, immD0 src2, flagsReg icc) %{
10986   match(Set dst (CmpD3 src1 src2));
10987   // effect(KILL fcc); // nobody cares if flagsRegF is killed
10988   effect(KILL icc);
10989   ins_cost(DEFAULT_COST*3); // FIXME
10990   size(12);
10991   format %{ "FCMP0_d $src1\n\t"
10992             "CSET   $dst, gt\n\t"
10993             "CSINV  $dst, $dst, ZR, ge" %}
10994   ins_encode %{
10995     Register dst = $dst$$Register;
10996     __ fcmp0_d($src1$$FloatRegister);
10997     __ cset(dst, gt);            // 1 if '>', else 0
10998     __ csinv(dst, dst, ZR, ge);  // previous value if '>=', else -1
10999   %}
11000   ins_pipe( floating_cmp ); // FIXME
11001 %}
11002 #else
11003 // Compare floating, generate -1,0,1
11004 instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsRegF fcc) %{
11005   match(Set dst (CmpF3 src1 src2));
11006   effect(KILL fcc);
11007   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
11008   size(20);
11009   // same number of instructions as code using conditional moves but
11010   // doesn't kill integer condition register
11011   format %{ "FCMPs  $dst,$src1,$src2 \n\t"
11012             "VMRS   $dst, FPSCR \n\t"
11013             "OR     $dst, $dst, 0x08000000 \n\t"
11014             "EOR    $dst, $dst, $dst << 3 \n\t"
11015             "MOV    $dst, $dst >> 30" %}
11016   ins_encode %{
11017     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
11018     __ floating_cmp($dst$$Register);
11019   %}
11020   ins_pipe( floating_cmp );
11021 %}
11022 
11023 instruct cmpF0_reg(iRegI dst, regF src1, immF0 src2, flagsRegF fcc) %{
11024   match(Set dst (CmpF3 src1 src2));
11025   effect(KILL fcc);
11026   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
11027   size(20);
11028   // same number of instructions as code using conditional moves but
11029   // doesn't kill integer condition register
11030   format %{ "FCMPZs $dst,$src1,$src2 \n\t"
11031             "VMRS   $dst, FPSCR \n\t"
11032             "OR     $dst, $dst, 0x08000000 \n\t"
11033             "EOR    $dst, $dst, $dst << 3 \n\t"
11034             "MOV    $dst, $dst >> 30" %}
11035   ins_encode %{
11036     __ fcmpzs($src1$$FloatRegister);
11037     __ floating_cmp($dst$$Register);
11038   %}
11039   ins_pipe( floating_cmp );
11040 %}
11041 
11042 instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsRegF fcc) %{
11043   match(Set dst (CmpD3 src1 src2));
11044   effect(KILL fcc);
11045   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
11046   size(20);
11047   // same number of instructions as code using conditional moves but
11048   // doesn't kill integer condition register
11049   format %{ "FCMPd  $dst,$src1,$src2 \n\t"
11050             "VMRS   $dst, FPSCR \n\t"
11051             "OR     $dst, $dst, 0x08000000 \n\t"
11052             "EOR    $dst, $dst, $dst << 3 \n\t"
11053             "MOV    $dst, $dst >> 30" %}
11054   ins_encode %{
11055     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
11056     __ floating_cmp($dst$$Register);
11057   %}
11058   ins_pipe( floating_cmp );
11059 %}
11060 
11061 instruct cmpD0_reg(iRegI dst, regD src1, immD0 src2, flagsRegF fcc) %{
11062   match(Set dst (CmpD3 src1 src2));
11063   effect(KILL fcc);
11064   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
11065   size(20);
11066   // same number of instructions as code using conditional moves but
11067   // doesn't kill integer condition register
11068   format %{ "FCMPZd $dst,$src1,$src2 \n\t"
11069             "VMRS   $dst, FPSCR \n\t"
11070             "OR     $dst, $dst, 0x08000000 \n\t"
11071             "EOR    $dst, $dst, $dst << 3 \n\t"
11072             "MOV    $dst, $dst >> 30" %}
11073   ins_encode %{
11074     __ fcmpzd($src1$$FloatRegister);
11075     __ floating_cmp($dst$$Register);
11076   %}
11077   ins_pipe( floating_cmp );
11078 %}
11079 #endif // !AARCH64
11080 
11081 //----------Branches---------------------------------------------------------
11082 // Jump
11083 // (compare 'operand indIndex' and 'instruct addP_reg_reg' above)
11084 // FIXME
11085 instruct jumpXtnd(iRegX switch_val, iRegP tmp) %{
11086   match(Jump switch_val);
11087   effect(TEMP tmp);
11088   ins_cost(350);
11089   format %{  "ADD    $tmp, $constanttablebase, $switch_val\n\t"
11090              "LDR    $tmp,[$tmp + $constantoffset]\n\t"
11091              "BX     $tmp" %}
11092   size(20);
11093   ins_encode %{
11094     Register table_reg;
11095     Register label_reg = $tmp$$Register;
11096     if (constant_offset() == 0) {
11097       table_reg = $constanttablebase;
11098       __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
11099     } else {
11100       table_reg = $tmp$$Register;
11101       int offset = $constantoffset;
11102       if (is_memoryP(offset)) {
11103         __ add(table_reg, $constanttablebase, $switch_val$$Register);
11104         __ ldr(label_reg, Address(table_reg, offset));
11105       } else {
11106         __ mov_slow(table_reg, $constantoffset);
11107         __ add(table_reg, $constanttablebase, table_reg);
11108         __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
11109       }
11110     }
11111     __ jump(label_reg); // ldr + b better than ldr to PC for branch predictor?
11112     //    __ ldr(PC, Address($table$$Register, $switch_val$$Register));
11113   %}
11114   ins_pipe(ialu_reg_reg);
11115 %}
11116 
11117 // // Direct Branch.
11118 instruct branch(label labl) %{
11119   match(Goto);
11120   effect(USE labl);
11121 
11122   size(4);
11123   ins_cost(BRANCH_COST);
11124   format %{ "B     $labl" %}
11125   ins_encode %{
11126     __ b(*($labl$$label));
11127   %}
11128   ins_pipe(br);
11129 %}
11130 
11131 // Conditional Direct Branch
11132 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{
11133   match(If cmp icc);
11134   effect(USE labl);
11135 
11136   size(4);
11137   ins_cost(BRANCH_COST);
11138   format %{ "B$cmp   $icc,$labl" %}
11139   ins_encode %{
11140     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
11141   %}
11142   ins_pipe(br_cc);
11143 %}
11144 
11145 #ifdef ARM
11146 instruct branchCon_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, label labl) %{
11147   match(If cmp icc);
11148   effect(USE labl);
11149   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);
11150 
11151   size(4);
11152   ins_cost(BRANCH_COST);
11153   format %{ "B$cmp   $icc,$labl" %}
11154   ins_encode %{
11155     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
11156   %}
11157   ins_pipe(br_cc);
11158 %}
11159 #endif
11160 
11161 #ifdef AARCH64
11162 instruct cbzI(cmpOp cmp, iRegI op1, immI0 op2, label labl) %{
11163   match(If cmp (CmpI op1 op2));
11164   effect(USE labl);
11165   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
11166             _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
11167   size(4);
11168   ins_cost(BRANCH_COST);
11169   format %{ "CB{N}Z $op1, $labl\t! int $cmp" %}
11170   ins_encode %{
11171     if ($cmp$$cmpcode == eq) {
11172       __ cbz_w($op1$$Register, *($labl$$label));
11173     } else {
11174       __ cbnz_w($op1$$Register, *($labl$$label));
11175     }
11176   %}
11177   ins_pipe(br_cc); // FIXME
11178 %}
11179 
11180 instruct cbzP(cmpOpP cmp, iRegP op1, immP0 op2, label labl) %{
11181   match(If cmp (CmpP op1 op2));
11182   effect(USE labl);
11183   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
11184             _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
11185   size(4);
11186   ins_cost(BRANCH_COST);
11187   format %{ "CB{N}Z $op1, $labl\t! ptr $cmp" %}
11188   ins_encode %{
11189     if ($cmp$$cmpcode == eq) {
11190       __ cbz($op1$$Register, *($labl$$label));
11191     } else {
11192       __ cbnz($op1$$Register, *($labl$$label));
11193     }
11194   %}
11195   ins_pipe(br_cc); // FIXME
11196 %}
11197 
11198 instruct cbzL(cmpOpL cmp, iRegL op1, immL0 op2, label labl) %{
11199   match(If cmp (CmpL op1 op2));
11200   effect(USE labl);
11201   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
11202             _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
11203   size(4);
11204   ins_cost(BRANCH_COST);
11205   format %{ "CB{N}Z $op1, $labl\t! long $cmp" %}
11206   ins_encode %{
11207     if ($cmp$$cmpcode == eq) {
11208       __ cbz($op1$$Register, *($labl$$label));
11209     } else {
11210       __ cbnz($op1$$Register, *($labl$$label));
11211     }
11212   %}
11213   ins_pipe(br_cc); // FIXME
11214 %}
11215 #endif
11216 
11217 instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{
11218   match(If cmp icc);
11219   effect(USE labl);
11220 
11221   size(4);
11222   ins_cost(BRANCH_COST);
11223   format %{ "B$cmp  $icc,$labl" %}
11224   ins_encode %{
11225     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
11226   %}
11227   ins_pipe(br_cc);
11228 %}
11229 
11230 instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{
11231   match(If cmp pcc);
11232   effect(USE labl);
11233 
11234   size(4);
11235   ins_cost(BRANCH_COST);
11236   format %{ "B$cmp  $pcc,$labl" %}
11237   ins_encode %{
11238     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
11239   %}
11240   ins_pipe(br_cc);
11241 %}
11242 
11243 #ifndef AARCH64
11244 instruct branchConL_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, label labl) %{
11245   match(If cmp xcc);
11246   effect(USE labl);
11247   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
11248 
11249   size(4);
11250   ins_cost(BRANCH_COST);
11251   format %{ "B$cmp  $xcc,$labl" %}
11252   ins_encode %{
11253     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
11254   %}
11255   ins_pipe(br_cc);
11256 %}
11257 
11258 instruct branchConL_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, label labl) %{
11259   match(If cmp xcc);
11260   effect(USE labl);
11261   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
11262 
11263   size(4);
11264   ins_cost(BRANCH_COST);
11265   format %{ "B$cmp  $xcc,$labl" %}
11266   ins_encode %{
11267     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
11268   %}
11269   ins_pipe(br_cc);
11270 %}
11271 
11272 instruct branchConL_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, label labl) %{
11273   match(If cmp xcc);
11274   effect(USE labl);
11275   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le );
11276 
11277   size(4);
11278   ins_cost(BRANCH_COST);
11279   format %{ "B$cmp  $xcc,$labl" %}
11280   ins_encode %{
11281     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
11282   %}
11283   ins_pipe(br_cc);
11284 %}
11285 
11286 instruct branchConUL_LTGE(cmpOpUL cmp, flagsRegUL_LTGE xcc, label labl) %{
11287   match(If cmp xcc);
11288   effect(USE labl);
11289   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
11290 
11291   size(4);
11292   ins_cost(BRANCH_COST);
11293   format %{ "B$cmp  $xcc,$labl" %}
11294   ins_encode %{
11295     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
11296   %}
11297   ins_pipe(br_cc);
11298 %}
11299 
11300 instruct branchConUL_EQNE(cmpOpUL cmp, flagsRegUL_EQNE xcc, label labl) %{
11301   match(If cmp xcc);
11302   effect(USE labl);
11303   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
11304 
11305   size(4);
11306   ins_cost(BRANCH_COST);
11307   format %{ "B$cmp  $xcc,$labl" %}
11308   ins_encode %{
11309     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
11310   %}
11311   ins_pipe(br_cc);
11312 %}
11313 
11314 instruct branchConUL_LEGT(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, label labl) %{
11315   match(If cmp xcc);
11316   effect(USE labl);
11317   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le);
11318 
11319   size(4);
11320   ins_cost(BRANCH_COST);
11321   format %{ "B$cmp  $xcc,$labl" %}
11322   ins_encode %{
11323     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
11324   %}
11325   ins_pipe(br_cc);
11326 %}
11327 #endif
11328 
11329 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
11330   match(CountedLoopEnd cmp icc);
11331   effect(USE labl);
11332 
11333   size(4);
11334   ins_cost(BRANCH_COST);
11335   format %{ "B$cmp   $icc,$labl\t! Loop end" %}
11336   ins_encode %{
11337     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
11338   %}
11339   ins_pipe(br_cc);
11340 %}
11341 
11342 // instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{
11343 //   match(CountedLoopEnd cmp icc);
11344 //   ins_pipe(br_cc);
11345 // %}
11346 
11347 // ============================================================================
11348 // Long Compare
11349 //
11350 // Currently we hold longs in 2 registers.  Comparing such values efficiently
11351 // is tricky.  The flavor of compare used depends on whether we are testing
11352 // for LT, LE, or EQ.  For a simple LT test we can check just the sign bit.
11353 // The GE test is the negated LT test.  The LE test can be had by commuting
11354 // the operands (yielding a GE test) and then negating; negate again for the
11355 // GT test.  The EQ test is done by ORcc'ing the high and low halves, and the
11356 // NE test is negated from that.
11357 
11358 // Due to a shortcoming in the ADLC, it mixes up expressions like:
11359 // (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)).  Note the
11360 // difference between 'Y' and '0L'.  The tree-matches for the CmpI sections
11361 // are collapsed internally in the ADLC's dfa-gen code.  The match for
11362 // (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the
11363 // foo match ends up with the wrong leaf.  One fix is to not match both
11364 // reg-reg and reg-zero forms of long-compare.  This is unfortunate because
11365 // both forms beat the trinary form of long-compare and both are very useful
11366 // on Intel which has so few registers.
11367 
11368 // instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{
11369 //   match(If cmp xcc);
11370 //   ins_pipe(br_cc);
11371 // %}
11372 
11373 // Manifest a CmpL3 result in an integer register.  Very painful.
11374 // This is the test to avoid.
11375 #ifdef AARCH64
11376 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr) %{
11377   match(Set dst (CmpL3 src1 src2));
11378   // effect(KILL fcc); // nobody cares if flagsRegF is killed
11379   effect(KILL ccr);
11380   ins_cost(DEFAULT_COST*3); // FIXME
11381   size(12);
11382   format %{ "CMP    $src1,$src2\n\t"
11383             "CSET   $dst, gt\n\t"
11384             "CSINV  $dst, $dst, ZR, ge" %}
11385   ins_encode %{
11386     Register dst = $dst$$Register;
11387     __ cmp($src1$$Register, $src2$$Register);
11388     __ cset(dst, gt);            // 1 if '>', else 0
11389     __ csinv(dst, dst, ZR, ge);  // previous value if '>=', else -1
11390   %}
11391   ins_pipe( ialu_cconly_reg_reg ); // FIXME
11392 %}
11393 // TODO cmpL3_reg_imm
11394 #else
11395 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
11396   match(Set dst (CmpL3 src1 src2) );
11397   effect( KILL ccr );
11398   ins_cost(6*DEFAULT_COST); // FIXME
11399   size(32);
11400   format %{
11401       "CMP    $src1.hi, $src2.hi\t\t! long\n"
11402     "\tMOV.gt $dst, 1\n"
11403     "\tmvn.lt $dst, 0\n"
11404     "\tB.ne   done\n"
11405     "\tSUBS   $dst, $src1.lo, $src2.lo\n"
11406     "\tMOV.hi $dst, 1\n"
11407     "\tmvn.lo $dst, 0\n"
11408     "done:"     %}
11409   ins_encode %{
11410     Label done;
11411     __ cmp($src1$$Register->successor(), $src2$$Register->successor());
11412     __ mov($dst$$Register, 1, gt);
11413     __ mvn($dst$$Register, 0, lt);
11414     __ b(done, ne);
11415     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
11416     __ mov($dst$$Register, 1, hi);
11417     __ mvn($dst$$Register, 0, lo);
11418     __ bind(done);
11419   %}
11420   ins_pipe(cmpL_reg);
11421 %}
11422 #endif
11423 
11424 #ifndef AARCH64
11425 // Conditional move
11426 instruct cmovLL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, iRegL src) %{
11427   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
11428   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
11429 
11430   ins_cost(150);
11431   size(8);
11432   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
11433             "MOV$cmp  $dst,$src.hi" %}
11434   ins_encode %{
11435     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
11436     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
11437   %}
11438   ins_pipe(ialu_reg);
11439 %}
11440 
11441 instruct cmovLL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, iRegL src) %{
11442   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
11443   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
11444 
11445   ins_cost(150);
11446   size(8);
11447   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
11448             "MOV$cmp  $dst,$src.hi" %}
11449   ins_encode %{
11450     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
11451     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
11452   %}
11453   ins_pipe(ialu_reg);
11454 %}
11455 
11456 instruct cmovLL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, iRegL src) %{
11457   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
11458   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
11459 
11460   ins_cost(150);
11461   size(8);
11462   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
11463             "MOV$cmp  $dst,$src.hi" %}
11464   ins_encode %{
11465     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
11466     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
11467   %}
11468   ins_pipe(ialu_reg);
11469 %}
11470 
11471 instruct cmovLL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, immL0 src) %{
11472   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
11473   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
11474   ins_cost(140);
11475   size(8);
11476   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
11477             "MOV$cmp  $dst,0" %}
11478   ins_encode %{
11479     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
11480     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
11481   %}
11482   ins_pipe(ialu_imm);
11483 %}
11484 
11485 instruct cmovLL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, immL0 src) %{
11486   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
11487   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
11488   ins_cost(140);
11489   size(8);
11490   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
11491             "MOV$cmp  $dst,0" %}
11492   ins_encode %{
11493     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
11494     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
11495   %}
11496   ins_pipe(ialu_imm);
11497 %}
11498 
11499 instruct cmovLL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, immL0 src) %{
11500   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
11501   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
11502   ins_cost(140);
11503   size(8);
11504   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
11505             "MOV$cmp  $dst,0" %}
11506   ins_encode %{
11507     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
11508     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
11509   %}
11510   ins_pipe(ialu_imm);
11511 %}
11512 #endif // !AARCH64
11513 
11514 #ifndef AARCH64
11515 instruct cmovIL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, iRegI src) %{
11516   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
11517   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
11518 
11519   ins_cost(150);
11520   size(4);
11521   format %{ "MOV$cmp  $dst,$src" %}
11522   ins_encode %{
11523     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
11524   %}
11525   ins_pipe(ialu_reg);
11526 %}
11527 
11528 instruct cmovIL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, iRegI src) %{
11529   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
11530   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
11531 
11532   ins_cost(150);
11533   size(4);
11534   format %{ "MOV$cmp  $dst,$src" %}
11535   ins_encode %{
11536     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
11537   %}
11538   ins_pipe(ialu_reg);
11539 %}
11540 
11541 instruct cmovIL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, iRegI src) %{
11542   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
11543   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
11544 
11545   ins_cost(150);
11546   size(4);
11547   format %{ "MOV$cmp  $dst,$src" %}
11548   ins_encode %{
11549     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
11550   %}
11551   ins_pipe(ialu_reg);
11552 %}
11553 #endif // !AARCH64
11554 
11555 #ifndef AARCH64
11556 instruct cmovIL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immI16 src) %{
11557   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
11558   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
11559 
11560   ins_cost(140);
11561   format %{ "MOVW$cmp  $dst,$src" %}
11562   ins_encode %{
11563     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
11564   %}
11565   ins_pipe(ialu_imm);
11566 %}
11567 
11568 instruct cmovIL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, immI16 src) %{
11569   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
11570   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
11571 
11572   ins_cost(140);
11573   format %{ "MOVW$cmp  $dst,$src" %}
11574   ins_encode %{
11575     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
11576   %}
11577   ins_pipe(ialu_imm);
11578 %}
11579 
11580 instruct cmovIL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immI16 src) %{
11581   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
11582   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
11583 
11584   ins_cost(140);
11585   format %{ "MOVW$cmp  $dst,$src" %}
11586   ins_encode %{
11587     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
11588   %}
11589   ins_pipe(ialu_imm);
11590 %}
11591 
11592 instruct cmovPL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, iRegP src) %{
11593   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
11594   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
11595 
11596   ins_cost(150);
11597   size(4);
11598   format %{ "MOV$cmp  $dst,$src" %}
11599   ins_encode %{
11600     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
11601   %}
11602   ins_pipe(ialu_reg);
11603 %}
11604 
11605 instruct cmovPL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, iRegP src) %{
11606   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
11607   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
11608 
11609   ins_cost(150);
11610   size(4);
11611   format %{ "MOV$cmp  $dst,$src" %}
11612   ins_encode %{
11613     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
11614   %}
11615   ins_pipe(ialu_reg);
11616 %}
11617 
11618 instruct cmovPL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, iRegP src) %{
11619   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
11620   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
11621 
11622   ins_cost(150);
11623   size(4);
11624   format %{ "MOV$cmp  $dst,$src" %}
11625   ins_encode %{
11626     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
11627   %}
11628   ins_pipe(ialu_reg);
11629 %}
11630 
11631 instruct cmovPL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, immP0 src) %{
11632   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
11633   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
11634 
11635   ins_cost(140);
11636   format %{ "MOVW$cmp  $dst,$src" %}
11637   ins_encode %{
11638     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
11639   %}
11640   ins_pipe(ialu_imm);
11641 %}
11642 
11643 instruct cmovPL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, immP0 src) %{
11644   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
11645   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
11646 
11647   ins_cost(140);
11648   format %{ "MOVW$cmp  $dst,$src" %}
11649   ins_encode %{
11650     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
11651   %}
11652   ins_pipe(ialu_imm);
11653 %}
11654 
11655 instruct cmovPL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, immP0 src) %{
11656   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
11657   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
11658 
11659   ins_cost(140);
11660   format %{ "MOVW$cmp  $dst,$src" %}
11661   ins_encode %{
11662     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
11663   %}
11664   ins_pipe(ialu_imm);
11665 %}
11666 
11667 instruct cmovFL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regF dst, regF src) %{
11668   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
11669   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
11670   ins_cost(150);
11671   size(4);
11672   format %{ "FCPYS$cmp $dst,$src" %}
11673   ins_encode %{
11674     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
11675   %}
11676   ins_pipe(int_conditional_float_move);
11677 %}
11678 
11679 instruct cmovFL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regF dst, regF src) %{
11680   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
11681   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
11682   ins_cost(150);
11683   size(4);
11684   format %{ "FCPYS$cmp $dst,$src" %}
11685   ins_encode %{
11686     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
11687   %}
11688   ins_pipe(int_conditional_float_move);
11689 %}
11690 
11691 instruct cmovFL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regF dst, regF src) %{
11692   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
11693   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
11694   ins_cost(150);
11695   size(4);
11696   format %{ "FCPYS$cmp $dst,$src" %}
11697   ins_encode %{
11698     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
11699   %}
11700   ins_pipe(int_conditional_float_move);
11701 %}
11702 
11703 instruct cmovDL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regD dst, regD src) %{
11704   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
11705   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
11706 
11707   ins_cost(150);
11708   size(4);
11709   format %{ "FCPYD$cmp $dst,$src" %}
11710   ins_encode %{
11711     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
11712   %}
11713   ins_pipe(int_conditional_float_move);
11714 %}
11715 
11716 instruct cmovDL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regD dst, regD src) %{
11717   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
11718   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
11719 
11720   ins_cost(150);
11721   size(4);
11722   format %{ "FCPYD$cmp $dst,$src" %}
11723   ins_encode %{
11724     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
11725   %}
11726   ins_pipe(int_conditional_float_move);
11727 %}
11728 
11729 instruct cmovDL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regD dst, regD src) %{
11730   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
11731   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
11732 
11733   ins_cost(150);
11734   size(4);
11735   format %{ "FCPYD$cmp $dst,$src" %}
11736   ins_encode %{
11737     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
11738   %}
11739   ins_pipe(int_conditional_float_move);
11740 %}
11741 #endif // !AARCH64
11742 
11743 // ============================================================================
11744 // Safepoint Instruction
11745 #ifdef AARCH64
11746 instruct safePoint_poll(iRegP poll, flagsReg icc, RtempRegP tmp) %{
11747   match(SafePoint poll);
11748   // The handler stub kills Rtemp
11749   effect(USE poll, KILL tmp, KILL icc);
11750 
11751   size(4);
11752   format %{ "LDR   ZR,[$poll]\t! Safepoint: poll for GC" %}
11753   ins_encode %{
11754     __ relocate(relocInfo::poll_type);
11755     __ ldr(ZR, Address($poll$$Register));
11756   %}
11757   ins_pipe(loadPollP);
11758 %}
11759 #else
11760 // rather than KILL R12, it would be better to use any reg as
11761 // TEMP. Can't do that at this point because it crashes the compiler
11762 instruct safePoint_poll(iRegP poll, R12RegI tmp, flagsReg icc) %{
11763   match(SafePoint poll);
11764   effect(USE poll, KILL tmp, KILL icc);
11765 
11766   size(4);
11767   format %{ "LDR   $tmp,[$poll]\t! Safepoint: poll for GC" %}
11768   ins_encode %{
11769     __ relocate(relocInfo::poll_type);
11770     __ ldr($tmp$$Register, Address($poll$$Register));
11771   %}
11772   ins_pipe(loadPollP);
11773 %}
11774 #endif
11775 
11776 
11777 // ============================================================================
11778 // Call Instructions
11779 // Call Java Static Instruction
11780 instruct CallStaticJavaDirect( method meth ) %{
11781   match(CallStaticJava);
11782   predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke());
11783   effect(USE meth);
11784 
11785   ins_cost(CALL_COST);
11786   format %{ "CALL,static ==> " %}
11787   ins_encode( Java_Static_Call( meth ), call_epilog );
11788   ins_pipe(simple_call);
11789 %}
11790 
11791 // Call Java Static Instruction (method handle version)
11792 instruct CallStaticJavaHandle( method meth ) %{
11793   match(CallStaticJava);
11794   predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke());
11795   effect(USE meth);
11796   // FP is saved by all callees (for interpreter stack correction).
11797   // We use it here for a similar purpose, in {preserve,restore}_FP.
11798 
11799   ins_cost(CALL_COST);
11800   format %{ "CALL,static/MethodHandle ==> " %}
11801   ins_encode( preserve_SP, Java_Static_Call( meth ), restore_SP, call_epilog );
11802   ins_pipe(simple_call);
11803 %}
11804 
11805 // Call Java Dynamic Instruction
11806 instruct CallDynamicJavaDirect( method meth ) %{
11807   match(CallDynamicJava);
11808   effect(USE meth);
11809 
11810   ins_cost(CALL_COST);
11811   format %{ "MOV_OOP    (empty),R_R8\n\t"
11812             "CALL,dynamic  ; NOP ==> " %}
11813   ins_encode( Java_Dynamic_Call( meth ), call_epilog );
11814   ins_pipe(call);
11815 %}
11816 
11817 // Call Runtime Instruction
11818 instruct CallRuntimeDirect(method meth) %{
11819   match(CallRuntime);
11820   effect(USE meth);
11821   ins_cost(CALL_COST);
11822   format %{ "CALL,runtime" %}
11823 #ifdef AARCH64
11824   ins_encode( save_last_PC, Java_To_Runtime( meth ),
11825               call_epilog );
11826 #else
11827   ins_encode( Java_To_Runtime( meth ),
11828               call_epilog );
11829 #endif
11830   ins_pipe(simple_call);
11831 %}
11832 
11833 // Call runtime without safepoint - same as CallRuntime
11834 instruct CallLeafDirect(method meth) %{
11835   match(CallLeaf);
11836   effect(USE meth);
11837   ins_cost(CALL_COST);
11838   format %{ "CALL,runtime leaf" %}
11839   // TODO: ned save_last_PC here?
11840   ins_encode( Java_To_Runtime( meth ),
11841               call_epilog );
11842   ins_pipe(simple_call);
11843 %}
11844 
11845 // Call runtime without safepoint - same as CallLeaf
11846 instruct CallLeafNoFPDirect(method meth) %{
11847   match(CallLeafNoFP);
11848   effect(USE meth);
11849   ins_cost(CALL_COST);
11850   format %{ "CALL,runtime leaf nofp" %}
11851   // TODO: ned save_last_PC here?
11852   ins_encode( Java_To_Runtime( meth ),
11853               call_epilog );
11854   ins_pipe(simple_call);
11855 %}
11856 
11857 // Tail Call; Jump from runtime stub to Java code.
11858 // Also known as an 'interprocedural jump'.
11859 // Target of jump will eventually return to caller.
11860 // TailJump below removes the return address.
11861 instruct TailCalljmpInd(IPRegP jump_target, inline_cache_regP method_oop) %{
11862   match(TailCall jump_target method_oop );
11863 
11864   ins_cost(CALL_COST);
11865   format %{ "MOV    Rexception_pc, LR\n\t"
11866             "jump   $jump_target  \t! $method_oop holds method oop" %}
11867   ins_encode %{
11868     __ mov(Rexception_pc, LR);   // this is used only to call
11869                                  // StubRoutines::forward_exception_entry()
11870                                  // which expects PC of exception in
11871                                  // R5. FIXME?
11872     __ jump($jump_target$$Register);
11873   %}
11874   ins_pipe(tail_call);
11875 %}
11876 
11877 
11878 // Return Instruction
11879 instruct Ret() %{
11880   match(Return);
11881 
11882   format %{ "ret LR" %}
11883 
11884   ins_encode %{
11885     __ ret(LR);
11886   %}
11887 
11888   ins_pipe(br);
11889 %}
11890 
11891 
11892 // Tail Jump; remove the return address; jump to target.
11893 // TailCall above leaves the return address around.
11894 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
11895 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
11896 // "restore" before this instruction (in Epilogue), we need to materialize it
11897 // in %i0.
11898 instruct tailjmpInd(IPRegP jump_target, RExceptionRegP ex_oop) %{
11899   match( TailJump jump_target ex_oop );
11900   ins_cost(CALL_COST);
11901   format %{ "MOV    Rexception_pc, LR\n\t"
11902             "jump   $jump_target \t! $ex_oop holds exc. oop" %}
11903   ins_encode %{
11904     __ mov(Rexception_pc, LR);
11905     __ jump($jump_target$$Register);
11906   %}
11907   ins_pipe(tail_call);
11908 %}
11909 
11910 // Create exception oop: created by stack-crawling runtime code.
11911 // Created exception is now available to this handler, and is setup
11912 // just prior to jumping to this handler.  No code emitted.
11913 instruct CreateException( RExceptionRegP ex_oop )
11914 %{
11915   match(Set ex_oop (CreateEx));
11916   ins_cost(0);
11917 
11918   size(0);
11919   // use the following format syntax
11920   format %{ "! exception oop is in Rexception_obj; no code emitted" %}
11921   ins_encode();
11922   ins_pipe(empty);
11923 %}
11924 
11925 
11926 // Rethrow exception:
11927 // The exception oop will come in the first argument position.
11928 // Then JUMP (not call) to the rethrow stub code.
11929 instruct RethrowException()
11930 %{
11931   match(Rethrow);
11932   ins_cost(CALL_COST);
11933 
11934   // use the following format syntax
11935   format %{ "b    rethrow_stub" %}
11936   ins_encode %{
11937     Register scratch = R1_tmp;
11938     assert_different_registers(scratch, c_rarg0, LR);
11939     __ jump(OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type, scratch);
11940   %}
11941   ins_pipe(tail_call);
11942 %}
11943 
11944 
11945 // Die now
11946 instruct ShouldNotReachHere( )
11947 %{
11948   match(Halt);
11949   ins_cost(CALL_COST);
11950 
11951   size(4);
11952   // Use the following format syntax
11953   format %{ "ShouldNotReachHere" %}
11954   ins_encode %{
11955 #ifdef AARCH64
11956     __ dpcs1(0xdead);
11957 #else
11958     __ udf(0xdead);
11959 #endif
11960   %}
11961   ins_pipe(tail_call);
11962 %}
11963 
11964 // ============================================================================
11965 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
11966 // array for an instance of the superklass.  Set a hidden internal cache on a
11967 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
11968 // not zero for a miss or zero for a hit.  The encoding ALSO sets flags.
11969 instruct partialSubtypeCheck( R0RegP index, R1RegP sub, R2RegP super, flagsRegP pcc, LRRegP lr ) %{
11970   match(Set index (PartialSubtypeCheck sub super));
11971   effect( KILL pcc, KILL lr );
11972   ins_cost(DEFAULT_COST*10);
11973   format %{ "CALL   PartialSubtypeCheck" %}
11974   ins_encode %{
11975     __ call(StubRoutines::Arm::partial_subtype_check(), relocInfo::runtime_call_type);
11976   %}
11977   ins_pipe(partial_subtype_check_pipe);
11978 %}
11979 
11980 /* instruct partialSubtypeCheck_vs_zero( flagsRegP pcc, o1RegP sub, o2RegP super, immP0 zero, o0RegP idx, o7RegP o7 ) %{ */
11981 /*   match(Set pcc (CmpP (PartialSubtypeCheck sub super) zero)); */
11982 /*   ins_pipe(partial_subtype_check_pipe); */
11983 /* %} */
11984 
11985 
11986 // ============================================================================
11987 // inlined locking and unlocking
11988 
11989 #ifdef AARCH64
11990 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch, iRegP scratch3 )
11991 #else
11992 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch )
11993 #endif
11994 %{
11995   match(Set pcc (FastLock object box));
11996 
11997 #ifdef AARCH64
11998   effect(TEMP scratch, TEMP scratch2, TEMP scratch3);
11999 #else
12000   effect(TEMP scratch, TEMP scratch2);
12001 #endif
12002   ins_cost(100);
12003 
12004 #ifdef AARCH64
12005   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2, $scratch3" %}
12006   ins_encode %{
12007     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register, $scratch3$$Register);
12008   %}
12009 #else
12010   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2" %}
12011   ins_encode %{
12012     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
12013   %}
12014 #endif
12015   ins_pipe(long_memory_op);
12016 %}
12017 
12018 
12019 #ifdef AARCH64
12020 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch, iRegP scratch3 ) %{
12021   match(Set pcc (FastUnlock object box));
12022   effect(TEMP scratch, TEMP scratch2, TEMP scratch3);
12023   ins_cost(100);
12024 
12025   format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2, $scratch3" %}
12026   ins_encode %{
12027     __ fast_unlock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register, $scratch3$$Register);
12028   %}
12029   ins_pipe(long_memory_op);
12030 %}
12031 #else
12032 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch ) %{
12033   match(Set pcc (FastUnlock object box));
12034   effect(TEMP scratch, TEMP scratch2);
12035   ins_cost(100);
12036 
12037   format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2" %}
12038   ins_encode %{
12039     __ fast_unlock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
12040   %}
12041   ins_pipe(long_memory_op);
12042 %}
12043 #endif
12044 
12045 #ifdef AARCH64
12046 // TODO: add version that takes immI cnt?
12047 instruct clear_array(iRegX cnt, iRegP base, iRegP ptr, iRegX temp, Universe dummy, flagsReg cpsr) %{
12048   match(Set dummy (ClearArray cnt base));
12049   effect(TEMP temp, TEMP ptr, KILL cpsr);
12050   ins_cost(300);
12051   format %{
12052       "        MOV    $temp,$cnt\n"
12053       "        ADD    $ptr,$base,$cnt\n"
12054       "        SUBS   $temp,$temp,16\t! Count down dword pair in bytes\n"
12055       "        B.lt   done16\n"
12056       "loop:   STP    ZR,ZR,[$ptr,-16]!\n"
12057       "        SUBS   $temp,$temp,16\t! Count down dword pair in bytes\n"
12058       "        B.ge   loop\t! Clearing loop\n"
12059       "done16: ADDS   $temp,$temp,8\t! Room for 1 more long?\n"
12060       "        B.lt   done\n"
12061       "        STR    ZR,[$base+$temp]\n"
12062       "done:"
12063   %}
12064   ins_encode %{
12065     // TODO: preload?
12066     __ mov($temp$$Register, $cnt$$Register);
12067     __ add($ptr$$Register, $base$$Register, $cnt$$Register);
12068     Label loop, done, done16;
12069     __ subs($temp$$Register, $temp$$Register, 16);
12070     __ b(done16, lt);
12071     __ bind(loop);
12072     __ stp(ZR, ZR, Address($ptr$$Register, -16, pre_indexed));
12073     __ subs($temp$$Register, $temp$$Register, 16);
12074     __ b(loop, ge);
12075     __ bind(done16);
12076     __ adds($temp$$Register, $temp$$Register, 8);
12077     __ b(done, lt);
12078     // $temp should be 0 here
12079     __ str(ZR, Address($base$$Register, $temp$$Register));
12080     __ bind(done);
12081   %}
12082   ins_pipe(long_memory_op);
12083 %}
12084 #else
12085 // Count and Base registers are fixed because the allocator cannot
12086 // kill unknown registers.  The encodings are generic.
12087 instruct clear_array(iRegX cnt, iRegP base, iRegI temp, iRegX zero, Universe dummy, flagsReg cpsr) %{
12088   match(Set dummy (ClearArray cnt base));
12089   effect(TEMP temp, TEMP zero, KILL cpsr);
12090   ins_cost(300);
12091   format %{ "MOV    $zero,0\n"
12092       "        MOV    $temp,$cnt\n"
12093       "loop:   SUBS   $temp,$temp,4\t! Count down a dword of bytes\n"
12094       "        STR.ge $zero,[$base+$temp]\t! delay slot"
12095       "        B.gt   loop\t\t! Clearing loop\n" %}
12096   ins_encode %{
12097     __ mov($zero$$Register, 0);
12098     __ mov($temp$$Register, $cnt$$Register);
12099     Label(loop);
12100     __ bind(loop);
12101     __ subs($temp$$Register, $temp$$Register, 4);
12102     __ str($zero$$Register, Address($base$$Register, $temp$$Register), ge);
12103     __ b(loop, gt);
12104   %}
12105   ins_pipe(long_memory_op);
12106 %}
12107 #endif
12108 
12109 #ifdef XXX
12110 // FIXME: Why R0/R1/R2/R3?
12111 instruct string_compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result,
12112                         iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
12113   predicate(!CompactStrings);
12114   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
12115   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, TEMP tmp1, TEMP tmp2);
12116   ins_cost(300);
12117   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // TEMP $tmp1, $tmp2" %}
12118   ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result, tmp1, tmp2) );
12119 
12120   ins_pipe(long_memory_op);
12121 %}
12122 
12123 // FIXME: Why R0/R1/R2?
12124 instruct string_equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2,
12125                        flagsReg ccr) %{
12126   predicate(!CompactStrings);
12127   match(Set result (StrEquals (Binary str1 str2) cnt));
12128   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp1, TEMP tmp2, TEMP result, KILL ccr);
12129 
12130   ins_cost(300);
12131   format %{ "String Equals $str1,$str2,$cnt -> $result   // TEMP $tmp1, $tmp2" %}
12132   ins_encode( enc_String_Equals(str1, str2, cnt, result, tmp1, tmp2) );
12133   ins_pipe(long_memory_op);
12134 %}
12135 
12136 // FIXME: Why R0/R1?
12137 instruct array_equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result,
12138                       flagsReg ccr) %{
12139   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
12140   match(Set result (AryEq ary1 ary2));
12141   effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP result, KILL ccr);
12142 
12143   ins_cost(300);
12144   format %{ "Array Equals $ary1,$ary2 -> $result   // TEMP $tmp1,$tmp2,$tmp3" %}
12145   ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, result));
12146   ins_pipe(long_memory_op);
12147 %}
12148 #endif
12149 
12150 //---------- Zeros Count Instructions ------------------------------------------
12151 
12152 instruct countLeadingZerosI(iRegI dst, iRegI src) %{
12153   match(Set dst (CountLeadingZerosI src));
12154   size(4);
12155   format %{ "CLZ_32 $dst,$src" %}
12156   ins_encode %{
12157     __ clz_32($dst$$Register, $src$$Register);
12158   %}
12159   ins_pipe(ialu_reg);
12160 %}
12161 
12162 #ifdef AARCH64
12163 instruct countLeadingZerosL(iRegI dst, iRegL src) %{
12164   match(Set dst (CountLeadingZerosL src));
12165   size(4);
12166   format %{ "CLZ $dst,$src" %}
12167   ins_encode %{
12168     __ clz($dst$$Register, $src$$Register);
12169   %}
12170   ins_pipe(ialu_reg);
12171 %}
12172 #else
12173 instruct countLeadingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
12174   match(Set dst (CountLeadingZerosL src));
12175   effect(TEMP tmp, TEMP dst, KILL ccr);
12176   size(16);
12177   format %{ "CLZ    $dst,$src.hi\n\t"
12178             "TEQ    $dst,32\n\t"
12179             "CLZ.eq $tmp,$src.lo\n\t"
12180             "ADD.eq $dst, $dst, $tmp\n\t" %}
12181   ins_encode %{
12182     __ clz($dst$$Register, $src$$Register->successor());
12183     __ teq($dst$$Register, 32);
12184     __ clz($tmp$$Register, $src$$Register, eq);
12185     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
12186   %}
12187   ins_pipe(ialu_reg);
12188 %}
12189 #endif
12190 
12191 instruct countTrailingZerosI(iRegI dst, iRegI src, iRegI tmp) %{
12192   match(Set dst (CountTrailingZerosI src));
12193   effect(TEMP tmp);
12194   size(8);
12195   format %{ "RBIT_32 $tmp, $src\n\t"
12196             "CLZ_32  $dst,$tmp" %}
12197   ins_encode %{
12198     __ rbit_32($tmp$$Register, $src$$Register);
12199     __ clz_32($dst$$Register, $tmp$$Register);
12200   %}
12201   ins_pipe(ialu_reg);
12202 %}
12203 
12204 #ifdef AARCH64
12205 instruct countTrailingZerosL(iRegI dst, iRegL src, iRegL tmp) %{
12206   match(Set dst (CountTrailingZerosL src));
12207   effect(TEMP tmp);
12208   size(8);
12209   format %{ "RBIT $tmp, $src\n\t"
12210             "CLZ  $dst,$tmp" %}
12211   ins_encode %{
12212     __ rbit($tmp$$Register, $src$$Register);
12213     __ clz($dst$$Register, $tmp$$Register);
12214   %}
12215   ins_pipe(ialu_reg);
12216 %}
12217 #else
12218 instruct countTrailingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
12219   match(Set dst (CountTrailingZerosL src));
12220   effect(TEMP tmp, TEMP dst, KILL ccr);
12221   size(24);
12222   format %{ "RBIT   $tmp,$src.lo\n\t"
12223             "CLZ    $dst,$tmp\n\t"
12224             "TEQ    $dst,32\n\t"
12225             "RBIT   $tmp,$src.hi\n\t"
12226             "CLZ.eq $tmp,$tmp\n\t"
12227             "ADD.eq $dst,$dst,$tmp\n\t" %}
12228   ins_encode %{
12229     __ rbit($tmp$$Register, $src$$Register);
12230     __ clz($dst$$Register, $tmp$$Register);
12231     __ teq($dst$$Register, 32);
12232     __ rbit($tmp$$Register, $src$$Register->successor());
12233     __ clz($tmp$$Register, $tmp$$Register, eq);
12234     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
12235   %}
12236   ins_pipe(ialu_reg);
12237 %}
12238 #endif
12239 
12240 
12241 //---------- Population Count Instructions -------------------------------------
12242 
12243 #ifdef AARCH64
12244 instruct popCountI(iRegI dst, iRegI src, regD_low tmp) %{
12245   predicate(UsePopCountInstruction);
12246   match(Set dst (PopCountI src));
12247   effect(TEMP tmp);
12248   size(20);
12249 
12250   format %{ "MOV_W      $dst,$src\n\t"
12251             "FMOV_dx    $tmp,$dst\n\t"
12252             "VCNT       $tmp.8B,$tmp.8B\n\t"
12253             "ADDV       $tmp.B,$tmp.8B\n\t"
12254             "FMRS       $dst,$tmp" %}
12255 
12256   ins_encode %{
12257     __ mov_w($dst$$Register, $src$$Register);
12258     __ fmov_dx($tmp$$FloatRegister, $dst$$Register);
12259     int quad = 0;
12260     int cnt_size = 0; // VELEM_SIZE_8
12261     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister, quad, cnt_size);
12262     int add_size = 0; // VELEM_SIZE_8
12263     __ addv($tmp$$FloatRegister, $tmp$$FloatRegister, quad, add_size);
12264     __ fmrs($dst$$Register, $tmp$$FloatRegister);
12265   %}
12266   ins_pipe(ialu_reg); // FIXME
12267 %}
12268 #else
12269 instruct popCountI(iRegI dst, iRegI src, regD_low tmp) %{
12270   predicate(UsePopCountInstruction);
12271   match(Set dst (PopCountI src));
12272   effect(TEMP tmp);
12273 
12274   format %{ "FMSR       $tmp,$src\n\t"
12275             "VCNT.8     $tmp,$tmp\n\t"
12276             "VPADDL.U8  $tmp,$tmp\n\t"
12277             "VPADDL.U16 $tmp,$tmp\n\t"
12278             "FMRS       $dst,$tmp" %}
12279   size(20);
12280 
12281   ins_encode %{
12282     __ fmsr($tmp$$FloatRegister, $src$$Register);
12283     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
12284     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
12285     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
12286     __ fmrs($dst$$Register, $tmp$$FloatRegister);
12287   %}
12288   ins_pipe(ialu_reg); // FIXME
12289 %}
12290 #endif
12291 
12292 #ifdef AARCH64
12293 instruct popCountL(iRegI dst, iRegL src, regD tmp) %{
12294   predicate(UsePopCountInstruction);
12295   match(Set dst (PopCountL src));
12296   effect(TEMP tmp);
12297   size(16);
12298 
12299   format %{ "FMOV_dx    $tmp,$src\n\t"
12300             "VCNT       $tmp.8B,$tmp.8B\n\t"
12301             "ADDV       $tmp.B,$tmp.8B\n\t"
12302             "FMOV_ws    $dst,$tmp" %}
12303 
12304   ins_encode %{
12305     __ fmov_dx($tmp$$FloatRegister, $src$$Register);
12306     int quad = 0;
12307     int cnt_size = 0;
12308     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister, quad, cnt_size);
12309     int add_size = 0;
12310     __ addv($tmp$$FloatRegister, $tmp$$FloatRegister, quad, add_size);
12311     __ fmov_ws($dst$$Register, $tmp$$FloatRegister);
12312   %}
12313   ins_pipe(ialu_reg); // FIXME
12314 %}
12315 #else
12316 // Note: Long.bitCount(long) returns an int.
12317 instruct popCountL(iRegI dst, iRegL src, regD_low tmp) %{
12318   predicate(UsePopCountInstruction);
12319   match(Set dst (PopCountL src));
12320   effect(TEMP tmp);
12321 
12322   format %{ "FMDRR       $tmp,$src.lo,$src.hi\n\t"
12323             "VCNT.8      $tmp,$tmp\n\t"
12324             "VPADDL.U8   $tmp,$tmp\n\t"
12325             "VPADDL.U16  $tmp,$tmp\n\t"
12326             "VPADDL.U32  $tmp,$tmp\n\t"
12327             "FMRS        $dst,$tmp" %}
12328 
12329   size(32);
12330 
12331   ins_encode %{
12332     __ fmdrr($tmp$$FloatRegister, $src$$Register, $src$$Register->successor());
12333     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
12334     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
12335     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
12336     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 32, 0);
12337     __ fmrs($dst$$Register, $tmp$$FloatRegister);
12338   %}
12339   ins_pipe(ialu_reg);
12340 %}
12341 #endif
12342 
12343 
12344 // ============================================================================
12345 //------------Bytes reverse--------------------------------------------------
12346 
12347 instruct bytes_reverse_int(iRegI dst, iRegI src) %{
12348   match(Set dst (ReverseBytesI src));
12349 
12350   size(4);
12351   format %{ "REV32 $dst,$src" %}
12352   ins_encode %{
12353 #ifdef AARCH64
12354     __ rev_w($dst$$Register, $src$$Register);
12355     // high 32 bits zeroed, not sign extended
12356 #else
12357     __ rev($dst$$Register, $src$$Register);
12358 #endif
12359   %}
12360   ins_pipe( iload_mem ); // FIXME
12361 %}
12362 
12363 instruct bytes_reverse_long(iRegL dst, iRegL src) %{
12364   match(Set dst (ReverseBytesL src));
12365 #ifdef AARCH64
12366 //size(4);
12367   format %{ "REV $dst,$src"  %}
12368   ins_encode %{
12369     __ rev($dst$$Register, $src$$Register);
12370   %}
12371   ins_pipe(ialu_reg_reg); // FIXME
12372 #else
12373   effect(TEMP dst);
12374   size(8);
12375   format %{ "REV $dst.lo,$src.lo\n\t"
12376             "REV $dst.hi,$src.hi" %}
12377   ins_encode %{
12378     __ rev($dst$$Register, $src$$Register->successor());
12379     __ rev($dst$$Register->successor(), $src$$Register);
12380   %}
12381   ins_pipe( iload_mem ); // FIXME
12382 #endif
12383 %}
12384 
12385 instruct bytes_reverse_unsigned_short(iRegI dst, iRegI src) %{
12386   match(Set dst (ReverseBytesUS src));
12387 #ifdef AARCH64
12388   size(4);
12389   format %{ "REV16_W $dst,$src" %}
12390   ins_encode %{
12391     __ rev16_w($dst$$Register, $src$$Register);
12392     // high 32 bits zeroed
12393   %}
12394 #else
12395   size(4);
12396   format %{ "REV16 $dst,$src" %}
12397   ins_encode %{
12398     __ rev16($dst$$Register, $src$$Register);
12399   %}
12400 #endif
12401   ins_pipe( iload_mem ); // FIXME
12402 %}
12403 
12404 instruct bytes_reverse_short(iRegI dst, iRegI src) %{
12405   match(Set dst (ReverseBytesS src));
12406 #ifdef AARCH64
12407   size(8);
12408   format %{ "REV16_W $dst,$src\n\t"
12409             "SIGN_EXT16 $dst" %}
12410   ins_encode %{
12411     __ rev16_w($dst$$Register, $src$$Register);
12412     __ sign_extend($dst$$Register, $dst$$Register, 16);
12413   %}
12414 #else
12415   size(4);
12416   format %{ "REVSH $dst,$src" %}
12417   ins_encode %{
12418     __ revsh($dst$$Register, $src$$Register);
12419   %}
12420 #endif
12421   ins_pipe( iload_mem ); // FIXME
12422 %}
12423 
12424 
12425 // ====================VECTOR INSTRUCTIONS=====================================
12426 
12427 // Load Aligned Packed values into a Double Register
12428 instruct loadV8(vecD dst, memoryD mem) %{
12429   predicate(n->as_LoadVector()->memory_size() == 8);
12430   match(Set dst (LoadVector mem));
12431   ins_cost(MEMORY_REF_COST);
12432   size(4);
12433   format %{ "FLDD   $mem,$dst\t! load vector (8 bytes)" %}
12434   ins_encode %{
12435     __ ldr_double($dst$$FloatRegister, $mem$$Address);
12436   %}
12437   ins_pipe(floadD_mem);
12438 %}
12439 
12440 // Load Aligned Packed values into a Double Register Pair
12441 instruct loadV16(vecX dst, memoryvld mem) %{
12442   predicate(n->as_LoadVector()->memory_size() == 16);
12443   match(Set dst (LoadVector mem));
12444   ins_cost(MEMORY_REF_COST);
12445   size(4);
12446   format %{ "VLD1   $mem,$dst.Q\t! load vector (16 bytes)" %}
12447   ins_encode %{
12448     __ vld1($dst$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
12449   %}
12450   ins_pipe(floadD_mem); // FIXME
12451 %}
12452 
12453 // Store Vector in Double register to memory
12454 instruct storeV8(memoryD mem, vecD src) %{
12455   predicate(n->as_StoreVector()->memory_size() == 8);
12456   match(Set mem (StoreVector mem src));
12457   ins_cost(MEMORY_REF_COST);
12458   size(4);
12459   format %{ "FSTD   $src,$mem\t! store vector (8 bytes)" %}
12460   ins_encode %{
12461     __ str_double($src$$FloatRegister, $mem$$Address);
12462   %}
12463   ins_pipe(fstoreD_mem_reg);
12464 %}
12465 
12466 // Store Vector in Double Register Pair to memory
12467 instruct storeV16(memoryvld mem, vecX src) %{
12468   predicate(n->as_StoreVector()->memory_size() == 16);
12469   match(Set mem (StoreVector mem src));
12470   ins_cost(MEMORY_REF_COST);
12471   size(4);
12472   format %{ "VST1   $src,$mem\t! store vector (16 bytes)" %}
12473   ins_encode %{
12474     __ vst1($src$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
12475   %}
12476   ins_pipe(fstoreD_mem_reg); // FIXME
12477 %}
12478 
12479 #ifndef AARCH64
12480 // Replicate scalar to packed byte values in Double register
12481 instruct Repl8B_reg(vecD dst, iRegI src, iRegI tmp) %{
12482   predicate(n->as_Vector()->length() == 8);
12483   match(Set dst (ReplicateB src));
12484   ins_cost(DEFAULT_COST*4);
12485   effect(TEMP tmp);
12486   size(16);
12487 
12488   // FIXME: could use PKH instruction instead?
12489   format %{ "LSL      $tmp, $src, 24 \n\t"
12490             "OR       $tmp, $tmp, ($tmp >> 8) \n\t"
12491             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
12492             "FMDRR    $dst,$tmp,$tmp\t" %}
12493   ins_encode %{
12494     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 24));
12495     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 8));
12496     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
12497     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
12498   %}
12499   ins_pipe(ialu_reg); // FIXME
12500 %}
12501 #endif /* !AARCH64 */
12502 
12503 // Replicate scalar to packed byte values in Double register
12504 instruct Repl8B_reg_simd(vecD dst, iRegI src) %{
12505   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
12506   match(Set dst (ReplicateB src));
12507   size(4);
12508 
12509   format %{ "VDUP.8 $dst,$src\t" %}
12510   ins_encode %{
12511     bool quad = false;
12512     __ vdupI($dst$$FloatRegister, $src$$Register,
12513              MacroAssembler::VELEM_SIZE_8, quad);
12514   %}
12515   ins_pipe(ialu_reg); // FIXME
12516 %}
12517 
12518 // Replicate scalar to packed byte values in Double register pair
12519 instruct Repl16B_reg(vecX dst, iRegI src) %{
12520   predicate(n->as_Vector()->length_in_bytes() == 16);
12521   match(Set dst (ReplicateB src));
12522   size(4);
12523 
12524   format %{ "VDUP.8 $dst.Q,$src\t" %}
12525   ins_encode %{
12526     bool quad = true;
12527     __ vdupI($dst$$FloatRegister, $src$$Register,
12528              MacroAssembler::VELEM_SIZE_8, quad);
12529   %}
12530   ins_pipe(ialu_reg); // FIXME
12531 %}
12532 
12533 #ifndef AARCH64
12534 // Replicate scalar constant to packed byte values in Double register
12535 instruct Repl8B_immI(vecD dst, immI src, iRegI tmp) %{
12536   predicate(n->as_Vector()->length() == 8);
12537   match(Set dst (ReplicateB src));
12538   ins_cost(DEFAULT_COST*2);
12539   effect(TEMP tmp);
12540   size(12);
12541 
12542   format %{ "MOV      $tmp, Repl4($src))\n\t"
12543             "FMDRR    $dst,$tmp,$tmp\t" %}
12544   ins_encode( LdReplImmI(src, dst, tmp, (4), (1)) );
12545   ins_pipe(loadConFD); // FIXME
12546 %}
12547 #endif /* !AARCH64 */
12548 
12549 // Replicate scalar constant to packed byte values in Double register
12550 // TODO: support negative constants with MVNI?
12551 instruct Repl8B_immU8(vecD dst, immU8 src) %{
12552   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
12553   match(Set dst (ReplicateB src));
12554   size(4);
12555 
12556   format %{ "VMOV.U8  $dst,$src" %}
12557   ins_encode %{
12558     bool quad = false;
12559     __ vmovI($dst$$FloatRegister, $src$$constant,
12560              MacroAssembler::VELEM_SIZE_8, quad);
12561   %}
12562   ins_pipe(loadConFD); // FIXME
12563 %}
12564 
12565 // Replicate scalar constant to packed byte values in Double register pair
12566 instruct Repl16B_immU8(vecX dst, immU8 src) %{
12567   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
12568   match(Set dst (ReplicateB src));
12569   size(4);
12570 
12571   format %{ "VMOV.U8  $dst.Q,$src" %}
12572   ins_encode %{
12573     bool quad = true;
12574     __ vmovI($dst$$FloatRegister, $src$$constant,
12575              MacroAssembler::VELEM_SIZE_8, quad);
12576   %}
12577   ins_pipe(loadConFD); // FIXME
12578 %}
12579 
12580 #ifndef AARCH64
12581 // Replicate scalar to packed short/char values into Double register
12582 instruct Repl4S_reg(vecD dst, iRegI src, iRegI tmp) %{
12583   predicate(n->as_Vector()->length() == 4);
12584   match(Set dst (ReplicateS src));
12585   ins_cost(DEFAULT_COST*3);
12586   effect(TEMP tmp);
12587   size(12);
12588 
12589   // FIXME: could use PKH instruction instead?
12590   format %{ "LSL      $tmp, $src, 16 \n\t"
12591             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
12592             "FMDRR    $dst,$tmp,$tmp\t" %}
12593   ins_encode %{
12594     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 16));
12595     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
12596     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
12597   %}
12598   ins_pipe(ialu_reg); // FIXME
12599 %}
12600 #endif /* !AARCH64 */
12601 
12602 // Replicate scalar to packed byte values in Double register
12603 instruct Repl4S_reg_simd(vecD dst, iRegI src) %{
12604   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
12605   match(Set dst (ReplicateS src));
12606   size(4);
12607 
12608   format %{ "VDUP.16 $dst,$src\t" %}
12609   ins_encode %{
12610     bool quad = false;
12611     __ vdupI($dst$$FloatRegister, $src$$Register,
12612              MacroAssembler::VELEM_SIZE_16, quad);
12613   %}
12614   ins_pipe(ialu_reg); // FIXME
12615 %}
12616 
12617 // Replicate scalar to packed byte values in Double register pair
12618 instruct Repl8S_reg(vecX dst, iRegI src) %{
12619   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
12620   match(Set dst (ReplicateS src));
12621   size(4);
12622 
12623   format %{ "VDUP.16 $dst.Q,$src\t" %}
12624   ins_encode %{
12625     bool quad = true;
12626     __ vdupI($dst$$FloatRegister, $src$$Register,
12627              MacroAssembler::VELEM_SIZE_16, quad);
12628   %}
12629   ins_pipe(ialu_reg); // FIXME
12630 %}
12631 
12632 
12633 #ifndef AARCH64
12634 // Replicate scalar constant to packed short/char values in Double register
12635 instruct Repl4S_immI(vecD dst, immI src, iRegP tmp) %{
12636   predicate(n->as_Vector()->length() == 4);
12637   match(Set dst (ReplicateS src));
12638   effect(TEMP tmp);
12639   size(12);
12640   ins_cost(DEFAULT_COST*4); // FIXME
12641 
12642   format %{ "MOV      $tmp, Repl2($src))\n\t"
12643             "FMDRR    $dst,$tmp,$tmp\t" %}
12644   ins_encode( LdReplImmI(src, dst, tmp, (2), (2)) );
12645   ins_pipe(loadConFD); // FIXME
12646 %}
12647 #endif /* !AARCH64 */
12648 
12649 // Replicate scalar constant to packed byte values in Double register
12650 instruct Repl4S_immU8(vecD dst, immU8 src) %{
12651   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
12652   match(Set dst (ReplicateS src));
12653   size(4);
12654 
12655   format %{ "VMOV.U16  $dst,$src" %}
12656   ins_encode %{
12657     bool quad = false;
12658     __ vmovI($dst$$FloatRegister, $src$$constant,
12659              MacroAssembler::VELEM_SIZE_16, quad);
12660   %}
12661   ins_pipe(loadConFD); // FIXME
12662 %}
12663 
12664 // Replicate scalar constant to packed byte values in Double register pair
12665 instruct Repl8S_immU8(vecX dst, immU8 src) %{
12666   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
12667   match(Set dst (ReplicateS src));
12668   size(4);
12669 
12670   format %{ "VMOV.U16  $dst.Q,$src" %}
12671   ins_encode %{
12672     bool quad = true;
12673     __ vmovI($dst$$FloatRegister, $src$$constant,
12674              MacroAssembler::VELEM_SIZE_16, quad);
12675   %}
12676   ins_pipe(loadConFD); // FIXME
12677 %}
12678 
12679 #ifndef AARCH64
12680 // Replicate scalar to packed int values in Double register
12681 instruct Repl2I_reg(vecD dst, iRegI src) %{
12682   predicate(n->as_Vector()->length() == 2);
12683   match(Set dst (ReplicateI src));
12684   size(4);
12685 
12686   format %{ "FMDRR    $dst,$src,$src\t" %}
12687   ins_encode %{
12688     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
12689   %}
12690   ins_pipe(ialu_reg); // FIXME
12691 %}
12692 
12693 // Replicate scalar to packed int values in Double register pair
12694 instruct Repl4I_reg(vecX dst, iRegI src) %{
12695   predicate(n->as_Vector()->length() == 4);
12696   match(Set dst (ReplicateI src));
12697   ins_cost(DEFAULT_COST*2);
12698   size(8);
12699 
12700   format %{ "FMDRR    $dst.lo,$src,$src\n\t"
12701             "FMDRR    $dst.hi,$src,$src" %}
12702 
12703   ins_encode %{
12704     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
12705     __ fmdrr($dst$$FloatRegister->successor()->successor(),
12706              $src$$Register, $src$$Register);
12707   %}
12708   ins_pipe(ialu_reg); // FIXME
12709 %}
12710 #endif /* !AARCH64 */
12711 
12712 // Replicate scalar to packed int values in Double register
12713 instruct Repl2I_reg_simd(vecD dst, iRegI src) %{
12714   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
12715   match(Set dst (ReplicateI src));
12716   size(4);
12717 
12718   format %{ "VDUP.32 $dst.D,$src\t" %}
12719   ins_encode %{
12720     bool quad = false;
12721     __ vdupI($dst$$FloatRegister, $src$$Register,
12722              MacroAssembler::VELEM_SIZE_32, quad);
12723   %}
12724   ins_pipe(ialu_reg); // FIXME
12725 %}
12726 
12727 // Replicate scalar to packed int values in Double register pair
12728 instruct Repl4I_reg_simd(vecX dst, iRegI src) %{
12729   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
12730   match(Set dst (ReplicateI src));
12731   size(4);
12732 
12733   format %{ "VDUP.32 $dst.Q,$src\t" %}
12734   ins_encode %{
12735     bool quad = true;
12736     __ vdupI($dst$$FloatRegister, $src$$Register,
12737              MacroAssembler::VELEM_SIZE_32, quad);
12738   %}
12739   ins_pipe(ialu_reg); // FIXME
12740 %}
12741 
12742 
12743 #ifndef AARCH64
12744 // Replicate scalar zero constant to packed int values in Double register
12745 instruct Repl2I_immI(vecD dst, immI src, iRegI tmp) %{
12746   predicate(n->as_Vector()->length() == 2);
12747   match(Set dst (ReplicateI src));
12748   effect(TEMP tmp);
12749   size(12);
12750   ins_cost(DEFAULT_COST*4); // FIXME
12751 
12752   format %{ "MOV      $tmp, Repl1($src))\n\t"
12753             "FMDRR    $dst,$tmp,$tmp\t" %}
12754   ins_encode( LdReplImmI(src, dst, tmp, (1), (4)) );
12755   ins_pipe(loadConFD); // FIXME
12756 %}
12757 #endif /* !AARCH64 */
12758 
12759 // Replicate scalar constant to packed byte values in Double register
12760 instruct Repl2I_immU8(vecD dst, immU8 src) %{
12761   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
12762   match(Set dst (ReplicateI src));
12763   size(4);
12764 
12765   format %{ "VMOV.I32  $dst.D,$src" %}
12766   ins_encode %{
12767     bool quad = false;
12768     __ vmovI($dst$$FloatRegister, $src$$constant,
12769              MacroAssembler::VELEM_SIZE_32, quad);
12770   %}
12771   ins_pipe(loadConFD); // FIXME
12772 %}
12773 
12774 // Replicate scalar constant to packed byte values in Double register pair
12775 instruct Repl4I_immU8(vecX dst, immU8 src) %{
12776   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
12777   match(Set dst (ReplicateI src));
12778   size(4);
12779 
12780   format %{ "VMOV.I32  $dst.Q,$src" %}
12781   ins_encode %{
12782     bool quad = true;
12783     __ vmovI($dst$$FloatRegister, $src$$constant,
12784              MacroAssembler::VELEM_SIZE_32, quad);
12785   %}
12786   ins_pipe(loadConFD); // FIXME
12787 %}
12788 
12789 #ifdef AARCH64
12790 // Replicate scalar to packed byte values in Double register pair
12791 instruct Repl2L_reg(vecX dst, iRegL src) %{
12792   predicate(n->as_Vector()->length() == 2);
12793   match(Set dst (ReplicateL src));
12794   size(4*1);
12795   ins_cost(DEFAULT_COST*1); // FIXME
12796 
12797   format %{ "VDUP.2D $dst.Q,$src\t" %}
12798   ins_encode %{
12799     bool quad = true;
12800     __ vdupI($dst$$FloatRegister, $src$$Register,
12801              MacroAssembler::VELEM_SIZE_64, quad);
12802   %}
12803   ins_pipe(ialu_reg); // FIXME
12804 %}
12805 #else /* !AARCH64 */
12806 // Replicate scalar to packed byte values in Double register pair
12807 instruct Repl2L_reg(vecX dst, iRegL src) %{
12808   predicate(n->as_Vector()->length() == 2);
12809   match(Set dst (ReplicateL src));
12810   size(8);
12811   ins_cost(DEFAULT_COST*2); // FIXME
12812 
12813   format %{ "FMDRR $dst.D,$src.lo,$src.hi\t\n"
12814             "FMDRR $dst.D.next,$src.lo,$src.hi" %}
12815   ins_encode %{
12816     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
12817     __ fmdrr($dst$$FloatRegister->successor()->successor(),
12818              $src$$Register, $src$$Register->successor());
12819   %}
12820   ins_pipe(ialu_reg); // FIXME
12821 %}
12822 
12823 
12824 // Replicate scalar to packed float values in Double register
12825 instruct Repl2F_regI(vecD dst, iRegI src) %{
12826   predicate(n->as_Vector()->length() == 2);
12827   match(Set dst (ReplicateF src));
12828   size(4);
12829 
12830   format %{ "FMDRR    $dst.D,$src,$src\t" %}
12831   ins_encode %{
12832     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
12833   %}
12834   ins_pipe(ialu_reg); // FIXME
12835 %}
12836 
12837 // Replicate scalar to packed float values in Double register
12838 instruct Repl2F_reg_vfp(vecD dst, regF src) %{
12839   predicate(n->as_Vector()->length() == 2);
12840   match(Set dst (ReplicateF src));
12841   size(4*2);
12842   ins_cost(DEFAULT_COST*2); // FIXME
12843 
12844   expand %{
12845     iRegI tmp;
12846     MoveF2I_reg_reg(tmp, src);
12847     Repl2F_regI(dst,tmp);
12848   %}
12849 %}
12850 #endif /* !AARCH64 */
12851 
12852 // Replicate scalar to packed float values in Double register
12853 instruct Repl2F_reg_simd(vecD dst, regF src) %{
12854   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
12855   match(Set dst (ReplicateF src));
12856   size(4);
12857   ins_cost(DEFAULT_COST); // FIXME
12858 
12859   format %{ "VDUP.32  $dst.D,$src.D\t" %}
12860   ins_encode %{
12861     bool quad = false;
12862     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
12863   %}
12864   ins_pipe(ialu_reg); // FIXME
12865 %}
12866 
12867 #ifndef AARCH64
12868 // Replicate scalar to packed float values in Double register pair
12869 instruct Repl4F_reg(vecX dst, regF src, iRegI tmp) %{
12870   predicate(n->as_Vector()->length() == 4);
12871   match(Set dst (ReplicateF src));
12872   effect(TEMP tmp);
12873   size(4*3);
12874   ins_cost(DEFAULT_COST*3); // FIXME
12875 
12876   format %{ "FMRS     $tmp,$src\n\t"
12877             "FMDRR    $dst.D,$tmp,$tmp\n\t"
12878             "FMDRR    $dst.D.next,$tmp,$tmp\t" %}
12879   ins_encode %{
12880     __ fmrs($tmp$$Register, $src$$FloatRegister);
12881     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
12882     __ fmdrr($dst$$FloatRegister->successor()->successor(),
12883              $tmp$$Register, $tmp$$Register);
12884   %}
12885   ins_pipe(ialu_reg); // FIXME
12886 %}
12887 #endif /* !AARCH64 */
12888 
12889 // Replicate scalar to packed float values in Double register pair
12890 instruct Repl4F_reg_simd(vecX dst, regF src) %{
12891   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
12892   match(Set dst (ReplicateF src));
12893   size(4);
12894   ins_cost(DEFAULT_COST); // FIXME
12895 
12896   format %{ "VDUP.32  $dst.Q,$src.D\t" %}
12897   ins_encode %{
12898     bool quad = true;
12899     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
12900   %}
12901   ins_pipe(ialu_reg); // FIXME
12902 %}
12903 
12904 #ifndef AARCH64
12905 // Replicate scalar zero constant to packed float values in Double register
12906 instruct Repl2F_immI(vecD dst, immF src, iRegI tmp) %{
12907   predicate(n->as_Vector()->length() == 2);
12908   match(Set dst (ReplicateF src));
12909   effect(TEMP tmp);
12910   size(12);
12911   ins_cost(DEFAULT_COST*4); // FIXME
12912 
12913   format %{ "MOV      $tmp, Repl1($src))\n\t"
12914             "FMDRR    $dst,$tmp,$tmp\t" %}
12915   ins_encode( LdReplImmF(src, dst, tmp) );
12916   ins_pipe(loadConFD); // FIXME
12917 %}
12918 #endif /* !AAARCH64 */
12919 
12920 // Replicate scalar to packed double float values in Double register pair
12921 instruct Repl2D_reg(vecX dst, regD src) %{
12922 #ifdef AARCH64
12923   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
12924   match(Set dst (ReplicateD src));
12925   size(4*1);
12926   ins_cost(DEFAULT_COST*1); // FIXME
12927 
12928   format %{ "VDUP     $dst.2D,$src\t" %}
12929   ins_encode %{
12930     bool quad = true;
12931     __ vdupD($dst$$FloatRegister, $src$$FloatRegister, quad);
12932   %}
12933 #else
12934   predicate(n->as_Vector()->length() == 2);
12935   match(Set dst (ReplicateD src));
12936   size(4*2);
12937   ins_cost(DEFAULT_COST*2); // FIXME
12938 
12939   format %{ "FCPYD    $dst.D.a,$src\n\t"
12940             "FCPYD    $dst.D.b,$src\t" %}
12941   ins_encode %{
12942     FloatRegister dsta = $dst$$FloatRegister;
12943     FloatRegister src = $src$$FloatRegister;
12944     __ fcpyd(dsta, src);
12945     FloatRegister dstb = dsta->successor()->successor();
12946     __ fcpyd(dstb, src);
12947   %}
12948 #endif
12949   ins_pipe(ialu_reg); // FIXME
12950 %}
12951 
12952 // ====================VECTOR ARITHMETIC=======================================
12953 
12954 // --------------------------------- ADD --------------------------------------
12955 
12956 // Bytes vector add
12957 instruct vadd8B_reg(vecD dst, vecD src1, vecD src2) %{
12958   predicate(n->as_Vector()->length() == 8);
12959   match(Set dst (AddVB src1 src2));
12960   format %{ "VADD.I8 $dst,$src1,$src2\t! add packed8B" %}
12961   size(4);
12962   ins_encode %{
12963     bool quad = false;
12964     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
12965              MacroAssembler::VELEM_SIZE_8, quad);
12966   %}
12967   ins_pipe( ialu_reg_reg ); // FIXME
12968 %}
12969 
12970 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
12971   predicate(n->as_Vector()->length() == 16);
12972   match(Set dst (AddVB src1 src2));
12973   size(4);
12974   format %{ "VADD.I8 $dst.Q,$src1.Q,$src2.Q\t! add packed16B" %}
12975   ins_encode %{
12976     bool quad = true;
12977     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
12978              MacroAssembler::VELEM_SIZE_8, quad);
12979   %}
12980   ins_pipe( ialu_reg_reg ); // FIXME
12981 %}
12982 
12983 // Shorts/Chars vector add
12984 instruct vadd4S_reg(vecD dst, vecD src1, vecD src2) %{
12985   predicate(n->as_Vector()->length() == 4);
12986   match(Set dst (AddVS src1 src2));
12987   size(4);
12988   format %{ "VADD.I16 $dst,$src1,$src2\t! add packed4S" %}
12989   ins_encode %{
12990     bool quad = false;
12991     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
12992              MacroAssembler::VELEM_SIZE_16, quad);
12993   %}
12994   ins_pipe( ialu_reg_reg ); // FIXME
12995 %}
12996 
12997 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
12998   predicate(n->as_Vector()->length() == 8);
12999   match(Set dst (AddVS src1 src2));
13000   size(4);
13001   format %{ "VADD.I16 $dst.Q,$src1.Q,$src2.Q\t! add packed8S" %}
13002   ins_encode %{
13003     bool quad = true;
13004     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13005              MacroAssembler::VELEM_SIZE_16, quad);
13006   %}
13007   ins_pipe( ialu_reg_reg ); // FIXME
13008 %}
13009 
13010 // Integers vector add
13011 instruct vadd2I_reg(vecD dst, vecD src1, vecD src2) %{
13012   predicate(n->as_Vector()->length() == 2);
13013   match(Set dst (AddVI src1 src2));
13014   size(4);
13015   format %{ "VADD.I32 $dst.D,$src1.D,$src2.D\t! add packed2I" %}
13016   ins_encode %{
13017     bool quad = false;
13018     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13019              MacroAssembler::VELEM_SIZE_32, quad);
13020   %}
13021   ins_pipe( ialu_reg_reg ); // FIXME
13022 %}
13023 
13024 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
13025   predicate(n->as_Vector()->length() == 4);
13026   match(Set dst (AddVI src1 src2));
13027   size(4);
13028   format %{ "VADD.I32 $dst.Q,$src1.Q,$src2.Q\t! add packed4I" %}
13029   ins_encode %{
13030     bool quad = true;
13031     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13032              MacroAssembler::VELEM_SIZE_32, quad);
13033   %}
13034   ins_pipe( ialu_reg_reg ); // FIXME
13035 %}
13036 
13037 // Longs vector add
13038 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
13039   predicate(n->as_Vector()->length() == 2);
13040   match(Set dst (AddVL src1 src2));
13041   size(4);
13042   format %{ "VADD.I64 $dst.Q,$src1.Q,$src2.Q\t! add packed2L" %}
13043   ins_encode %{
13044     bool quad = true;
13045     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13046              MacroAssembler::VELEM_SIZE_64, quad);
13047   %}
13048   ins_pipe( ialu_reg_reg ); // FIXME
13049 %}
13050 
13051 // Floats vector add
13052 instruct vadd2F_reg(vecD dst, vecD src1, vecD src2) %{
13053   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
13054   match(Set dst (AddVF src1 src2));
13055   size(4);
13056   format %{ "VADD.F32 $dst,$src1,$src2\t! add packed2F" %}
13057   ins_encode %{
13058     bool quad = false;
13059     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13060              MacroAssembler::VFA_SIZE_F32, quad);
13061   %}
13062   ins_pipe( faddD_reg_reg ); // FIXME
13063 %}
13064 
13065 #ifndef AARCH64
13066 instruct vadd2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
13067   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
13068   match(Set dst (AddVF src1 src2));
13069   ins_cost(DEFAULT_COST*2); // FIXME
13070 
13071   size(4*2);
13072   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
13073             "FADDS  $dst.b,$src1.b,$src2.b" %}
13074   ins_encode %{
13075     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
13076     __ add_float($dst$$FloatRegister->successor(),
13077              $src1$$FloatRegister->successor(),
13078              $src2$$FloatRegister->successor());
13079   %}
13080 
13081   ins_pipe(faddF_reg_reg); // FIXME
13082 %}
13083 #endif
13084 
13085 instruct vadd4F_reg_simd(vecX dst, vecX src1, vecX src2) %{
13086   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
13087   match(Set dst (AddVF src1 src2));
13088   size(4);
13089   format %{ "VADD.F32 $dst.Q,$src1.Q,$src2.Q\t! add packed4F" %}
13090   ins_encode %{
13091     bool quad = true;
13092     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13093              MacroAssembler::VFA_SIZE_F32, quad);
13094   %}
13095   ins_pipe( faddD_reg_reg ); // FIXME
13096 %}
13097 
13098 #ifdef AARCH64
13099 instruct vadd2D_reg_simd(vecX dst, vecX src1, vecX src2) %{
13100   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
13101   match(Set dst (AddVD src1 src2));
13102   size(4);
13103   format %{ "VADD.F64 $dst.Q,$src1.Q,$src2.Q\t! add packed2D" %}
13104   ins_encode %{
13105     bool quad = true;
13106     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13107              MacroAssembler::VFA_SIZE_F64, quad);
13108   %}
13109   ins_pipe( faddD_reg_reg ); // FIXME
13110 %}
13111 #else
13112 instruct vadd4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
13113   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
13114   match(Set dst (AddVF src1 src2));
13115   size(4*4);
13116   ins_cost(DEFAULT_COST*4); // FIXME
13117 
13118   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
13119             "FADDS  $dst.b,$src1.b,$src2.b\n\t"
13120             "FADDS  $dst.c,$src1.c,$src2.c\n\t"
13121             "FADDS  $dst.d,$src1.d,$src2.d" %}
13122 
13123   ins_encode %{
13124     FloatRegister dsta = $dst$$FloatRegister;
13125     FloatRegister src1a = $src1$$FloatRegister;
13126     FloatRegister src2a = $src2$$FloatRegister;
13127     __ add_float(dsta, src1a, src2a);
13128     FloatRegister dstb = dsta->successor();
13129     FloatRegister src1b = src1a->successor();
13130     FloatRegister src2b = src2a->successor();
13131     __ add_float(dstb, src1b, src2b);
13132     FloatRegister dstc = dstb->successor();
13133     FloatRegister src1c = src1b->successor();
13134     FloatRegister src2c = src2b->successor();
13135     __ add_float(dstc, src1c, src2c);
13136     FloatRegister dstd = dstc->successor();
13137     FloatRegister src1d = src1c->successor();
13138     FloatRegister src2d = src2c->successor();
13139     __ add_float(dstd, src1d, src2d);
13140   %}
13141 
13142   ins_pipe(faddF_reg_reg); // FIXME
13143 %}
13144 
13145 instruct vadd2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
13146   predicate(n->as_Vector()->length() == 2);
13147   match(Set dst (AddVD src1 src2));
13148   size(4*2);
13149   ins_cost(DEFAULT_COST*2); // FIXME
13150 
13151   format %{ "FADDD  $dst.a,$src1.a,$src2.a\n\t"
13152             "FADDD  $dst.b,$src1.b,$src2.b" %}
13153 
13154   ins_encode %{
13155     FloatRegister dsta = $dst$$FloatRegister;
13156     FloatRegister src1a = $src1$$FloatRegister;
13157     FloatRegister src2a = $src2$$FloatRegister;
13158     __ add_double(dsta, src1a, src2a);
13159     FloatRegister dstb = dsta->successor()->successor();
13160     FloatRegister src1b = src1a->successor()->successor();
13161     FloatRegister src2b = src2a->successor()->successor();
13162     __ add_double(dstb, src1b, src2b);
13163   %}
13164 
13165   ins_pipe(faddF_reg_reg); // FIXME
13166 %}
13167 #endif
13168 
13169 
13170 // Bytes vector sub
13171 instruct vsub8B_reg(vecD dst, vecD src1, vecD src2) %{
13172   predicate(n->as_Vector()->length() == 8);
13173   match(Set dst (SubVB src1 src2));
13174   size(4);
13175   format %{ "VSUB.I8 $dst,$src1,$src2\t! sub packed8B" %}
13176   ins_encode %{
13177     bool quad = false;
13178     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13179              MacroAssembler::VELEM_SIZE_8, quad);
13180   %}
13181   ins_pipe( ialu_reg_reg ); // FIXME
13182 %}
13183 
13184 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
13185   predicate(n->as_Vector()->length() == 16);
13186   match(Set dst (SubVB src1 src2));
13187   size(4);
13188   format %{ "VSUB.I8 $dst.Q,$src1.Q,$src2.Q\t! sub packed16B" %}
13189   ins_encode %{
13190     bool quad = true;
13191     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13192              MacroAssembler::VELEM_SIZE_8, quad);
13193   %}
13194   ins_pipe( ialu_reg_reg ); // FIXME
13195 %}
13196 
13197 // Shorts/Chars vector sub
13198 instruct vsub4S_reg(vecD dst, vecD src1, vecD src2) %{
13199   predicate(n->as_Vector()->length() == 4);
13200   match(Set dst (SubVS src1 src2));
13201   size(4);
13202   format %{ "VSUB.I16 $dst,$src1,$src2\t! sub packed4S" %}
13203   ins_encode %{
13204     bool quad = false;
13205     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13206              MacroAssembler::VELEM_SIZE_16, quad);
13207   %}
13208   ins_pipe( ialu_reg_reg ); // FIXME
13209 %}
13210 
13211 instruct vsub16S_reg(vecX dst, vecX src1, vecX src2) %{
13212   predicate(n->as_Vector()->length() == 8);
13213   match(Set dst (SubVS src1 src2));
13214   size(4);
13215   format %{ "VSUB.I16 $dst.Q,$src1.Q,$src2.Q\t! sub packed8S" %}
13216   ins_encode %{
13217     bool quad = true;
13218     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13219              MacroAssembler::VELEM_SIZE_16, quad);
13220   %}
13221   ins_pipe( ialu_reg_reg ); // FIXME
13222 %}
13223 
13224 // Integers vector sub
13225 instruct vsub2I_reg(vecD dst, vecD src1, vecD src2) %{
13226   predicate(n->as_Vector()->length() == 2);
13227   match(Set dst (SubVI src1 src2));
13228   size(4);
13229   format %{ "VSUB.I32 $dst,$src1,$src2\t! sub packed2I" %}
13230   ins_encode %{
13231     bool quad = false;
13232     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13233              MacroAssembler::VELEM_SIZE_32, quad);
13234   %}
13235   ins_pipe( ialu_reg_reg ); // FIXME
13236 %}
13237 
13238 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
13239   predicate(n->as_Vector()->length() == 4);
13240   match(Set dst (SubVI src1 src2));
13241   size(4);
13242   format %{ "VSUB.I32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4I" %}
13243   ins_encode %{
13244     bool quad = true;
13245     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13246              MacroAssembler::VELEM_SIZE_32, quad);
13247   %}
13248   ins_pipe( ialu_reg_reg ); // FIXME
13249 %}
13250 
13251 // Longs vector sub
13252 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
13253   predicate(n->as_Vector()->length() == 2);
13254   match(Set dst (SubVL src1 src2));
13255   size(4);
13256   format %{ "VSUB.I64 $dst.Q,$src1.Q,$src2.Q\t! sub packed2L" %}
13257   ins_encode %{
13258     bool quad = true;
13259     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13260              MacroAssembler::VELEM_SIZE_64, quad);
13261   %}
13262   ins_pipe( ialu_reg_reg ); // FIXME
13263 %}
13264 
13265 // Floats vector sub
13266 instruct vsub2F_reg(vecD dst, vecD src1, vecD src2) %{
13267   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
13268   match(Set dst (SubVF src1 src2));
13269   size(4);
13270   format %{ "VSUB.F32 $dst,$src1,$src2\t! sub packed2F" %}
13271   ins_encode %{
13272     bool quad = false;
13273     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13274              MacroAssembler::VFA_SIZE_F32, quad);
13275   %}
13276   ins_pipe( faddF_reg_reg ); // FIXME
13277 %}
13278 
13279 #ifndef AARCH64
13280 instruct vsub2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
13281   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
13282   match(Set dst (SubVF src1 src2));
13283   size(4*2);
13284   ins_cost(DEFAULT_COST*2); // FIXME
13285 
13286   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
13287             "FSUBS  $dst.b,$src1.b,$src2.b" %}
13288 
13289   ins_encode %{
13290     FloatRegister dsta = $dst$$FloatRegister;
13291     FloatRegister src1a = $src1$$FloatRegister;
13292     FloatRegister src2a = $src2$$FloatRegister;
13293     __ sub_float(dsta, src1a, src2a);
13294     FloatRegister dstb = dsta->successor();
13295     FloatRegister src1b = src1a->successor();
13296     FloatRegister src2b = src2a->successor();
13297     __ sub_float(dstb, src1b, src2b);
13298   %}
13299 
13300   ins_pipe(faddF_reg_reg); // FIXME
13301 %}
13302 #endif
13303 
13304 
13305 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
13306   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
13307   match(Set dst (SubVF src1 src2));
13308   size(4);
13309   format %{ "VSUB.F32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4F" %}
13310   ins_encode %{
13311     bool quad = true;
13312     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13313              MacroAssembler::VFA_SIZE_F32, quad);
13314   %}
13315   ins_pipe( faddF_reg_reg ); // FIXME
13316 %}
13317 
13318 #ifdef AARCH64
13319 instruct vsub2D_reg_simd(vecX dst, vecX src1, vecX src2) %{
13320   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
13321   match(Set dst (SubVD src1 src2));
13322   size(4);
13323   format %{ "VSUB.F64 $dst.Q,$src1.Q,$src2.Q\t! add packed2D" %}
13324   ins_encode %{
13325     bool quad = true;
13326     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13327              MacroAssembler::VFA_SIZE_F64, quad);
13328   %}
13329   ins_pipe( faddD_reg_reg ); // FIXME
13330 %}
13331 #else
13332 instruct vsub4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
13333   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
13334   match(Set dst (SubVF src1 src2));
13335   size(4*4);
13336   ins_cost(DEFAULT_COST*4); // FIXME
13337 
13338   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
13339             "FSUBS  $dst.b,$src1.b,$src2.b\n\t"
13340             "FSUBS  $dst.c,$src1.c,$src2.c\n\t"
13341             "FSUBS  $dst.d,$src1.d,$src2.d" %}
13342 
13343   ins_encode %{
13344     FloatRegister dsta = $dst$$FloatRegister;
13345     FloatRegister src1a = $src1$$FloatRegister;
13346     FloatRegister src2a = $src2$$FloatRegister;
13347     __ sub_float(dsta, src1a, src2a);
13348     FloatRegister dstb = dsta->successor();
13349     FloatRegister src1b = src1a->successor();
13350     FloatRegister src2b = src2a->successor();
13351     __ sub_float(dstb, src1b, src2b);
13352     FloatRegister dstc = dstb->successor();
13353     FloatRegister src1c = src1b->successor();
13354     FloatRegister src2c = src2b->successor();
13355     __ sub_float(dstc, src1c, src2c);
13356     FloatRegister dstd = dstc->successor();
13357     FloatRegister src1d = src1c->successor();
13358     FloatRegister src2d = src2c->successor();
13359     __ sub_float(dstd, src1d, src2d);
13360   %}
13361 
13362   ins_pipe(faddF_reg_reg); // FIXME
13363 %}
13364 
13365 instruct vsub2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
13366   predicate(n->as_Vector()->length() == 2);
13367   match(Set dst (SubVD src1 src2));
13368   size(4*2);
13369   ins_cost(DEFAULT_COST*2); // FIXME
13370 
13371   format %{ "FSUBD  $dst.a,$src1.a,$src2.a\n\t"
13372             "FSUBD  $dst.b,$src1.b,$src2.b" %}
13373 
13374   ins_encode %{
13375     FloatRegister dsta = $dst$$FloatRegister;
13376     FloatRegister src1a = $src1$$FloatRegister;
13377     FloatRegister src2a = $src2$$FloatRegister;
13378     __ sub_double(dsta, src1a, src2a);
13379     FloatRegister dstb = dsta->successor()->successor();
13380     FloatRegister src1b = src1a->successor()->successor();
13381     FloatRegister src2b = src2a->successor()->successor();
13382     __ sub_double(dstb, src1b, src2b);
13383   %}
13384 
13385   ins_pipe(faddF_reg_reg); // FIXME
13386 %}
13387 #endif
13388 
13389 // Shorts/Chars vector mul
13390 instruct vmul4S_reg(vecD dst, vecD src1, vecD src2) %{
13391   predicate(n->as_Vector()->length() == 4);
13392   match(Set dst (MulVS src1 src2));
13393   size(4);
13394   format %{ "VMUL.I16 $dst,$src1,$src2\t! mul packed4S" %}
13395   ins_encode %{
13396     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13397              MacroAssembler::VELEM_SIZE_16, 0);
13398   %}
13399   ins_pipe( ialu_reg_reg ); // FIXME
13400 %}
13401 
13402 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2) %{
13403   predicate(n->as_Vector()->length() == 8);
13404   match(Set dst (MulVS src1 src2));
13405   size(4);
13406   format %{ "VMUL.I16 $dst.Q,$src1.Q,$src2.Q\t! mul packed8S" %}
13407   ins_encode %{
13408     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13409              MacroAssembler::VELEM_SIZE_16, 1);
13410   %}
13411   ins_pipe( ialu_reg_reg ); // FIXME
13412 %}
13413 
13414 // Integers vector mul
13415 instruct vmul2I_reg(vecD dst, vecD src1, vecD src2) %{
13416   predicate(n->as_Vector()->length() == 2);
13417   match(Set dst (MulVI src1 src2));
13418   size(4);
13419   format %{ "VMUL.I32 $dst,$src1,$src2\t! mul packed2I" %}
13420   ins_encode %{
13421     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13422              MacroAssembler::VELEM_SIZE_32, 0);
13423   %}
13424   ins_pipe( ialu_reg_reg ); // FIXME
13425 %}
13426 
13427 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
13428   predicate(n->as_Vector()->length() == 4);
13429   match(Set dst (MulVI src1 src2));
13430   size(4);
13431   format %{ "VMUL.I32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4I" %}
13432   ins_encode %{
13433     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13434              MacroAssembler::VELEM_SIZE_32, 1);
13435   %}
13436   ins_pipe( ialu_reg_reg ); // FIXME
13437 %}
13438 
13439 // Floats vector mul
13440 instruct vmul2F_reg(vecD dst, vecD src1, vecD src2) %{
13441   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
13442   match(Set dst (MulVF src1 src2));
13443   size(4);
13444   format %{ "VMUL.F32 $dst,$src1,$src2\t! mul packed2F" %}
13445   ins_encode %{
13446     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13447              MacroAssembler::VFA_SIZE_F32, 0);
13448   %}
13449   ins_pipe( fmulF_reg_reg ); // FIXME
13450 %}
13451 
13452 #ifndef AARCH64
13453 instruct vmul2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
13454   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
13455   match(Set dst (MulVF src1 src2));
13456   size(4*2);
13457   ins_cost(DEFAULT_COST*2); // FIXME
13458 
13459   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
13460             "FMULS  $dst.b,$src1.b,$src2.b" %}
13461   ins_encode %{
13462     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
13463     __ mul_float($dst$$FloatRegister->successor(),
13464              $src1$$FloatRegister->successor(),
13465              $src2$$FloatRegister->successor());
13466   %}
13467 
13468   ins_pipe(fmulF_reg_reg); // FIXME
13469 %}
13470 #endif
13471 
13472 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
13473   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
13474   match(Set dst (MulVF src1 src2));
13475   size(4);
13476   format %{ "VMUL.F32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4F" %}
13477   ins_encode %{
13478     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13479              MacroAssembler::VFA_SIZE_F32, 1);
13480   %}
13481   ins_pipe( fmulF_reg_reg ); // FIXME
13482 %}
13483 
13484 #ifndef AARCH64
13485 instruct vmul4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
13486   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
13487   match(Set dst (MulVF src1 src2));
13488   size(4*4);
13489   ins_cost(DEFAULT_COST*4); // FIXME
13490 
13491   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
13492             "FMULS  $dst.b,$src1.b,$src2.b\n\t"
13493             "FMULS  $dst.c,$src1.c,$src2.c\n\t"
13494             "FMULS  $dst.d,$src1.d,$src2.d" %}
13495 
13496   ins_encode %{
13497     FloatRegister dsta = $dst$$FloatRegister;
13498     FloatRegister src1a = $src1$$FloatRegister;
13499     FloatRegister src2a = $src2$$FloatRegister;
13500     __ mul_float(dsta, src1a, src2a);
13501     FloatRegister dstb = dsta->successor();
13502     FloatRegister src1b = src1a->successor();
13503     FloatRegister src2b = src2a->successor();
13504     __ mul_float(dstb, src1b, src2b);
13505     FloatRegister dstc = dstb->successor();
13506     FloatRegister src1c = src1b->successor();
13507     FloatRegister src2c = src2b->successor();
13508     __ mul_float(dstc, src1c, src2c);
13509     FloatRegister dstd = dstc->successor();
13510     FloatRegister src1d = src1c->successor();
13511     FloatRegister src2d = src2c->successor();
13512     __ mul_float(dstd, src1d, src2d);
13513   %}
13514 
13515   ins_pipe(fmulF_reg_reg); // FIXME
13516 %}
13517 #endif
13518 
13519 #ifdef AARCH64
13520 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{
13521   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
13522   match(Set dst (MulVD src1 src2));
13523   size(4*1);
13524   ins_cost(DEFAULT_COST*1); // FIXME
13525 
13526   format %{ "FMUL.2D $dst,$src1,$src2\t! double[2]" %}
13527   ins_encode %{
13528     int quad = 1;
13529     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13530              MacroAssembler::VFA_SIZE_F64, quad);
13531   %}
13532 
13533   ins_pipe(fdivF_reg_reg); // FIXME
13534 %}
13535 #else
13536 instruct vmul2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
13537   predicate(n->as_Vector()->length() == 2);
13538   match(Set dst (MulVD src1 src2));
13539   size(4*2);
13540   ins_cost(DEFAULT_COST*2); // FIXME
13541 
13542   format %{ "FMULD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
13543             "FMULD  $dst.D.b,$src1.D.b,$src2.D.b" %}
13544   ins_encode %{
13545     FloatRegister dsta = $dst$$FloatRegister;
13546     FloatRegister src1a = $src1$$FloatRegister;
13547     FloatRegister src2a = $src2$$FloatRegister;
13548     __ mul_double(dsta, src1a, src2a);
13549     FloatRegister dstb = dsta->successor()->successor();
13550     FloatRegister src1b = src1a->successor()->successor();
13551     FloatRegister src2b = src2a->successor()->successor();
13552     __ mul_double(dstb, src1b, src2b);
13553   %}
13554 
13555   ins_pipe(fmulD_reg_reg); // FIXME
13556 %}
13557 #endif
13558 
13559 
13560 // Floats vector div
13561 instruct vdiv2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
13562   predicate(n->as_Vector()->length() == 2);
13563   match(Set dst (DivVF src1 src2));
13564 #ifdef AARCH64
13565   size(4*1);
13566   ins_cost(DEFAULT_COST*1); // FIXME
13567 
13568   format %{ "FDIV.2S $dst,$src1,$src2\t! float[2]" %}
13569   ins_encode %{
13570     int quad = 0;
13571     __ vdivF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13572              MacroAssembler::VFA_SIZE_F32, quad);
13573   %}
13574 
13575   ins_pipe(fdivF_reg_reg); // FIXME
13576 #else
13577   size(4*2);
13578   ins_cost(DEFAULT_COST*2); // FIXME
13579 
13580   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
13581             "FDIVS  $dst.b,$src1.b,$src2.b" %}
13582   ins_encode %{
13583     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
13584     __ div_float($dst$$FloatRegister->successor(),
13585              $src1$$FloatRegister->successor(),
13586              $src2$$FloatRegister->successor());
13587   %}
13588 
13589   ins_pipe(fdivF_reg_reg); // FIXME
13590 #endif
13591 %}
13592 
13593 instruct vdiv4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
13594   predicate(n->as_Vector()->length() == 4);
13595   match(Set dst (DivVF src1 src2));
13596 #ifdef AARCH64
13597   size(4*1);
13598   ins_cost(DEFAULT_COST*1); // FIXME
13599 
13600   format %{ "FDIV.4S $dst,$src1,$src2\t! float[4]" %}
13601   ins_encode %{
13602     int quad = 1;
13603     __ vdivF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13604              MacroAssembler::VFA_SIZE_F32, quad);
13605   %}
13606 
13607   ins_pipe(fdivF_reg_reg); // FIXME
13608 #else
13609   size(4*4);
13610   ins_cost(DEFAULT_COST*4); // FIXME
13611 
13612   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
13613             "FDIVS  $dst.b,$src1.b,$src2.b\n\t"
13614             "FDIVS  $dst.c,$src1.c,$src2.c\n\t"
13615             "FDIVS  $dst.d,$src1.d,$src2.d" %}
13616 
13617   ins_encode %{
13618     FloatRegister dsta = $dst$$FloatRegister;
13619     FloatRegister src1a = $src1$$FloatRegister;
13620     FloatRegister src2a = $src2$$FloatRegister;
13621     __ div_float(dsta, src1a, src2a);
13622     FloatRegister dstb = dsta->successor();
13623     FloatRegister src1b = src1a->successor();
13624     FloatRegister src2b = src2a->successor();
13625     __ div_float(dstb, src1b, src2b);
13626     FloatRegister dstc = dstb->successor();
13627     FloatRegister src1c = src1b->successor();
13628     FloatRegister src2c = src2b->successor();
13629     __ div_float(dstc, src1c, src2c);
13630     FloatRegister dstd = dstc->successor();
13631     FloatRegister src1d = src1c->successor();
13632     FloatRegister src2d = src2c->successor();
13633     __ div_float(dstd, src1d, src2d);
13634   %}
13635 
13636   ins_pipe(fdivF_reg_reg); // FIXME
13637 #endif
13638 %}
13639 
13640 #ifdef AARCH64
13641 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{
13642   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
13643   match(Set dst (DivVD src1 src2));
13644   size(4*1);
13645   ins_cost(DEFAULT_COST*1); // FIXME
13646 
13647   format %{ "FDIV.2D $dst,$src1,$src2\t! double[2]" %}
13648   ins_encode %{
13649     int quad = 1;
13650     __ vdivF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
13651              MacroAssembler::VFA_SIZE_F64, quad);
13652   %}
13653 
13654   ins_pipe(fdivF_reg_reg); // FIXME
13655 %}
13656 #else
13657 instruct vdiv2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
13658   predicate(n->as_Vector()->length() == 2);
13659   match(Set dst (DivVD src1 src2));
13660   size(4*2);
13661   ins_cost(DEFAULT_COST*2); // FIXME
13662 
13663   format %{ "FDIVD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
13664             "FDIVD  $dst.D.b,$src1.D.b,$src2.D.b" %}
13665   ins_encode %{
13666     FloatRegister dsta = $dst$$FloatRegister;
13667     FloatRegister src1a = $src1$$FloatRegister;
13668     FloatRegister src2a = $src2$$FloatRegister;
13669     __ div_double(dsta, src1a, src2a);
13670     FloatRegister dstb = dsta->successor()->successor();
13671     FloatRegister src1b = src1a->successor()->successor();
13672     FloatRegister src2b = src2a->successor()->successor();
13673     __ div_double(dstb, src1b, src2b);
13674   %}
13675 
13676   ins_pipe(fdivD_reg_reg); // FIXME
13677 %}
13678 #endif
13679 
13680 // --------------------------------- NEG --------------------------------------
13681 
13682 instruct vneg8B_reg(vecD dst, vecD src) %{
13683   predicate(n->as_Vector()->length_in_bytes() == 8);
13684   effect(DEF dst, USE src);
13685   size(4);
13686   ins_cost(DEFAULT_COST); // FIXME
13687   format %{ "VNEG.S8 $dst.D,$src.D\t! neg packed8B" %}
13688   ins_encode %{
13689     bool quad = false;
13690     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
13691               MacroAssembler::VELEM_SIZE_8, quad);
13692   %}
13693   ins_pipe( ialu_reg_reg ); // FIXME
13694 %}
13695 
13696 instruct vneg16B_reg(vecX dst, vecX src) %{
13697   predicate(n->as_Vector()->length_in_bytes() == 16);
13698   effect(DEF dst, USE src);
13699   size(4);
13700   ins_cost(DEFAULT_COST); // FIXME
13701   format %{ "VNEG.S8 $dst.Q,$src.Q\t! neg0 packed16B" %}
13702   ins_encode %{
13703     bool _float = false;
13704     bool quad = true;
13705     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
13706               MacroAssembler::VELEM_SIZE_8, quad);
13707   %}
13708   ins_pipe( ialu_reg_reg ); // FIXME
13709 %}
13710 
13711 // ------------------------------ Shift ---------------------------------------
13712 
13713 instruct vslcntD(vecD dst, iRegI cnt) %{
13714   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
13715   match(Set dst (LShiftCntV cnt));
13716   size(4);
13717   ins_cost(DEFAULT_COST); // FIXME
13718   expand %{
13719     Repl8B_reg_simd(dst, cnt);
13720   %}
13721 %}
13722 
13723 instruct vslcntX(vecX dst, iRegI cnt) %{
13724   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
13725   match(Set dst (LShiftCntV cnt));
13726   size(4);
13727   ins_cost(DEFAULT_COST); // FIXME
13728   expand %{
13729     Repl16B_reg(dst, cnt);
13730   %}
13731 %}
13732 
13733 // Low bits of vector "shift" elements are used, so it
13734 // doesn't matter if we treat it as ints or bytes here.
13735 instruct vsrcntD(vecD dst, iRegI cnt) %{
13736   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
13737   match(Set dst (RShiftCntV cnt));
13738   size(4*2);
13739   ins_cost(DEFAULT_COST*2); // FIXME
13740 
13741   format %{ "VDUP.8 $dst.D,$cnt\n\t"
13742             "VNEG.S8 $dst.D,$dst.D\t! neg packed8B" %}
13743   ins_encode %{
13744     bool quad = false;
13745     __ vdupI($dst$$FloatRegister, $cnt$$Register,
13746              MacroAssembler::VELEM_SIZE_8, quad);
13747     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
13748               MacroAssembler::VELEM_SIZE_8, quad);
13749   %}
13750   ins_pipe( ialu_reg_reg ); // FIXME
13751 %}
13752 
13753 instruct vsrcntX(vecX dst, iRegI cnt) %{
13754   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
13755   match(Set dst (RShiftCntV cnt));
13756   size(4*2);
13757   ins_cost(DEFAULT_COST*2); // FIXME
13758   format %{ "VDUP.8 $dst.Q,$cnt\n\t"
13759             "VNEG.S8 $dst.Q,$dst.Q\t! neg packed16B" %}
13760   ins_encode %{
13761     bool quad = true;
13762     __ vdupI($dst$$FloatRegister, $cnt$$Register,
13763              MacroAssembler::VELEM_SIZE_8, quad);
13764     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
13765               MacroAssembler::VELEM_SIZE_8, quad);
13766   %}
13767   ins_pipe( ialu_reg_reg ); // FIXME
13768 %}
13769 
13770 // Byte vector logical left/right shift based on sign
13771 instruct vsh8B_reg(vecD dst, vecD src, vecD shift) %{
13772   predicate(n->as_Vector()->length() == 8);
13773   effect(DEF dst, USE src, USE shift);
13774   size(4);
13775   ins_cost(DEFAULT_COST); // FIXME
13776   format %{
13777     "VSHL.U8 $dst.D,$src.D,$shift.D\t! logical left/right shift packed8B"
13778   %}
13779   ins_encode %{
13780     bool quad = false;
13781     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
13782               MacroAssembler::VELEM_SIZE_8, quad);
13783   %}
13784   ins_pipe( ialu_reg_reg ); // FIXME
13785 %}
13786 
13787 instruct vsh16B_reg(vecX dst, vecX src, vecX shift) %{
13788   predicate(n->as_Vector()->length() == 16);
13789   effect(DEF dst, USE src, USE shift);
13790   size(4);
13791   ins_cost(DEFAULT_COST); // FIXME
13792   format %{
13793     "VSHL.U8 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed16B"
13794   %}
13795   ins_encode %{
13796     bool quad = true;
13797     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
13798               MacroAssembler::VELEM_SIZE_8, quad);
13799   %}
13800   ins_pipe( ialu_reg_reg ); // FIXME
13801 %}
13802 
13803 // Shorts/Char vector logical left/right shift based on sign
13804 instruct vsh4S_reg(vecD dst, vecD src, vecD shift) %{
13805   predicate(n->as_Vector()->length() == 4);
13806   effect(DEF dst, USE src, USE shift);
13807   size(4);
13808   ins_cost(DEFAULT_COST); // FIXME
13809   format %{
13810     "VSHL.U16 $dst.D,$src.D,$shift.D\t! logical left/right shift packed4S"
13811   %}
13812   ins_encode %{
13813     bool quad = false;
13814     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
13815               MacroAssembler::VELEM_SIZE_16, quad);
13816   %}
13817   ins_pipe( ialu_reg_reg ); // FIXME
13818 %}
13819 
13820 instruct vsh8S_reg(vecX dst, vecX src, vecX shift) %{
13821   predicate(n->as_Vector()->length() == 8);
13822   effect(DEF dst, USE src, USE shift);
13823   size(4);
13824   ins_cost(DEFAULT_COST); // FIXME
13825   format %{
13826     "VSHL.U16 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed8S"
13827   %}
13828   ins_encode %{
13829     bool quad = true;
13830     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
13831               MacroAssembler::VELEM_SIZE_16, quad);
13832   %}
13833   ins_pipe( ialu_reg_reg ); // FIXME
13834 %}
13835 
13836 // Integers vector logical left/right shift based on sign
13837 instruct vsh2I_reg(vecD dst, vecD src, vecD shift) %{
13838   predicate(n->as_Vector()->length() == 2);
13839   effect(DEF dst, USE src, USE shift);
13840   size(4);
13841   ins_cost(DEFAULT_COST); // FIXME
13842   format %{
13843     "VSHL.U32 $dst.D,$src.D,$shift.D\t! logical left/right shift packed2I"
13844   %}
13845   ins_encode %{
13846     bool quad = false;
13847     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
13848               MacroAssembler::VELEM_SIZE_32, quad);
13849   %}
13850   ins_pipe( ialu_reg_reg ); // FIXME
13851 %}
13852 
13853 instruct vsh4I_reg(vecX dst, vecX src, vecX shift) %{
13854   predicate(n->as_Vector()->length() == 4);
13855   effect(DEF dst, USE src, USE shift);
13856   size(4);
13857   ins_cost(DEFAULT_COST); // FIXME
13858   format %{
13859     "VSHL.U32 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed4I"
13860   %}
13861   ins_encode %{
13862     bool quad = true;
13863     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
13864               MacroAssembler::VELEM_SIZE_32, quad);
13865   %}
13866   ins_pipe( ialu_reg_reg ); // FIXME
13867 %}
13868 
13869 // Longs vector logical left/right shift based on sign
13870 instruct vsh2L_reg(vecX dst, vecX src, vecX shift) %{
13871   predicate(n->as_Vector()->length() == 2);
13872   effect(DEF dst, USE src, USE shift);
13873   size(4);
13874   ins_cost(DEFAULT_COST); // FIXME
13875   format %{
13876     "VSHL.U64 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed2L"
13877   %}
13878   ins_encode %{
13879     bool quad = true;
13880     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
13881               MacroAssembler::VELEM_SIZE_64, quad);
13882   %}
13883   ins_pipe( ialu_reg_reg ); // FIXME
13884 %}
13885 
13886 // ------------------------------ LeftShift -----------------------------------
13887 
13888 // Byte vector left shift
13889 instruct vsl8B_reg(vecD dst, vecD src, vecD shift) %{
13890   predicate(n->as_Vector()->length() == 8);
13891   match(Set dst (LShiftVB src shift));
13892   size(4*1);
13893   ins_cost(DEFAULT_COST*1); // FIXME
13894   expand %{
13895     vsh8B_reg(dst, src, shift);
13896   %}
13897 %}
13898 
13899 instruct vsl16B_reg(vecX dst, vecX src, vecX shift) %{
13900   predicate(n->as_Vector()->length() == 16);
13901   match(Set dst (LShiftVB src shift));
13902   size(4*1);
13903   ins_cost(DEFAULT_COST*1); // FIXME
13904   expand %{
13905     vsh16B_reg(dst, src, shift);
13906   %}
13907 %}
13908 
13909 instruct vsl8B_immI(vecD dst, vecD src, immI shift) %{
13910   predicate(n->as_Vector()->length() == 8);
13911   match(Set dst (LShiftVB src shift));
13912   size(4);
13913   ins_cost(DEFAULT_COST); // FIXME
13914   format %{
13915     "VSHL.I8 $dst.D,$src.D,$shift\t! logical left shift packed8B"
13916   %}
13917   ins_encode %{
13918     bool quad = false;
13919     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
13920              quad);
13921   %}
13922   ins_pipe( ialu_reg_reg ); // FIXME
13923 %}
13924 
13925 instruct vsl16B_immI(vecX dst, vecX src, immI shift) %{
13926   predicate(n->as_Vector()->length() == 16);
13927   match(Set dst (LShiftVB src shift));
13928   size(4);
13929   ins_cost(DEFAULT_COST); // FIXME
13930   format %{
13931     "VSHL.I8 $dst.Q,$src.Q,$shift\t! logical left shift packed16B"
13932   %}
13933   ins_encode %{
13934     bool quad = true;
13935     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
13936              quad);
13937   %}
13938   ins_pipe( ialu_reg_reg ); // FIXME
13939 %}
13940 
13941 // Shorts/Chars vector logical left/right shift
13942 instruct vsl4S_reg(vecD dst, vecD src, vecD shift) %{
13943   predicate(n->as_Vector()->length() == 4);
13944   match(Set dst (LShiftVS src shift));
13945   match(Set dst (URShiftVS src shift));
13946   size(4*1);
13947   ins_cost(DEFAULT_COST*1); // FIXME
13948   expand %{
13949     vsh4S_reg(dst, src, shift);
13950   %}
13951 %}
13952 
13953 instruct vsl8S_reg(vecX dst, vecX src, vecX shift) %{
13954   predicate(n->as_Vector()->length() == 8);
13955   match(Set dst (LShiftVS src shift));
13956   match(Set dst (URShiftVS src shift));
13957   size(4*1);
13958   ins_cost(DEFAULT_COST*1); // FIXME
13959   expand %{
13960     vsh8S_reg(dst, src, shift);
13961   %}
13962 %}
13963 
13964 instruct vsl4S_immI(vecD dst, vecD src, immI shift) %{
13965   predicate(n->as_Vector()->length() == 4);
13966   match(Set dst (LShiftVS src shift));
13967   size(4);
13968   ins_cost(DEFAULT_COST); // FIXME
13969   format %{
13970     "VSHL.I16 $dst.D,$src.D,$shift\t! logical left shift packed4S"
13971   %}
13972   ins_encode %{
13973     bool quad = false;
13974     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
13975              quad);
13976   %}
13977   ins_pipe( ialu_reg_reg ); // FIXME
13978 %}
13979 
13980 instruct vsl8S_immI(vecX dst, vecX src, immI shift) %{
13981   predicate(n->as_Vector()->length() == 8);
13982   match(Set dst (LShiftVS src shift));
13983   size(4);
13984   ins_cost(DEFAULT_COST); // FIXME
13985   format %{
13986     "VSHL.I16 $dst.Q,$src.Q,$shift\t! logical left shift packed8S"
13987   %}
13988   ins_encode %{
13989     bool quad = true;
13990     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
13991              quad);
13992   %}
13993   ins_pipe( ialu_reg_reg ); // FIXME
13994 %}
13995 
13996 // Integers vector logical left/right shift
13997 instruct vsl2I_reg(vecD dst, vecD src, vecD shift) %{
13998   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
13999   match(Set dst (LShiftVI src shift));
14000   match(Set dst (URShiftVI src shift));
14001   size(4*1);
14002   ins_cost(DEFAULT_COST*1); // FIXME
14003   expand %{
14004     vsh2I_reg(dst, src, shift);
14005   %}
14006 %}
14007 
14008 instruct vsl4I_reg(vecX dst, vecX src, vecX shift) %{
14009   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
14010   match(Set dst (LShiftVI src shift));
14011   match(Set dst (URShiftVI src shift));
14012   size(4*1);
14013   ins_cost(DEFAULT_COST*1); // FIXME
14014   expand %{
14015     vsh4I_reg(dst, src, shift);
14016   %}
14017 %}
14018 
14019 instruct vsl2I_immI(vecD dst, vecD src, immI shift) %{
14020   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
14021   match(Set dst (LShiftVI src shift));
14022   size(4);
14023   ins_cost(DEFAULT_COST); // FIXME
14024   format %{
14025     "VSHL.I32 $dst.D,$src.D,$shift\t! logical left shift packed2I"
14026   %}
14027   ins_encode %{
14028     bool quad = false;
14029     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
14030              quad);
14031   %}
14032   ins_pipe( ialu_reg_reg ); // FIXME
14033 %}
14034 
14035 instruct vsl4I_immI(vecX dst, vecX src, immI shift) %{
14036   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
14037   match(Set dst (LShiftVI src shift));
14038   size(4);
14039   ins_cost(DEFAULT_COST); // FIXME
14040   format %{
14041     "VSHL.I32 $dst.Q,$src.Q,$shift\t! logical left shift packed4I"
14042   %}
14043   ins_encode %{
14044     bool quad = true;
14045     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
14046              quad);
14047   %}
14048   ins_pipe( ialu_reg_reg ); // FIXME
14049 %}
14050 
14051 // Longs vector logical left/right shift
14052 instruct vsl2L_reg(vecX dst, vecX src, vecX shift) %{
14053   predicate(n->as_Vector()->length() == 2);
14054   match(Set dst (LShiftVL src shift));
14055   match(Set dst (URShiftVL src shift));
14056   size(4*1);
14057   ins_cost(DEFAULT_COST*1); // FIXME
14058   expand %{
14059     vsh2L_reg(dst, src, shift);
14060   %}
14061 %}
14062 
14063 instruct vsl2L_immI(vecX dst, vecX src, immI shift) %{
14064   predicate(n->as_Vector()->length() == 2);
14065   match(Set dst (LShiftVL src shift));
14066   size(4);
14067   ins_cost(DEFAULT_COST); // FIXME
14068   format %{
14069     "VSHL.I64 $dst.Q,$src.Q,$shift\t! logical left shift packed2L"
14070   %}
14071   ins_encode %{
14072     bool quad = true;
14073     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
14074              quad);
14075   %}
14076   ins_pipe( ialu_reg_reg ); // FIXME
14077 %}
14078 
14079 // ----------------------- LogicalRightShift -----------------------------------
14080 
14081 // Bytes/Shorts vector logical right shift produces incorrect Java result
14082 // for negative data because java code convert short value into int with
14083 // sign extension before a shift.
14084 
14085 // Chars vector logical right shift
14086 instruct vsrl4S_immI(vecD dst, vecD src, immI shift) %{
14087   predicate(n->as_Vector()->length() == 4);
14088   match(Set dst (URShiftVS src shift));
14089   size(4);
14090   ins_cost(DEFAULT_COST); // FIXME
14091   format %{
14092     "VSHR.U16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
14093   %}
14094   ins_encode %{
14095     bool quad = false;
14096     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
14097              quad);
14098   %}
14099   ins_pipe( ialu_reg_reg ); // FIXME
14100 %}
14101 
14102 instruct vsrl8S_immI(vecX dst, vecX src, immI shift) %{
14103   predicate(n->as_Vector()->length() == 8);
14104   match(Set dst (URShiftVS src shift));
14105   size(4);
14106   ins_cost(DEFAULT_COST); // FIXME
14107   format %{
14108     "VSHR.U16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
14109   %}
14110   ins_encode %{
14111     bool quad = true;
14112     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
14113              quad);
14114   %}
14115   ins_pipe( ialu_reg_reg ); // FIXME
14116 %}
14117 
14118 // Integers vector logical right shift
14119 instruct vsrl2I_immI(vecD dst, vecD src, immI shift) %{
14120   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
14121   match(Set dst (URShiftVI src shift));
14122   size(4);
14123   ins_cost(DEFAULT_COST); // FIXME
14124   format %{
14125     "VSHR.U32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
14126   %}
14127   ins_encode %{
14128     bool quad = false;
14129     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
14130              quad);
14131   %}
14132   ins_pipe( ialu_reg_reg ); // FIXME
14133 %}
14134 
14135 instruct vsrl4I_immI(vecX dst, vecX src, immI shift) %{
14136   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
14137   match(Set dst (URShiftVI src shift));
14138   size(4);
14139   ins_cost(DEFAULT_COST); // FIXME
14140   format %{
14141     "VSHR.U32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
14142   %}
14143   ins_encode %{
14144     bool quad = true;
14145     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
14146              quad);
14147   %}
14148   ins_pipe( ialu_reg_reg ); // FIXME
14149 %}
14150 
14151 // Longs vector logical right shift
14152 instruct vsrl2L_immI(vecX dst, vecX src, immI shift) %{
14153   predicate(n->as_Vector()->length() == 2);
14154   match(Set dst (URShiftVL src shift));
14155   size(4);
14156   ins_cost(DEFAULT_COST); // FIXME
14157   format %{
14158     "VSHR.U64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
14159   %}
14160   ins_encode %{
14161     bool quad = true;
14162     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
14163              quad);
14164   %}
14165   ins_pipe( ialu_reg_reg ); // FIXME
14166 %}
14167 
14168 // ------------------- ArithmeticRightShift -----------------------------------
14169 
14170 // Bytes vector arithmetic left/right shift based on sign
14171 instruct vsha8B_reg(vecD dst, vecD src, vecD shift) %{
14172   predicate(n->as_Vector()->length() == 8);
14173   effect(DEF dst, USE src, USE shift);
14174   size(4);
14175   ins_cost(DEFAULT_COST); // FIXME
14176   format %{
14177     "VSHL.S8 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed8B"
14178   %}
14179   ins_encode %{
14180     bool quad = false;
14181     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
14182               MacroAssembler::VELEM_SIZE_8, quad);
14183   %}
14184   ins_pipe( ialu_reg_reg ); // FIXME
14185 %}
14186 
14187 instruct vsha16B_reg(vecX dst, vecX src, vecX shift) %{
14188   predicate(n->as_Vector()->length() == 16);
14189   effect(DEF dst, USE src, USE shift);
14190   size(4);
14191   ins_cost(DEFAULT_COST); // FIXME
14192   format %{
14193     "VSHL.S8 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed16B"
14194   %}
14195   ins_encode %{
14196     bool quad = true;
14197     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
14198               MacroAssembler::VELEM_SIZE_8, quad);
14199   %}
14200   ins_pipe( ialu_reg_reg ); // FIXME
14201 %}
14202 
14203 // Shorts vector arithmetic left/right shift based on sign
14204 instruct vsha4S_reg(vecD dst, vecD src, vecD shift) %{
14205   predicate(n->as_Vector()->length() == 4);
14206   effect(DEF dst, USE src, USE shift);
14207   size(4);
14208   ins_cost(DEFAULT_COST); // FIXME
14209   format %{
14210     "VSHL.S16 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed4S"
14211   %}
14212   ins_encode %{
14213     bool quad = false;
14214     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
14215               MacroAssembler::VELEM_SIZE_16, quad);
14216   %}
14217   ins_pipe( ialu_reg_reg ); // FIXME
14218 %}
14219 
14220 instruct vsha8S_reg(vecX dst, vecX src, vecX shift) %{
14221   predicate(n->as_Vector()->length() == 8);
14222   effect(DEF dst, USE src, USE shift);
14223   size(4);
14224   ins_cost(DEFAULT_COST); // FIXME
14225   format %{
14226     "VSHL.S16 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed8S"
14227   %}
14228   ins_encode %{
14229     bool quad = true;
14230     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
14231               MacroAssembler::VELEM_SIZE_16, quad);
14232   %}
14233   ins_pipe( ialu_reg_reg ); // FIXME
14234 %}
14235 
14236 // Integers vector arithmetic left/right shift based on sign
14237 instruct vsha2I_reg(vecD dst, vecD src, vecD shift) %{
14238   predicate(n->as_Vector()->length() == 2);
14239   effect(DEF dst, USE src, USE shift);
14240   size(4);
14241   ins_cost(DEFAULT_COST); // FIXME
14242   format %{
14243     "VSHL.S32 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed2I"
14244   %}
14245   ins_encode %{
14246     bool quad = false;
14247     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
14248               MacroAssembler::VELEM_SIZE_32, quad);
14249   %}
14250   ins_pipe( ialu_reg_reg ); // FIXME
14251 %}
14252 
14253 instruct vsha4I_reg(vecX dst, vecX src, vecX shift) %{
14254   predicate(n->as_Vector()->length() == 4);
14255   effect(DEF dst, USE src, USE shift);
14256   size(4);
14257   ins_cost(DEFAULT_COST); // FIXME
14258   format %{
14259     "VSHL.S32 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed4I"
14260   %}
14261   ins_encode %{
14262     bool quad = true;
14263     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
14264               MacroAssembler::VELEM_SIZE_32, quad);
14265   %}
14266   ins_pipe( ialu_reg_reg ); // FIXME
14267 %}
14268 
14269 // Longs vector arithmetic left/right shift based on sign
14270 instruct vsha2L_reg(vecX dst, vecX src, vecX shift) %{
14271   predicate(n->as_Vector()->length() == 2);
14272   effect(DEF dst, USE src, USE shift);
14273   size(4);
14274   ins_cost(DEFAULT_COST); // FIXME
14275   format %{
14276     "VSHL.S64 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed2L"
14277   %}
14278   ins_encode %{
14279     bool quad = true;
14280     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
14281               MacroAssembler::VELEM_SIZE_64, quad);
14282   %}
14283   ins_pipe( ialu_reg_reg ); // FIXME
14284 %}
14285 
14286 // Byte vector arithmetic right shift
14287 
14288 instruct vsra8B_reg(vecD dst, vecD src, vecD shift) %{
14289   predicate(n->as_Vector()->length() == 8);
14290   match(Set dst (RShiftVB src shift));
14291   size(4);
14292   ins_cost(DEFAULT_COST); // FIXME
14293   expand %{
14294     vsha8B_reg(dst, src, shift);
14295   %}
14296 %}
14297 
14298 instruct vsrl16B_reg(vecX dst, vecX src, vecX shift) %{
14299   predicate(n->as_Vector()->length() == 16);
14300   match(Set dst (RShiftVB src shift));
14301   size(4);
14302   ins_cost(DEFAULT_COST); // FIXME
14303   expand %{
14304     vsha16B_reg(dst, src, shift);
14305   %}
14306 %}
14307 
14308 instruct vsrl8B_immI(vecD dst, vecD src, immI shift) %{
14309   predicate(n->as_Vector()->length() == 8);
14310   match(Set dst (RShiftVB src shift));
14311   size(4);
14312   ins_cost(DEFAULT_COST); // FIXME
14313   format %{
14314     "VSHR.S8 $dst.D,$src.D,$shift\t! logical right shift packed8B"
14315   %}
14316   ins_encode %{
14317     bool quad = false;
14318     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
14319              quad);
14320   %}
14321   ins_pipe( ialu_reg_reg ); // FIXME
14322 %}
14323 
14324 instruct vsrl16B_immI(vecX dst, vecX src, immI shift) %{
14325   predicate(n->as_Vector()->length() == 16);
14326   match(Set dst (RShiftVB src shift));
14327   size(4);
14328   ins_cost(DEFAULT_COST); // FIXME
14329   format %{
14330     "VSHR.S8 $dst.Q,$src.Q,$shift\t! logical right shift packed16B"
14331   %}
14332   ins_encode %{
14333     bool quad = true;
14334     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
14335              quad);
14336   %}
14337   ins_pipe( ialu_reg_reg ); // FIXME
14338 %}
14339 
14340 // Shorts vector arithmetic right shift
14341 instruct vsra4S_reg(vecD dst, vecD src, vecD shift) %{
14342   predicate(n->as_Vector()->length() == 4);
14343   match(Set dst (RShiftVS src shift));
14344   size(4);
14345   ins_cost(DEFAULT_COST); // FIXME
14346   expand %{
14347     vsha4S_reg(dst, src, shift);
14348   %}
14349 %}
14350 
14351 instruct vsra8S_reg(vecX dst, vecX src, vecX shift) %{
14352   predicate(n->as_Vector()->length() == 8);
14353   match(Set dst (RShiftVS src shift));
14354   size(4);
14355   ins_cost(DEFAULT_COST); // FIXME
14356   expand %{
14357     vsha8S_reg(dst, src, shift);
14358   %}
14359 %}
14360 
14361 instruct vsra4S_immI(vecD dst, vecD src, immI shift) %{
14362   predicate(n->as_Vector()->length() == 4);
14363   match(Set dst (RShiftVS src shift));
14364   size(4);
14365   ins_cost(DEFAULT_COST); // FIXME
14366   format %{
14367     "VSHR.S16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
14368   %}
14369   ins_encode %{
14370     bool quad = false;
14371     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
14372              quad);
14373   %}
14374   ins_pipe( ialu_reg_reg ); // FIXME
14375 %}
14376 
14377 instruct vsra8S_immI(vecX dst, vecX src, immI shift) %{
14378   predicate(n->as_Vector()->length() == 8);
14379   match(Set dst (RShiftVS src shift));
14380   size(4);
14381   ins_cost(DEFAULT_COST); // FIXME
14382   format %{
14383     "VSHR.S16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
14384   %}
14385   ins_encode %{
14386     bool quad = true;
14387     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
14388              quad);
14389   %}
14390   ins_pipe( ialu_reg_reg ); // FIXME
14391 %}
14392 
14393 // Integers vector arithmetic right shift
14394 instruct vsra2I_reg(vecD dst, vecD src, vecD shift) %{
14395   predicate(n->as_Vector()->length() == 2);
14396   match(Set dst (RShiftVI src shift));
14397   size(4);
14398   ins_cost(DEFAULT_COST); // FIXME
14399   expand %{
14400     vsha2I_reg(dst, src, shift);
14401   %}
14402 %}
14403 
14404 instruct vsra4I_reg(vecX dst, vecX src, vecX shift) %{
14405   predicate(n->as_Vector()->length() == 4);
14406   match(Set dst (RShiftVI src shift));
14407   size(4);
14408   ins_cost(DEFAULT_COST); // FIXME
14409   expand %{
14410     vsha4I_reg(dst, src, shift);
14411   %}
14412 %}
14413 
14414 instruct vsra2I_immI(vecD dst, vecD src, immI shift) %{
14415   predicate(n->as_Vector()->length() == 2);
14416   match(Set dst (RShiftVI src shift));
14417   size(4);
14418   ins_cost(DEFAULT_COST); // FIXME
14419   format %{
14420     "VSHR.S32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
14421   %}
14422   ins_encode %{
14423     bool quad = false;
14424     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
14425              quad);
14426   %}
14427   ins_pipe( ialu_reg_reg ); // FIXME
14428 %}
14429 
14430 instruct vsra4I_immI(vecX dst, vecX src, immI shift) %{
14431   predicate(n->as_Vector()->length() == 4);
14432   match(Set dst (RShiftVI src shift));
14433   size(4);
14434   ins_cost(DEFAULT_COST); // FIXME
14435   format %{
14436     "VSHR.S32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
14437   %}
14438   ins_encode %{
14439     bool quad = true;
14440     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
14441              quad);
14442   %}
14443   ins_pipe( ialu_reg_reg ); // FIXME
14444 %}
14445 
14446 // Longs vector arithmetic right shift
14447 instruct vsra2L_reg(vecX dst, vecX src, vecX shift) %{
14448   predicate(n->as_Vector()->length() == 2);
14449   match(Set dst (RShiftVL src shift));
14450   size(4);
14451   ins_cost(DEFAULT_COST); // FIXME
14452   expand %{
14453     vsha2L_reg(dst, src, shift);
14454   %}
14455 %}
14456 
14457 instruct vsra2L_immI(vecX dst, vecX src, immI shift) %{
14458   predicate(n->as_Vector()->length() == 2);
14459   match(Set dst (RShiftVL src shift));
14460   size(4);
14461   ins_cost(DEFAULT_COST); // FIXME
14462   format %{
14463     "VSHR.S64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
14464   %}
14465   ins_encode %{
14466     bool quad = true;
14467     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
14468              quad);
14469   %}
14470   ins_pipe( ialu_reg_reg ); // FIXME
14471 %}
14472 
14473 // --------------------------------- AND --------------------------------------
14474 
14475 instruct vandD(vecD dst, vecD src1, vecD src2) %{
14476   predicate(n->as_Vector()->length_in_bytes() == 8);
14477   match(Set dst (AndV src1 src2));
14478   format %{ "VAND    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
14479   ins_encode %{
14480     bool quad = false;
14481     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
14482              quad);
14483   %}
14484   ins_pipe( ialu_reg_reg ); // FIXME
14485 %}
14486 
14487 instruct vandX(vecX dst, vecX src1, vecX src2) %{
14488   predicate(n->as_Vector()->length_in_bytes() == 16);
14489   match(Set dst (AndV src1 src2));
14490   format %{ "VAND    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
14491   ins_encode %{
14492     bool quad = true;
14493     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
14494              quad);
14495   %}
14496   ins_pipe( ialu_reg_reg ); // FIXME
14497 %}
14498 
14499 // --------------------------------- OR ---------------------------------------
14500 
14501 instruct vorD(vecD dst, vecD src1, vecD src2) %{
14502   predicate(n->as_Vector()->length_in_bytes() == 8);
14503   match(Set dst (OrV src1 src2));
14504   format %{ "VOR     $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
14505   ins_encode %{
14506     bool quad = false;
14507     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
14508             quad);
14509   %}
14510   ins_pipe( ialu_reg_reg ); // FIXME
14511 %}
14512 
14513 instruct vorX(vecX dst, vecX src1, vecX src2) %{
14514   predicate(n->as_Vector()->length_in_bytes() == 16);
14515   match(Set dst (OrV src1 src2));
14516   format %{ "VOR     $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
14517   ins_encode %{
14518     bool quad = true;
14519     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
14520             quad);
14521   %}
14522   ins_pipe( ialu_reg_reg ); // FIXME
14523 %}
14524 
14525 // --------------------------------- XOR --------------------------------------
14526 
14527 instruct vxorD(vecD dst, vecD src1, vecD src2) %{
14528   predicate(n->as_Vector()->length_in_bytes() == 8);
14529   match(Set dst (XorV src1 src2));
14530   format %{ "VXOR    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
14531   ins_encode %{
14532     bool quad = false;
14533     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
14534              quad);
14535   %}
14536   ins_pipe( ialu_reg_reg ); // FIXME
14537 %}
14538 
14539 instruct vxorX(vecX dst, vecX src1, vecX src2) %{
14540   predicate(n->as_Vector()->length_in_bytes() == 16);
14541   match(Set dst (XorV src1 src2));
14542   format %{ "VXOR    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
14543   ins_encode %{
14544     bool quad = true;
14545     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
14546              quad);
14547   %}
14548   ins_pipe( ialu_reg_reg ); // FIXME
14549 %}
14550 
14551 
14552 //----------PEEPHOLE RULES-----------------------------------------------------
14553 // These must follow all instruction definitions as they use the names
14554 // defined in the instructions definitions.
14555 //
14556 // peepmatch ( root_instr_name [preceding_instruction]* );
14557 //
14558 // peepconstraint %{
14559 // (instruction_number.operand_name relational_op instruction_number.operand_name
14560 //  [, ...] );
14561 // // instruction numbers are zero-based using left to right order in peepmatch
14562 //
14563 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
14564 // // provide an instruction_number.operand_name for each operand that appears
14565 // // in the replacement instruction's match rule
14566 //
14567 // ---------VM FLAGS---------------------------------------------------------
14568 //
14569 // All peephole optimizations can be turned off using -XX:-OptoPeephole
14570 //
14571 // Each peephole rule is given an identifying number starting with zero and
14572 // increasing by one in the order seen by the parser.  An individual peephole
14573 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
14574 // on the command-line.
14575 //
14576 // ---------CURRENT LIMITATIONS----------------------------------------------
14577 //
14578 // Only match adjacent instructions in same basic block
14579 // Only equality constraints
14580 // Only constraints between operands, not (0.dest_reg == EAX_enc)
14581 // Only one replacement instruction
14582 //
14583 // ---------EXAMPLE----------------------------------------------------------
14584 //
14585 // // pertinent parts of existing instructions in architecture description
14586 // instruct movI(eRegI dst, eRegI src) %{
14587 //   match(Set dst (CopyI src));
14588 // %}
14589 //
14590 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
14591 //   match(Set dst (AddI dst src));
14592 //   effect(KILL cr);
14593 // %}
14594 //
14595 // // Change (inc mov) to lea
14596 // peephole %{
14597 //   // increment preceeded by register-register move
14598 //   peepmatch ( incI_eReg movI );
14599 //   // require that the destination register of the increment
14600 //   // match the destination register of the move
14601 //   peepconstraint ( 0.dst == 1.dst );
14602 //   // construct a replacement instruction that sets
14603 //   // the destination to ( move's source register + one )
14604 //   peepreplace ( incI_eReg_immI1( 0.dst 1.src 0.src ) );
14605 // %}
14606 //
14607 
14608 // // Change load of spilled value to only a spill
14609 // instruct storeI(memory mem, eRegI src) %{
14610 //   match(Set mem (StoreI mem src));
14611 // %}
14612 //
14613 // instruct loadI(eRegI dst, memory mem) %{
14614 //   match(Set dst (LoadI mem));
14615 // %}
14616 //
14617 // peephole %{
14618 //   peepmatch ( loadI storeI );
14619 //   peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14620 //   peepreplace ( storeI( 1.mem 1.mem 1.src ) );
14621 // %}
14622 
14623 //----------SMARTSPILL RULES---------------------------------------------------
14624 // These must follow all instruction definitions as they use the names
14625 // defined in the instructions definitions.
14626 //
14627 // ARM will probably not have any of these rules due to RISC instruction set.
14628 
14629 //----------PIPELINE-----------------------------------------------------------
14630 // Rules which define the behavior of the target architectures pipeline.