1 //
    2 // Copyright (c) 2008, 2026, 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 #include "asm/macroAssembler.hpp"
   63 #include "gc/shared/barrierSetAssembler.hpp"
   64 
   65 // Does destination need to be loaded in a register then passed to a
   66 // branch instruction?
   67 extern bool maybe_far_call(const CallNode *n);
   68 extern bool maybe_far_call(const MachCallNode *n);
   69 static inline bool cache_reachable() {
   70   return MacroAssembler::_cache_fully_reachable();
   71 }
   72 
   73 #define ldr_32 ldr
   74 #define str_32 str
   75 #define tst_32 tst
   76 #define teq_32 teq
   77 #if 1
   78 extern bool PrintOptoAssembly;
   79 #endif
   80 
   81 class c2 {
   82 public:
   83   static OptoRegPair return_value(int ideal_reg);
   84 };
   85 
   86 class CallStubImpl {
   87 
   88   //--------------------------------------------------------------
   89   //---<  Used for optimization in Compile::Shorten_branches  >---
   90   //--------------------------------------------------------------
   91 
   92  public:
   93   // Size of call trampoline stub.
   94   static uint size_call_trampoline() {
   95     return 0; // no call trampolines on this platform
   96   }
   97 
   98   // number of relocations needed by a call trampoline stub
   99   static uint reloc_call_trampoline() {
  100     return 0; // no call trampolines on this platform
  101   }
  102 };
  103 
  104 class HandlerImpl {
  105 
  106  public:
  107 
  108   static int emit_deopt_handler(C2_MacroAssembler* masm);
  109 
  110   static uint size_deopt_handler() {
  111     return ( 9 * 4 );
  112   }
  113 
  114 };
  115 
  116 class Node::PD {
  117 public:
  118   enum NodeFlags {
  119     _last_flag = Node::_last_flag
  120   };
  121 };
  122 
  123 // Assert that the given node is not a var shift.
  124 bool assert_not_var_shift(const Node *n);
  125 %}
  126 
  127 source %{
  128 
  129 // Assert that the given node is not a var shift.
  130 bool assert_not_var_shift(const Node *n) {
  131   assert(!n->as_ShiftV()->is_var_shift(), "illegal var shift");
  132   return true;
  133 }
  134 
  135 #define __ masm->
  136 
  137 static FloatRegister reg_to_FloatRegister_object(int register_encoding);
  138 static Register reg_to_register_object(int register_encoding);
  139 
  140 void PhaseOutput::pd_perform_mach_node_analysis() {
  141 }
  142 
  143 int MachNode::pd_alignment_required() const {
  144   return 1;
  145 }
  146 
  147 int MachNode::compute_padding(int current_offset) const {
  148   return 0;
  149 }
  150 
  151 // ****************************************************************************
  152 
  153 // REQUIRED FUNCTIONALITY
  154 
  155 // emit an interrupt that is caught by the debugger (for debugging compiler)
  156 void emit_break(C2_MacroAssembler *masm) {
  157   __ breakpoint();
  158 }
  159 
  160 #ifndef PRODUCT
  161 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream *st ) const {
  162   st->print("TA");
  163 }
  164 #endif
  165 
  166 void MachBreakpointNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
  167   emit_break(masm);
  168 }
  169 
  170 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
  171   return MachNode::size(ra_);
  172 }
  173 
  174 
  175 void emit_nop(C2_MacroAssembler *masm) {
  176   __ nop();
  177 }
  178 
  179 
  180 void emit_call_reloc(C2_MacroAssembler *masm, const MachCallNode *n, MachOper *m, RelocationHolder const& rspec) {
  181   int ret_addr_offset0 = n->as_MachCall()->ret_addr_offset();
  182   int call_site_offset = __ code()->insts()->mark_off();
  183   __ set_inst_mark(); // needed in emit_to_interp_stub() to locate the call
  184   address target = (address)m->method();
  185   assert(n->as_MachCall()->entry_point() == target, "sanity");
  186   assert(maybe_far_call(n) == !__ reachable_from_cache(target), "sanity");
  187   assert(cache_reachable() == __ cache_fully_reachable(), "sanity");
  188 
  189   assert(target != nullptr, "need real address");
  190 
  191   int ret_addr_offset = -1;
  192   if (rspec.type() == relocInfo::runtime_call_type) {
  193     __ call(target, rspec);
  194     ret_addr_offset = __ offset();
  195   } else {
  196     // scratches Rtemp
  197     ret_addr_offset = __ patchable_call(target, rspec, true);
  198   }
  199   assert(ret_addr_offset - call_site_offset == ret_addr_offset0, "fix ret_addr_offset()");
  200 }
  201 
  202 //=============================================================================
  203 // REQUIRED FUNCTIONALITY for encoding
  204 void emit_lo(C2_MacroAssembler *masm, int val) {  }
  205 void emit_hi(C2_MacroAssembler *masm, int val) {  }
  206 
  207 
  208 //=============================================================================
  209 const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask();
  210 
  211 int ConstantTable::calculate_table_base_offset() const {
  212   int offset = -(size() / 2);
  213   // flds, fldd: 8-bit  offset multiplied by 4: +/- 1024
  214   // ldr, ldrb : 12-bit offset:                 +/- 4096
  215   if (!Assembler::is_simm10(offset)) {
  216     offset = Assembler::min_simm10;
  217   }
  218   return offset;
  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(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const {
  227   Compile* C = ra_->C;
  228   ConstantTable& constant_table = C->output()->constant_table();
  229 
  230   Register r = as_Register(ra_->get_encode(this));
  231   CodeSection* consts_section = __ code()->consts();
  232   CodeSection* insts_section = __ code()->insts();
  233   // constants section size is aligned according to the align_at_start settings of the next section
  234   int consts_size = insts_section->align_at_start(consts_section->size());
  235   assert(constant_table.size() == consts_size, "must be: %d == %d", constant_table.size(), consts_size);
  236 
  237   // Materialize the constant table base.
  238   address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
  239   RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
  240   __ mov_address(r, baseaddr, rspec);
  241 }
  242 
  243 uint MachConstantBaseNode::size(PhaseRegAlloc*) const {
  244   return 8;
  245 }
  246 
  247 #ifndef PRODUCT
  248 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
  249   char reg[128];
  250   ra_->dump_register(this, reg, sizeof(reg));
  251   st->print("MOV_SLOW    &constanttable,%s\t! constant table base", reg);
  252 }
  253 #endif
  254 
  255 #ifndef PRODUCT
  256 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  257   Compile* C = ra_->C;
  258 
  259   for (int i = 0; i < OptoPrologueNops; i++) {
  260     st->print_cr("NOP"); st->print("\t");
  261   }
  262 
  263   size_t framesize = C->output()->frame_size_in_bytes();
  264   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  265   int bangsize = C->output()->bang_size_in_bytes();
  266   // Remove two words for return addr and rbp,
  267   framesize -= 2*wordSize;
  268   bangsize -= 2*wordSize;
  269 
  270   // Calls to C2R adapters often do not accept exceptional returns.
  271   // We require that their callers must bang for them.  But be careful, because
  272   // some VM calls (such as call site linkage) can use several kilobytes of
  273   // stack.  But the stack safety zone should account for that.
  274   // See bugs 4446381, 4468289, 4497237.
  275   if (C->output()->need_stack_bang(bangsize)) {
  276     st->print_cr("! stack bang (%d bytes)", bangsize); st->print("\t");
  277   }
  278   st->print_cr("PUSH   R_FP|R_LR_LR"); st->print("\t");
  279   if (framesize != 0) {
  280     st->print   ("SUB    R_SP, R_SP, %zu", framesize);
  281   }
  282 
  283   if (C->stub_function() == nullptr) {
  284     st->print("ldr t0, [guard]\n\t");
  285     st->print("ldr t1, [Rthread, #thread_disarmed_guard_value_offset]\n\t");
  286     st->print("cmp t0, t1\n\t");
  287     st->print("beq skip\n\t");
  288     st->print("blr #nmethod_entry_barrier_stub\n\t");
  289     st->print("b skip\n\t");
  290     st->print("guard: int\n\t");
  291     st->print("skip:\n\t");
  292   }
  293 }
  294 #endif
  295 
  296 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
  297   Compile* C = ra_->C;
  298 
  299   for (int i = 0; i < OptoPrologueNops; i++) {
  300     __ nop();
  301   }
  302 
  303   size_t framesize = C->output()->frame_size_in_bytes();
  304   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  305   int bangsize = C->output()->bang_size_in_bytes();
  306   // Remove two words for return addr and fp,
  307   framesize -= 2*wordSize;
  308   bangsize -= 2*wordSize;
  309 
  310   // Calls to C2R adapters often do not accept exceptional returns.
  311   // We require that their callers must bang for them.  But be careful, because
  312   // some VM calls (such as call site linkage) can use several kilobytes of
  313   // stack.  But the stack safety zone should account for that.
  314   // See bugs 4446381, 4468289, 4497237.
  315   if (C->output()->need_stack_bang(bangsize)) {
  316     __ arm_stack_overflow_check(bangsize, Rtemp);
  317   }
  318 
  319   __ raw_push(FP, LR);
  320   if (framesize != 0) {
  321     __ sub_slow(SP, SP, framesize);
  322   }
  323 
  324   if (C->stub_function() == nullptr) {
  325     BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
  326     bs->nmethod_entry_barrier(masm);
  327   }
  328 
  329   // offset from scratch buffer is not valid
  330   if (strcmp(__ code()->name(), "Compile::Fill_buffer") == 0) {
  331     C->output()->set_frame_complete( __ offset() );
  332   }
  333 
  334   if (C->has_mach_constant_base_node()) {
  335     // NOTE: We set the table base offset here because users might be
  336     // emitted before MachConstantBaseNode.
  337     ConstantTable& constant_table = C->output()->constant_table();
  338     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
  339   }
  340 }
  341 
  342 int MachPrologNode::reloc() const {
  343   return 10; // a large enough number
  344 }
  345 
  346 //=============================================================================
  347 #ifndef PRODUCT
  348 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  349   Compile* C = ra_->C;
  350 
  351   size_t framesize = C->output()->frame_size_in_bytes();
  352   framesize -= 2*wordSize;
  353 
  354   if (framesize != 0) {
  355     st->print("ADD    R_SP, R_SP, %zu\n\t",framesize);
  356   }
  357   st->print("POP    R_FP|R_LR_LR");
  358 
  359   if (do_polling() && ra_->C->is_method_compilation()) {
  360     st->print("\n\t");
  361     st->print("MOV    Rtemp, #PollAddr\t! Load Polling address\n\t");
  362     st->print("LDR    Rtemp,[Rtemp]\t!Poll for Safepointing");
  363   }
  364 }
  365 #endif
  366 
  367 void MachEpilogNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
  368   Compile* C = ra_->C;
  369 
  370   size_t framesize = C->output()->frame_size_in_bytes();
  371   framesize -= 2*wordSize;
  372   if (framesize != 0) {
  373     __ add_slow(SP, SP, framesize);
  374   }
  375   __ raw_pop(FP, LR);
  376 
  377   // If this does safepoint polling, then do it here
  378   if (do_polling() && ra_->C->is_method_compilation()) {
  379     __ read_polling_page(Rtemp, relocInfo::poll_return_type);
  380   }
  381 }
  382 
  383 int MachEpilogNode::reloc() const {
  384   return 16; // a large enough number
  385 }
  386 
  387 const Pipeline * MachEpilogNode::pipeline() const {
  388   return MachNode::pipeline_class();
  389 }
  390 
  391 //=============================================================================
  392 
  393 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
  394 enum RC { rc_bad, rc_int, rc_float, rc_stack };
  395 static enum RC rc_class( OptoReg::Name reg ) {
  396   if (!OptoReg::is_valid(reg)) return rc_bad;
  397   if (OptoReg::is_stack(reg)) return rc_stack;
  398   VMReg r = OptoReg::as_VMReg(reg);
  399   if (r->is_Register()) return rc_int;
  400   assert(r->is_FloatRegister(), "must be");
  401   return rc_float;
  402 }
  403 
  404 static inline bool is_iRegLd_memhd(OptoReg::Name src_first, OptoReg::Name src_second, int offset) {
  405   int rlo = Matcher::_regEncode[src_first];
  406   int rhi = Matcher::_regEncode[src_second];
  407   if (!((rlo&1)==0 && (rlo+1 == rhi))) {
  408     tty->print_cr("CAUGHT BAD LDRD/STRD");
  409   }
  410   return (rlo&1)==0 && (rlo+1 == rhi) && is_memoryHD(offset);
  411 }
  412 
  413 uint MachSpillCopyNode::implementation( C2_MacroAssembler *masm,
  414                                         PhaseRegAlloc *ra_,
  415                                         bool do_size,
  416                                         outputStream* st ) const {
  417   // Get registers to move
  418   OptoReg::Name src_second = ra_->get_reg_second(in(1));
  419   OptoReg::Name src_first = ra_->get_reg_first(in(1));
  420   OptoReg::Name dst_second = ra_->get_reg_second(this );
  421   OptoReg::Name dst_first = ra_->get_reg_first(this );
  422 
  423   enum RC src_second_rc = rc_class(src_second);
  424   enum RC src_first_rc = rc_class(src_first);
  425   enum RC dst_second_rc = rc_class(dst_second);
  426   enum RC dst_first_rc = rc_class(dst_first);
  427 
  428   assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
  429 
  430   // Generate spill code!
  431   int size = 0;
  432 
  433   if (src_first == dst_first && src_second == dst_second)
  434     return size;            // Self copy, no move
  435 
  436 #ifdef TODO
  437   if (bottom_type()->isa_vect() != nullptr) {
  438   }
  439 #endif
  440 
  441   // Shared code does not expect instruction set capability based bailouts here.
  442   // Handle offset unreachable bailout with minimal change in shared code.
  443   // Bailout only for real instruction emit.
  444   // This requires a single comment change in shared code. ( see output.cpp "Normal" instruction case )
  445 
  446   // --------------------------------------
  447   // Check for mem-mem move.  Load into unused float registers and fall into
  448   // the float-store case.
  449   if (src_first_rc == rc_stack && dst_first_rc == rc_stack) {
  450     int offset = ra_->reg2offset(src_first);
  451     if (masm && !is_memoryfp(offset)) {
  452       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  453       return 0;
  454     } else {
  455       if (src_second_rc != rc_bad) {
  456         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
  457         src_first     = OptoReg::Name(R_mem_copy_lo_num);
  458         src_second    = OptoReg::Name(R_mem_copy_hi_num);
  459         src_first_rc  = rc_float;
  460         src_second_rc = rc_float;
  461         if (masm) {
  462           __ ldr_double(Rmemcopy, Address(SP, offset));
  463         } else if (!do_size) {
  464           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  465         }
  466       } else {
  467         src_first     = OptoReg::Name(R_mem_copy_lo_num);
  468         src_first_rc  = rc_float;
  469         if (masm) {
  470           __ ldr_float(Rmemcopy, Address(SP, offset));
  471         } else if (!do_size) {
  472           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  473         }
  474       }
  475       size += 4;
  476     }
  477   }
  478 
  479   if (src_second_rc == rc_stack && dst_second_rc == rc_stack) {
  480     Unimplemented();
  481   }
  482 
  483   // --------------------------------------
  484   // Check for integer reg-reg copy
  485   if (src_first_rc == rc_int && dst_first_rc == rc_int) {
  486     // Else normal reg-reg copy
  487     assert( src_second != dst_first, "smashed second before evacuating it" );
  488     if (masm) {
  489       __ mov(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
  490 #ifndef PRODUCT
  491     } else if (!do_size) {
  492       st->print("MOV    R_%s, R_%s\t# spill",
  493                 Matcher::regName[dst_first],
  494                 Matcher::regName[src_first]);
  495 #endif
  496     }
  497     size += 4;
  498   }
  499 
  500   // Check for integer store
  501   if (src_first_rc == rc_int && dst_first_rc == rc_stack) {
  502     int offset = ra_->reg2offset(dst_first);
  503     if (masm && !is_memoryI(offset)) {
  504       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  505       return 0;
  506     } else {
  507       if (src_second_rc != rc_bad && is_iRegLd_memhd(src_first, src_second, offset)) {
  508         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
  509         if (masm) {
  510           __ str_64(reg_to_register_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  511 #ifndef PRODUCT
  512         } else if (!do_size) {
  513           if (size != 0) st->print("\n\t");
  514           st->print(STR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
  515 #endif
  516         }
  517         return size + 4;
  518       } else {
  519         if (masm) {
  520           __ str_32(reg_to_register_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  521 #ifndef PRODUCT
  522         } else if (!do_size) {
  523           if (size != 0) st->print("\n\t");
  524           st->print(STR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
  525 #endif
  526         }
  527       }
  528     }
  529     size += 4;
  530   }
  531 
  532   // Check for integer load
  533   if (dst_first_rc == rc_int && src_first_rc == rc_stack) {
  534     int offset = ra_->reg2offset(src_first);
  535     if (masm && !is_memoryI(offset)) {
  536       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  537       return 0;
  538     } else {
  539       if (src_second_rc != rc_bad && is_iRegLd_memhd(dst_first, dst_second, offset)) {
  540         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
  541         if (masm) {
  542           __ ldr_64(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  543 #ifndef PRODUCT
  544         } else if (!do_size) {
  545           if (size != 0) st->print("\n\t");
  546           st->print(LDR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
  547 #endif
  548         }
  549         return size + 4;
  550       } else {
  551         if (masm) {
  552           __ ldr_32(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  553 #ifndef PRODUCT
  554         } else if (!do_size) {
  555           if (size != 0) st->print("\n\t");
  556           st->print(LDR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
  557 #endif
  558         }
  559       }
  560     }
  561     size += 4;
  562   }
  563 
  564   // Check for float reg-reg copy
  565   if (src_first_rc == rc_float && dst_first_rc == rc_float) {
  566     if (src_second_rc != rc_bad) {
  567       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");
  568       if (masm) {
  569       __ mov_double(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
  570 #ifndef PRODUCT
  571       } else if (!do_size) {
  572         st->print(MOV_DOUBLE "    R_%s, R_%s\t# spill",
  573                   Matcher::regName[dst_first],
  574                   Matcher::regName[src_first]);
  575 #endif
  576       }
  577       return 4;
  578     }
  579     if (masm) {
  580       __ mov_float(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
  581 #ifndef PRODUCT
  582     } else if (!do_size) {
  583       st->print(MOV_FLOAT "    R_%s, R_%s\t# spill",
  584                 Matcher::regName[dst_first],
  585                 Matcher::regName[src_first]);
  586 #endif
  587     }
  588     size = 4;
  589   }
  590 
  591   // Check for float store
  592   if (src_first_rc == rc_float && dst_first_rc == rc_stack) {
  593     int offset = ra_->reg2offset(dst_first);
  594     if (masm && !is_memoryfp(offset)) {
  595       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  596       return 0;
  597     } else {
  598       // Further check for aligned-adjacent pair, so we can use a double store
  599       if (src_second_rc != rc_bad) {
  600         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");
  601         if (masm) {
  602           __ str_double(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  603 #ifndef PRODUCT
  604         } else if (!do_size) {
  605           if (size != 0) st->print("\n\t");
  606           st->print(STR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  607 #endif
  608         }
  609         return size + 4;
  610       } else {
  611         if (masm) {
  612           __ str_float(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  613 #ifndef PRODUCT
  614         } else if (!do_size) {
  615           if (size != 0) st->print("\n\t");
  616           st->print(STR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  617 #endif
  618         }
  619       }
  620     }
  621     size += 4;
  622   }
  623 
  624   // Check for float load
  625   if (dst_first_rc == rc_float && src_first_rc == rc_stack) {
  626     int offset = ra_->reg2offset(src_first);
  627     if (masm && !is_memoryfp(offset)) {
  628       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  629       return 0;
  630     } else {
  631       // Further check for aligned-adjacent pair, so we can use a double store
  632       if (src_second_rc != rc_bad) {
  633         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");
  634         if (masm) {
  635           __ ldr_double(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  636 #ifndef PRODUCT
  637         } else if (!do_size) {
  638           if (size != 0) st->print("\n\t");
  639           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
  640 #endif
  641         }
  642         return size + 4;
  643       } else {
  644         if (masm) {
  645           __ ldr_float(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  646 #ifndef PRODUCT
  647         } else if (!do_size) {
  648           if (size != 0) st->print("\n\t");
  649           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
  650 #endif
  651         }
  652       }
  653     }
  654     size += 4;
  655   }
  656 
  657   // check for int reg -> float reg move
  658   if (src_first_rc == rc_int && dst_first_rc == rc_float) {
  659     // Further check for aligned-adjacent pair, so we can use a single instruction
  660     if (src_second_rc != rc_bad) {
  661       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
  662       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
  663       assert(src_second_rc == rc_int && dst_second_rc == rc_float, "unsupported");
  664       if (masm) {
  665         __ 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]));
  666 #ifndef PRODUCT
  667       } else if (!do_size) {
  668         if (size != 0) st->print("\n\t");
  669         st->print("FMDRR   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first), OptoReg::regname(src_second));
  670 #endif
  671       }
  672       return size + 4;
  673     } else {
  674       if (masm) {
  675         __ fmsr(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
  676 #ifndef PRODUCT
  677       } else if (!do_size) {
  678         if (size != 0) st->print("\n\t");
  679         st->print(FMSR "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
  680 #endif
  681       }
  682       size += 4;
  683     }
  684   }
  685 
  686   // check for float reg -> int reg move
  687   if (src_first_rc == rc_float && dst_first_rc == rc_int) {
  688     // Further check for aligned-adjacent pair, so we can use a single instruction
  689     if (src_second_rc != rc_bad) {
  690       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
  691       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
  692       assert(src_second_rc == rc_float && dst_second_rc == rc_int, "unsupported");
  693       if (masm) {
  694         __ 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]));
  695 #ifndef PRODUCT
  696       } else if (!do_size) {
  697         if (size != 0) st->print("\n\t");
  698         st->print("FMRRD   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(dst_second), OptoReg::regname(src_first));
  699 #endif
  700       }
  701       return size + 4;
  702     } else {
  703       if (masm) {
  704         __ fmrs(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
  705 #ifndef PRODUCT
  706       } else if (!do_size) {
  707         if (size != 0) st->print("\n\t");
  708         st->print(FMRS "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
  709 #endif
  710       }
  711       size += 4;
  712     }
  713   }
  714 
  715   // --------------------------------------------------------------------
  716   // Check for hi bits still needing moving.  Only happens for misaligned
  717   // arguments to native calls.
  718   if (src_second == dst_second)
  719     return size;               // Self copy; no move
  720   assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" );
  721 
  722   // Check for integer reg-reg copy.  Hi bits are stuck up in the top
  723   // 32-bits of a 64-bit register, but are needed in low bits of another
  724   // register (else it's a hi-bits-to-hi-bits copy which should have
  725   // happened already as part of a 64-bit move)
  726   if (src_second_rc == rc_int && dst_second_rc == rc_int) {
  727     if (masm) {
  728       __ mov(reg_to_register_object(Matcher::_regEncode[dst_second]), reg_to_register_object(Matcher::_regEncode[src_second]));
  729 #ifndef PRODUCT
  730     } else if (!do_size) {
  731       if (size != 0) st->print("\n\t");
  732       st->print("MOV    R_%s, R_%s\t# spill high",
  733                 Matcher::regName[dst_second],
  734                 Matcher::regName[src_second]);
  735 #endif
  736     }
  737     return size+4;
  738   }
  739 
  740   // Check for high word integer store
  741   if (src_second_rc == rc_int && dst_second_rc == rc_stack) {
  742     int offset = ra_->reg2offset(dst_second);
  743 
  744     if (masm && !is_memoryP(offset)) {
  745       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  746       return 0;
  747     } else {
  748       if (masm) {
  749         __ str(reg_to_register_object(Matcher::_regEncode[src_second]), Address(SP, offset));
  750 #ifndef PRODUCT
  751       } else if (!do_size) {
  752         if (size != 0) st->print("\n\t");
  753         st->print("STR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_second), offset);
  754 #endif
  755       }
  756     }
  757     return size + 4;
  758   }
  759 
  760   // Check for high word integer load
  761   if (dst_second_rc == rc_int && src_second_rc == rc_stack) {
  762     int offset = ra_->reg2offset(src_second);
  763     if (masm && !is_memoryP(offset)) {
  764       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  765       return 0;
  766     } else {
  767       if (masm) {
  768         __ ldr(reg_to_register_object(Matcher::_regEncode[dst_second]), Address(SP, offset));
  769 #ifndef PRODUCT
  770       } else if (!do_size) {
  771         if (size != 0) st->print("\n\t");
  772         st->print("LDR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_second), offset);
  773 #endif
  774       }
  775     }
  776     return size + 4;
  777   }
  778 
  779   Unimplemented();
  780   return 0; // Mute compiler
  781 }
  782 
  783 #ifndef PRODUCT
  784 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  785   implementation( nullptr, ra_, false, st );
  786 }
  787 #endif
  788 
  789 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
  790   implementation( masm, ra_, false, nullptr );
  791 }
  792 
  793 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
  794   return implementation( nullptr, ra_, true, nullptr );
  795 }
  796 
  797 //=============================================================================
  798 #ifndef PRODUCT
  799 void MachNopNode::format( PhaseRegAlloc *, outputStream *st ) const {
  800   st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
  801 }
  802 #endif
  803 
  804 void MachNopNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc * ) const {
  805   for(int i = 0; i < _count; i += 1) {
  806     __ nop();
  807   }
  808 }
  809 
  810 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
  811   return 4 * _count;
  812 }
  813 
  814 
  815 //=============================================================================
  816 #ifndef PRODUCT
  817 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  818   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  819   int reg = ra_->get_reg_first(this);
  820   st->print("ADD    %s,R_SP+#%d",Matcher::regName[reg], offset);
  821 }
  822 #endif
  823 
  824 void BoxLockNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
  825   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  826   int reg = ra_->get_encode(this);
  827   Register dst = reg_to_register_object(reg);
  828 
  829   if (is_aimm(offset)) {
  830     __ add(dst, SP, offset);
  831   } else {
  832     __ mov_slow(dst, offset);
  833     __ add(dst, SP, dst);
  834   }
  835 }
  836 
  837 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
  838   // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_)
  839   assert(ra_ == ra_->C->regalloc(), "sanity");
  840   return ra_->C->output()->scratch_emit_size(this);
  841 }
  842 
  843 //=============================================================================
  844 #ifndef PRODUCT
  845 void MachVEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
  846 {
  847   Unimplemented();
  848 }
  849 #endif
  850 
  851 void MachVEPNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc* ra_) const
  852 {
  853   Unimplemented();
  854 }
  855 
  856 #ifndef PRODUCT
  857 #define R_RTEMP "R_R12"
  858 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  859   st->print_cr("\nUEP:");
  860   st->print_cr("\tLDR   " R_RTEMP ",[R_R0 + oopDesc::klass_offset_in_bytes]\t! Inline cache check");
  861   st->print_cr("\tCMP   " R_RTEMP ",R_R8" );
  862   st->print   ("\tB.NE  SharedRuntime::handle_ic_miss_stub");
  863 }
  864 #endif
  865 
  866 void MachUEPNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
  867   __ ic_check(InteriorEntryAlignment);
  868 }
  869 
  870 //=============================================================================
  871 
  872 int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm) {
  873   // Can't use any of the current frame's registers as we may have deopted
  874   // at a poll and everything can be live.
  875   address base = __ start_a_stub(size_deopt_handler());
  876   if (base == nullptr) {
  877     ciEnv::current()->record_failure("CodeCache is full");
  878     return 0;  // CodeBuffer::expand failed
  879   }
  880 
  881   int offset = __ offset();
  882 
  883   Label start;
  884   __ bind(start);
  885 
  886   __ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, noreg);
  887 
  888   int entry_offset = __ offset();
  889   address deopt_pc = __ pc();
  890   // Preserve R0 and reserve space for the address of the entry point
  891   __ push(RegisterSet(R0) | RegisterSet(R1));
  892   // Store the entry point address
  893   __ mov_relative_address(R0, deopt_pc);
  894   __ str(R0, Address(SP, wordSize));
  895   __ pop(R0); // restore R0
  896   __ b(start);
  897 
  898   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
  899   assert(__ offset() - entry_offset >= NativePostCallNop::first_check_size,
  900          "out of bounds read in post-call NOP check");
  901 
  902   __ end_a_stub();
  903   return entry_offset;
  904 }
  905 
  906 bool Matcher::match_rule_supported(int opcode) {
  907   if (!has_match_rule(opcode))
  908     return false;
  909 
  910   switch (opcode) {
  911   case Op_PopCountI:
  912   case Op_PopCountL:
  913     if (!UsePopCountInstruction)
  914       return false;
  915     break;
  916   case Op_LShiftCntV:
  917   case Op_RShiftCntV:
  918   case Op_AddVB:
  919   case Op_AddVS:
  920   case Op_AddVI:
  921   case Op_AddVL:
  922   case Op_SubVB:
  923   case Op_SubVS:
  924   case Op_SubVI:
  925   case Op_SubVL:
  926   case Op_MulVS:
  927   case Op_MulVI:
  928   case Op_LShiftVB:
  929   case Op_LShiftVS:
  930   case Op_LShiftVI:
  931   case Op_LShiftVL:
  932   case Op_RShiftVB:
  933   case Op_RShiftVS:
  934   case Op_RShiftVI:
  935   case Op_RShiftVL:
  936   case Op_URShiftVB:
  937   case Op_URShiftVS:
  938   case Op_URShiftVI:
  939   case Op_URShiftVL:
  940   case Op_AndV:
  941   case Op_OrV:
  942   case Op_XorV:
  943     return VM_Version::has_simd();
  944   case Op_LoadVector:
  945   case Op_StoreVector:
  946   case Op_AddVF:
  947   case Op_SubVF:
  948   case Op_MulVF:
  949     return VM_Version::has_vfp() || VM_Version::has_simd();
  950   case Op_AddVD:
  951   case Op_SubVD:
  952   case Op_MulVD:
  953   case Op_DivVF:
  954   case Op_DivVD:
  955     return VM_Version::has_vfp();
  956   }
  957 
  958   return true;  // Per default match rules are supported.
  959 }
  960 
  961 bool Matcher::match_rule_supported_auto_vectorization(int opcode, int vlen, BasicType bt) {
  962   return match_rule_supported_vector(opcode, vlen, bt);
  963 }
  964 
  965 bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
  966 
  967   // TODO
  968   // identify extra cases that we might want to provide match rules for
  969   // e.g. Op_ vector nodes and other intrinsics while guarding with vlen
  970   bool ret_value = match_rule_supported(opcode) && vector_size_supported(bt, vlen);
  971   // Add rules here.
  972 
  973   return ret_value;  // Per default match rules are supported.
  974 }
  975 
  976 bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType bt) {
  977   return false;
  978 }
  979 
  980 bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) {
  981   return false;
  982 }
  983 
  984 bool Matcher::vector_rearrange_requires_load_shuffle(BasicType elem_bt, int vlen) {
  985   return false;
  986 }
  987 
  988 bool Matcher::mask_op_prefers_predicate(int opcode, const TypeVect* vt) {
  989   return false;
  990 }
  991 
  992 const RegMask* Matcher::predicate_reg_mask(void) {
  993   return nullptr;
  994 }
  995 
  996 // Vector calling convention not yet implemented.
  997 bool Matcher::supports_vector_calling_convention(void) {
  998   return false;
  999 }
 1000 
 1001 OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
 1002   Unimplemented();
 1003   return OptoRegPair(0, 0);
 1004 }
 1005 
 1006 // Vector width in bytes
 1007 int Matcher::vector_width_in_bytes(BasicType bt) {
 1008   return MaxVectorSize;
 1009 }
 1010 
 1011 int Matcher::scalable_vector_reg_size(const BasicType bt) {
 1012   return -1;
 1013 }
 1014 
 1015 // Vector ideal reg corresponding to specified size in bytes
 1016 uint Matcher::vector_ideal_reg(int size) {
 1017   assert(MaxVectorSize >= size, "");
 1018   switch(size) {
 1019     case  8: return Op_VecD;
 1020     case 16: return Op_VecX;
 1021   }
 1022   ShouldNotReachHere();
 1023   return 0;
 1024 }
 1025 
 1026 // Limits on vector size (number of elements) loaded into vector.
 1027 int Matcher::max_vector_size(const BasicType bt) {
 1028   assert(is_java_primitive(bt), "only primitive type vectors");
 1029   return vector_width_in_bytes(bt)/type2aelembytes(bt);
 1030 }
 1031 
 1032 int Matcher::min_vector_size(const BasicType bt) {
 1033   assert(is_java_primitive(bt), "only primitive type vectors");
 1034   return 8/type2aelembytes(bt);
 1035 }
 1036 
 1037 int Matcher::max_vector_size_auto_vectorization(const BasicType bt) {
 1038   return Matcher::max_vector_size(bt);
 1039 }
 1040 
 1041 // Is this branch offset short enough that a short branch can be used?
 1042 //
 1043 // NOTE: If the platform does not provide any short branch variants, then
 1044 //       this method should return false for offset 0.
 1045 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
 1046   // The passed offset is relative to address of the branch.
 1047   // On ARM a branch displacement is calculated relative to address
 1048   // of the branch + 8.
 1049   //
 1050   // offset -= 8;
 1051   // return (Assembler::is_simm24(offset));
 1052   return false;
 1053 }
 1054 
 1055 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) {
 1056   ShouldNotReachHere(); // generic vector operands not supported
 1057   return nullptr;
 1058 }
 1059 
 1060 bool Matcher::is_reg2reg_move(MachNode* m) {
 1061   ShouldNotReachHere();  // generic vector operands not supported
 1062   return false;
 1063 }
 1064 
 1065 bool Matcher::is_register_biasing_candidate(const MachNode* mdef, int oper_index) {
 1066   return false;
 1067 }
 1068 
 1069 bool Matcher::is_generic_vector(MachOper* opnd)  {
 1070   ShouldNotReachHere();  // generic vector operands not supported
 1071   return false;
 1072 }
 1073 
 1074 // Should the matcher clone input 'm' of node 'n'?
 1075 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
 1076   if (is_vshift_con_pattern(n, m)) { // ShiftV src (ShiftCntV con)
 1077     mstack.push(m, Visit);           // m = ShiftCntV
 1078     return true;
 1079   }
 1080   return false;
 1081 }
 1082 
 1083 // Should the Matcher clone shifts on addressing modes, expecting them
 1084 // to be subsumed into complex addressing expressions or compute them
 1085 // into registers?
 1086 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
 1087   return clone_base_plus_offset_address(m, mstack, address_visited);
 1088 }
 1089 
 1090 #ifdef ASSERT
 1091 // Return whether or not this register is ever used as an argument.
 1092 bool Matcher::can_be_java_arg( int reg ) {
 1093   if (reg == R_R0_num ||
 1094       reg == R_R1_num ||
 1095       reg == R_R2_num ||
 1096       reg == R_R3_num) return true;
 1097 
 1098   if (reg >= R_S0_num &&
 1099       reg <= R_S13_num) return true;
 1100   return false;
 1101 }
 1102 #endif
 1103 
 1104 uint Matcher::int_pressure_limit()
 1105 {
 1106   return (INTPRESSURE == -1) ? 12 : INTPRESSURE;
 1107 }
 1108 
 1109 uint Matcher::float_pressure_limit()
 1110 {
 1111   return (FLOATPRESSURE == -1) ? 30 : FLOATPRESSURE;
 1112 }
 1113 
 1114 // Register for DIVI projection of divmodI
 1115 const RegMask& Matcher::divI_proj_mask() {
 1116   ShouldNotReachHere();
 1117   return RegMask::EMPTY;
 1118 }
 1119 
 1120 // Register for MODI projection of divmodI
 1121 const RegMask& Matcher::modI_proj_mask() {
 1122   ShouldNotReachHere();
 1123   return RegMask::EMPTY;
 1124 }
 1125 
 1126 // Register for DIVL projection of divmodL
 1127 const RegMask& Matcher::divL_proj_mask() {
 1128   ShouldNotReachHere();
 1129   return RegMask::EMPTY;
 1130 }
 1131 
 1132 // Register for MODL projection of divmodL
 1133 const RegMask& Matcher::modL_proj_mask() {
 1134   ShouldNotReachHere();
 1135   return RegMask::EMPTY;
 1136 }
 1137 
 1138 bool maybe_far_call(const CallNode *n) {
 1139   return !MacroAssembler::_reachable_from_cache(n->as_Call()->entry_point());
 1140 }
 1141 
 1142 bool maybe_far_call(const MachCallNode *n) {
 1143   return !MacroAssembler::_reachable_from_cache(n->as_MachCall()->entry_point());
 1144 }
 1145 
 1146 %}
 1147 
 1148 //----------ENCODING BLOCK-----------------------------------------------------
 1149 // This block specifies the encoding classes used by the compiler to output
 1150 // byte streams.  Encoding classes are parameterized macros used by
 1151 // Machine Instruction Nodes in order to generate the bit encoding of the
 1152 // instruction.  Operands specify their base encoding interface with the
 1153 // interface keyword.  There are currently supported four interfaces,
 1154 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
 1155 // operand to generate a function which returns its register number when
 1156 // queried.   CONST_INTER causes an operand to generate a function which
 1157 // returns the value of the constant when queried.  MEMORY_INTER causes an
 1158 // operand to generate four functions which return the Base Register, the
 1159 // Index Register, the Scale Value, and the Offset Value of the operand when
 1160 // queried.  COND_INTER causes an operand to generate six functions which
 1161 // return the encoding code (ie - encoding bits for the instruction)
 1162 // associated with each basic boolean condition for a conditional instruction.
 1163 //
 1164 // Instructions specify two basic values for encoding.  Again, a function
 1165 // is available to check if the constant displacement is an oop. They use the
 1166 // ins_encode keyword to specify their encoding classes (which must be
 1167 // a sequence of enc_class names, and their parameters, specified in
 1168 // the encoding block), and they use the
 1169 // opcode keyword to specify, in order, their primary, secondary, and
 1170 // tertiary opcode.  Only the opcode sections which a particular instruction
 1171 // needs for encoding need to be specified.
 1172 encode %{
 1173   // Set instruction mark in MacroAssembler. This is used only in
 1174   // instructions that emit bytes directly to the CodeBuffer wraped
 1175   // in the MacroAssembler. Should go away once all "instruct" are
 1176   // patched to emit bytes only using methods in MacroAssembler.
 1177   enc_class SetInstMark %{
 1178     __ set_inst_mark();
 1179   %}
 1180 
 1181   enc_class ClearInstMark %{
 1182     __ clear_inst_mark();
 1183   %}
 1184 
 1185   enc_class call_epilog %{
 1186     // nothing
 1187   %}
 1188 
 1189   enc_class Java_To_Runtime (method meth) %{
 1190     // CALL directly to the runtime
 1191     emit_call_reloc(masm, as_MachCall(), $meth, runtime_call_Relocation::spec());
 1192   %}
 1193 
 1194   enc_class Java_Static_Call (method meth) %{
 1195     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
 1196     // who we intended to call.
 1197 
 1198     if ( !_method) {
 1199       emit_call_reloc(masm, as_MachCall(), $meth, runtime_call_Relocation::spec());
 1200     } else {
 1201       int method_index = resolved_method_index(masm);
 1202       RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
 1203                                                   : static_call_Relocation::spec(method_index);
 1204       emit_call_reloc(masm, as_MachCall(), $meth, rspec);
 1205 
 1206       // Emit stubs for static call.
 1207       address stub = CompiledDirectCall::emit_to_interp_stub(masm);
 1208       if (stub == nullptr) {
 1209         ciEnv::current()->record_failure("CodeCache is full");
 1210         return;
 1211       }
 1212     }
 1213   %}
 1214 
 1215   enc_class save_last_PC %{
 1216     // preserve mark
 1217     address mark = __ inst_mark();
 1218     DEBUG_ONLY(int off0 = __ offset());
 1219     int ret_addr_offset = as_MachCall()->ret_addr_offset();
 1220     __ adr(LR, mark + ret_addr_offset);
 1221     __ str(LR, Address(Rthread, JavaThread::last_Java_pc_offset()));
 1222     DEBUG_ONLY(int off1 = __ offset());
 1223     assert(off1 - off0 == 2 * Assembler::InstructionSize, "correct size prediction");
 1224     // restore mark
 1225     __ set_inst_mark(mark);
 1226   %}
 1227 
 1228   enc_class Java_Dynamic_Call (method meth) %{
 1229     Register R8_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode());
 1230     assert(R8_ic_reg == Ricklass, "should be");
 1231     __ set_inst_mark();
 1232     __ movw(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) & 0xffff);
 1233     __ movt(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) >> 16);
 1234     address  virtual_call_oop_addr = __ inst_mark();
 1235     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
 1236     // who we intended to call.
 1237     int method_index = resolved_method_index(masm);
 1238     __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index));
 1239     emit_call_reloc(masm, as_MachCall(), $meth, RelocationHolder::none);
 1240   %}
 1241 
 1242   enc_class LdReplImmI(immI src, regD dst, iRegI tmp, int cnt, int wth) %{
 1243     // FIXME: load from constant table?
 1244     // Load a constant replicated "count" times with width "width"
 1245     int count = $cnt$$constant;
 1246     int width = $wth$$constant;
 1247     assert(count*width == 4, "sanity");
 1248     int val = $src$$constant;
 1249     if (width < 4) {
 1250       int bit_width = width * 8;
 1251       val &= (((int)1) << bit_width) - 1; // mask off sign bits
 1252       for (int i = 0; i < count - 1; i++) {
 1253         val |= (val << bit_width);
 1254       }
 1255     }
 1256 
 1257     if (val == -1) {
 1258       __ mvn($tmp$$Register, 0);
 1259     } else if (val == 0) {
 1260       __ mov($tmp$$Register, 0);
 1261     } else {
 1262       __ movw($tmp$$Register, val & 0xffff);
 1263       __ movt($tmp$$Register, (unsigned int)val >> 16);
 1264     }
 1265     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 1266   %}
 1267 
 1268   enc_class LdReplImmF(immF src, regD dst, iRegI tmp) %{
 1269     // Replicate float con 2 times and pack into vector (8 bytes) in regD.
 1270     float fval = $src$$constant;
 1271     int val = *((int*)&fval);
 1272 
 1273     if (val == -1) {
 1274       __ mvn($tmp$$Register, 0);
 1275     } else if (val == 0) {
 1276       __ mov($tmp$$Register, 0);
 1277     } else {
 1278       __ movw($tmp$$Register, val & 0xffff);
 1279       __ movt($tmp$$Register, (unsigned int)val >> 16);
 1280     }
 1281     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 1282   %}
 1283 
 1284   enc_class enc_String_Compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result, iRegI tmp1, iRegI tmp2) %{
 1285     Label Ldone, Lloop;
 1286 
 1287     Register   str1_reg = $str1$$Register;
 1288     Register   str2_reg = $str2$$Register;
 1289     Register   cnt1_reg = $cnt1$$Register; // int
 1290     Register   cnt2_reg = $cnt2$$Register; // int
 1291     Register   tmp1_reg = $tmp1$$Register;
 1292     Register   tmp2_reg = $tmp2$$Register;
 1293     Register result_reg = $result$$Register;
 1294 
 1295     assert_different_registers(str1_reg, str2_reg, cnt1_reg, cnt2_reg, tmp1_reg, tmp2_reg);
 1296 
 1297     // Compute the minimum of the string lengths(str1_reg) and the
 1298     // difference of the string lengths (stack)
 1299 
 1300     // See if the lengths are different, and calculate min in str1_reg.
 1301     // Stash diff in tmp2 in case we need it for a tie-breaker.
 1302     __ subs_32(tmp2_reg, cnt1_reg, cnt2_reg);
 1303     __ mov(cnt1_reg, AsmOperand(cnt1_reg, lsl, exact_log2(sizeof(jchar)))); // scale the limit
 1304     __ mov(cnt1_reg, AsmOperand(cnt2_reg, lsl, exact_log2(sizeof(jchar))), pl); // scale the limit
 1305 
 1306     // reallocate cnt1_reg, cnt2_reg, result_reg
 1307     // Note:  limit_reg holds the string length pre-scaled by 2
 1308     Register limit_reg = cnt1_reg;
 1309     Register  chr2_reg = cnt2_reg;
 1310     Register  chr1_reg = tmp1_reg;
 1311     // str{12} are the base pointers
 1312 
 1313     // Is the minimum length zero?
 1314     __ cmp_32(limit_reg, 0);
 1315     if (result_reg != tmp2_reg) {
 1316       __ mov(result_reg, tmp2_reg, eq);
 1317     }
 1318     __ b(Ldone, eq);
 1319 
 1320     // Load first characters
 1321     __ ldrh(chr1_reg, Address(str1_reg, 0));
 1322     __ ldrh(chr2_reg, Address(str2_reg, 0));
 1323 
 1324     // Compare first characters
 1325     __ subs(chr1_reg, chr1_reg, chr2_reg);
 1326     if (result_reg != chr1_reg) {
 1327       __ mov(result_reg, chr1_reg, ne);
 1328     }
 1329     __ b(Ldone, ne);
 1330 
 1331     {
 1332       // Check after comparing first character to see if strings are equivalent
 1333       // Check if the strings start at same location
 1334       __ cmp(str1_reg, str2_reg);
 1335       // Check if the length difference is zero
 1336       __ cond_cmp(tmp2_reg, 0, eq);
 1337       __ mov(result_reg, 0, eq); // result is zero
 1338       __ b(Ldone, eq);
 1339       // Strings might not be equal
 1340     }
 1341 
 1342     __ subs(chr1_reg, limit_reg, 1 * sizeof(jchar));
 1343     if (result_reg != tmp2_reg) {
 1344       __ mov(result_reg, tmp2_reg, eq);
 1345     }
 1346     __ b(Ldone, eq);
 1347 
 1348     // Shift str1_reg and str2_reg to the end of the arrays, negate limit
 1349     __ add(str1_reg, str1_reg, limit_reg);
 1350     __ add(str2_reg, str2_reg, limit_reg);
 1351     __ neg(limit_reg, chr1_reg);  // limit = -(limit-2)
 1352 
 1353     // Compare the rest of the characters
 1354     __ bind(Lloop);
 1355     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
 1356     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
 1357     __ subs(chr1_reg, chr1_reg, chr2_reg);
 1358     if (result_reg != chr1_reg) {
 1359       __ mov(result_reg, chr1_reg, ne);
 1360     }
 1361     __ b(Ldone, ne);
 1362 
 1363     __ adds(limit_reg, limit_reg, sizeof(jchar));
 1364     __ b(Lloop, ne);
 1365 
 1366     // If strings are equal up to min length, return the length difference.
 1367     if (result_reg != tmp2_reg) {
 1368       __ mov(result_reg, tmp2_reg);
 1369     }
 1370 
 1371     // Otherwise, return the difference between the first mismatched chars.
 1372     __ bind(Ldone);
 1373   %}
 1374 
 1375   enc_class enc_String_Equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2) %{
 1376     Label Lchar, Lchar_loop, Ldone, Lequal;
 1377 
 1378     Register   str1_reg = $str1$$Register;
 1379     Register   str2_reg = $str2$$Register;
 1380     Register    cnt_reg = $cnt$$Register; // int
 1381     Register   tmp1_reg = $tmp1$$Register;
 1382     Register   tmp2_reg = $tmp2$$Register;
 1383     Register result_reg = $result$$Register;
 1384 
 1385     assert_different_registers(str1_reg, str2_reg, cnt_reg, tmp1_reg, tmp2_reg, result_reg);
 1386 
 1387     __ cmp(str1_reg, str2_reg); //same char[] ?
 1388     __ b(Lequal, eq);
 1389 
 1390     __ cbz_32(cnt_reg, Lequal); // count == 0
 1391 
 1392     //rename registers
 1393     Register limit_reg = cnt_reg;
 1394     Register  chr1_reg = tmp1_reg;
 1395     Register  chr2_reg = tmp2_reg;
 1396 
 1397     __ logical_shift_left(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
 1398 
 1399     //check for alignment and position the pointers to the ends
 1400     __ orr(chr1_reg, str1_reg, str2_reg);
 1401     __ tst(chr1_reg, 0x3);
 1402 
 1403     // notZero means at least one not 4-byte aligned.
 1404     // We could optimize the case when both arrays are not aligned
 1405     // but it is not frequent case and it requires additional checks.
 1406     __ b(Lchar, ne);
 1407 
 1408     // Compare char[] arrays aligned to 4 bytes.
 1409     __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg,
 1410                           chr1_reg, chr2_reg, Ldone);
 1411 
 1412     __ b(Lequal); // equal
 1413 
 1414     // char by char compare
 1415     __ bind(Lchar);
 1416     __ mov(result_reg, 0);
 1417     __ add(str1_reg, limit_reg, str1_reg);
 1418     __ add(str2_reg, limit_reg, str2_reg);
 1419     __ neg(limit_reg, limit_reg); //negate count
 1420 
 1421     // Lchar_loop
 1422     __ bind(Lchar_loop);
 1423     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
 1424     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
 1425     __ cmp(chr1_reg, chr2_reg);
 1426     __ b(Ldone, ne);
 1427     __ adds(limit_reg, limit_reg, sizeof(jchar));
 1428     __ b(Lchar_loop, ne);
 1429 
 1430     __ bind(Lequal);
 1431     __ mov(result_reg, 1);  //equal
 1432 
 1433     __ bind(Ldone);
 1434   %}
 1435 
 1436   enc_class enc_Array_Equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result) %{
 1437     Label Ldone, Lloop, Lequal;
 1438 
 1439     Register   ary1_reg = $ary1$$Register;
 1440     Register   ary2_reg = $ary2$$Register;
 1441     Register   tmp1_reg = $tmp1$$Register;
 1442     Register   tmp2_reg = $tmp2$$Register;
 1443     Register   tmp3_reg = $tmp3$$Register;
 1444     Register result_reg = $result$$Register;
 1445 
 1446     assert_different_registers(ary1_reg, ary2_reg, tmp1_reg, tmp2_reg, tmp3_reg, result_reg);
 1447 
 1448     int length_offset  = arrayOopDesc::length_offset_in_bytes();
 1449     int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
 1450 
 1451     // return true if the same array
 1452     __ teq(ary1_reg, ary2_reg);
 1453     __ mov(result_reg, 1, eq);
 1454     __ b(Ldone, eq); // equal
 1455 
 1456     __ tst(ary1_reg, ary1_reg);
 1457     __ mov(result_reg, 0, eq);
 1458     __ b(Ldone, eq);    // not equal
 1459 
 1460     __ tst(ary2_reg, ary2_reg);
 1461     __ mov(result_reg, 0, eq);
 1462     __ b(Ldone, eq);    // not equal
 1463 
 1464     //load the lengths of arrays
 1465     __ ldr_s32(tmp1_reg, Address(ary1_reg, length_offset)); // int
 1466     __ ldr_s32(tmp2_reg, Address(ary2_reg, length_offset)); // int
 1467 
 1468     // return false if the two arrays are not equal length
 1469     __ teq_32(tmp1_reg, tmp2_reg);
 1470     __ mov(result_reg, 0, ne);
 1471     __ b(Ldone, ne);    // not equal
 1472 
 1473     __ tst(tmp1_reg, tmp1_reg);
 1474     __ mov(result_reg, 1, eq);
 1475     __ b(Ldone, eq);    // zero-length arrays are equal
 1476 
 1477     // load array addresses
 1478     __ add(ary1_reg, ary1_reg, base_offset);
 1479     __ add(ary2_reg, ary2_reg, base_offset);
 1480 
 1481     // renaming registers
 1482     Register chr1_reg  =  tmp3_reg;   // for characters in ary1
 1483     Register chr2_reg  =  tmp2_reg;   // for characters in ary2
 1484     Register limit_reg =  tmp1_reg;   // length
 1485 
 1486     // set byte count
 1487     __ logical_shift_left_32(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
 1488 
 1489     // Compare char[] arrays aligned to 4 bytes.
 1490     __ char_arrays_equals(ary1_reg, ary2_reg, limit_reg, result_reg,
 1491                           chr1_reg, chr2_reg, Ldone);
 1492     __ bind(Lequal);
 1493     __ mov(result_reg, 1);  //equal
 1494 
 1495     __ bind(Ldone);
 1496     %}
 1497 %}
 1498 
 1499 //----------FRAME--------------------------------------------------------------
 1500 // Definition of frame structure and management information.
 1501 //
 1502 //  S T A C K   L A Y O U T    Allocators stack-slot number
 1503 //                             |   (to get allocators register number
 1504 //  G  Owned by    |        |  v    add VMRegImpl::stack0)
 1505 //  r   CALLER     |        |
 1506 //  o     |        +--------+      pad to even-align allocators stack-slot
 1507 //  w     V        |  pad0  |        numbers; owned by CALLER
 1508 //  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
 1509 //  h     ^        |   in   |  5
 1510 //        |        |  args  |  4   Holes in incoming args owned by SELF
 1511 //  |     |        |        |  3
 1512 //  |     |        +--------+
 1513 //  V     |        | old out|      Empty on Intel, window on Sparc
 1514 //        |    old |preserve|      Must be even aligned.
 1515 //        |     SP-+--------+----> Matcher::_old_SP, 8 (or 16 in LP64)-byte aligned
 1516 //        |        |   in   |  3   area for Intel ret address
 1517 //     Owned by    |preserve|      Empty on Sparc.
 1518 //       SELF      +--------+
 1519 //        |        |  pad2  |  2   pad to align old SP
 1520 //        |        +--------+  1
 1521 //        |        | locks  |  0
 1522 //        |        +--------+----> VMRegImpl::stack0, 8 (or 16 in LP64)-byte aligned
 1523 //        |        |  pad1  | 11   pad to align new SP
 1524 //        |        +--------+
 1525 //        |        |        | 10
 1526 //        |        | spills |  9   spills
 1527 //        V        |        |  8   (pad0 slot for callee)
 1528 //      -----------+--------+----> Matcher::_out_arg_limit, unaligned
 1529 //        ^        |  out   |  7
 1530 //        |        |  args  |  6   Holes in outgoing args owned by CALLEE
 1531 //     Owned by    +--------+
 1532 //      CALLEE     | new out|  6   Empty on Intel, window on Sparc
 1533 //        |    new |preserve|      Must be even-aligned.
 1534 //        |     SP-+--------+----> Matcher::_new_SP, even aligned
 1535 //        |        |        |
 1536 //
 1537 // Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
 1538 //         known from SELF's arguments and the Java calling convention.
 1539 //         Region 6-7 is determined per call site.
 1540 // Note 2: If the calling convention leaves holes in the incoming argument
 1541 //         area, those holes are owned by SELF.  Holes in the outgoing area
 1542 //         are owned by the CALLEE.  Holes should not be necessary in the
 1543 //         incoming area, as the Java calling convention is completely under
 1544 //         the control of the AD file.  Doubles can be sorted and packed to
 1545 //         avoid holes.  Holes in the outgoing arguments may be necessary for
 1546 //         varargs C calling conventions.
 1547 // Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
 1548 //         even aligned with pad0 as needed.
 1549 //         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
 1550 //         region 6-11 is even aligned; it may be padded out more so that
 1551 //         the region from SP to FP meets the minimum stack alignment.
 1552 
 1553 frame %{
 1554   // These two registers define part of the calling convention
 1555   // between compiled code and the interpreter.
 1556   inline_cache_reg(R_Ricklass);          // Inline Cache Register or Method* for I2C
 1557 
 1558   // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
 1559   cisc_spilling_operand_name(indOffset);
 1560 
 1561   // Number of stack slots consumed by a Monitor enter
 1562   sync_stack_slots(1 * VMRegImpl::slots_per_word);
 1563 
 1564   // Compiled code's Frame Pointer
 1565   frame_pointer(R_R13);
 1566 
 1567   // Stack alignment requirement
 1568   stack_alignment(StackAlignmentInBytes);
 1569   //  LP64: Alignment size in bytes (128-bit -> 16 bytes)
 1570   // !LP64: Alignment size in bytes (64-bit  ->  8 bytes)
 1571 
 1572   // Number of outgoing stack slots killed above the out_preserve_stack_slots
 1573   // for calls to C.  Supports the var-args backing area for register parms.
 1574   // ADLC doesn't support parsing expressions, so I folded the math by hand.
 1575   varargs_C_out_slots_killed( 0);
 1576 
 1577   // The after-PROLOG location of the return address.  Location of
 1578   // return address specifies a type (REG or STACK) and a number
 1579   // representing the register number (i.e. - use a register name) or
 1580   // stack slot.
 1581   // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
 1582   // Otherwise, it is above the locks and verification slot and alignment word
 1583   return_addr(STACK - 1*VMRegImpl::slots_per_word +
 1584               align_up((Compile::current()->in_preserve_stack_slots() +
 1585                         Compile::current()->fixed_slots()),
 1586                        stack_alignment_in_slots()));
 1587 
 1588   // Location of compiled Java return values.  Same as C
 1589   return_value %{
 1590     return c2::return_value(ideal_reg);
 1591   %}
 1592 
 1593 %}
 1594 
 1595 //----------ATTRIBUTES---------------------------------------------------------
 1596 //----------Instruction Attributes---------------------------------------------
 1597 ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute
 1598 ins_attrib ins_size(32);           // Required size attribute (in bits)
 1599 ins_attrib ins_short_branch(0);    // Required flag: is this instruction a
 1600                                    // non-matching short branch variant of some
 1601                                                             // long branch?
 1602 
 1603 //----------OPERANDS-----------------------------------------------------------
 1604 // Operand definitions must precede instruction definitions for correct parsing
 1605 // in the ADLC because operands constitute user defined types which are used in
 1606 // instruction definitions.
 1607 
 1608 //----------Simple Operands----------------------------------------------------
 1609 // Immediate Operands
 1610 // Integer Immediate: 32-bit
 1611 operand immI() %{
 1612   match(ConI);
 1613 
 1614   op_cost(0);
 1615   // formats are generated automatically for constants and base registers
 1616   format %{ %}
 1617   interface(CONST_INTER);
 1618 %}
 1619 
 1620 // Integer Immediate: 8-bit unsigned - for VMOV
 1621 operand immU8() %{
 1622   predicate(0 <= n->get_int() && (n->get_int() <= 255));
 1623   match(ConI);
 1624   op_cost(0);
 1625 
 1626   format %{ %}
 1627   interface(CONST_INTER);
 1628 %}
 1629 
 1630 // Integer Immediate: 16-bit
 1631 operand immI16() %{
 1632   predicate((n->get_int() >> 16) == 0 && VM_Version::supports_movw());
 1633   match(ConI);
 1634   op_cost(0);
 1635 
 1636   format %{ %}
 1637   interface(CONST_INTER);
 1638 %}
 1639 
 1640 // Integer Immediate: offset for half and double word loads and stores
 1641 operand immIHD() %{
 1642   predicate(is_memoryHD(n->get_int()));
 1643   match(ConI);
 1644   op_cost(0);
 1645   format %{ %}
 1646   interface(CONST_INTER);
 1647 %}
 1648 
 1649 // Integer Immediate: offset for fp loads and stores
 1650 operand immIFP() %{
 1651   predicate(is_memoryfp(n->get_int()) && ((n->get_int() & 3) == 0));
 1652   match(ConI);
 1653   op_cost(0);
 1654 
 1655   format %{ %}
 1656   interface(CONST_INTER);
 1657 %}
 1658 
 1659 // Valid scale values for addressing modes and shifts
 1660 operand immU5() %{
 1661   predicate(0 <= n->get_int() && (n->get_int() <= 31));
 1662   match(ConI);
 1663   op_cost(0);
 1664 
 1665   format %{ %}
 1666   interface(CONST_INTER);
 1667 %}
 1668 
 1669 // Integer Immediate: 6-bit
 1670 operand immU6Big() %{
 1671   predicate(n->get_int() >= 32 && n->get_int() <= 63);
 1672   match(ConI);
 1673   op_cost(0);
 1674   format %{ %}
 1675   interface(CONST_INTER);
 1676 %}
 1677 
 1678 // Integer Immediate: 0-bit
 1679 operand immI0() %{
 1680   predicate(n->get_int() == 0);
 1681   match(ConI);
 1682   op_cost(0);
 1683 
 1684   format %{ %}
 1685   interface(CONST_INTER);
 1686 %}
 1687 
 1688 // Int Immediate non-negative
 1689 operand immU31()
 1690 %{
 1691   predicate(n->get_int() >= 0);
 1692   match(ConI);
 1693 
 1694   op_cost(0);
 1695   format %{ %}
 1696   interface(CONST_INTER);
 1697 %}
 1698 
 1699 // Integer Immediate: the values 32-63
 1700 operand immI_32_63() %{
 1701   predicate(n->get_int() >= 32 && n->get_int() <= 63);
 1702   match(ConI);
 1703   op_cost(0);
 1704 
 1705   format %{ %}
 1706   interface(CONST_INTER);
 1707 %}
 1708 
 1709 // Immediates for special shifts (sign extend)
 1710 
 1711 // Integer Immediate: the value 16
 1712 operand immI_16() %{
 1713   predicate(n->get_int() == 16);
 1714   match(ConI);
 1715   op_cost(0);
 1716 
 1717   format %{ %}
 1718   interface(CONST_INTER);
 1719 %}
 1720 
 1721 // Integer Immediate: the value 24
 1722 operand immI_24() %{
 1723   predicate(n->get_int() == 24);
 1724   match(ConI);
 1725   op_cost(0);
 1726 
 1727   format %{ %}
 1728   interface(CONST_INTER);
 1729 %}
 1730 
 1731 // Integer Immediate: the value 255
 1732 operand immI_255() %{
 1733   predicate( n->get_int() == 255 );
 1734   match(ConI);
 1735   op_cost(0);
 1736 
 1737   format %{ %}
 1738   interface(CONST_INTER);
 1739 %}
 1740 
 1741 // Integer Immediate: the value 65535
 1742 operand immI_65535() %{
 1743   predicate(n->get_int() == 65535);
 1744   match(ConI);
 1745   op_cost(0);
 1746 
 1747   format %{ %}
 1748   interface(CONST_INTER);
 1749 %}
 1750 
 1751 // Integer Immediates for arithmetic instructions
 1752 
 1753 operand aimmI() %{
 1754   predicate(is_aimm(n->get_int()));
 1755   match(ConI);
 1756   op_cost(0);
 1757 
 1758   format %{ %}
 1759   interface(CONST_INTER);
 1760 %}
 1761 
 1762 operand aimmIneg() %{
 1763   predicate(is_aimm(-n->get_int()));
 1764   match(ConI);
 1765   op_cost(0);
 1766 
 1767   format %{ %}
 1768   interface(CONST_INTER);
 1769 %}
 1770 
 1771 operand aimmU31() %{
 1772   predicate((0 <= n->get_int()) && is_aimm(n->get_int()));
 1773   match(ConI);
 1774   op_cost(0);
 1775 
 1776   format %{ %}
 1777   interface(CONST_INTER);
 1778 %}
 1779 
 1780 // Integer Immediates for logical instructions
 1781 
 1782 operand limmI() %{
 1783   predicate(is_limmI(n->get_int()));
 1784   match(ConI);
 1785   op_cost(0);
 1786 
 1787   format %{ %}
 1788   interface(CONST_INTER);
 1789 %}
 1790 
 1791 operand limmIlow8() %{
 1792   predicate(is_limmI_low(n->get_int(), 8));
 1793   match(ConI);
 1794   op_cost(0);
 1795 
 1796   format %{ %}
 1797   interface(CONST_INTER);
 1798 %}
 1799 
 1800 operand limmU31() %{
 1801   predicate(0 <= n->get_int() && is_limmI(n->get_int()));
 1802   match(ConI);
 1803   op_cost(0);
 1804 
 1805   format %{ %}
 1806   interface(CONST_INTER);
 1807 %}
 1808 
 1809 operand limmIn() %{
 1810   predicate(is_limmI(~n->get_int()));
 1811   match(ConI);
 1812   op_cost(0);
 1813 
 1814   format %{ %}
 1815   interface(CONST_INTER);
 1816 %}
 1817 
 1818 // Pointer Immediate: 32 or 64-bit
 1819 operand immP() %{
 1820   match(ConP);
 1821 
 1822   op_cost(5);
 1823   // formats are generated automatically for constants and base registers
 1824   format %{ %}
 1825   interface(CONST_INTER);
 1826 %}
 1827 
 1828 operand immP0() %{
 1829   predicate(n->get_ptr() == 0);
 1830   match(ConP);
 1831   op_cost(0);
 1832 
 1833   format %{ %}
 1834   interface(CONST_INTER);
 1835 %}
 1836 
 1837 operand immL() %{
 1838   match(ConL);
 1839   op_cost(40);
 1840   // formats are generated automatically for constants and base registers
 1841   format %{ %}
 1842   interface(CONST_INTER);
 1843 %}
 1844 
 1845 operand immL0() %{
 1846   predicate(n->get_long() == 0L);
 1847   match(ConL);
 1848   op_cost(0);
 1849   // formats are generated automatically for constants and base registers
 1850   format %{ %}
 1851   interface(CONST_INTER);
 1852 %}
 1853 
 1854 // Long Immediate: 16-bit
 1855 operand immL16() %{
 1856   predicate(n->get_long() >= 0 && n->get_long() < (1<<16)  && VM_Version::supports_movw());
 1857   match(ConL);
 1858   op_cost(0);
 1859 
 1860   format %{ %}
 1861   interface(CONST_INTER);
 1862 %}
 1863 
 1864 // Long Immediate: low 32-bit mask
 1865 operand immL_32bits() %{
 1866   predicate(n->get_long() == 0xFFFFFFFFL);
 1867   match(ConL);
 1868   op_cost(0);
 1869 
 1870   format %{ %}
 1871   interface(CONST_INTER);
 1872 %}
 1873 
 1874 // Double Immediate
 1875 operand immD() %{
 1876   match(ConD);
 1877 
 1878   op_cost(40);
 1879   format %{ %}
 1880   interface(CONST_INTER);
 1881 %}
 1882 
 1883 // Double Immediate: +0.0d.
 1884 operand immD0() %{
 1885   predicate(jlong_cast(n->getd()) == 0);
 1886 
 1887   match(ConD);
 1888   op_cost(0);
 1889   format %{ %}
 1890   interface(CONST_INTER);
 1891 %}
 1892 
 1893 operand imm8D() %{
 1894   predicate(Assembler::double_num(n->getd()).can_be_imm8());
 1895   match(ConD);
 1896 
 1897   op_cost(0);
 1898   format %{ %}
 1899   interface(CONST_INTER);
 1900 %}
 1901 
 1902 // Float Immediate
 1903 operand immF() %{
 1904   match(ConF);
 1905 
 1906   op_cost(20);
 1907   format %{ %}
 1908   interface(CONST_INTER);
 1909 %}
 1910 
 1911 // Float Immediate: +0.0f
 1912 operand immF0() %{
 1913   predicate(jint_cast(n->getf()) == 0);
 1914   match(ConF);
 1915 
 1916   op_cost(0);
 1917   format %{ %}
 1918   interface(CONST_INTER);
 1919 %}
 1920 
 1921 // Float Immediate: encoded as 8 bits
 1922 operand imm8F() %{
 1923   predicate(Assembler::float_num(n->getf()).can_be_imm8());
 1924   match(ConF);
 1925 
 1926   op_cost(0);
 1927   format %{ %}
 1928   interface(CONST_INTER);
 1929 %}
 1930 
 1931 // Integer Register Operands
 1932 // Integer Register
 1933 operand iRegI() %{
 1934   constraint(ALLOC_IN_RC(int_reg));
 1935   match(RegI);
 1936   match(R0RegI);
 1937   match(R1RegI);
 1938   match(R2RegI);
 1939   match(R3RegI);
 1940   match(R12RegI);
 1941 
 1942   format %{ %}
 1943   interface(REG_INTER);
 1944 %}
 1945 
 1946 // Pointer Register
 1947 operand iRegP() %{
 1948   constraint(ALLOC_IN_RC(ptr_reg));
 1949   match(RegP);
 1950   match(R0RegP);
 1951   match(R1RegP);
 1952   match(R2RegP);
 1953   match(RExceptionRegP);
 1954   match(R8RegP);
 1955   match(R9RegP);
 1956   match(RthreadRegP); // FIXME: move to sp_ptr_RegP?
 1957   match(R12RegP);
 1958   match(LRRegP);
 1959 
 1960   match(sp_ptr_RegP);
 1961   match(store_ptr_RegP);
 1962 
 1963   format %{ %}
 1964   interface(REG_INTER);
 1965 %}
 1966 
 1967 // GPRs + Rthread + SP
 1968 operand sp_ptr_RegP() %{
 1969   constraint(ALLOC_IN_RC(sp_ptr_reg));
 1970   match(RegP);
 1971   match(iRegP);
 1972   match(SPRegP); // FIXME: check cost
 1973 
 1974   format %{ %}
 1975   interface(REG_INTER);
 1976 %}
 1977 
 1978 
 1979 operand R0RegP() %{
 1980   constraint(ALLOC_IN_RC(R0_regP));
 1981   match(iRegP);
 1982 
 1983   format %{ %}
 1984   interface(REG_INTER);
 1985 %}
 1986 
 1987 operand R1RegP() %{
 1988   constraint(ALLOC_IN_RC(R1_regP));
 1989   match(iRegP);
 1990 
 1991   format %{ %}
 1992   interface(REG_INTER);
 1993 %}
 1994 
 1995 operand R8RegP() %{
 1996   constraint(ALLOC_IN_RC(R8_regP));
 1997   match(iRegP);
 1998 
 1999   format %{ %}
 2000   interface(REG_INTER);
 2001 %}
 2002 
 2003 operand R9RegP() %{
 2004   constraint(ALLOC_IN_RC(R9_regP));
 2005   match(iRegP);
 2006 
 2007   format %{ %}
 2008   interface(REG_INTER);
 2009 %}
 2010 
 2011 operand R12RegP() %{
 2012   constraint(ALLOC_IN_RC(R12_regP));
 2013   match(iRegP);
 2014 
 2015   format %{ %}
 2016   interface(REG_INTER);
 2017 %}
 2018 
 2019 operand R2RegP() %{
 2020   constraint(ALLOC_IN_RC(R2_regP));
 2021   match(iRegP);
 2022 
 2023   format %{ %}
 2024   interface(REG_INTER);
 2025 %}
 2026 
 2027 operand RExceptionRegP() %{
 2028   constraint(ALLOC_IN_RC(Rexception_regP));
 2029   match(iRegP);
 2030 
 2031   format %{ %}
 2032   interface(REG_INTER);
 2033 %}
 2034 
 2035 operand RthreadRegP() %{
 2036   constraint(ALLOC_IN_RC(Rthread_regP));
 2037   match(iRegP);
 2038 
 2039   format %{ %}
 2040   interface(REG_INTER);
 2041 %}
 2042 
 2043 operand IPRegP() %{
 2044   constraint(ALLOC_IN_RC(IP_regP));
 2045   match(iRegP);
 2046 
 2047   format %{ %}
 2048   interface(REG_INTER);
 2049 %}
 2050 
 2051 operand SPRegP() %{
 2052   constraint(ALLOC_IN_RC(SP_regP));
 2053   match(iRegP);
 2054 
 2055   format %{ %}
 2056   interface(REG_INTER);
 2057 %}
 2058 
 2059 operand LRRegP() %{
 2060   constraint(ALLOC_IN_RC(LR_regP));
 2061   match(iRegP);
 2062 
 2063   format %{ %}
 2064   interface(REG_INTER);
 2065 %}
 2066 
 2067 operand R0RegI() %{
 2068   constraint(ALLOC_IN_RC(R0_regI));
 2069   match(iRegI);
 2070 
 2071   format %{ %}
 2072   interface(REG_INTER);
 2073 %}
 2074 
 2075 operand R1RegI() %{
 2076   constraint(ALLOC_IN_RC(R1_regI));
 2077   match(iRegI);
 2078 
 2079   format %{ %}
 2080   interface(REG_INTER);
 2081 %}
 2082 
 2083 operand R2RegI() %{
 2084   constraint(ALLOC_IN_RC(R2_regI));
 2085   match(iRegI);
 2086 
 2087   format %{ %}
 2088   interface(REG_INTER);
 2089 %}
 2090 
 2091 operand R3RegI() %{
 2092   constraint(ALLOC_IN_RC(R3_regI));
 2093   match(iRegI);
 2094 
 2095   format %{ %}
 2096   interface(REG_INTER);
 2097 %}
 2098 
 2099 operand R12RegI() %{
 2100   constraint(ALLOC_IN_RC(R12_regI));
 2101   match(iRegI);
 2102 
 2103   format %{ %}
 2104   interface(REG_INTER);
 2105 %}
 2106 
 2107 // Long Register
 2108 operand iRegL() %{
 2109   constraint(ALLOC_IN_RC(long_reg));
 2110   match(RegL);
 2111   match(R0R1RegL);
 2112   match(R2R3RegL);
 2113 //match(iRegLex);
 2114 
 2115   format %{ %}
 2116   interface(REG_INTER);
 2117 %}
 2118 
 2119 operand iRegLd() %{
 2120   constraint(ALLOC_IN_RC(long_reg_align));
 2121   match(iRegL); // FIXME: allows unaligned R11/R12?
 2122 
 2123   format %{ %}
 2124   interface(REG_INTER);
 2125 %}
 2126 
 2127 // first long arg, or return value
 2128 operand R0R1RegL() %{
 2129   constraint(ALLOC_IN_RC(R0R1_regL));
 2130   match(iRegL);
 2131 
 2132   format %{ %}
 2133   interface(REG_INTER);
 2134 %}
 2135 
 2136 operand R2R3RegL() %{
 2137   constraint(ALLOC_IN_RC(R2R3_regL));
 2138   match(iRegL);
 2139 
 2140   format %{ %}
 2141   interface(REG_INTER);
 2142 %}
 2143 
 2144 // Condition Code Flag Register
 2145 operand flagsReg() %{
 2146   constraint(ALLOC_IN_RC(int_flags));
 2147   match(RegFlags);
 2148 
 2149   format %{ "apsr" %}
 2150   interface(REG_INTER);
 2151 %}
 2152 
 2153 // Result of compare to 0 (TST)
 2154 operand flagsReg_EQNELTGE() %{
 2155   constraint(ALLOC_IN_RC(int_flags));
 2156   match(RegFlags);
 2157 
 2158   format %{ "apsr_EQNELTGE" %}
 2159   interface(REG_INTER);
 2160 %}
 2161 
 2162 // Condition Code Register, unsigned comparisons.
 2163 operand flagsRegU() %{
 2164   constraint(ALLOC_IN_RC(int_flags));
 2165   match(RegFlags);
 2166 #ifdef TODO
 2167   match(RegFlagsP);
 2168 #endif
 2169 
 2170   format %{ "apsr_U" %}
 2171   interface(REG_INTER);
 2172 %}
 2173 
 2174 // Condition Code Register, pointer comparisons.
 2175 operand flagsRegP() %{
 2176   constraint(ALLOC_IN_RC(int_flags));
 2177   match(RegFlags);
 2178 
 2179   format %{ "apsr_P" %}
 2180   interface(REG_INTER);
 2181 %}
 2182 
 2183 // Condition Code Register, long comparisons.
 2184 operand flagsRegL_LTGE() %{
 2185   constraint(ALLOC_IN_RC(int_flags));
 2186   match(RegFlags);
 2187 
 2188   format %{ "apsr_L_LTGE" %}
 2189   interface(REG_INTER);
 2190 %}
 2191 
 2192 operand flagsRegL_EQNE() %{
 2193   constraint(ALLOC_IN_RC(int_flags));
 2194   match(RegFlags);
 2195 
 2196   format %{ "apsr_L_EQNE" %}
 2197   interface(REG_INTER);
 2198 %}
 2199 
 2200 operand flagsRegL_LEGT() %{
 2201   constraint(ALLOC_IN_RC(int_flags));
 2202   match(RegFlags);
 2203 
 2204   format %{ "apsr_L_LEGT" %}
 2205   interface(REG_INTER);
 2206 %}
 2207 
 2208 operand flagsRegUL_LTGE() %{
 2209   constraint(ALLOC_IN_RC(int_flags));
 2210   match(RegFlags);
 2211 
 2212   format %{ "apsr_UL_LTGE" %}
 2213   interface(REG_INTER);
 2214 %}
 2215 
 2216 operand flagsRegUL_EQNE() %{
 2217   constraint(ALLOC_IN_RC(int_flags));
 2218   match(RegFlags);
 2219 
 2220   format %{ "apsr_UL_EQNE" %}
 2221   interface(REG_INTER);
 2222 %}
 2223 
 2224 operand flagsRegUL_LEGT() %{
 2225   constraint(ALLOC_IN_RC(int_flags));
 2226   match(RegFlags);
 2227 
 2228   format %{ "apsr_UL_LEGT" %}
 2229   interface(REG_INTER);
 2230 %}
 2231 
 2232 // Condition Code Register, floating comparisons, unordered same as "less".
 2233 operand flagsRegF() %{
 2234   constraint(ALLOC_IN_RC(float_flags));
 2235   match(RegFlags);
 2236 
 2237   format %{ "fpscr_F" %}
 2238   interface(REG_INTER);
 2239 %}
 2240 
 2241 // Vectors
 2242 operand vecD() %{
 2243   constraint(ALLOC_IN_RC(actual_dflt_reg));
 2244   match(VecD);
 2245 
 2246   format %{ %}
 2247   interface(REG_INTER);
 2248 %}
 2249 
 2250 operand vecX() %{
 2251   constraint(ALLOC_IN_RC(vectorx_reg));
 2252   match(VecX);
 2253 
 2254   format %{ %}
 2255   interface(REG_INTER);
 2256 %}
 2257 
 2258 operand regD() %{
 2259   constraint(ALLOC_IN_RC(actual_dflt_reg));
 2260   match(RegD);
 2261   match(regD_low);
 2262 
 2263   format %{ %}
 2264   interface(REG_INTER);
 2265 %}
 2266 
 2267 operand regF() %{
 2268   constraint(ALLOC_IN_RC(sflt_reg));
 2269   match(RegF);
 2270 
 2271   format %{ %}
 2272   interface(REG_INTER);
 2273 %}
 2274 
 2275 operand regD_low() %{
 2276   constraint(ALLOC_IN_RC(dflt_low_reg));
 2277   match(RegD);
 2278 
 2279   format %{ %}
 2280   interface(REG_INTER);
 2281 %}
 2282 
 2283 // Special Registers
 2284 
 2285 // Method Register
 2286 operand inline_cache_regP(iRegP reg) %{
 2287   constraint(ALLOC_IN_RC(Ricklass_regP));
 2288   match(reg);
 2289   format %{ %}
 2290   interface(REG_INTER);
 2291 %}
 2292 
 2293 //----------Complex Operands---------------------------------------------------
 2294 // Indirect Memory Reference
 2295 operand indirect(sp_ptr_RegP reg) %{
 2296   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2297   match(reg);
 2298 
 2299   op_cost(100);
 2300   format %{ "[$reg]" %}
 2301   interface(MEMORY_INTER) %{
 2302     base($reg);
 2303     index(0xf); // PC => no index
 2304     scale(0x0);
 2305     disp(0x0);
 2306   %}
 2307 %}
 2308 
 2309 
 2310 // Indirect with Offset in ]-4096, 4096[
 2311 operand indOffset12(sp_ptr_RegP reg, immI12 offset) %{
 2312   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2313   match(AddP reg offset);
 2314 
 2315   op_cost(100);
 2316   format %{ "[$reg + $offset]" %}
 2317   interface(MEMORY_INTER) %{
 2318     base($reg);
 2319     index(0xf); // PC => no index
 2320     scale(0x0);
 2321     disp($offset);
 2322   %}
 2323 %}
 2324 
 2325 // Indirect with offset for float load/store
 2326 operand indOffsetFP(sp_ptr_RegP reg, immIFP offset) %{
 2327   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2328   match(AddP reg offset);
 2329 
 2330   op_cost(100);
 2331   format %{ "[$reg + $offset]" %}
 2332   interface(MEMORY_INTER) %{
 2333     base($reg);
 2334     index(0xf); // PC => no index
 2335     scale(0x0);
 2336     disp($offset);
 2337   %}
 2338 %}
 2339 
 2340 // Indirect with Offset for half and double words
 2341 operand indOffsetHD(sp_ptr_RegP reg, immIHD offset) %{
 2342   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2343   match(AddP reg offset);
 2344 
 2345   op_cost(100);
 2346   format %{ "[$reg + $offset]" %}
 2347   interface(MEMORY_INTER) %{
 2348     base($reg);
 2349     index(0xf); // PC => no index
 2350     scale(0x0);
 2351     disp($offset);
 2352   %}
 2353 %}
 2354 
 2355 // Indirect with Offset and Offset+4 in ]-1024, 1024[
 2356 operand indOffsetFPx2(sp_ptr_RegP reg, immX10x2 offset) %{
 2357   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2358   match(AddP reg offset);
 2359 
 2360   op_cost(100);
 2361   format %{ "[$reg + $offset]" %}
 2362   interface(MEMORY_INTER) %{
 2363     base($reg);
 2364     index(0xf); // PC => no index
 2365     scale(0x0);
 2366     disp($offset);
 2367   %}
 2368 %}
 2369 
 2370 // Indirect with Offset and Offset+4 in ]-4096, 4096[
 2371 operand indOffset12x2(sp_ptr_RegP reg, immI12x2 offset) %{
 2372   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2373   match(AddP reg offset);
 2374 
 2375   op_cost(100);
 2376   format %{ "[$reg + $offset]" %}
 2377   interface(MEMORY_INTER) %{
 2378     base($reg);
 2379     index(0xf); // PC => no index
 2380     scale(0x0);
 2381     disp($offset);
 2382   %}
 2383 %}
 2384 
 2385 // Indirect with Register Index
 2386 operand indIndex(iRegP addr, iRegX index) %{
 2387   constraint(ALLOC_IN_RC(ptr_reg));
 2388   match(AddP addr index);
 2389 
 2390   op_cost(100);
 2391   format %{ "[$addr + $index]" %}
 2392   interface(MEMORY_INTER) %{
 2393     base($addr);
 2394     index($index);
 2395     scale(0x0);
 2396     disp(0x0);
 2397   %}
 2398 %}
 2399 
 2400 // Indirect Memory Times Scale Plus Index Register
 2401 operand indIndexScale(iRegP addr, iRegX index, immU5 scale) %{
 2402   constraint(ALLOC_IN_RC(ptr_reg));
 2403   match(AddP addr (LShiftX index scale));
 2404 
 2405   op_cost(100);
 2406   format %{"[$addr + $index << $scale]" %}
 2407   interface(MEMORY_INTER) %{
 2408     base($addr);
 2409     index($index);
 2410     scale($scale);
 2411     disp(0x0);
 2412   %}
 2413 %}
 2414 
 2415 // Operands for expressing Control Flow
 2416 // NOTE:  Label is a predefined operand which should not be redefined in
 2417 //        the AD file.  It is generically handled within the ADLC.
 2418 
 2419 //----------Conditional Branch Operands----------------------------------------
 2420 // Comparison Op  - This is the operation of the comparison, and is limited to
 2421 //                  the following set of codes:
 2422 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
 2423 //
 2424 // Other attributes of the comparison, such as unsignedness, are specified
 2425 // by the comparison instruction that sets a condition code flags register.
 2426 // That result is represented by a flags operand whose subtype is appropriate
 2427 // to the unsignedness (etc.) of the comparison.
 2428 //
 2429 // Later, the instruction which matches both the Comparison Op (a Bool) and
 2430 // the flags (produced by the Cmp) specifies the coding of the comparison op
 2431 // by matching a specific subtype of Bool operand below, such as cmpOpU.
 2432 
 2433 operand cmpOp() %{
 2434   match(Bool);
 2435 
 2436   format %{ "" %}
 2437   interface(COND_INTER) %{
 2438     equal(0x0);
 2439     not_equal(0x1);
 2440     less(0xb);
 2441     greater_equal(0xa);
 2442     less_equal(0xd);
 2443     greater(0xc);
 2444     overflow(0x0); // unsupported/unimplemented
 2445     no_overflow(0x0); // unsupported/unimplemented
 2446   %}
 2447 %}
 2448 
 2449 // integer comparison with 0, signed
 2450 operand cmpOp0() %{
 2451   match(Bool);
 2452 
 2453   format %{ "" %}
 2454   interface(COND_INTER) %{
 2455     equal(0x0);
 2456     not_equal(0x1);
 2457     less(0x4);
 2458     greater_equal(0x5);
 2459     less_equal(0xd); // unsupported
 2460     greater(0xc); // unsupported
 2461     overflow(0x0); // unsupported/unimplemented
 2462     no_overflow(0x0); // unsupported/unimplemented
 2463   %}
 2464 %}
 2465 
 2466 // Comparison Op, unsigned
 2467 operand cmpOpU() %{
 2468   match(Bool);
 2469 
 2470   format %{ "u" %}
 2471   interface(COND_INTER) %{
 2472     equal(0x0);
 2473     not_equal(0x1);
 2474     less(0x3);
 2475     greater_equal(0x2);
 2476     less_equal(0x9);
 2477     greater(0x8);
 2478     overflow(0x0); // unsupported/unimplemented
 2479     no_overflow(0x0); // unsupported/unimplemented
 2480   %}
 2481 %}
 2482 
 2483 // Comparison Op, pointer (same as unsigned)
 2484 operand cmpOpP() %{
 2485   match(Bool);
 2486 
 2487   format %{ "p" %}
 2488   interface(COND_INTER) %{
 2489     equal(0x0);
 2490     not_equal(0x1);
 2491     less(0x3);
 2492     greater_equal(0x2);
 2493     less_equal(0x9);
 2494     greater(0x8);
 2495     overflow(0x0); // unsupported/unimplemented
 2496     no_overflow(0x0); // unsupported/unimplemented
 2497   %}
 2498 %}
 2499 
 2500 operand cmpOpL() %{
 2501   match(Bool);
 2502 
 2503   format %{ "L" %}
 2504   interface(COND_INTER) %{
 2505     equal(0x0);
 2506     not_equal(0x1);
 2507     less(0xb);
 2508     greater_equal(0xa);
 2509     less_equal(0xd);
 2510     greater(0xc);
 2511     overflow(0x0); // unsupported/unimplemented
 2512     no_overflow(0x0); // unsupported/unimplemented
 2513   %}
 2514 %}
 2515 
 2516 operand cmpOpL_commute() %{
 2517   match(Bool);
 2518 
 2519   format %{ "L" %}
 2520   interface(COND_INTER) %{
 2521     equal(0x0);
 2522     not_equal(0x1);
 2523     less(0xc);
 2524     greater_equal(0xd);
 2525     less_equal(0xa);
 2526     greater(0xb);
 2527     overflow(0x0); // unsupported/unimplemented
 2528     no_overflow(0x0); // unsupported/unimplemented
 2529   %}
 2530 %}
 2531 
 2532 operand cmpOpUL() %{
 2533   match(Bool);
 2534 
 2535   format %{ "UL" %}
 2536   interface(COND_INTER) %{
 2537     equal(0x0);
 2538     not_equal(0x1);
 2539     less(0x3);
 2540     greater_equal(0x2);
 2541     less_equal(0x9);
 2542     greater(0x8);
 2543     overflow(0x0); // unsupported/unimplemented
 2544     no_overflow(0x0); // unsupported/unimplemented
 2545   %}
 2546 %}
 2547 
 2548 operand cmpOpUL_commute() %{
 2549   match(Bool);
 2550 
 2551   format %{ "UL" %}
 2552   interface(COND_INTER) %{
 2553     equal(0x0);
 2554     not_equal(0x1);
 2555     less(0x8);
 2556     greater_equal(0x9);
 2557     less_equal(0x2);
 2558     greater(0x3);
 2559     overflow(0x0); // unsupported/unimplemented
 2560     no_overflow(0x0); // unsupported/unimplemented
 2561   %}
 2562 %}
 2563 
 2564 
 2565 //----------OPERAND CLASSES----------------------------------------------------
 2566 // Operand Classes are groups of operands that are used to simplify
 2567 // instruction definitions by not requiring the AD writer to specify separate
 2568 // instructions for every form of operand when the instruction accepts
 2569 // multiple operand types with the same basic encoding and format.  The classic
 2570 // case of this is memory operands.
 2571 
 2572 opclass memoryI ( indirect, indOffset12, indIndex, indIndexScale );
 2573 opclass memoryP ( indirect, indOffset12, indIndex, indIndexScale );
 2574 opclass memoryF ( indirect, indOffsetFP );
 2575 opclass memoryF2 ( indirect, indOffsetFPx2 );
 2576 opclass memoryD ( indirect, indOffsetFP );
 2577 opclass memoryfp( indirect, indOffsetFP );
 2578 opclass memoryB ( indirect, indIndex, indOffsetHD );
 2579 opclass memoryS ( indirect, indIndex, indOffsetHD );
 2580 opclass memoryL ( indirect, indIndex, indOffsetHD );
 2581 
 2582 opclass memoryScaledI(indIndexScale);
 2583 opclass memoryScaledP(indIndexScale);
 2584 
 2585 // when ldrex/strex is used:
 2586 opclass memoryex ( indirect );
 2587 opclass indIndexMemory( indIndex );
 2588 opclass memorylong ( indirect, indOffset12x2 );
 2589 opclass memoryvld ( indirect /* , write back mode not implemented */ );
 2590 
 2591 //----------PIPELINE-----------------------------------------------------------
 2592 pipeline %{
 2593 
 2594 //----------ATTRIBUTES---------------------------------------------------------
 2595 attributes %{
 2596   fixed_size_instructions;           // Fixed size instructions
 2597   max_instructions_per_bundle = 4;   // Up to 4 instructions per bundle
 2598   instruction_unit_size = 4;         // An instruction is 4 bytes long
 2599   instruction_fetch_unit_size = 16;  // The processor fetches one line
 2600   instruction_fetch_units = 1;       // of 16 bytes
 2601 %}
 2602 
 2603 //----------RESOURCES----------------------------------------------------------
 2604 // Resources are the functional units available to the machine
 2605 resources(A0, A1, MS, BR, FA, FM, IDIV, FDIV, IALU = A0 | A1);
 2606 
 2607 //----------PIPELINE DESCRIPTION-----------------------------------------------
 2608 // Pipeline Description specifies the stages in the machine's pipeline
 2609 
 2610 pipe_desc(A, P, F, B, I, J, S, R, E, C, M, W, X, T, D);
 2611 
 2612 //----------PIPELINE CLASSES---------------------------------------------------
 2613 // Pipeline Classes describe the stages in which input and output are
 2614 // referenced by the hardware pipeline.
 2615 
 2616 // Integer ALU reg-reg operation
 2617 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 2618     single_instruction;
 2619     dst   : E(write);
 2620     src1  : R(read);
 2621     src2  : R(read);
 2622     IALU  : R;
 2623 %}
 2624 
 2625 // Integer ALU reg-reg long operation
 2626 pipe_class ialu_reg_reg_2(iRegL dst, iRegL src1, iRegL src2) %{
 2627     instruction_count(2);
 2628     dst   : E(write);
 2629     src1  : R(read);
 2630     src2  : R(read);
 2631     IALU  : R;
 2632     IALU  : R;
 2633 %}
 2634 
 2635 // Integer ALU reg-reg long dependent operation
 2636 pipe_class ialu_reg_reg_2_dep(iRegL dst, iRegL src1, iRegL src2, flagsReg cr) %{
 2637     instruction_count(1); multiple_bundles;
 2638     dst   : E(write);
 2639     src1  : R(read);
 2640     src2  : R(read);
 2641     cr    : E(write);
 2642     IALU  : R(2);
 2643 %}
 2644 
 2645 // Integer ALU reg-imm operation
 2646 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) %{
 2647     single_instruction;
 2648     dst   : E(write);
 2649     src1  : R(read);
 2650     IALU  : R;
 2651 %}
 2652 
 2653 // Integer ALU reg-reg operation with condition code
 2654 pipe_class ialu_cc_reg_reg(iRegI dst, iRegI src1, iRegI src2, flagsReg cr) %{
 2655     single_instruction;
 2656     dst   : E(write);
 2657     cr    : E(write);
 2658     src1  : R(read);
 2659     src2  : R(read);
 2660     IALU  : R;
 2661 %}
 2662 
 2663 // Integer ALU zero-reg operation
 2664 pipe_class ialu_zero_reg(iRegI dst, immI0 zero, iRegI src2) %{
 2665     single_instruction;
 2666     dst   : E(write);
 2667     src2  : R(read);
 2668     IALU  : R;
 2669 %}
 2670 
 2671 // Integer ALU zero-reg operation with condition code only
 2672 pipe_class ialu_cconly_zero_reg(flagsReg cr, iRegI src) %{
 2673     single_instruction;
 2674     cr    : E(write);
 2675     src   : R(read);
 2676     IALU  : R;
 2677 %}
 2678 
 2679 // Integer ALU reg-reg operation with condition code only
 2680 pipe_class ialu_cconly_reg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
 2681     single_instruction;
 2682     cr    : E(write);
 2683     src1  : R(read);
 2684     src2  : R(read);
 2685     IALU  : R;
 2686 %}
 2687 
 2688 // Integer ALU reg-imm operation with condition code only
 2689 pipe_class ialu_cconly_reg_imm(flagsReg cr, iRegI src1) %{
 2690     single_instruction;
 2691     cr    : E(write);
 2692     src1  : R(read);
 2693     IALU  : R;
 2694 %}
 2695 
 2696 // Integer ALU reg-reg-zero operation with condition code only
 2697 pipe_class ialu_cconly_reg_reg_zero(flagsReg cr, iRegI src1, iRegI src2, immI0 zero) %{
 2698     single_instruction;
 2699     cr    : E(write);
 2700     src1  : R(read);
 2701     src2  : R(read);
 2702     IALU  : R;
 2703 %}
 2704 
 2705 // Integer ALU reg-imm-zero operation with condition code only
 2706 pipe_class ialu_cconly_reg_imm_zero(flagsReg cr, iRegI src1, immI0 zero) %{
 2707     single_instruction;
 2708     cr    : E(write);
 2709     src1  : R(read);
 2710     IALU  : R;
 2711 %}
 2712 
 2713 // Integer ALU reg-reg operation with condition code, src1 modified
 2714 pipe_class ialu_cc_rwreg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
 2715     single_instruction;
 2716     cr    : E(write);
 2717     src1  : E(write);
 2718     src1  : R(read);
 2719     src2  : R(read);
 2720     IALU  : R;
 2721 %}
 2722 
 2723 pipe_class cmpL_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg cr ) %{
 2724     multiple_bundles;
 2725     dst   : E(write)+4;
 2726     cr    : E(write);
 2727     src1  : R(read);
 2728     src2  : R(read);
 2729     IALU  : R(3);
 2730     BR    : R(2);
 2731 %}
 2732 
 2733 // Integer ALU operation
 2734 pipe_class ialu_none(iRegI dst) %{
 2735     single_instruction;
 2736     dst   : E(write);
 2737     IALU  : R;
 2738 %}
 2739 
 2740 // Integer ALU reg operation
 2741 pipe_class ialu_reg(iRegI dst, iRegI src) %{
 2742     single_instruction; may_have_no_code;
 2743     dst   : E(write);
 2744     src   : R(read);
 2745     IALU  : R;
 2746 %}
 2747 
 2748 // Integer ALU reg conditional operation
 2749 // This instruction has a 1 cycle stall, and cannot execute
 2750 // in the same cycle as the instruction setting the condition
 2751 // code. We kludge this by pretending to read the condition code
 2752 // 1 cycle earlier, and by marking the functional units as busy
 2753 // for 2 cycles with the result available 1 cycle later than
 2754 // is really the case.
 2755 pipe_class ialu_reg_flags( iRegI op2_out, iRegI op2_in, iRegI op1, flagsReg cr ) %{
 2756     single_instruction;
 2757     op2_out : C(write);
 2758     op1     : R(read);
 2759     cr      : R(read);       // This is really E, with a 1 cycle stall
 2760     BR      : R(2);
 2761     MS      : R(2);
 2762 %}
 2763 
 2764 // Integer ALU reg operation
 2765 pipe_class ialu_move_reg_L_to_I(iRegI dst, iRegL src) %{
 2766     single_instruction; may_have_no_code;
 2767     dst   : E(write);
 2768     src   : R(read);
 2769     IALU  : R;
 2770 %}
 2771 pipe_class ialu_move_reg_I_to_L(iRegL dst, iRegI src) %{
 2772     single_instruction; may_have_no_code;
 2773     dst   : E(write);
 2774     src   : R(read);
 2775     IALU  : R;
 2776 %}
 2777 
 2778 // Two integer ALU reg operations
 2779 pipe_class ialu_reg_2(iRegL dst, iRegL src) %{
 2780     instruction_count(2);
 2781     dst   : E(write);
 2782     src   : R(read);
 2783     A0    : R;
 2784     A1    : R;
 2785 %}
 2786 
 2787 // Two integer ALU reg operations
 2788 pipe_class ialu_move_reg_L_to_L(iRegL dst, iRegL src) %{
 2789     instruction_count(2); may_have_no_code;
 2790     dst   : E(write);
 2791     src   : R(read);
 2792     A0    : R;
 2793     A1    : R;
 2794 %}
 2795 
 2796 // Integer ALU imm operation
 2797 pipe_class ialu_imm(iRegI dst) %{
 2798     single_instruction;
 2799     dst   : E(write);
 2800     IALU  : R;
 2801 %}
 2802 
 2803 pipe_class ialu_imm_n(iRegI dst) %{
 2804     single_instruction;
 2805     dst   : E(write);
 2806     IALU  : R;
 2807 %}
 2808 
 2809 // Integer ALU reg-reg with carry operation
 2810 pipe_class ialu_reg_reg_cy(iRegI dst, iRegI src1, iRegI src2, iRegI cy) %{
 2811     single_instruction;
 2812     dst   : E(write);
 2813     src1  : R(read);
 2814     src2  : R(read);
 2815     IALU  : R;
 2816 %}
 2817 
 2818 // Integer ALU cc operation
 2819 pipe_class ialu_cc(iRegI dst, flagsReg cc) %{
 2820     single_instruction;
 2821     dst   : E(write);
 2822     cc    : R(read);
 2823     IALU  : R;
 2824 %}
 2825 
 2826 // Integer ALU cc / second IALU operation
 2827 pipe_class ialu_reg_ialu( iRegI dst, iRegI src ) %{
 2828     instruction_count(1); multiple_bundles;
 2829     dst   : E(write)+1;
 2830     src   : R(read);
 2831     IALU  : R;
 2832 %}
 2833 
 2834 // Integer ALU cc / second IALU operation
 2835 pipe_class ialu_reg_reg_ialu( iRegI dst, iRegI p, iRegI q ) %{
 2836     instruction_count(1); multiple_bundles;
 2837     dst   : E(write)+1;
 2838     p     : R(read);
 2839     q     : R(read);
 2840     IALU  : R;
 2841 %}
 2842 
 2843 // Integer ALU hi-lo-reg operation
 2844 pipe_class ialu_hi_lo_reg(iRegI dst, immI src) %{
 2845     instruction_count(1); multiple_bundles;
 2846     dst   : E(write)+1;
 2847     IALU  : R(2);
 2848 %}
 2849 
 2850 // Long Constant
 2851 pipe_class loadConL( iRegL dst, immL src ) %{
 2852     instruction_count(2); multiple_bundles;
 2853     dst   : E(write)+1;
 2854     IALU  : R(2);
 2855     IALU  : R(2);
 2856 %}
 2857 
 2858 // Pointer Constant
 2859 pipe_class loadConP( iRegP dst, immP src ) %{
 2860     instruction_count(0); multiple_bundles;
 2861     fixed_latency(6);
 2862 %}
 2863 
 2864 // Long Constant small
 2865 pipe_class loadConLlo( iRegL dst, immL src ) %{
 2866     instruction_count(2);
 2867     dst   : E(write);
 2868     IALU  : R;
 2869     IALU  : R;
 2870 %}
 2871 
 2872 // [PHH] This is wrong for 64-bit.  See LdImmF/D.
 2873 pipe_class loadConFD(regF dst, immF src, iRegP tmp) %{
 2874     instruction_count(1); multiple_bundles;
 2875     src   : R(read);
 2876     dst   : M(write)+1;
 2877     IALU  : R;
 2878     MS    : E;
 2879 %}
 2880 
 2881 // Integer ALU nop operation
 2882 pipe_class ialu_nop() %{
 2883     single_instruction;
 2884     IALU  : R;
 2885 %}
 2886 
 2887 // Integer ALU nop operation
 2888 pipe_class ialu_nop_A0() %{
 2889     single_instruction;
 2890     A0    : R;
 2891 %}
 2892 
 2893 // Integer ALU nop operation
 2894 pipe_class ialu_nop_A1() %{
 2895     single_instruction;
 2896     A1    : R;
 2897 %}
 2898 
 2899 // Integer Multiply reg-reg operation
 2900 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 2901     single_instruction;
 2902     dst   : E(write);
 2903     src1  : R(read);
 2904     src2  : R(read);
 2905     MS    : R(5);
 2906 %}
 2907 
 2908 pipe_class mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 2909     single_instruction;
 2910     dst   : E(write)+4;
 2911     src1  : R(read);
 2912     src2  : R(read);
 2913     MS    : R(6);
 2914 %}
 2915 
 2916 // Integer Divide reg-reg
 2917 pipe_class sdiv_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI temp, flagsReg cr) %{
 2918     instruction_count(1); multiple_bundles;
 2919     dst   : E(write);
 2920     temp  : E(write);
 2921     src1  : R(read);
 2922     src2  : R(read);
 2923     temp  : R(read);
 2924     MS    : R(38);
 2925 %}
 2926 
 2927 // Long Divide
 2928 pipe_class divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 2929     dst  : E(write)+71;
 2930     src1 : R(read);
 2931     src2 : R(read)+1;
 2932     MS   : R(70);
 2933 %}
 2934 
 2935 // Floating Point Add Float
 2936 pipe_class faddF_reg_reg(regF dst, regF src1, regF src2) %{
 2937     single_instruction;
 2938     dst   : X(write);
 2939     src1  : E(read);
 2940     src2  : E(read);
 2941     FA    : R;
 2942 %}
 2943 
 2944 // Floating Point Add Double
 2945 pipe_class faddD_reg_reg(regD dst, regD src1, regD src2) %{
 2946     single_instruction;
 2947     dst   : X(write);
 2948     src1  : E(read);
 2949     src2  : E(read);
 2950     FA    : R;
 2951 %}
 2952 
 2953 // Floating Point Conditional Move based on integer flags
 2954 pipe_class int_conditional_float_move (cmpOp cmp, flagsReg cr, regF dst, regF src) %{
 2955     single_instruction;
 2956     dst   : X(write);
 2957     src   : E(read);
 2958     cr    : R(read);
 2959     FA    : R(2);
 2960     BR    : R(2);
 2961 %}
 2962 
 2963 // Floating Point Conditional Move based on integer flags
 2964 pipe_class int_conditional_double_move (cmpOp cmp, flagsReg cr, regD dst, regD src) %{
 2965     single_instruction;
 2966     dst   : X(write);
 2967     src   : E(read);
 2968     cr    : R(read);
 2969     FA    : R(2);
 2970     BR    : R(2);
 2971 %}
 2972 
 2973 // Floating Point Multiply Float
 2974 pipe_class fmulF_reg_reg(regF dst, regF src1, regF src2) %{
 2975     single_instruction;
 2976     dst   : X(write);
 2977     src1  : E(read);
 2978     src2  : E(read);
 2979     FM    : R;
 2980 %}
 2981 
 2982 // Floating Point Multiply Double
 2983 pipe_class fmulD_reg_reg(regD dst, regD src1, regD src2) %{
 2984     single_instruction;
 2985     dst   : X(write);
 2986     src1  : E(read);
 2987     src2  : E(read);
 2988     FM    : R;
 2989 %}
 2990 
 2991 // Floating Point Divide Float
 2992 pipe_class fdivF_reg_reg(regF dst, regF src1, regF src2) %{
 2993     single_instruction;
 2994     dst   : X(write);
 2995     src1  : E(read);
 2996     src2  : E(read);
 2997     FM    : R;
 2998     FDIV  : C(14);
 2999 %}
 3000 
 3001 // Floating Point Divide Double
 3002 pipe_class fdivD_reg_reg(regD dst, regD src1, regD src2) %{
 3003     single_instruction;
 3004     dst   : X(write);
 3005     src1  : E(read);
 3006     src2  : E(read);
 3007     FM    : R;
 3008     FDIV  : C(17);
 3009 %}
 3010 
 3011 // Floating Point Move/Negate/Abs Float
 3012 pipe_class faddF_reg(regF dst, regF src) %{
 3013     single_instruction;
 3014     dst   : W(write);
 3015     src   : E(read);
 3016     FA    : R(1);
 3017 %}
 3018 
 3019 // Floating Point Move/Negate/Abs Double
 3020 pipe_class faddD_reg(regD dst, regD src) %{
 3021     single_instruction;
 3022     dst   : W(write);
 3023     src   : E(read);
 3024     FA    : R;
 3025 %}
 3026 
 3027 // Floating Point Convert F->D
 3028 pipe_class fcvtF2D(regD dst, regF src) %{
 3029     single_instruction;
 3030     dst   : X(write);
 3031     src   : E(read);
 3032     FA    : R;
 3033 %}
 3034 
 3035 // Floating Point Convert I->D
 3036 pipe_class fcvtI2D(regD dst, regF src) %{
 3037     single_instruction;
 3038     dst   : X(write);
 3039     src   : E(read);
 3040     FA    : R;
 3041 %}
 3042 
 3043 // Floating Point Convert LHi->D
 3044 pipe_class fcvtLHi2D(regD dst, regD src) %{
 3045     single_instruction;
 3046     dst   : X(write);
 3047     src   : E(read);
 3048     FA    : R;
 3049 %}
 3050 
 3051 // Floating Point Convert L->D
 3052 pipe_class fcvtL2D(regD dst, iRegL src) %{
 3053     single_instruction;
 3054     dst   : X(write);
 3055     src   : E(read);
 3056     FA    : R;
 3057 %}
 3058 
 3059 // Floating Point Convert L->F
 3060 pipe_class fcvtL2F(regF dst, iRegL src) %{
 3061     single_instruction;
 3062     dst   : X(write);
 3063     src   : E(read);
 3064     FA    : R;
 3065 %}
 3066 
 3067 // Floating Point Convert D->F
 3068 pipe_class fcvtD2F(regD dst, regF src) %{
 3069     single_instruction;
 3070     dst   : X(write);
 3071     src   : E(read);
 3072     FA    : R;
 3073 %}
 3074 
 3075 // Floating Point Convert I->L
 3076 pipe_class fcvtI2L(regD dst, regF src) %{
 3077     single_instruction;
 3078     dst   : X(write);
 3079     src   : E(read);
 3080     FA    : R;
 3081 %}
 3082 
 3083 // Floating Point Convert D->F
 3084 pipe_class fcvtD2I(iRegI dst, regD src, flagsReg cr) %{
 3085     instruction_count(1); multiple_bundles;
 3086     dst   : X(write)+6;
 3087     src   : E(read);
 3088     FA    : R;
 3089 %}
 3090 
 3091 // Floating Point Convert D->L
 3092 pipe_class fcvtD2L(regD dst, regD src, flagsReg cr) %{
 3093     instruction_count(1); multiple_bundles;
 3094     dst   : X(write)+6;
 3095     src   : E(read);
 3096     FA    : R;
 3097 %}
 3098 
 3099 // Floating Point Convert F->I
 3100 pipe_class fcvtF2I(regF dst, regF src, flagsReg cr) %{
 3101     instruction_count(1); multiple_bundles;
 3102     dst   : X(write)+6;
 3103     src   : E(read);
 3104     FA    : R;
 3105 %}
 3106 
 3107 // Floating Point Convert F->L
 3108 pipe_class fcvtF2L(regD dst, regF src, flagsReg cr) %{
 3109     instruction_count(1); multiple_bundles;
 3110     dst   : X(write)+6;
 3111     src   : E(read);
 3112     FA    : R;
 3113 %}
 3114 
 3115 // Floating Point Convert I->F
 3116 pipe_class fcvtI2F(regF dst, regF src) %{
 3117     single_instruction;
 3118     dst   : X(write);
 3119     src   : E(read);
 3120     FA    : R;
 3121 %}
 3122 
 3123 // Floating Point Compare
 3124 pipe_class faddF_fcc_reg_reg_zero(flagsRegF cr, regF src1, regF src2, immI0 zero) %{
 3125     single_instruction;
 3126     cr    : X(write);
 3127     src1  : E(read);
 3128     src2  : E(read);
 3129     FA    : R;
 3130 %}
 3131 
 3132 // Floating Point Compare
 3133 pipe_class faddD_fcc_reg_reg_zero(flagsRegF cr, regD src1, regD src2, immI0 zero) %{
 3134     single_instruction;
 3135     cr    : X(write);
 3136     src1  : E(read);
 3137     src2  : E(read);
 3138     FA    : R;
 3139 %}
 3140 
 3141 // Floating Add Nop
 3142 pipe_class fadd_nop() %{
 3143     single_instruction;
 3144     FA  : R;
 3145 %}
 3146 
 3147 // Integer Store to Memory
 3148 pipe_class istore_mem_reg(memoryI mem, iRegI src) %{
 3149     single_instruction;
 3150     mem   : R(read);
 3151     src   : C(read);
 3152     MS    : R;
 3153 %}
 3154 
 3155 // Integer Store to Memory
 3156 pipe_class istore_mem_spORreg(memoryI mem, sp_ptr_RegP src) %{
 3157     single_instruction;
 3158     mem   : R(read);
 3159     src   : C(read);
 3160     MS    : R;
 3161 %}
 3162 
 3163 // Float Store
 3164 pipe_class fstoreF_mem_reg(memoryF mem, RegF src) %{
 3165     single_instruction;
 3166     mem : R(read);
 3167     src : C(read);
 3168     MS  : R;
 3169 %}
 3170 
 3171 // Float Store
 3172 pipe_class fstoreF_mem_zero(memoryF mem, immF0 src) %{
 3173     single_instruction;
 3174     mem : R(read);
 3175     MS  : R;
 3176 %}
 3177 
 3178 // Double Store
 3179 pipe_class fstoreD_mem_reg(memoryD mem, RegD src) %{
 3180     instruction_count(1);
 3181     mem : R(read);
 3182     src : C(read);
 3183     MS  : R;
 3184 %}
 3185 
 3186 // Double Store
 3187 pipe_class fstoreD_mem_zero(memoryD mem, immD0 src) %{
 3188     single_instruction;
 3189     mem : R(read);
 3190     MS  : R;
 3191 %}
 3192 
 3193 // Integer Load (when sign bit propagation not needed)
 3194 pipe_class iload_mem(iRegI dst, memoryI mem) %{
 3195     single_instruction;
 3196     mem : R(read);
 3197     dst : C(write);
 3198     MS  : R;
 3199 %}
 3200 
 3201 // Integer Load (when sign bit propagation or masking is needed)
 3202 pipe_class iload_mask_mem(iRegI dst, memoryI mem) %{
 3203     single_instruction;
 3204     mem : R(read);
 3205     dst : M(write);
 3206     MS  : R;
 3207 %}
 3208 
 3209 // Float Load
 3210 pipe_class floadF_mem(regF dst, memoryF mem) %{
 3211     single_instruction;
 3212     mem : R(read);
 3213     dst : M(write);
 3214     MS  : R;
 3215 %}
 3216 
 3217 // Float Load
 3218 pipe_class floadD_mem(regD dst, memoryD mem) %{
 3219     instruction_count(1); multiple_bundles; // Again, unaligned argument is only multiple case
 3220     mem : R(read);
 3221     dst : M(write);
 3222     MS  : R;
 3223 %}
 3224 
 3225 // Memory Nop
 3226 pipe_class mem_nop() %{
 3227     single_instruction;
 3228     MS  : R;
 3229 %}
 3230 
 3231 pipe_class sethi(iRegP dst, immI src) %{
 3232     single_instruction;
 3233     dst  : E(write);
 3234     IALU : R;
 3235 %}
 3236 
 3237 pipe_class loadPollP(iRegP poll) %{
 3238     single_instruction;
 3239     poll : R(read);
 3240     MS   : R;
 3241 %}
 3242 
 3243 pipe_class br(Universe br, label labl) %{
 3244     single_instruction;
 3245     BR  : R;
 3246 %}
 3247 
 3248 pipe_class br_cc(Universe br, cmpOp cmp, flagsReg cr, label labl) %{
 3249     single_instruction;
 3250     cr    : E(read);
 3251     BR    : R;
 3252 %}
 3253 
 3254 pipe_class br_reg(Universe br, cmpOp cmp, iRegI op1, label labl) %{
 3255     single_instruction;
 3256     op1 : E(read);
 3257     BR  : R;
 3258     MS  : R;
 3259 %}
 3260 
 3261 pipe_class br_nop() %{
 3262     single_instruction;
 3263     BR  : R;
 3264 %}
 3265 
 3266 pipe_class simple_call(method meth) %{
 3267     instruction_count(2); multiple_bundles; force_serialization;
 3268     fixed_latency(100);
 3269     BR  : R(1);
 3270     MS  : R(1);
 3271     A0  : R(1);
 3272 %}
 3273 
 3274 pipe_class compiled_call(method meth) %{
 3275     instruction_count(1); multiple_bundles; force_serialization;
 3276     fixed_latency(100);
 3277     MS  : R(1);
 3278 %}
 3279 
 3280 pipe_class call(method meth) %{
 3281     instruction_count(0); multiple_bundles; force_serialization;
 3282     fixed_latency(100);
 3283 %}
 3284 
 3285 pipe_class tail_call(Universe ignore, label labl) %{
 3286     single_instruction;
 3287     fixed_latency(100);
 3288     BR  : R(1);
 3289     MS  : R(1);
 3290 %}
 3291 
 3292 pipe_class ret(Universe ignore) %{
 3293     single_instruction;
 3294     BR  : R(1);
 3295     MS  : R(1);
 3296 %}
 3297 
 3298 // The real do-nothing guy
 3299 pipe_class empty( ) %{
 3300     instruction_count(0);
 3301 %}
 3302 
 3303 pipe_class long_memory_op() %{
 3304     instruction_count(0); multiple_bundles; force_serialization;
 3305     fixed_latency(25);
 3306     MS  : R(1);
 3307 %}
 3308 
 3309 // Check-cast
 3310 pipe_class partial_subtype_check_pipe(Universe ignore, iRegP array, iRegP match ) %{
 3311     array : R(read);
 3312     match  : R(read);
 3313     IALU   : R(2);
 3314     BR     : R(2);
 3315     MS     : R;
 3316 %}
 3317 
 3318 // Convert FPU flags into +1,0,-1
 3319 pipe_class floating_cmp( iRegI dst, regF src1, regF src2 ) %{
 3320     src1  : E(read);
 3321     src2  : E(read);
 3322     dst   : E(write);
 3323     FA    : R;
 3324     MS    : R(2);
 3325     BR    : R(2);
 3326 %}
 3327 
 3328 // Compare for p < q, and conditionally add y
 3329 pipe_class cadd_cmpltmask( iRegI p, iRegI q, iRegI y ) %{
 3330     p     : E(read);
 3331     q     : E(read);
 3332     y     : E(read);
 3333     IALU  : R(3)
 3334 %}
 3335 
 3336 // Define the class for the Nop node
 3337 define %{
 3338    MachNop = ialu_nop;
 3339 %}
 3340 
 3341 %}
 3342 
 3343 //----------INSTRUCTIONS-------------------------------------------------------
 3344 
 3345 //------------Special Nop instructions for bundling - no match rules-----------
 3346 // Nop using the A0 functional unit
 3347 instruct Nop_A0() %{
 3348   ins_pipe(ialu_nop_A0);
 3349 %}
 3350 
 3351 // Nop using the A1 functional unit
 3352 instruct Nop_A1( ) %{
 3353   ins_pipe(ialu_nop_A1);
 3354 %}
 3355 
 3356 // Nop using the memory functional unit
 3357 instruct Nop_MS( ) %{
 3358   ins_pipe(mem_nop);
 3359 %}
 3360 
 3361 // Nop using the floating add functional unit
 3362 instruct Nop_FA( ) %{
 3363   ins_pipe(fadd_nop);
 3364 %}
 3365 
 3366 // Nop using the branch functional unit
 3367 instruct Nop_BR( ) %{
 3368   ins_pipe(br_nop);
 3369 %}
 3370 
 3371 //----------Load/Store/Move Instructions---------------------------------------
 3372 //----------Load Instructions--------------------------------------------------
 3373 // Load Byte (8bit signed)
 3374 instruct loadB(iRegI dst, memoryB mem) %{
 3375   match(Set dst (LoadB mem));
 3376   ins_cost(MEMORY_REF_COST);
 3377 
 3378   size(4);
 3379   format %{ "LDRSB   $dst,$mem\t! byte -> int" %}
 3380   ins_encode %{
 3381     __ ldrsb($dst$$Register, $mem$$Address);
 3382   %}
 3383   ins_pipe(iload_mask_mem);
 3384 %}
 3385 
 3386 // Load Byte (8bit signed) into a Long Register
 3387 instruct loadB2L(iRegL dst, memoryB mem) %{
 3388   match(Set dst (ConvI2L (LoadB mem)));
 3389   ins_cost(MEMORY_REF_COST);
 3390 
 3391   size(8);
 3392   format %{ "LDRSB $dst.lo,$mem\t! byte -> long\n\t"
 3393             "ASR   $dst.hi,$dst.lo,31" %}
 3394   ins_encode %{
 3395     __ ldrsb($dst$$Register, $mem$$Address);
 3396     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
 3397   %}
 3398   ins_pipe(iload_mask_mem);
 3399 %}
 3400 
 3401 // Load Unsigned Byte (8bit UNsigned) into an int reg
 3402 instruct loadUB(iRegI dst, memoryB mem) %{
 3403   match(Set dst (LoadUB mem));
 3404   ins_cost(MEMORY_REF_COST);
 3405 
 3406   size(4);
 3407   format %{ "LDRB   $dst,$mem\t! ubyte -> int" %}
 3408   ins_encode %{
 3409     __ ldrb($dst$$Register, $mem$$Address);
 3410   %}
 3411   ins_pipe(iload_mem);
 3412 %}
 3413 
 3414 // Load Unsigned Byte (8bit UNsigned) into a Long Register
 3415 instruct loadUB2L(iRegL dst, memoryB mem) %{
 3416   match(Set dst (ConvI2L (LoadUB mem)));
 3417   ins_cost(MEMORY_REF_COST);
 3418 
 3419   size(8);
 3420   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
 3421             "MOV   $dst.hi,0" %}
 3422   ins_encode %{
 3423     __ ldrb($dst$$Register, $mem$$Address);
 3424     __ mov($dst$$Register->successor(), 0);
 3425   %}
 3426   ins_pipe(iload_mem);
 3427 %}
 3428 
 3429 // Load Unsigned Byte (8 bit UNsigned) with immediate mask into Long Register
 3430 instruct loadUB2L_limmI(iRegL dst, memoryB mem, limmIlow8 mask) %{
 3431   match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
 3432 
 3433   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 3434   size(12);
 3435   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
 3436             "MOV   $dst.hi,0\n\t"
 3437             "AND  $dst.lo,$dst.lo,$mask" %}
 3438   ins_encode %{
 3439     __ ldrb($dst$$Register, $mem$$Address);
 3440     __ mov($dst$$Register->successor(), 0);
 3441     __ andr($dst$$Register, $dst$$Register, limmI_low($mask$$constant, 8));
 3442   %}
 3443   ins_pipe(iload_mem);
 3444 %}
 3445 
 3446 // Load Short (16bit signed)
 3447 
 3448 instruct loadS(iRegI dst, memoryS mem) %{
 3449   match(Set dst (LoadS mem));
 3450   ins_cost(MEMORY_REF_COST);
 3451 
 3452   size(4);
 3453   format %{ "LDRSH   $dst,$mem\t! short" %}
 3454   ins_encode %{
 3455     __ ldrsh($dst$$Register, $mem$$Address);
 3456   %}
 3457   ins_pipe(iload_mask_mem);
 3458 %}
 3459 
 3460 // Load Short (16 bit signed) to Byte (8 bit signed)
 3461 instruct loadS2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
 3462   match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
 3463   ins_cost(MEMORY_REF_COST);
 3464 
 3465   size(4);
 3466 
 3467   format %{ "LDRSB   $dst,$mem\t! short -> byte" %}
 3468   ins_encode %{
 3469     __ ldrsb($dst$$Register, $mem$$Address);
 3470   %}
 3471   ins_pipe(iload_mask_mem);
 3472 %}
 3473 
 3474 // Load Short (16bit signed) into a Long Register
 3475 instruct loadS2L(iRegL dst, memoryS mem) %{
 3476   match(Set dst (ConvI2L (LoadS mem)));
 3477   ins_cost(MEMORY_REF_COST);
 3478 
 3479   size(8);
 3480   format %{ "LDRSH $dst.lo,$mem\t! short -> long\n\t"
 3481             "ASR   $dst.hi,$dst.lo,31" %}
 3482   ins_encode %{
 3483     __ ldrsh($dst$$Register, $mem$$Address);
 3484     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
 3485   %}
 3486   ins_pipe(iload_mask_mem);
 3487 %}
 3488 
 3489 // Load Unsigned Short/Char (16bit UNsigned)
 3490 
 3491 
 3492 instruct loadUS(iRegI dst, memoryS mem) %{
 3493   match(Set dst (LoadUS mem));
 3494   ins_cost(MEMORY_REF_COST);
 3495 
 3496   size(4);
 3497   format %{ "LDRH   $dst,$mem\t! ushort/char" %}
 3498   ins_encode %{
 3499     __ ldrh($dst$$Register, $mem$$Address);
 3500   %}
 3501   ins_pipe(iload_mem);
 3502 %}
 3503 
 3504 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
 3505 instruct loadUS2B(iRegI dst, memoryB mem, immI_24 twentyfour) %{
 3506   match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
 3507   ins_cost(MEMORY_REF_COST);
 3508 
 3509   size(4);
 3510   format %{ "LDRSB   $dst,$mem\t! ushort -> byte" %}
 3511   ins_encode %{
 3512     __ ldrsb($dst$$Register, $mem$$Address);
 3513   %}
 3514   ins_pipe(iload_mask_mem);
 3515 %}
 3516 
 3517 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register
 3518 instruct loadUS2L(iRegL dst, memoryS mem) %{
 3519   match(Set dst (ConvI2L (LoadUS mem)));
 3520   ins_cost(MEMORY_REF_COST);
 3521 
 3522   size(8);
 3523   format %{ "LDRH  $dst.lo,$mem\t! short -> long\n\t"
 3524             "MOV   $dst.hi, 0" %}
 3525   ins_encode %{
 3526     __ ldrh($dst$$Register, $mem$$Address);
 3527     __ mov($dst$$Register->successor(), 0);
 3528   %}
 3529   ins_pipe(iload_mem);
 3530 %}
 3531 
 3532 // Load Unsigned Short/Char (16bit UNsigned) with mask 0xFF into a Long Register
 3533 instruct loadUS2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
 3534   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
 3535   ins_cost(MEMORY_REF_COST);
 3536 
 3537   size(8);
 3538   format %{ "LDRB  $dst.lo,$mem\t! \n\t"
 3539             "MOV   $dst.hi, 0" %}
 3540   ins_encode %{
 3541     __ ldrb($dst$$Register, $mem$$Address);
 3542     __ mov($dst$$Register->successor(), 0);
 3543   %}
 3544   ins_pipe(iload_mem);
 3545 %}
 3546 
 3547 // Load Unsigned Short/Char (16bit UNsigned) with a immediate mask into a Long Register
 3548 instruct loadUS2L_limmI(iRegL dst, memoryS mem, limmI mask) %{
 3549   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
 3550   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 3551 
 3552   size(12);
 3553   format %{ "LDRH   $dst,$mem\t! ushort/char & mask -> long\n\t"
 3554             "MOV    $dst.hi, 0\n\t"
 3555             "AND    $dst,$dst,$mask" %}
 3556   ins_encode %{
 3557     __ ldrh($dst$$Register, $mem$$Address);
 3558     __ mov($dst$$Register->successor(), 0);
 3559     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
 3560   %}
 3561   ins_pipe(iload_mem);
 3562 %}
 3563 
 3564 // Load Integer
 3565 
 3566 
 3567 instruct loadI(iRegI dst, memoryI mem) %{
 3568   match(Set dst (LoadI mem));
 3569   ins_cost(MEMORY_REF_COST);
 3570 
 3571   size(4);
 3572   format %{ "ldr_s32 $dst,$mem\t! int" %}
 3573   ins_encode %{
 3574     __ ldr_s32($dst$$Register, $mem$$Address);
 3575   %}
 3576   ins_pipe(iload_mem);
 3577 %}
 3578 
 3579 // Load Integer to Byte (8 bit signed)
 3580 instruct loadI2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
 3581   match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
 3582   ins_cost(MEMORY_REF_COST);
 3583 
 3584   size(4);
 3585 
 3586   format %{ "LDRSB   $dst,$mem\t! int -> byte" %}
 3587   ins_encode %{
 3588     __ ldrsb($dst$$Register, $mem$$Address);
 3589   %}
 3590   ins_pipe(iload_mask_mem);
 3591 %}
 3592 
 3593 // Load Integer to Unsigned Byte (8 bit UNsigned)
 3594 instruct loadI2UB(iRegI dst, memoryB mem, immI_255 mask) %{
 3595   match(Set dst (AndI (LoadI mem) mask));
 3596   ins_cost(MEMORY_REF_COST);
 3597 
 3598   size(4);
 3599 
 3600   format %{ "LDRB   $dst,$mem\t! int -> ubyte" %}
 3601   ins_encode %{
 3602     __ ldrb($dst$$Register, $mem$$Address);
 3603   %}
 3604   ins_pipe(iload_mask_mem);
 3605 %}
 3606 
 3607 // Load Integer to Short (16 bit signed)
 3608 instruct loadI2S(iRegI dst, memoryS mem, immI_16 sixteen) %{
 3609   match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
 3610   ins_cost(MEMORY_REF_COST);
 3611 
 3612   size(4);
 3613   format %{ "LDRSH   $dst,$mem\t! int -> short" %}
 3614   ins_encode %{
 3615     __ ldrsh($dst$$Register, $mem$$Address);
 3616   %}
 3617   ins_pipe(iload_mask_mem);
 3618 %}
 3619 
 3620 // Load Integer to Unsigned Short (16 bit UNsigned)
 3621 instruct loadI2US(iRegI dst, memoryS mem, immI_65535 mask) %{
 3622   match(Set dst (AndI (LoadI mem) mask));
 3623   ins_cost(MEMORY_REF_COST);
 3624 
 3625   size(4);
 3626   format %{ "LDRH   $dst,$mem\t! int -> ushort/char" %}
 3627   ins_encode %{
 3628     __ ldrh($dst$$Register, $mem$$Address);
 3629   %}
 3630   ins_pipe(iload_mask_mem);
 3631 %}
 3632 
 3633 // Load Integer into a Long Register
 3634 instruct loadI2L(iRegL dst, memoryI mem) %{
 3635   match(Set dst (ConvI2L (LoadI mem)));
 3636   ins_cost(MEMORY_REF_COST);
 3637 
 3638   size(8);
 3639   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
 3640             "ASR   $dst.hi,$dst.lo,31\t! int->long" %}
 3641   ins_encode %{
 3642     __ ldr($dst$$Register, $mem$$Address);
 3643     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
 3644   %}
 3645   ins_pipe(iload_mask_mem);
 3646 %}
 3647 
 3648 // Load Integer with mask 0xFF into a Long Register
 3649 instruct loadI2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
 3650   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3651   ins_cost(MEMORY_REF_COST);
 3652 
 3653   size(8);
 3654   format %{ "LDRB   $dst.lo,$mem\t! int & 0xFF -> long\n\t"
 3655             "MOV    $dst.hi, 0" %}
 3656   ins_encode %{
 3657     __ ldrb($dst$$Register, $mem$$Address);
 3658     __ mov($dst$$Register->successor(), 0);
 3659   %}
 3660   ins_pipe(iload_mem);
 3661 %}
 3662 
 3663 // Load Integer with mask 0xFFFF into a Long Register
 3664 instruct loadI2L_immI_65535(iRegL dst, memoryS mem, immI_65535 mask) %{
 3665   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3666   ins_cost(MEMORY_REF_COST);
 3667 
 3668   size(8);
 3669   format %{ "LDRH   $dst,$mem\t! int & 0xFFFF -> long\n\t"
 3670             "MOV    $dst.hi, 0" %}
 3671   ins_encode %{
 3672     __ ldrh($dst$$Register, $mem$$Address);
 3673     __ mov($dst$$Register->successor(), 0);
 3674   %}
 3675   ins_pipe(iload_mask_mem);
 3676 %}
 3677 
 3678 // Load Integer with a 31-bit immediate mask into a Long Register
 3679 instruct loadI2L_limmU31(iRegL dst, memoryI mem, limmU31 mask) %{
 3680   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3681   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 3682 
 3683   size(12);
 3684   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
 3685             "MOV    $dst.hi, 0\n\t"
 3686             "AND   $dst,$dst,$mask" %}
 3687 
 3688   ins_encode %{
 3689     __ ldr($dst$$Register, $mem$$Address);
 3690     __ mov($dst$$Register->successor(), 0);
 3691     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
 3692   %}
 3693   ins_pipe(iload_mem);
 3694 %}
 3695 
 3696 // Load Integer with a 31-bit mask into a Long Register
 3697 // FIXME: use iRegI mask, remove tmp?
 3698 instruct loadI2L_immU31(iRegL dst, memoryI mem, immU31 mask, iRegI tmp) %{
 3699   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3700   effect(TEMP dst, TEMP tmp);
 3701 
 3702   ins_cost(MEMORY_REF_COST + 4*DEFAULT_COST);
 3703   size(20);
 3704   format %{ "LDR      $mem,$dst\t! int & 31-bit mask -> long\n\t"
 3705             "MOV      $dst.hi, 0\n\t"
 3706             "MOV_SLOW $tmp,$mask\n\t"
 3707             "AND      $dst,$tmp,$dst" %}
 3708   ins_encode %{
 3709     __ ldr($dst$$Register, $mem$$Address);
 3710     __ mov($dst$$Register->successor(), 0);
 3711     __ mov_slow($tmp$$Register, $mask$$constant);
 3712     __ andr($dst$$Register, $dst$$Register, $tmp$$Register);
 3713   %}
 3714   ins_pipe(iload_mem);
 3715 %}
 3716 
 3717 // Load Unsigned Integer into a Long Register
 3718 instruct loadUI2L(iRegL dst, memoryI mem, immL_32bits mask) %{
 3719   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
 3720   ins_cost(MEMORY_REF_COST);
 3721 
 3722   size(8);
 3723   format %{ "LDR   $dst.lo,$mem\t! uint -> long\n\t"
 3724             "MOV   $dst.hi,0" %}
 3725   ins_encode %{
 3726     __ ldr($dst$$Register, $mem$$Address);
 3727     __ mov($dst$$Register->successor(), 0);
 3728   %}
 3729   ins_pipe(iload_mem);
 3730 %}
 3731 
 3732 // Load Long
 3733 
 3734 
 3735 instruct loadL(iRegLd dst, memoryL mem ) %{
 3736   predicate(!((LoadLNode*)n)->require_atomic_access());
 3737   match(Set dst (LoadL mem));
 3738   effect(TEMP dst);
 3739   ins_cost(MEMORY_REF_COST);
 3740 
 3741   size(4);
 3742   format %{ "ldr_64  $dst,$mem\t! long" %}
 3743   ins_encode %{
 3744     __ ldr_64($dst$$Register, $mem$$Address);
 3745   %}
 3746   ins_pipe(iload_mem);
 3747 %}
 3748 
 3749 instruct loadL_2instr(iRegL dst, memorylong mem ) %{
 3750   predicate(!((LoadLNode*)n)->require_atomic_access());
 3751   match(Set dst (LoadL mem));
 3752   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
 3753 
 3754   size(8);
 3755   format %{ "LDR    $dst.lo,$mem \t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
 3756             "LDR    $dst.hi,$mem+4 or $mem" %}
 3757   ins_encode %{
 3758     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 3759     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 3760 
 3761     if ($dst$$Register == reg_to_register_object($mem$$base)) {
 3762       __ ldr($dst$$Register->successor(), Amemhi);
 3763       __ ldr($dst$$Register, Amemlo);
 3764     } else {
 3765       __ ldr($dst$$Register, Amemlo);
 3766       __ ldr($dst$$Register->successor(), Amemhi);
 3767     }
 3768   %}
 3769   ins_pipe(iload_mem);
 3770 %}
 3771 
 3772 instruct loadL_volatile(iRegL dst, indirect mem ) %{
 3773   predicate(((LoadLNode*)n)->require_atomic_access());
 3774   match(Set dst (LoadL mem));
 3775   ins_cost(MEMORY_REF_COST);
 3776 
 3777   size(4);
 3778   format %{ "LDMIA    $dst,$mem\t! long" %}
 3779   ins_encode %{
 3780     // FIXME: why is ldmia considered atomic?  Should be ldrexd
 3781     RegisterSet set($dst$$Register);
 3782     set = set | reg_to_register_object($dst$$reg + 1);
 3783     __ ldmia(reg_to_register_object($mem$$base), set);
 3784   %}
 3785   ins_pipe(iload_mem);
 3786 %}
 3787 
 3788 instruct loadL_volatile_fp(iRegL dst, memoryD mem ) %{
 3789   predicate(((LoadLNode*)n)->require_atomic_access());
 3790   match(Set dst (LoadL mem));
 3791   ins_cost(MEMORY_REF_COST);
 3792 
 3793   size(8);
 3794   format %{ "FLDD      S14, $mem"
 3795             "FMRRD    $dst, S14\t! long \n't" %}
 3796   ins_encode %{
 3797     __ fldd(S14, $mem$$Address);
 3798     __ fmrrd($dst$$Register, $dst$$Register->successor(), S14);
 3799   %}
 3800   ins_pipe(iload_mem);
 3801 %}
 3802 
 3803 instruct loadL_unaligned(iRegL dst, memorylong mem ) %{
 3804   match(Set dst (LoadL_unaligned mem));
 3805   ins_cost(MEMORY_REF_COST);
 3806 
 3807   size(8);
 3808   format %{ "LDR    $dst.lo,$mem\t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
 3809             "LDR    $dst.hi,$mem+4" %}
 3810   ins_encode %{
 3811     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 3812     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 3813 
 3814     if ($dst$$Register == reg_to_register_object($mem$$base)) {
 3815       __ ldr($dst$$Register->successor(), Amemhi);
 3816       __ ldr($dst$$Register, Amemlo);
 3817     } else {
 3818       __ ldr($dst$$Register, Amemlo);
 3819       __ ldr($dst$$Register->successor(), Amemhi);
 3820     }
 3821   %}
 3822   ins_pipe(iload_mem);
 3823 %}
 3824 
 3825 // Load Range
 3826 instruct loadRange(iRegI dst, memoryI mem) %{
 3827   match(Set dst (LoadRange mem));
 3828   ins_cost(MEMORY_REF_COST);
 3829 
 3830   size(4);
 3831   format %{ "LDR_u32 $dst,$mem\t! range" %}
 3832   ins_encode %{
 3833     __ ldr_u32($dst$$Register, $mem$$Address);
 3834   %}
 3835   ins_pipe(iload_mem);
 3836 %}
 3837 
 3838 // Load Pointer
 3839 
 3840 
 3841 instruct loadP(iRegP dst, memoryP mem) %{
 3842   predicate(!(UseG1GC && n->as_Load()->barrier_data() != 0));
 3843   match(Set dst (LoadP mem));
 3844   ins_cost(MEMORY_REF_COST);
 3845   size(4);
 3846 
 3847   format %{ "LDR   $dst,$mem\t! ptr" %}
 3848   ins_encode %{
 3849     __ ldr($dst$$Register, $mem$$Address);
 3850   %}
 3851   ins_pipe(iload_mem);
 3852 %}
 3853 
 3854 #ifdef XXX
 3855 // FIXME XXXX
 3856 //instruct loadSP(iRegP dst, memoryP mem) %{
 3857 instruct loadSP(SPRegP dst, memoryP mem, iRegP tmp) %{
 3858   match(Set dst (LoadP mem));
 3859   effect(TEMP tmp);
 3860   ins_cost(MEMORY_REF_COST+1);
 3861   size(8);
 3862 
 3863   format %{ "LDR   $tmp,$mem\t! ptr\n\t"
 3864             "MOV   $dst,$tmp\t! ptr" %}
 3865   ins_encode %{
 3866     __ ldr($tmp$$Register, $mem$$Address);
 3867     __ mov($dst$$Register, $tmp$$Register);
 3868   %}
 3869   ins_pipe(iload_mem);
 3870 %}
 3871 #endif
 3872 
 3873 #ifdef _LP64
 3874 // Load Compressed Pointer
 3875 
 3876 // XXX This variant shouldn't be necessary if 6217251 is implemented
 3877 instruct loadNoff(iRegN dst, memoryScaledI mem, aimmX off, iRegP tmp) %{
 3878   match(Set dst (LoadN (AddP mem off)));
 3879   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
 3880   effect(TEMP tmp);
 3881   size(4 * 2);
 3882 
 3883   format %{ "ldr_u32 $dst,$mem+$off\t! compressed ptr temp=$tmp" %}
 3884   ins_encode %{
 3885     Register base = reg_to_register_object($mem$$base);
 3886     __ add($tmp$$Register, base, $off$$constant);
 3887     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 3888     __ ldr_u32($dst$$Register, nmem);
 3889   %}
 3890   ins_pipe(iload_mem);
 3891 %}
 3892 
 3893 instruct loadN(iRegN dst, memoryI mem) %{
 3894   match(Set dst (LoadN mem));
 3895   ins_cost(MEMORY_REF_COST);
 3896   size(4);
 3897 
 3898   format %{ "ldr_u32 $dst,$mem\t! compressed ptr" %}
 3899   ins_encode %{
 3900     __ ldr_u32($dst$$Register, $mem$$Address);
 3901   %}
 3902   ins_pipe(iload_mem);
 3903 %}
 3904 #endif
 3905 
 3906 // Load Klass Pointer
 3907 instruct loadKlass(iRegP dst, memoryI mem) %{
 3908   match(Set dst (LoadKlass mem));
 3909   ins_cost(MEMORY_REF_COST);
 3910   size(4);
 3911 
 3912   format %{ "LDR   $dst,$mem\t! klass ptr" %}
 3913   ins_encode %{
 3914     __ ldr($dst$$Register, $mem$$Address);
 3915   %}
 3916   ins_pipe(iload_mem);
 3917 %}
 3918 
 3919 #ifdef _LP64
 3920 // Load narrow Klass Pointer
 3921 instruct loadNKlass(iRegN dst, memoryI mem) %{
 3922   match(Set dst (LoadNKlass mem));
 3923   ins_cost(MEMORY_REF_COST);
 3924   size(4);
 3925 
 3926   format %{ "ldr_u32 $dst,$mem\t! compressed klass ptr" %}
 3927   ins_encode %{
 3928     __ ldr_u32($dst$$Register, $mem$$Address);
 3929   %}
 3930   ins_pipe(iload_mem);
 3931 %}
 3932 #endif
 3933 
 3934 
 3935 instruct loadD(regD dst, memoryD mem) %{
 3936   match(Set dst (LoadD mem));
 3937   ins_cost(MEMORY_REF_COST);
 3938 
 3939   size(4);
 3940   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
 3941   // only LDREXD and STREXD are 64-bit single-copy atomic
 3942   format %{ "FLDD   $dst,$mem" %}
 3943   ins_encode %{
 3944     __ ldr_double($dst$$FloatRegister, $mem$$Address);
 3945   %}
 3946   ins_pipe(floadD_mem);
 3947 %}
 3948 
 3949 // Load Double - UNaligned
 3950 instruct loadD_unaligned(regD_low dst, memoryF2 mem ) %{
 3951   match(Set dst (LoadD_unaligned mem));
 3952   ins_cost(MEMORY_REF_COST*2+DEFAULT_COST);
 3953   size(8);
 3954   format %{ "FLDS    $dst.lo,$mem\t! misaligned double\n"
 3955           "\tFLDS    $dst.hi,$mem+4\t!" %}
 3956   ins_encode %{
 3957     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 3958     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 3959       __ flds($dst$$FloatRegister, Amemlo);
 3960       __ flds($dst$$FloatRegister->successor(), Amemhi);
 3961   %}
 3962   ins_pipe(iload_mem);
 3963 %}
 3964 
 3965 
 3966 instruct loadF(regF dst, memoryF mem) %{
 3967   match(Set dst (LoadF mem));
 3968 
 3969   ins_cost(MEMORY_REF_COST);
 3970   size(4);
 3971   format %{ "FLDS    $dst,$mem" %}
 3972   ins_encode %{
 3973     __ ldr_float($dst$$FloatRegister, $mem$$Address);
 3974   %}
 3975   ins_pipe(floadF_mem);
 3976 %}
 3977 
 3978 
 3979 // // Load Constant
 3980 instruct loadConI( iRegI dst, immI src ) %{
 3981   match(Set dst src);
 3982   ins_cost(DEFAULT_COST * 3/2);
 3983   format %{ "MOV_SLOW    $dst, $src" %}
 3984   ins_encode %{
 3985     __ mov_slow($dst$$Register, $src$$constant);
 3986   %}
 3987   ins_pipe(ialu_hi_lo_reg);
 3988 %}
 3989 
 3990 instruct loadConIMov( iRegI dst, immIMov src ) %{
 3991   match(Set dst src);
 3992   size(4);
 3993   format %{ "MOV    $dst, $src" %}
 3994   ins_encode %{
 3995     __ mov($dst$$Register, $src$$constant);
 3996   %}
 3997   ins_pipe(ialu_imm);
 3998 %}
 3999 
 4000 instruct loadConIMovn( iRegI dst, immIRotn src ) %{
 4001   match(Set dst src);
 4002   size(4);
 4003   format %{ "MVN    $dst, ~$src" %}
 4004   ins_encode %{
 4005     __ mvn($dst$$Register, ~$src$$constant);
 4006   %}
 4007   ins_pipe(ialu_imm_n);
 4008 %}
 4009 
 4010 instruct loadConI16( iRegI dst, immI16 src ) %{
 4011   match(Set dst src);
 4012   size(4);
 4013   format %{ "MOVW    $dst, $src" %}
 4014   ins_encode %{
 4015     __ movw($dst$$Register, $src$$constant);
 4016   %}
 4017   ins_pipe(ialu_imm_n);
 4018 %}
 4019 
 4020 instruct loadConP(iRegP dst, immP src) %{
 4021   match(Set dst src);
 4022   ins_cost(DEFAULT_COST * 3/2);
 4023   format %{ "MOV_SLOW    $dst,$src\t!ptr" %}
 4024   ins_encode %{
 4025     relocInfo::relocType constant_reloc = _opnds[1]->constant_reloc();
 4026     intptr_t val = $src$$constant;
 4027     if (constant_reloc == relocInfo::oop_type) {
 4028       __ mov_oop($dst$$Register, (jobject)val);
 4029     } else if (constant_reloc == relocInfo::metadata_type) {
 4030       __ mov_metadata($dst$$Register, (Metadata*)val);
 4031     } else {
 4032       __ mov_slow($dst$$Register, val);
 4033     }
 4034   %}
 4035   ins_pipe(loadConP);
 4036 %}
 4037 
 4038 
 4039 instruct loadConL(iRegL dst, immL src) %{
 4040   match(Set dst src);
 4041   ins_cost(DEFAULT_COST * 4);
 4042   format %{ "MOV_SLOW   $dst.lo, $src & 0x0FFFFFFFFL \t! long\n\t"
 4043             "MOV_SLOW   $dst.hi, $src >> 32" %}
 4044   ins_encode %{
 4045     __ mov_slow(reg_to_register_object($dst$$reg), $src$$constant & 0x0FFFFFFFFL);
 4046     __ mov_slow(reg_to_register_object($dst$$reg + 1), ((julong)($src$$constant)) >> 32);
 4047   %}
 4048   ins_pipe(loadConL);
 4049 %}
 4050 
 4051 instruct loadConL16( iRegL dst, immL16 src ) %{
 4052   match(Set dst src);
 4053   ins_cost(DEFAULT_COST * 2);
 4054 
 4055   size(8);
 4056   format %{ "MOVW    $dst.lo, $src \n\t"
 4057             "MOVW    $dst.hi, 0 \n\t" %}
 4058   ins_encode %{
 4059     __ movw($dst$$Register, $src$$constant);
 4060     __ movw($dst$$Register->successor(), 0);
 4061   %}
 4062   ins_pipe(ialu_imm);
 4063 %}
 4064 
 4065 instruct loadConF_imm8(regF dst, imm8F src) %{
 4066   match(Set dst src);
 4067   ins_cost(DEFAULT_COST);
 4068   size(4);
 4069 
 4070   format %{ "FCONSTS      $dst, $src"%}
 4071 
 4072   ins_encode %{
 4073     __ fconsts($dst$$FloatRegister, Assembler::float_num($src$$constant).imm8());
 4074   %}
 4075   ins_pipe(loadConFD); // FIXME
 4076 %}
 4077 
 4078 
 4079 instruct loadConF(regF dst, immF src, iRegI tmp) %{
 4080   match(Set dst src);
 4081   ins_cost(DEFAULT_COST * 2);
 4082   effect(TEMP tmp);
 4083   size(3*4);
 4084 
 4085   format %{ "MOV_SLOW  $tmp, $src\n\t"
 4086             "FMSR      $dst, $tmp"%}
 4087 
 4088   ins_encode %{
 4089     // FIXME revisit once 6961697 is in
 4090     union {
 4091       jfloat f;
 4092       int i;
 4093     } v;
 4094     v.f = $src$$constant;
 4095     __ mov_slow($tmp$$Register, v.i);
 4096     __ fmsr($dst$$FloatRegister, $tmp$$Register);
 4097   %}
 4098   ins_pipe(loadConFD); // FIXME
 4099 %}
 4100 
 4101 instruct loadConD_imm8(regD dst, imm8D src) %{
 4102   match(Set dst src);
 4103   ins_cost(DEFAULT_COST);
 4104   size(4);
 4105 
 4106   format %{ "FCONSTD      $dst, $src"%}
 4107 
 4108   ins_encode %{
 4109     __ fconstd($dst$$FloatRegister, Assembler::double_num($src$$constant).imm8());
 4110   %}
 4111   ins_pipe(loadConFD); // FIXME
 4112 %}
 4113 
 4114 instruct loadConD(regD dst, immD src, iRegP tmp) %{
 4115   match(Set dst src);
 4116   effect(TEMP tmp);
 4117   ins_cost(MEMORY_REF_COST);
 4118   format %{ "FLDD  $dst, [$constanttablebase + $constantoffset]\t! load from constant table: double=$src" %}
 4119 
 4120   ins_encode %{
 4121     Register r = $constanttablebase;
 4122     int offset  = $constantoffset($src);
 4123     if (!is_memoryD(offset)) {                // can't use a predicate
 4124                                               // in load constant instructs
 4125       __ add_slow($tmp$$Register, r, offset);
 4126       r = $tmp$$Register;
 4127       offset = 0;
 4128     }
 4129     __ ldr_double($dst$$FloatRegister, Address(r, offset));
 4130   %}
 4131   ins_pipe(loadConFD);
 4132 %}
 4133 
 4134 // Prefetch instructions.
 4135 // Must be safe to execute with invalid address (cannot fault).
 4136 
 4137 instruct prefetchAlloc_mp( memoryP mem ) %{
 4138   predicate(VM_Version::has_multiprocessing_extensions());
 4139   match( PrefetchAllocation mem );
 4140   ins_cost(MEMORY_REF_COST);
 4141   size(4);
 4142 
 4143   format %{ "PLDW $mem\t! Prefetch allocation" %}
 4144   ins_encode %{
 4145     __ pldw($mem$$Address);
 4146   %}
 4147   ins_pipe(iload_mem);
 4148 %}
 4149 
 4150 instruct prefetchAlloc_sp( memoryP mem ) %{
 4151   predicate(!VM_Version::has_multiprocessing_extensions());
 4152   match( PrefetchAllocation mem );
 4153   ins_cost(MEMORY_REF_COST);
 4154   size(4);
 4155 
 4156   format %{ "PLD $mem\t! Prefetch allocation" %}
 4157   ins_encode %{
 4158     __ pld($mem$$Address);
 4159   %}
 4160   ins_pipe(iload_mem);
 4161 %}
 4162 
 4163 
 4164 //----------Store Instructions-------------------------------------------------
 4165 // Store Byte
 4166 instruct storeB(memoryB mem, store_RegI src) %{
 4167   match(Set mem (StoreB mem src));
 4168   ins_cost(MEMORY_REF_COST);
 4169 
 4170   size(4);
 4171   format %{ "STRB    $src,$mem\t! byte" %}
 4172   ins_encode %{
 4173     __ strb($src$$Register, $mem$$Address);
 4174   %}
 4175   ins_pipe(istore_mem_reg);
 4176 %}
 4177 
 4178 // Store Char/Short
 4179 
 4180 
 4181 instruct storeC(memoryS mem, store_RegI src) %{
 4182   match(Set mem (StoreC mem src));
 4183   ins_cost(MEMORY_REF_COST);
 4184 
 4185   size(4);
 4186   format %{ "STRH    $src,$mem\t! short" %}
 4187   ins_encode %{
 4188     __ strh($src$$Register, $mem$$Address);
 4189   %}
 4190   ins_pipe(istore_mem_reg);
 4191 %}
 4192 
 4193 // Store Integer
 4194 
 4195 
 4196 instruct storeI(memoryI mem, store_RegI src) %{
 4197   match(Set mem (StoreI mem src));
 4198   ins_cost(MEMORY_REF_COST);
 4199 
 4200   size(4);
 4201   format %{ "str_32 $src,$mem" %}
 4202   ins_encode %{
 4203     __ str_32($src$$Register, $mem$$Address);
 4204   %}
 4205   ins_pipe(istore_mem_reg);
 4206 %}
 4207 
 4208 // Store Long
 4209 
 4210 
 4211 instruct storeL(memoryL mem, store_RegLd src) %{
 4212   predicate(!((StoreLNode*)n)->require_atomic_access());
 4213   match(Set mem (StoreL mem src));
 4214   ins_cost(MEMORY_REF_COST);
 4215 
 4216   size(4);
 4217   format %{ "str_64  $src,$mem\t! long\n\t" %}
 4218 
 4219   ins_encode %{
 4220     __ str_64($src$$Register, $mem$$Address);
 4221   %}
 4222   ins_pipe(istore_mem_reg);
 4223 %}
 4224 
 4225 instruct storeL_2instr(memorylong mem, iRegL src) %{
 4226   predicate(!((StoreLNode*)n)->require_atomic_access());
 4227   match(Set mem (StoreL mem src));
 4228   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
 4229 
 4230   size(8);
 4231   format %{ "STR    $src.lo,$mem\t! long\n\t"
 4232             "STR    $src.hi,$mem+4" %}
 4233 
 4234   ins_encode %{
 4235     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 4236     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 4237     __ str($src$$Register, Amemlo);
 4238     __ str($src$$Register->successor(), Amemhi);
 4239   %}
 4240   ins_pipe(istore_mem_reg);
 4241 %}
 4242 
 4243 instruct storeL_volatile(indirect mem, iRegL src) %{
 4244   predicate(((StoreLNode*)n)->require_atomic_access());
 4245   match(Set mem (StoreL mem src));
 4246   ins_cost(MEMORY_REF_COST);
 4247   size(4);
 4248   format %{ "STMIA    $src,$mem\t! long" %}
 4249   ins_encode %{
 4250     // FIXME: why is stmia considered atomic?  Should be strexd
 4251     RegisterSet set($src$$Register);
 4252     set = set | reg_to_register_object($src$$reg + 1);
 4253     __ stmia(reg_to_register_object($mem$$base), set);
 4254   %}
 4255   ins_pipe(istore_mem_reg);
 4256 %}
 4257 
 4258 instruct storeL_volatile_fp(memoryD mem, iRegL src) %{
 4259   predicate(((StoreLNode*)n)->require_atomic_access());
 4260   match(Set mem (StoreL mem src));
 4261   ins_cost(MEMORY_REF_COST);
 4262   size(8);
 4263   format %{ "FMDRR    S14, $src\t! long \n\t"
 4264             "FSTD     S14, $mem" %}
 4265   ins_encode %{
 4266     __ fmdrr(S14, $src$$Register, $src$$Register->successor());
 4267     __ fstd(S14, $mem$$Address);
 4268   %}
 4269   ins_pipe(istore_mem_reg);
 4270 %}
 4271 
 4272 #ifdef XXX
 4273 // Move SP Pointer
 4274 //instruct movSP(sp_ptr_RegP dst, SPRegP src) %{
 4275 //instruct movSP(iRegP dst, SPRegP src) %{
 4276 instruct movSP(store_ptr_RegP dst, SPRegP src) %{
 4277   match(Set dst src);
 4278 //predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con == TypeFunc::FramePtr);
 4279   ins_cost(MEMORY_REF_COST);
 4280   size(4);
 4281 
 4282   format %{ "MOV    $dst,$src\t! SP ptr\n\t" %}
 4283   ins_encode %{
 4284     assert(false, "XXX1 got here");
 4285     __ mov($dst$$Register, SP);
 4286     __ mov($dst$$Register, $src$$Register);
 4287   %}
 4288   ins_pipe(ialu_reg);
 4289 %}
 4290 #endif
 4291 
 4292 
 4293 // Store Pointer
 4294 
 4295 
 4296 instruct storeP(memoryP mem, store_ptr_RegP src) %{
 4297   predicate(!(UseG1GC && n->as_Store()->barrier_data() != 0));
 4298   match(Set mem (StoreP mem src));
 4299   ins_cost(MEMORY_REF_COST);
 4300   size(4);
 4301 
 4302   format %{ "STR    $src,$mem\t! ptr" %}
 4303   ins_encode %{
 4304     __ str($src$$Register, $mem$$Address);
 4305   %}
 4306   ins_pipe(istore_mem_spORreg);
 4307 %}
 4308 
 4309 
 4310 #ifdef _LP64
 4311 // Store Compressed Pointer
 4312 
 4313 
 4314 instruct storeN(memoryI mem, store_RegN src) %{
 4315   match(Set mem (StoreN mem src));
 4316   ins_cost(MEMORY_REF_COST);
 4317   size(4);
 4318 
 4319   format %{ "str_32 $src,$mem\t! compressed ptr" %}
 4320   ins_encode %{
 4321     __ str_32($src$$Register, $mem$$Address);
 4322   %}
 4323   ins_pipe(istore_mem_reg);
 4324 %}
 4325 
 4326 
 4327 // Store Compressed Klass Pointer
 4328 instruct storeNKlass(memoryI mem, store_RegN src) %{
 4329   match(Set mem (StoreNKlass mem src));
 4330   ins_cost(MEMORY_REF_COST);
 4331   size(4);
 4332 
 4333   format %{ "str_32 $src,$mem\t! compressed klass ptr" %}
 4334   ins_encode %{
 4335     __ str_32($src$$Register, $mem$$Address);
 4336   %}
 4337   ins_pipe(istore_mem_reg);
 4338 %}
 4339 #endif
 4340 
 4341 // Store Double
 4342 
 4343 
 4344 instruct storeD(memoryD mem, regD src) %{
 4345   match(Set mem (StoreD mem src));
 4346   ins_cost(MEMORY_REF_COST);
 4347 
 4348   size(4);
 4349   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
 4350   // only LDREXD and STREXD are 64-bit single-copy atomic
 4351   format %{ "FSTD   $src,$mem" %}
 4352   ins_encode %{
 4353     __ str_double($src$$FloatRegister, $mem$$Address);
 4354   %}
 4355   ins_pipe(fstoreD_mem_reg);
 4356 %}
 4357 
 4358 
 4359 // Store Float
 4360 
 4361 
 4362 instruct storeF( memoryF mem, regF src) %{
 4363   match(Set mem (StoreF mem src));
 4364   ins_cost(MEMORY_REF_COST);
 4365 
 4366   size(4);
 4367   format %{ "FSTS    $src,$mem" %}
 4368   ins_encode %{
 4369     __ str_float($src$$FloatRegister, $mem$$Address);
 4370   %}
 4371   ins_pipe(fstoreF_mem_reg);
 4372 %}
 4373 
 4374 
 4375 //----------MemBar Instructions-----------------------------------------------
 4376 // Memory barrier flavors
 4377 
 4378 // pattern-match out unnecessary membars
 4379 instruct membar_storestore() %{
 4380   match(MemBarStoreStore);
 4381   match(StoreStoreFence);
 4382   ins_cost(4*MEMORY_REF_COST);
 4383 
 4384   size(4);
 4385   format %{ "MEMBAR-storestore" %}
 4386   ins_encode %{
 4387     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore), noreg);
 4388   %}
 4389   ins_pipe(long_memory_op);
 4390 %}
 4391 
 4392 instruct membar_acquire() %{
 4393   match(MemBarAcquire);
 4394   match(LoadFence);
 4395   ins_cost(4*MEMORY_REF_COST);
 4396 
 4397   size(4);
 4398   format %{ "MEMBAR-acquire" %}
 4399   ins_encode %{
 4400     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), noreg);
 4401   %}
 4402   ins_pipe(long_memory_op);
 4403 %}
 4404 
 4405 instruct membar_acquire_lock() %{
 4406   match(MemBarAcquireLock);
 4407   ins_cost(0);
 4408 
 4409   size(0);
 4410   format %{ "!MEMBAR-acquire (CAS in prior FastLock so empty encoding)" %}
 4411   ins_encode( );
 4412   ins_pipe(empty);
 4413 %}
 4414 
 4415 instruct membar_release() %{
 4416   match(MemBarRelease);
 4417   match(StoreFence);
 4418   ins_cost(4*MEMORY_REF_COST);
 4419 
 4420   size(4);
 4421   format %{ "MEMBAR-release" %}
 4422   ins_encode %{
 4423     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), noreg);
 4424   %}
 4425   ins_pipe(long_memory_op);
 4426 %}
 4427 
 4428 instruct membar_release_lock() %{
 4429   match(MemBarReleaseLock);
 4430   ins_cost(0);
 4431 
 4432   size(0);
 4433   format %{ "!MEMBAR-release (CAS in succeeding FastUnlock so empty encoding)" %}
 4434   ins_encode( );
 4435   ins_pipe(empty);
 4436 %}
 4437 
 4438 instruct membar_storeload() %{
 4439   match(MemBarStoreLoad);
 4440   ins_cost(4*MEMORY_REF_COST);
 4441 
 4442   size(4);
 4443   format %{ "MEMBAR-storeload" %}
 4444   ins_encode %{
 4445     __ membar(MacroAssembler::StoreLoad, noreg);
 4446   %}
 4447   ins_pipe(long_memory_op);
 4448 %}
 4449 
 4450 instruct membar_volatile() %{
 4451   match(MemBarVolatile);
 4452   ins_cost(4*MEMORY_REF_COST);
 4453 
 4454   size(4);
 4455   format %{ "MEMBAR-volatile" %}
 4456   ins_encode %{
 4457     __ membar(MacroAssembler::StoreLoad, noreg);
 4458   %}
 4459   ins_pipe(long_memory_op);
 4460 %}
 4461 
 4462 instruct unnecessary_membar_volatile() %{
 4463   match(MemBarVolatile);
 4464   predicate(Matcher::post_store_load_barrier(n));
 4465   ins_cost(0);
 4466 
 4467   size(0);
 4468   format %{ "!MEMBAR-volatile (unnecessary so empty encoding)" %}
 4469   ins_encode( );
 4470   ins_pipe(empty);
 4471 %}
 4472 
 4473 instruct membar_full() %{
 4474   match(MemBarFull);
 4475   ins_cost(4*MEMORY_REF_COST);
 4476 
 4477   size(4);
 4478   format %{ "MEMBAR-full" %}
 4479   ins_encode %{
 4480     __ membar(MacroAssembler::StoreLoad, noreg);
 4481   %}
 4482   ins_pipe(long_memory_op);
 4483 %}
 4484 
 4485 //----------Register Move Instructions-----------------------------------------
 4486 
 4487 // Cast Index to Pointer for unsafe natives
 4488 instruct castX2P(iRegX src, iRegP dst) %{
 4489   match(Set dst (CastX2P src));
 4490 
 4491   format %{ "MOV    $dst,$src\t! IntX->Ptr if $dst != $src" %}
 4492   ins_encode %{
 4493     if ($dst$$Register !=  $src$$Register) {
 4494       __ mov($dst$$Register, $src$$Register);
 4495     }
 4496   %}
 4497   ins_pipe(ialu_reg);
 4498 %}
 4499 
 4500 // Cast Pointer to Index for unsafe natives
 4501 instruct castP2X(iRegP src, iRegX dst) %{
 4502   match(Set dst (CastP2X src));
 4503 
 4504   format %{ "MOV    $dst,$src\t! Ptr->IntX if $dst != $src" %}
 4505   ins_encode %{
 4506     if ($dst$$Register !=  $src$$Register) {
 4507       __ mov($dst$$Register, $src$$Register);
 4508     }
 4509   %}
 4510   ins_pipe(ialu_reg);
 4511 %}
 4512 
 4513 //----------Conditional Move---------------------------------------------------
 4514 // Conditional move
 4515 instruct cmovIP_reg(cmpOpP cmp, flagsRegP pcc, iRegI dst, iRegI src) %{
 4516   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
 4517   ins_cost(150);
 4518   size(4);
 4519   format %{ "MOV$cmp  $dst,$src\t! int" %}
 4520   ins_encode %{
 4521     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4522   %}
 4523   ins_pipe(ialu_reg);
 4524 %}
 4525 
 4526 
 4527 instruct cmovIP_immMov(cmpOpP cmp, flagsRegP pcc, iRegI dst, immIMov src) %{
 4528   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
 4529   ins_cost(140);
 4530   size(4);
 4531   format %{ "MOV$cmp  $dst,$src" %}
 4532   ins_encode %{
 4533     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4534   %}
 4535   ins_pipe(ialu_imm);
 4536 %}
 4537 
 4538 instruct cmovIP_imm16(cmpOpP cmp, flagsRegP pcc, iRegI dst, immI16 src) %{
 4539   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
 4540   ins_cost(140);
 4541   size(4);
 4542   format %{ "MOVw$cmp  $dst,$src" %}
 4543   ins_encode %{
 4544     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4545   %}
 4546   ins_pipe(ialu_imm);
 4547 %}
 4548 
 4549 instruct cmovI_reg(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src) %{
 4550   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4551   ins_cost(150);
 4552   size(4);
 4553   format %{ "MOV$cmp  $dst,$src" %}
 4554   ins_encode %{
 4555     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4556   %}
 4557   ins_pipe(ialu_reg);
 4558 %}
 4559 
 4560 
 4561 instruct cmovI_immMov(cmpOp cmp, flagsReg icc, iRegI dst, immIMov src) %{
 4562   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4563   ins_cost(140);
 4564   size(4);
 4565   format %{ "MOV$cmp  $dst,$src" %}
 4566   ins_encode %{
 4567     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4568   %}
 4569   ins_pipe(ialu_imm);
 4570 %}
 4571 
 4572 instruct cmovII_imm16(cmpOp cmp, flagsReg icc, iRegI dst, immI16 src) %{
 4573   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4574   ins_cost(140);
 4575   size(4);
 4576   format %{ "MOVw$cmp  $dst,$src" %}
 4577   ins_encode %{
 4578     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4579   %}
 4580   ins_pipe(ialu_imm);
 4581 %}
 4582 
 4583 instruct cmovII_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, iRegI src) %{
 4584   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4585   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4586             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4587             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4588             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4589   ins_cost(150);
 4590   size(4);
 4591   format %{ "MOV$cmp  $dst,$src" %}
 4592   ins_encode %{
 4593     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4594   %}
 4595   ins_pipe(ialu_reg);
 4596 %}
 4597 
 4598 instruct cmovII_immMov_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immIMov src) %{
 4599   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4600   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4601             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4602             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4603             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4604   ins_cost(140);
 4605   size(4);
 4606   format %{ "MOV$cmp  $dst,$src" %}
 4607   ins_encode %{
 4608     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4609   %}
 4610   ins_pipe(ialu_imm);
 4611 %}
 4612 
 4613 instruct cmovII_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immI16 src) %{
 4614   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4615   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4616             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4617             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4618             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4619   ins_cost(140);
 4620   size(4);
 4621   format %{ "MOVW$cmp  $dst,$src" %}
 4622   ins_encode %{
 4623     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4624   %}
 4625   ins_pipe(ialu_imm);
 4626 %}
 4627 
 4628 instruct cmovIIu_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
 4629   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4630   ins_cost(150);
 4631   size(4);
 4632   format %{ "MOV$cmp  $dst,$src" %}
 4633   ins_encode %{
 4634     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4635   %}
 4636   ins_pipe(ialu_reg);
 4637 %}
 4638 
 4639 instruct cmovIIu_immMov(cmpOpU cmp, flagsRegU icc, iRegI dst, immIMov src) %{
 4640   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4641   ins_cost(140);
 4642   size(4);
 4643   format %{ "MOV$cmp  $dst,$src" %}
 4644   ins_encode %{
 4645     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4646   %}
 4647   ins_pipe(ialu_imm);
 4648 %}
 4649 
 4650 instruct cmovIIu_imm16(cmpOpU cmp, flagsRegU icc, iRegI dst, immI16 src) %{
 4651   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4652   ins_cost(140);
 4653   size(4);
 4654   format %{ "MOVW$cmp  $dst,$src" %}
 4655   ins_encode %{
 4656     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4657   %}
 4658   ins_pipe(ialu_imm);
 4659 %}
 4660 
 4661 // Conditional move
 4662 instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{
 4663   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
 4664   ins_cost(150);
 4665   size(4);
 4666   format %{ "MOV$cmp  $dst,$src" %}
 4667   ins_encode %{
 4668     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4669   %}
 4670   ins_pipe(ialu_reg);
 4671 %}
 4672 
 4673 instruct cmovPP_imm(cmpOpP cmp, flagsRegP pcc, iRegP dst, immP0 src) %{
 4674   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
 4675   ins_cost(140);
 4676   size(4);
 4677   format %{ "MOV$cmp  $dst,$src" %}
 4678   ins_encode %{
 4679     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4680   %}
 4681   ins_pipe(ialu_imm);
 4682 %}
 4683 
 4684 // This instruction also works with CmpN so we don't need cmovPN_reg.
 4685 instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{
 4686   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4687   ins_cost(150);
 4688 
 4689   size(4);
 4690   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4691   ins_encode %{
 4692     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4693   %}
 4694   ins_pipe(ialu_reg);
 4695 %}
 4696 
 4697 instruct cmovPI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, iRegP src) %{
 4698   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4699   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4700             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4701             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4702             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4703   ins_cost(150);
 4704 
 4705   size(4);
 4706   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4707   ins_encode %{
 4708     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4709   %}
 4710   ins_pipe(ialu_reg);
 4711 %}
 4712 
 4713 instruct cmovPIu_reg(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src) %{
 4714   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4715   ins_cost(150);
 4716 
 4717   size(4);
 4718   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4719   ins_encode %{
 4720     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4721   %}
 4722   ins_pipe(ialu_reg);
 4723 %}
 4724 
 4725 instruct cmovPI_imm(cmpOp cmp, flagsReg icc, iRegP dst, immP0 src) %{
 4726   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4727   ins_cost(140);
 4728 
 4729   size(4);
 4730   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4731   ins_encode %{
 4732     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4733   %}
 4734   ins_pipe(ialu_imm);
 4735 %}
 4736 
 4737 instruct cmovPI_imm_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, immP0 src) %{
 4738   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4739   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4740             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4741             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4742             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4743   ins_cost(140);
 4744 
 4745   size(4);
 4746   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4747   ins_encode %{
 4748     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4749   %}
 4750   ins_pipe(ialu_imm);
 4751 %}
 4752 
 4753 instruct cmovPIu_imm(cmpOpU cmp, flagsRegU icc, iRegP dst, immP0 src) %{
 4754   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4755   ins_cost(140);
 4756 
 4757   size(4);
 4758   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4759   ins_encode %{
 4760     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4761   %}
 4762   ins_pipe(ialu_imm);
 4763 %}
 4764 
 4765 
 4766 // Conditional move
 4767 instruct cmovFP_reg(cmpOpP cmp, flagsRegP pcc, regF dst, regF src) %{
 4768   match(Set dst (CMoveF (Binary cmp pcc) (Binary dst src)));
 4769   ins_cost(150);
 4770   size(4);
 4771   format %{ "FCPYS$cmp $dst,$src" %}
 4772   ins_encode %{
 4773     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4774   %}
 4775   ins_pipe(int_conditional_float_move);
 4776 %}
 4777 
 4778 instruct cmovFI_reg(cmpOp cmp, flagsReg icc, regF dst, regF src) %{
 4779   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
 4780   ins_cost(150);
 4781 
 4782   size(4);
 4783   format %{ "FCPYS$cmp $dst,$src" %}
 4784   ins_encode %{
 4785     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4786   %}
 4787   ins_pipe(int_conditional_float_move);
 4788 %}
 4789 
 4790 instruct cmovFI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regF dst, regF src) %{
 4791   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
 4792   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4793             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4794             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4795             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4796   ins_cost(150);
 4797 
 4798   size(4);
 4799   format %{ "FCPYS$cmp $dst,$src" %}
 4800   ins_encode %{
 4801     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4802   %}
 4803   ins_pipe(int_conditional_float_move);
 4804 %}
 4805 
 4806 instruct cmovFIu_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src) %{
 4807   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
 4808   ins_cost(150);
 4809 
 4810   size(4);
 4811   format %{ "FCPYS$cmp $dst,$src" %}
 4812   ins_encode %{
 4813     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4814   %}
 4815   ins_pipe(int_conditional_float_move);
 4816 %}
 4817 
 4818 // Conditional move
 4819 instruct cmovDP_reg(cmpOpP cmp, flagsRegP pcc, regD dst, regD src) %{
 4820   match(Set dst (CMoveD (Binary cmp pcc) (Binary dst src)));
 4821   ins_cost(150);
 4822   size(4);
 4823   format %{ "FCPYD$cmp $dst,$src" %}
 4824   ins_encode %{
 4825     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4826   %}
 4827   ins_pipe(int_conditional_double_move);
 4828 %}
 4829 
 4830 instruct cmovDI_reg(cmpOp cmp, flagsReg icc, regD dst, regD src) %{
 4831   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
 4832   ins_cost(150);
 4833 
 4834   size(4);
 4835   format %{ "FCPYD$cmp $dst,$src" %}
 4836   ins_encode %{
 4837     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4838   %}
 4839   ins_pipe(int_conditional_double_move);
 4840 %}
 4841 
 4842 instruct cmovDI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regD dst, regD src) %{
 4843   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
 4844   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);
 4845   ins_cost(150);
 4846 
 4847   size(4);
 4848   format %{ "FCPYD$cmp $dst,$src" %}
 4849   ins_encode %{
 4850     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4851   %}
 4852   ins_pipe(int_conditional_double_move);
 4853 %}
 4854 
 4855 instruct cmovDIu_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src) %{
 4856   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
 4857   ins_cost(150);
 4858 
 4859   size(4);
 4860   format %{ "FCPYD$cmp $dst,$src" %}
 4861   ins_encode %{
 4862     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4863   %}
 4864   ins_pipe(int_conditional_double_move);
 4865 %}
 4866 
 4867 // Conditional move
 4868 instruct cmovLP_reg(cmpOpP cmp, flagsRegP pcc, iRegL dst, iRegL src) %{
 4869   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
 4870   ins_cost(150);
 4871 
 4872   size(8);
 4873   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 4874             "MOV$cmp  $dst.hi,$src.hi" %}
 4875   ins_encode %{
 4876     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4877     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 4878   %}
 4879   ins_pipe(ialu_reg);
 4880 %}
 4881 
 4882 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 4883 // (hi($con$$constant), lo($con$$constant)) becomes
 4884 instruct cmovLP_immRot(cmpOpP cmp, flagsRegP pcc, iRegL dst, immLlowRot src) %{
 4885   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
 4886   ins_cost(140);
 4887 
 4888   size(8);
 4889   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 4890             "MOV$cmp  $dst.hi,0" %}
 4891   ins_encode %{
 4892     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4893     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 4894   %}
 4895   ins_pipe(ialu_imm);
 4896 %}
 4897 
 4898 instruct cmovLP_imm16(cmpOpP cmp, flagsRegP pcc, iRegL dst, immL16 src) %{
 4899   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
 4900   ins_cost(140);
 4901 
 4902   size(8);
 4903   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 4904             "MOV$cmp  $dst.hi,0" %}
 4905   ins_encode %{
 4906     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4907     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 4908   %}
 4909   ins_pipe(ialu_imm);
 4910 %}
 4911 
 4912 instruct cmovLI_reg(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src) %{
 4913   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 4914   ins_cost(150);
 4915 
 4916   size(8);
 4917   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 4918             "MOV$cmp  $dst.hi,$src.hi" %}
 4919   ins_encode %{
 4920     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4921     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 4922   %}
 4923   ins_pipe(ialu_reg);
 4924 %}
 4925 
 4926 instruct cmovLI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, iRegL src) %{
 4927   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 4928   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4929             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4930             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4931             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4932   ins_cost(150);
 4933 
 4934   size(8);
 4935   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 4936             "MOV$cmp  $dst.hi,$src.hi" %}
 4937   ins_encode %{
 4938     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4939     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 4940   %}
 4941   ins_pipe(ialu_reg);
 4942 %}
 4943 
 4944 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 4945 // (hi($con$$constant), lo($con$$constant)) becomes
 4946 instruct cmovLI_immRot(cmpOp cmp, flagsReg icc, iRegL dst, immLlowRot src) %{
 4947   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 4948   ins_cost(140);
 4949 
 4950   size(8);
 4951   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 4952             "MOV$cmp  $dst.hi,0" %}
 4953   ins_encode %{
 4954     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4955     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 4956   %}
 4957   ins_pipe(ialu_imm);
 4958 %}
 4959 
 4960 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 4961 // (hi($con$$constant), lo($con$$constant)) becomes
 4962 instruct cmovLI_immRot_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immLlowRot src) %{
 4963   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 4964   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4965             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4966             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4967             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4968   ins_cost(140);
 4969 
 4970   size(8);
 4971   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 4972             "MOV$cmp  $dst.hi,0" %}
 4973   ins_encode %{
 4974     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4975     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 4976   %}
 4977   ins_pipe(ialu_imm);
 4978 %}
 4979 
 4980 instruct cmovLI_imm16(cmpOp cmp, flagsReg icc, iRegL dst, immL16 src) %{
 4981   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 4982   ins_cost(140);
 4983 
 4984   size(8);
 4985   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 4986             "MOV$cmp  $dst.hi,0" %}
 4987   ins_encode %{
 4988     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4989     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 4990   %}
 4991   ins_pipe(ialu_imm);
 4992 %}
 4993 
 4994 instruct cmovLI_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immL16 src) %{
 4995   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 4996   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4997             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4998             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4999             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 5000   ins_cost(140);
 5001 
 5002   size(8);
 5003   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5004             "MOV$cmp  $dst.hi,0" %}
 5005   ins_encode %{
 5006     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5007     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5008   %}
 5009   ins_pipe(ialu_imm);
 5010 %}
 5011 
 5012 instruct cmovLIu_reg(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src) %{
 5013   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5014   ins_cost(150);
 5015 
 5016   size(8);
 5017   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 5018             "MOV$cmp  $dst.hi,$src.hi" %}
 5019   ins_encode %{
 5020     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 5021     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 5022   %}
 5023   ins_pipe(ialu_reg);
 5024 %}
 5025 
 5026 
 5027 //----------OS and Locking Instructions----------------------------------------
 5028 
 5029 // This name is KNOWN by the ADLC and cannot be changed.
 5030 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
 5031 // for this guy.
 5032 instruct tlsLoadP(RthreadRegP dst) %{
 5033   match(Set dst (ThreadLocal));
 5034 
 5035   size(0);
 5036   ins_cost(0);
 5037   format %{ "! TLS is in $dst" %}
 5038   ins_encode( /*empty encoding*/ );
 5039   ins_pipe(ialu_none);
 5040 %}
 5041 
 5042 instruct checkCastPP( iRegP dst ) %{
 5043   match(Set dst (CheckCastPP dst));
 5044 
 5045   size(0);
 5046   format %{ "! checkcastPP of $dst" %}
 5047   ins_encode( /*empty encoding*/ );
 5048   ins_pipe(empty);
 5049 %}
 5050 
 5051 
 5052 instruct castPP( iRegP dst ) %{
 5053   match(Set dst (CastPP dst));
 5054   format %{ "! castPP of $dst" %}
 5055   ins_encode( /*empty encoding*/ );
 5056   ins_pipe(empty);
 5057 %}
 5058 
 5059 instruct castII( iRegI dst ) %{
 5060   match(Set dst (CastII dst));
 5061   format %{ "! castII of $dst" %}
 5062   ins_encode( /*empty encoding*/ );
 5063   ins_cost(0);
 5064   ins_pipe(empty);
 5065 %}
 5066 
 5067 instruct castLL( iRegL dst ) %{
 5068   match(Set dst (CastLL dst));
 5069   format %{ "! castLL of $dst" %}
 5070   ins_encode( /*empty encoding*/ );
 5071   ins_cost(0);
 5072   ins_pipe(empty);
 5073 %}
 5074 
 5075 instruct castFF( regF dst ) %{
 5076   match(Set dst (CastFF dst));
 5077   format %{ "! castFF of $dst" %}
 5078   ins_encode( /*empty encoding*/ );
 5079   ins_cost(0);
 5080   ins_pipe(empty);
 5081 %}
 5082 
 5083 instruct castDD( regD dst ) %{
 5084   match(Set dst (CastDD dst));
 5085   format %{ "! castDD of $dst" %}
 5086   ins_encode( /*empty encoding*/ );
 5087   ins_cost(0);
 5088   ins_pipe(empty);
 5089 %}
 5090 
 5091 instruct castVVD( vecD dst ) %{
 5092   match(Set dst (CastVV dst));
 5093   format %{ "! castVV of $dst" %}
 5094   ins_encode( /*empty encoding*/ );
 5095   ins_cost(0);
 5096   ins_pipe(empty);
 5097 %}
 5098 
 5099 instruct castVVX( vecX dst ) %{
 5100   match(Set dst (CastVV dst));
 5101   format %{ "! castVV of $dst" %}
 5102   ins_encode( /*empty encoding*/ );
 5103   ins_cost(0);
 5104   ins_pipe(empty);
 5105 %}
 5106 
 5107 
 5108 //----------Arithmetic Instructions--------------------------------------------
 5109 // Addition Instructions
 5110 // Register Addition
 5111 instruct addI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 5112   match(Set dst (AddI src1 src2));
 5113 
 5114   size(4);
 5115   format %{ "add_32 $dst,$src1,$src2\t! int" %}
 5116   ins_encode %{
 5117     __ add_32($dst$$Register, $src1$$Register, $src2$$Register);
 5118   %}
 5119   ins_pipe(ialu_reg_reg);
 5120 %}
 5121 
 5122 instruct addshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5123   match(Set dst (AddI (LShiftI src1 src2) src3));
 5124 
 5125   size(4);
 5126   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
 5127   ins_encode %{
 5128     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 5129   %}
 5130   ins_pipe(ialu_reg_reg);
 5131 %}
 5132 
 5133 
 5134 instruct addshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5135   match(Set dst (AddI (LShiftI src1 src2) src3));
 5136 
 5137   size(4);
 5138   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
 5139   ins_encode %{
 5140     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
 5141   %}
 5142   ins_pipe(ialu_reg_reg);
 5143 %}
 5144 
 5145 instruct addsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5146   match(Set dst (AddI (RShiftI src1 src2) src3));
 5147 
 5148   size(4);
 5149   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
 5150   ins_encode %{
 5151     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
 5152   %}
 5153   ins_pipe(ialu_reg_reg);
 5154 %}
 5155 
 5156 instruct addsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5157   match(Set dst (AddI (RShiftI src1 src2) src3));
 5158 
 5159   size(4);
 5160   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
 5161   ins_encode %{
 5162     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
 5163   %}
 5164   ins_pipe(ialu_reg_reg);
 5165 %}
 5166 
 5167 instruct addshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5168   match(Set dst (AddI (URShiftI src1 src2) src3));
 5169 
 5170   size(4);
 5171   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
 5172   ins_encode %{
 5173     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 5174   %}
 5175   ins_pipe(ialu_reg_reg);
 5176 %}
 5177 
 5178 instruct addshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5179   match(Set dst (AddI (URShiftI src1 src2) src3));
 5180 
 5181   size(4);
 5182   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
 5183   ins_encode %{
 5184     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 5185   %}
 5186   ins_pipe(ialu_reg_reg);
 5187 %}
 5188 
 5189 // Immediate Addition
 5190 instruct addI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
 5191   match(Set dst (AddI src1 src2));
 5192 
 5193   size(4);
 5194   format %{ "add_32 $dst,$src1,$src2\t! int" %}
 5195   ins_encode %{
 5196     __ add_32($dst$$Register, $src1$$Register, $src2$$constant);
 5197   %}
 5198   ins_pipe(ialu_reg_imm);
 5199 %}
 5200 
 5201 // Pointer Register Addition
 5202 instruct addP_reg_reg(iRegP dst, iRegP src1, iRegX src2) %{
 5203   match(Set dst (AddP src1 src2));
 5204 
 5205   size(4);
 5206   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
 5207   ins_encode %{
 5208     __ add($dst$$Register, $src1$$Register, $src2$$Register);
 5209   %}
 5210   ins_pipe(ialu_reg_reg);
 5211 %}
 5212 
 5213 
 5214 // shifted iRegX operand
 5215 operand shiftedX(iRegX src2, shimmX src3) %{
 5216 //constraint(ALLOC_IN_RC(sp_ptr_reg));
 5217   match(LShiftX src2 src3);
 5218 
 5219   op_cost(1);
 5220   format %{ "$src2 << $src3" %}
 5221   interface(MEMORY_INTER) %{
 5222     base($src2);
 5223     index(0xff);
 5224     scale($src3);
 5225     disp(0x0);
 5226   %}
 5227 %}
 5228 
 5229 instruct addshlP_reg_reg_imm(iRegP dst, iRegP src1, shiftedX src2) %{
 5230   match(Set dst (AddP src1 src2));
 5231 
 5232   ins_cost(DEFAULT_COST * 3/2);
 5233   size(4);
 5234   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
 5235   ins_encode %{
 5236     Register base = reg_to_register_object($src2$$base);
 5237     __ add($dst$$Register, $src1$$Register, AsmOperand(base, lsl, $src2$$scale));
 5238   %}
 5239   ins_pipe(ialu_reg_reg);
 5240 %}
 5241 
 5242 // Pointer Immediate Addition
 5243 instruct addP_reg_aimmX(iRegP dst, iRegP src1, aimmX src2) %{
 5244   match(Set dst (AddP src1 src2));
 5245 
 5246   size(4);
 5247   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
 5248   ins_encode %{
 5249     __ add($dst$$Register, $src1$$Register, $src2$$constant);
 5250   %}
 5251   ins_pipe(ialu_reg_imm);
 5252 %}
 5253 
 5254 // Long Addition
 5255 instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg ccr) %{
 5256   match(Set dst (AddL src1 src2));
 5257   effect(KILL ccr);
 5258   size(8);
 5259   format %{ "ADDS    $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
 5260             "ADC     $dst.hi,$src1.hi,$src2.hi" %}
 5261   ins_encode %{
 5262     __ adds($dst$$Register, $src1$$Register, $src2$$Register);
 5263     __ adc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 5264   %}
 5265   ins_pipe(ialu_reg_reg);
 5266 %}
 5267 
 5268 // TODO
 5269 
 5270 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5271 // (hi($con$$constant), lo($con$$constant)) becomes
 5272 instruct addL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg ccr) %{
 5273   match(Set dst (AddL src1 con));
 5274   effect(KILL ccr);
 5275   size(8);
 5276   format %{ "ADDS    $dst.lo,$src1.lo,$con\t! long\n\t"
 5277             "ADC     $dst.hi,$src1.hi,0" %}
 5278   ins_encode %{
 5279     __ adds($dst$$Register, $src1$$Register, $con$$constant);
 5280     __ adc($dst$$Register->successor(), $src1$$Register->successor(), 0);
 5281   %}
 5282   ins_pipe(ialu_reg_imm);
 5283 %}
 5284 
 5285 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
 5286 
 5287 instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegLd newval, iRegI res, iRegLd tmp, flagsReg ccr ) %{
 5288   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
 5289   effect( KILL ccr, TEMP tmp);
 5290   size(32);
 5291   format %{ "loop: \n\t"
 5292             "LDREXD   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
 5293             "CMP      $tmp.lo, $oldval.lo\n\t"
 5294             "CMP.eq   $tmp.hi, $oldval.hi\n\t"
 5295             "STREXD.eq $tmp, $newval, $mem\n\t"
 5296             "MOV.ne   $tmp, 0 \n\t"
 5297             "XORS.eq  $tmp,$tmp, 1 \n\t"
 5298             "B.eq     loop \n\t"
 5299             "MOV      $res, $tmp" %}
 5300   ins_encode %{
 5301     Label loop;
 5302     __ bind(loop);
 5303     __ ldrexd($tmp$$Register, $mem$$Address);
 5304     __ cmp($tmp$$Register, $oldval$$Register);
 5305     __ cmp($tmp$$Register->successor(), $oldval$$Register->successor(), eq);
 5306     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5307     __ mov($tmp$$Register, 0, ne);
 5308     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
 5309     __ b(loop, eq);
 5310     __ mov($res$$Register, $tmp$$Register);
 5311   %}
 5312   ins_pipe( long_memory_op );
 5313 %}
 5314 
 5315 
 5316 instruct compareAndSwapI_bool(memoryex mem, iRegI oldval, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
 5317   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
 5318   effect( KILL ccr, TEMP tmp);
 5319   size(28);
 5320   format %{ "loop: \n\t"
 5321             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
 5322             "CMP      $tmp, $oldval\n\t"
 5323             "STREX.eq $tmp, $newval, $mem\n\t"
 5324             "MOV.ne   $tmp, 0 \n\t"
 5325             "XORS.eq  $tmp,$tmp, 1 \n\t"
 5326             "B.eq     loop \n\t"
 5327             "MOV      $res, $tmp" %}
 5328 
 5329   ins_encode %{
 5330     Label loop;
 5331     __ bind(loop);
 5332     __ ldrex($tmp$$Register,$mem$$Address);
 5333     __ cmp($tmp$$Register, $oldval$$Register);
 5334     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5335     __ mov($tmp$$Register, 0, ne);
 5336     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
 5337     __ b(loop, eq);
 5338     __ mov($res$$Register, $tmp$$Register);
 5339   %}
 5340   ins_pipe( long_memory_op );
 5341 %}
 5342 
 5343 instruct compareAndSwapP_bool(memoryex mem, iRegP oldval, iRegP newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
 5344   predicate(!(UseG1GC && n->as_LoadStore()->barrier_data() != 0));
 5345   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
 5346   effect( KILL ccr, TEMP tmp);
 5347   size(28);
 5348   format %{ "loop: \n\t"
 5349             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
 5350             "CMP      $tmp, $oldval\n\t"
 5351             "STREX.eq $tmp, $newval, $mem\n\t"
 5352             "MOV.ne   $tmp, 0 \n\t"
 5353             "EORS.eq  $tmp,$tmp, 1 \n\t"
 5354             "B.eq     loop \n\t"
 5355             "MOV      $res, $tmp" %}
 5356 
 5357   ins_encode %{
 5358     Label loop;
 5359     __ bind(loop);
 5360     __ ldrex($tmp$$Register,$mem$$Address);
 5361     __ cmp($tmp$$Register, $oldval$$Register);
 5362     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5363     __ mov($tmp$$Register, 0, ne);
 5364     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
 5365     __ b(loop, eq);
 5366     __ mov($res$$Register, $tmp$$Register);
 5367   %}
 5368   ins_pipe( long_memory_op );
 5369 %}
 5370 
 5371 instruct xaddI_aimmI_no_res(memoryex mem, aimmI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5372   predicate(n->as_LoadStore()->result_not_used());
 5373   match(Set dummy (GetAndAddI mem add));
 5374   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
 5375   size(20);
 5376   format %{ "loop: \n\t"
 5377             "LDREX    $tmp1, $mem\n\t"
 5378             "ADD      $tmp1, $tmp1, $add\n\t"
 5379             "STREX    $tmp2, $tmp1, $mem\n\t"
 5380             "CMP      $tmp2, 0 \n\t"
 5381             "B.ne     loop \n\t" %}
 5382 
 5383   ins_encode %{
 5384     Label loop;
 5385     __ bind(loop);
 5386     __ ldrex($tmp1$$Register,$mem$$Address);
 5387     __ add($tmp1$$Register, $tmp1$$Register, $add$$constant);
 5388     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5389     __ cmp($tmp2$$Register, 0);
 5390     __ b(loop, ne);
 5391   %}
 5392   ins_pipe( long_memory_op );
 5393 %}
 5394 
 5395 instruct xaddI_reg_no_res(memoryex mem, iRegI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5396   predicate(n->as_LoadStore()->result_not_used());
 5397   match(Set dummy (GetAndAddI mem add));
 5398   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
 5399   size(20);
 5400   format %{ "loop: \n\t"
 5401             "LDREX    $tmp1, $mem\n\t"
 5402             "ADD      $tmp1, $tmp1, $add\n\t"
 5403             "STREX    $tmp2, $tmp1, $mem\n\t"
 5404             "CMP      $tmp2, 0 \n\t"
 5405             "B.ne     loop \n\t" %}
 5406 
 5407   ins_encode %{
 5408     Label loop;
 5409     __ bind(loop);
 5410     __ ldrex($tmp1$$Register,$mem$$Address);
 5411     __ add($tmp1$$Register, $tmp1$$Register, $add$$Register);
 5412     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5413     __ cmp($tmp2$$Register, 0);
 5414     __ b(loop, ne);
 5415   %}
 5416   ins_pipe( long_memory_op );
 5417 %}
 5418 
 5419 instruct xaddI_aimmI(memoryex mem, aimmI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5420   match(Set res (GetAndAddI mem add));
 5421   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5422   size(20);
 5423   format %{ "loop: \n\t"
 5424             "LDREX    $res, $mem\n\t"
 5425             "ADD      $tmp1, $res, $add\n\t"
 5426             "STREX    $tmp2, $tmp1, $mem\n\t"
 5427             "CMP      $tmp2, 0 \n\t"
 5428             "B.ne     loop \n\t" %}
 5429 
 5430   ins_encode %{
 5431     Label loop;
 5432     __ bind(loop);
 5433     __ ldrex($res$$Register,$mem$$Address);
 5434     __ add($tmp1$$Register, $res$$Register, $add$$constant);
 5435     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5436     __ cmp($tmp2$$Register, 0);
 5437     __ b(loop, ne);
 5438   %}
 5439   ins_pipe( long_memory_op );
 5440 %}
 5441 
 5442 instruct xaddI_reg(memoryex mem, iRegI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5443   match(Set res (GetAndAddI mem add));
 5444   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5445   size(20);
 5446   format %{ "loop: \n\t"
 5447             "LDREX    $res, $mem\n\t"
 5448             "ADD      $tmp1, $res, $add\n\t"
 5449             "STREX    $tmp2, $tmp1, $mem\n\t"
 5450             "CMP      $tmp2, 0 \n\t"
 5451             "B.ne     loop \n\t" %}
 5452 
 5453   ins_encode %{
 5454     Label loop;
 5455     __ bind(loop);
 5456     __ ldrex($res$$Register,$mem$$Address);
 5457     __ add($tmp1$$Register, $res$$Register, $add$$Register);
 5458     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5459     __ cmp($tmp2$$Register, 0);
 5460     __ b(loop, ne);
 5461   %}
 5462   ins_pipe( long_memory_op );
 5463 %}
 5464 
 5465 instruct xaddL_reg_no_res(memoryex mem, iRegL add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5466   predicate(n->as_LoadStore()->result_not_used());
 5467   match(Set dummy (GetAndAddL mem add));
 5468   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
 5469   size(24);
 5470   format %{ "loop: \n\t"
 5471             "LDREXD   $tmp1, $mem\n\t"
 5472             "ADDS     $tmp1.lo, $tmp1.lo, $add.lo\n\t"
 5473             "ADC      $tmp1.hi, $tmp1.hi, $add.hi\n\t"
 5474             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5475             "CMP      $tmp2, 0 \n\t"
 5476             "B.ne     loop \n\t" %}
 5477 
 5478   ins_encode %{
 5479     Label loop;
 5480     __ bind(loop);
 5481     __ ldrexd($tmp1$$Register, $mem$$Address);
 5482     __ adds($tmp1$$Register, $tmp1$$Register, $add$$Register);
 5483     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), $add$$Register->successor());
 5484     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5485     __ cmp($tmp2$$Register, 0);
 5486     __ b(loop, ne);
 5487   %}
 5488   ins_pipe( long_memory_op );
 5489 %}
 5490 
 5491 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5492 // (hi($con$$constant), lo($con$$constant)) becomes
 5493 instruct xaddL_immRot_no_res(memoryex mem, immLlowRot add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5494   predicate(n->as_LoadStore()->result_not_used());
 5495   match(Set dummy (GetAndAddL mem add));
 5496   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
 5497   size(24);
 5498   format %{ "loop: \n\t"
 5499             "LDREXD   $tmp1, $mem\n\t"
 5500             "ADDS     $tmp1.lo, $tmp1.lo, $add\n\t"
 5501             "ADC      $tmp1.hi, $tmp1.hi, 0\n\t"
 5502             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5503             "CMP      $tmp2, 0 \n\t"
 5504             "B.ne     loop \n\t" %}
 5505 
 5506   ins_encode %{
 5507     Label loop;
 5508     __ bind(loop);
 5509     __ ldrexd($tmp1$$Register, $mem$$Address);
 5510     __ adds($tmp1$$Register, $tmp1$$Register, $add$$constant);
 5511     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), 0);
 5512     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5513     __ cmp($tmp2$$Register, 0);
 5514     __ b(loop, ne);
 5515   %}
 5516   ins_pipe( long_memory_op );
 5517 %}
 5518 
 5519 instruct xaddL_reg(memoryex mem, iRegL add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5520   match(Set res (GetAndAddL mem add));
 5521   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5522   size(24);
 5523   format %{ "loop: \n\t"
 5524             "LDREXD   $res, $mem\n\t"
 5525             "ADDS     $tmp1.lo, $res.lo, $add.lo\n\t"
 5526             "ADC      $tmp1.hi, $res.hi, $add.hi\n\t"
 5527             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5528             "CMP      $tmp2, 0 \n\t"
 5529             "B.ne     loop \n\t" %}
 5530 
 5531   ins_encode %{
 5532     Label loop;
 5533     __ bind(loop);
 5534     __ ldrexd($res$$Register, $mem$$Address);
 5535     __ adds($tmp1$$Register, $res$$Register, $add$$Register);
 5536     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), $add$$Register->successor());
 5537     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5538     __ cmp($tmp2$$Register, 0);
 5539     __ b(loop, ne);
 5540   %}
 5541   ins_pipe( long_memory_op );
 5542 %}
 5543 
 5544 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5545 // (hi($con$$constant), lo($con$$constant)) becomes
 5546 instruct xaddL_immRot(memoryex mem, immLlowRot add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5547   match(Set res (GetAndAddL mem add));
 5548   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5549   size(24);
 5550   format %{ "loop: \n\t"
 5551             "LDREXD   $res, $mem\n\t"
 5552             "ADDS     $tmp1.lo, $res.lo, $add\n\t"
 5553             "ADC      $tmp1.hi, $res.hi, 0\n\t"
 5554             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5555             "CMP      $tmp2, 0 \n\t"
 5556             "B.ne     loop \n\t" %}
 5557 
 5558   ins_encode %{
 5559     Label loop;
 5560     __ bind(loop);
 5561     __ ldrexd($res$$Register, $mem$$Address);
 5562     __ adds($tmp1$$Register, $res$$Register, $add$$constant);
 5563     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), 0);
 5564     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5565     __ cmp($tmp2$$Register, 0);
 5566     __ b(loop, ne);
 5567   %}
 5568   ins_pipe( long_memory_op );
 5569 %}
 5570 
 5571 instruct xchgI(memoryex mem, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr) %{
 5572   match(Set res (GetAndSetI mem newval));
 5573   effect(KILL ccr, TEMP tmp, TEMP res);
 5574   size(16);
 5575   format %{ "loop: \n\t"
 5576             "LDREX    $res, $mem\n\t"
 5577             "STREX    $tmp, $newval, $mem\n\t"
 5578             "CMP      $tmp, 0 \n\t"
 5579             "B.ne     loop \n\t" %}
 5580 
 5581   ins_encode %{
 5582     Label loop;
 5583     __ bind(loop);
 5584     __ ldrex($res$$Register,$mem$$Address);
 5585     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
 5586     __ cmp($tmp$$Register, 0);
 5587     __ b(loop, ne);
 5588   %}
 5589   ins_pipe( long_memory_op );
 5590 %}
 5591 
 5592 instruct xchgL(memoryex mem, iRegLd newval, iRegLd res, iRegI tmp, flagsReg ccr) %{
 5593   match(Set res (GetAndSetL mem newval));
 5594   effect( KILL ccr, TEMP tmp, TEMP res);
 5595   size(16);
 5596   format %{ "loop: \n\t"
 5597             "LDREXD   $res, $mem\n\t"
 5598             "STREXD   $tmp, $newval, $mem\n\t"
 5599             "CMP      $tmp, 0 \n\t"
 5600             "B.ne     loop \n\t" %}
 5601 
 5602   ins_encode %{
 5603     Label loop;
 5604     __ bind(loop);
 5605     __ ldrexd($res$$Register, $mem$$Address);
 5606     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address);
 5607     __ cmp($tmp$$Register, 0);
 5608     __ b(loop, ne);
 5609   %}
 5610   ins_pipe( long_memory_op );
 5611 %}
 5612 
 5613 instruct xchgP(memoryex mem, iRegP newval, iRegP res, iRegI tmp, flagsReg ccr) %{
 5614   predicate(!(UseG1GC && n->as_LoadStore()->barrier_data() != 0));
 5615   match(Set res (GetAndSetP mem newval));
 5616   effect(KILL ccr, TEMP tmp, TEMP res);
 5617   size(16);
 5618   format %{ "loop: \n\t"
 5619             "LDREX    $res, $mem\n\t"
 5620             "STREX    $tmp, $newval, $mem\n\t"
 5621             "CMP      $tmp, 0 \n\t"
 5622             "B.ne     loop \n\t" %}
 5623 
 5624   ins_encode %{
 5625     Label loop;
 5626     __ bind(loop);
 5627     __ ldrex($res$$Register,$mem$$Address);
 5628     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
 5629     __ cmp($tmp$$Register, 0);
 5630     __ b(loop, ne);
 5631   %}
 5632   ins_pipe( long_memory_op );
 5633 %}
 5634 
 5635 //---------------------
 5636 // Subtraction Instructions
 5637 // Register Subtraction
 5638 instruct subI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 5639   match(Set dst (SubI src1 src2));
 5640 
 5641   size(4);
 5642   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
 5643   ins_encode %{
 5644     __ sub_32($dst$$Register, $src1$$Register, $src2$$Register);
 5645   %}
 5646   ins_pipe(ialu_reg_reg);
 5647 %}
 5648 
 5649 instruct subshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5650   match(Set dst (SubI src1 (LShiftI src2 src3)));
 5651 
 5652   size(4);
 5653   format %{ "SUB    $dst,$src1,$src2<<$src3" %}
 5654   ins_encode %{
 5655     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 5656   %}
 5657   ins_pipe(ialu_reg_reg);
 5658 %}
 5659 
 5660 instruct subshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 5661   match(Set dst (SubI src1 (LShiftI src2 src3)));
 5662 
 5663   size(4);
 5664   format %{ "sub_32 $dst,$src1,$src2<<$src3\t! int" %}
 5665   ins_encode %{
 5666     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 5667   %}
 5668   ins_pipe(ialu_reg_reg);
 5669 %}
 5670 
 5671 instruct subsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5672   match(Set dst (SubI src1 (RShiftI src2 src3)));
 5673 
 5674   size(4);
 5675   format %{ "SUB    $dst,$src1,$src2>>$src3" %}
 5676   ins_encode %{
 5677     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 5678   %}
 5679   ins_pipe(ialu_reg_reg);
 5680 %}
 5681 
 5682 instruct subsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 5683   match(Set dst (SubI src1 (RShiftI src2 src3)));
 5684 
 5685   size(4);
 5686   format %{ "sub_32 $dst,$src1,$src2>>$src3\t! int" %}
 5687   ins_encode %{
 5688     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 5689   %}
 5690   ins_pipe(ialu_reg_reg);
 5691 %}
 5692 
 5693 instruct subshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5694   match(Set dst (SubI src1 (URShiftI src2 src3)));
 5695 
 5696   size(4);
 5697   format %{ "SUB    $dst,$src1,$src2>>>$src3" %}
 5698   ins_encode %{
 5699     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 5700   %}
 5701   ins_pipe(ialu_reg_reg);
 5702 %}
 5703 
 5704 instruct subshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 5705   match(Set dst (SubI src1 (URShiftI src2 src3)));
 5706 
 5707   size(4);
 5708   format %{ "sub_32 $dst,$src1,$src2>>>$src3\t! int" %}
 5709   ins_encode %{
 5710     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 5711   %}
 5712   ins_pipe(ialu_reg_reg);
 5713 %}
 5714 
 5715 instruct rsbshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5716   match(Set dst (SubI (LShiftI src1 src2) src3));
 5717 
 5718   size(4);
 5719   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
 5720   ins_encode %{
 5721     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 5722   %}
 5723   ins_pipe(ialu_reg_reg);
 5724 %}
 5725 
 5726 instruct rsbshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5727   match(Set dst (SubI (LShiftI src1 src2) src3));
 5728 
 5729   size(4);
 5730   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
 5731   ins_encode %{
 5732     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
 5733   %}
 5734   ins_pipe(ialu_reg_reg);
 5735 %}
 5736 
 5737 instruct rsbsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5738   match(Set dst (SubI (RShiftI src1 src2) src3));
 5739 
 5740   size(4);
 5741   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
 5742   ins_encode %{
 5743     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
 5744   %}
 5745   ins_pipe(ialu_reg_reg);
 5746 %}
 5747 
 5748 instruct rsbsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5749   match(Set dst (SubI (RShiftI src1 src2) src3));
 5750 
 5751   size(4);
 5752   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
 5753   ins_encode %{
 5754     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
 5755   %}
 5756   ins_pipe(ialu_reg_reg);
 5757 %}
 5758 
 5759 instruct rsbshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5760   match(Set dst (SubI (URShiftI src1 src2) src3));
 5761 
 5762   size(4);
 5763   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
 5764   ins_encode %{
 5765     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 5766   %}
 5767   ins_pipe(ialu_reg_reg);
 5768 %}
 5769 
 5770 instruct rsbshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5771   match(Set dst (SubI (URShiftI src1 src2) src3));
 5772 
 5773   size(4);
 5774   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
 5775   ins_encode %{
 5776     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 5777   %}
 5778   ins_pipe(ialu_reg_reg);
 5779 %}
 5780 
 5781 // Immediate Subtraction
 5782 instruct subI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
 5783   match(Set dst (SubI src1 src2));
 5784 
 5785   size(4);
 5786   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
 5787   ins_encode %{
 5788     __ sub_32($dst$$Register, $src1$$Register, $src2$$constant);
 5789   %}
 5790   ins_pipe(ialu_reg_imm);
 5791 %}
 5792 
 5793 instruct subI_reg_immRotneg(iRegI dst, iRegI src1, aimmIneg src2) %{
 5794   match(Set dst (AddI src1 src2));
 5795 
 5796   size(4);
 5797   format %{ "sub_32 $dst,$src1,-($src2)\t! int" %}
 5798   ins_encode %{
 5799     __ sub_32($dst$$Register, $src1$$Register, -$src2$$constant);
 5800   %}
 5801   ins_pipe(ialu_reg_imm);
 5802 %}
 5803 
 5804 instruct subI_immRot_reg(iRegI dst, immIRot src1, iRegI src2) %{
 5805   match(Set dst (SubI src1 src2));
 5806 
 5807   size(4);
 5808   format %{ "RSB    $dst,$src2,src1" %}
 5809   ins_encode %{
 5810     __ rsb($dst$$Register, $src2$$Register, $src1$$constant);
 5811   %}
 5812   ins_pipe(ialu_zero_reg);
 5813 %}
 5814 
 5815 // Register Subtraction
 5816 instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg icc ) %{
 5817   match(Set dst (SubL src1 src2));
 5818   effect (KILL icc);
 5819 
 5820   size(8);
 5821   format %{ "SUBS   $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
 5822             "SBC    $dst.hi,$src1.hi,$src2.hi" %}
 5823   ins_encode %{
 5824     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
 5825     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 5826   %}
 5827   ins_pipe(ialu_reg_reg);
 5828 %}
 5829 
 5830 // TODO
 5831 
 5832 // Immediate Subtraction
 5833 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5834 // (hi($con$$constant), lo($con$$constant)) becomes
 5835 instruct subL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg icc) %{
 5836   match(Set dst (SubL src1 con));
 5837   effect (KILL icc);
 5838 
 5839   size(8);
 5840   format %{ "SUB    $dst.lo,$src1.lo,$con\t! long\n\t"
 5841             "SBC    $dst.hi,$src1.hi,0" %}
 5842   ins_encode %{
 5843     __ subs($dst$$Register, $src1$$Register, $con$$constant);
 5844     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), 0);
 5845   %}
 5846   ins_pipe(ialu_reg_imm);
 5847 %}
 5848 
 5849 // Long negation
 5850 instruct negL_reg_reg(iRegL dst, immL0 zero, iRegL src2, flagsReg icc) %{
 5851   match(Set dst (SubL zero src2));
 5852   effect (KILL icc);
 5853 
 5854   size(8);
 5855   format %{ "RSBS   $dst.lo,$src2.lo,0\t! long\n\t"
 5856             "RSC    $dst.hi,$src2.hi,0" %}
 5857   ins_encode %{
 5858     __ rsbs($dst$$Register, $src2$$Register, 0);
 5859     __ rsc($dst$$Register->successor(), $src2$$Register->successor(), 0);
 5860   %}
 5861   ins_pipe(ialu_zero_reg);
 5862 %}
 5863 
 5864 // Multiplication Instructions
 5865 // Integer Multiplication
 5866 // Register Multiplication
 5867 instruct mulI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 5868   match(Set dst (MulI src1 src2));
 5869 
 5870   size(4);
 5871   format %{ "mul_32 $dst,$src1,$src2" %}
 5872   ins_encode %{
 5873     __ mul_32($dst$$Register, $src1$$Register, $src2$$Register);
 5874   %}
 5875   ins_pipe(imul_reg_reg);
 5876 %}
 5877 
 5878 instruct mulL_lo1_hi2(iRegL dst, iRegL src1, iRegL src2) %{
 5879   effect(DEF dst, USE src1, USE src2);
 5880   size(4);
 5881   format %{ "MUL  $dst.hi,$src1.lo,$src2.hi\t! long" %}
 5882   ins_encode %{
 5883     __ mul($dst$$Register->successor(), $src1$$Register, $src2$$Register->successor());
 5884   %}
 5885   ins_pipe(imul_reg_reg);
 5886 %}
 5887 
 5888 instruct mulL_hi1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
 5889   effect(USE_DEF dst, USE src1, USE src2);
 5890   size(8);
 5891   format %{ "MLA  $dst.hi,$src1.hi,$src2.lo,$dst.hi\t! long\n\t"
 5892             "MOV  $dst.lo, 0"%}
 5893   ins_encode %{
 5894     __ mla($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register, $dst$$Register->successor());
 5895     __ mov($dst$$Register, 0);
 5896   %}
 5897   ins_pipe(imul_reg_reg);
 5898 %}
 5899 
 5900 instruct mulL_lo1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
 5901   effect(USE_DEF dst, USE src1, USE src2);
 5902   size(4);
 5903   format %{ "UMLAL  $dst.lo,$dst.hi,$src1,$src2\t! long" %}
 5904   ins_encode %{
 5905     __ umlal($dst$$Register, $dst$$Register->successor(), $src1$$Register, $src2$$Register);
 5906   %}
 5907   ins_pipe(imul_reg_reg);
 5908 %}
 5909 
 5910 instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 5911   match(Set dst (MulL src1 src2));
 5912 
 5913   expand %{
 5914     mulL_lo1_hi2(dst, src1, src2);
 5915     mulL_hi1_lo2(dst, src1, src2);
 5916     mulL_lo1_lo2(dst, src1, src2);
 5917   %}
 5918 %}
 5919 
 5920 // Integer Division
 5921 // Register Division
 5922 instruct divI_reg_reg(R1RegI dst, R0RegI src1, R2RegI src2, LRRegP lr, flagsReg ccr) %{
 5923   match(Set dst (DivI src1 src2));
 5924   effect( KILL ccr, KILL src1, KILL src2, KILL lr);
 5925   ins_cost((2+71)*DEFAULT_COST);
 5926 
 5927   format %{ "DIV   $dst,$src1,$src2 ! call to StubRoutines::Arm::idiv_irem_entry()" %}
 5928   ins_encode %{
 5929     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
 5930   %}
 5931   ins_pipe(sdiv_reg_reg);
 5932 %}
 5933 
 5934 // Register Long Division
 5935 instruct divL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
 5936   match(Set dst (DivL src1 src2));
 5937   effect(CALL);
 5938   ins_cost(DEFAULT_COST*71);
 5939   format %{ "DIVL  $src1,$src2,$dst\t! long ! call to SharedRuntime::ldiv" %}
 5940   ins_encode %{
 5941     address target = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);
 5942     __ call(target, relocInfo::runtime_call_type);
 5943   %}
 5944   ins_pipe(divL_reg_reg);
 5945 %}
 5946 
 5947 // Integer Remainder
 5948 // Register Remainder
 5949 instruct modI_reg_reg(R0RegI dst, R0RegI src1, R2RegI src2, R1RegI temp, LRRegP lr, flagsReg ccr ) %{
 5950   match(Set dst (ModI src1 src2));
 5951   effect( KILL ccr, KILL temp, KILL src2, KILL lr);
 5952 
 5953   format %{ "MODI   $dst,$src1,$src2\t ! call to StubRoutines::Arm::idiv_irem_entry" %}
 5954   ins_encode %{
 5955     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
 5956   %}
 5957   ins_pipe(sdiv_reg_reg);
 5958 %}
 5959 
 5960 // Register Long Remainder
 5961 instruct modL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
 5962   match(Set dst (ModL src1 src2));
 5963   effect(CALL);
 5964   ins_cost(MEMORY_REF_COST); // FIXME
 5965   format %{ "modL    $dst,$src1,$src2\t ! call to SharedRuntime::lrem" %}
 5966   ins_encode %{
 5967     address target = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
 5968     __ call(target, relocInfo::runtime_call_type);
 5969   %}
 5970   ins_pipe(divL_reg_reg);
 5971 %}
 5972 
 5973 // Integer Shift Instructions
 5974 
 5975 // Register Shift Left
 5976 instruct shlI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 5977   match(Set dst (LShiftI src1 src2));
 5978 
 5979   size(4);
 5980   format %{ "LSL  $dst,$src1,$src2 \n\t" %}
 5981   ins_encode %{
 5982     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 5983   %}
 5984   ins_pipe(ialu_reg_reg);
 5985 %}
 5986 
 5987 // Register Shift Left Immediate
 5988 instruct shlI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
 5989   match(Set dst (LShiftI src1 src2));
 5990 
 5991   size(4);
 5992   format %{ "LSL    $dst,$src1,$src2\t! int" %}
 5993   ins_encode %{
 5994     __ logical_shift_left($dst$$Register, $src1$$Register, $src2$$constant);
 5995   %}
 5996   ins_pipe(ialu_reg_imm);
 5997 %}
 5998 
 5999 instruct shlL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
 6000   effect(USE_DEF dst, USE src1, USE src2);
 6001   size(4);
 6002   format %{"OR  $dst.hi,$dst.hi,($src1.hi << $src2)"  %}
 6003   ins_encode %{
 6004     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$Register));
 6005   %}
 6006   ins_pipe(ialu_reg_reg);
 6007 %}
 6008 
 6009 instruct shlL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
 6010   effect(USE_DEF dst, USE src1, USE src2);
 6011   size(4);
 6012   format %{ "LSL  $dst.lo,$src1.lo,$src2 \n\t" %}
 6013   ins_encode %{
 6014     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 6015   %}
 6016   ins_pipe(ialu_reg_reg);
 6017 %}
 6018 
 6019 instruct shlL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
 6020   effect(DEF dst, USE src1, USE src2, KILL ccr);
 6021   size(16);
 6022   format %{ "SUBS  $dst.hi,$src2,32 \n\t"
 6023             "LSLpl $dst.hi,$src1.lo,$dst.hi \n\t"
 6024             "RSBmi $dst.hi,$dst.hi,0 \n\t"
 6025             "LSRmi $dst.hi,$src1.lo,$dst.hi" %}
 6026 
 6027   ins_encode %{
 6028     // $src1$$Register and $dst$$Register->successor() can't be the same
 6029     __ subs($dst$$Register->successor(), $src2$$Register, 32);
 6030     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $dst$$Register->successor()), pl);
 6031     __ rsb($dst$$Register->successor(), $dst$$Register->successor(), 0, mi);
 6032     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsr, $dst$$Register->successor()), mi);
 6033   %}
 6034   ins_pipe(ialu_reg_reg);
 6035 %}
 6036 
 6037 instruct shlL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
 6038   match(Set dst (LShiftL src1 src2));
 6039 
 6040   expand %{
 6041     flagsReg ccr;
 6042     shlL_reg_reg_overlap(dst, src1, src2, ccr);
 6043     shlL_reg_reg_merge_hi(dst, src1, src2);
 6044     shlL_reg_reg_merge_lo(dst, src1, src2);
 6045   %}
 6046 %}
 6047 
 6048 // Register Shift Left Immediate
 6049 instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
 6050   match(Set dst (LShiftL src1 src2));
 6051 
 6052   size(8);
 6053   format %{ "LSL   $dst.hi,$src1.lo,$src2-32\t! or mov if $src2==32\n\t"
 6054             "MOV   $dst.lo, 0" %}
 6055   ins_encode %{
 6056     if ($src2$$constant == 32) {
 6057       __ mov($dst$$Register->successor(), $src1$$Register);
 6058     } else {
 6059       __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $src2$$constant-32));
 6060     }
 6061     __ mov($dst$$Register, 0);
 6062   %}
 6063   ins_pipe(ialu_reg_imm);
 6064 %}
 6065 
 6066 instruct shlL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
 6067   match(Set dst (LShiftL src1 src2));
 6068 
 6069   size(12);
 6070   format %{ "LSL   $dst.hi,$src1.lo,$src2\n\t"
 6071             "OR    $dst.hi, $dst.hi, $src1.lo >> 32-$src2\n\t"
 6072             "LSL   $dst.lo,$src1.lo,$src2" %}
 6073   ins_encode %{
 6074     // The order of the following 3 instructions matters: src1.lo and
 6075     // dst.hi can't overlap but src.hi and dst.hi can.
 6076     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$constant));
 6077     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register, lsr, 32-$src2$$constant));
 6078     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
 6079   %}
 6080   ins_pipe(ialu_reg_imm);
 6081 %}
 6082 
 6083 // Register Arithmetic Shift Right
 6084 instruct sarI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6085   match(Set dst (RShiftI src1 src2));
 6086   size(4);
 6087   format %{ "ASR    $dst,$src1,$src2\t! int" %}
 6088   ins_encode %{
 6089     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
 6090   %}
 6091   ins_pipe(ialu_reg_reg);
 6092 %}
 6093 
 6094 // Register Arithmetic Shift Right Immediate
 6095 instruct sarI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
 6096   match(Set dst (RShiftI src1 src2));
 6097 
 6098   size(4);
 6099   format %{ "ASR    $dst,$src1,$src2" %}
 6100   ins_encode %{
 6101     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
 6102   %}
 6103   ins_pipe(ialu_reg_imm);
 6104 %}
 6105 
 6106 // Register Shift Right Arithmetic Long
 6107 instruct sarL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
 6108   effect(USE_DEF dst, USE src1, USE src2);
 6109   size(4);
 6110   format %{ "OR  $dst.lo,$dst.lo,($src1.lo >> $src2)"  %}
 6111   ins_encode %{
 6112     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6113   %}
 6114   ins_pipe(ialu_reg_reg);
 6115 %}
 6116 
 6117 instruct sarL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
 6118   effect(USE_DEF dst, USE src1, USE src2);
 6119   size(4);
 6120   format %{ "ASR  $dst.hi,$src1.hi,$src2 \n\t" %}
 6121   ins_encode %{
 6122     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$Register));
 6123   %}
 6124   ins_pipe(ialu_reg_reg);
 6125 %}
 6126 
 6127 instruct sarL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
 6128   effect(DEF dst, USE src1, USE src2, KILL ccr);
 6129   size(16);
 6130   format %{ "SUBS  $dst.lo,$src2,32 \n\t"
 6131             "ASRpl $dst.lo,$src1.hi,$dst.lo \n\t"
 6132             "RSBmi $dst.lo,$dst.lo,0 \n\t"
 6133             "LSLmi $dst.lo,$src1.hi,$dst.lo" %}
 6134 
 6135   ins_encode %{
 6136     // $src1$$Register->successor() and $dst$$Register can't be the same
 6137     __ subs($dst$$Register, $src2$$Register, 32);
 6138     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $dst$$Register), pl);
 6139     __ rsb($dst$$Register, $dst$$Register, 0, mi);
 6140     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
 6141   %}
 6142   ins_pipe(ialu_reg_reg);
 6143 %}
 6144 
 6145 instruct sarL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
 6146   match(Set dst (RShiftL src1 src2));
 6147 
 6148   expand %{
 6149     flagsReg ccr;
 6150     sarL_reg_reg_overlap(dst, src1, src2, ccr);
 6151     sarL_reg_reg_merge_lo(dst, src1, src2);
 6152     sarL_reg_reg_merge_hi(dst, src1, src2);
 6153   %}
 6154 %}
 6155 
 6156 // Register Shift Left Immediate
 6157 instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
 6158   match(Set dst (RShiftL src1 src2));
 6159 
 6160   size(8);
 6161   format %{ "ASR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
 6162             "ASR   $dst.hi,$src1.hi, $src2" %}
 6163   ins_encode %{
 6164     if ($src2$$constant == 32) {
 6165       __ mov($dst$$Register, $src1$$Register->successor());
 6166     } else{
 6167       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $src2$$constant-32));
 6168     }
 6169     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, 0));
 6170   %}
 6171 
 6172   ins_pipe(ialu_reg_imm);
 6173 %}
 6174 
 6175 instruct sarL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
 6176   match(Set dst (RShiftL src1 src2));
 6177   size(12);
 6178   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
 6179             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
 6180             "ASR   $dst.hi,$src1.hi,$src2" %}
 6181   ins_encode %{
 6182     // The order of the following 3 instructions matters: src1.lo and
 6183     // dst.hi can't overlap but src.hi and dst.hi can.
 6184     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6185     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
 6186     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$constant));
 6187   %}
 6188   ins_pipe(ialu_reg_imm);
 6189 %}
 6190 
 6191 // Register Shift Right
 6192 instruct shrI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6193   match(Set dst (URShiftI src1 src2));
 6194   size(4);
 6195   format %{ "LSR    $dst,$src1,$src2\t! int" %}
 6196   ins_encode %{
 6197     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6198   %}
 6199   ins_pipe(ialu_reg_reg);
 6200 %}
 6201 
 6202 // Register Shift Right Immediate
 6203 instruct shrI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
 6204   match(Set dst (URShiftI src1 src2));
 6205 
 6206   size(4);
 6207   format %{ "LSR    $dst,$src1,$src2" %}
 6208   ins_encode %{
 6209     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6210   %}
 6211   ins_pipe(ialu_reg_imm);
 6212 %}
 6213 
 6214 // Register Shift Right
 6215 instruct shrL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
 6216   effect(USE_DEF dst, USE src1, USE src2);
 6217   size(4);
 6218   format %{ "OR   $dst.lo,$dst,($src1.lo >>> $src2)"  %}
 6219   ins_encode %{
 6220     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6221   %}
 6222   ins_pipe(ialu_reg_reg);
 6223 %}
 6224 
 6225 instruct shrL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
 6226   effect(USE_DEF dst, USE src1, USE src2);
 6227   size(4);
 6228   format %{ "LSR  $dst.hi,$src1.hi,$src2 \n\t" %}
 6229   ins_encode %{
 6230     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$Register));
 6231   %}
 6232   ins_pipe(ialu_reg_reg);
 6233 %}
 6234 
 6235 instruct shrL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
 6236   effect(DEF dst, USE src1, USE src2, KILL ccr);
 6237   size(16);
 6238   format %{ "SUBS  $dst,$src2,32 \n\t"
 6239             "LSRpl $dst,$src1.hi,$dst \n\t"
 6240             "RSBmi $dst,$dst,0 \n\t"
 6241             "LSLmi $dst,$src1.hi,$dst" %}
 6242 
 6243   ins_encode %{
 6244     // $src1$$Register->successor() and $dst$$Register can't be the same
 6245     __ subs($dst$$Register, $src2$$Register, 32);
 6246     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $dst$$Register), pl);
 6247     __ rsb($dst$$Register, $dst$$Register, 0, mi);
 6248     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
 6249   %}
 6250   ins_pipe(ialu_reg_reg);
 6251 %}
 6252 
 6253 instruct shrL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
 6254   match(Set dst (URShiftL src1 src2));
 6255 
 6256   expand %{
 6257     flagsReg ccr;
 6258     shrL_reg_reg_overlap(dst, src1, src2, ccr);
 6259     shrL_reg_reg_merge_lo(dst, src1, src2);
 6260     shrL_reg_reg_merge_hi(dst, src1, src2);
 6261   %}
 6262 %}
 6263 
 6264 // Register Shift Right Immediate
 6265 instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
 6266   match(Set dst (URShiftL src1 src2));
 6267 
 6268   size(8);
 6269   format %{ "LSR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
 6270             "MOV   $dst.hi, 0" %}
 6271   ins_encode %{
 6272     if ($src2$$constant == 32) {
 6273       __ mov($dst$$Register, $src1$$Register->successor());
 6274     } else {
 6275       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $src2$$constant-32));
 6276     }
 6277     __ mov($dst$$Register->successor(), 0);
 6278   %}
 6279 
 6280   ins_pipe(ialu_reg_imm);
 6281 %}
 6282 
 6283 instruct shrL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
 6284   match(Set dst (URShiftL src1 src2));
 6285 
 6286   size(12);
 6287   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
 6288             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
 6289             "LSR   $dst.hi,$src1.hi,$src2" %}
 6290   ins_encode %{
 6291     // The order of the following 3 instructions matters: src1.lo and
 6292     // dst.hi can't overlap but src.hi and dst.hi can.
 6293     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6294     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
 6295     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$constant));
 6296   %}
 6297   ins_pipe(ialu_reg_imm);
 6298 %}
 6299 
 6300 
 6301 instruct shrP_reg_imm5(iRegX dst, iRegP src1, immU5 src2) %{
 6302   match(Set dst (URShiftI (CastP2X src1) src2));
 6303   size(4);
 6304   format %{ "LSR    $dst,$src1,$src2\t! Cast ptr $src1 to int and shift" %}
 6305   ins_encode %{
 6306     __ logical_shift_right($dst$$Register, $src1$$Register, $src2$$constant);
 6307   %}
 6308   ins_pipe(ialu_reg_imm);
 6309 %}
 6310 
 6311 //----------Floating Point Arithmetic Instructions-----------------------------
 6312 
 6313 //  Add float single precision
 6314 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
 6315   match(Set dst (AddF src1 src2));
 6316 
 6317   size(4);
 6318   format %{ "FADDS  $dst,$src1,$src2" %}
 6319   ins_encode %{
 6320     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6321   %}
 6322 
 6323   ins_pipe(faddF_reg_reg);
 6324 %}
 6325 
 6326 //  Add float double precision
 6327 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
 6328   match(Set dst (AddD src1 src2));
 6329 
 6330   size(4);
 6331   format %{ "FADDD  $dst,$src1,$src2" %}
 6332   ins_encode %{
 6333     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6334   %}
 6335 
 6336   ins_pipe(faddD_reg_reg);
 6337 %}
 6338 
 6339 //  Sub float single precision
 6340 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
 6341   match(Set dst (SubF src1 src2));
 6342 
 6343   size(4);
 6344   format %{ "FSUBS  $dst,$src1,$src2" %}
 6345   ins_encode %{
 6346     __ sub_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6347   %}
 6348   ins_pipe(faddF_reg_reg);
 6349 %}
 6350 
 6351 //  Sub float double precision
 6352 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
 6353   match(Set dst (SubD src1 src2));
 6354 
 6355   size(4);
 6356   format %{ "FSUBD  $dst,$src1,$src2" %}
 6357   ins_encode %{
 6358     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6359   %}
 6360   ins_pipe(faddD_reg_reg);
 6361 %}
 6362 
 6363 //  Mul float single precision
 6364 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
 6365   match(Set dst (MulF src1 src2));
 6366 
 6367   size(4);
 6368   format %{ "FMULS  $dst,$src1,$src2" %}
 6369   ins_encode %{
 6370     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6371   %}
 6372 
 6373   ins_pipe(fmulF_reg_reg);
 6374 %}
 6375 
 6376 //  Mul float double precision
 6377 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
 6378   match(Set dst (MulD src1 src2));
 6379 
 6380   size(4);
 6381   format %{ "FMULD  $dst,$src1,$src2" %}
 6382   ins_encode %{
 6383     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6384   %}
 6385 
 6386   ins_pipe(fmulD_reg_reg);
 6387 %}
 6388 
 6389 //  Div float single precision
 6390 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
 6391   match(Set dst (DivF src1 src2));
 6392 
 6393   size(4);
 6394   format %{ "FDIVS  $dst,$src1,$src2" %}
 6395   ins_encode %{
 6396     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6397   %}
 6398 
 6399   ins_pipe(fdivF_reg_reg);
 6400 %}
 6401 
 6402 //  Div float double precision
 6403 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
 6404   match(Set dst (DivD src1 src2));
 6405 
 6406   size(4);
 6407   format %{ "FDIVD  $dst,$src1,$src2" %}
 6408   ins_encode %{
 6409     __ div_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6410   %}
 6411 
 6412   ins_pipe(fdivD_reg_reg);
 6413 %}
 6414 
 6415 //  Absolute float double precision
 6416 instruct absD_reg(regD dst, regD src) %{
 6417   match(Set dst (AbsD src));
 6418 
 6419   size(4);
 6420   format %{ "FABSd  $dst,$src" %}
 6421   ins_encode %{
 6422     __ abs_double($dst$$FloatRegister, $src$$FloatRegister);
 6423   %}
 6424   ins_pipe(faddD_reg);
 6425 %}
 6426 
 6427 //  Absolute float single precision
 6428 instruct absF_reg(regF dst, regF src) %{
 6429   match(Set dst (AbsF src));
 6430   format %{ "FABSs  $dst,$src" %}
 6431   ins_encode %{
 6432     __ abs_float($dst$$FloatRegister, $src$$FloatRegister);
 6433   %}
 6434   ins_pipe(faddF_reg);
 6435 %}
 6436 
 6437 instruct negF_reg(regF dst, regF src) %{
 6438   match(Set dst (NegF src));
 6439 
 6440   size(4);
 6441   format %{ "FNEGs  $dst,$src" %}
 6442   ins_encode %{
 6443     __ neg_float($dst$$FloatRegister, $src$$FloatRegister);
 6444   %}
 6445   ins_pipe(faddF_reg);
 6446 %}
 6447 
 6448 instruct negD_reg(regD dst, regD src) %{
 6449   match(Set dst (NegD src));
 6450 
 6451   format %{ "FNEGd  $dst,$src" %}
 6452   ins_encode %{
 6453     __ neg_double($dst$$FloatRegister, $src$$FloatRegister);
 6454   %}
 6455   ins_pipe(faddD_reg);
 6456 %}
 6457 
 6458 //  Sqrt float double precision
 6459 instruct sqrtF_reg_reg(regF dst, regF src) %{
 6460   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
 6461 
 6462   size(4);
 6463   format %{ "FSQRTS $dst,$src" %}
 6464   ins_encode %{
 6465     __ sqrt_float($dst$$FloatRegister, $src$$FloatRegister);
 6466   %}
 6467   ins_pipe(fdivF_reg_reg);
 6468 %}
 6469 
 6470 //  Sqrt float double precision
 6471 instruct sqrtD_reg_reg(regD dst, regD src) %{
 6472   match(Set dst (SqrtD src));
 6473 
 6474   size(4);
 6475   format %{ "FSQRTD $dst,$src" %}
 6476   ins_encode %{
 6477     __ sqrt_double($dst$$FloatRegister, $src$$FloatRegister);
 6478   %}
 6479   ins_pipe(fdivD_reg_reg);
 6480 %}
 6481 
 6482 //----------Logical Instructions-----------------------------------------------
 6483 // And Instructions
 6484 // Register And
 6485 instruct andI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6486   match(Set dst (AndI src1 src2));
 6487 
 6488   size(4);
 6489   format %{ "and_32 $dst,$src1,$src2" %}
 6490   ins_encode %{
 6491     __ and_32($dst$$Register, $src1$$Register, $src2$$Register);
 6492   %}
 6493   ins_pipe(ialu_reg_reg);
 6494 %}
 6495 
 6496 instruct andshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6497   match(Set dst (AndI src1 (LShiftI src2 src3)));
 6498 
 6499   size(4);
 6500   format %{ "AND    $dst,$src1,$src2<<$src3" %}
 6501   ins_encode %{
 6502     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 6503   %}
 6504   ins_pipe(ialu_reg_reg);
 6505 %}
 6506 
 6507 instruct andshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6508   match(Set dst (AndI src1 (LShiftI src2 src3)));
 6509 
 6510   size(4);
 6511   format %{ "and_32 $dst,$src1,$src2<<$src3" %}
 6512   ins_encode %{
 6513     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 6514   %}
 6515   ins_pipe(ialu_reg_reg);
 6516 %}
 6517 
 6518 instruct andsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6519   match(Set dst (AndI src1 (RShiftI src2 src3)));
 6520 
 6521   size(4);
 6522   format %{ "AND    $dst,$src1,$src2>>$src3" %}
 6523   ins_encode %{
 6524     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 6525   %}
 6526   ins_pipe(ialu_reg_reg);
 6527 %}
 6528 
 6529 instruct andsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6530   match(Set dst (AndI src1 (RShiftI src2 src3)));
 6531 
 6532   size(4);
 6533   format %{ "and_32 $dst,$src1,$src2>>$src3" %}
 6534   ins_encode %{
 6535     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 6536   %}
 6537   ins_pipe(ialu_reg_reg);
 6538 %}
 6539 
 6540 instruct andshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6541   match(Set dst (AndI src1 (URShiftI src2 src3)));
 6542 
 6543   size(4);
 6544   format %{ "AND    $dst,$src1,$src2>>>$src3" %}
 6545   ins_encode %{
 6546     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 6547   %}
 6548   ins_pipe(ialu_reg_reg);
 6549 %}
 6550 
 6551 instruct andshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6552   match(Set dst (AndI src1 (URShiftI src2 src3)));
 6553 
 6554   size(4);
 6555   format %{ "and_32 $dst,$src1,$src2>>>$src3" %}
 6556   ins_encode %{
 6557     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 6558   %}
 6559   ins_pipe(ialu_reg_reg);
 6560 %}
 6561 
 6562 // Immediate And
 6563 instruct andI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
 6564   match(Set dst (AndI src1 src2));
 6565 
 6566   size(4);
 6567   format %{ "and_32 $dst,$src1,$src2\t! int" %}
 6568   ins_encode %{
 6569     __ and_32($dst$$Register, $src1$$Register, $src2$$constant);
 6570   %}
 6571   ins_pipe(ialu_reg_imm);
 6572 %}
 6573 
 6574 instruct andI_reg_limmn(iRegI dst, iRegI src1, limmIn src2) %{
 6575   match(Set dst (AndI src1 src2));
 6576 
 6577   size(4);
 6578   format %{ "bic    $dst,$src1,~$src2\t! int" %}
 6579   ins_encode %{
 6580     __ bic($dst$$Register, $src1$$Register, ~$src2$$constant);
 6581   %}
 6582   ins_pipe(ialu_reg_imm);
 6583 %}
 6584 
 6585 // Register And Long
 6586 instruct andL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 6587   match(Set dst (AndL src1 src2));
 6588 
 6589   ins_cost(DEFAULT_COST);
 6590   size(8);
 6591   format %{ "AND    $dst,$src1,$src2\t! long" %}
 6592   ins_encode %{
 6593     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
 6594     __ andr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 6595   %}
 6596   ins_pipe(ialu_reg_reg);
 6597 %}
 6598 
 6599 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 6600 // (hi($con$$constant), lo($con$$constant)) becomes
 6601 instruct andL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
 6602   match(Set dst (AndL src1 con));
 6603   ins_cost(DEFAULT_COST);
 6604   size(8);
 6605   format %{ "AND    $dst,$src1,$con\t! long" %}
 6606   ins_encode %{
 6607     __ andr($dst$$Register, $src1$$Register, $con$$constant);
 6608     __ andr($dst$$Register->successor(), $src1$$Register->successor(), 0);
 6609   %}
 6610   ins_pipe(ialu_reg_imm);
 6611 %}
 6612 
 6613 // Or Instructions
 6614 // Register Or
 6615 instruct orI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6616   match(Set dst (OrI src1 src2));
 6617 
 6618   size(4);
 6619   format %{ "orr_32 $dst,$src1,$src2\t! int" %}
 6620   ins_encode %{
 6621     __ orr_32($dst$$Register, $src1$$Register, $src2$$Register);
 6622   %}
 6623   ins_pipe(ialu_reg_reg);
 6624 %}
 6625 
 6626 instruct orshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6627   match(Set dst (OrI src1 (LShiftI src2 src3)));
 6628 
 6629   size(4);
 6630   format %{ "OR    $dst,$src1,$src2<<$src3" %}
 6631   ins_encode %{
 6632     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 6633   %}
 6634   ins_pipe(ialu_reg_reg);
 6635 %}
 6636 
 6637 instruct orshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6638   match(Set dst (OrI src1 (LShiftI src2 src3)));
 6639 
 6640   size(4);
 6641   format %{ "orr_32 $dst,$src1,$src2<<$src3" %}
 6642   ins_encode %{
 6643     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 6644   %}
 6645   ins_pipe(ialu_reg_reg);
 6646 %}
 6647 
 6648 instruct orsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6649   match(Set dst (OrI src1 (RShiftI src2 src3)));
 6650 
 6651   size(4);
 6652   format %{ "OR    $dst,$src1,$src2>>$src3" %}
 6653   ins_encode %{
 6654     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 6655   %}
 6656   ins_pipe(ialu_reg_reg);
 6657 %}
 6658 
 6659 instruct orsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6660   match(Set dst (OrI src1 (RShiftI src2 src3)));
 6661 
 6662   size(4);
 6663   format %{ "orr_32 $dst,$src1,$src2>>$src3" %}
 6664   ins_encode %{
 6665     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 6666   %}
 6667   ins_pipe(ialu_reg_reg);
 6668 %}
 6669 
 6670 instruct orshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6671   match(Set dst (OrI src1 (URShiftI src2 src3)));
 6672 
 6673   size(4);
 6674   format %{ "OR    $dst,$src1,$src2>>>$src3" %}
 6675   ins_encode %{
 6676     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 6677   %}
 6678   ins_pipe(ialu_reg_reg);
 6679 %}
 6680 
 6681 instruct orshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6682   match(Set dst (OrI src1 (URShiftI src2 src3)));
 6683 
 6684   size(4);
 6685   format %{ "orr_32 $dst,$src1,$src2>>>$src3" %}
 6686   ins_encode %{
 6687     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 6688   %}
 6689   ins_pipe(ialu_reg_reg);
 6690 %}
 6691 
 6692 // Immediate Or
 6693 instruct orI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
 6694   match(Set dst (OrI src1 src2));
 6695 
 6696   size(4);
 6697   format %{ "orr_32  $dst,$src1,$src2" %}
 6698   ins_encode %{
 6699     __ orr_32($dst$$Register, $src1$$Register, $src2$$constant);
 6700   %}
 6701   ins_pipe(ialu_reg_imm);
 6702 %}
 6703 // TODO: orn_32 with limmIn
 6704 
 6705 // Register Or Long
 6706 instruct orL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 6707   match(Set dst (OrL src1 src2));
 6708 
 6709   ins_cost(DEFAULT_COST);
 6710   size(8);
 6711   format %{ "OR     $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
 6712             "OR     $dst.hi,$src1.hi,$src2.hi" %}
 6713   ins_encode %{
 6714     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
 6715     __ orr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 6716   %}
 6717   ins_pipe(ialu_reg_reg);
 6718 %}
 6719 
 6720 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 6721 // (hi($con$$constant), lo($con$$constant)) becomes
 6722 instruct orL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
 6723   match(Set dst (OrL src1 con));
 6724   ins_cost(DEFAULT_COST);
 6725   size(8);
 6726   format %{ "OR     $dst.lo,$src1.lo,$con\t! long\n\t"
 6727             "OR     $dst.hi,$src1.hi,$con" %}
 6728   ins_encode %{
 6729     __ orr($dst$$Register, $src1$$Register, $con$$constant);
 6730     __ orr($dst$$Register->successor(), $src1$$Register->successor(), 0);
 6731   %}
 6732   ins_pipe(ialu_reg_imm);
 6733 %}
 6734 
 6735 #ifdef TODO
 6736 // Use SPRegP to match Rthread (TLS register) without spilling.
 6737 // Use store_ptr_RegP to match Rthread (TLS register) without spilling.
 6738 // Use sp_ptr_RegP to match Rthread (TLS register) without spilling.
 6739 instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
 6740   match(Set dst (OrI src1 (CastP2X src2)));
 6741   size(4);
 6742   format %{ "OR     $dst,$src1,$src2" %}
 6743   ins_encode %{
 6744     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
 6745   %}
 6746   ins_pipe(ialu_reg_reg);
 6747 %}
 6748 #endif
 6749 
 6750 // Xor Instructions
 6751 // Register Xor
 6752 instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6753   match(Set dst (XorI src1 src2));
 6754 
 6755   size(4);
 6756   format %{ "eor_32 $dst,$src1,$src2" %}
 6757   ins_encode %{
 6758     __ eor_32($dst$$Register, $src1$$Register, $src2$$Register);
 6759   %}
 6760   ins_pipe(ialu_reg_reg);
 6761 %}
 6762 
 6763 instruct xorshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6764   match(Set dst (XorI src1 (LShiftI src2 src3)));
 6765 
 6766   size(4);
 6767   format %{ "XOR    $dst,$src1,$src2<<$src3" %}
 6768   ins_encode %{
 6769     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 6770   %}
 6771   ins_pipe(ialu_reg_reg);
 6772 %}
 6773 
 6774 instruct xorshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6775   match(Set dst (XorI src1 (LShiftI src2 src3)));
 6776 
 6777   size(4);
 6778   format %{ "eor_32 $dst,$src1,$src2<<$src3" %}
 6779   ins_encode %{
 6780     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 6781   %}
 6782   ins_pipe(ialu_reg_reg);
 6783 %}
 6784 
 6785 instruct xorsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6786   match(Set dst (XorI src1 (RShiftI src2 src3)));
 6787 
 6788   size(4);
 6789   format %{ "XOR    $dst,$src1,$src2>>$src3" %}
 6790   ins_encode %{
 6791     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 6792   %}
 6793   ins_pipe(ialu_reg_reg);
 6794 %}
 6795 
 6796 instruct xorsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6797   match(Set dst (XorI src1 (RShiftI src2 src3)));
 6798 
 6799   size(4);
 6800   format %{ "eor_32 $dst,$src1,$src2>>$src3" %}
 6801   ins_encode %{
 6802     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 6803   %}
 6804   ins_pipe(ialu_reg_reg);
 6805 %}
 6806 
 6807 instruct xorshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6808   match(Set dst (XorI src1 (URShiftI src2 src3)));
 6809 
 6810   size(4);
 6811   format %{ "XOR    $dst,$src1,$src2>>>$src3" %}
 6812   ins_encode %{
 6813     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 6814   %}
 6815   ins_pipe(ialu_reg_reg);
 6816 %}
 6817 
 6818 instruct xorshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6819   match(Set dst (XorI src1 (URShiftI src2 src3)));
 6820 
 6821   size(4);
 6822   format %{ "eor_32 $dst,$src1,$src2>>>$src3" %}
 6823   ins_encode %{
 6824     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 6825   %}
 6826   ins_pipe(ialu_reg_reg);
 6827 %}
 6828 
 6829 // Immediate Xor
 6830 instruct xorI_reg_imm(iRegI dst, iRegI src1, limmI src2) %{
 6831   match(Set dst (XorI src1 src2));
 6832 
 6833   size(4);
 6834   format %{ "eor_32 $dst,$src1,$src2" %}
 6835   ins_encode %{
 6836     __ eor_32($dst$$Register, $src1$$Register, $src2$$constant);
 6837   %}
 6838   ins_pipe(ialu_reg_imm);
 6839 %}
 6840 
 6841 // Register Xor Long
 6842 instruct xorL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 6843   match(Set dst (XorL src1 src2));
 6844   ins_cost(DEFAULT_COST);
 6845   size(8);
 6846   format %{ "XOR     $dst.hi,$src1.hi,$src2.hi\t! long\n\t"
 6847             "XOR     $dst.lo,$src1.lo,$src2.lo\t! long" %}
 6848   ins_encode %{
 6849     __ eor($dst$$Register, $src1$$Register, $src2$$Register);
 6850     __ eor($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 6851   %}
 6852   ins_pipe(ialu_reg_reg);
 6853 %}
 6854 
 6855 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 6856 // (hi($con$$constant), lo($con$$constant)) becomes
 6857 instruct xorL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
 6858   match(Set dst (XorL src1 con));
 6859   ins_cost(DEFAULT_COST);
 6860   size(8);
 6861   format %{ "XOR     $dst.hi,$src1.hi,$con\t! long\n\t"
 6862             "XOR     $dst.lo,$src1.lo,0\t! long" %}
 6863   ins_encode %{
 6864     __ eor($dst$$Register, $src1$$Register, $con$$constant);
 6865     __ eor($dst$$Register->successor(), $src1$$Register->successor(), 0);
 6866   %}
 6867   ins_pipe(ialu_reg_imm);
 6868 %}
 6869 
 6870 instruct cmpLTMask_reg_reg( iRegI dst, iRegI p, iRegI q, flagsReg ccr ) %{
 6871   match(Set dst (CmpLTMask p q));
 6872   effect( KILL ccr );
 6873   ins_cost(DEFAULT_COST*3);
 6874   format %{ "CMP    $p,$q\n\t"
 6875             "MOV    $dst, #0\n\t"
 6876             "MOV.lt $dst, #-1" %}
 6877   ins_encode %{
 6878     __ cmp($p$$Register, $q$$Register);
 6879     __ mov($dst$$Register, 0);
 6880     __ mvn($dst$$Register, 0, lt);
 6881   %}
 6882   ins_pipe(ialu_reg_reg_ialu);
 6883 %}
 6884 
 6885 instruct cmpLTMask_reg_imm( iRegI dst, iRegI p, aimmI q, flagsReg ccr ) %{
 6886   match(Set dst (CmpLTMask p q));
 6887   effect( KILL ccr );
 6888   ins_cost(DEFAULT_COST*3);
 6889   format %{ "CMP    $p,$q\n\t"
 6890             "MOV    $dst, #0\n\t"
 6891             "MOV.lt $dst, #-1" %}
 6892   ins_encode %{
 6893     __ cmp($p$$Register, $q$$constant);
 6894     __ mov($dst$$Register, 0);
 6895     __ mvn($dst$$Register, 0, lt);
 6896   %}
 6897   ins_pipe(ialu_reg_reg_ialu);
 6898 %}
 6899 
 6900 instruct cadd_cmpLTMask3( iRegI p, iRegI q, iRegI y, iRegI z, flagsReg ccr ) %{
 6901   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
 6902   effect( KILL ccr );
 6903   ins_cost(DEFAULT_COST*2);
 6904   format %{ "CMP    $p,$q\n\t"
 6905             "ADD.lt $z,$y,$z" %}
 6906   ins_encode %{
 6907     __ cmp($p$$Register, $q$$Register);
 6908     __ add($z$$Register, $y$$Register, $z$$Register, lt);
 6909   %}
 6910   ins_pipe( cadd_cmpltmask );
 6911 %}
 6912 
 6913 // FIXME: remove unused "dst"
 6914 instruct cadd_cmpLTMask4( iRegI dst, iRegI p, aimmI q, iRegI y, iRegI z, flagsReg ccr ) %{
 6915   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
 6916   effect( KILL ccr );
 6917   ins_cost(DEFAULT_COST*2);
 6918   format %{ "CMP    $p,$q\n\t"
 6919             "ADD.lt $z,$y,$z" %}
 6920   ins_encode %{
 6921     __ cmp($p$$Register, $q$$constant);
 6922     __ add($z$$Register, $y$$Register, $z$$Register, lt);
 6923   %}
 6924   ins_pipe( cadd_cmpltmask );
 6925 %}
 6926 
 6927 instruct cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, flagsReg ccr ) %{
 6928   match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
 6929   effect( KILL ccr );
 6930   ins_cost(DEFAULT_COST*2);
 6931   format %{ "SUBS   $p,$p,$q\n\t"
 6932             "ADD.lt $p,$y,$p" %}
 6933   ins_encode %{
 6934     __ subs($p$$Register, $p$$Register, $q$$Register);
 6935     __ add($p$$Register, $y$$Register, $p$$Register, lt);
 6936   %}
 6937   ins_pipe( cadd_cmpltmask );
 6938 %}
 6939 
 6940 //----------Arithmetic Conversion Instructions---------------------------------
 6941 // The conversions operations are all Alpha sorted.  Please keep it that way!
 6942 
 6943 instruct convD2F_reg(regF dst, regD src) %{
 6944   match(Set dst (ConvD2F src));
 6945   size(4);
 6946   format %{ "FCVTSD  $dst,$src" %}
 6947   ins_encode %{
 6948     __ convert_d2f($dst$$FloatRegister, $src$$FloatRegister);
 6949   %}
 6950   ins_pipe(fcvtD2F);
 6951 %}
 6952 
 6953 // Convert a double to an int in a float register.
 6954 // If the double is a NAN, stuff a zero in instead.
 6955 
 6956 instruct convD2I_reg_reg(iRegI dst, regD src, regF tmp) %{
 6957   match(Set dst (ConvD2I src));
 6958   effect( TEMP tmp );
 6959   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
 6960   format %{ "FTOSIZD  $tmp,$src\n\t"
 6961             "FMRS     $dst, $tmp" %}
 6962   ins_encode %{
 6963     __ ftosizd($tmp$$FloatRegister, $src$$FloatRegister);
 6964     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 6965   %}
 6966   ins_pipe(fcvtD2I);
 6967 %}
 6968 
 6969 // Convert a double to a long in a double register.
 6970 // If the double is a NAN, stuff a zero in instead.
 6971 
 6972 // Double to Long conversion
 6973 instruct convD2L_reg(R0R1RegL dst, regD src) %{
 6974   match(Set dst (ConvD2L src));
 6975   effect(CALL);
 6976   ins_cost(MEMORY_REF_COST); // FIXME
 6977   format %{ "convD2L    $dst,$src\t ! call to SharedRuntime::d2l" %}
 6978   ins_encode %{
 6979 #ifndef __ABI_HARD__
 6980     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
 6981 #else
 6982     if ($src$$FloatRegister != D0) {
 6983       __ mov_double(D0, $src$$FloatRegister);
 6984     }
 6985 #endif
 6986     address target = CAST_FROM_FN_PTR(address, SharedRuntime::d2l);
 6987     __ call(target, relocInfo::runtime_call_type);
 6988   %}
 6989   ins_pipe(fcvtD2L);
 6990 %}
 6991 
 6992 instruct convF2D_reg(regD dst, regF src) %{
 6993   match(Set dst (ConvF2D src));
 6994   size(4);
 6995   format %{ "FCVTDS  $dst,$src" %}
 6996   ins_encode %{
 6997     __ convert_f2d($dst$$FloatRegister, $src$$FloatRegister);
 6998   %}
 6999   ins_pipe(fcvtF2D);
 7000 %}
 7001 
 7002 instruct convF2I_reg_reg(iRegI dst, regF src, regF tmp) %{
 7003   match(Set dst (ConvF2I src));
 7004   effect( TEMP tmp );
 7005   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
 7006   size(8);
 7007   format %{ "FTOSIZS  $tmp,$src\n\t"
 7008             "FMRS     $dst, $tmp" %}
 7009   ins_encode %{
 7010     __ ftosizs($tmp$$FloatRegister, $src$$FloatRegister);
 7011     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 7012   %}
 7013   ins_pipe(fcvtF2I);
 7014 %}
 7015 
 7016 // Float to Long conversion
 7017 instruct convF2L_reg(R0R1RegL dst, regF src, R0RegI arg1) %{
 7018   match(Set dst (ConvF2L src));
 7019   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
 7020   effect(CALL);
 7021   format %{ "convF2L  $dst,$src\t! call to SharedRuntime::f2l" %}
 7022   ins_encode %{
 7023 #ifndef __ABI_HARD__
 7024     __ fmrs($arg1$$Register, $src$$FloatRegister);
 7025 #else
 7026     if($src$$FloatRegister != S0) {
 7027       __ mov_float(S0, $src$$FloatRegister);
 7028     }
 7029 #endif
 7030     address target = CAST_FROM_FN_PTR(address, SharedRuntime::f2l);
 7031     __ call(target, relocInfo::runtime_call_type);
 7032   %}
 7033   ins_pipe(fcvtF2L);
 7034 %}
 7035 
 7036 instruct convI2D_reg_reg(iRegI src, regD_low dst) %{
 7037   match(Set dst (ConvI2D src));
 7038   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
 7039   size(8);
 7040   format %{ "FMSR     $dst,$src \n\t"
 7041             "FSITOD   $dst $dst"%}
 7042   ins_encode %{
 7043       __ fmsr($dst$$FloatRegister, $src$$Register);
 7044       __ fsitod($dst$$FloatRegister, $dst$$FloatRegister);
 7045   %}
 7046   ins_pipe(fcvtI2D);
 7047 %}
 7048 
 7049 instruct convI2F_reg_reg( regF dst, iRegI src ) %{
 7050   match(Set dst (ConvI2F src));
 7051   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
 7052   size(8);
 7053   format %{ "FMSR     $dst,$src \n\t"
 7054             "FSITOS   $dst, $dst"%}
 7055   ins_encode %{
 7056       __ fmsr($dst$$FloatRegister, $src$$Register);
 7057       __ fsitos($dst$$FloatRegister, $dst$$FloatRegister);
 7058   %}
 7059   ins_pipe(fcvtI2F);
 7060 %}
 7061 
 7062 instruct convI2L_reg(iRegL dst, iRegI src) %{
 7063   match(Set dst (ConvI2L src));
 7064   size(8);
 7065   format %{ "MOV    $dst.lo, $src \n\t"
 7066             "ASR    $dst.hi,$src,31\t! int->long" %}
 7067   ins_encode %{
 7068     __ mov($dst$$Register, $src$$Register);
 7069     __ mov($dst$$Register->successor(), AsmOperand($src$$Register, asr, 31));
 7070   %}
 7071   ins_pipe(ialu_reg_reg);
 7072 %}
 7073 
 7074 // Zero-extend convert int to long
 7075 instruct convI2L_reg_zex(iRegL dst, iRegI src, immL_32bits mask ) %{
 7076   match(Set dst (AndL (ConvI2L src) mask) );
 7077   size(8);
 7078   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend int to long\n\t"
 7079             "MOV    $dst.hi, 0"%}
 7080   ins_encode %{
 7081     __ mov($dst$$Register, $src$$Register);
 7082     __ mov($dst$$Register->successor(), 0);
 7083   %}
 7084   ins_pipe(ialu_reg_reg);
 7085 %}
 7086 
 7087 // Zero-extend long
 7088 instruct zerox_long(iRegL dst, iRegL src, immL_32bits mask ) %{
 7089   match(Set dst (AndL src mask) );
 7090   size(8);
 7091   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend long\n\t"
 7092             "MOV    $dst.hi, 0"%}
 7093   ins_encode %{
 7094     __ mov($dst$$Register, $src$$Register);
 7095     __ mov($dst$$Register->successor(), 0);
 7096   %}
 7097   ins_pipe(ialu_reg_reg);
 7098 %}
 7099 
 7100 instruct MoveF2I_reg_reg(iRegI dst, regF src) %{
 7101   match(Set dst (MoveF2I src));
 7102   effect(DEF dst, USE src);
 7103   ins_cost(MEMORY_REF_COST); // FIXME
 7104 
 7105   size(4);
 7106   format %{ "FMRS   $dst,$src\t! MoveF2I" %}
 7107   ins_encode %{
 7108     __ fmrs($dst$$Register, $src$$FloatRegister);
 7109   %}
 7110   ins_pipe(iload_mem); // FIXME
 7111 %}
 7112 
 7113 instruct MoveI2F_reg_reg(regF dst, iRegI src) %{
 7114   match(Set dst (MoveI2F src));
 7115   ins_cost(MEMORY_REF_COST); // FIXME
 7116 
 7117   size(4);
 7118   format %{ "FMSR   $dst,$src\t! MoveI2F" %}
 7119   ins_encode %{
 7120     __ fmsr($dst$$FloatRegister, $src$$Register);
 7121   %}
 7122   ins_pipe(iload_mem); // FIXME
 7123 %}
 7124 
 7125 instruct MoveD2L_reg_reg(iRegL dst, regD src) %{
 7126   match(Set dst (MoveD2L src));
 7127   effect(DEF dst, USE src);
 7128   ins_cost(MEMORY_REF_COST); // FIXME
 7129 
 7130   size(4);
 7131   format %{ "FMRRD    $dst,$src\t! MoveD2L" %}
 7132   ins_encode %{
 7133     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
 7134   %}
 7135   ins_pipe(iload_mem); // FIXME
 7136 %}
 7137 
 7138 instruct MoveL2D_reg_reg(regD dst, iRegL src) %{
 7139   match(Set dst (MoveL2D src));
 7140   effect(DEF dst, USE src);
 7141   ins_cost(MEMORY_REF_COST); // FIXME
 7142 
 7143   size(4);
 7144   format %{ "FMDRR   $dst,$src\t! MoveL2D" %}
 7145   ins_encode %{
 7146     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
 7147   %}
 7148   ins_pipe(ialu_reg_reg); // FIXME
 7149 %}
 7150 
 7151 //-----------
 7152 // Long to Double conversion
 7153 
 7154 // Magic constant, 0x43300000
 7155 instruct loadConI_x43300000(iRegI dst) %{
 7156   effect(DEF dst);
 7157   size(8);
 7158   format %{ "MOV_SLOW  $dst,0x43300000\t! 2^52" %}
 7159   ins_encode %{
 7160     __ mov_slow($dst$$Register, 0x43300000);
 7161   %}
 7162   ins_pipe(ialu_none);
 7163 %}
 7164 
 7165 // Magic constant, 0x41f00000
 7166 instruct loadConI_x41f00000(iRegI dst) %{
 7167   effect(DEF dst);
 7168   size(8);
 7169   format %{ "MOV_SLOW  $dst, 0x41f00000\t! 2^32" %}
 7170   ins_encode %{
 7171     __ mov_slow($dst$$Register, 0x41f00000);
 7172   %}
 7173   ins_pipe(ialu_none);
 7174 %}
 7175 
 7176 instruct loadConI_x0(iRegI dst) %{
 7177   effect(DEF dst);
 7178   size(4);
 7179   format %{ "MOV  $dst, 0x0\t! 0" %}
 7180   ins_encode %{
 7181     __ mov($dst$$Register, 0);
 7182   %}
 7183   ins_pipe(ialu_none);
 7184 %}
 7185 
 7186 // Construct a double from two float halves
 7187 instruct regDHi_regDLo_to_regD(regD_low dst, regD_low src1, regD_low src2) %{
 7188   effect(DEF dst, USE src1, USE src2);
 7189   size(8);
 7190   format %{ "FCPYS  $dst.hi,$src1.hi\n\t"
 7191             "FCPYS  $dst.lo,$src2.lo" %}
 7192   ins_encode %{
 7193     __ fcpys($dst$$FloatRegister->successor(), $src1$$FloatRegister->successor());
 7194     __ fcpys($dst$$FloatRegister, $src2$$FloatRegister);
 7195   %}
 7196   ins_pipe(faddD_reg_reg);
 7197 %}
 7198 
 7199 // Convert integer in high half of a double register (in the lower half of
 7200 // the double register file) to double
 7201 instruct convI2D_regDHi_regD(regD dst, regD_low src) %{
 7202   effect(DEF dst, USE src);
 7203   size(4);
 7204   format %{ "FSITOD  $dst,$src" %}
 7205   ins_encode %{
 7206     __ fsitod($dst$$FloatRegister, $src$$FloatRegister->successor());
 7207   %}
 7208   ins_pipe(fcvtLHi2D);
 7209 %}
 7210 
 7211 // Add float double precision
 7212 instruct addD_regD_regD(regD dst, regD src1, regD src2) %{
 7213   effect(DEF dst, USE src1, USE src2);
 7214   size(4);
 7215   format %{ "FADDD  $dst,$src1,$src2" %}
 7216   ins_encode %{
 7217     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 7218   %}
 7219   ins_pipe(faddD_reg_reg);
 7220 %}
 7221 
 7222 // Sub float double precision
 7223 instruct subD_regD_regD(regD dst, regD src1, regD src2) %{
 7224   effect(DEF dst, USE src1, USE src2);
 7225   size(4);
 7226   format %{ "FSUBD  $dst,$src1,$src2" %}
 7227   ins_encode %{
 7228     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 7229   %}
 7230   ins_pipe(faddD_reg_reg);
 7231 %}
 7232 
 7233 // Mul float double precision
 7234 instruct mulD_regD_regD(regD dst, regD src1, regD src2) %{
 7235   effect(DEF dst, USE src1, USE src2);
 7236   size(4);
 7237   format %{ "FMULD  $dst,$src1,$src2" %}
 7238   ins_encode %{
 7239     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 7240   %}
 7241   ins_pipe(fmulD_reg_reg);
 7242 %}
 7243 
 7244 instruct regL_to_regD(regD dst, iRegL src) %{
 7245   // No match rule to avoid chain rule match.
 7246   effect(DEF dst, USE src);
 7247   ins_cost(MEMORY_REF_COST);
 7248   size(4);
 7249   format %{ "FMDRR   $dst,$src\t! regL to regD" %}
 7250   ins_encode %{
 7251     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
 7252   %}
 7253   ins_pipe(ialu_reg_reg); // FIXME
 7254 %}
 7255 
 7256 instruct regI_regI_to_regD(regD dst, iRegI src1, iRegI src2) %{
 7257   // No match rule to avoid chain rule match.
 7258   effect(DEF dst, USE src1, USE src2);
 7259   ins_cost(MEMORY_REF_COST);
 7260   size(4);
 7261   format %{ "FMDRR   $dst,$src1,$src2\t! regI,regI to regD" %}
 7262   ins_encode %{
 7263     __ fmdrr($dst$$FloatRegister, $src1$$Register, $src2$$Register);
 7264   %}
 7265   ins_pipe(ialu_reg_reg); // FIXME
 7266 %}
 7267 
 7268 instruct convL2D_reg_slow_fxtof(regD dst, iRegL src) %{
 7269   match(Set dst (ConvL2D src));
 7270   ins_cost(DEFAULT_COST*8 + MEMORY_REF_COST*6); // FIXME
 7271 
 7272   expand %{
 7273     regD_low   tmpsrc;
 7274     iRegI      ix43300000;
 7275     iRegI      ix41f00000;
 7276     iRegI      ix0;
 7277     regD_low   dx43300000;
 7278     regD       dx41f00000;
 7279     regD       tmp1;
 7280     regD_low   tmp2;
 7281     regD       tmp3;
 7282     regD       tmp4;
 7283 
 7284     regL_to_regD(tmpsrc, src);
 7285 
 7286     loadConI_x43300000(ix43300000);
 7287     loadConI_x41f00000(ix41f00000);
 7288     loadConI_x0(ix0);
 7289 
 7290     regI_regI_to_regD(dx43300000, ix0, ix43300000);
 7291     regI_regI_to_regD(dx41f00000, ix0, ix41f00000);
 7292 
 7293     convI2D_regDHi_regD(tmp1, tmpsrc);
 7294     regDHi_regDLo_to_regD(tmp2, dx43300000, tmpsrc);
 7295     subD_regD_regD(tmp3, tmp2, dx43300000);
 7296     mulD_regD_regD(tmp4, tmp1, dx41f00000);
 7297     addD_regD_regD(dst, tmp3, tmp4);
 7298   %}
 7299 %}
 7300 
 7301 instruct convL2I_reg(iRegI dst, iRegL src) %{
 7302   match(Set dst (ConvL2I src));
 7303   size(4);
 7304   format %{ "MOV    $dst,$src.lo\t! long->int" %}
 7305   ins_encode %{
 7306     __ mov($dst$$Register, $src$$Register);
 7307   %}
 7308   ins_pipe(ialu_move_reg_I_to_L);
 7309 %}
 7310 
 7311 // Register Shift Right Immediate
 7312 instruct shrL_reg_imm6_L2I(iRegI dst, iRegL src, immI_32_63 cnt) %{
 7313   match(Set dst (ConvL2I (RShiftL src cnt)));
 7314   size(4);
 7315   format %{ "ASR    $dst,$src.hi,($cnt - 32)\t! long->int or mov if $cnt==32" %}
 7316   ins_encode %{
 7317     if ($cnt$$constant == 32) {
 7318       __ mov($dst$$Register, $src$$Register->successor());
 7319     } else {
 7320       __ mov($dst$$Register, AsmOperand($src$$Register->successor(), asr, $cnt$$constant - 32));
 7321     }
 7322   %}
 7323   ins_pipe(ialu_reg_imm);
 7324 %}
 7325 
 7326 
 7327 //----------Control Flow Instructions------------------------------------------
 7328 // Compare Instructions
 7329 // Compare Integers
 7330 instruct compI_iReg(flagsReg icc, iRegI op1, iRegI op2) %{
 7331   match(Set icc (CmpI op1 op2));
 7332   effect( DEF icc, USE op1, USE op2 );
 7333 
 7334   size(4);
 7335   format %{ "cmp_32 $op1,$op2\t! int" %}
 7336   ins_encode %{
 7337     __ cmp_32($op1$$Register, $op2$$Register);
 7338   %}
 7339   ins_pipe(ialu_cconly_reg_reg);
 7340 %}
 7341 
 7342 #ifdef _LP64
 7343 // Compare compressed pointers
 7344 instruct compN_reg2(flagsRegU icc, iRegN op1, iRegN op2) %{
 7345   match(Set icc (CmpN op1 op2));
 7346   effect( DEF icc, USE op1, USE op2 );
 7347 
 7348   size(4);
 7349   format %{ "cmp_32 $op1,$op2\t! int" %}
 7350   ins_encode %{
 7351     __ cmp_32($op1$$Register, $op2$$Register);
 7352   %}
 7353   ins_pipe(ialu_cconly_reg_reg);
 7354 %}
 7355 #endif
 7356 
 7357 instruct compU_iReg(flagsRegU icc, iRegI op1, iRegI op2) %{
 7358   match(Set icc (CmpU op1 op2));
 7359 
 7360   size(4);
 7361   format %{ "cmp_32 $op1,$op2\t! unsigned int" %}
 7362   ins_encode %{
 7363     __ cmp_32($op1$$Register, $op2$$Register);
 7364   %}
 7365   ins_pipe(ialu_cconly_reg_reg);
 7366 %}
 7367 
 7368 instruct compI_iReg_immneg(flagsReg icc, iRegI op1, aimmIneg op2) %{
 7369   match(Set icc (CmpI op1 op2));
 7370   effect( DEF icc, USE op1 );
 7371 
 7372   size(4);
 7373   format %{ "cmn_32 $op1,-$op2\t! int" %}
 7374   ins_encode %{
 7375     __ cmn_32($op1$$Register, -$op2$$constant);
 7376   %}
 7377   ins_pipe(ialu_cconly_reg_imm);
 7378 %}
 7379 
 7380 instruct compI_iReg_imm(flagsReg icc, iRegI op1, aimmI op2) %{
 7381   match(Set icc (CmpI op1 op2));
 7382   effect( DEF icc, USE op1 );
 7383 
 7384   size(4);
 7385   format %{ "cmp_32 $op1,$op2\t! int" %}
 7386   ins_encode %{
 7387     __ cmp_32($op1$$Register, $op2$$constant);
 7388   %}
 7389   ins_pipe(ialu_cconly_reg_imm);
 7390 %}
 7391 
 7392 instruct testI_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immI0 zero ) %{
 7393   match(Set icc (CmpI (AndI op1 op2) zero));
 7394   size(4);
 7395   format %{ "tst_32 $op2,$op1" %}
 7396 
 7397   ins_encode %{
 7398     __ tst_32($op1$$Register, $op2$$Register);
 7399   %}
 7400   ins_pipe(ialu_cconly_reg_reg_zero);
 7401 %}
 7402 
 7403 instruct testshlI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
 7404   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
 7405   size(4);
 7406   format %{ "TST   $op2,$op1<<$op3" %}
 7407 
 7408   ins_encode %{
 7409     __ tst($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$Register));
 7410   %}
 7411   ins_pipe(ialu_cconly_reg_reg_zero);
 7412 %}
 7413 
 7414 instruct testshlI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
 7415   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
 7416   size(4);
 7417   format %{ "tst_32 $op2,$op1<<$op3" %}
 7418 
 7419   ins_encode %{
 7420     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$constant));
 7421   %}
 7422   ins_pipe(ialu_cconly_reg_reg_zero);
 7423 %}
 7424 
 7425 instruct testsarI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
 7426   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
 7427   size(4);
 7428   format %{ "TST   $op2,$op1<<$op3" %}
 7429 
 7430   ins_encode %{
 7431     __ tst($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$Register));
 7432   %}
 7433   ins_pipe(ialu_cconly_reg_reg_zero);
 7434 %}
 7435 
 7436 instruct testsarI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
 7437   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
 7438   size(4);
 7439   format %{ "tst_32 $op2,$op1<<$op3" %}
 7440 
 7441   ins_encode %{
 7442     __ tst_32($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$constant));
 7443   %}
 7444   ins_pipe(ialu_cconly_reg_reg_zero);
 7445 %}
 7446 
 7447 instruct testshrI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
 7448   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
 7449   size(4);
 7450   format %{ "TST   $op2,$op1<<$op3" %}
 7451 
 7452   ins_encode %{
 7453     __ tst($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$Register));
 7454   %}
 7455   ins_pipe(ialu_cconly_reg_reg_zero);
 7456 %}
 7457 
 7458 instruct testshrI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
 7459   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
 7460   size(4);
 7461   format %{ "tst_32 $op2,$op1<<$op3" %}
 7462 
 7463   ins_encode %{
 7464     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$constant));
 7465   %}
 7466   ins_pipe(ialu_cconly_reg_reg_zero);
 7467 %}
 7468 
 7469 instruct testI_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, limmI op2, immI0 zero ) %{
 7470   match(Set icc (CmpI (AndI op1 op2) zero));
 7471   size(4);
 7472   format %{ "tst_32 $op2,$op1" %}
 7473 
 7474   ins_encode %{
 7475     __ tst_32($op1$$Register, $op2$$constant);
 7476   %}
 7477   ins_pipe(ialu_cconly_reg_imm_zero);
 7478 %}
 7479 
 7480 instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7481   match(Set xcc (CmpL op1 op2));
 7482   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
 7483 
 7484   size(8);
 7485   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! long\n\t"
 7486             "SBCS    $tmp,$op1.hi,$op2.hi" %}
 7487   ins_encode %{
 7488     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
 7489     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
 7490   %}
 7491   ins_pipe(ialu_cconly_reg_reg);
 7492 %}
 7493 
 7494 instruct compUL_reg_reg_LTGE(flagsRegUL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7495   match(Set xcc (CmpUL op1 op2));
 7496   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
 7497 
 7498   size(8);
 7499   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! unsigned long\n\t"
 7500             "SBCS    $tmp,$op1.hi,$op2.hi" %}
 7501   ins_encode %{
 7502     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
 7503     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
 7504   %}
 7505   ins_pipe(ialu_cconly_reg_reg);
 7506 %}
 7507 
 7508 instruct compL_reg_reg_EQNE(flagsRegL_EQNE xcc, iRegL op1, iRegL op2) %{
 7509   match(Set xcc (CmpL op1 op2));
 7510   effect( DEF xcc, USE op1, USE op2 );
 7511 
 7512   size(8);
 7513   format %{ "TEQ    $op1.hi,$op2.hi\t\t! long\n\t"
 7514             "TEQ.eq $op1.lo,$op2.lo" %}
 7515   ins_encode %{
 7516     __ teq($op1$$Register->successor(), $op2$$Register->successor());
 7517     __ teq($op1$$Register, $op2$$Register, eq);
 7518   %}
 7519   ins_pipe(ialu_cconly_reg_reg);
 7520 %}
 7521 
 7522 instruct compL_reg_reg_LEGT(flagsRegL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7523   match(Set xcc (CmpL op1 op2));
 7524   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
 7525 
 7526   size(8);
 7527   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! long\n\t"
 7528             "SBCS    $tmp,$op2.hi,$op1.hi" %}
 7529   ins_encode %{
 7530     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
 7531     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
 7532   %}
 7533   ins_pipe(ialu_cconly_reg_reg);
 7534 %}
 7535 
 7536 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7537 // (hi($con$$constant), lo($con$$constant)) becomes
 7538 instruct compL_reg_con_LTGE(flagsRegL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7539   match(Set xcc (CmpL op1 con));
 7540   effect( DEF xcc, USE op1, USE con, TEMP tmp );
 7541 
 7542   size(8);
 7543   format %{ "SUBS    $tmp,$op1.low,$con\t\t! long\n\t"
 7544             "SBCS    $tmp,$op1.hi,0" %}
 7545   ins_encode %{
 7546     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
 7547     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7548   %}
 7549 
 7550   ins_pipe(ialu_cconly_reg_reg);
 7551 %}
 7552 
 7553 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7554 // (hi($con$$constant), lo($con$$constant)) becomes
 7555 instruct compL_reg_con_EQNE(flagsRegL_EQNE xcc, iRegL op1, immLlowRot con) %{
 7556   match(Set xcc (CmpL op1 con));
 7557   effect( DEF xcc, USE op1, USE con );
 7558 
 7559   size(8);
 7560   format %{ "TEQ    $op1.hi,0\t\t! long\n\t"
 7561             "TEQ.eq $op1.lo,$con" %}
 7562   ins_encode %{
 7563     __ teq($op1$$Register->successor(), 0);
 7564     __ teq($op1$$Register, $con$$constant, eq);
 7565   %}
 7566 
 7567   ins_pipe(ialu_cconly_reg_reg);
 7568 %}
 7569 
 7570 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7571 // (hi($con$$constant), lo($con$$constant)) becomes
 7572 instruct compL_reg_con_LEGT(flagsRegL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7573   match(Set xcc (CmpL op1 con));
 7574   effect( DEF xcc, USE op1, USE con, TEMP tmp );
 7575 
 7576   size(8);
 7577   format %{ "RSBS    $tmp,$op1.low,$con\t\t! long\n\t"
 7578             "RSCS    $tmp,$op1.hi,0" %}
 7579   ins_encode %{
 7580     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
 7581     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7582   %}
 7583 
 7584   ins_pipe(ialu_cconly_reg_reg);
 7585 %}
 7586 
 7587 instruct compUL_reg_reg_EQNE(flagsRegUL_EQNE xcc, iRegL op1, iRegL op2) %{
 7588   match(Set xcc (CmpUL op1 op2));
 7589   effect(DEF xcc, USE op1, USE op2);
 7590 
 7591   size(8);
 7592   format %{ "TEQ    $op1.hi,$op2.hi\t\t! unsigned long\n\t"
 7593             "TEQ.eq $op1.lo,$op2.lo" %}
 7594   ins_encode %{
 7595     __ teq($op1$$Register->successor(), $op2$$Register->successor());
 7596     __ teq($op1$$Register, $op2$$Register, eq);
 7597   %}
 7598   ins_pipe(ialu_cconly_reg_reg);
 7599 %}
 7600 
 7601 instruct compUL_reg_reg_LEGT(flagsRegUL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7602   match(Set xcc (CmpUL op1 op2));
 7603   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
 7604 
 7605   size(8);
 7606   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! unsigned long\n\t"
 7607             "SBCS    $tmp,$op2.hi,$op1.hi" %}
 7608   ins_encode %{
 7609     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
 7610     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
 7611   %}
 7612   ins_pipe(ialu_cconly_reg_reg);
 7613 %}
 7614 
 7615 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7616 // (hi($con$$constant), lo($con$$constant)) becomes
 7617 instruct compUL_reg_con_LTGE(flagsRegUL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7618   match(Set xcc (CmpUL op1 con));
 7619   effect(DEF xcc, USE op1, USE con, TEMP tmp);
 7620 
 7621   size(8);
 7622   format %{ "SUBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
 7623             "SBCS    $tmp,$op1.hi,0" %}
 7624   ins_encode %{
 7625     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
 7626     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7627   %}
 7628 
 7629   ins_pipe(ialu_cconly_reg_reg);
 7630 %}
 7631 
 7632 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7633 // (hi($con$$constant), lo($con$$constant)) becomes
 7634 instruct compUL_reg_con_EQNE(flagsRegUL_EQNE xcc, iRegL op1, immLlowRot con) %{
 7635   match(Set xcc (CmpUL op1 con));
 7636   effect(DEF xcc, USE op1, USE con);
 7637 
 7638   size(8);
 7639   format %{ "TEQ    $op1.hi,0\t\t! unsigned long\n\t"
 7640             "TEQ.eq $op1.lo,$con" %}
 7641   ins_encode %{
 7642     __ teq($op1$$Register->successor(), 0);
 7643     __ teq($op1$$Register, $con$$constant, eq);
 7644   %}
 7645 
 7646   ins_pipe(ialu_cconly_reg_reg);
 7647 %}
 7648 
 7649 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7650 // (hi($con$$constant), lo($con$$constant)) becomes
 7651 instruct compUL_reg_con_LEGT(flagsRegUL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7652   match(Set xcc (CmpUL op1 con));
 7653   effect(DEF xcc, USE op1, USE con, TEMP tmp);
 7654 
 7655   size(8);
 7656   format %{ "RSBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
 7657             "RSCS    $tmp,$op1.hi,0" %}
 7658   ins_encode %{
 7659     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
 7660     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7661   %}
 7662 
 7663   ins_pipe(ialu_cconly_reg_reg);
 7664 %}
 7665 
 7666 /* instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ */
 7667 /*   match(Set xcc (CmpL (AndL op1 op2) zero)); */
 7668 /*   ins_encode %{ */
 7669 /*     __ stop("testL_reg_reg unimplemented"); */
 7670 /*   %} */
 7671 /*   ins_pipe(ialu_cconly_reg_reg); */
 7672 /* %} */
 7673 
 7674 /* // useful for checking the alignment of a pointer: */
 7675 /* instruct testL_reg_con(flagsRegL xcc, iRegL op1, immLlowRot con, immL0 zero) %{ */
 7676 /*   match(Set xcc (CmpL (AndL op1 con) zero)); */
 7677 /*   ins_encode %{ */
 7678 /*     __ stop("testL_reg_con unimplemented"); */
 7679 /*   %} */
 7680 /*   ins_pipe(ialu_cconly_reg_reg); */
 7681 /* %} */
 7682 
 7683 instruct compU_iReg_imm(flagsRegU icc, iRegI op1, aimmU31 op2 ) %{
 7684   match(Set icc (CmpU op1 op2));
 7685 
 7686   size(4);
 7687   format %{ "cmp_32 $op1,$op2\t! unsigned" %}
 7688   ins_encode %{
 7689     __ cmp_32($op1$$Register, $op2$$constant);
 7690   %}
 7691   ins_pipe(ialu_cconly_reg_imm);
 7692 %}
 7693 
 7694 // Compare Pointers
 7695 instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{
 7696   match(Set pcc (CmpP op1 op2));
 7697 
 7698   size(4);
 7699   format %{ "CMP    $op1,$op2\t! ptr" %}
 7700   ins_encode %{
 7701     __ cmp($op1$$Register, $op2$$Register);
 7702   %}
 7703   ins_pipe(ialu_cconly_reg_reg);
 7704 %}
 7705 
 7706 instruct compP_iRegP_imm(flagsRegP pcc, iRegP op1, aimmP op2 ) %{
 7707   match(Set pcc (CmpP op1 op2));
 7708 
 7709   size(4);
 7710   format %{ "CMP    $op1,$op2\t! ptr" %}
 7711   ins_encode %{
 7712     assert($op2$$constant == 0 || _opnds[2]->constant_reloc() == relocInfo::none, "reloc in cmp?");
 7713     __ cmp($op1$$Register, $op2$$constant);
 7714   %}
 7715   ins_pipe(ialu_cconly_reg_imm);
 7716 %}
 7717 
 7718 //----------Max and Min--------------------------------------------------------
 7719 // Min Instructions
 7720 // Conditional move for min
 7721 instruct cmovI_reg_lt( iRegI op2, iRegI op1, flagsReg icc ) %{
 7722   effect( USE_DEF op2, USE op1, USE icc );
 7723 
 7724   size(4);
 7725   format %{ "MOV.lt  $op2,$op1\t! min" %}
 7726   ins_encode %{
 7727     __ mov($op2$$Register, $op1$$Register, lt);
 7728   %}
 7729   ins_pipe(ialu_reg_flags);
 7730 %}
 7731 
 7732 // Min Register with Register.
 7733 instruct minI_eReg(iRegI op1, iRegI op2) %{
 7734   match(Set op2 (MinI op1 op2));
 7735   ins_cost(DEFAULT_COST*2);
 7736   expand %{
 7737     flagsReg icc;
 7738     compI_iReg(icc,op1,op2);
 7739     cmovI_reg_lt(op2,op1,icc);
 7740   %}
 7741 %}
 7742 
 7743 // Max Instructions
 7744 // Conditional move for max
 7745 instruct cmovI_reg_gt( iRegI op2, iRegI op1, flagsReg icc ) %{
 7746   effect( USE_DEF op2, USE op1, USE icc );
 7747   format %{ "MOV.gt  $op2,$op1\t! max" %}
 7748   ins_encode %{
 7749     __ mov($op2$$Register, $op1$$Register, gt);
 7750   %}
 7751   ins_pipe(ialu_reg_flags);
 7752 %}
 7753 
 7754 // Max Register with Register
 7755 instruct maxI_eReg(iRegI op1, iRegI op2) %{
 7756   match(Set op2 (MaxI op1 op2));
 7757   ins_cost(DEFAULT_COST*2);
 7758   expand %{
 7759     flagsReg icc;
 7760     compI_iReg(icc,op1,op2);
 7761     cmovI_reg_gt(op2,op1,icc);
 7762   %}
 7763 %}
 7764 
 7765 
 7766 //----------Float Compares----------------------------------------------------
 7767 // Compare floating, generate condition code
 7768 instruct cmpF_cc(flagsRegF fcc, flagsReg icc, regF src1, regF src2) %{
 7769   match(Set icc (CmpF src1 src2));
 7770   effect(KILL fcc);
 7771 
 7772   size(8);
 7773   format %{ "FCMPs  $src1,$src2\n\t"
 7774             "FMSTAT" %}
 7775   ins_encode %{
 7776     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
 7777     __ fmstat();
 7778   %}
 7779   ins_pipe(faddF_fcc_reg_reg_zero);
 7780 %}
 7781 
 7782 instruct cmpF0_cc(flagsRegF fcc, flagsReg icc, regF src1, immF0 src2) %{
 7783   match(Set icc (CmpF src1 src2));
 7784   effect(KILL fcc);
 7785 
 7786   size(8);
 7787   format %{ "FCMPs  $src1,$src2\n\t"
 7788             "FMSTAT" %}
 7789   ins_encode %{
 7790     __ fcmpzs($src1$$FloatRegister);
 7791     __ fmstat();
 7792   %}
 7793   ins_pipe(faddF_fcc_reg_reg_zero);
 7794 %}
 7795 
 7796 instruct cmpD_cc(flagsRegF fcc, flagsReg icc, regD src1, regD src2) %{
 7797   match(Set icc (CmpD src1 src2));
 7798   effect(KILL fcc);
 7799 
 7800   size(8);
 7801   format %{ "FCMPd  $src1,$src2 \n\t"
 7802             "FMSTAT" %}
 7803   ins_encode %{
 7804     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
 7805     __ fmstat();
 7806   %}
 7807   ins_pipe(faddD_fcc_reg_reg_zero);
 7808 %}
 7809 
 7810 instruct cmpD0_cc(flagsRegF fcc, flagsReg icc, regD src1, immD0 src2) %{
 7811   match(Set icc (CmpD src1 src2));
 7812   effect(KILL fcc);
 7813 
 7814   size(8);
 7815   format %{ "FCMPZd  $src1,$src2 \n\t"
 7816             "FMSTAT" %}
 7817   ins_encode %{
 7818     __ fcmpzd($src1$$FloatRegister);
 7819     __ fmstat();
 7820   %}
 7821   ins_pipe(faddD_fcc_reg_reg_zero);
 7822 %}
 7823 
 7824 // Compare floating, generate -1,0,1
 7825 instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsRegF fcc) %{
 7826   match(Set dst (CmpF3 src1 src2));
 7827   effect(KILL fcc);
 7828   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 7829   size(20);
 7830   // same number of instructions as code using conditional moves but
 7831   // doesn't kill integer condition register
 7832   format %{ "FCMPs  $dst,$src1,$src2 \n\t"
 7833             "VMRS   $dst, FPSCR \n\t"
 7834             "OR     $dst, $dst, 0x08000000 \n\t"
 7835             "EOR    $dst, $dst, $dst << 3 \n\t"
 7836             "MOV    $dst, $dst >> 30" %}
 7837   ins_encode %{
 7838     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
 7839     __ floating_cmp($dst$$Register);
 7840   %}
 7841   ins_pipe( floating_cmp );
 7842 %}
 7843 
 7844 instruct cmpF0_reg(iRegI dst, regF src1, immF0 src2, flagsRegF fcc) %{
 7845   match(Set dst (CmpF3 src1 src2));
 7846   effect(KILL fcc);
 7847   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 7848   size(20);
 7849   // same number of instructions as code using conditional moves but
 7850   // doesn't kill integer condition register
 7851   format %{ "FCMPZs $dst,$src1,$src2 \n\t"
 7852             "VMRS   $dst, FPSCR \n\t"
 7853             "OR     $dst, $dst, 0x08000000 \n\t"
 7854             "EOR    $dst, $dst, $dst << 3 \n\t"
 7855             "MOV    $dst, $dst >> 30" %}
 7856   ins_encode %{
 7857     __ fcmpzs($src1$$FloatRegister);
 7858     __ floating_cmp($dst$$Register);
 7859   %}
 7860   ins_pipe( floating_cmp );
 7861 %}
 7862 
 7863 instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsRegF fcc) %{
 7864   match(Set dst (CmpD3 src1 src2));
 7865   effect(KILL fcc);
 7866   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 7867   size(20);
 7868   // same number of instructions as code using conditional moves but
 7869   // doesn't kill integer condition register
 7870   format %{ "FCMPd  $dst,$src1,$src2 \n\t"
 7871             "VMRS   $dst, FPSCR \n\t"
 7872             "OR     $dst, $dst, 0x08000000 \n\t"
 7873             "EOR    $dst, $dst, $dst << 3 \n\t"
 7874             "MOV    $dst, $dst >> 30" %}
 7875   ins_encode %{
 7876     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
 7877     __ floating_cmp($dst$$Register);
 7878   %}
 7879   ins_pipe( floating_cmp );
 7880 %}
 7881 
 7882 instruct cmpD0_reg(iRegI dst, regD src1, immD0 src2, flagsRegF fcc) %{
 7883   match(Set dst (CmpD3 src1 src2));
 7884   effect(KILL fcc);
 7885   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 7886   size(20);
 7887   // same number of instructions as code using conditional moves but
 7888   // doesn't kill integer condition register
 7889   format %{ "FCMPZd $dst,$src1,$src2 \n\t"
 7890             "VMRS   $dst, FPSCR \n\t"
 7891             "OR     $dst, $dst, 0x08000000 \n\t"
 7892             "EOR    $dst, $dst, $dst << 3 \n\t"
 7893             "MOV    $dst, $dst >> 30" %}
 7894   ins_encode %{
 7895     __ fcmpzd($src1$$FloatRegister);
 7896     __ floating_cmp($dst$$Register);
 7897   %}
 7898   ins_pipe( floating_cmp );
 7899 %}
 7900 
 7901 //----------Branches---------------------------------------------------------
 7902 // Jump
 7903 // (compare 'operand indIndex' and 'instruct addP_reg_reg' above)
 7904 // FIXME
 7905 instruct jumpXtnd(iRegX switch_val, iRegP tmp) %{
 7906   match(Jump switch_val);
 7907   effect(TEMP tmp);
 7908   ins_cost(350);
 7909   format %{  "ADD    $tmp, $constanttablebase, $switch_val\n\t"
 7910              "LDR    $tmp,[$tmp + $constantoffset]\n\t"
 7911              "BX     $tmp" %}
 7912   size(20);
 7913   ins_encode %{
 7914     Register table_reg;
 7915     Register label_reg = $tmp$$Register;
 7916     if (constant_offset() == 0) {
 7917       table_reg = $constanttablebase;
 7918       __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
 7919     } else {
 7920       table_reg = $tmp$$Register;
 7921       int offset = $constantoffset;
 7922       if (is_memoryP(offset)) {
 7923         __ add(table_reg, $constanttablebase, $switch_val$$Register);
 7924         __ ldr(label_reg, Address(table_reg, offset));
 7925       } else {
 7926         __ mov_slow(table_reg, $constantoffset);
 7927         __ add(table_reg, $constanttablebase, table_reg);
 7928         __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
 7929       }
 7930     }
 7931     __ jump(label_reg); // ldr + b better than ldr to PC for branch predictor?
 7932     //    __ ldr(PC, Address($table$$Register, $switch_val$$Register));
 7933   %}
 7934   ins_pipe(ialu_reg_reg);
 7935 %}
 7936 
 7937 // // Direct Branch.
 7938 instruct branch(label labl) %{
 7939   match(Goto);
 7940   effect(USE labl);
 7941 
 7942   size(4);
 7943   ins_cost(BRANCH_COST);
 7944   format %{ "B     $labl" %}
 7945   ins_encode %{
 7946     __ b(*($labl$$label));
 7947   %}
 7948   ins_pipe(br);
 7949 %}
 7950 
 7951 // Conditional Direct Branch
 7952 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{
 7953   match(If cmp icc);
 7954   effect(USE labl);
 7955 
 7956   size(4);
 7957   ins_cost(BRANCH_COST);
 7958   format %{ "B$cmp   $icc,$labl" %}
 7959   ins_encode %{
 7960     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 7961   %}
 7962   ins_pipe(br_cc);
 7963 %}
 7964 
 7965 #ifdef ARM
 7966 instruct branchCon_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, label labl) %{
 7967   match(If cmp icc);
 7968   effect(USE labl);
 7969   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);
 7970 
 7971   size(4);
 7972   ins_cost(BRANCH_COST);
 7973   format %{ "B$cmp   $icc,$labl" %}
 7974   ins_encode %{
 7975     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 7976   %}
 7977   ins_pipe(br_cc);
 7978 %}
 7979 #endif
 7980 
 7981 
 7982 instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{
 7983   match(If cmp icc);
 7984   effect(USE labl);
 7985 
 7986   size(4);
 7987   ins_cost(BRANCH_COST);
 7988   format %{ "B$cmp  $icc,$labl" %}
 7989   ins_encode %{
 7990     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 7991   %}
 7992   ins_pipe(br_cc);
 7993 %}
 7994 
 7995 instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{
 7996   match(If cmp pcc);
 7997   effect(USE labl);
 7998 
 7999   size(4);
 8000   ins_cost(BRANCH_COST);
 8001   format %{ "B$cmp  $pcc,$labl" %}
 8002   ins_encode %{
 8003     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8004   %}
 8005   ins_pipe(br_cc);
 8006 %}
 8007 
 8008 instruct branchConL_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, label labl) %{
 8009   match(If cmp xcc);
 8010   effect(USE labl);
 8011   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8012 
 8013   size(4);
 8014   ins_cost(BRANCH_COST);
 8015   format %{ "B$cmp  $xcc,$labl" %}
 8016   ins_encode %{
 8017     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8018   %}
 8019   ins_pipe(br_cc);
 8020 %}
 8021 
 8022 instruct branchConL_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, label labl) %{
 8023   match(If cmp xcc);
 8024   effect(USE labl);
 8025   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8026 
 8027   size(4);
 8028   ins_cost(BRANCH_COST);
 8029   format %{ "B$cmp  $xcc,$labl" %}
 8030   ins_encode %{
 8031     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8032   %}
 8033   ins_pipe(br_cc);
 8034 %}
 8035 
 8036 instruct branchConL_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, label labl) %{
 8037   match(If cmp xcc);
 8038   effect(USE labl);
 8039   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le );
 8040 
 8041   size(4);
 8042   ins_cost(BRANCH_COST);
 8043   format %{ "B$cmp  $xcc,$labl" %}
 8044   ins_encode %{
 8045     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8046   %}
 8047   ins_pipe(br_cc);
 8048 %}
 8049 
 8050 instruct branchConUL_LTGE(cmpOpUL cmp, flagsRegUL_LTGE xcc, label labl) %{
 8051   match(If cmp xcc);
 8052   effect(USE labl);
 8053   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8054 
 8055   size(4);
 8056   ins_cost(BRANCH_COST);
 8057   format %{ "B$cmp  $xcc,$labl" %}
 8058   ins_encode %{
 8059     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8060   %}
 8061   ins_pipe(br_cc);
 8062 %}
 8063 
 8064 instruct branchConUL_EQNE(cmpOpUL cmp, flagsRegUL_EQNE xcc, label labl) %{
 8065   match(If cmp xcc);
 8066   effect(USE labl);
 8067   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8068 
 8069   size(4);
 8070   ins_cost(BRANCH_COST);
 8071   format %{ "B$cmp  $xcc,$labl" %}
 8072   ins_encode %{
 8073     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8074   %}
 8075   ins_pipe(br_cc);
 8076 %}
 8077 
 8078 instruct branchConUL_LEGT(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, label labl) %{
 8079   match(If cmp xcc);
 8080   effect(USE labl);
 8081   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le);
 8082 
 8083   size(4);
 8084   ins_cost(BRANCH_COST);
 8085   format %{ "B$cmp  $xcc,$labl" %}
 8086   ins_encode %{
 8087     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8088   %}
 8089   ins_pipe(br_cc);
 8090 %}
 8091 
 8092 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
 8093   match(CountedLoopEnd cmp icc);
 8094   effect(USE labl);
 8095 
 8096   size(4);
 8097   ins_cost(BRANCH_COST);
 8098   format %{ "B$cmp   $icc,$labl\t! Loop end" %}
 8099   ins_encode %{
 8100     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8101   %}
 8102   ins_pipe(br_cc);
 8103 %}
 8104 
 8105 // instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{
 8106 //   match(CountedLoopEnd cmp icc);
 8107 //   ins_pipe(br_cc);
 8108 // %}
 8109 
 8110 // ============================================================================
 8111 // Long Compare
 8112 //
 8113 // Currently we hold longs in 2 registers.  Comparing such values efficiently
 8114 // is tricky.  The flavor of compare used depends on whether we are testing
 8115 // for LT, LE, or EQ.  For a simple LT test we can check just the sign bit.
 8116 // The GE test is the negated LT test.  The LE test can be had by commuting
 8117 // the operands (yielding a GE test) and then negating; negate again for the
 8118 // GT test.  The EQ test is done by ORcc'ing the high and low halves, and the
 8119 // NE test is negated from that.
 8120 
 8121 // Due to a shortcoming in the ADLC, it mixes up expressions like:
 8122 // (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)).  Note the
 8123 // difference between 'Y' and '0L'.  The tree-matches for the CmpI sections
 8124 // are collapsed internally in the ADLC's dfa-gen code.  The match for
 8125 // (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the
 8126 // foo match ends up with the wrong leaf.  One fix is to not match both
 8127 // reg-reg and reg-zero forms of long-compare.  This is unfortunate because
 8128 // both forms beat the trinary form of long-compare and both are very useful
 8129 // on Intel which has so few registers.
 8130 
 8131 // instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{
 8132 //   match(If cmp xcc);
 8133 //   ins_pipe(br_cc);
 8134 // %}
 8135 
 8136 // Manifest a CmpL3 result in an integer register.  Very painful.
 8137 // This is the test to avoid.
 8138 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
 8139   match(Set dst (CmpL3 src1 src2) );
 8140   effect( KILL ccr );
 8141   ins_cost(6*DEFAULT_COST); // FIXME
 8142   size(32);
 8143   format %{
 8144       "CMP    $src1.hi, $src2.hi\t\t! long\n"
 8145     "\tMOV.gt $dst, 1\n"
 8146     "\tmvn.lt $dst, 0\n"
 8147     "\tB.ne   done\n"
 8148     "\tSUBS   $dst, $src1.lo, $src2.lo\n"
 8149     "\tMOV.hi $dst, 1\n"
 8150     "\tmvn.lo $dst, 0\n"
 8151     "done:"     %}
 8152   ins_encode %{
 8153     Label done;
 8154     __ cmp($src1$$Register->successor(), $src2$$Register->successor());
 8155     __ mov($dst$$Register, 1, gt);
 8156     __ mvn($dst$$Register, 0, lt);
 8157     __ b(done, ne);
 8158     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
 8159     __ mov($dst$$Register, 1, hi);
 8160     __ mvn($dst$$Register, 0, lo);
 8161     __ bind(done);
 8162   %}
 8163   ins_pipe(cmpL_reg);
 8164 %}
 8165 
 8166 // Conditional move
 8167 instruct cmovLL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, iRegL src) %{
 8168   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8169   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8170 
 8171   ins_cost(150);
 8172   size(8);
 8173   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8174             "MOV$cmp  $dst,$src.hi" %}
 8175   ins_encode %{
 8176     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8177     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8178   %}
 8179   ins_pipe(ialu_reg);
 8180 %}
 8181 
 8182 instruct cmovLL_reg_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegL dst, iRegL src) %{
 8183   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8184   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8185 
 8186   ins_cost(150);
 8187   size(8);
 8188   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8189             "MOV$cmp  $dst,$src.hi" %}
 8190   ins_encode %{
 8191     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8192     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8193   %}
 8194   ins_pipe(ialu_reg);
 8195 %}
 8196 
 8197 instruct cmovLL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, iRegL src) %{
 8198   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8199   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8200 
 8201   ins_cost(150);
 8202   size(8);
 8203   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8204             "MOV$cmp  $dst,$src.hi" %}
 8205   ins_encode %{
 8206     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8207     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8208   %}
 8209   ins_pipe(ialu_reg);
 8210 %}
 8211 
 8212 instruct cmovLL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, iRegL src) %{
 8213   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8214   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8215 
 8216   ins_cost(150);
 8217   size(8);
 8218   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8219             "MOV$cmp  $dst,$src.hi" %}
 8220   ins_encode %{
 8221     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8222     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8223   %}
 8224   ins_pipe(ialu_reg);
 8225 %}
 8226 
 8227 instruct cmovLL_reg_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegL dst, iRegL src) %{
 8228   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8229   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8230 
 8231   ins_cost(150);
 8232   size(8);
 8233   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8234             "MOV$cmp  $dst,$src.hi" %}
 8235   ins_encode %{
 8236     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8237     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8238   %}
 8239   ins_pipe(ialu_reg);
 8240 %}
 8241 
 8242 instruct cmovLL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, immL0 src) %{
 8243   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8244   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8245   ins_cost(140);
 8246   size(8);
 8247   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8248             "MOV$cmp  $dst,0" %}
 8249   ins_encode %{
 8250     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8251     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8252   %}
 8253   ins_pipe(ialu_imm);
 8254 %}
 8255 
 8256 instruct cmovLL_imm_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegL dst, immL0 src) %{
 8257   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8258   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8259   ins_cost(140);
 8260   size(8);
 8261   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8262             "MOV$cmp  $dst,0" %}
 8263   ins_encode %{
 8264     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8265     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8266   %}
 8267   ins_pipe(ialu_imm);
 8268 %}
 8269 
 8270 instruct cmovLL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, immL0 src) %{
 8271   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8272   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8273   ins_cost(140);
 8274   size(8);
 8275   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8276             "MOV$cmp  $dst,0" %}
 8277   ins_encode %{
 8278     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8279     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8280   %}
 8281   ins_pipe(ialu_imm);
 8282 %}
 8283 
 8284 instruct cmovLL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, immL0 src) %{
 8285   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8286   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8287   ins_cost(140);
 8288   size(8);
 8289   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8290             "MOV$cmp  $dst,0" %}
 8291   ins_encode %{
 8292     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8293     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8294   %}
 8295   ins_pipe(ialu_imm);
 8296 %}
 8297 
 8298 instruct cmovIL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, iRegI src) %{
 8299   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8300   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8301 
 8302   ins_cost(150);
 8303   size(4);
 8304   format %{ "MOV$cmp  $dst,$src" %}
 8305   ins_encode %{
 8306     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8307   %}
 8308   ins_pipe(ialu_reg);
 8309 %}
 8310 
 8311 instruct cmovIL_reg_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegI dst, iRegI src) %{
 8312   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8313   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8314 
 8315   ins_cost(150);
 8316   size(4);
 8317   format %{ "MOV$cmp  $dst,$src" %}
 8318   ins_encode %{
 8319     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8320   %}
 8321   ins_pipe(ialu_reg);
 8322 %}
 8323 
 8324 instruct cmovIL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, iRegI src) %{
 8325   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8326   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8327 
 8328   ins_cost(150);
 8329   size(4);
 8330   format %{ "MOV$cmp  $dst,$src" %}
 8331   ins_encode %{
 8332     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8333   %}
 8334   ins_pipe(ialu_reg);
 8335 %}
 8336 
 8337 instruct cmovIL_reg_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE xcc, iRegI dst, iRegI src) %{
 8338   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8339   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8340 
 8341   ins_cost(150);
 8342   size(4);
 8343   format %{ "MOV$cmp  $dst,$src" %}
 8344   ins_encode %{
 8345    __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8346   %}
 8347   ins_pipe(ialu_reg);
 8348 %}
 8349 
 8350 instruct cmovIL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, iRegI src) %{
 8351   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8352   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8353 
 8354   ins_cost(150);
 8355   size(4);
 8356   format %{ "MOV$cmp  $dst,$src" %}
 8357   ins_encode %{
 8358     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8359   %}
 8360   ins_pipe(ialu_reg);
 8361 %}
 8362 
 8363 instruct cmovIL_reg_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegI dst, iRegI src) %{
 8364   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8365   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8366 
 8367   ins_cost(150);
 8368   size(4);
 8369   format %{ "MOV$cmp  $dst,$src" %}
 8370   ins_encode %{
 8371     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8372   %}
 8373   ins_pipe(ialu_reg);
 8374 %}
 8375 
 8376 instruct cmovIL_imm16_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immI16 src) %{
 8377   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8378   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8379 
 8380   ins_cost(140);
 8381   size(4);
 8382   format %{ "MOVW$cmp  $dst,$src" %}
 8383   ins_encode %{
 8384     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8385   %}
 8386   ins_pipe(ialu_imm);
 8387 %}
 8388 
 8389 instruct cmovIL_imm16_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegI dst, immI16 src) %{
 8390   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8391   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8392 
 8393   ins_cost(140);
 8394   size(4);
 8395   format %{ "MOVW$cmp  $dst,$src" %}
 8396   ins_encode %{
 8397     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8398   %}
 8399   ins_pipe(ialu_imm);
 8400 %}
 8401 
 8402 instruct cmovIL_imm16_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, immI16 src) %{
 8403   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8404   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8405 
 8406   ins_cost(140);
 8407   size(4);
 8408   format %{ "MOVW$cmp  $dst,$src" %}
 8409   ins_encode %{
 8410     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8411   %}
 8412   ins_pipe(ialu_imm);
 8413 %}
 8414 
 8415 instruct cmovIL_imm16_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE xcc, iRegI dst, immI16 src) %{
 8416   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8417   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8418 
 8419   ins_cost(140);
 8420   size(4);
 8421   format %{ "MOVW$cmp  $dst,$src" %}
 8422   ins_encode %{
 8423     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8424   %}
 8425   ins_pipe(ialu_imm);
 8426 %}
 8427 
 8428 instruct cmovIL_imm16_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immI16 src) %{
 8429   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8430   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8431 
 8432   ins_cost(140);
 8433   size(4);
 8434   format %{ "MOVW$cmp  $dst,$src" %}
 8435   ins_encode %{
 8436     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8437   %}
 8438   ins_pipe(ialu_imm);
 8439 %}
 8440 
 8441 instruct cmovIL_imm16_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegI dst, immI16 src) %{
 8442   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8443   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8444 
 8445   ins_cost(140);
 8446   size(4);
 8447   format %{ "MOVW$cmp  $dst,$src" %}
 8448   ins_encode %{
 8449     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8450   %}
 8451   ins_pipe(ialu_imm);
 8452 %}
 8453 
 8454 instruct cmovIL_immMov_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immIMov src) %{
 8455   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8456   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8457 
 8458   ins_cost(140);
 8459   size(4);
 8460   format %{ "MOV$cmp  $dst,$src" %}
 8461   ins_encode %{
 8462     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8463   %}
 8464   ins_pipe(ialu_imm);
 8465 %}
 8466 
 8467 instruct cmovIL_immMov_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegI dst, immIMov src) %{
 8468   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8469   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8470 
 8471   ins_cost(140);
 8472   size(4);
 8473   format %{ "MOV$cmp  $dst,$src" %}
 8474   ins_encode %{
 8475     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8476   %}
 8477   ins_pipe(ialu_imm);
 8478 %}
 8479 
 8480 instruct cmovIL_immMov_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, immIMov src) %{
 8481   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8482   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8483 
 8484   ins_cost(140);
 8485   size(4);
 8486   format %{ "MOV$cmp  $dst,$src" %}
 8487   ins_encode %{
 8488     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8489   %}
 8490   ins_pipe(ialu_imm);
 8491 %}
 8492 
 8493 instruct cmovIL_immMov_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE xcc, iRegI dst, immIMov src) %{
 8494   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8495   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8496 
 8497   ins_cost(140);
 8498   size(4);
 8499   format %{ "MOV$cmp  $dst,$src" %}
 8500   ins_encode %{
 8501     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8502   %}
 8503   ins_pipe(ialu_imm);
 8504 %}
 8505 
 8506 instruct cmovIL_immMov_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immIMov src) %{
 8507   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8508   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8509 
 8510   ins_cost(140);
 8511   size(4);
 8512   format %{ "MOV$cmp  $dst,$src" %}
 8513   ins_encode %{
 8514     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8515   %}
 8516   ins_pipe(ialu_imm);
 8517 %}
 8518 
 8519 instruct cmovIL_immMov_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegI dst, immIMov src) %{
 8520   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8521   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8522 
 8523   ins_cost(140);
 8524   size(4);
 8525   format %{ "MOV$cmp  $dst,$src" %}
 8526   ins_encode %{
 8527     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8528   %}
 8529   ins_pipe(ialu_imm);
 8530 %}
 8531 
 8532 instruct cmovPL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, iRegP src) %{
 8533   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8534   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8535 
 8536   ins_cost(150);
 8537   size(4);
 8538   format %{ "MOV$cmp  $dst,$src" %}
 8539   ins_encode %{
 8540     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8541   %}
 8542   ins_pipe(ialu_reg);
 8543 %}
 8544 
 8545 instruct cmovPL_reg_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegP dst, iRegP src) %{
 8546   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8547   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8548 
 8549   ins_cost(150);
 8550   size(4);
 8551   format %{ "MOV$cmp  $dst,$src" %}
 8552   ins_encode %{
 8553     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8554   %}
 8555   ins_pipe(ialu_reg);
 8556 %}
 8557 
 8558 instruct cmovPL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, iRegP src) %{
 8559   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8560   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8561 
 8562   ins_cost(150);
 8563   size(4);
 8564   format %{ "MOV$cmp  $dst,$src" %}
 8565   ins_encode %{
 8566     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8567   %}
 8568   ins_pipe(ialu_reg);
 8569 %}
 8570 
 8571 instruct cmovPL_reg_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE xcc, iRegP dst, iRegP src) %{
 8572   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8573   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8574 
 8575   ins_cost(150);
 8576   size(4);
 8577   format %{ "MOV$cmp  $dst,$src" %}
 8578   ins_encode %{
 8579     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8580   %}
 8581   ins_pipe(ialu_reg);
 8582 %}
 8583 
 8584 instruct cmovPL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, iRegP src) %{
 8585   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8586   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8587 
 8588   ins_cost(150);
 8589   size(4);
 8590   format %{ "MOV$cmp  $dst,$src" %}
 8591   ins_encode %{
 8592     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8593   %}
 8594   ins_pipe(ialu_reg);
 8595 %}
 8596 
 8597 instruct cmovPL_reg_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegP dst, iRegP src) %{
 8598   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8599   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8600 
 8601   ins_cost(150);
 8602   size(4);
 8603   format %{ "MOV$cmp  $dst,$src" %}
 8604   ins_encode %{
 8605     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8606   %}
 8607   ins_pipe(ialu_reg);
 8608 %}
 8609 
 8610 instruct cmovPL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, immP0 src) %{
 8611   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8612   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8613 
 8614   ins_cost(140);
 8615   size(4);
 8616   format %{ "MOVW$cmp  $dst,$src" %}
 8617   ins_encode %{
 8618     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8619   %}
 8620   ins_pipe(ialu_imm);
 8621 %}
 8622 
 8623 instruct cmovPL_imm_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegP dst, immP0 src) %{
 8624   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8625   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8626 
 8627   ins_cost(140);
 8628   size(4);
 8629   format %{ "MOVW$cmp  $dst,$src" %}
 8630   ins_encode %{
 8631     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8632   %}
 8633   ins_pipe(ialu_imm);
 8634 %}
 8635 
 8636 instruct cmovPL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, immP0 src) %{
 8637   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8638   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8639 
 8640   ins_cost(140);
 8641   size(4);
 8642   format %{ "MOVW$cmp  $dst,$src" %}
 8643   ins_encode %{
 8644     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8645   %}
 8646   ins_pipe(ialu_imm);
 8647 %}
 8648 
 8649 instruct cmovPL_imm_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE xcc, iRegP dst, immP0 src) %{
 8650   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8651   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8652 
 8653   ins_cost(140);
 8654   size(4);
 8655   format %{ "MOVW$cmp  $dst,$src" %}
 8656   ins_encode %{
 8657     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8658   %}
 8659   ins_pipe(ialu_imm);
 8660 %}
 8661 
 8662 instruct cmovPL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, immP0 src) %{
 8663   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8664   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8665 
 8666   ins_cost(140);
 8667   size(4);
 8668   format %{ "MOVW$cmp  $dst,$src" %}
 8669   ins_encode %{
 8670     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8671   %}
 8672   ins_pipe(ialu_imm);
 8673 %}
 8674 
 8675 instruct cmovPL_imm_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegP dst, immP0 src) %{
 8676   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8677   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8678 
 8679   ins_cost(140);
 8680   size(4);
 8681   format %{ "MOVW$cmp  $dst,$src" %}
 8682   ins_encode %{
 8683     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8684   %}
 8685   ins_pipe(ialu_imm);
 8686 %}
 8687 
 8688 instruct cmovFL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regF dst, regF src) %{
 8689   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
 8690   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8691   ins_cost(150);
 8692   size(4);
 8693   format %{ "FCPYS$cmp $dst,$src" %}
 8694   ins_encode %{
 8695     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8696   %}
 8697   ins_pipe(int_conditional_float_move);
 8698 %}
 8699 
 8700 instruct cmovFL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regF dst, regF src) %{
 8701   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
 8702   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8703   ins_cost(150);
 8704   size(4);
 8705   format %{ "FCPYS$cmp $dst,$src" %}
 8706   ins_encode %{
 8707     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8708   %}
 8709   ins_pipe(int_conditional_float_move);
 8710 %}
 8711 
 8712 instruct cmovFL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regF dst, regF src) %{
 8713   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
 8714   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8715   ins_cost(150);
 8716   size(4);
 8717   format %{ "FCPYS$cmp $dst,$src" %}
 8718   ins_encode %{
 8719     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8720   %}
 8721   ins_pipe(int_conditional_float_move);
 8722 %}
 8723 
 8724 instruct cmovDL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regD dst, regD src) %{
 8725   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
 8726   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8727 
 8728   ins_cost(150);
 8729   size(4);
 8730   format %{ "FCPYD$cmp $dst,$src" %}
 8731   ins_encode %{
 8732     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8733   %}
 8734   ins_pipe(int_conditional_float_move);
 8735 %}
 8736 
 8737 instruct cmovDL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regD dst, regD src) %{
 8738   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
 8739   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8740 
 8741   ins_cost(150);
 8742   size(4);
 8743   format %{ "FCPYD$cmp $dst,$src" %}
 8744   ins_encode %{
 8745     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8746   %}
 8747   ins_pipe(int_conditional_float_move);
 8748 %}
 8749 
 8750 instruct cmovDL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regD dst, regD src) %{
 8751   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
 8752   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8753 
 8754   ins_cost(150);
 8755   size(4);
 8756   format %{ "FCPYD$cmp $dst,$src" %}
 8757   ins_encode %{
 8758     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8759   %}
 8760   ins_pipe(int_conditional_float_move);
 8761 %}
 8762 
 8763 // ============================================================================
 8764 // Safepoint Instruction
 8765 // rather than KILL R12, it would be better to use any reg as
 8766 // TEMP. Can't do that at this point because it crashes the compiler
 8767 instruct safePoint_poll(iRegP poll, R12RegI tmp, flagsReg icc) %{
 8768   match(SafePoint poll);
 8769   effect(USE poll, KILL tmp, KILL icc);
 8770 
 8771   size(4);
 8772   format %{ "LDR   $tmp,[$poll]\t! Safepoint: poll for GC" %}
 8773   ins_encode %{
 8774     __ relocate(relocInfo::poll_type);
 8775     __ ldr($tmp$$Register, Address($poll$$Register));
 8776   %}
 8777   ins_pipe(loadPollP);
 8778 %}
 8779 
 8780 
 8781 // ============================================================================
 8782 // Call Instructions
 8783 // Call Java Static Instruction
 8784 instruct CallStaticJavaDirect( method meth ) %{
 8785   match(CallStaticJava);
 8786   effect(USE meth);
 8787 
 8788   ins_cost(CALL_COST);
 8789   format %{ "CALL,static ==> " %}
 8790   ins_encode( SetInstMark, Java_Static_Call( meth ), call_epilog, ClearInstMark );
 8791   ins_pipe(simple_call);
 8792 %}
 8793 
 8794 // Call Java Dynamic Instruction
 8795 instruct CallDynamicJavaDirect( method meth ) %{
 8796   match(CallDynamicJava);
 8797   effect(USE meth);
 8798 
 8799   ins_cost(CALL_COST);
 8800   format %{ "MOV_OOP    (empty),R_R8\n\t"
 8801             "CALL,dynamic  ; NOP ==> " %}
 8802   ins_encode( SetInstMark, Java_Dynamic_Call( meth ), call_epilog, ClearInstMark );
 8803   ins_pipe(call);
 8804 %}
 8805 
 8806 // Call Runtime Instruction
 8807 instruct CallRuntimeDirect(method meth) %{
 8808   match(CallRuntime);
 8809   effect(USE meth);
 8810   ins_cost(CALL_COST);
 8811   format %{ "CALL,runtime" %}
 8812   ins_encode( SetInstMark, Java_To_Runtime( meth ),
 8813               call_epilog, ClearInstMark );
 8814   ins_pipe(simple_call);
 8815 %}
 8816 
 8817 // Call runtime without safepoint - same as CallRuntime
 8818 instruct CallLeafDirect(method meth) %{
 8819   match(CallLeaf);
 8820   effect(USE meth);
 8821   ins_cost(CALL_COST);
 8822   format %{ "CALL,runtime leaf" %}
 8823   // TODO: need save_last_PC here?
 8824   ins_encode( SetInstMark, Java_To_Runtime( meth ),
 8825               call_epilog, ClearInstMark );
 8826   ins_pipe(simple_call);
 8827 %}
 8828 
 8829 // Call runtime without safepoint - same as CallLeaf
 8830 instruct CallLeafNoFPDirect(method meth) %{
 8831   match(CallLeafNoFP);
 8832   effect(USE meth);
 8833   ins_cost(CALL_COST);
 8834   format %{ "CALL,runtime leaf nofp" %}
 8835   // TODO: need save_last_PC here?
 8836   ins_encode( SetInstMark, Java_To_Runtime( meth ),
 8837               call_epilog, ClearInstMark );
 8838   ins_pipe(simple_call);
 8839 %}
 8840 
 8841 // Tail Call; Jump from runtime stub to Java code.
 8842 // Also known as an 'interprocedural jump'.
 8843 // Target of jump will eventually return to caller.
 8844 // TailJump below removes the return address.
 8845 instruct TailCalljmpInd(IPRegP jump_target, inline_cache_regP method_ptr) %{
 8846   match(TailCall jump_target method_ptr);
 8847 
 8848   ins_cost(CALL_COST);
 8849   format %{ "jump   $jump_target  \t! $method_ptr holds method" %}
 8850   ins_encode %{
 8851     __ jump($jump_target$$Register);
 8852   %}
 8853   ins_pipe(tail_call);
 8854 %}
 8855 
 8856 
 8857 // Return Instruction
 8858 instruct Ret() %{
 8859   match(Return);
 8860 
 8861   format %{ "ret LR" %}
 8862 
 8863   ins_encode %{
 8864     __ ret(LR);
 8865   %}
 8866 
 8867   ins_pipe(br);
 8868 %}
 8869 
 8870 
 8871 // Tail Jump; remove the return address; jump to target.
 8872 // TailCall above leaves the return address around.
 8873 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
 8874 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
 8875 // "restore" before this instruction (in Epilogue), we need to materialize it
 8876 // in %i0.
 8877 instruct tailjmpInd(IPRegP jump_target, RExceptionRegP ex_oop) %{
 8878   match( TailJump jump_target ex_oop );
 8879   ins_cost(CALL_COST);
 8880   format %{ "MOV    Rexception_pc, LR\n\t"
 8881             "jump   $jump_target \t! $ex_oop holds exc. oop" %}
 8882   ins_encode %{
 8883     __ mov(Rexception_pc, LR);
 8884     __ jump($jump_target$$Register);
 8885   %}
 8886   ins_pipe(tail_call);
 8887 %}
 8888 
 8889 // Forward exception.
 8890 instruct ForwardExceptionjmp()
 8891 %{
 8892   match(ForwardException);
 8893   ins_cost(CALL_COST);
 8894 
 8895   format %{ "MOV  Rexception_pc, LR\n\t"
 8896             "b    forward_exception_entry" %}
 8897   ins_encode %{
 8898     __ mov(Rexception_pc, LR);
 8899     // OK to trash Rtemp, because Rtemp is used by stub
 8900     __ jump(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type, Rtemp);
 8901   %}
 8902   ins_pipe(tail_call);
 8903 %}
 8904 
 8905 // Create exception oop: created by stack-crawling runtime code.
 8906 // Created exception is now available to this handler, and is setup
 8907 // just prior to jumping to this handler.  No code emitted.
 8908 instruct CreateException( RExceptionRegP ex_oop )
 8909 %{
 8910   match(Set ex_oop (CreateEx));
 8911   ins_cost(0);
 8912 
 8913   size(0);
 8914   // use the following format syntax
 8915   format %{ "! exception oop is in Rexception_obj; no code emitted" %}
 8916   ins_encode();
 8917   ins_pipe(empty);
 8918 %}
 8919 
 8920 
 8921 // Rethrow exception:
 8922 // The exception oop will come in the first argument position.
 8923 // Then JUMP (not call) to the rethrow stub code.
 8924 instruct RethrowException()
 8925 %{
 8926   match(Rethrow);
 8927   ins_cost(CALL_COST);
 8928 
 8929   // use the following format syntax
 8930   format %{ "b    rethrow_stub" %}
 8931   ins_encode %{
 8932     Register scratch = R1_tmp;
 8933     assert_different_registers(scratch, c_rarg0, LR);
 8934     __ jump(OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type, scratch);
 8935   %}
 8936   ins_pipe(tail_call);
 8937 %}
 8938 
 8939 
 8940 // Die now
 8941 instruct ShouldNotReachHere( )
 8942 %{
 8943   match(Halt);
 8944   ins_cost(CALL_COST);
 8945 
 8946   // Use the following format syntax
 8947   format %{ "ShouldNotReachHere" %}
 8948   ins_encode %{
 8949     if (is_reachable()) {
 8950       const char* str = __ code_string(_halt_reason);
 8951       __ stop(str);
 8952     }
 8953   %}
 8954   ins_pipe(tail_call);
 8955 %}
 8956 
 8957 // ============================================================================
 8958 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
 8959 // array for an instance of the superklass.  Set a hidden internal cache on a
 8960 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
 8961 // not zero for a miss or zero for a hit.  The encoding ALSO sets flags.
 8962 instruct partialSubtypeCheck( R0RegP index, R1RegP sub, R2RegP super, flagsRegP pcc, LRRegP lr ) %{
 8963   match(Set index (PartialSubtypeCheck sub super));
 8964   effect( KILL pcc, KILL lr );
 8965   ins_cost(DEFAULT_COST*10);
 8966   format %{ "CALL   PartialSubtypeCheck" %}
 8967   ins_encode %{
 8968     __ call(StubRoutines::Arm::partial_subtype_check(), relocInfo::runtime_call_type);
 8969   %}
 8970   ins_pipe(partial_subtype_check_pipe);
 8971 %}
 8972 
 8973 /* instruct partialSubtypeCheck_vs_zero( flagsRegP pcc, o1RegP sub, o2RegP super, immP0 zero, o0RegP idx, o7RegP o7 ) %{ */
 8974 /*   match(Set pcc (CmpP (PartialSubtypeCheck sub super) zero)); */
 8975 /*   ins_pipe(partial_subtype_check_pipe); */
 8976 /* %} */
 8977 
 8978 
 8979 // ============================================================================
 8980 // inlined locking and unlocking
 8981 
 8982 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch )
 8983 %{
 8984   match(Set pcc (FastLock object box));
 8985 
 8986   effect(TEMP scratch, TEMP scratch2);
 8987   ins_cost(DEFAULT_COST*3);
 8988 
 8989   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2" %}
 8990   ins_encode %{
 8991     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
 8992   %}
 8993   ins_pipe(long_memory_op);
 8994 %}
 8995 
 8996 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch ) %{
 8997   match(Set pcc (FastUnlock object box));
 8998   effect(TEMP scratch, TEMP scratch2);
 8999   ins_cost(100);
 9000 
 9001   format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2" %}
 9002   ins_encode %{
 9003     __ fast_unlock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
 9004   %}
 9005   ins_pipe(long_memory_op);
 9006 %}
 9007 
 9008 // Count and Base registers are fixed because the allocator cannot
 9009 // kill unknown registers.  The encodings are generic.
 9010 instruct clear_array(iRegX cnt, iRegP base, iRegI temp, iRegX zero, Universe dummy, flagsReg cpsr) %{
 9011   match(Set dummy (ClearArray cnt base));
 9012   effect(TEMP temp, TEMP zero, KILL cpsr);
 9013   ins_cost(300);
 9014   format %{ "MOV    $zero,0\n"
 9015       "        MOV    $temp,$cnt\n"
 9016       "loop:   SUBS   $temp,$temp,4\t! Count down a dword of bytes\n"
 9017       "        STR.ge $zero,[$base+$temp]\n"
 9018       "        B.gt   loop\t\t! Clearing loop\n" %}
 9019   ins_encode %{
 9020     __ mov($zero$$Register, 0);
 9021     __ mov($temp$$Register, $cnt$$Register);
 9022     Label loop;
 9023     __ bind(loop);
 9024     __ subs($temp$$Register, $temp$$Register, 4);
 9025     __ str($zero$$Register, Address($base$$Register, $temp$$Register), ge);
 9026     __ b(loop, gt);
 9027   %}
 9028   ins_pipe(long_memory_op);
 9029 %}
 9030 
 9031 #ifdef XXX
 9032 // FIXME: Why R0/R1/R2/R3?
 9033 instruct string_compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result,
 9034                         iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 9035   predicate(!CompactStrings);
 9036   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
 9037   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, TEMP tmp1, TEMP tmp2);
 9038   ins_cost(300);
 9039   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // TEMP $tmp1, $tmp2" %}
 9040   ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result, tmp1, tmp2) );
 9041 
 9042   ins_pipe(long_memory_op);
 9043 %}
 9044 
 9045 // FIXME: Why R0/R1/R2?
 9046 instruct string_equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2,
 9047                        flagsReg ccr) %{
 9048   predicate(!CompactStrings);
 9049   match(Set result (StrEquals (Binary str1 str2) cnt));
 9050   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp1, TEMP tmp2, TEMP result, KILL ccr);
 9051 
 9052   ins_cost(300);
 9053   format %{ "String Equals $str1,$str2,$cnt -> $result   // TEMP $tmp1, $tmp2" %}
 9054   ins_encode( enc_String_Equals(str1, str2, cnt, result, tmp1, tmp2) );
 9055   ins_pipe(long_memory_op);
 9056 %}
 9057 
 9058 // FIXME: Why R0/R1?
 9059 instruct array_equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result,
 9060                       flagsReg ccr) %{
 9061   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
 9062   match(Set result (AryEq ary1 ary2));
 9063   effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP result, KILL ccr);
 9064 
 9065   ins_cost(300);
 9066   format %{ "Array Equals $ary1,$ary2 -> $result   // TEMP $tmp1,$tmp2,$tmp3" %}
 9067   ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, result));
 9068   ins_pipe(long_memory_op);
 9069 %}
 9070 #endif
 9071 
 9072 //---------- Zeros Count Instructions ------------------------------------------
 9073 
 9074 instruct countLeadingZerosI(iRegI dst, iRegI src) %{
 9075   match(Set dst (CountLeadingZerosI src));
 9076   size(4);
 9077   format %{ "CLZ_32 $dst,$src" %}
 9078   ins_encode %{
 9079     __ clz_32($dst$$Register, $src$$Register);
 9080   %}
 9081   ins_pipe(ialu_reg);
 9082 %}
 9083 
 9084 instruct countLeadingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
 9085   match(Set dst (CountLeadingZerosL src));
 9086   effect(TEMP tmp, TEMP dst, KILL ccr);
 9087   size(16);
 9088   format %{ "CLZ    $dst,$src.hi\n\t"
 9089             "TEQ    $dst,32\n\t"
 9090             "CLZ.eq $tmp,$src.lo\n\t"
 9091             "ADD.eq $dst, $dst, $tmp\n\t" %}
 9092   ins_encode %{
 9093     __ clz($dst$$Register, $src$$Register->successor());
 9094     __ teq($dst$$Register, 32);
 9095     __ clz($tmp$$Register, $src$$Register, eq);
 9096     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
 9097   %}
 9098   ins_pipe(ialu_reg);
 9099 %}
 9100 
 9101 instruct countTrailingZerosI(iRegI dst, iRegI src, iRegI tmp) %{
 9102   match(Set dst (CountTrailingZerosI src));
 9103   effect(TEMP tmp);
 9104   size(8);
 9105   format %{ "RBIT_32 $tmp, $src\n\t"
 9106             "CLZ_32  $dst,$tmp" %}
 9107   ins_encode %{
 9108     __ rbit_32($tmp$$Register, $src$$Register);
 9109     __ clz_32($dst$$Register, $tmp$$Register);
 9110   %}
 9111   ins_pipe(ialu_reg);
 9112 %}
 9113 
 9114 instruct countTrailingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
 9115   match(Set dst (CountTrailingZerosL src));
 9116   effect(TEMP tmp, TEMP dst, KILL ccr);
 9117   size(24);
 9118   format %{ "RBIT   $tmp,$src.lo\n\t"
 9119             "CLZ    $dst,$tmp\n\t"
 9120             "TEQ    $dst,32\n\t"
 9121             "RBIT   $tmp,$src.hi\n\t"
 9122             "CLZ.eq $tmp,$tmp\n\t"
 9123             "ADD.eq $dst,$dst,$tmp\n\t" %}
 9124   ins_encode %{
 9125     __ rbit($tmp$$Register, $src$$Register);
 9126     __ clz($dst$$Register, $tmp$$Register);
 9127     __ teq($dst$$Register, 32);
 9128     __ rbit($tmp$$Register, $src$$Register->successor());
 9129     __ clz($tmp$$Register, $tmp$$Register, eq);
 9130     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
 9131   %}
 9132   ins_pipe(ialu_reg);
 9133 %}
 9134 
 9135 
 9136 //---------- Population Count Instructions -------------------------------------
 9137 
 9138 instruct popCountI(iRegI dst, iRegI src, regD_low tmp) %{
 9139   predicate(UsePopCountInstruction);
 9140   match(Set dst (PopCountI src));
 9141   effect(TEMP tmp);
 9142 
 9143   format %{ "FMSR       $tmp,$src\n\t"
 9144             "VCNT.8     $tmp,$tmp\n\t"
 9145             "VPADDL.U8  $tmp,$tmp\n\t"
 9146             "VPADDL.U16 $tmp,$tmp\n\t"
 9147             "FMRS       $dst,$tmp" %}
 9148   size(20);
 9149 
 9150   ins_encode %{
 9151     __ fmsr($tmp$$FloatRegister, $src$$Register);
 9152     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
 9153     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
 9154     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
 9155     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 9156   %}
 9157   ins_pipe(ialu_reg); // FIXME
 9158 %}
 9159 
 9160 // Note: Long.bitCount(long) returns an int.
 9161 instruct popCountL(iRegI dst, iRegL src, regD_low tmp) %{
 9162   predicate(UsePopCountInstruction);
 9163   match(Set dst (PopCountL src));
 9164   effect(TEMP tmp);
 9165 
 9166   format %{ "FMDRR       $tmp,$src.lo,$src.hi\n\t"
 9167             "VCNT.8      $tmp,$tmp\n\t"
 9168             "VPADDL.U8   $tmp,$tmp\n\t"
 9169             "VPADDL.U16  $tmp,$tmp\n\t"
 9170             "VPADDL.U32  $tmp,$tmp\n\t"
 9171             "FMRS        $dst,$tmp" %}
 9172 
 9173   size(32);
 9174 
 9175   ins_encode %{
 9176     __ fmdrr($tmp$$FloatRegister, $src$$Register, $src$$Register->successor());
 9177     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
 9178     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
 9179     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
 9180     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 32, 0);
 9181     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 9182   %}
 9183   ins_pipe(ialu_reg);
 9184 %}
 9185 
 9186 
 9187 // ============================================================================
 9188 //------------Bytes reverse--------------------------------------------------
 9189 
 9190 instruct bytes_reverse_int(iRegI dst, iRegI src) %{
 9191   match(Set dst (ReverseBytesI src));
 9192 
 9193   size(4);
 9194   format %{ "REV32 $dst,$src" %}
 9195   ins_encode %{
 9196     __ rev($dst$$Register, $src$$Register);
 9197   %}
 9198   ins_pipe( iload_mem ); // FIXME
 9199 %}
 9200 
 9201 instruct bytes_reverse_long(iRegL dst, iRegL src) %{
 9202   match(Set dst (ReverseBytesL src));
 9203   effect(TEMP dst);
 9204   size(8);
 9205   format %{ "REV $dst.lo,$src.lo\n\t"
 9206             "REV $dst.hi,$src.hi" %}
 9207   ins_encode %{
 9208     __ rev($dst$$Register, $src$$Register->successor());
 9209     __ rev($dst$$Register->successor(), $src$$Register);
 9210   %}
 9211   ins_pipe( iload_mem ); // FIXME
 9212 %}
 9213 
 9214 instruct bytes_reverse_unsigned_short(iRegI dst, iRegI src) %{
 9215   match(Set dst (ReverseBytesUS src));
 9216   size(8);
 9217   format %{ "REV32 $dst,$src\n\t"
 9218             "LSR   $dst,$dst,#16" %}
 9219   ins_encode %{
 9220     __ rev($dst$$Register, $src$$Register);
 9221     __ mov($dst$$Register, AsmOperand($dst$$Register, lsr, 16));
 9222   %}
 9223   ins_pipe( iload_mem ); // FIXME
 9224 %}
 9225 
 9226 instruct bytes_reverse_short(iRegI dst, iRegI src) %{
 9227   match(Set dst (ReverseBytesS src));
 9228   size(4);
 9229   format %{ "REVSH $dst,$src" %}
 9230   ins_encode %{
 9231     __ revsh($dst$$Register, $src$$Register);
 9232   %}
 9233   ins_pipe( iload_mem ); // FIXME
 9234 %}
 9235 
 9236 
 9237 // ====================VECTOR INSTRUCTIONS=====================================
 9238 
 9239 // Load Aligned Packed values into a Double Register
 9240 instruct loadV8(vecD dst, memoryD mem) %{
 9241   predicate(n->as_LoadVector()->memory_size() == 8);
 9242   match(Set dst (LoadVector mem));
 9243   ins_cost(MEMORY_REF_COST);
 9244   size(4);
 9245   format %{ "FLDD   $mem,$dst\t! load vector (8 bytes)" %}
 9246   ins_encode %{
 9247     __ ldr_double($dst$$FloatRegister, $mem$$Address);
 9248   %}
 9249   ins_pipe(floadD_mem);
 9250 %}
 9251 
 9252 // Load Aligned Packed values into a Double Register Pair
 9253 instruct loadV16(vecX dst, memoryvld mem) %{
 9254   predicate(n->as_LoadVector()->memory_size() == 16);
 9255   match(Set dst (LoadVector mem));
 9256   ins_cost(MEMORY_REF_COST);
 9257   size(4);
 9258   format %{ "VLD1   $mem,$dst.Q\t! load vector (16 bytes)" %}
 9259   ins_encode %{
 9260     __ vld1($dst$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
 9261   %}
 9262   ins_pipe(floadD_mem); // FIXME
 9263 %}
 9264 
 9265 // Store Vector in Double register to memory
 9266 instruct storeV8(memoryD mem, vecD src) %{
 9267   predicate(n->as_StoreVector()->memory_size() == 8);
 9268   match(Set mem (StoreVector mem src));
 9269   ins_cost(MEMORY_REF_COST);
 9270   size(4);
 9271   format %{ "FSTD   $src,$mem\t! store vector (8 bytes)" %}
 9272   ins_encode %{
 9273     __ str_double($src$$FloatRegister, $mem$$Address);
 9274   %}
 9275   ins_pipe(fstoreD_mem_reg);
 9276 %}
 9277 
 9278 // Store Vector in Double Register Pair to memory
 9279 instruct storeV16(memoryvld mem, vecX src) %{
 9280   predicate(n->as_StoreVector()->memory_size() == 16);
 9281   match(Set mem (StoreVector mem src));
 9282   ins_cost(MEMORY_REF_COST);
 9283   size(4);
 9284   format %{ "VST1   $src,$mem\t! store vector (16 bytes)" %}
 9285   ins_encode %{
 9286     __ vst1($src$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
 9287   %}
 9288   ins_pipe(fstoreD_mem_reg); // FIXME
 9289 %}
 9290 
 9291 // Replicate scalar to packed byte values in Double register
 9292 instruct Repl8B_reg(vecD dst, iRegI src, iRegI tmp) %{
 9293   predicate(n->as_Vector()->length() == 8 &&
 9294             Matcher::vector_element_basic_type(n) == T_BYTE);
 9295   match(Set dst (Replicate src));
 9296   ins_cost(DEFAULT_COST*4);
 9297   effect(TEMP tmp);
 9298   size(16);
 9299 
 9300   // FIXME: could use PKH instruction instead?
 9301   format %{ "LSL      $tmp, $src, 24 \n\t"
 9302             "OR       $tmp, $tmp, ($tmp >> 8) \n\t"
 9303             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
 9304             "FMDRR    $dst,$tmp,$tmp\t" %}
 9305   ins_encode %{
 9306     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 24));
 9307     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 8));
 9308     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
 9309     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 9310   %}
 9311   ins_pipe(ialu_reg); // FIXME
 9312 %}
 9313 
 9314 // Replicate scalar to packed byte values in Double register
 9315 instruct Repl8B_reg_simd(vecD dst, iRegI src) %{
 9316   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9317             Matcher::vector_element_basic_type(n) == T_BYTE);
 9318   match(Set dst (Replicate src));
 9319   size(4);
 9320 
 9321   format %{ "VDUP.8 $dst,$src\t" %}
 9322   ins_encode %{
 9323     bool quad = false;
 9324     __ vdupI($dst$$FloatRegister, $src$$Register,
 9325              MacroAssembler::VELEM_SIZE_8, quad);
 9326   %}
 9327   ins_pipe(ialu_reg); // FIXME
 9328 %}
 9329 
 9330 // Replicate scalar to packed byte values in Double register pair
 9331 instruct Repl16B_reg(vecX dst, iRegI src) %{
 9332   predicate(n->as_Vector()->length_in_bytes() == 16 &&
 9333             Matcher::vector_element_basic_type(n) == T_BYTE);
 9334   match(Set dst (Replicate src));
 9335   size(4);
 9336 
 9337   format %{ "VDUP.8 $dst.Q,$src\t" %}
 9338   ins_encode %{
 9339     bool quad = true;
 9340     __ vdupI($dst$$FloatRegister, $src$$Register,
 9341              MacroAssembler::VELEM_SIZE_8, quad);
 9342   %}
 9343   ins_pipe(ialu_reg); // FIXME
 9344 %}
 9345 
 9346 // Replicate scalar constant to packed byte values in Double register
 9347 instruct Repl8B_immI(vecD dst, immI src, iRegI tmp) %{
 9348   predicate(n->as_Vector()->length() == 8 &&
 9349             Matcher::vector_element_basic_type(n) == T_BYTE);
 9350   match(Set dst (Replicate src));
 9351   ins_cost(DEFAULT_COST*2);
 9352   effect(TEMP tmp);
 9353   size(12);
 9354 
 9355   format %{ "MOV      $tmp, Repl4($src))\n\t"
 9356             "FMDRR    $dst,$tmp,$tmp\t" %}
 9357   ins_encode( LdReplImmI(src, dst, tmp, (4), (1)) );
 9358   ins_pipe(loadConFD); // FIXME
 9359 %}
 9360 
 9361 // Replicate scalar constant to packed byte values in Double register
 9362 // TODO: support negative constants with MVNI?
 9363 instruct Repl8B_immU8(vecD dst, immU8 src) %{
 9364   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9365             Matcher::vector_element_basic_type(n) == T_BYTE);
 9366   match(Set dst (Replicate src));
 9367   size(4);
 9368 
 9369   format %{ "VMOV.U8  $dst,$src" %}
 9370   ins_encode %{
 9371     bool quad = false;
 9372     __ vmovI($dst$$FloatRegister, $src$$constant,
 9373              MacroAssembler::VELEM_SIZE_8, quad);
 9374   %}
 9375   ins_pipe(loadConFD); // FIXME
 9376 %}
 9377 
 9378 // Replicate scalar constant to packed byte values in Double register pair
 9379 instruct Repl16B_immU8(vecX dst, immU8 src) %{
 9380   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd() &&
 9381             Matcher::vector_element_basic_type(n) == T_BYTE);
 9382   match(Set dst (Replicate src));
 9383   size(4);
 9384 
 9385   format %{ "VMOV.U8  $dst.Q,$src" %}
 9386   ins_encode %{
 9387     bool quad = true;
 9388     __ vmovI($dst$$FloatRegister, $src$$constant,
 9389              MacroAssembler::VELEM_SIZE_8, quad);
 9390   %}
 9391   ins_pipe(loadConFD); // FIXME
 9392 %}
 9393 
 9394 // Replicate scalar to packed short/char values into Double register
 9395 instruct Repl4S_reg(vecD dst, iRegI src, iRegI tmp) %{
 9396   predicate(n->as_Vector()->length() == 4 &&
 9397             Matcher::vector_element_basic_type(n) == T_SHORT);
 9398   match(Set dst (Replicate src));
 9399   ins_cost(DEFAULT_COST*3);
 9400   effect(TEMP tmp);
 9401   size(12);
 9402 
 9403   // FIXME: could use PKH instruction instead?
 9404   format %{ "LSL      $tmp, $src, 16 \n\t"
 9405             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
 9406             "FMDRR    $dst,$tmp,$tmp\t" %}
 9407   ins_encode %{
 9408     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 16));
 9409     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
 9410     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 9411   %}
 9412   ins_pipe(ialu_reg); // FIXME
 9413 %}
 9414 
 9415 // Replicate scalar to packed byte values in Double register
 9416 instruct Repl4S_reg_simd(vecD dst, iRegI src) %{
 9417   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9418             Matcher::vector_element_basic_type(n) == T_SHORT);
 9419   match(Set dst (Replicate src));
 9420   size(4);
 9421 
 9422   format %{ "VDUP.16 $dst,$src\t" %}
 9423   ins_encode %{
 9424     bool quad = false;
 9425     __ vdupI($dst$$FloatRegister, $src$$Register,
 9426              MacroAssembler::VELEM_SIZE_16, quad);
 9427   %}
 9428   ins_pipe(ialu_reg); // FIXME
 9429 %}
 9430 
 9431 // Replicate scalar to packed byte values in Double register pair
 9432 instruct Repl8S_reg(vecX dst, iRegI src) %{
 9433   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd() &&
 9434             Matcher::vector_element_basic_type(n) == T_SHORT);
 9435   match(Set dst (Replicate src));
 9436   size(4);
 9437 
 9438   format %{ "VDUP.16 $dst.Q,$src\t" %}
 9439   ins_encode %{
 9440     bool quad = true;
 9441     __ vdupI($dst$$FloatRegister, $src$$Register,
 9442              MacroAssembler::VELEM_SIZE_16, quad);
 9443   %}
 9444   ins_pipe(ialu_reg); // FIXME
 9445 %}
 9446 
 9447 
 9448 // Replicate scalar constant to packed short/char values in Double register
 9449 instruct Repl4S_immI(vecD dst, immI src, iRegP tmp) %{
 9450   predicate(n->as_Vector()->length() == 4 &&
 9451             Matcher::vector_element_basic_type(n) == T_SHORT);
 9452   match(Set dst (Replicate src));
 9453   effect(TEMP tmp);
 9454   size(12);
 9455   ins_cost(DEFAULT_COST*4); // FIXME
 9456 
 9457   format %{ "MOV      $tmp, Repl2($src))\n\t"
 9458             "FMDRR    $dst,$tmp,$tmp\t" %}
 9459   ins_encode( LdReplImmI(src, dst, tmp, (2), (2)) );
 9460   ins_pipe(loadConFD); // FIXME
 9461 %}
 9462 
 9463 // Replicate scalar constant to packed byte values in Double register
 9464 instruct Repl4S_immU8(vecD dst, immU8 src) %{
 9465   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9466             Matcher::vector_element_basic_type(n) == T_SHORT);
 9467   match(Set dst (Replicate src));
 9468   size(4);
 9469 
 9470   format %{ "VMOV.U16  $dst,$src" %}
 9471   ins_encode %{
 9472     bool quad = false;
 9473     __ vmovI($dst$$FloatRegister, $src$$constant,
 9474              MacroAssembler::VELEM_SIZE_16, quad);
 9475   %}
 9476   ins_pipe(loadConFD); // FIXME
 9477 %}
 9478 
 9479 // Replicate scalar constant to packed byte values in Double register pair
 9480 instruct Repl8S_immU8(vecX dst, immU8 src) %{
 9481   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd() &&
 9482             Matcher::vector_element_basic_type(n) == T_SHORT);
 9483   match(Set dst (Replicate src));
 9484   size(4);
 9485 
 9486   format %{ "VMOV.U16  $dst.Q,$src" %}
 9487   ins_encode %{
 9488     bool quad = true;
 9489     __ vmovI($dst$$FloatRegister, $src$$constant,
 9490              MacroAssembler::VELEM_SIZE_16, quad);
 9491   %}
 9492   ins_pipe(loadConFD); // FIXME
 9493 %}
 9494 
 9495 // Replicate scalar to packed int values in Double register
 9496 instruct Repl2I_reg(vecD dst, iRegI src) %{
 9497   predicate(n->as_Vector()->length() == 2 &&
 9498             Matcher::vector_element_basic_type(n) == T_INT);
 9499   match(Set dst (Replicate src));
 9500   size(4);
 9501 
 9502   format %{ "FMDRR    $dst,$src,$src\t" %}
 9503   ins_encode %{
 9504     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
 9505   %}
 9506   ins_pipe(ialu_reg); // FIXME
 9507 %}
 9508 
 9509 // Replicate scalar to packed int values in Double register pair
 9510 instruct Repl4I_reg(vecX dst, iRegI src) %{
 9511   predicate(n->as_Vector()->length() == 4 &&
 9512             Matcher::vector_element_basic_type(n) == T_INT);
 9513   match(Set dst (Replicate src));
 9514   ins_cost(DEFAULT_COST*2);
 9515   size(8);
 9516 
 9517   format %{ "FMDRR    $dst.lo,$src,$src\n\t"
 9518             "FMDRR    $dst.hi,$src,$src" %}
 9519 
 9520   ins_encode %{
 9521     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
 9522     __ fmdrr($dst$$FloatRegister->successor()->successor(),
 9523              $src$$Register, $src$$Register);
 9524   %}
 9525   ins_pipe(ialu_reg); // FIXME
 9526 %}
 9527 
 9528 // Replicate scalar to packed int values in Double register
 9529 instruct Repl2I_reg_simd(vecD dst, iRegI src) %{
 9530   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9531             Matcher::vector_element_basic_type(n) == T_INT);
 9532   match(Set dst (Replicate src));
 9533   size(4);
 9534 
 9535   format %{ "VDUP.32 $dst.D,$src\t" %}
 9536   ins_encode %{
 9537     bool quad = false;
 9538     __ vdupI($dst$$FloatRegister, $src$$Register,
 9539              MacroAssembler::VELEM_SIZE_32, quad);
 9540   %}
 9541   ins_pipe(ialu_reg); // FIXME
 9542 %}
 9543 
 9544 // Replicate scalar to packed int values in Double register pair
 9545 instruct Repl4I_reg_simd(vecX dst, iRegI src) %{
 9546   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd() &&
 9547             Matcher::vector_element_basic_type(n) == T_INT);
 9548   match(Set dst (Replicate src));
 9549   size(4);
 9550 
 9551   format %{ "VDUP.32 $dst.Q,$src\t" %}
 9552   ins_encode %{
 9553     bool quad = true;
 9554     __ vdupI($dst$$FloatRegister, $src$$Register,
 9555              MacroAssembler::VELEM_SIZE_32, quad);
 9556   %}
 9557   ins_pipe(ialu_reg); // FIXME
 9558 %}
 9559 
 9560 
 9561 // Replicate scalar zero constant to packed int values in Double register
 9562 instruct Repl2I_immI(vecD dst, immI src, iRegI tmp) %{
 9563   predicate(n->as_Vector()->length() == 2 &&
 9564             Matcher::vector_element_basic_type(n) == T_INT);
 9565   match(Set dst (Replicate src));
 9566   effect(TEMP tmp);
 9567   size(12);
 9568   ins_cost(DEFAULT_COST*4); // FIXME
 9569 
 9570   format %{ "MOV      $tmp, Repl1($src))\n\t"
 9571             "FMDRR    $dst,$tmp,$tmp\t" %}
 9572   ins_encode( LdReplImmI(src, dst, tmp, (1), (4)) );
 9573   ins_pipe(loadConFD); // FIXME
 9574 %}
 9575 
 9576 // Replicate scalar constant to packed byte values in Double register
 9577 instruct Repl2I_immU8(vecD dst, immU8 src) %{
 9578   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9579             Matcher::vector_element_basic_type(n) == T_INT);
 9580   match(Set dst (Replicate src));
 9581   size(4);
 9582 
 9583   format %{ "VMOV.I32  $dst.D,$src" %}
 9584   ins_encode %{
 9585     bool quad = false;
 9586     __ vmovI($dst$$FloatRegister, $src$$constant,
 9587              MacroAssembler::VELEM_SIZE_32, quad);
 9588   %}
 9589   ins_pipe(loadConFD); // FIXME
 9590 %}
 9591 
 9592 // Replicate scalar constant to packed byte values in Double register pair
 9593 instruct Repl4I_immU8(vecX dst, immU8 src) %{
 9594   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd() &&
 9595             Matcher::vector_element_basic_type(n) == T_INT);
 9596   match(Set dst (Replicate src));
 9597   size(4);
 9598 
 9599   format %{ "VMOV.I32  $dst.Q,$src" %}
 9600   ins_encode %{
 9601     bool quad = true;
 9602     __ vmovI($dst$$FloatRegister, $src$$constant,
 9603              MacroAssembler::VELEM_SIZE_32, quad);
 9604   %}
 9605   ins_pipe(loadConFD); // FIXME
 9606 %}
 9607 
 9608 // Replicate scalar to packed byte values in Double register pair
 9609 instruct Repl2L_reg(vecX dst, iRegL src) %{
 9610   predicate(n->as_Vector()->length() == 2 &&
 9611             Matcher::vector_element_basic_type(n) == T_LONG);
 9612   match(Set dst (Replicate src));
 9613   size(8);
 9614   ins_cost(DEFAULT_COST*2); // FIXME
 9615 
 9616   format %{ "FMDRR $dst.D,$src.lo,$src.hi\t\n"
 9617             "FMDRR $dst.D.next,$src.lo,$src.hi" %}
 9618   ins_encode %{
 9619     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
 9620     __ fmdrr($dst$$FloatRegister->successor()->successor(),
 9621              $src$$Register, $src$$Register->successor());
 9622   %}
 9623   ins_pipe(ialu_reg); // FIXME
 9624 %}
 9625 
 9626 
 9627 // Replicate scalar to packed float values in Double register
 9628 instruct Repl2F_regI(vecD dst, iRegI src) %{
 9629   predicate(n->as_Vector()->length() == 2 &&
 9630             Matcher::vector_element_basic_type(n) == T_FLOAT);
 9631   match(Set dst (Replicate src));
 9632   size(4);
 9633 
 9634   format %{ "FMDRR    $dst.D,$src,$src\t" %}
 9635   ins_encode %{
 9636     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
 9637   %}
 9638   ins_pipe(ialu_reg); // FIXME
 9639 %}
 9640 
 9641 // Replicate scalar to packed float values in Double register
 9642 instruct Repl2F_reg_vfp(vecD dst, regF src) %{
 9643   predicate(n->as_Vector()->length() == 2 &&
 9644             Matcher::vector_element_basic_type(n) == T_FLOAT);
 9645   match(Set dst (Replicate src));
 9646   size(4*2);
 9647   ins_cost(DEFAULT_COST*2); // FIXME
 9648 
 9649   expand %{
 9650     iRegI tmp;
 9651     MoveF2I_reg_reg(tmp, src);
 9652     Repl2F_regI(dst,tmp);
 9653   %}
 9654 %}
 9655 
 9656 // Replicate scalar to packed float values in Double register
 9657 instruct Repl2F_reg_simd(vecD dst, regF src) %{
 9658   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9659             Matcher::vector_element_basic_type(n) == T_FLOAT);
 9660   match(Set dst (Replicate src));
 9661   size(4);
 9662   ins_cost(DEFAULT_COST); // FIXME
 9663 
 9664   format %{ "VDUP.32  $dst.D,$src.D\t" %}
 9665   ins_encode %{
 9666     bool quad = false;
 9667     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
 9668   %}
 9669   ins_pipe(ialu_reg); // FIXME
 9670 %}
 9671 
 9672 // Replicate scalar to packed float values in Double register pair
 9673 instruct Repl4F_reg(vecX dst, regF src, iRegI tmp) %{
 9674   predicate(n->as_Vector()->length() == 4 &&
 9675             Matcher::vector_element_basic_type(n) == T_FLOAT);
 9676   match(Set dst (Replicate src));
 9677   effect(TEMP tmp);
 9678   size(4*3);
 9679   ins_cost(DEFAULT_COST*3); // FIXME
 9680 
 9681   format %{ "FMRS     $tmp,$src\n\t"
 9682             "FMDRR    $dst.D,$tmp,$tmp\n\t"
 9683             "FMDRR    $dst.D.next,$tmp,$tmp\t" %}
 9684   ins_encode %{
 9685     __ fmrs($tmp$$Register, $src$$FloatRegister);
 9686     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 9687     __ fmdrr($dst$$FloatRegister->successor()->successor(),
 9688              $tmp$$Register, $tmp$$Register);
 9689   %}
 9690   ins_pipe(ialu_reg); // FIXME
 9691 %}
 9692 
 9693 // Replicate scalar to packed float values in Double register pair
 9694 instruct Repl4F_reg_simd(vecX dst, regF src) %{
 9695   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd() &&
 9696             Matcher::vector_element_basic_type(n) == T_FLOAT);
 9697   match(Set dst (Replicate src));
 9698   size(4);
 9699   ins_cost(DEFAULT_COST); // FIXME
 9700 
 9701   format %{ "VDUP.32  $dst.Q,$src.D\t" %}
 9702   ins_encode %{
 9703     bool quad = true;
 9704     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
 9705   %}
 9706   ins_pipe(ialu_reg); // FIXME
 9707 %}
 9708 
 9709 // Replicate scalar zero constant to packed float values in Double register
 9710 instruct Repl2F_immI(vecD dst, immF src, iRegI tmp) %{
 9711   predicate(n->as_Vector()->length() == 2 &&
 9712             Matcher::vector_element_basic_type(n) == T_FLOAT);
 9713   match(Set dst (Replicate src));
 9714   effect(TEMP tmp);
 9715   size(12);
 9716   ins_cost(DEFAULT_COST*4); // FIXME
 9717 
 9718   format %{ "MOV      $tmp, Repl1($src))\n\t"
 9719             "FMDRR    $dst,$tmp,$tmp\t" %}
 9720   ins_encode( LdReplImmF(src, dst, tmp) );
 9721   ins_pipe(loadConFD); // FIXME
 9722 %}
 9723 
 9724 // Replicate scalar to packed double float values in Double register pair
 9725 instruct Repl2D_reg(vecX dst, regD src) %{
 9726   predicate(n->as_Vector()->length() == 2 &&
 9727             Matcher::vector_element_basic_type(n) == T_DOUBLE);
 9728   match(Set dst (Replicate src));
 9729   size(4*2);
 9730   ins_cost(DEFAULT_COST*2); // FIXME
 9731 
 9732   format %{ "FCPYD    $dst.D.a,$src\n\t"
 9733             "FCPYD    $dst.D.b,$src\t" %}
 9734   ins_encode %{
 9735     FloatRegister dsta = $dst$$FloatRegister;
 9736     FloatRegister src = $src$$FloatRegister;
 9737     __ fcpyd(dsta, src);
 9738     FloatRegister dstb = dsta->successor()->successor();
 9739     __ fcpyd(dstb, src);
 9740   %}
 9741   ins_pipe(ialu_reg); // FIXME
 9742 %}
 9743 
 9744 // ====================VECTOR ARITHMETIC=======================================
 9745 
 9746 // --------------------------------- ADD --------------------------------------
 9747 
 9748 // Bytes vector add
 9749 instruct vadd8B_reg(vecD dst, vecD src1, vecD src2) %{
 9750   predicate(n->as_Vector()->length() == 8);
 9751   match(Set dst (AddVB src1 src2));
 9752   format %{ "VADD.I8 $dst,$src1,$src2\t! add packed8B" %}
 9753   size(4);
 9754   ins_encode %{
 9755     bool quad = false;
 9756     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9757              MacroAssembler::VELEM_SIZE_8, quad);
 9758   %}
 9759   ins_pipe( ialu_reg_reg ); // FIXME
 9760 %}
 9761 
 9762 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
 9763   predicate(n->as_Vector()->length() == 16);
 9764   match(Set dst (AddVB src1 src2));
 9765   size(4);
 9766   format %{ "VADD.I8 $dst.Q,$src1.Q,$src2.Q\t! add packed16B" %}
 9767   ins_encode %{
 9768     bool quad = true;
 9769     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9770              MacroAssembler::VELEM_SIZE_8, quad);
 9771   %}
 9772   ins_pipe( ialu_reg_reg ); // FIXME
 9773 %}
 9774 
 9775 // Shorts/Chars vector add
 9776 instruct vadd4S_reg(vecD dst, vecD src1, vecD src2) %{
 9777   predicate(n->as_Vector()->length() == 4);
 9778   match(Set dst (AddVS src1 src2));
 9779   size(4);
 9780   format %{ "VADD.I16 $dst,$src1,$src2\t! add packed4S" %}
 9781   ins_encode %{
 9782     bool quad = false;
 9783     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9784              MacroAssembler::VELEM_SIZE_16, quad);
 9785   %}
 9786   ins_pipe( ialu_reg_reg ); // FIXME
 9787 %}
 9788 
 9789 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
 9790   predicate(n->as_Vector()->length() == 8);
 9791   match(Set dst (AddVS src1 src2));
 9792   size(4);
 9793   format %{ "VADD.I16 $dst.Q,$src1.Q,$src2.Q\t! add packed8S" %}
 9794   ins_encode %{
 9795     bool quad = true;
 9796     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9797              MacroAssembler::VELEM_SIZE_16, quad);
 9798   %}
 9799   ins_pipe( ialu_reg_reg ); // FIXME
 9800 %}
 9801 
 9802 // Integers vector add
 9803 instruct vadd2I_reg(vecD dst, vecD src1, vecD src2) %{
 9804   predicate(n->as_Vector()->length() == 2);
 9805   match(Set dst (AddVI src1 src2));
 9806   size(4);
 9807   format %{ "VADD.I32 $dst.D,$src1.D,$src2.D\t! add packed2I" %}
 9808   ins_encode %{
 9809     bool quad = false;
 9810     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9811              MacroAssembler::VELEM_SIZE_32, quad);
 9812   %}
 9813   ins_pipe( ialu_reg_reg ); // FIXME
 9814 %}
 9815 
 9816 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
 9817   predicate(n->as_Vector()->length() == 4);
 9818   match(Set dst (AddVI src1 src2));
 9819   size(4);
 9820   format %{ "VADD.I32 $dst.Q,$src1.Q,$src2.Q\t! add packed4I" %}
 9821   ins_encode %{
 9822     bool quad = true;
 9823     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9824              MacroAssembler::VELEM_SIZE_32, quad);
 9825   %}
 9826   ins_pipe( ialu_reg_reg ); // FIXME
 9827 %}
 9828 
 9829 // Longs vector add
 9830 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
 9831   predicate(n->as_Vector()->length() == 2);
 9832   match(Set dst (AddVL src1 src2));
 9833   size(4);
 9834   format %{ "VADD.I64 $dst.Q,$src1.Q,$src2.Q\t! add packed2L" %}
 9835   ins_encode %{
 9836     bool quad = true;
 9837     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9838              MacroAssembler::VELEM_SIZE_64, quad);
 9839   %}
 9840   ins_pipe( ialu_reg_reg ); // FIXME
 9841 %}
 9842 
 9843 // Floats vector add
 9844 instruct vadd2F_reg(vecD dst, vecD src1, vecD src2) %{
 9845   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
 9846   match(Set dst (AddVF src1 src2));
 9847   size(4);
 9848   format %{ "VADD.F32 $dst,$src1,$src2\t! add packed2F" %}
 9849   ins_encode %{
 9850     bool quad = false;
 9851     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9852              MacroAssembler::VFA_SIZE_F32, quad);
 9853   %}
 9854   ins_pipe( faddD_reg_reg ); // FIXME
 9855 %}
 9856 
 9857 instruct vadd2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
 9858   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
 9859   match(Set dst (AddVF src1 src2));
 9860   ins_cost(DEFAULT_COST*2); // FIXME
 9861 
 9862   size(4*2);
 9863   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
 9864             "FADDS  $dst.b,$src1.b,$src2.b" %}
 9865   ins_encode %{
 9866     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 9867     __ add_float($dst$$FloatRegister->successor(),
 9868              $src1$$FloatRegister->successor(),
 9869              $src2$$FloatRegister->successor());
 9870   %}
 9871 
 9872   ins_pipe(faddF_reg_reg); // FIXME
 9873 %}
 9874 
 9875 instruct vadd4F_reg_simd(vecX dst, vecX src1, vecX src2) %{
 9876   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
 9877   match(Set dst (AddVF src1 src2));
 9878   size(4);
 9879   format %{ "VADD.F32 $dst.Q,$src1.Q,$src2.Q\t! add packed4F" %}
 9880   ins_encode %{
 9881     bool quad = true;
 9882     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9883              MacroAssembler::VFA_SIZE_F32, quad);
 9884   %}
 9885   ins_pipe( faddD_reg_reg ); // FIXME
 9886 %}
 9887 
 9888 instruct vadd4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
 9889   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
 9890   match(Set dst (AddVF src1 src2));
 9891   size(4*4);
 9892   ins_cost(DEFAULT_COST*4); // FIXME
 9893 
 9894   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
 9895             "FADDS  $dst.b,$src1.b,$src2.b\n\t"
 9896             "FADDS  $dst.c,$src1.c,$src2.c\n\t"
 9897             "FADDS  $dst.d,$src1.d,$src2.d" %}
 9898 
 9899   ins_encode %{
 9900     FloatRegister dsta = $dst$$FloatRegister;
 9901     FloatRegister src1a = $src1$$FloatRegister;
 9902     FloatRegister src2a = $src2$$FloatRegister;
 9903     __ add_float(dsta, src1a, src2a);
 9904     FloatRegister dstb = dsta->successor();
 9905     FloatRegister src1b = src1a->successor();
 9906     FloatRegister src2b = src2a->successor();
 9907     __ add_float(dstb, src1b, src2b);
 9908     FloatRegister dstc = dstb->successor();
 9909     FloatRegister src1c = src1b->successor();
 9910     FloatRegister src2c = src2b->successor();
 9911     __ add_float(dstc, src1c, src2c);
 9912     FloatRegister dstd = dstc->successor();
 9913     FloatRegister src1d = src1c->successor();
 9914     FloatRegister src2d = src2c->successor();
 9915     __ add_float(dstd, src1d, src2d);
 9916   %}
 9917 
 9918   ins_pipe(faddF_reg_reg); // FIXME
 9919 %}
 9920 
 9921 instruct vadd2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
 9922   predicate(n->as_Vector()->length() == 2);
 9923   match(Set dst (AddVD src1 src2));
 9924   size(4*2);
 9925   ins_cost(DEFAULT_COST*2); // FIXME
 9926 
 9927   format %{ "FADDD  $dst.a,$src1.a,$src2.a\n\t"
 9928             "FADDD  $dst.b,$src1.b,$src2.b" %}
 9929 
 9930   ins_encode %{
 9931     FloatRegister dsta = $dst$$FloatRegister;
 9932     FloatRegister src1a = $src1$$FloatRegister;
 9933     FloatRegister src2a = $src2$$FloatRegister;
 9934     __ add_double(dsta, src1a, src2a);
 9935     FloatRegister dstb = dsta->successor()->successor();
 9936     FloatRegister src1b = src1a->successor()->successor();
 9937     FloatRegister src2b = src2a->successor()->successor();
 9938     __ add_double(dstb, src1b, src2b);
 9939   %}
 9940 
 9941   ins_pipe(faddF_reg_reg); // FIXME
 9942 %}
 9943 
 9944 
 9945 // Bytes vector sub
 9946 instruct vsub8B_reg(vecD dst, vecD src1, vecD src2) %{
 9947   predicate(n->as_Vector()->length() == 8);
 9948   match(Set dst (SubVB src1 src2));
 9949   size(4);
 9950   format %{ "VSUB.I8 $dst,$src1,$src2\t! sub packed8B" %}
 9951   ins_encode %{
 9952     bool quad = false;
 9953     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9954              MacroAssembler::VELEM_SIZE_8, quad);
 9955   %}
 9956   ins_pipe( ialu_reg_reg ); // FIXME
 9957 %}
 9958 
 9959 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
 9960   predicate(n->as_Vector()->length() == 16);
 9961   match(Set dst (SubVB src1 src2));
 9962   size(4);
 9963   format %{ "VSUB.I8 $dst.Q,$src1.Q,$src2.Q\t! sub packed16B" %}
 9964   ins_encode %{
 9965     bool quad = true;
 9966     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9967              MacroAssembler::VELEM_SIZE_8, quad);
 9968   %}
 9969   ins_pipe( ialu_reg_reg ); // FIXME
 9970 %}
 9971 
 9972 // Shorts/Chars vector sub
 9973 instruct vsub4S_reg(vecD dst, vecD src1, vecD src2) %{
 9974   predicate(n->as_Vector()->length() == 4);
 9975   match(Set dst (SubVS src1 src2));
 9976   size(4);
 9977   format %{ "VSUB.I16 $dst,$src1,$src2\t! sub packed4S" %}
 9978   ins_encode %{
 9979     bool quad = false;
 9980     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9981              MacroAssembler::VELEM_SIZE_16, quad);
 9982   %}
 9983   ins_pipe( ialu_reg_reg ); // FIXME
 9984 %}
 9985 
 9986 instruct vsub16S_reg(vecX dst, vecX src1, vecX src2) %{
 9987   predicate(n->as_Vector()->length() == 8);
 9988   match(Set dst (SubVS src1 src2));
 9989   size(4);
 9990   format %{ "VSUB.I16 $dst.Q,$src1.Q,$src2.Q\t! sub packed8S" %}
 9991   ins_encode %{
 9992     bool quad = true;
 9993     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9994              MacroAssembler::VELEM_SIZE_16, quad);
 9995   %}
 9996   ins_pipe( ialu_reg_reg ); // FIXME
 9997 %}
 9998 
 9999 // Integers vector sub
10000 instruct vsub2I_reg(vecD dst, vecD src1, vecD src2) %{
10001   predicate(n->as_Vector()->length() == 2);
10002   match(Set dst (SubVI src1 src2));
10003   size(4);
10004   format %{ "VSUB.I32 $dst,$src1,$src2\t! sub packed2I" %}
10005   ins_encode %{
10006     bool quad = false;
10007     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10008              MacroAssembler::VELEM_SIZE_32, quad);
10009   %}
10010   ins_pipe( ialu_reg_reg ); // FIXME
10011 %}
10012 
10013 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
10014   predicate(n->as_Vector()->length() == 4);
10015   match(Set dst (SubVI src1 src2));
10016   size(4);
10017   format %{ "VSUB.I32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4I" %}
10018   ins_encode %{
10019     bool quad = true;
10020     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10021              MacroAssembler::VELEM_SIZE_32, quad);
10022   %}
10023   ins_pipe( ialu_reg_reg ); // FIXME
10024 %}
10025 
10026 // Longs vector sub
10027 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
10028   predicate(n->as_Vector()->length() == 2);
10029   match(Set dst (SubVL src1 src2));
10030   size(4);
10031   format %{ "VSUB.I64 $dst.Q,$src1.Q,$src2.Q\t! sub packed2L" %}
10032   ins_encode %{
10033     bool quad = true;
10034     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10035              MacroAssembler::VELEM_SIZE_64, quad);
10036   %}
10037   ins_pipe( ialu_reg_reg ); // FIXME
10038 %}
10039 
10040 // Floats vector sub
10041 instruct vsub2F_reg(vecD dst, vecD src1, vecD src2) %{
10042   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
10043   match(Set dst (SubVF src1 src2));
10044   size(4);
10045   format %{ "VSUB.F32 $dst,$src1,$src2\t! sub packed2F" %}
10046   ins_encode %{
10047     bool quad = false;
10048     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10049              MacroAssembler::VFA_SIZE_F32, quad);
10050   %}
10051   ins_pipe( faddF_reg_reg ); // FIXME
10052 %}
10053 
10054 instruct vsub2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10055   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
10056   match(Set dst (SubVF src1 src2));
10057   size(4*2);
10058   ins_cost(DEFAULT_COST*2); // FIXME
10059 
10060   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10061             "FSUBS  $dst.b,$src1.b,$src2.b" %}
10062 
10063   ins_encode %{
10064     FloatRegister dsta = $dst$$FloatRegister;
10065     FloatRegister src1a = $src1$$FloatRegister;
10066     FloatRegister src2a = $src2$$FloatRegister;
10067     __ sub_float(dsta, src1a, src2a);
10068     FloatRegister dstb = dsta->successor();
10069     FloatRegister src1b = src1a->successor();
10070     FloatRegister src2b = src2a->successor();
10071     __ sub_float(dstb, src1b, src2b);
10072   %}
10073 
10074   ins_pipe(faddF_reg_reg); // FIXME
10075 %}
10076 
10077 
10078 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
10079   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
10080   match(Set dst (SubVF src1 src2));
10081   size(4);
10082   format %{ "VSUB.F32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4F" %}
10083   ins_encode %{
10084     bool quad = true;
10085     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10086              MacroAssembler::VFA_SIZE_F32, quad);
10087   %}
10088   ins_pipe( faddF_reg_reg ); // FIXME
10089 %}
10090 
10091 instruct vsub4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10092   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
10093   match(Set dst (SubVF src1 src2));
10094   size(4*4);
10095   ins_cost(DEFAULT_COST*4); // FIXME
10096 
10097   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10098             "FSUBS  $dst.b,$src1.b,$src2.b\n\t"
10099             "FSUBS  $dst.c,$src1.c,$src2.c\n\t"
10100             "FSUBS  $dst.d,$src1.d,$src2.d" %}
10101 
10102   ins_encode %{
10103     FloatRegister dsta = $dst$$FloatRegister;
10104     FloatRegister src1a = $src1$$FloatRegister;
10105     FloatRegister src2a = $src2$$FloatRegister;
10106     __ sub_float(dsta, src1a, src2a);
10107     FloatRegister dstb = dsta->successor();
10108     FloatRegister src1b = src1a->successor();
10109     FloatRegister src2b = src2a->successor();
10110     __ sub_float(dstb, src1b, src2b);
10111     FloatRegister dstc = dstb->successor();
10112     FloatRegister src1c = src1b->successor();
10113     FloatRegister src2c = src2b->successor();
10114     __ sub_float(dstc, src1c, src2c);
10115     FloatRegister dstd = dstc->successor();
10116     FloatRegister src1d = src1c->successor();
10117     FloatRegister src2d = src2c->successor();
10118     __ sub_float(dstd, src1d, src2d);
10119   %}
10120 
10121   ins_pipe(faddF_reg_reg); // FIXME
10122 %}
10123 
10124 instruct vsub2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10125   predicate(n->as_Vector()->length() == 2);
10126   match(Set dst (SubVD src1 src2));
10127   size(4*2);
10128   ins_cost(DEFAULT_COST*2); // FIXME
10129 
10130   format %{ "FSUBD  $dst.a,$src1.a,$src2.a\n\t"
10131             "FSUBD  $dst.b,$src1.b,$src2.b" %}
10132 
10133   ins_encode %{
10134     FloatRegister dsta = $dst$$FloatRegister;
10135     FloatRegister src1a = $src1$$FloatRegister;
10136     FloatRegister src2a = $src2$$FloatRegister;
10137     __ sub_double(dsta, src1a, src2a);
10138     FloatRegister dstb = dsta->successor()->successor();
10139     FloatRegister src1b = src1a->successor()->successor();
10140     FloatRegister src2b = src2a->successor()->successor();
10141     __ sub_double(dstb, src1b, src2b);
10142   %}
10143 
10144   ins_pipe(faddF_reg_reg); // FIXME
10145 %}
10146 
10147 // Shorts/Chars vector mul
10148 instruct vmul4S_reg(vecD dst, vecD src1, vecD src2) %{
10149   predicate(n->as_Vector()->length() == 4);
10150   match(Set dst (MulVS src1 src2));
10151   size(4);
10152   format %{ "VMUL.I16 $dst,$src1,$src2\t! mul packed4S" %}
10153   ins_encode %{
10154     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10155              MacroAssembler::VELEM_SIZE_16, 0);
10156   %}
10157   ins_pipe( ialu_reg_reg ); // FIXME
10158 %}
10159 
10160 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2) %{
10161   predicate(n->as_Vector()->length() == 8);
10162   match(Set dst (MulVS src1 src2));
10163   size(4);
10164   format %{ "VMUL.I16 $dst.Q,$src1.Q,$src2.Q\t! mul packed8S" %}
10165   ins_encode %{
10166     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10167              MacroAssembler::VELEM_SIZE_16, 1);
10168   %}
10169   ins_pipe( ialu_reg_reg ); // FIXME
10170 %}
10171 
10172 // Integers vector mul
10173 instruct vmul2I_reg(vecD dst, vecD src1, vecD src2) %{
10174   predicate(n->as_Vector()->length() == 2);
10175   match(Set dst (MulVI src1 src2));
10176   size(4);
10177   format %{ "VMUL.I32 $dst,$src1,$src2\t! mul packed2I" %}
10178   ins_encode %{
10179     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10180              MacroAssembler::VELEM_SIZE_32, 0);
10181   %}
10182   ins_pipe( ialu_reg_reg ); // FIXME
10183 %}
10184 
10185 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
10186   predicate(n->as_Vector()->length() == 4);
10187   match(Set dst (MulVI src1 src2));
10188   size(4);
10189   format %{ "VMUL.I32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4I" %}
10190   ins_encode %{
10191     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10192              MacroAssembler::VELEM_SIZE_32, 1);
10193   %}
10194   ins_pipe( ialu_reg_reg ); // FIXME
10195 %}
10196 
10197 // Floats vector mul
10198 instruct vmul2F_reg(vecD dst, vecD src1, vecD src2) %{
10199   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
10200   match(Set dst (MulVF src1 src2));
10201   size(4);
10202   format %{ "VMUL.F32 $dst,$src1,$src2\t! mul packed2F" %}
10203   ins_encode %{
10204     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10205              MacroAssembler::VFA_SIZE_F32, 0);
10206   %}
10207   ins_pipe( fmulF_reg_reg ); // FIXME
10208 %}
10209 
10210 instruct vmul2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10211   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
10212   match(Set dst (MulVF src1 src2));
10213   size(4*2);
10214   ins_cost(DEFAULT_COST*2); // FIXME
10215 
10216   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10217             "FMULS  $dst.b,$src1.b,$src2.b" %}
10218   ins_encode %{
10219     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10220     __ mul_float($dst$$FloatRegister->successor(),
10221              $src1$$FloatRegister->successor(),
10222              $src2$$FloatRegister->successor());
10223   %}
10224 
10225   ins_pipe(fmulF_reg_reg); // FIXME
10226 %}
10227 
10228 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
10229   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
10230   match(Set dst (MulVF src1 src2));
10231   size(4);
10232   format %{ "VMUL.F32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4F" %}
10233   ins_encode %{
10234     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10235              MacroAssembler::VFA_SIZE_F32, 1);
10236   %}
10237   ins_pipe( fmulF_reg_reg ); // FIXME
10238 %}
10239 
10240 instruct vmul4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10241   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
10242   match(Set dst (MulVF src1 src2));
10243   size(4*4);
10244   ins_cost(DEFAULT_COST*4); // FIXME
10245 
10246   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10247             "FMULS  $dst.b,$src1.b,$src2.b\n\t"
10248             "FMULS  $dst.c,$src1.c,$src2.c\n\t"
10249             "FMULS  $dst.d,$src1.d,$src2.d" %}
10250 
10251   ins_encode %{
10252     FloatRegister dsta = $dst$$FloatRegister;
10253     FloatRegister src1a = $src1$$FloatRegister;
10254     FloatRegister src2a = $src2$$FloatRegister;
10255     __ mul_float(dsta, src1a, src2a);
10256     FloatRegister dstb = dsta->successor();
10257     FloatRegister src1b = src1a->successor();
10258     FloatRegister src2b = src2a->successor();
10259     __ mul_float(dstb, src1b, src2b);
10260     FloatRegister dstc = dstb->successor();
10261     FloatRegister src1c = src1b->successor();
10262     FloatRegister src2c = src2b->successor();
10263     __ mul_float(dstc, src1c, src2c);
10264     FloatRegister dstd = dstc->successor();
10265     FloatRegister src1d = src1c->successor();
10266     FloatRegister src2d = src2c->successor();
10267     __ mul_float(dstd, src1d, src2d);
10268   %}
10269 
10270   ins_pipe(fmulF_reg_reg); // FIXME
10271 %}
10272 
10273 instruct vmul2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10274   predicate(n->as_Vector()->length() == 2);
10275   match(Set dst (MulVD src1 src2));
10276   size(4*2);
10277   ins_cost(DEFAULT_COST*2); // FIXME
10278 
10279   format %{ "FMULD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10280             "FMULD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10281   ins_encode %{
10282     FloatRegister dsta = $dst$$FloatRegister;
10283     FloatRegister src1a = $src1$$FloatRegister;
10284     FloatRegister src2a = $src2$$FloatRegister;
10285     __ mul_double(dsta, src1a, src2a);
10286     FloatRegister dstb = dsta->successor()->successor();
10287     FloatRegister src1b = src1a->successor()->successor();
10288     FloatRegister src2b = src2a->successor()->successor();
10289     __ mul_double(dstb, src1b, src2b);
10290   %}
10291 
10292   ins_pipe(fmulD_reg_reg); // FIXME
10293 %}
10294 
10295 
10296 // Floats vector div
10297 instruct vdiv2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10298   predicate(n->as_Vector()->length() == 2);
10299   match(Set dst (DivVF src1 src2));
10300   size(4*2);
10301   ins_cost(DEFAULT_COST*2); // FIXME
10302 
10303   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10304             "FDIVS  $dst.b,$src1.b,$src2.b" %}
10305   ins_encode %{
10306     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10307     __ div_float($dst$$FloatRegister->successor(),
10308              $src1$$FloatRegister->successor(),
10309              $src2$$FloatRegister->successor());
10310   %}
10311 
10312   ins_pipe(fdivF_reg_reg); // FIXME
10313 %}
10314 
10315 instruct vdiv4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10316   predicate(n->as_Vector()->length() == 4);
10317   match(Set dst (DivVF src1 src2));
10318   size(4*4);
10319   ins_cost(DEFAULT_COST*4); // FIXME
10320 
10321   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10322             "FDIVS  $dst.b,$src1.b,$src2.b\n\t"
10323             "FDIVS  $dst.c,$src1.c,$src2.c\n\t"
10324             "FDIVS  $dst.d,$src1.d,$src2.d" %}
10325 
10326   ins_encode %{
10327     FloatRegister dsta = $dst$$FloatRegister;
10328     FloatRegister src1a = $src1$$FloatRegister;
10329     FloatRegister src2a = $src2$$FloatRegister;
10330     __ div_float(dsta, src1a, src2a);
10331     FloatRegister dstb = dsta->successor();
10332     FloatRegister src1b = src1a->successor();
10333     FloatRegister src2b = src2a->successor();
10334     __ div_float(dstb, src1b, src2b);
10335     FloatRegister dstc = dstb->successor();
10336     FloatRegister src1c = src1b->successor();
10337     FloatRegister src2c = src2b->successor();
10338     __ div_float(dstc, src1c, src2c);
10339     FloatRegister dstd = dstc->successor();
10340     FloatRegister src1d = src1c->successor();
10341     FloatRegister src2d = src2c->successor();
10342     __ div_float(dstd, src1d, src2d);
10343   %}
10344 
10345   ins_pipe(fdivF_reg_reg); // FIXME
10346 %}
10347 
10348 instruct vdiv2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10349   predicate(n->as_Vector()->length() == 2);
10350   match(Set dst (DivVD src1 src2));
10351   size(4*2);
10352   ins_cost(DEFAULT_COST*2); // FIXME
10353 
10354   format %{ "FDIVD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10355             "FDIVD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10356   ins_encode %{
10357     FloatRegister dsta = $dst$$FloatRegister;
10358     FloatRegister src1a = $src1$$FloatRegister;
10359     FloatRegister src2a = $src2$$FloatRegister;
10360     __ div_double(dsta, src1a, src2a);
10361     FloatRegister dstb = dsta->successor()->successor();
10362     FloatRegister src1b = src1a->successor()->successor();
10363     FloatRegister src2b = src2a->successor()->successor();
10364     __ div_double(dstb, src1b, src2b);
10365   %}
10366 
10367   ins_pipe(fdivD_reg_reg); // FIXME
10368 %}
10369 
10370 // --------------------------------- NEG --------------------------------------
10371 
10372 instruct vneg8B_reg(vecD dst, vecD src) %{
10373   predicate(n->as_Vector()->length_in_bytes() == 8);
10374   effect(DEF dst, USE src);
10375   size(4);
10376   ins_cost(DEFAULT_COST); // FIXME
10377   format %{ "VNEG.S8 $dst.D,$src.D\t! neg packed8B" %}
10378   ins_encode %{
10379     bool quad = false;
10380     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
10381               MacroAssembler::VELEM_SIZE_8, quad);
10382   %}
10383   ins_pipe( ialu_reg_reg ); // FIXME
10384 %}
10385 
10386 instruct vneg16B_reg(vecX dst, vecX src) %{
10387   predicate(n->as_Vector()->length_in_bytes() == 16);
10388   effect(DEF dst, USE src);
10389   size(4);
10390   ins_cost(DEFAULT_COST); // FIXME
10391   format %{ "VNEG.S8 $dst.Q,$src.Q\t! neg0 packed16B" %}
10392   ins_encode %{
10393     bool _float = false;
10394     bool quad = true;
10395     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
10396               MacroAssembler::VELEM_SIZE_8, quad);
10397   %}
10398   ins_pipe( ialu_reg_reg ); // FIXME
10399 %}
10400 
10401 // ------------------------------ ShiftCount ----------------------------------
10402 
10403 instruct vslcntD(vecD dst, iRegI cnt) %{
10404   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
10405   match(Set dst (LShiftCntV cnt));
10406   size(4);
10407   ins_cost(DEFAULT_COST); // FIXME
10408   expand %{
10409     Repl8B_reg_simd(dst, cnt);
10410   %}
10411 %}
10412 
10413 instruct vslcntX(vecX dst, iRegI cnt) %{
10414   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
10415   match(Set dst (LShiftCntV cnt));
10416   size(4);
10417   ins_cost(DEFAULT_COST); // FIXME
10418   expand %{
10419     Repl16B_reg(dst, cnt);
10420   %}
10421 %}
10422 
10423 // Low bits of vector "shift" elements are used, so it
10424 // doesn't matter if we treat it as ints or bytes here.
10425 instruct vsrcntD(vecD dst, iRegI cnt) %{
10426   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
10427   match(Set dst (RShiftCntV cnt));
10428   size(4*2);
10429   ins_cost(DEFAULT_COST*2); // FIXME
10430 
10431   format %{ "VDUP.8 $dst.D,$cnt\n\t"
10432             "VNEG.S8 $dst.D,$dst.D\t! neg packed8B" %}
10433   ins_encode %{
10434     bool quad = false;
10435     __ vdupI($dst$$FloatRegister, $cnt$$Register,
10436              MacroAssembler::VELEM_SIZE_8, quad);
10437     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
10438               MacroAssembler::VELEM_SIZE_8, quad);
10439   %}
10440   ins_pipe( ialu_reg_reg ); // FIXME
10441 %}
10442 
10443 instruct vsrcntX(vecX dst, iRegI cnt) %{
10444   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
10445   match(Set dst (RShiftCntV cnt));
10446   size(4*2);
10447   ins_cost(DEFAULT_COST*2); // FIXME
10448   format %{ "VDUP.8 $dst.Q,$cnt\n\t"
10449             "VNEG.S8 $dst.Q,$dst.Q\t! neg packed16B" %}
10450   ins_encode %{
10451     bool quad = true;
10452     __ vdupI($dst$$FloatRegister, $cnt$$Register,
10453              MacroAssembler::VELEM_SIZE_8, quad);
10454     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
10455               MacroAssembler::VELEM_SIZE_8, quad);
10456   %}
10457   ins_pipe( ialu_reg_reg ); // FIXME
10458 %}
10459 
10460 // ------------------------------ LogicalShift --------------------------------
10461 
10462 // Byte vector logical left/right shift based on sign
10463 instruct vsh8B_reg(vecD dst, vecD src, vecD shift) %{
10464   predicate(n->as_Vector()->length() == 8);
10465   effect(DEF dst, USE src, USE shift);
10466   size(4);
10467   ins_cost(DEFAULT_COST); // FIXME
10468   format %{
10469     "VSHL.U8 $dst.D,$src.D,$shift.D\t! logical left/right shift packed8B"
10470   %}
10471   ins_encode %{
10472     bool quad = false;
10473     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10474               MacroAssembler::VELEM_SIZE_8, quad);
10475   %}
10476   ins_pipe( ialu_reg_reg ); // FIXME
10477 %}
10478 
10479 instruct vsh16B_reg(vecX dst, vecX src, vecX shift) %{
10480   predicate(n->as_Vector()->length() == 16);
10481   effect(DEF dst, USE src, USE shift);
10482   size(4);
10483   ins_cost(DEFAULT_COST); // FIXME
10484   format %{
10485     "VSHL.U8 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed16B"
10486   %}
10487   ins_encode %{
10488     bool quad = true;
10489     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10490               MacroAssembler::VELEM_SIZE_8, quad);
10491   %}
10492   ins_pipe( ialu_reg_reg ); // FIXME
10493 %}
10494 
10495 // Shorts/Char vector logical left/right shift based on sign
10496 instruct vsh4S_reg(vecD dst, vecD src, vecD shift) %{
10497   predicate(n->as_Vector()->length() == 4);
10498   effect(DEF dst, USE src, USE shift);
10499   size(4);
10500   ins_cost(DEFAULT_COST); // FIXME
10501   format %{
10502     "VSHL.U16 $dst.D,$src.D,$shift.D\t! logical left/right shift packed4S"
10503   %}
10504   ins_encode %{
10505     bool quad = false;
10506     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10507               MacroAssembler::VELEM_SIZE_16, quad);
10508   %}
10509   ins_pipe( ialu_reg_reg ); // FIXME
10510 %}
10511 
10512 instruct vsh8S_reg(vecX dst, vecX src, vecX shift) %{
10513   predicate(n->as_Vector()->length() == 8);
10514   effect(DEF dst, USE src, USE shift);
10515   size(4);
10516   ins_cost(DEFAULT_COST); // FIXME
10517   format %{
10518     "VSHL.U16 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed8S"
10519   %}
10520   ins_encode %{
10521     bool quad = true;
10522     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10523               MacroAssembler::VELEM_SIZE_16, quad);
10524   %}
10525   ins_pipe( ialu_reg_reg ); // FIXME
10526 %}
10527 
10528 // Integers vector logical left/right shift based on sign
10529 instruct vsh2I_reg(vecD dst, vecD src, vecD shift) %{
10530   predicate(n->as_Vector()->length() == 2);
10531   effect(DEF dst, USE src, USE shift);
10532   size(4);
10533   ins_cost(DEFAULT_COST); // FIXME
10534   format %{
10535     "VSHL.U32 $dst.D,$src.D,$shift.D\t! logical left/right shift packed2I"
10536   %}
10537   ins_encode %{
10538     bool quad = false;
10539     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10540               MacroAssembler::VELEM_SIZE_32, quad);
10541   %}
10542   ins_pipe( ialu_reg_reg ); // FIXME
10543 %}
10544 
10545 instruct vsh4I_reg(vecX dst, vecX src, vecX shift) %{
10546   predicate(n->as_Vector()->length() == 4);
10547   effect(DEF dst, USE src, USE shift);
10548   size(4);
10549   ins_cost(DEFAULT_COST); // FIXME
10550   format %{
10551     "VSHL.U32 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed4I"
10552   %}
10553   ins_encode %{
10554     bool quad = true;
10555     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10556               MacroAssembler::VELEM_SIZE_32, quad);
10557   %}
10558   ins_pipe( ialu_reg_reg ); // FIXME
10559 %}
10560 
10561 // Longs vector logical left/right shift based on sign
10562 instruct vsh2L_reg(vecX dst, vecX src, vecX shift) %{
10563   predicate(n->as_Vector()->length() == 2);
10564   effect(DEF dst, USE src, USE shift);
10565   size(4);
10566   ins_cost(DEFAULT_COST); // FIXME
10567   format %{
10568     "VSHL.U64 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed2L"
10569   %}
10570   ins_encode %{
10571     bool quad = true;
10572     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10573               MacroAssembler::VELEM_SIZE_64, quad);
10574   %}
10575   ins_pipe( ialu_reg_reg ); // FIXME
10576 %}
10577 
10578 // ------------------------------ LogicalLeftShift ----------------------------
10579 
10580 // Byte vector logical left shift
10581 instruct vsl8B_reg(vecD dst, vecD src, vecD shift) %{
10582   predicate(n->as_Vector()->length() == 8);
10583   match(Set dst (LShiftVB src shift));
10584   size(4*1);
10585   ins_cost(DEFAULT_COST*1); // FIXME
10586   expand %{
10587     vsh8B_reg(dst, src, shift);
10588   %}
10589 %}
10590 
10591 instruct vsl16B_reg(vecX dst, vecX src, vecX shift) %{
10592   predicate(n->as_Vector()->length() == 16);
10593   match(Set dst (LShiftVB src shift));
10594   size(4*1);
10595   ins_cost(DEFAULT_COST*1); // FIXME
10596   expand %{
10597     vsh16B_reg(dst, src, shift);
10598   %}
10599 %}
10600 
10601 instruct vsl8B_immI(vecD dst, vecD src, immI shift) %{
10602   predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n));
10603   match(Set dst (LShiftVB src (LShiftCntV shift)));
10604   size(4);
10605   ins_cost(DEFAULT_COST); // FIXME
10606   format %{
10607     "VSHL.I8 $dst.D,$src.D,$shift\t! logical left shift packed8B"
10608   %}
10609   ins_encode %{
10610     bool quad = false;
10611     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10612              quad);
10613   %}
10614   ins_pipe( ialu_reg_reg ); // FIXME
10615 %}
10616 
10617 instruct vsl16B_immI(vecX dst, vecX src, immI shift) %{
10618   predicate(n->as_Vector()->length() == 16 && assert_not_var_shift(n));
10619   match(Set dst (LShiftVB src (LShiftCntV shift)));
10620   size(4);
10621   ins_cost(DEFAULT_COST); // FIXME
10622   format %{
10623     "VSHL.I8 $dst.Q,$src.Q,$shift\t! logical left shift packed16B"
10624   %}
10625   ins_encode %{
10626     bool quad = true;
10627     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10628              quad);
10629   %}
10630   ins_pipe( ialu_reg_reg ); // FIXME
10631 %}
10632 
10633 // Shorts/Chars vector logical left shift
10634 instruct vsl4S_reg(vecD dst, vecD src, vecD shift) %{
10635   predicate(n->as_Vector()->length() == 4);
10636   match(Set dst (LShiftVS src shift));
10637   size(4*1);
10638   ins_cost(DEFAULT_COST*1); // FIXME
10639   expand %{
10640     vsh4S_reg(dst, src, shift);
10641   %}
10642 %}
10643 
10644 instruct vsl8S_reg(vecX dst, vecX src, vecX shift) %{
10645   predicate(n->as_Vector()->length() == 8);
10646   match(Set dst (LShiftVS src shift));
10647   size(4*1);
10648   ins_cost(DEFAULT_COST*1); // FIXME
10649   expand %{
10650     vsh8S_reg(dst, src, shift);
10651   %}
10652 %}
10653 
10654 instruct vsl4S_immI(vecD dst, vecD src, immI shift) %{
10655   predicate(n->as_Vector()->length() == 4 && assert_not_var_shift(n));
10656   match(Set dst (LShiftVS src (LShiftCntV shift)));
10657   size(4);
10658   ins_cost(DEFAULT_COST); // FIXME
10659   format %{
10660     "VSHL.I16 $dst.D,$src.D,$shift\t! logical left shift packed4S"
10661   %}
10662   ins_encode %{
10663     bool quad = false;
10664     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10665              quad);
10666   %}
10667   ins_pipe( ialu_reg_reg ); // FIXME
10668 %}
10669 
10670 instruct vsl8S_immI(vecX dst, vecX src, immI shift) %{
10671   predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n));
10672   match(Set dst (LShiftVS src shift));
10673   size(4);
10674   ins_cost(DEFAULT_COST); // FIXME
10675   format %{
10676     "VSHL.I16 $dst.Q,$src.Q,$shift\t! logical left shift packed8S"
10677   %}
10678   ins_encode %{
10679     bool quad = true;
10680     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10681              quad);
10682   %}
10683   ins_pipe( ialu_reg_reg ); // FIXME
10684 %}
10685 
10686 // Integers vector logical left shift
10687 instruct vsl2I_reg(vecD dst, vecD src, vecD shift) %{
10688   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10689   match(Set dst (LShiftVI src shift));
10690   size(4*1);
10691   ins_cost(DEFAULT_COST*1); // FIXME
10692   expand %{
10693     vsh2I_reg(dst, src, shift);
10694   %}
10695 %}
10696 
10697 instruct vsl4I_reg(vecX dst, vecX src, vecX shift) %{
10698   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10699   match(Set dst (LShiftVI src shift));
10700   size(4*1);
10701   ins_cost(DEFAULT_COST*1); // FIXME
10702   expand %{
10703     vsh4I_reg(dst, src, shift);
10704   %}
10705 %}
10706 
10707 instruct vsl2I_immI(vecD dst, vecD src, immI shift) %{
10708   predicate(n->as_Vector()->length() == 2 &&
10709             VM_Version::has_simd() &&
10710             assert_not_var_shift(n));
10711   match(Set dst (LShiftVI src (LShiftCntV shift)));
10712   size(4);
10713   ins_cost(DEFAULT_COST); // FIXME
10714   format %{
10715     "VSHL.I32 $dst.D,$src.D,$shift\t! logical left shift packed2I"
10716   %}
10717   ins_encode %{
10718     bool quad = false;
10719     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10720              quad);
10721   %}
10722   ins_pipe( ialu_reg_reg ); // FIXME
10723 %}
10724 
10725 instruct vsl4I_immI(vecX dst, vecX src, immI shift) %{
10726   predicate(n->as_Vector()->length() == 4 &&
10727             VM_Version::has_simd() &&
10728             assert_not_var_shift(n));
10729   match(Set dst (LShiftVI src (LShiftCntV shift)));
10730   size(4);
10731   ins_cost(DEFAULT_COST); // FIXME
10732   format %{
10733     "VSHL.I32 $dst.Q,$src.Q,$shift\t! logical left shift packed4I"
10734   %}
10735   ins_encode %{
10736     bool quad = true;
10737     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10738              quad);
10739   %}
10740   ins_pipe( ialu_reg_reg ); // FIXME
10741 %}
10742 
10743 // Longs vector logical left shift
10744 instruct vsl2L_reg(vecX dst, vecX src, vecX shift) %{
10745   predicate(n->as_Vector()->length() == 2);
10746   match(Set dst (LShiftVL src shift));
10747   size(4*1);
10748   ins_cost(DEFAULT_COST*1); // FIXME
10749   expand %{
10750     vsh2L_reg(dst, src, shift);
10751   %}
10752 %}
10753 
10754 instruct vsl2L_immI(vecX dst, vecX src, immI shift) %{
10755   predicate(n->as_Vector()->length() == 2 && assert_not_var_shift(n));
10756   match(Set dst (LShiftVL src (LShiftCntV shift)));
10757   size(4);
10758   ins_cost(DEFAULT_COST); // FIXME
10759   format %{
10760     "VSHL.I64 $dst.Q,$src.Q,$shift\t! logical left shift packed2L"
10761   %}
10762   ins_encode %{
10763     bool quad = true;
10764     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
10765              quad);
10766   %}
10767   ins_pipe( ialu_reg_reg ); // FIXME
10768 %}
10769 
10770 // ----------------------- LogicalRightShift -----------------------------------
10771 
10772 // Bytes/Shorts vector logical right shift produces incorrect Java result
10773 // for negative data because java code convert short value into int with
10774 // sign extension before a shift.
10775 
10776 // Right shift with vector shift count on aarch32 SIMD is implemented as left
10777 // shift by negative shift count value.
10778 //
10779 // Method is_var_shift() denotes that vector shift count is a variable shift:
10780 // 1) for this case, vector shift count should be negated before conducting
10781 //    right shifts. E.g., vsrl4S_reg_var rule.
10782 // 2) for the opposite case, vector shift count is generated via RShiftCntV
10783 //    rules and is already negated there. Hence, no negation is needed.
10784 //    E.g., vsrl4S_reg rule.
10785 
10786 // Chars vector logical right shift
10787 instruct vsrl4S_reg(vecD dst, vecD src, vecD shift) %{
10788   predicate(n->as_Vector()->length() == 4 && !n->as_ShiftV()->is_var_shift());
10789   match(Set dst (URShiftVS src shift));
10790   size(4);
10791   ins_cost(DEFAULT_COST);
10792   expand %{
10793     vsh4S_reg(dst, src, shift);
10794   %}
10795 %}
10796 
10797 instruct vsrl4S_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{
10798   predicate(n->as_Vector()->length() == 4 && n->as_ShiftV()->is_var_shift());
10799   match(Set dst (URShiftVS src shift));
10800   effect(TEMP tmp);
10801   size(4*2);
10802   ins_cost(DEFAULT_COST*2);
10803   format %{
10804     "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B"
10805     "VSHL.U16 $dst.D,$src.D,$tmp.D\t! logical right shift packed4S"
10806   %}
10807   ins_encode %{
10808     bool quad = false;
10809     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
10810              MacroAssembler::VELEM_SIZE_8, quad);
10811     __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
10812               MacroAssembler::VELEM_SIZE_16, quad);
10813   %}
10814   ins_pipe(ialu_reg_reg);
10815 %}
10816 
10817 instruct vsrl8S_reg(vecX dst, vecX src, vecX shift) %{
10818   predicate(n->as_Vector()->length() == 8 && !n->as_ShiftV()->is_var_shift());
10819   match(Set dst (URShiftVS src shift));
10820   size(4);
10821   ins_cost(DEFAULT_COST);
10822   expand %{
10823     vsh8S_reg(dst, src, shift);
10824   %}
10825 %}
10826 
10827 instruct vsrl8S_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
10828   predicate(n->as_Vector()->length() == 8 && n->as_ShiftV()->is_var_shift());
10829   match(Set dst (URShiftVS src shift));
10830   effect(TEMP tmp);
10831   size(4*2);
10832   ins_cost(DEFAULT_COST*2);
10833   format %{
10834     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
10835     "VSHL.U16 $dst.Q,$src.Q,$tmp.Q\t! logical right shift packed8S"
10836   %}
10837   ins_encode %{
10838     bool quad = true;
10839     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
10840              MacroAssembler::VELEM_SIZE_8, quad);
10841     __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
10842               MacroAssembler::VELEM_SIZE_16, quad);
10843   %}
10844   ins_pipe(ialu_reg_reg);
10845 %}
10846 
10847 instruct vsrl4S_immI(vecD dst, vecD src, immI shift) %{
10848   predicate(n->as_Vector()->length() == 4 && assert_not_var_shift(n));
10849   match(Set dst (URShiftVS src (RShiftCntV shift)));
10850   size(4);
10851   ins_cost(DEFAULT_COST); // FIXME
10852   format %{
10853     "VSHR.U16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
10854   %}
10855   ins_encode %{
10856     bool quad = false;
10857     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10858              quad);
10859   %}
10860   ins_pipe( ialu_reg_reg ); // FIXME
10861 %}
10862 
10863 instruct vsrl8S_immI(vecX dst, vecX src, immI shift) %{
10864   predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n));
10865   match(Set dst (URShiftVS src (RShiftCntV shift)));
10866   size(4);
10867   ins_cost(DEFAULT_COST); // FIXME
10868   format %{
10869     "VSHR.U16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
10870   %}
10871   ins_encode %{
10872     bool quad = true;
10873     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10874              quad);
10875   %}
10876   ins_pipe( ialu_reg_reg ); // FIXME
10877 %}
10878 
10879 // Integers vector logical right shift
10880 instruct vsrl2I_reg(vecD dst, vecD src, vecD shift) %{
10881   predicate(n->as_Vector()->length() == 2 &&
10882             VM_Version::has_simd() &&
10883             !n->as_ShiftV()->is_var_shift());
10884   match(Set dst (URShiftVI src shift));
10885   size(4);
10886   ins_cost(DEFAULT_COST);
10887   expand %{
10888     vsh2I_reg(dst, src, shift);
10889   %}
10890 %}
10891 
10892 instruct vsrl2I_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{
10893   predicate(n->as_Vector()->length() == 2 &&
10894             VM_Version::has_simd() &&
10895             n->as_ShiftV()->is_var_shift());
10896   match(Set dst (URShiftVI src shift));
10897   effect(TEMP tmp);
10898   size(4*2);
10899   ins_cost(DEFAULT_COST*2);
10900   format %{
10901     "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B"
10902     "VSHL.U32 $dst.D,$src.D,$tmp.D\t! logical right shift packed2I"
10903   %}
10904   ins_encode %{
10905     bool quad = false;
10906     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
10907              MacroAssembler::VELEM_SIZE_8, quad);
10908     __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
10909               MacroAssembler::VELEM_SIZE_32, quad);
10910   %}
10911   ins_pipe(ialu_reg_reg);
10912 %}
10913 
10914 instruct vsrl4I_reg(vecX dst, vecX src, vecX shift) %{
10915   predicate(n->as_Vector()->length() == 4 &&
10916             VM_Version::has_simd() &&
10917             !n->as_ShiftV()->is_var_shift());
10918   match(Set dst (URShiftVI src shift));
10919   size(4);
10920   ins_cost(DEFAULT_COST);
10921   expand %{
10922     vsh4I_reg(dst, src, shift);
10923   %}
10924 %}
10925 
10926 instruct vsrl4I_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
10927   predicate(n->as_Vector()->length() == 4 &&
10928             VM_Version::has_simd() &&
10929             n->as_ShiftV()->is_var_shift());
10930   match(Set dst (URShiftVI src shift));
10931   effect(TEMP tmp);
10932   size(4*2);
10933   ins_cost(DEFAULT_COST*2);
10934   format %{
10935     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
10936     "VSHL.U32 $dst.Q,$src.Q,$tmp.Q\t! logical right shift packed4I"
10937   %}
10938   ins_encode %{
10939     bool quad = true;
10940     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
10941              MacroAssembler::VELEM_SIZE_8, quad);
10942     __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
10943               MacroAssembler::VELEM_SIZE_32, quad);
10944   %}
10945   ins_pipe(ialu_reg_reg);
10946 %}
10947 
10948 instruct vsrl2I_immI(vecD dst, vecD src, immI shift) %{
10949   predicate(n->as_Vector()->length() == 2 &&
10950             VM_Version::has_simd() &&
10951             assert_not_var_shift(n));
10952   match(Set dst (URShiftVI src (RShiftCntV shift)));
10953   size(4);
10954   ins_cost(DEFAULT_COST); // FIXME
10955   format %{
10956     "VSHR.U32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
10957   %}
10958   ins_encode %{
10959     bool quad = false;
10960     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10961              quad);
10962   %}
10963   ins_pipe( ialu_reg_reg ); // FIXME
10964 %}
10965 
10966 instruct vsrl4I_immI(vecX dst, vecX src, immI shift) %{
10967   predicate(n->as_Vector()->length() == 4 &&
10968             VM_Version::has_simd() &&
10969             assert_not_var_shift(n));
10970   match(Set dst (URShiftVI src (RShiftCntV shift)));
10971   size(4);
10972   ins_cost(DEFAULT_COST); // FIXME
10973   format %{
10974     "VSHR.U32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
10975   %}
10976   ins_encode %{
10977     bool quad = true;
10978     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10979              quad);
10980   %}
10981   ins_pipe( ialu_reg_reg ); // FIXME
10982 %}
10983 
10984 // Longs vector logical right shift
10985 instruct vsrl2L_reg(vecX dst, vecX src, vecX shift) %{
10986   predicate(n->as_Vector()->length() == 2 && !n->as_ShiftV()->is_var_shift());
10987   match(Set dst (URShiftVL src shift));
10988   size(4);
10989   ins_cost(DEFAULT_COST);
10990   expand %{
10991     vsh2L_reg(dst, src, shift);
10992   %}
10993 %}
10994 
10995 instruct vsrl2L_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
10996   predicate(n->as_Vector()->length() == 2 && n->as_ShiftV()->is_var_shift());
10997   match(Set dst (URShiftVL src shift));
10998   effect(TEMP tmp, DEF dst, USE src, USE shift);
10999   size(4*2);
11000   ins_cost(DEFAULT_COST*2);
11001   format %{
11002     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
11003     "VSHL.U64 $dst.Q,$src.Q,$tmp.Q\t! logical right shift packed2L"
11004   %}
11005   ins_encode %{
11006     bool quad = true;
11007     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11008              MacroAssembler::VELEM_SIZE_8, quad);
11009     __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11010               MacroAssembler::VELEM_SIZE_64, quad);
11011   %}
11012   ins_pipe(ialu_reg_reg);
11013 %}
11014 
11015 instruct vsrl2L_immI(vecX dst, vecX src, immI shift) %{
11016   predicate(n->as_Vector()->length() == 2 && assert_not_var_shift(n));
11017   match(Set dst (URShiftVL src (RShiftCntV shift)));
11018   size(4);
11019   ins_cost(DEFAULT_COST); // FIXME
11020   format %{
11021     "VSHR.U64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
11022   %}
11023   ins_encode %{
11024     bool quad = true;
11025     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
11026              quad);
11027   %}
11028   ins_pipe( ialu_reg_reg ); // FIXME
11029 %}
11030 
11031 // ------------------- ArithmeticRightShift -----------------------------------
11032 
11033 // Bytes vector arithmetic left/right shift based on sign
11034 instruct vsha8B_reg(vecD dst, vecD src, vecD shift) %{
11035   predicate(n->as_Vector()->length() == 8);
11036   effect(DEF dst, USE src, USE shift);
11037   size(4);
11038   ins_cost(DEFAULT_COST); // FIXME
11039   format %{
11040     "VSHL.S8 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed8B"
11041   %}
11042   ins_encode %{
11043     bool quad = false;
11044     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11045               MacroAssembler::VELEM_SIZE_8, quad);
11046   %}
11047   ins_pipe( ialu_reg_reg ); // FIXME
11048 %}
11049 
11050 instruct vsha16B_reg(vecX dst, vecX src, vecX shift) %{
11051   predicate(n->as_Vector()->length() == 16);
11052   effect(DEF dst, USE src, USE shift);
11053   size(4);
11054   ins_cost(DEFAULT_COST); // FIXME
11055   format %{
11056     "VSHL.S8 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed16B"
11057   %}
11058   ins_encode %{
11059     bool quad = true;
11060     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11061               MacroAssembler::VELEM_SIZE_8, quad);
11062   %}
11063   ins_pipe( ialu_reg_reg ); // FIXME
11064 %}
11065 
11066 // Shorts vector arithmetic left/right shift based on sign
11067 instruct vsha4S_reg(vecD dst, vecD src, vecD shift) %{
11068   predicate(n->as_Vector()->length() == 4);
11069   effect(DEF dst, USE src, USE shift);
11070   size(4);
11071   ins_cost(DEFAULT_COST); // FIXME
11072   format %{
11073     "VSHL.S16 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed4S"
11074   %}
11075   ins_encode %{
11076     bool quad = false;
11077     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11078               MacroAssembler::VELEM_SIZE_16, quad);
11079   %}
11080   ins_pipe( ialu_reg_reg ); // FIXME
11081 %}
11082 
11083 instruct vsha8S_reg(vecX dst, vecX src, vecX shift) %{
11084   predicate(n->as_Vector()->length() == 8);
11085   effect(DEF dst, USE src, USE shift);
11086   size(4);
11087   ins_cost(DEFAULT_COST); // FIXME
11088   format %{
11089     "VSHL.S16 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed8S"
11090   %}
11091   ins_encode %{
11092     bool quad = true;
11093     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11094               MacroAssembler::VELEM_SIZE_16, quad);
11095   %}
11096   ins_pipe( ialu_reg_reg ); // FIXME
11097 %}
11098 
11099 // Integers vector arithmetic left/right shift based on sign
11100 instruct vsha2I_reg(vecD dst, vecD src, vecD shift) %{
11101   predicate(n->as_Vector()->length() == 2);
11102   effect(DEF dst, USE src, USE shift);
11103   size(4);
11104   ins_cost(DEFAULT_COST); // FIXME
11105   format %{
11106     "VSHL.S32 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed2I"
11107   %}
11108   ins_encode %{
11109     bool quad = false;
11110     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11111               MacroAssembler::VELEM_SIZE_32, quad);
11112   %}
11113   ins_pipe( ialu_reg_reg ); // FIXME
11114 %}
11115 
11116 instruct vsha4I_reg(vecX dst, vecX src, vecX shift) %{
11117   predicate(n->as_Vector()->length() == 4);
11118   effect(DEF dst, USE src, USE shift);
11119   size(4);
11120   ins_cost(DEFAULT_COST); // FIXME
11121   format %{
11122     "VSHL.S32 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed4I"
11123   %}
11124   ins_encode %{
11125     bool quad = true;
11126     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11127               MacroAssembler::VELEM_SIZE_32, quad);
11128   %}
11129   ins_pipe( ialu_reg_reg ); // FIXME
11130 %}
11131 
11132 // Longs vector arithmetic left/right shift based on sign
11133 instruct vsha2L_reg(vecX dst, vecX src, vecX shift) %{
11134   predicate(n->as_Vector()->length() == 2);
11135   effect(DEF dst, USE src, USE shift);
11136   size(4);
11137   ins_cost(DEFAULT_COST); // FIXME
11138   format %{
11139     "VSHL.S64 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed2L"
11140   %}
11141   ins_encode %{
11142     bool quad = true;
11143     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11144               MacroAssembler::VELEM_SIZE_64, quad);
11145   %}
11146   ins_pipe( ialu_reg_reg ); // FIXME
11147 %}
11148 
11149 // Byte vector arithmetic right shift
11150 instruct vsra8B_reg(vecD dst, vecD src, vecD shift) %{
11151   predicate(n->as_Vector()->length() == 8 && !n->as_ShiftV()->is_var_shift());
11152   match(Set dst (RShiftVB src shift));
11153   size(4);
11154   ins_cost(DEFAULT_COST); // FIXME
11155   expand %{
11156     vsha8B_reg(dst, src, shift);
11157   %}
11158 %}
11159 
11160 instruct vsra8B_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{
11161   predicate(n->as_Vector()->length() == 8 && n->as_ShiftV()->is_var_shift());
11162   match(Set dst (RShiftVB src shift));
11163   effect(TEMP tmp);
11164   size(4*2);
11165   ins_cost(DEFAULT_COST*2);
11166   format %{
11167     "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B"
11168     "VSHL.S8 $dst.D,$src.D,$tmp.D\t! arithmetic right shift packed8B"
11169   %}
11170   ins_encode %{
11171     bool quad = false;
11172     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11173              MacroAssembler::VELEM_SIZE_8, quad);
11174     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11175               MacroAssembler::VELEM_SIZE_8, quad);
11176   %}
11177   ins_pipe(ialu_reg_reg);
11178 %}
11179 
11180 instruct vsra16B_reg(vecX dst, vecX src, vecX shift) %{
11181   predicate(n->as_Vector()->length() == 16 && !n->as_ShiftV()->is_var_shift());
11182   match(Set dst (RShiftVB src shift));
11183   size(4);
11184   ins_cost(DEFAULT_COST); // FIXME
11185   expand %{
11186     vsha16B_reg(dst, src, shift);
11187   %}
11188 %}
11189 
11190 instruct vsra16B_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
11191   predicate(n->as_Vector()->length() == 16 && n->as_ShiftV()->is_var_shift());
11192   match(Set dst (RShiftVB src shift));
11193   effect(TEMP tmp);
11194   size(4*2);
11195   ins_cost(DEFAULT_COST*2);
11196   format %{
11197     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
11198     "VSHL.S8 $dst.Q,$src.Q,$tmp.Q\t! arithmetic right shift packed16B"
11199   %}
11200   ins_encode %{
11201     bool quad = true;
11202     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11203              MacroAssembler::VELEM_SIZE_8, quad);
11204     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11205               MacroAssembler::VELEM_SIZE_8, quad);
11206   %}
11207   ins_pipe(ialu_reg_reg);
11208 %}
11209 
11210 instruct vsra8B_immI(vecD dst, vecD src, immI shift) %{
11211   predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n));
11212   match(Set dst (RShiftVB src (RShiftCntV shift)));
11213   size(4);
11214   ins_cost(DEFAULT_COST); // FIXME
11215   format %{
11216     "VSHR.S8 $dst.D,$src.D,$shift\t! arithmetic right shift packed8B"
11217   %}
11218   ins_encode %{
11219     bool quad = false;
11220     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
11221              quad);
11222   %}
11223   ins_pipe( ialu_reg_reg ); // FIXME
11224 %}
11225 
11226 instruct vsra16B_immI(vecX dst, vecX src, immI shift) %{
11227   predicate(n->as_Vector()->length() == 16 && assert_not_var_shift(n));
11228   match(Set dst (RShiftVB src (RShiftCntV shift)));
11229   size(4);
11230   ins_cost(DEFAULT_COST); // FIXME
11231   format %{
11232     "VSHR.S8 $dst.Q,$src.Q,$shift\t! arithmetic right shift packed16B"
11233   %}
11234   ins_encode %{
11235     bool quad = true;
11236     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
11237              quad);
11238   %}
11239   ins_pipe( ialu_reg_reg ); // FIXME
11240 %}
11241 
11242 // Shorts vector arithmetic right shift
11243 instruct vsra4S_reg(vecD dst, vecD src, vecD shift) %{
11244   predicate(n->as_Vector()->length() == 4 && !n->as_ShiftV()->is_var_shift());
11245   match(Set dst (RShiftVS src shift));
11246   size(4);
11247   ins_cost(DEFAULT_COST); // FIXME
11248   expand %{
11249     vsha4S_reg(dst, src, shift);
11250   %}
11251 %}
11252 
11253 instruct vsra4S_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{
11254   predicate(n->as_Vector()->length() == 4 && n->as_ShiftV()->is_var_shift());
11255   match(Set dst (RShiftVS src shift));
11256   effect(TEMP tmp);
11257   size(4*2);
11258   ins_cost(DEFAULT_COST*2);
11259   format %{
11260     "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B"
11261     "VSHL.S16 $dst.D,$src.D,$tmp.D\t! arithmetic right shift packed4S"
11262   %}
11263   ins_encode %{
11264     bool quad = false;
11265     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11266              MacroAssembler::VELEM_SIZE_8, quad);
11267     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11268               MacroAssembler::VELEM_SIZE_16, quad);
11269   %}
11270   ins_pipe(ialu_reg_reg);
11271 %}
11272 
11273 instruct vsra8S_reg(vecX dst, vecX src, vecX shift) %{
11274   predicate(n->as_Vector()->length() == 8 && !n->as_ShiftV()->is_var_shift());
11275   match(Set dst (RShiftVS src shift));
11276   size(4);
11277   ins_cost(DEFAULT_COST); // FIXME
11278   expand %{
11279     vsha8S_reg(dst, src, shift);
11280   %}
11281 %}
11282 
11283 instruct vsra8S_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
11284   predicate(n->as_Vector()->length() == 8 && n->as_ShiftV()->is_var_shift());
11285   match(Set dst (RShiftVS src shift));
11286   effect(TEMP tmp);
11287   size(4*2);
11288   ins_cost(DEFAULT_COST*2);
11289   format %{
11290     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
11291     "VSHL.S16 $dst.Q,$src.Q,$tmp.Q\t! arithmetic right shift packed8S"
11292   %}
11293   ins_encode %{
11294     bool quad = true;
11295     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11296              MacroAssembler::VELEM_SIZE_8, quad);
11297     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11298               MacroAssembler::VELEM_SIZE_16, quad);
11299   %}
11300   ins_pipe(ialu_reg_reg);
11301 %}
11302 
11303 instruct vsra4S_immI(vecD dst, vecD src, immI shift) %{
11304   predicate(n->as_Vector()->length() == 4 && assert_not_var_shift(n));
11305   match(Set dst (RShiftVS src (RShiftCntV shift)));
11306   size(4);
11307   ins_cost(DEFAULT_COST); // FIXME
11308   format %{
11309     "VSHR.S16 $dst.D,$src.D,$shift\t! arithmetic right shift packed4S"
11310   %}
11311   ins_encode %{
11312     bool quad = false;
11313     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
11314              quad);
11315   %}
11316   ins_pipe( ialu_reg_reg ); // FIXME
11317 %}
11318 
11319 instruct vsra8S_immI(vecX dst, vecX src, immI shift) %{
11320   predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n));
11321   match(Set dst (RShiftVS src (RShiftCntV shift)));
11322   size(4);
11323   ins_cost(DEFAULT_COST); // FIXME
11324   format %{
11325     "VSHR.S16 $dst.Q,$src.Q,$shift\t! arithmetic right shift packed8S"
11326   %}
11327   ins_encode %{
11328     bool quad = true;
11329     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
11330              quad);
11331   %}
11332   ins_pipe( ialu_reg_reg ); // FIXME
11333 %}
11334 
11335 // Integers vector arithmetic right shift
11336 instruct vsra2I_reg(vecD dst, vecD src, vecD shift) %{
11337   predicate(n->as_Vector()->length() == 2 && !n->as_ShiftV()->is_var_shift());
11338   match(Set dst (RShiftVI src shift));
11339   size(4);
11340   ins_cost(DEFAULT_COST); // FIXME
11341   expand %{
11342     vsha2I_reg(dst, src, shift);
11343   %}
11344 %}
11345 
11346 instruct vsra2I_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{
11347   predicate(n->as_Vector()->length() == 2 && n->as_ShiftV()->is_var_shift());
11348   match(Set dst (RShiftVI src shift));
11349   effect(TEMP tmp);
11350   size(4*2);
11351   ins_cost(DEFAULT_COST*2);
11352   format %{
11353     "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B"
11354     "VSHL.S32 $dst.D,$src.D,$tmp.D\t! arithmetic right shift packed2I"
11355   %}
11356   ins_encode %{
11357     bool quad = false;
11358     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11359              MacroAssembler::VELEM_SIZE_8, quad);
11360     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11361               MacroAssembler::VELEM_SIZE_32, quad);
11362   %}
11363   ins_pipe(ialu_reg_reg);
11364 %}
11365 
11366 instruct vsra4I_reg(vecX dst, vecX src, vecX shift) %{
11367   predicate(n->as_Vector()->length() == 4 && !n->as_ShiftV()->is_var_shift());
11368   match(Set dst (RShiftVI src shift));
11369   size(4);
11370   ins_cost(DEFAULT_COST); // FIXME
11371   expand %{
11372     vsha4I_reg(dst, src, shift);
11373   %}
11374 %}
11375 
11376 instruct vsra4I_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
11377   predicate(n->as_Vector()->length() == 4 && n->as_ShiftV()->is_var_shift());
11378   match(Set dst (RShiftVI src shift));
11379   effect(TEMP tmp);
11380   size(4*2);
11381   ins_cost(DEFAULT_COST*2);
11382   format %{
11383     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
11384     "VSHL.S32 $dst.Q,$src.Q,$tmp.Q\t! arithmetic right shift packed4I"
11385   %}
11386   ins_encode %{
11387     bool quad = true;
11388     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11389              MacroAssembler::VELEM_SIZE_8, quad);
11390     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11391               MacroAssembler::VELEM_SIZE_32, quad);
11392   %}
11393   ins_pipe(ialu_reg_reg);
11394 %}
11395 
11396 instruct vsra2I_immI(vecD dst, vecD src, immI shift) %{
11397   predicate(n->as_Vector()->length() == 2 && assert_not_var_shift(n));
11398   match(Set dst (RShiftVI src (RShiftCntV shift)));
11399   size(4);
11400   ins_cost(DEFAULT_COST); // FIXME
11401   format %{
11402     "VSHR.S32 $dst.D,$src.D,$shift\t! arithmetic right shift packed2I"
11403   %}
11404   ins_encode %{
11405     bool quad = false;
11406     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11407              quad);
11408   %}
11409   ins_pipe( ialu_reg_reg ); // FIXME
11410 %}
11411 
11412 instruct vsra4I_immI(vecX dst, vecX src, immI shift) %{
11413   predicate(n->as_Vector()->length() == 4 && assert_not_var_shift(n));
11414   match(Set dst (RShiftVI src (RShiftCntV shift)));
11415   size(4);
11416   ins_cost(DEFAULT_COST); // FIXME
11417   format %{
11418     "VSHR.S32 $dst.Q,$src.Q,$shift\t! arithmetic right shift packed4I"
11419   %}
11420   ins_encode %{
11421     bool quad = true;
11422     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11423              quad);
11424   %}
11425   ins_pipe( ialu_reg_reg ); // FIXME
11426 %}
11427 
11428 // Longs vector arithmetic right shift
11429 instruct vsra2L_reg(vecX dst, vecX src, vecX shift) %{
11430   predicate(n->as_Vector()->length() == 2 && !n->as_ShiftV()->is_var_shift());
11431   match(Set dst (RShiftVL src shift));
11432   size(4);
11433   ins_cost(DEFAULT_COST); // FIXME
11434   expand %{
11435     vsha2L_reg(dst, src, shift);
11436   %}
11437 %}
11438 
11439 instruct vsra2L_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
11440   predicate(n->as_Vector()->length() == 2 && n->as_ShiftV()->is_var_shift());
11441   match(Set dst (RShiftVL src shift));
11442   effect(TEMP tmp);
11443   size(4*2);
11444   ins_cost(DEFAULT_COST*2);
11445   format %{
11446     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
11447     "VSHL.S64 $dst.Q,$src.Q,$tmp.Q\t! arithmetic right shift packed2L"
11448   %}
11449   ins_encode %{
11450     bool quad = true;
11451     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11452              MacroAssembler::VELEM_SIZE_8, quad);
11453     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11454               MacroAssembler::VELEM_SIZE_64, quad);
11455   %}
11456   ins_pipe(ialu_reg_reg);
11457 %}
11458 
11459 instruct vsra2L_immI(vecX dst, vecX src, immI shift) %{
11460   predicate(n->as_Vector()->length() == 2 && assert_not_var_shift(n));
11461   match(Set dst (RShiftVL src (RShiftCntV shift)));
11462   size(4);
11463   ins_cost(DEFAULT_COST); // FIXME
11464   format %{
11465     "VSHR.S64 $dst.Q,$src.Q,$shift\t! arithmetic right shift packed2L"
11466   %}
11467   ins_encode %{
11468     bool quad = true;
11469     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
11470              quad);
11471   %}
11472   ins_pipe( ialu_reg_reg ); // FIXME
11473 %}
11474 
11475 // --------------------------------- AND --------------------------------------
11476 
11477 instruct vandD(vecD dst, vecD src1, vecD src2) %{
11478   predicate(n->as_Vector()->length_in_bytes() == 8);
11479   match(Set dst (AndV src1 src2));
11480   format %{ "VAND    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11481   ins_encode %{
11482     bool quad = false;
11483     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11484              quad);
11485   %}
11486   ins_pipe( ialu_reg_reg ); // FIXME
11487 %}
11488 
11489 instruct vandX(vecX dst, vecX src1, vecX src2) %{
11490   predicate(n->as_Vector()->length_in_bytes() == 16);
11491   match(Set dst (AndV src1 src2));
11492   format %{ "VAND    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11493   ins_encode %{
11494     bool quad = true;
11495     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11496              quad);
11497   %}
11498   ins_pipe( ialu_reg_reg ); // FIXME
11499 %}
11500 
11501 // --------------------------------- OR ---------------------------------------
11502 
11503 instruct vorD(vecD dst, vecD src1, vecD src2) %{
11504   predicate(n->as_Vector()->length_in_bytes() == 8);
11505   match(Set dst (OrV src1 src2));
11506   format %{ "VOR     $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11507   ins_encode %{
11508     bool quad = false;
11509     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11510             quad);
11511   %}
11512   ins_pipe( ialu_reg_reg ); // FIXME
11513 %}
11514 
11515 instruct vorX(vecX dst, vecX src1, vecX src2) %{
11516   predicate(n->as_Vector()->length_in_bytes() == 16);
11517   match(Set dst (OrV src1 src2));
11518   format %{ "VOR     $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11519   ins_encode %{
11520     bool quad = true;
11521     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11522             quad);
11523   %}
11524   ins_pipe( ialu_reg_reg ); // FIXME
11525 %}
11526 
11527 // --------------------------------- XOR --------------------------------------
11528 
11529 instruct vxorD(vecD dst, vecD src1, vecD src2) %{
11530   predicate(n->as_Vector()->length_in_bytes() == 8);
11531   match(Set dst (XorV src1 src2));
11532   format %{ "VXOR    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11533   ins_encode %{
11534     bool quad = false;
11535     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11536              quad);
11537   %}
11538   ins_pipe( ialu_reg_reg ); // FIXME
11539 %}
11540 
11541 instruct vxorX(vecX dst, vecX src1, vecX src2) %{
11542   predicate(n->as_Vector()->length_in_bytes() == 16);
11543   match(Set dst (XorV src1 src2));
11544   format %{ "VXOR    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11545   ins_encode %{
11546     bool quad = true;
11547     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11548              quad);
11549   %}
11550   ins_pipe( ialu_reg_reg ); // FIXME
11551 %}
11552 
11553 
11554 //----------PEEPHOLE RULES-----------------------------------------------------
11555 // These must follow all instruction definitions as they use the names
11556 // defined in the instructions definitions.
11557 //
11558 // peepmatch ( root_instr_name [preceding_instruction]* );
11559 //
11560 // peepconstraint %{
11561 // (instruction_number.operand_name relational_op instruction_number.operand_name
11562 //  [, ...] );
11563 // // instruction numbers are zero-based using left to right order in peepmatch
11564 //
11565 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
11566 // // provide an instruction_number.operand_name for each operand that appears
11567 // // in the replacement instruction's match rule
11568 //
11569 // ---------VM FLAGS---------------------------------------------------------
11570 //
11571 // All peephole optimizations can be turned off using -XX:-OptoPeephole
11572 //
11573 // Each peephole rule is given an identifying number starting with zero and
11574 // increasing by one in the order seen by the parser.  An individual peephole
11575 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
11576 // on the command-line.
11577 //
11578 // ---------CURRENT LIMITATIONS----------------------------------------------
11579 //
11580 // Only match adjacent instructions in same basic block
11581 // Only equality constraints
11582 // Only constraints between operands, not (0.dest_reg == EAX_enc)
11583 // Only one replacement instruction
11584 //
11585 // ---------EXAMPLE----------------------------------------------------------
11586 //
11587 // // pertinent parts of existing instructions in architecture description
11588 // instruct movI(eRegI dst, eRegI src) %{
11589 //   match(Set dst (CopyI src));
11590 // %}
11591 //
11592 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
11593 //   match(Set dst (AddI dst src));
11594 //   effect(KILL cr);
11595 // %}
11596 //
11597 // // Change (inc mov) to lea
11598 // peephole %{
11599 //   // increment preceded by register-register move
11600 //   peepmatch ( incI_eReg movI );
11601 //   // require that the destination register of the increment
11602 //   // match the destination register of the move
11603 //   peepconstraint ( 0.dst == 1.dst );
11604 //   // construct a replacement instruction that sets
11605 //   // the destination to ( move's source register + one )
11606 //   peepreplace ( incI_eReg_immI1( 0.dst 1.src 0.src ) );
11607 // %}
11608 //
11609 
11610 // // Change load of spilled value to only a spill
11611 // instruct storeI(memory mem, eRegI src) %{
11612 //   match(Set mem (StoreI mem src));
11613 // %}
11614 //
11615 // instruct loadI(eRegI dst, memory mem) %{
11616 //   match(Set dst (LoadI mem));
11617 // %}
11618 //
11619 // peephole %{
11620 //   peepmatch ( loadI storeI );
11621 //   peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
11622 //   peepreplace ( storeI( 1.mem 1.mem 1.src ) );
11623 // %}
11624 
11625 //----------SMARTSPILL RULES---------------------------------------------------
11626 // These must follow all instruction definitions as they use the names
11627 // defined in the instructions definitions.
11628 //
11629 // ARM will probably not have any of these rules due to RISC instruction set.
11630 
11631 //----------PIPELINE-----------------------------------------------------------
11632 // Rules which define the behavior of the target architectures pipeline.