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 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
  343   return MachNode::size(ra_);
  344 }
  345 
  346 int MachPrologNode::reloc() const {
  347   return 10; // a large enough number
  348 }
  349 
  350 //=============================================================================
  351 #ifndef PRODUCT
  352 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  353   Compile* C = ra_->C;
  354 
  355   size_t framesize = C->output()->frame_size_in_bytes();
  356   framesize -= 2*wordSize;
  357 
  358   if (framesize != 0) {
  359     st->print("ADD    R_SP, R_SP, %zu\n\t",framesize);
  360   }
  361   st->print("POP    R_FP|R_LR_LR");
  362 
  363   if (do_polling() && ra_->C->is_method_compilation()) {
  364     st->print("\n\t");
  365     st->print("MOV    Rtemp, #PollAddr\t! Load Polling address\n\t");
  366     st->print("LDR    Rtemp,[Rtemp]\t!Poll for Safepointing");
  367   }
  368 }
  369 #endif
  370 
  371 void MachEpilogNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
  372   Compile* C = ra_->C;
  373 
  374   size_t framesize = C->output()->frame_size_in_bytes();
  375   framesize -= 2*wordSize;
  376   if (framesize != 0) {
  377     __ add_slow(SP, SP, framesize);
  378   }
  379   __ raw_pop(FP, LR);
  380 
  381   // If this does safepoint polling, then do it here
  382   if (do_polling() && ra_->C->is_method_compilation()) {
  383     __ read_polling_page(Rtemp, relocInfo::poll_return_type);
  384   }
  385 }
  386 
  387 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
  388   return MachNode::size(ra_);
  389 }
  390 
  391 int MachEpilogNode::reloc() const {
  392   return 16; // a large enough number
  393 }
  394 
  395 const Pipeline * MachEpilogNode::pipeline() const {
  396   return MachNode::pipeline_class();
  397 }
  398 
  399 //=============================================================================
  400 
  401 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
  402 enum RC { rc_bad, rc_int, rc_float, rc_stack };
  403 static enum RC rc_class( OptoReg::Name reg ) {
  404   if (!OptoReg::is_valid(reg)) return rc_bad;
  405   if (OptoReg::is_stack(reg)) return rc_stack;
  406   VMReg r = OptoReg::as_VMReg(reg);
  407   if (r->is_Register()) return rc_int;
  408   assert(r->is_FloatRegister(), "must be");
  409   return rc_float;
  410 }
  411 
  412 static inline bool is_iRegLd_memhd(OptoReg::Name src_first, OptoReg::Name src_second, int offset) {
  413   int rlo = Matcher::_regEncode[src_first];
  414   int rhi = Matcher::_regEncode[src_second];
  415   if (!((rlo&1)==0 && (rlo+1 == rhi))) {
  416     tty->print_cr("CAUGHT BAD LDRD/STRD");
  417   }
  418   return (rlo&1)==0 && (rlo+1 == rhi) && is_memoryHD(offset);
  419 }
  420 
  421 uint MachSpillCopyNode::implementation( C2_MacroAssembler *masm,
  422                                         PhaseRegAlloc *ra_,
  423                                         bool do_size,
  424                                         outputStream* st ) const {
  425   // Get registers to move
  426   OptoReg::Name src_second = ra_->get_reg_second(in(1));
  427   OptoReg::Name src_first = ra_->get_reg_first(in(1));
  428   OptoReg::Name dst_second = ra_->get_reg_second(this );
  429   OptoReg::Name dst_first = ra_->get_reg_first(this );
  430 
  431   enum RC src_second_rc = rc_class(src_second);
  432   enum RC src_first_rc = rc_class(src_first);
  433   enum RC dst_second_rc = rc_class(dst_second);
  434   enum RC dst_first_rc = rc_class(dst_first);
  435 
  436   assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
  437 
  438   // Generate spill code!
  439   int size = 0;
  440 
  441   if (src_first == dst_first && src_second == dst_second)
  442     return size;            // Self copy, no move
  443 
  444 #ifdef TODO
  445   if (bottom_type()->isa_vect() != nullptr) {
  446   }
  447 #endif
  448 
  449   // Shared code does not expect instruction set capability based bailouts here.
  450   // Handle offset unreachable bailout with minimal change in shared code.
  451   // Bailout only for real instruction emit.
  452   // This requires a single comment change in shared code. ( see output.cpp "Normal" instruction case )
  453 
  454   // --------------------------------------
  455   // Check for mem-mem move.  Load into unused float registers and fall into
  456   // the float-store case.
  457   if (src_first_rc == rc_stack && dst_first_rc == rc_stack) {
  458     int offset = ra_->reg2offset(src_first);
  459     if (masm && !is_memoryfp(offset)) {
  460       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  461       return 0;
  462     } else {
  463       if (src_second_rc != rc_bad) {
  464         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
  465         src_first     = OptoReg::Name(R_mem_copy_lo_num);
  466         src_second    = OptoReg::Name(R_mem_copy_hi_num);
  467         src_first_rc  = rc_float;
  468         src_second_rc = rc_float;
  469         if (masm) {
  470           __ ldr_double(Rmemcopy, Address(SP, offset));
  471         } else if (!do_size) {
  472           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  473         }
  474       } else {
  475         src_first     = OptoReg::Name(R_mem_copy_lo_num);
  476         src_first_rc  = rc_float;
  477         if (masm) {
  478           __ ldr_float(Rmemcopy, Address(SP, offset));
  479         } else if (!do_size) {
  480           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  481         }
  482       }
  483       size += 4;
  484     }
  485   }
  486 
  487   if (src_second_rc == rc_stack && dst_second_rc == rc_stack) {
  488     Unimplemented();
  489   }
  490 
  491   // --------------------------------------
  492   // Check for integer reg-reg copy
  493   if (src_first_rc == rc_int && dst_first_rc == rc_int) {
  494     // Else normal reg-reg copy
  495     assert( src_second != dst_first, "smashed second before evacuating it" );
  496     if (masm) {
  497       __ mov(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
  498 #ifndef PRODUCT
  499     } else if (!do_size) {
  500       st->print("MOV    R_%s, R_%s\t# spill",
  501                 Matcher::regName[dst_first],
  502                 Matcher::regName[src_first]);
  503 #endif
  504     }
  505     size += 4;
  506   }
  507 
  508   // Check for integer store
  509   if (src_first_rc == rc_int && dst_first_rc == rc_stack) {
  510     int offset = ra_->reg2offset(dst_first);
  511     if (masm && !is_memoryI(offset)) {
  512       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  513       return 0;
  514     } else {
  515       if (src_second_rc != rc_bad && is_iRegLd_memhd(src_first, src_second, offset)) {
  516         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
  517         if (masm) {
  518           __ str_64(reg_to_register_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  519 #ifndef PRODUCT
  520         } else if (!do_size) {
  521           if (size != 0) st->print("\n\t");
  522           st->print(STR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
  523 #endif
  524         }
  525         return size + 4;
  526       } else {
  527         if (masm) {
  528           __ str_32(reg_to_register_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  529 #ifndef PRODUCT
  530         } else if (!do_size) {
  531           if (size != 0) st->print("\n\t");
  532           st->print(STR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
  533 #endif
  534         }
  535       }
  536     }
  537     size += 4;
  538   }
  539 
  540   // Check for integer load
  541   if (dst_first_rc == rc_int && src_first_rc == rc_stack) {
  542     int offset = ra_->reg2offset(src_first);
  543     if (masm && !is_memoryI(offset)) {
  544       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  545       return 0;
  546     } else {
  547       if (src_second_rc != rc_bad && is_iRegLd_memhd(dst_first, dst_second, offset)) {
  548         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
  549         if (masm) {
  550           __ ldr_64(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  551 #ifndef PRODUCT
  552         } else if (!do_size) {
  553           if (size != 0) st->print("\n\t");
  554           st->print(LDR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
  555 #endif
  556         }
  557         return size + 4;
  558       } else {
  559         if (masm) {
  560           __ ldr_32(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  561 #ifndef PRODUCT
  562         } else if (!do_size) {
  563           if (size != 0) st->print("\n\t");
  564           st->print(LDR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
  565 #endif
  566         }
  567       }
  568     }
  569     size += 4;
  570   }
  571 
  572   // Check for float reg-reg copy
  573   if (src_first_rc == rc_float && dst_first_rc == rc_float) {
  574     if (src_second_rc != rc_bad) {
  575       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");
  576       if (masm) {
  577       __ mov_double(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
  578 #ifndef PRODUCT
  579       } else if (!do_size) {
  580         st->print(MOV_DOUBLE "    R_%s, R_%s\t# spill",
  581                   Matcher::regName[dst_first],
  582                   Matcher::regName[src_first]);
  583 #endif
  584       }
  585       return 4;
  586     }
  587     if (masm) {
  588       __ mov_float(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
  589 #ifndef PRODUCT
  590     } else if (!do_size) {
  591       st->print(MOV_FLOAT "    R_%s, R_%s\t# spill",
  592                 Matcher::regName[dst_first],
  593                 Matcher::regName[src_first]);
  594 #endif
  595     }
  596     size = 4;
  597   }
  598 
  599   // Check for float store
  600   if (src_first_rc == rc_float && dst_first_rc == rc_stack) {
  601     int offset = ra_->reg2offset(dst_first);
  602     if (masm && !is_memoryfp(offset)) {
  603       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  604       return 0;
  605     } else {
  606       // Further check for aligned-adjacent pair, so we can use a double store
  607       if (src_second_rc != rc_bad) {
  608         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");
  609         if (masm) {
  610           __ str_double(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  611 #ifndef PRODUCT
  612         } else if (!do_size) {
  613           if (size != 0) st->print("\n\t");
  614           st->print(STR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  615 #endif
  616         }
  617         return size + 4;
  618       } else {
  619         if (masm) {
  620           __ str_float(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  621 #ifndef PRODUCT
  622         } else if (!do_size) {
  623           if (size != 0) st->print("\n\t");
  624           st->print(STR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  625 #endif
  626         }
  627       }
  628     }
  629     size += 4;
  630   }
  631 
  632   // Check for float load
  633   if (dst_first_rc == rc_float && src_first_rc == rc_stack) {
  634     int offset = ra_->reg2offset(src_first);
  635     if (masm && !is_memoryfp(offset)) {
  636       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  637       return 0;
  638     } else {
  639       // Further check for aligned-adjacent pair, so we can use a double store
  640       if (src_second_rc != rc_bad) {
  641         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");
  642         if (masm) {
  643           __ ldr_double(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  644 #ifndef PRODUCT
  645         } else if (!do_size) {
  646           if (size != 0) st->print("\n\t");
  647           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
  648 #endif
  649         }
  650         return size + 4;
  651       } else {
  652         if (masm) {
  653           __ ldr_float(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  654 #ifndef PRODUCT
  655         } else if (!do_size) {
  656           if (size != 0) st->print("\n\t");
  657           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
  658 #endif
  659         }
  660       }
  661     }
  662     size += 4;
  663   }
  664 
  665   // check for int reg -> float reg move
  666   if (src_first_rc == rc_int && dst_first_rc == rc_float) {
  667     // Further check for aligned-adjacent pair, so we can use a single instruction
  668     if (src_second_rc != rc_bad) {
  669       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
  670       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
  671       assert(src_second_rc == rc_int && dst_second_rc == rc_float, "unsupported");
  672       if (masm) {
  673         __ 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]));
  674 #ifndef PRODUCT
  675       } else if (!do_size) {
  676         if (size != 0) st->print("\n\t");
  677         st->print("FMDRR   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first), OptoReg::regname(src_second));
  678 #endif
  679       }
  680       return size + 4;
  681     } else {
  682       if (masm) {
  683         __ fmsr(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
  684 #ifndef PRODUCT
  685       } else if (!do_size) {
  686         if (size != 0) st->print("\n\t");
  687         st->print(FMSR "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
  688 #endif
  689       }
  690       size += 4;
  691     }
  692   }
  693 
  694   // check for float reg -> int reg move
  695   if (src_first_rc == rc_float && dst_first_rc == rc_int) {
  696     // Further check for aligned-adjacent pair, so we can use a single instruction
  697     if (src_second_rc != rc_bad) {
  698       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
  699       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
  700       assert(src_second_rc == rc_float && dst_second_rc == rc_int, "unsupported");
  701       if (masm) {
  702         __ 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]));
  703 #ifndef PRODUCT
  704       } else if (!do_size) {
  705         if (size != 0) st->print("\n\t");
  706         st->print("FMRRD   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(dst_second), OptoReg::regname(src_first));
  707 #endif
  708       }
  709       return size + 4;
  710     } else {
  711       if (masm) {
  712         __ fmrs(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
  713 #ifndef PRODUCT
  714       } else if (!do_size) {
  715         if (size != 0) st->print("\n\t");
  716         st->print(FMRS "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
  717 #endif
  718       }
  719       size += 4;
  720     }
  721   }
  722 
  723   // --------------------------------------------------------------------
  724   // Check for hi bits still needing moving.  Only happens for misaligned
  725   // arguments to native calls.
  726   if (src_second == dst_second)
  727     return size;               // Self copy; no move
  728   assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" );
  729 
  730   // Check for integer reg-reg copy.  Hi bits are stuck up in the top
  731   // 32-bits of a 64-bit register, but are needed in low bits of another
  732   // register (else it's a hi-bits-to-hi-bits copy which should have
  733   // happened already as part of a 64-bit move)
  734   if (src_second_rc == rc_int && dst_second_rc == rc_int) {
  735     if (masm) {
  736       __ mov(reg_to_register_object(Matcher::_regEncode[dst_second]), reg_to_register_object(Matcher::_regEncode[src_second]));
  737 #ifndef PRODUCT
  738     } else if (!do_size) {
  739       if (size != 0) st->print("\n\t");
  740       st->print("MOV    R_%s, R_%s\t# spill high",
  741                 Matcher::regName[dst_second],
  742                 Matcher::regName[src_second]);
  743 #endif
  744     }
  745     return size+4;
  746   }
  747 
  748   // Check for high word integer store
  749   if (src_second_rc == rc_int && dst_second_rc == rc_stack) {
  750     int offset = ra_->reg2offset(dst_second);
  751 
  752     if (masm && !is_memoryP(offset)) {
  753       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  754       return 0;
  755     } else {
  756       if (masm) {
  757         __ str(reg_to_register_object(Matcher::_regEncode[src_second]), Address(SP, offset));
  758 #ifndef PRODUCT
  759       } else if (!do_size) {
  760         if (size != 0) st->print("\n\t");
  761         st->print("STR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_second), offset);
  762 #endif
  763       }
  764     }
  765     return size + 4;
  766   }
  767 
  768   // Check for high word integer load
  769   if (dst_second_rc == rc_int && src_second_rc == rc_stack) {
  770     int offset = ra_->reg2offset(src_second);
  771     if (masm && !is_memoryP(offset)) {
  772       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  773       return 0;
  774     } else {
  775       if (masm) {
  776         __ ldr(reg_to_register_object(Matcher::_regEncode[dst_second]), Address(SP, offset));
  777 #ifndef PRODUCT
  778       } else if (!do_size) {
  779         if (size != 0) st->print("\n\t");
  780         st->print("LDR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_second), offset);
  781 #endif
  782       }
  783     }
  784     return size + 4;
  785   }
  786 
  787   Unimplemented();
  788   return 0; // Mute compiler
  789 }
  790 
  791 #ifndef PRODUCT
  792 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  793   implementation( nullptr, ra_, false, st );
  794 }
  795 #endif
  796 
  797 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
  798   implementation( masm, ra_, false, nullptr );
  799 }
  800 
  801 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
  802   return implementation( nullptr, ra_, true, nullptr );
  803 }
  804 
  805 //=============================================================================
  806 #ifndef PRODUCT
  807 void MachNopNode::format( PhaseRegAlloc *, outputStream *st ) const {
  808   st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
  809 }
  810 #endif
  811 
  812 void MachNopNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc * ) const {
  813   for(int i = 0; i < _count; i += 1) {
  814     __ nop();
  815   }
  816 }
  817 
  818 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
  819   return 4 * _count;
  820 }
  821 
  822 
  823 //=============================================================================
  824 #ifndef PRODUCT
  825 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  826   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  827   int reg = ra_->get_reg_first(this);
  828   st->print("ADD    %s,R_SP+#%d",Matcher::regName[reg], offset);
  829 }
  830 #endif
  831 
  832 void BoxLockNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
  833   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  834   int reg = ra_->get_encode(this);
  835   Register dst = reg_to_register_object(reg);
  836 
  837   if (is_aimm(offset)) {
  838     __ add(dst, SP, offset);
  839   } else {
  840     __ mov_slow(dst, offset);
  841     __ add(dst, SP, dst);
  842   }
  843 }
  844 
  845 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
  846   // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_)
  847   assert(ra_ == ra_->C->regalloc(), "sanity");
  848   return ra_->C->output()->scratch_emit_size(this);
  849 }
  850 
  851 //=============================================================================
  852 #ifndef PRODUCT
  853 #define R_RTEMP "R_R12"
  854 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  855   st->print_cr("\nUEP:");
  856   st->print_cr("\tLDR   " R_RTEMP ",[R_R0 + oopDesc::klass_offset_in_bytes]\t! Inline cache check");
  857   st->print_cr("\tCMP   " R_RTEMP ",R_R8" );
  858   st->print   ("\tB.NE  SharedRuntime::handle_ic_miss_stub");
  859 }
  860 #endif
  861 
  862 void MachUEPNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
  863   __ ic_check(InteriorEntryAlignment);
  864 }
  865 
  866 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
  867   return MachNode::size(ra_);
  868 }
  869 
  870 
  871 //=============================================================================
  872 
  873 int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm) {
  874   // Can't use any of the current frame's registers as we may have deopted
  875   // at a poll and everything can be live.
  876   address base = __ start_a_stub(size_deopt_handler());
  877   if (base == nullptr) {
  878     ciEnv::current()->record_failure("CodeCache is full");
  879     return 0;  // CodeBuffer::expand failed
  880   }
  881 
  882   int offset = __ offset();
  883 
  884   Label start;
  885   __ bind(start);
  886 
  887   __ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, noreg);
  888 
  889   int entry_offset = __ offset();
  890   address deopt_pc = __ pc();
  891   // Preserve R0 and reserve space for the address of the entry point
  892   __ push(RegisterSet(R0) | RegisterSet(R1));
  893   // Store the entry point address
  894   __ mov_relative_address(R0, deopt_pc);
  895   __ str(R0, Address(SP, wordSize));
  896   __ pop(R0); // restore R0
  897   __ b(start);
  898 
  899   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
  900   assert(__ offset() - entry_offset >= NativePostCallNop::first_check_size,
  901          "out of bounds read in post-call NOP check");
  902 
  903   __ end_a_stub();
  904   return entry_offset;
  905 }
  906 
  907 bool Matcher::match_rule_supported(int opcode) {
  908   if (!has_match_rule(opcode))
  909     return false;
  910 
  911   switch (opcode) {
  912   case Op_PopCountI:
  913   case Op_PopCountL:
  914     if (!UsePopCountInstruction)
  915       return false;
  916     break;
  917   case Op_LShiftCntV:
  918   case Op_RShiftCntV:
  919   case Op_AddVB:
  920   case Op_AddVS:
  921   case Op_AddVI:
  922   case Op_AddVL:
  923   case Op_SubVB:
  924   case Op_SubVS:
  925   case Op_SubVI:
  926   case Op_SubVL:
  927   case Op_MulVS:
  928   case Op_MulVI:
  929   case Op_LShiftVB:
  930   case Op_LShiftVS:
  931   case Op_LShiftVI:
  932   case Op_LShiftVL:
  933   case Op_RShiftVB:
  934   case Op_RShiftVS:
  935   case Op_RShiftVI:
  936   case Op_RShiftVL:
  937   case Op_URShiftVB:
  938   case Op_URShiftVS:
  939   case Op_URShiftVI:
  940   case Op_URShiftVL:
  941   case Op_AndV:
  942   case Op_OrV:
  943   case Op_XorV:
  944     return VM_Version::has_simd();
  945   case Op_LoadVector:
  946   case Op_StoreVector:
  947   case Op_AddVF:
  948   case Op_SubVF:
  949   case Op_MulVF:
  950     return VM_Version::has_vfp() || VM_Version::has_simd();
  951   case Op_AddVD:
  952   case Op_SubVD:
  953   case Op_MulVD:
  954   case Op_DivVF:
  955   case Op_DivVD:
  956     return VM_Version::has_vfp();
  957   }
  958 
  959   return true;  // Per default match rules are supported.
  960 }
  961 
  962 bool Matcher::match_rule_supported_auto_vectorization(int opcode, int vlen, BasicType bt) {
  963   return match_rule_supported_vector(opcode, vlen, bt);
  964 }
  965 
  966 bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
  967 
  968   // TODO
  969   // identify extra cases that we might want to provide match rules for
  970   // e.g. Op_ vector nodes and other intrinsics while guarding with vlen
  971   bool ret_value = match_rule_supported(opcode) && vector_size_supported(bt, vlen);
  972   // Add rules here.
  973 
  974   return ret_value;  // Per default match rules are supported.
  975 }
  976 
  977 bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType bt) {
  978   return false;
  979 }
  980 
  981 bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) {
  982   return false;
  983 }
  984 
  985 bool Matcher::vector_rearrange_requires_load_shuffle(BasicType elem_bt, int vlen) {
  986   return false;
  987 }
  988 
  989 bool Matcher::mask_op_prefers_predicate(int opcode, const TypeVect* vt) {
  990   return false;
  991 }
  992 
  993 const RegMask* Matcher::predicate_reg_mask(void) {
  994   return nullptr;
  995 }
  996 
  997 // Vector calling convention not yet implemented.
  998 bool Matcher::supports_vector_calling_convention(void) {
  999   return false;
 1000 }
 1001 
 1002 OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
 1003   Unimplemented();
 1004   return OptoRegPair(0, 0);
 1005 }
 1006 
 1007 // Vector width in bytes
 1008 int Matcher::vector_width_in_bytes(BasicType bt) {
 1009   return MaxVectorSize;
 1010 }
 1011 
 1012 int Matcher::scalable_vector_reg_size(const BasicType bt) {
 1013   return -1;
 1014 }
 1015 
 1016 // Vector ideal reg corresponding to specified size in bytes
 1017 uint Matcher::vector_ideal_reg(int size) {
 1018   assert(MaxVectorSize >= size, "");
 1019   switch(size) {
 1020     case  8: return Op_VecD;
 1021     case 16: return Op_VecX;
 1022   }
 1023   ShouldNotReachHere();
 1024   return 0;
 1025 }
 1026 
 1027 // Limits on vector size (number of elements) loaded into vector.
 1028 int Matcher::max_vector_size(const BasicType bt) {
 1029   assert(is_java_primitive(bt), "only primitive type vectors");
 1030   return vector_width_in_bytes(bt)/type2aelembytes(bt);
 1031 }
 1032 
 1033 int Matcher::min_vector_size(const BasicType bt) {
 1034   assert(is_java_primitive(bt), "only primitive type vectors");
 1035   return 8/type2aelembytes(bt);
 1036 }
 1037 
 1038 int Matcher::max_vector_size_auto_vectorization(const BasicType bt) {
 1039   return Matcher::max_vector_size(bt);
 1040 }
 1041 
 1042 // Is this branch offset short enough that a short branch can be used?
 1043 //
 1044 // NOTE: If the platform does not provide any short branch variants, then
 1045 //       this method should return false for offset 0.
 1046 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
 1047   // The passed offset is relative to address of the branch.
 1048   // On ARM a branch displacement is calculated relative to address
 1049   // of the branch + 8.
 1050   //
 1051   // offset -= 8;
 1052   // return (Assembler::is_simm24(offset));
 1053   return false;
 1054 }
 1055 
 1056 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) {
 1057   ShouldNotReachHere(); // generic vector operands not supported
 1058   return nullptr;
 1059 }
 1060 
 1061 bool Matcher::is_reg2reg_move(MachNode* m) {
 1062   ShouldNotReachHere();  // generic vector operands not supported
 1063   return false;
 1064 }
 1065 
 1066 bool Matcher::is_register_biasing_candidate(const MachNode* mdef, int oper_index) {
 1067   return false;
 1068 }
 1069 
 1070 bool Matcher::is_generic_vector(MachOper* opnd)  {
 1071   ShouldNotReachHere();  // generic vector operands not supported
 1072   return false;
 1073 }
 1074 
 1075 // Should the matcher clone input 'm' of node 'n'?
 1076 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
 1077   if (is_vshift_con_pattern(n, m)) { // ShiftV src (ShiftCntV con)
 1078     mstack.push(m, Visit);           // m = ShiftCntV
 1079     return true;
 1080   }
 1081   return false;
 1082 }
 1083 
 1084 // Should the Matcher clone shifts on addressing modes, expecting them
 1085 // to be subsumed into complex addressing expressions or compute them
 1086 // into registers?
 1087 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
 1088   return clone_base_plus_offset_address(m, mstack, address_visited);
 1089 }
 1090 
 1091 #ifdef ASSERT
 1092 // Return whether or not this register is ever used as an argument.
 1093 bool Matcher::can_be_java_arg( int reg ) {
 1094   if (reg == R_R0_num ||
 1095       reg == R_R1_num ||
 1096       reg == R_R2_num ||
 1097       reg == R_R3_num) return true;
 1098 
 1099   if (reg >= R_S0_num &&
 1100       reg <= R_S13_num) return true;
 1101   return false;
 1102 }
 1103 #endif
 1104 
 1105 uint Matcher::int_pressure_limit()
 1106 {
 1107   return (INTPRESSURE == -1) ? 12 : INTPRESSURE;
 1108 }
 1109 
 1110 uint Matcher::float_pressure_limit()
 1111 {
 1112   return (FLOATPRESSURE == -1) ? 30 : FLOATPRESSURE;
 1113 }
 1114 
 1115 // Register for DIVI projection of divmodI
 1116 const RegMask& Matcher::divI_proj_mask() {
 1117   ShouldNotReachHere();
 1118   return RegMask::EMPTY;
 1119 }
 1120 
 1121 // Register for MODI projection of divmodI
 1122 const RegMask& Matcher::modI_proj_mask() {
 1123   ShouldNotReachHere();
 1124   return RegMask::EMPTY;
 1125 }
 1126 
 1127 // Register for DIVL projection of divmodL
 1128 const RegMask& Matcher::divL_proj_mask() {
 1129   ShouldNotReachHere();
 1130   return RegMask::EMPTY;
 1131 }
 1132 
 1133 // Register for MODL projection of divmodL
 1134 const RegMask& Matcher::modL_proj_mask() {
 1135   ShouldNotReachHere();
 1136   return RegMask::EMPTY;
 1137 }
 1138 
 1139 bool maybe_far_call(const CallNode *n) {
 1140   return !MacroAssembler::_reachable_from_cache(n->as_Call()->entry_point());
 1141 }
 1142 
 1143 bool maybe_far_call(const MachCallNode *n) {
 1144   return !MacroAssembler::_reachable_from_cache(n->as_MachCall()->entry_point());
 1145 }
 1146 
 1147 %}
 1148 
 1149 //----------ENCODING BLOCK-----------------------------------------------------
 1150 // This block specifies the encoding classes used by the compiler to output
 1151 // byte streams.  Encoding classes are parameterized macros used by
 1152 // Machine Instruction Nodes in order to generate the bit encoding of the
 1153 // instruction.  Operands specify their base encoding interface with the
 1154 // interface keyword.  There are currently supported four interfaces,
 1155 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
 1156 // operand to generate a function which returns its register number when
 1157 // queried.   CONST_INTER causes an operand to generate a function which
 1158 // returns the value of the constant when queried.  MEMORY_INTER causes an
 1159 // operand to generate four functions which return the Base Register, the
 1160 // Index Register, the Scale Value, and the Offset Value of the operand when
 1161 // queried.  COND_INTER causes an operand to generate six functions which
 1162 // return the encoding code (ie - encoding bits for the instruction)
 1163 // associated with each basic boolean condition for a conditional instruction.
 1164 //
 1165 // Instructions specify two basic values for encoding.  Again, a function
 1166 // is available to check if the constant displacement is an oop. They use the
 1167 // ins_encode keyword to specify their encoding classes (which must be
 1168 // a sequence of enc_class names, and their parameters, specified in
 1169 // the encoding block), and they use the
 1170 // opcode keyword to specify, in order, their primary, secondary, and
 1171 // tertiary opcode.  Only the opcode sections which a particular instruction
 1172 // needs for encoding need to be specified.
 1173 encode %{
 1174   // Set instruction mark in MacroAssembler. This is used only in
 1175   // instructions that emit bytes directly to the CodeBuffer wraped
 1176   // in the MacroAssembler. Should go away once all "instruct" are
 1177   // patched to emit bytes only using methods in MacroAssembler.
 1178   enc_class SetInstMark %{
 1179     __ set_inst_mark();
 1180   %}
 1181 
 1182   enc_class ClearInstMark %{
 1183     __ clear_inst_mark();
 1184   %}
 1185 
 1186   enc_class call_epilog %{
 1187     // nothing
 1188   %}
 1189 
 1190   enc_class Java_To_Runtime (method meth) %{
 1191     // CALL directly to the runtime
 1192     emit_call_reloc(masm, as_MachCall(), $meth, runtime_call_Relocation::spec());
 1193   %}
 1194 
 1195   enc_class Java_Static_Call (method meth) %{
 1196     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
 1197     // who we intended to call.
 1198 
 1199     if ( !_method) {
 1200       emit_call_reloc(masm, as_MachCall(), $meth, runtime_call_Relocation::spec());
 1201     } else {
 1202       int method_index = resolved_method_index(masm);
 1203       RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
 1204                                                   : static_call_Relocation::spec(method_index);
 1205       emit_call_reloc(masm, as_MachCall(), $meth, rspec);
 1206 
 1207       // Emit stubs for static call.
 1208       address stub = CompiledDirectCall::emit_to_interp_stub(masm);
 1209       if (stub == nullptr) {
 1210         ciEnv::current()->record_failure("CodeCache is full");
 1211         return;
 1212       }
 1213     }
 1214   %}
 1215 
 1216   enc_class save_last_PC %{
 1217     // preserve mark
 1218     address mark = __ inst_mark();
 1219     DEBUG_ONLY(int off0 = __ offset());
 1220     int ret_addr_offset = as_MachCall()->ret_addr_offset();
 1221     __ adr(LR, mark + ret_addr_offset);
 1222     __ str(LR, Address(Rthread, JavaThread::last_Java_pc_offset()));
 1223     DEBUG_ONLY(int off1 = __ offset());
 1224     assert(off1 - off0 == 2 * Assembler::InstructionSize, "correct size prediction");
 1225     // restore mark
 1226     __ set_inst_mark(mark);
 1227   %}
 1228 
 1229   enc_class Java_Dynamic_Call (method meth) %{
 1230     Register R8_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode());
 1231     assert(R8_ic_reg == Ricklass, "should be");
 1232     __ set_inst_mark();
 1233     __ movw(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) & 0xffff);
 1234     __ movt(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) >> 16);
 1235     address  virtual_call_oop_addr = __ inst_mark();
 1236     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
 1237     // who we intended to call.
 1238     int method_index = resolved_method_index(masm);
 1239     __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index));
 1240     emit_call_reloc(masm, as_MachCall(), $meth, RelocationHolder::none);
 1241   %}
 1242 
 1243   enc_class LdReplImmI(immI src, regD dst, iRegI tmp, int cnt, int wth) %{
 1244     // FIXME: load from constant table?
 1245     // Load a constant replicated "count" times with width "width"
 1246     int count = $cnt$$constant;
 1247     int width = $wth$$constant;
 1248     assert(count*width == 4, "sanity");
 1249     int val = $src$$constant;
 1250     if (width < 4) {
 1251       int bit_width = width * 8;
 1252       val &= (((int)1) << bit_width) - 1; // mask off sign bits
 1253       for (int i = 0; i < count - 1; i++) {
 1254         val |= (val << bit_width);
 1255       }
 1256     }
 1257 
 1258     if (val == -1) {
 1259       __ mvn($tmp$$Register, 0);
 1260     } else if (val == 0) {
 1261       __ mov($tmp$$Register, 0);
 1262     } else {
 1263       __ movw($tmp$$Register, val & 0xffff);
 1264       __ movt($tmp$$Register, (unsigned int)val >> 16);
 1265     }
 1266     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 1267   %}
 1268 
 1269   enc_class LdReplImmF(immF src, regD dst, iRegI tmp) %{
 1270     // Replicate float con 2 times and pack into vector (8 bytes) in regD.
 1271     float fval = $src$$constant;
 1272     int val = *((int*)&fval);
 1273 
 1274     if (val == -1) {
 1275       __ mvn($tmp$$Register, 0);
 1276     } else if (val == 0) {
 1277       __ mov($tmp$$Register, 0);
 1278     } else {
 1279       __ movw($tmp$$Register, val & 0xffff);
 1280       __ movt($tmp$$Register, (unsigned int)val >> 16);
 1281     }
 1282     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 1283   %}
 1284 
 1285   enc_class enc_String_Compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result, iRegI tmp1, iRegI tmp2) %{
 1286     Label Ldone, Lloop;
 1287 
 1288     Register   str1_reg = $str1$$Register;
 1289     Register   str2_reg = $str2$$Register;
 1290     Register   cnt1_reg = $cnt1$$Register; // int
 1291     Register   cnt2_reg = $cnt2$$Register; // int
 1292     Register   tmp1_reg = $tmp1$$Register;
 1293     Register   tmp2_reg = $tmp2$$Register;
 1294     Register result_reg = $result$$Register;
 1295 
 1296     assert_different_registers(str1_reg, str2_reg, cnt1_reg, cnt2_reg, tmp1_reg, tmp2_reg);
 1297 
 1298     // Compute the minimum of the string lengths(str1_reg) and the
 1299     // difference of the string lengths (stack)
 1300 
 1301     // See if the lengths are different, and calculate min in str1_reg.
 1302     // Stash diff in tmp2 in case we need it for a tie-breaker.
 1303     __ subs_32(tmp2_reg, cnt1_reg, cnt2_reg);
 1304     __ mov(cnt1_reg, AsmOperand(cnt1_reg, lsl, exact_log2(sizeof(jchar)))); // scale the limit
 1305     __ mov(cnt1_reg, AsmOperand(cnt2_reg, lsl, exact_log2(sizeof(jchar))), pl); // scale the limit
 1306 
 1307     // reallocate cnt1_reg, cnt2_reg, result_reg
 1308     // Note:  limit_reg holds the string length pre-scaled by 2
 1309     Register limit_reg = cnt1_reg;
 1310     Register  chr2_reg = cnt2_reg;
 1311     Register  chr1_reg = tmp1_reg;
 1312     // str{12} are the base pointers
 1313 
 1314     // Is the minimum length zero?
 1315     __ cmp_32(limit_reg, 0);
 1316     if (result_reg != tmp2_reg) {
 1317       __ mov(result_reg, tmp2_reg, eq);
 1318     }
 1319     __ b(Ldone, eq);
 1320 
 1321     // Load first characters
 1322     __ ldrh(chr1_reg, Address(str1_reg, 0));
 1323     __ ldrh(chr2_reg, Address(str2_reg, 0));
 1324 
 1325     // Compare first characters
 1326     __ subs(chr1_reg, chr1_reg, chr2_reg);
 1327     if (result_reg != chr1_reg) {
 1328       __ mov(result_reg, chr1_reg, ne);
 1329     }
 1330     __ b(Ldone, ne);
 1331 
 1332     {
 1333       // Check after comparing first character to see if strings are equivalent
 1334       // Check if the strings start at same location
 1335       __ cmp(str1_reg, str2_reg);
 1336       // Check if the length difference is zero
 1337       __ cond_cmp(tmp2_reg, 0, eq);
 1338       __ mov(result_reg, 0, eq); // result is zero
 1339       __ b(Ldone, eq);
 1340       // Strings might not be equal
 1341     }
 1342 
 1343     __ subs(chr1_reg, limit_reg, 1 * sizeof(jchar));
 1344     if (result_reg != tmp2_reg) {
 1345       __ mov(result_reg, tmp2_reg, eq);
 1346     }
 1347     __ b(Ldone, eq);
 1348 
 1349     // Shift str1_reg and str2_reg to the end of the arrays, negate limit
 1350     __ add(str1_reg, str1_reg, limit_reg);
 1351     __ add(str2_reg, str2_reg, limit_reg);
 1352     __ neg(limit_reg, chr1_reg);  // limit = -(limit-2)
 1353 
 1354     // Compare the rest of the characters
 1355     __ bind(Lloop);
 1356     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
 1357     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
 1358     __ subs(chr1_reg, chr1_reg, chr2_reg);
 1359     if (result_reg != chr1_reg) {
 1360       __ mov(result_reg, chr1_reg, ne);
 1361     }
 1362     __ b(Ldone, ne);
 1363 
 1364     __ adds(limit_reg, limit_reg, sizeof(jchar));
 1365     __ b(Lloop, ne);
 1366 
 1367     // If strings are equal up to min length, return the length difference.
 1368     if (result_reg != tmp2_reg) {
 1369       __ mov(result_reg, tmp2_reg);
 1370     }
 1371 
 1372     // Otherwise, return the difference between the first mismatched chars.
 1373     __ bind(Ldone);
 1374   %}
 1375 
 1376   enc_class enc_String_Equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2) %{
 1377     Label Lchar, Lchar_loop, Ldone, Lequal;
 1378 
 1379     Register   str1_reg = $str1$$Register;
 1380     Register   str2_reg = $str2$$Register;
 1381     Register    cnt_reg = $cnt$$Register; // int
 1382     Register   tmp1_reg = $tmp1$$Register;
 1383     Register   tmp2_reg = $tmp2$$Register;
 1384     Register result_reg = $result$$Register;
 1385 
 1386     assert_different_registers(str1_reg, str2_reg, cnt_reg, tmp1_reg, tmp2_reg, result_reg);
 1387 
 1388     __ cmp(str1_reg, str2_reg); //same char[] ?
 1389     __ b(Lequal, eq);
 1390 
 1391     __ cbz_32(cnt_reg, Lequal); // count == 0
 1392 
 1393     //rename registers
 1394     Register limit_reg = cnt_reg;
 1395     Register  chr1_reg = tmp1_reg;
 1396     Register  chr2_reg = tmp2_reg;
 1397 
 1398     __ logical_shift_left(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
 1399 
 1400     //check for alignment and position the pointers to the ends
 1401     __ orr(chr1_reg, str1_reg, str2_reg);
 1402     __ tst(chr1_reg, 0x3);
 1403 
 1404     // notZero means at least one not 4-byte aligned.
 1405     // We could optimize the case when both arrays are not aligned
 1406     // but it is not frequent case and it requires additional checks.
 1407     __ b(Lchar, ne);
 1408 
 1409     // Compare char[] arrays aligned to 4 bytes.
 1410     __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg,
 1411                           chr1_reg, chr2_reg, Ldone);
 1412 
 1413     __ b(Lequal); // equal
 1414 
 1415     // char by char compare
 1416     __ bind(Lchar);
 1417     __ mov(result_reg, 0);
 1418     __ add(str1_reg, limit_reg, str1_reg);
 1419     __ add(str2_reg, limit_reg, str2_reg);
 1420     __ neg(limit_reg, limit_reg); //negate count
 1421 
 1422     // Lchar_loop
 1423     __ bind(Lchar_loop);
 1424     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
 1425     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
 1426     __ cmp(chr1_reg, chr2_reg);
 1427     __ b(Ldone, ne);
 1428     __ adds(limit_reg, limit_reg, sizeof(jchar));
 1429     __ b(Lchar_loop, ne);
 1430 
 1431     __ bind(Lequal);
 1432     __ mov(result_reg, 1);  //equal
 1433 
 1434     __ bind(Ldone);
 1435   %}
 1436 
 1437   enc_class enc_Array_Equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result) %{
 1438     Label Ldone, Lloop, Lequal;
 1439 
 1440     Register   ary1_reg = $ary1$$Register;
 1441     Register   ary2_reg = $ary2$$Register;
 1442     Register   tmp1_reg = $tmp1$$Register;
 1443     Register   tmp2_reg = $tmp2$$Register;
 1444     Register   tmp3_reg = $tmp3$$Register;
 1445     Register result_reg = $result$$Register;
 1446 
 1447     assert_different_registers(ary1_reg, ary2_reg, tmp1_reg, tmp2_reg, tmp3_reg, result_reg);
 1448 
 1449     int length_offset  = arrayOopDesc::length_offset_in_bytes();
 1450     int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
 1451 
 1452     // return true if the same array
 1453     __ teq(ary1_reg, ary2_reg);
 1454     __ mov(result_reg, 1, eq);
 1455     __ b(Ldone, eq); // equal
 1456 
 1457     __ tst(ary1_reg, ary1_reg);
 1458     __ mov(result_reg, 0, eq);
 1459     __ b(Ldone, eq);    // not equal
 1460 
 1461     __ tst(ary2_reg, ary2_reg);
 1462     __ mov(result_reg, 0, eq);
 1463     __ b(Ldone, eq);    // not equal
 1464 
 1465     //load the lengths of arrays
 1466     __ ldr_s32(tmp1_reg, Address(ary1_reg, length_offset)); // int
 1467     __ ldr_s32(tmp2_reg, Address(ary2_reg, length_offset)); // int
 1468 
 1469     // return false if the two arrays are not equal length
 1470     __ teq_32(tmp1_reg, tmp2_reg);
 1471     __ mov(result_reg, 0, ne);
 1472     __ b(Ldone, ne);    // not equal
 1473 
 1474     __ tst(tmp1_reg, tmp1_reg);
 1475     __ mov(result_reg, 1, eq);
 1476     __ b(Ldone, eq);    // zero-length arrays are equal
 1477 
 1478     // load array addresses
 1479     __ add(ary1_reg, ary1_reg, base_offset);
 1480     __ add(ary2_reg, ary2_reg, base_offset);
 1481 
 1482     // renaming registers
 1483     Register chr1_reg  =  tmp3_reg;   // for characters in ary1
 1484     Register chr2_reg  =  tmp2_reg;   // for characters in ary2
 1485     Register limit_reg =  tmp1_reg;   // length
 1486 
 1487     // set byte count
 1488     __ logical_shift_left_32(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
 1489 
 1490     // Compare char[] arrays aligned to 4 bytes.
 1491     __ char_arrays_equals(ary1_reg, ary2_reg, limit_reg, result_reg,
 1492                           chr1_reg, chr2_reg, Ldone);
 1493     __ bind(Lequal);
 1494     __ mov(result_reg, 1);  //equal
 1495 
 1496     __ bind(Ldone);
 1497     %}
 1498 %}
 1499 
 1500 //----------FRAME--------------------------------------------------------------
 1501 // Definition of frame structure and management information.
 1502 //
 1503 //  S T A C K   L A Y O U T    Allocators stack-slot number
 1504 //                             |   (to get allocators register number
 1505 //  G  Owned by    |        |  v    add VMRegImpl::stack0)
 1506 //  r   CALLER     |        |
 1507 //  o     |        +--------+      pad to even-align allocators stack-slot
 1508 //  w     V        |  pad0  |        numbers; owned by CALLER
 1509 //  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
 1510 //  h     ^        |   in   |  5
 1511 //        |        |  args  |  4   Holes in incoming args owned by SELF
 1512 //  |     |        |        |  3
 1513 //  |     |        +--------+
 1514 //  V     |        | old out|      Empty on Intel, window on Sparc
 1515 //        |    old |preserve|      Must be even aligned.
 1516 //        |     SP-+--------+----> Matcher::_old_SP, 8 (or 16 in LP64)-byte aligned
 1517 //        |        |   in   |  3   area for Intel ret address
 1518 //     Owned by    |preserve|      Empty on Sparc.
 1519 //       SELF      +--------+
 1520 //        |        |  pad2  |  2   pad to align old SP
 1521 //        |        +--------+  1
 1522 //        |        | locks  |  0
 1523 //        |        +--------+----> VMRegImpl::stack0, 8 (or 16 in LP64)-byte aligned
 1524 //        |        |  pad1  | 11   pad to align new SP
 1525 //        |        +--------+
 1526 //        |        |        | 10
 1527 //        |        | spills |  9   spills
 1528 //        V        |        |  8   (pad0 slot for callee)
 1529 //      -----------+--------+----> Matcher::_out_arg_limit, unaligned
 1530 //        ^        |  out   |  7
 1531 //        |        |  args  |  6   Holes in outgoing args owned by CALLEE
 1532 //     Owned by    +--------+
 1533 //      CALLEE     | new out|  6   Empty on Intel, window on Sparc
 1534 //        |    new |preserve|      Must be even-aligned.
 1535 //        |     SP-+--------+----> Matcher::_new_SP, even aligned
 1536 //        |        |        |
 1537 //
 1538 // Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
 1539 //         known from SELF's arguments and the Java calling convention.
 1540 //         Region 6-7 is determined per call site.
 1541 // Note 2: If the calling convention leaves holes in the incoming argument
 1542 //         area, those holes are owned by SELF.  Holes in the outgoing area
 1543 //         are owned by the CALLEE.  Holes should not be necessary in the
 1544 //         incoming area, as the Java calling convention is completely under
 1545 //         the control of the AD file.  Doubles can be sorted and packed to
 1546 //         avoid holes.  Holes in the outgoing arguments may be necessary for
 1547 //         varargs C calling conventions.
 1548 // Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
 1549 //         even aligned with pad0 as needed.
 1550 //         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
 1551 //         region 6-11 is even aligned; it may be padded out more so that
 1552 //         the region from SP to FP meets the minimum stack alignment.
 1553 
 1554 frame %{
 1555   // These two registers define part of the calling convention
 1556   // between compiled code and the interpreter.
 1557   inline_cache_reg(R_Ricklass);          // Inline Cache Register or Method* for I2C
 1558 
 1559   // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
 1560   cisc_spilling_operand_name(indOffset);
 1561 
 1562   // Number of stack slots consumed by a Monitor enter
 1563   sync_stack_slots(1 * VMRegImpl::slots_per_word);
 1564 
 1565   // Compiled code's Frame Pointer
 1566   frame_pointer(R_R13);
 1567 
 1568   // Stack alignment requirement
 1569   stack_alignment(StackAlignmentInBytes);
 1570   //  LP64: Alignment size in bytes (128-bit -> 16 bytes)
 1571   // !LP64: Alignment size in bytes (64-bit  ->  8 bytes)
 1572 
 1573   // Number of outgoing stack slots killed above the out_preserve_stack_slots
 1574   // for calls to C.  Supports the var-args backing area for register parms.
 1575   // ADLC doesn't support parsing expressions, so I folded the math by hand.
 1576   varargs_C_out_slots_killed( 0);
 1577 
 1578   // The after-PROLOG location of the return address.  Location of
 1579   // return address specifies a type (REG or STACK) and a number
 1580   // representing the register number (i.e. - use a register name) or
 1581   // stack slot.
 1582   // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
 1583   // Otherwise, it is above the locks and verification slot and alignment word
 1584   return_addr(STACK - 1*VMRegImpl::slots_per_word +
 1585               align_up((Compile::current()->in_preserve_stack_slots() +
 1586                         Compile::current()->fixed_slots()),
 1587                        stack_alignment_in_slots()));
 1588 
 1589   // Location of compiled Java return values.  Same as C
 1590   return_value %{
 1591     return c2::return_value(ideal_reg);
 1592   %}
 1593 
 1594 %}
 1595 
 1596 //----------ATTRIBUTES---------------------------------------------------------
 1597 //----------Instruction Attributes---------------------------------------------
 1598 ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute
 1599 ins_attrib ins_size(32);           // Required size attribute (in bits)
 1600 ins_attrib ins_short_branch(0);    // Required flag: is this instruction a
 1601                                    // non-matching short branch variant of some
 1602                                                             // long branch?
 1603 
 1604 //----------OPERANDS-----------------------------------------------------------
 1605 // Operand definitions must precede instruction definitions for correct parsing
 1606 // in the ADLC because operands constitute user defined types which are used in
 1607 // instruction definitions.
 1608 
 1609 //----------Simple Operands----------------------------------------------------
 1610 // Immediate Operands
 1611 // Integer Immediate: 32-bit
 1612 operand immI() %{
 1613   match(ConI);
 1614 
 1615   op_cost(0);
 1616   // formats are generated automatically for constants and base registers
 1617   format %{ %}
 1618   interface(CONST_INTER);
 1619 %}
 1620 
 1621 // Integer Immediate: 8-bit unsigned - for VMOV
 1622 operand immU8() %{
 1623   predicate(0 <= n->get_int() && (n->get_int() <= 255));
 1624   match(ConI);
 1625   op_cost(0);
 1626 
 1627   format %{ %}
 1628   interface(CONST_INTER);
 1629 %}
 1630 
 1631 // Integer Immediate: 16-bit
 1632 operand immI16() %{
 1633   predicate((n->get_int() >> 16) == 0 && VM_Version::supports_movw());
 1634   match(ConI);
 1635   op_cost(0);
 1636 
 1637   format %{ %}
 1638   interface(CONST_INTER);
 1639 %}
 1640 
 1641 // Integer Immediate: offset for half and double word loads and stores
 1642 operand immIHD() %{
 1643   predicate(is_memoryHD(n->get_int()));
 1644   match(ConI);
 1645   op_cost(0);
 1646   format %{ %}
 1647   interface(CONST_INTER);
 1648 %}
 1649 
 1650 // Integer Immediate: offset for fp loads and stores
 1651 operand immIFP() %{
 1652   predicate(is_memoryfp(n->get_int()) && ((n->get_int() & 3) == 0));
 1653   match(ConI);
 1654   op_cost(0);
 1655 
 1656   format %{ %}
 1657   interface(CONST_INTER);
 1658 %}
 1659 
 1660 // Valid scale values for addressing modes and shifts
 1661 operand immU5() %{
 1662   predicate(0 <= n->get_int() && (n->get_int() <= 31));
 1663   match(ConI);
 1664   op_cost(0);
 1665 
 1666   format %{ %}
 1667   interface(CONST_INTER);
 1668 %}
 1669 
 1670 // Integer Immediate: 6-bit
 1671 operand immU6Big() %{
 1672   predicate(n->get_int() >= 32 && n->get_int() <= 63);
 1673   match(ConI);
 1674   op_cost(0);
 1675   format %{ %}
 1676   interface(CONST_INTER);
 1677 %}
 1678 
 1679 // Integer Immediate: 0-bit
 1680 operand immI0() %{
 1681   predicate(n->get_int() == 0);
 1682   match(ConI);
 1683   op_cost(0);
 1684 
 1685   format %{ %}
 1686   interface(CONST_INTER);
 1687 %}
 1688 
 1689 // Int Immediate non-negative
 1690 operand immU31()
 1691 %{
 1692   predicate(n->get_int() >= 0);
 1693   match(ConI);
 1694 
 1695   op_cost(0);
 1696   format %{ %}
 1697   interface(CONST_INTER);
 1698 %}
 1699 
 1700 // Integer Immediate: the values 32-63
 1701 operand immI_32_63() %{
 1702   predicate(n->get_int() >= 32 && n->get_int() <= 63);
 1703   match(ConI);
 1704   op_cost(0);
 1705 
 1706   format %{ %}
 1707   interface(CONST_INTER);
 1708 %}
 1709 
 1710 // Immediates for special shifts (sign extend)
 1711 
 1712 // Integer Immediate: the value 16
 1713 operand immI_16() %{
 1714   predicate(n->get_int() == 16);
 1715   match(ConI);
 1716   op_cost(0);
 1717 
 1718   format %{ %}
 1719   interface(CONST_INTER);
 1720 %}
 1721 
 1722 // Integer Immediate: the value 24
 1723 operand immI_24() %{
 1724   predicate(n->get_int() == 24);
 1725   match(ConI);
 1726   op_cost(0);
 1727 
 1728   format %{ %}
 1729   interface(CONST_INTER);
 1730 %}
 1731 
 1732 // Integer Immediate: the value 255
 1733 operand immI_255() %{
 1734   predicate( n->get_int() == 255 );
 1735   match(ConI);
 1736   op_cost(0);
 1737 
 1738   format %{ %}
 1739   interface(CONST_INTER);
 1740 %}
 1741 
 1742 // Integer Immediate: the value 65535
 1743 operand immI_65535() %{
 1744   predicate(n->get_int() == 65535);
 1745   match(ConI);
 1746   op_cost(0);
 1747 
 1748   format %{ %}
 1749   interface(CONST_INTER);
 1750 %}
 1751 
 1752 // Integer Immediates for arithmetic instructions
 1753 
 1754 operand aimmI() %{
 1755   predicate(is_aimm(n->get_int()));
 1756   match(ConI);
 1757   op_cost(0);
 1758 
 1759   format %{ %}
 1760   interface(CONST_INTER);
 1761 %}
 1762 
 1763 operand aimmIneg() %{
 1764   predicate(is_aimm(-n->get_int()));
 1765   match(ConI);
 1766   op_cost(0);
 1767 
 1768   format %{ %}
 1769   interface(CONST_INTER);
 1770 %}
 1771 
 1772 operand aimmU31() %{
 1773   predicate((0 <= n->get_int()) && is_aimm(n->get_int()));
 1774   match(ConI);
 1775   op_cost(0);
 1776 
 1777   format %{ %}
 1778   interface(CONST_INTER);
 1779 %}
 1780 
 1781 // Integer Immediates for logical instructions
 1782 
 1783 operand limmI() %{
 1784   predicate(is_limmI(n->get_int()));
 1785   match(ConI);
 1786   op_cost(0);
 1787 
 1788   format %{ %}
 1789   interface(CONST_INTER);
 1790 %}
 1791 
 1792 operand limmIlow8() %{
 1793   predicate(is_limmI_low(n->get_int(), 8));
 1794   match(ConI);
 1795   op_cost(0);
 1796 
 1797   format %{ %}
 1798   interface(CONST_INTER);
 1799 %}
 1800 
 1801 operand limmU31() %{
 1802   predicate(0 <= n->get_int() && is_limmI(n->get_int()));
 1803   match(ConI);
 1804   op_cost(0);
 1805 
 1806   format %{ %}
 1807   interface(CONST_INTER);
 1808 %}
 1809 
 1810 operand limmIn() %{
 1811   predicate(is_limmI(~n->get_int()));
 1812   match(ConI);
 1813   op_cost(0);
 1814 
 1815   format %{ %}
 1816   interface(CONST_INTER);
 1817 %}
 1818 
 1819 // Pointer Immediate: 32 or 64-bit
 1820 operand immP() %{
 1821   match(ConP);
 1822 
 1823   op_cost(5);
 1824   // formats are generated automatically for constants and base registers
 1825   format %{ %}
 1826   interface(CONST_INTER);
 1827 %}
 1828 
 1829 operand immP0() %{
 1830   predicate(n->get_ptr() == 0);
 1831   match(ConP);
 1832   op_cost(0);
 1833 
 1834   format %{ %}
 1835   interface(CONST_INTER);
 1836 %}
 1837 
 1838 operand immL() %{
 1839   match(ConL);
 1840   op_cost(40);
 1841   // formats are generated automatically for constants and base registers
 1842   format %{ %}
 1843   interface(CONST_INTER);
 1844 %}
 1845 
 1846 operand immL0() %{
 1847   predicate(n->get_long() == 0L);
 1848   match(ConL);
 1849   op_cost(0);
 1850   // formats are generated automatically for constants and base registers
 1851   format %{ %}
 1852   interface(CONST_INTER);
 1853 %}
 1854 
 1855 // Long Immediate: 16-bit
 1856 operand immL16() %{
 1857   predicate(n->get_long() >= 0 && n->get_long() < (1<<16)  && VM_Version::supports_movw());
 1858   match(ConL);
 1859   op_cost(0);
 1860 
 1861   format %{ %}
 1862   interface(CONST_INTER);
 1863 %}
 1864 
 1865 // Long Immediate: low 32-bit mask
 1866 operand immL_32bits() %{
 1867   predicate(n->get_long() == 0xFFFFFFFFL);
 1868   match(ConL);
 1869   op_cost(0);
 1870 
 1871   format %{ %}
 1872   interface(CONST_INTER);
 1873 %}
 1874 
 1875 // Double Immediate
 1876 operand immD() %{
 1877   match(ConD);
 1878 
 1879   op_cost(40);
 1880   format %{ %}
 1881   interface(CONST_INTER);
 1882 %}
 1883 
 1884 // Double Immediate: +0.0d.
 1885 operand immD0() %{
 1886   predicate(jlong_cast(n->getd()) == 0);
 1887 
 1888   match(ConD);
 1889   op_cost(0);
 1890   format %{ %}
 1891   interface(CONST_INTER);
 1892 %}
 1893 
 1894 operand imm8D() %{
 1895   predicate(Assembler::double_num(n->getd()).can_be_imm8());
 1896   match(ConD);
 1897 
 1898   op_cost(0);
 1899   format %{ %}
 1900   interface(CONST_INTER);
 1901 %}
 1902 
 1903 // Float Immediate
 1904 operand immF() %{
 1905   match(ConF);
 1906 
 1907   op_cost(20);
 1908   format %{ %}
 1909   interface(CONST_INTER);
 1910 %}
 1911 
 1912 // Float Immediate: +0.0f
 1913 operand immF0() %{
 1914   predicate(jint_cast(n->getf()) == 0);
 1915   match(ConF);
 1916 
 1917   op_cost(0);
 1918   format %{ %}
 1919   interface(CONST_INTER);
 1920 %}
 1921 
 1922 // Float Immediate: encoded as 8 bits
 1923 operand imm8F() %{
 1924   predicate(Assembler::float_num(n->getf()).can_be_imm8());
 1925   match(ConF);
 1926 
 1927   op_cost(0);
 1928   format %{ %}
 1929   interface(CONST_INTER);
 1930 %}
 1931 
 1932 // Integer Register Operands
 1933 // Integer Register
 1934 operand iRegI() %{
 1935   constraint(ALLOC_IN_RC(int_reg));
 1936   match(RegI);
 1937   match(R0RegI);
 1938   match(R1RegI);
 1939   match(R2RegI);
 1940   match(R3RegI);
 1941   match(R12RegI);
 1942 
 1943   format %{ %}
 1944   interface(REG_INTER);
 1945 %}
 1946 
 1947 // Pointer Register
 1948 operand iRegP() %{
 1949   constraint(ALLOC_IN_RC(ptr_reg));
 1950   match(RegP);
 1951   match(R0RegP);
 1952   match(R1RegP);
 1953   match(R2RegP);
 1954   match(RExceptionRegP);
 1955   match(R8RegP);
 1956   match(R9RegP);
 1957   match(RthreadRegP); // FIXME: move to sp_ptr_RegP?
 1958   match(R12RegP);
 1959   match(LRRegP);
 1960 
 1961   match(sp_ptr_RegP);
 1962   match(store_ptr_RegP);
 1963 
 1964   format %{ %}
 1965   interface(REG_INTER);
 1966 %}
 1967 
 1968 // GPRs + Rthread + SP
 1969 operand sp_ptr_RegP() %{
 1970   constraint(ALLOC_IN_RC(sp_ptr_reg));
 1971   match(RegP);
 1972   match(iRegP);
 1973   match(SPRegP); // FIXME: check cost
 1974 
 1975   format %{ %}
 1976   interface(REG_INTER);
 1977 %}
 1978 
 1979 
 1980 operand R0RegP() %{
 1981   constraint(ALLOC_IN_RC(R0_regP));
 1982   match(iRegP);
 1983 
 1984   format %{ %}
 1985   interface(REG_INTER);
 1986 %}
 1987 
 1988 operand R1RegP() %{
 1989   constraint(ALLOC_IN_RC(R1_regP));
 1990   match(iRegP);
 1991 
 1992   format %{ %}
 1993   interface(REG_INTER);
 1994 %}
 1995 
 1996 operand R8RegP() %{
 1997   constraint(ALLOC_IN_RC(R8_regP));
 1998   match(iRegP);
 1999 
 2000   format %{ %}
 2001   interface(REG_INTER);
 2002 %}
 2003 
 2004 operand R9RegP() %{
 2005   constraint(ALLOC_IN_RC(R9_regP));
 2006   match(iRegP);
 2007 
 2008   format %{ %}
 2009   interface(REG_INTER);
 2010 %}
 2011 
 2012 operand R12RegP() %{
 2013   constraint(ALLOC_IN_RC(R12_regP));
 2014   match(iRegP);
 2015 
 2016   format %{ %}
 2017   interface(REG_INTER);
 2018 %}
 2019 
 2020 operand R2RegP() %{
 2021   constraint(ALLOC_IN_RC(R2_regP));
 2022   match(iRegP);
 2023 
 2024   format %{ %}
 2025   interface(REG_INTER);
 2026 %}
 2027 
 2028 operand RExceptionRegP() %{
 2029   constraint(ALLOC_IN_RC(Rexception_regP));
 2030   match(iRegP);
 2031 
 2032   format %{ %}
 2033   interface(REG_INTER);
 2034 %}
 2035 
 2036 operand RthreadRegP() %{
 2037   constraint(ALLOC_IN_RC(Rthread_regP));
 2038   match(iRegP);
 2039 
 2040   format %{ %}
 2041   interface(REG_INTER);
 2042 %}
 2043 
 2044 operand IPRegP() %{
 2045   constraint(ALLOC_IN_RC(IP_regP));
 2046   match(iRegP);
 2047 
 2048   format %{ %}
 2049   interface(REG_INTER);
 2050 %}
 2051 
 2052 operand SPRegP() %{
 2053   constraint(ALLOC_IN_RC(SP_regP));
 2054   match(iRegP);
 2055 
 2056   format %{ %}
 2057   interface(REG_INTER);
 2058 %}
 2059 
 2060 operand LRRegP() %{
 2061   constraint(ALLOC_IN_RC(LR_regP));
 2062   match(iRegP);
 2063 
 2064   format %{ %}
 2065   interface(REG_INTER);
 2066 %}
 2067 
 2068 operand R0RegI() %{
 2069   constraint(ALLOC_IN_RC(R0_regI));
 2070   match(iRegI);
 2071 
 2072   format %{ %}
 2073   interface(REG_INTER);
 2074 %}
 2075 
 2076 operand R1RegI() %{
 2077   constraint(ALLOC_IN_RC(R1_regI));
 2078   match(iRegI);
 2079 
 2080   format %{ %}
 2081   interface(REG_INTER);
 2082 %}
 2083 
 2084 operand R2RegI() %{
 2085   constraint(ALLOC_IN_RC(R2_regI));
 2086   match(iRegI);
 2087 
 2088   format %{ %}
 2089   interface(REG_INTER);
 2090 %}
 2091 
 2092 operand R3RegI() %{
 2093   constraint(ALLOC_IN_RC(R3_regI));
 2094   match(iRegI);
 2095 
 2096   format %{ %}
 2097   interface(REG_INTER);
 2098 %}
 2099 
 2100 operand R12RegI() %{
 2101   constraint(ALLOC_IN_RC(R12_regI));
 2102   match(iRegI);
 2103 
 2104   format %{ %}
 2105   interface(REG_INTER);
 2106 %}
 2107 
 2108 // Long Register
 2109 operand iRegL() %{
 2110   constraint(ALLOC_IN_RC(long_reg));
 2111   match(RegL);
 2112   match(R0R1RegL);
 2113   match(R2R3RegL);
 2114 //match(iRegLex);
 2115 
 2116   format %{ %}
 2117   interface(REG_INTER);
 2118 %}
 2119 
 2120 operand iRegLd() %{
 2121   constraint(ALLOC_IN_RC(long_reg_align));
 2122   match(iRegL); // FIXME: allows unaligned R11/R12?
 2123 
 2124   format %{ %}
 2125   interface(REG_INTER);
 2126 %}
 2127 
 2128 // first long arg, or return value
 2129 operand R0R1RegL() %{
 2130   constraint(ALLOC_IN_RC(R0R1_regL));
 2131   match(iRegL);
 2132 
 2133   format %{ %}
 2134   interface(REG_INTER);
 2135 %}
 2136 
 2137 operand R2R3RegL() %{
 2138   constraint(ALLOC_IN_RC(R2R3_regL));
 2139   match(iRegL);
 2140 
 2141   format %{ %}
 2142   interface(REG_INTER);
 2143 %}
 2144 
 2145 // Condition Code Flag Register
 2146 operand flagsReg() %{
 2147   constraint(ALLOC_IN_RC(int_flags));
 2148   match(RegFlags);
 2149 
 2150   format %{ "apsr" %}
 2151   interface(REG_INTER);
 2152 %}
 2153 
 2154 // Result of compare to 0 (TST)
 2155 operand flagsReg_EQNELTGE() %{
 2156   constraint(ALLOC_IN_RC(int_flags));
 2157   match(RegFlags);
 2158 
 2159   format %{ "apsr_EQNELTGE" %}
 2160   interface(REG_INTER);
 2161 %}
 2162 
 2163 // Condition Code Register, unsigned comparisons.
 2164 operand flagsRegU() %{
 2165   constraint(ALLOC_IN_RC(int_flags));
 2166   match(RegFlags);
 2167 #ifdef TODO
 2168   match(RegFlagsP);
 2169 #endif
 2170 
 2171   format %{ "apsr_U" %}
 2172   interface(REG_INTER);
 2173 %}
 2174 
 2175 // Condition Code Register, pointer comparisons.
 2176 operand flagsRegP() %{
 2177   constraint(ALLOC_IN_RC(int_flags));
 2178   match(RegFlags);
 2179 
 2180   format %{ "apsr_P" %}
 2181   interface(REG_INTER);
 2182 %}
 2183 
 2184 // Condition Code Register, long comparisons.
 2185 operand flagsRegL_LTGE() %{
 2186   constraint(ALLOC_IN_RC(int_flags));
 2187   match(RegFlags);
 2188 
 2189   format %{ "apsr_L_LTGE" %}
 2190   interface(REG_INTER);
 2191 %}
 2192 
 2193 operand flagsRegL_EQNE() %{
 2194   constraint(ALLOC_IN_RC(int_flags));
 2195   match(RegFlags);
 2196 
 2197   format %{ "apsr_L_EQNE" %}
 2198   interface(REG_INTER);
 2199 %}
 2200 
 2201 operand flagsRegL_LEGT() %{
 2202   constraint(ALLOC_IN_RC(int_flags));
 2203   match(RegFlags);
 2204 
 2205   format %{ "apsr_L_LEGT" %}
 2206   interface(REG_INTER);
 2207 %}
 2208 
 2209 operand flagsRegUL_LTGE() %{
 2210   constraint(ALLOC_IN_RC(int_flags));
 2211   match(RegFlags);
 2212 
 2213   format %{ "apsr_UL_LTGE" %}
 2214   interface(REG_INTER);
 2215 %}
 2216 
 2217 operand flagsRegUL_EQNE() %{
 2218   constraint(ALLOC_IN_RC(int_flags));
 2219   match(RegFlags);
 2220 
 2221   format %{ "apsr_UL_EQNE" %}
 2222   interface(REG_INTER);
 2223 %}
 2224 
 2225 operand flagsRegUL_LEGT() %{
 2226   constraint(ALLOC_IN_RC(int_flags));
 2227   match(RegFlags);
 2228 
 2229   format %{ "apsr_UL_LEGT" %}
 2230   interface(REG_INTER);
 2231 %}
 2232 
 2233 // Condition Code Register, floating comparisons, unordered same as "less".
 2234 operand flagsRegF() %{
 2235   constraint(ALLOC_IN_RC(float_flags));
 2236   match(RegFlags);
 2237 
 2238   format %{ "fpscr_F" %}
 2239   interface(REG_INTER);
 2240 %}
 2241 
 2242 // Vectors
 2243 operand vecD() %{
 2244   constraint(ALLOC_IN_RC(actual_dflt_reg));
 2245   match(VecD);
 2246 
 2247   format %{ %}
 2248   interface(REG_INTER);
 2249 %}
 2250 
 2251 operand vecX() %{
 2252   constraint(ALLOC_IN_RC(vectorx_reg));
 2253   match(VecX);
 2254 
 2255   format %{ %}
 2256   interface(REG_INTER);
 2257 %}
 2258 
 2259 operand regD() %{
 2260   constraint(ALLOC_IN_RC(actual_dflt_reg));
 2261   match(RegD);
 2262   match(regD_low);
 2263 
 2264   format %{ %}
 2265   interface(REG_INTER);
 2266 %}
 2267 
 2268 operand regF() %{
 2269   constraint(ALLOC_IN_RC(sflt_reg));
 2270   match(RegF);
 2271 
 2272   format %{ %}
 2273   interface(REG_INTER);
 2274 %}
 2275 
 2276 operand regD_low() %{
 2277   constraint(ALLOC_IN_RC(dflt_low_reg));
 2278   match(RegD);
 2279 
 2280   format %{ %}
 2281   interface(REG_INTER);
 2282 %}
 2283 
 2284 // Special Registers
 2285 
 2286 // Method Register
 2287 operand inline_cache_regP(iRegP reg) %{
 2288   constraint(ALLOC_IN_RC(Ricklass_regP));
 2289   match(reg);
 2290   format %{ %}
 2291   interface(REG_INTER);
 2292 %}
 2293 
 2294 //----------Complex Operands---------------------------------------------------
 2295 // Indirect Memory Reference
 2296 operand indirect(sp_ptr_RegP reg) %{
 2297   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2298   match(reg);
 2299 
 2300   op_cost(100);
 2301   format %{ "[$reg]" %}
 2302   interface(MEMORY_INTER) %{
 2303     base($reg);
 2304     index(0xf); // PC => no index
 2305     scale(0x0);
 2306     disp(0x0);
 2307   %}
 2308 %}
 2309 
 2310 
 2311 // Indirect with Offset in ]-4096, 4096[
 2312 operand indOffset12(sp_ptr_RegP reg, immI12 offset) %{
 2313   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2314   match(AddP reg offset);
 2315 
 2316   op_cost(100);
 2317   format %{ "[$reg + $offset]" %}
 2318   interface(MEMORY_INTER) %{
 2319     base($reg);
 2320     index(0xf); // PC => no index
 2321     scale(0x0);
 2322     disp($offset);
 2323   %}
 2324 %}
 2325 
 2326 // Indirect with offset for float load/store
 2327 operand indOffsetFP(sp_ptr_RegP reg, immIFP offset) %{
 2328   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2329   match(AddP reg offset);
 2330 
 2331   op_cost(100);
 2332   format %{ "[$reg + $offset]" %}
 2333   interface(MEMORY_INTER) %{
 2334     base($reg);
 2335     index(0xf); // PC => no index
 2336     scale(0x0);
 2337     disp($offset);
 2338   %}
 2339 %}
 2340 
 2341 // Indirect with Offset for half and double words
 2342 operand indOffsetHD(sp_ptr_RegP reg, immIHD offset) %{
 2343   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2344   match(AddP reg offset);
 2345 
 2346   op_cost(100);
 2347   format %{ "[$reg + $offset]" %}
 2348   interface(MEMORY_INTER) %{
 2349     base($reg);
 2350     index(0xf); // PC => no index
 2351     scale(0x0);
 2352     disp($offset);
 2353   %}
 2354 %}
 2355 
 2356 // Indirect with Offset and Offset+4 in ]-1024, 1024[
 2357 operand indOffsetFPx2(sp_ptr_RegP reg, immX10x2 offset) %{
 2358   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2359   match(AddP reg offset);
 2360 
 2361   op_cost(100);
 2362   format %{ "[$reg + $offset]" %}
 2363   interface(MEMORY_INTER) %{
 2364     base($reg);
 2365     index(0xf); // PC => no index
 2366     scale(0x0);
 2367     disp($offset);
 2368   %}
 2369 %}
 2370 
 2371 // Indirect with Offset and Offset+4 in ]-4096, 4096[
 2372 operand indOffset12x2(sp_ptr_RegP reg, immI12x2 offset) %{
 2373   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2374   match(AddP reg offset);
 2375 
 2376   op_cost(100);
 2377   format %{ "[$reg + $offset]" %}
 2378   interface(MEMORY_INTER) %{
 2379     base($reg);
 2380     index(0xf); // PC => no index
 2381     scale(0x0);
 2382     disp($offset);
 2383   %}
 2384 %}
 2385 
 2386 // Indirect with Register Index
 2387 operand indIndex(iRegP addr, iRegX index) %{
 2388   constraint(ALLOC_IN_RC(ptr_reg));
 2389   match(AddP addr index);
 2390 
 2391   op_cost(100);
 2392   format %{ "[$addr + $index]" %}
 2393   interface(MEMORY_INTER) %{
 2394     base($addr);
 2395     index($index);
 2396     scale(0x0);
 2397     disp(0x0);
 2398   %}
 2399 %}
 2400 
 2401 // Indirect Memory Times Scale Plus Index Register
 2402 operand indIndexScale(iRegP addr, iRegX index, immU5 scale) %{
 2403   constraint(ALLOC_IN_RC(ptr_reg));
 2404   match(AddP addr (LShiftX index scale));
 2405 
 2406   op_cost(100);
 2407   format %{"[$addr + $index << $scale]" %}
 2408   interface(MEMORY_INTER) %{
 2409     base($addr);
 2410     index($index);
 2411     scale($scale);
 2412     disp(0x0);
 2413   %}
 2414 %}
 2415 
 2416 // Operands for expressing Control Flow
 2417 // NOTE:  Label is a predefined operand which should not be redefined in
 2418 //        the AD file.  It is generically handled within the ADLC.
 2419 
 2420 //----------Conditional Branch Operands----------------------------------------
 2421 // Comparison Op  - This is the operation of the comparison, and is limited to
 2422 //                  the following set of codes:
 2423 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
 2424 //
 2425 // Other attributes of the comparison, such as unsignedness, are specified
 2426 // by the comparison instruction that sets a condition code flags register.
 2427 // That result is represented by a flags operand whose subtype is appropriate
 2428 // to the unsignedness (etc.) of the comparison.
 2429 //
 2430 // Later, the instruction which matches both the Comparison Op (a Bool) and
 2431 // the flags (produced by the Cmp) specifies the coding of the comparison op
 2432 // by matching a specific subtype of Bool operand below, such as cmpOpU.
 2433 
 2434 operand cmpOp() %{
 2435   match(Bool);
 2436 
 2437   format %{ "" %}
 2438   interface(COND_INTER) %{
 2439     equal(0x0);
 2440     not_equal(0x1);
 2441     less(0xb);
 2442     greater_equal(0xa);
 2443     less_equal(0xd);
 2444     greater(0xc);
 2445     overflow(0x0); // unsupported/unimplemented
 2446     no_overflow(0x0); // unsupported/unimplemented
 2447   %}
 2448 %}
 2449 
 2450 // integer comparison with 0, signed
 2451 operand cmpOp0() %{
 2452   match(Bool);
 2453 
 2454   format %{ "" %}
 2455   interface(COND_INTER) %{
 2456     equal(0x0);
 2457     not_equal(0x1);
 2458     less(0x4);
 2459     greater_equal(0x5);
 2460     less_equal(0xd); // unsupported
 2461     greater(0xc); // unsupported
 2462     overflow(0x0); // unsupported/unimplemented
 2463     no_overflow(0x0); // unsupported/unimplemented
 2464   %}
 2465 %}
 2466 
 2467 // Comparison Op, unsigned
 2468 operand cmpOpU() %{
 2469   match(Bool);
 2470 
 2471   format %{ "u" %}
 2472   interface(COND_INTER) %{
 2473     equal(0x0);
 2474     not_equal(0x1);
 2475     less(0x3);
 2476     greater_equal(0x2);
 2477     less_equal(0x9);
 2478     greater(0x8);
 2479     overflow(0x0); // unsupported/unimplemented
 2480     no_overflow(0x0); // unsupported/unimplemented
 2481   %}
 2482 %}
 2483 
 2484 // Comparison Op, pointer (same as unsigned)
 2485 operand cmpOpP() %{
 2486   match(Bool);
 2487 
 2488   format %{ "p" %}
 2489   interface(COND_INTER) %{
 2490     equal(0x0);
 2491     not_equal(0x1);
 2492     less(0x3);
 2493     greater_equal(0x2);
 2494     less_equal(0x9);
 2495     greater(0x8);
 2496     overflow(0x0); // unsupported/unimplemented
 2497     no_overflow(0x0); // unsupported/unimplemented
 2498   %}
 2499 %}
 2500 
 2501 operand cmpOpL() %{
 2502   match(Bool);
 2503 
 2504   format %{ "L" %}
 2505   interface(COND_INTER) %{
 2506     equal(0x0);
 2507     not_equal(0x1);
 2508     less(0xb);
 2509     greater_equal(0xa);
 2510     less_equal(0xd);
 2511     greater(0xc);
 2512     overflow(0x0); // unsupported/unimplemented
 2513     no_overflow(0x0); // unsupported/unimplemented
 2514   %}
 2515 %}
 2516 
 2517 operand cmpOpL_commute() %{
 2518   match(Bool);
 2519 
 2520   format %{ "L" %}
 2521   interface(COND_INTER) %{
 2522     equal(0x0);
 2523     not_equal(0x1);
 2524     less(0xc);
 2525     greater_equal(0xd);
 2526     less_equal(0xa);
 2527     greater(0xb);
 2528     overflow(0x0); // unsupported/unimplemented
 2529     no_overflow(0x0); // unsupported/unimplemented
 2530   %}
 2531 %}
 2532 
 2533 operand cmpOpUL() %{
 2534   match(Bool);
 2535 
 2536   format %{ "UL" %}
 2537   interface(COND_INTER) %{
 2538     equal(0x0);
 2539     not_equal(0x1);
 2540     less(0x3);
 2541     greater_equal(0x2);
 2542     less_equal(0x9);
 2543     greater(0x8);
 2544     overflow(0x0); // unsupported/unimplemented
 2545     no_overflow(0x0); // unsupported/unimplemented
 2546   %}
 2547 %}
 2548 
 2549 operand cmpOpUL_commute() %{
 2550   match(Bool);
 2551 
 2552   format %{ "UL" %}
 2553   interface(COND_INTER) %{
 2554     equal(0x0);
 2555     not_equal(0x1);
 2556     less(0x8);
 2557     greater_equal(0x9);
 2558     less_equal(0x2);
 2559     greater(0x3);
 2560     overflow(0x0); // unsupported/unimplemented
 2561     no_overflow(0x0); // unsupported/unimplemented
 2562   %}
 2563 %}
 2564 
 2565 
 2566 //----------OPERAND CLASSES----------------------------------------------------
 2567 // Operand Classes are groups of operands that are used to simplify
 2568 // instruction definitions by not requiring the AD writer to specify separate
 2569 // instructions for every form of operand when the instruction accepts
 2570 // multiple operand types with the same basic encoding and format.  The classic
 2571 // case of this is memory operands.
 2572 
 2573 opclass memoryI ( indirect, indOffset12, indIndex, indIndexScale );
 2574 opclass memoryP ( indirect, indOffset12, indIndex, indIndexScale );
 2575 opclass memoryF ( indirect, indOffsetFP );
 2576 opclass memoryF2 ( indirect, indOffsetFPx2 );
 2577 opclass memoryD ( indirect, indOffsetFP );
 2578 opclass memoryfp( indirect, indOffsetFP );
 2579 opclass memoryB ( indirect, indIndex, indOffsetHD );
 2580 opclass memoryS ( indirect, indIndex, indOffsetHD );
 2581 opclass memoryL ( indirect, indIndex, indOffsetHD );
 2582 
 2583 opclass memoryScaledI(indIndexScale);
 2584 opclass memoryScaledP(indIndexScale);
 2585 
 2586 // when ldrex/strex is used:
 2587 opclass memoryex ( indirect );
 2588 opclass indIndexMemory( indIndex );
 2589 opclass memorylong ( indirect, indOffset12x2 );
 2590 opclass memoryvld ( indirect /* , write back mode not implemented */ );
 2591 
 2592 //----------PIPELINE-----------------------------------------------------------
 2593 pipeline %{
 2594 
 2595 //----------ATTRIBUTES---------------------------------------------------------
 2596 attributes %{
 2597   fixed_size_instructions;           // Fixed size instructions
 2598   max_instructions_per_bundle = 4;   // Up to 4 instructions per bundle
 2599   instruction_unit_size = 4;         // An instruction is 4 bytes long
 2600   instruction_fetch_unit_size = 16;  // The processor fetches one line
 2601   instruction_fetch_units = 1;       // of 16 bytes
 2602 %}
 2603 
 2604 //----------RESOURCES----------------------------------------------------------
 2605 // Resources are the functional units available to the machine
 2606 resources(A0, A1, MS, BR, FA, FM, IDIV, FDIV, IALU = A0 | A1);
 2607 
 2608 //----------PIPELINE DESCRIPTION-----------------------------------------------
 2609 // Pipeline Description specifies the stages in the machine's pipeline
 2610 
 2611 pipe_desc(A, P, F, B, I, J, S, R, E, C, M, W, X, T, D);
 2612 
 2613 //----------PIPELINE CLASSES---------------------------------------------------
 2614 // Pipeline Classes describe the stages in which input and output are
 2615 // referenced by the hardware pipeline.
 2616 
 2617 // Integer ALU reg-reg operation
 2618 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 2619     single_instruction;
 2620     dst   : E(write);
 2621     src1  : R(read);
 2622     src2  : R(read);
 2623     IALU  : R;
 2624 %}
 2625 
 2626 // Integer ALU reg-reg long operation
 2627 pipe_class ialu_reg_reg_2(iRegL dst, iRegL src1, iRegL src2) %{
 2628     instruction_count(2);
 2629     dst   : E(write);
 2630     src1  : R(read);
 2631     src2  : R(read);
 2632     IALU  : R;
 2633     IALU  : R;
 2634 %}
 2635 
 2636 // Integer ALU reg-reg long dependent operation
 2637 pipe_class ialu_reg_reg_2_dep(iRegL dst, iRegL src1, iRegL src2, flagsReg cr) %{
 2638     instruction_count(1); multiple_bundles;
 2639     dst   : E(write);
 2640     src1  : R(read);
 2641     src2  : R(read);
 2642     cr    : E(write);
 2643     IALU  : R(2);
 2644 %}
 2645 
 2646 // Integer ALU reg-imm operation
 2647 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) %{
 2648     single_instruction;
 2649     dst   : E(write);
 2650     src1  : R(read);
 2651     IALU  : R;
 2652 %}
 2653 
 2654 // Integer ALU reg-reg operation with condition code
 2655 pipe_class ialu_cc_reg_reg(iRegI dst, iRegI src1, iRegI src2, flagsReg cr) %{
 2656     single_instruction;
 2657     dst   : E(write);
 2658     cr    : E(write);
 2659     src1  : R(read);
 2660     src2  : R(read);
 2661     IALU  : R;
 2662 %}
 2663 
 2664 // Integer ALU zero-reg operation
 2665 pipe_class ialu_zero_reg(iRegI dst, immI0 zero, iRegI src2) %{
 2666     single_instruction;
 2667     dst   : E(write);
 2668     src2  : R(read);
 2669     IALU  : R;
 2670 %}
 2671 
 2672 // Integer ALU zero-reg operation with condition code only
 2673 pipe_class ialu_cconly_zero_reg(flagsReg cr, iRegI src) %{
 2674     single_instruction;
 2675     cr    : E(write);
 2676     src   : R(read);
 2677     IALU  : R;
 2678 %}
 2679 
 2680 // Integer ALU reg-reg operation with condition code only
 2681 pipe_class ialu_cconly_reg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
 2682     single_instruction;
 2683     cr    : E(write);
 2684     src1  : R(read);
 2685     src2  : R(read);
 2686     IALU  : R;
 2687 %}
 2688 
 2689 // Integer ALU reg-imm operation with condition code only
 2690 pipe_class ialu_cconly_reg_imm(flagsReg cr, iRegI src1) %{
 2691     single_instruction;
 2692     cr    : E(write);
 2693     src1  : R(read);
 2694     IALU  : R;
 2695 %}
 2696 
 2697 // Integer ALU reg-reg-zero operation with condition code only
 2698 pipe_class ialu_cconly_reg_reg_zero(flagsReg cr, iRegI src1, iRegI src2, immI0 zero) %{
 2699     single_instruction;
 2700     cr    : E(write);
 2701     src1  : R(read);
 2702     src2  : R(read);
 2703     IALU  : R;
 2704 %}
 2705 
 2706 // Integer ALU reg-imm-zero operation with condition code only
 2707 pipe_class ialu_cconly_reg_imm_zero(flagsReg cr, iRegI src1, immI0 zero) %{
 2708     single_instruction;
 2709     cr    : E(write);
 2710     src1  : R(read);
 2711     IALU  : R;
 2712 %}
 2713 
 2714 // Integer ALU reg-reg operation with condition code, src1 modified
 2715 pipe_class ialu_cc_rwreg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
 2716     single_instruction;
 2717     cr    : E(write);
 2718     src1  : E(write);
 2719     src1  : R(read);
 2720     src2  : R(read);
 2721     IALU  : R;
 2722 %}
 2723 
 2724 pipe_class cmpL_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg cr ) %{
 2725     multiple_bundles;
 2726     dst   : E(write)+4;
 2727     cr    : E(write);
 2728     src1  : R(read);
 2729     src2  : R(read);
 2730     IALU  : R(3);
 2731     BR    : R(2);
 2732 %}
 2733 
 2734 // Integer ALU operation
 2735 pipe_class ialu_none(iRegI dst) %{
 2736     single_instruction;
 2737     dst   : E(write);
 2738     IALU  : R;
 2739 %}
 2740 
 2741 // Integer ALU reg operation
 2742 pipe_class ialu_reg(iRegI dst, iRegI src) %{
 2743     single_instruction; may_have_no_code;
 2744     dst   : E(write);
 2745     src   : R(read);
 2746     IALU  : R;
 2747 %}
 2748 
 2749 // Integer ALU reg conditional operation
 2750 // This instruction has a 1 cycle stall, and cannot execute
 2751 // in the same cycle as the instruction setting the condition
 2752 // code. We kludge this by pretending to read the condition code
 2753 // 1 cycle earlier, and by marking the functional units as busy
 2754 // for 2 cycles with the result available 1 cycle later than
 2755 // is really the case.
 2756 pipe_class ialu_reg_flags( iRegI op2_out, iRegI op2_in, iRegI op1, flagsReg cr ) %{
 2757     single_instruction;
 2758     op2_out : C(write);
 2759     op1     : R(read);
 2760     cr      : R(read);       // This is really E, with a 1 cycle stall
 2761     BR      : R(2);
 2762     MS      : R(2);
 2763 %}
 2764 
 2765 // Integer ALU reg operation
 2766 pipe_class ialu_move_reg_L_to_I(iRegI dst, iRegL src) %{
 2767     single_instruction; may_have_no_code;
 2768     dst   : E(write);
 2769     src   : R(read);
 2770     IALU  : R;
 2771 %}
 2772 pipe_class ialu_move_reg_I_to_L(iRegL dst, iRegI src) %{
 2773     single_instruction; may_have_no_code;
 2774     dst   : E(write);
 2775     src   : R(read);
 2776     IALU  : R;
 2777 %}
 2778 
 2779 // Two integer ALU reg operations
 2780 pipe_class ialu_reg_2(iRegL dst, iRegL src) %{
 2781     instruction_count(2);
 2782     dst   : E(write);
 2783     src   : R(read);
 2784     A0    : R;
 2785     A1    : R;
 2786 %}
 2787 
 2788 // Two integer ALU reg operations
 2789 pipe_class ialu_move_reg_L_to_L(iRegL dst, iRegL src) %{
 2790     instruction_count(2); may_have_no_code;
 2791     dst   : E(write);
 2792     src   : R(read);
 2793     A0    : R;
 2794     A1    : R;
 2795 %}
 2796 
 2797 // Integer ALU imm operation
 2798 pipe_class ialu_imm(iRegI dst) %{
 2799     single_instruction;
 2800     dst   : E(write);
 2801     IALU  : R;
 2802 %}
 2803 
 2804 pipe_class ialu_imm_n(iRegI dst) %{
 2805     single_instruction;
 2806     dst   : E(write);
 2807     IALU  : R;
 2808 %}
 2809 
 2810 // Integer ALU reg-reg with carry operation
 2811 pipe_class ialu_reg_reg_cy(iRegI dst, iRegI src1, iRegI src2, iRegI cy) %{
 2812     single_instruction;
 2813     dst   : E(write);
 2814     src1  : R(read);
 2815     src2  : R(read);
 2816     IALU  : R;
 2817 %}
 2818 
 2819 // Integer ALU cc operation
 2820 pipe_class ialu_cc(iRegI dst, flagsReg cc) %{
 2821     single_instruction;
 2822     dst   : E(write);
 2823     cc    : R(read);
 2824     IALU  : R;
 2825 %}
 2826 
 2827 // Integer ALU cc / second IALU operation
 2828 pipe_class ialu_reg_ialu( iRegI dst, iRegI src ) %{
 2829     instruction_count(1); multiple_bundles;
 2830     dst   : E(write)+1;
 2831     src   : R(read);
 2832     IALU  : R;
 2833 %}
 2834 
 2835 // Integer ALU cc / second IALU operation
 2836 pipe_class ialu_reg_reg_ialu( iRegI dst, iRegI p, iRegI q ) %{
 2837     instruction_count(1); multiple_bundles;
 2838     dst   : E(write)+1;
 2839     p     : R(read);
 2840     q     : R(read);
 2841     IALU  : R;
 2842 %}
 2843 
 2844 // Integer ALU hi-lo-reg operation
 2845 pipe_class ialu_hi_lo_reg(iRegI dst, immI src) %{
 2846     instruction_count(1); multiple_bundles;
 2847     dst   : E(write)+1;
 2848     IALU  : R(2);
 2849 %}
 2850 
 2851 // Long Constant
 2852 pipe_class loadConL( iRegL dst, immL src ) %{
 2853     instruction_count(2); multiple_bundles;
 2854     dst   : E(write)+1;
 2855     IALU  : R(2);
 2856     IALU  : R(2);
 2857 %}
 2858 
 2859 // Pointer Constant
 2860 pipe_class loadConP( iRegP dst, immP src ) %{
 2861     instruction_count(0); multiple_bundles;
 2862     fixed_latency(6);
 2863 %}
 2864 
 2865 // Long Constant small
 2866 pipe_class loadConLlo( iRegL dst, immL src ) %{
 2867     instruction_count(2);
 2868     dst   : E(write);
 2869     IALU  : R;
 2870     IALU  : R;
 2871 %}
 2872 
 2873 // [PHH] This is wrong for 64-bit.  See LdImmF/D.
 2874 pipe_class loadConFD(regF dst, immF src, iRegP tmp) %{
 2875     instruction_count(1); multiple_bundles;
 2876     src   : R(read);
 2877     dst   : M(write)+1;
 2878     IALU  : R;
 2879     MS    : E;
 2880 %}
 2881 
 2882 // Integer ALU nop operation
 2883 pipe_class ialu_nop() %{
 2884     single_instruction;
 2885     IALU  : R;
 2886 %}
 2887 
 2888 // Integer ALU nop operation
 2889 pipe_class ialu_nop_A0() %{
 2890     single_instruction;
 2891     A0    : R;
 2892 %}
 2893 
 2894 // Integer ALU nop operation
 2895 pipe_class ialu_nop_A1() %{
 2896     single_instruction;
 2897     A1    : R;
 2898 %}
 2899 
 2900 // Integer Multiply reg-reg operation
 2901 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 2902     single_instruction;
 2903     dst   : E(write);
 2904     src1  : R(read);
 2905     src2  : R(read);
 2906     MS    : R(5);
 2907 %}
 2908 
 2909 pipe_class mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 2910     single_instruction;
 2911     dst   : E(write)+4;
 2912     src1  : R(read);
 2913     src2  : R(read);
 2914     MS    : R(6);
 2915 %}
 2916 
 2917 // Integer Divide reg-reg
 2918 pipe_class sdiv_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI temp, flagsReg cr) %{
 2919     instruction_count(1); multiple_bundles;
 2920     dst   : E(write);
 2921     temp  : E(write);
 2922     src1  : R(read);
 2923     src2  : R(read);
 2924     temp  : R(read);
 2925     MS    : R(38);
 2926 %}
 2927 
 2928 // Long Divide
 2929 pipe_class divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 2930     dst  : E(write)+71;
 2931     src1 : R(read);
 2932     src2 : R(read)+1;
 2933     MS   : R(70);
 2934 %}
 2935 
 2936 // Floating Point Add Float
 2937 pipe_class faddF_reg_reg(regF dst, regF src1, regF src2) %{
 2938     single_instruction;
 2939     dst   : X(write);
 2940     src1  : E(read);
 2941     src2  : E(read);
 2942     FA    : R;
 2943 %}
 2944 
 2945 // Floating Point Add Double
 2946 pipe_class faddD_reg_reg(regD dst, regD src1, regD src2) %{
 2947     single_instruction;
 2948     dst   : X(write);
 2949     src1  : E(read);
 2950     src2  : E(read);
 2951     FA    : R;
 2952 %}
 2953 
 2954 // Floating Point Conditional Move based on integer flags
 2955 pipe_class int_conditional_float_move (cmpOp cmp, flagsReg cr, regF dst, regF src) %{
 2956     single_instruction;
 2957     dst   : X(write);
 2958     src   : E(read);
 2959     cr    : R(read);
 2960     FA    : R(2);
 2961     BR    : R(2);
 2962 %}
 2963 
 2964 // Floating Point Conditional Move based on integer flags
 2965 pipe_class int_conditional_double_move (cmpOp cmp, flagsReg cr, regD dst, regD src) %{
 2966     single_instruction;
 2967     dst   : X(write);
 2968     src   : E(read);
 2969     cr    : R(read);
 2970     FA    : R(2);
 2971     BR    : R(2);
 2972 %}
 2973 
 2974 // Floating Point Multiply Float
 2975 pipe_class fmulF_reg_reg(regF dst, regF src1, regF src2) %{
 2976     single_instruction;
 2977     dst   : X(write);
 2978     src1  : E(read);
 2979     src2  : E(read);
 2980     FM    : R;
 2981 %}
 2982 
 2983 // Floating Point Multiply Double
 2984 pipe_class fmulD_reg_reg(regD dst, regD src1, regD src2) %{
 2985     single_instruction;
 2986     dst   : X(write);
 2987     src1  : E(read);
 2988     src2  : E(read);
 2989     FM    : R;
 2990 %}
 2991 
 2992 // Floating Point Divide Float
 2993 pipe_class fdivF_reg_reg(regF dst, regF src1, regF src2) %{
 2994     single_instruction;
 2995     dst   : X(write);
 2996     src1  : E(read);
 2997     src2  : E(read);
 2998     FM    : R;
 2999     FDIV  : C(14);
 3000 %}
 3001 
 3002 // Floating Point Divide Double
 3003 pipe_class fdivD_reg_reg(regD dst, regD src1, regD src2) %{
 3004     single_instruction;
 3005     dst   : X(write);
 3006     src1  : E(read);
 3007     src2  : E(read);
 3008     FM    : R;
 3009     FDIV  : C(17);
 3010 %}
 3011 
 3012 // Floating Point Move/Negate/Abs Float
 3013 pipe_class faddF_reg(regF dst, regF src) %{
 3014     single_instruction;
 3015     dst   : W(write);
 3016     src   : E(read);
 3017     FA    : R(1);
 3018 %}
 3019 
 3020 // Floating Point Move/Negate/Abs Double
 3021 pipe_class faddD_reg(regD dst, regD src) %{
 3022     single_instruction;
 3023     dst   : W(write);
 3024     src   : E(read);
 3025     FA    : R;
 3026 %}
 3027 
 3028 // Floating Point Convert F->D
 3029 pipe_class fcvtF2D(regD dst, regF src) %{
 3030     single_instruction;
 3031     dst   : X(write);
 3032     src   : E(read);
 3033     FA    : R;
 3034 %}
 3035 
 3036 // Floating Point Convert I->D
 3037 pipe_class fcvtI2D(regD dst, regF src) %{
 3038     single_instruction;
 3039     dst   : X(write);
 3040     src   : E(read);
 3041     FA    : R;
 3042 %}
 3043 
 3044 // Floating Point Convert LHi->D
 3045 pipe_class fcvtLHi2D(regD dst, regD src) %{
 3046     single_instruction;
 3047     dst   : X(write);
 3048     src   : E(read);
 3049     FA    : R;
 3050 %}
 3051 
 3052 // Floating Point Convert L->D
 3053 pipe_class fcvtL2D(regD dst, iRegL src) %{
 3054     single_instruction;
 3055     dst   : X(write);
 3056     src   : E(read);
 3057     FA    : R;
 3058 %}
 3059 
 3060 // Floating Point Convert L->F
 3061 pipe_class fcvtL2F(regF dst, iRegL src) %{
 3062     single_instruction;
 3063     dst   : X(write);
 3064     src   : E(read);
 3065     FA    : R;
 3066 %}
 3067 
 3068 // Floating Point Convert D->F
 3069 pipe_class fcvtD2F(regD dst, regF src) %{
 3070     single_instruction;
 3071     dst   : X(write);
 3072     src   : E(read);
 3073     FA    : R;
 3074 %}
 3075 
 3076 // Floating Point Convert I->L
 3077 pipe_class fcvtI2L(regD dst, regF src) %{
 3078     single_instruction;
 3079     dst   : X(write);
 3080     src   : E(read);
 3081     FA    : R;
 3082 %}
 3083 
 3084 // Floating Point Convert D->F
 3085 pipe_class fcvtD2I(iRegI dst, regD src, flagsReg cr) %{
 3086     instruction_count(1); multiple_bundles;
 3087     dst   : X(write)+6;
 3088     src   : E(read);
 3089     FA    : R;
 3090 %}
 3091 
 3092 // Floating Point Convert D->L
 3093 pipe_class fcvtD2L(regD dst, regD src, flagsReg cr) %{
 3094     instruction_count(1); multiple_bundles;
 3095     dst   : X(write)+6;
 3096     src   : E(read);
 3097     FA    : R;
 3098 %}
 3099 
 3100 // Floating Point Convert F->I
 3101 pipe_class fcvtF2I(regF dst, regF src, flagsReg cr) %{
 3102     instruction_count(1); multiple_bundles;
 3103     dst   : X(write)+6;
 3104     src   : E(read);
 3105     FA    : R;
 3106 %}
 3107 
 3108 // Floating Point Convert F->L
 3109 pipe_class fcvtF2L(regD dst, regF src, flagsReg cr) %{
 3110     instruction_count(1); multiple_bundles;
 3111     dst   : X(write)+6;
 3112     src   : E(read);
 3113     FA    : R;
 3114 %}
 3115 
 3116 // Floating Point Convert I->F
 3117 pipe_class fcvtI2F(regF dst, regF src) %{
 3118     single_instruction;
 3119     dst   : X(write);
 3120     src   : E(read);
 3121     FA    : R;
 3122 %}
 3123 
 3124 // Floating Point Compare
 3125 pipe_class faddF_fcc_reg_reg_zero(flagsRegF cr, regF src1, regF src2, immI0 zero) %{
 3126     single_instruction;
 3127     cr    : X(write);
 3128     src1  : E(read);
 3129     src2  : E(read);
 3130     FA    : R;
 3131 %}
 3132 
 3133 // Floating Point Compare
 3134 pipe_class faddD_fcc_reg_reg_zero(flagsRegF cr, regD src1, regD src2, immI0 zero) %{
 3135     single_instruction;
 3136     cr    : X(write);
 3137     src1  : E(read);
 3138     src2  : E(read);
 3139     FA    : R;
 3140 %}
 3141 
 3142 // Floating Add Nop
 3143 pipe_class fadd_nop() %{
 3144     single_instruction;
 3145     FA  : R;
 3146 %}
 3147 
 3148 // Integer Store to Memory
 3149 pipe_class istore_mem_reg(memoryI mem, iRegI src) %{
 3150     single_instruction;
 3151     mem   : R(read);
 3152     src   : C(read);
 3153     MS    : R;
 3154 %}
 3155 
 3156 // Integer Store to Memory
 3157 pipe_class istore_mem_spORreg(memoryI mem, sp_ptr_RegP src) %{
 3158     single_instruction;
 3159     mem   : R(read);
 3160     src   : C(read);
 3161     MS    : R;
 3162 %}
 3163 
 3164 // Float Store
 3165 pipe_class fstoreF_mem_reg(memoryF mem, RegF src) %{
 3166     single_instruction;
 3167     mem : R(read);
 3168     src : C(read);
 3169     MS  : R;
 3170 %}
 3171 
 3172 // Float Store
 3173 pipe_class fstoreF_mem_zero(memoryF mem, immF0 src) %{
 3174     single_instruction;
 3175     mem : R(read);
 3176     MS  : R;
 3177 %}
 3178 
 3179 // Double Store
 3180 pipe_class fstoreD_mem_reg(memoryD mem, RegD src) %{
 3181     instruction_count(1);
 3182     mem : R(read);
 3183     src : C(read);
 3184     MS  : R;
 3185 %}
 3186 
 3187 // Double Store
 3188 pipe_class fstoreD_mem_zero(memoryD mem, immD0 src) %{
 3189     single_instruction;
 3190     mem : R(read);
 3191     MS  : R;
 3192 %}
 3193 
 3194 // Integer Load (when sign bit propagation not needed)
 3195 pipe_class iload_mem(iRegI dst, memoryI mem) %{
 3196     single_instruction;
 3197     mem : R(read);
 3198     dst : C(write);
 3199     MS  : R;
 3200 %}
 3201 
 3202 // Integer Load (when sign bit propagation or masking is needed)
 3203 pipe_class iload_mask_mem(iRegI dst, memoryI mem) %{
 3204     single_instruction;
 3205     mem : R(read);
 3206     dst : M(write);
 3207     MS  : R;
 3208 %}
 3209 
 3210 // Float Load
 3211 pipe_class floadF_mem(regF dst, memoryF mem) %{
 3212     single_instruction;
 3213     mem : R(read);
 3214     dst : M(write);
 3215     MS  : R;
 3216 %}
 3217 
 3218 // Float Load
 3219 pipe_class floadD_mem(regD dst, memoryD mem) %{
 3220     instruction_count(1); multiple_bundles; // Again, unaligned argument is only multiple case
 3221     mem : R(read);
 3222     dst : M(write);
 3223     MS  : R;
 3224 %}
 3225 
 3226 // Memory Nop
 3227 pipe_class mem_nop() %{
 3228     single_instruction;
 3229     MS  : R;
 3230 %}
 3231 
 3232 pipe_class sethi(iRegP dst, immI src) %{
 3233     single_instruction;
 3234     dst  : E(write);
 3235     IALU : R;
 3236 %}
 3237 
 3238 pipe_class loadPollP(iRegP poll) %{
 3239     single_instruction;
 3240     poll : R(read);
 3241     MS   : R;
 3242 %}
 3243 
 3244 pipe_class br(Universe br, label labl) %{
 3245     single_instruction;
 3246     BR  : R;
 3247 %}
 3248 
 3249 pipe_class br_cc(Universe br, cmpOp cmp, flagsReg cr, label labl) %{
 3250     single_instruction;
 3251     cr    : E(read);
 3252     BR    : R;
 3253 %}
 3254 
 3255 pipe_class br_reg(Universe br, cmpOp cmp, iRegI op1, label labl) %{
 3256     single_instruction;
 3257     op1 : E(read);
 3258     BR  : R;
 3259     MS  : R;
 3260 %}
 3261 
 3262 pipe_class br_nop() %{
 3263     single_instruction;
 3264     BR  : R;
 3265 %}
 3266 
 3267 pipe_class simple_call(method meth) %{
 3268     instruction_count(2); multiple_bundles; force_serialization;
 3269     fixed_latency(100);
 3270     BR  : R(1);
 3271     MS  : R(1);
 3272     A0  : R(1);
 3273 %}
 3274 
 3275 pipe_class compiled_call(method meth) %{
 3276     instruction_count(1); multiple_bundles; force_serialization;
 3277     fixed_latency(100);
 3278     MS  : R(1);
 3279 %}
 3280 
 3281 pipe_class call(method meth) %{
 3282     instruction_count(0); multiple_bundles; force_serialization;
 3283     fixed_latency(100);
 3284 %}
 3285 
 3286 pipe_class tail_call(Universe ignore, label labl) %{
 3287     single_instruction;
 3288     fixed_latency(100);
 3289     BR  : R(1);
 3290     MS  : R(1);
 3291 %}
 3292 
 3293 pipe_class ret(Universe ignore) %{
 3294     single_instruction;
 3295     BR  : R(1);
 3296     MS  : R(1);
 3297 %}
 3298 
 3299 // The real do-nothing guy
 3300 pipe_class empty( ) %{
 3301     instruction_count(0);
 3302 %}
 3303 
 3304 pipe_class long_memory_op() %{
 3305     instruction_count(0); multiple_bundles; force_serialization;
 3306     fixed_latency(25);
 3307     MS  : R(1);
 3308 %}
 3309 
 3310 // Check-cast
 3311 pipe_class partial_subtype_check_pipe(Universe ignore, iRegP array, iRegP match ) %{
 3312     array : R(read);
 3313     match  : R(read);
 3314     IALU   : R(2);
 3315     BR     : R(2);
 3316     MS     : R;
 3317 %}
 3318 
 3319 // Convert FPU flags into +1,0,-1
 3320 pipe_class floating_cmp( iRegI dst, regF src1, regF src2 ) %{
 3321     src1  : E(read);
 3322     src2  : E(read);
 3323     dst   : E(write);
 3324     FA    : R;
 3325     MS    : R(2);
 3326     BR    : R(2);
 3327 %}
 3328 
 3329 // Compare for p < q, and conditionally add y
 3330 pipe_class cadd_cmpltmask( iRegI p, iRegI q, iRegI y ) %{
 3331     p     : E(read);
 3332     q     : E(read);
 3333     y     : E(read);
 3334     IALU  : R(3)
 3335 %}
 3336 
 3337 // Define the class for the Nop node
 3338 define %{
 3339    MachNop = ialu_nop;
 3340 %}
 3341 
 3342 %}
 3343 
 3344 //----------INSTRUCTIONS-------------------------------------------------------
 3345 
 3346 //------------Special Nop instructions for bundling - no match rules-----------
 3347 // Nop using the A0 functional unit
 3348 instruct Nop_A0() %{
 3349   ins_pipe(ialu_nop_A0);
 3350 %}
 3351 
 3352 // Nop using the A1 functional unit
 3353 instruct Nop_A1( ) %{
 3354   ins_pipe(ialu_nop_A1);
 3355 %}
 3356 
 3357 // Nop using the memory functional unit
 3358 instruct Nop_MS( ) %{
 3359   ins_pipe(mem_nop);
 3360 %}
 3361 
 3362 // Nop using the floating add functional unit
 3363 instruct Nop_FA( ) %{
 3364   ins_pipe(fadd_nop);
 3365 %}
 3366 
 3367 // Nop using the branch functional unit
 3368 instruct Nop_BR( ) %{
 3369   ins_pipe(br_nop);
 3370 %}
 3371 
 3372 //----------Load/Store/Move Instructions---------------------------------------
 3373 //----------Load Instructions--------------------------------------------------
 3374 // Load Byte (8bit signed)
 3375 instruct loadB(iRegI dst, memoryB mem) %{
 3376   match(Set dst (LoadB mem));
 3377   ins_cost(MEMORY_REF_COST);
 3378 
 3379   size(4);
 3380   format %{ "LDRSB   $dst,$mem\t! byte -> int" %}
 3381   ins_encode %{
 3382     __ ldrsb($dst$$Register, $mem$$Address);
 3383   %}
 3384   ins_pipe(iload_mask_mem);
 3385 %}
 3386 
 3387 // Load Byte (8bit signed) into a Long Register
 3388 instruct loadB2L(iRegL dst, memoryB mem) %{
 3389   match(Set dst (ConvI2L (LoadB mem)));
 3390   ins_cost(MEMORY_REF_COST);
 3391 
 3392   size(8);
 3393   format %{ "LDRSB $dst.lo,$mem\t! byte -> long\n\t"
 3394             "ASR   $dst.hi,$dst.lo,31" %}
 3395   ins_encode %{
 3396     __ ldrsb($dst$$Register, $mem$$Address);
 3397     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
 3398   %}
 3399   ins_pipe(iload_mask_mem);
 3400 %}
 3401 
 3402 // Load Unsigned Byte (8bit UNsigned) into an int reg
 3403 instruct loadUB(iRegI dst, memoryB mem) %{
 3404   match(Set dst (LoadUB mem));
 3405   ins_cost(MEMORY_REF_COST);
 3406 
 3407   size(4);
 3408   format %{ "LDRB   $dst,$mem\t! ubyte -> int" %}
 3409   ins_encode %{
 3410     __ ldrb($dst$$Register, $mem$$Address);
 3411   %}
 3412   ins_pipe(iload_mem);
 3413 %}
 3414 
 3415 // Load Unsigned Byte (8bit UNsigned) into a Long Register
 3416 instruct loadUB2L(iRegL dst, memoryB mem) %{
 3417   match(Set dst (ConvI2L (LoadUB mem)));
 3418   ins_cost(MEMORY_REF_COST);
 3419 
 3420   size(8);
 3421   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
 3422             "MOV   $dst.hi,0" %}
 3423   ins_encode %{
 3424     __ ldrb($dst$$Register, $mem$$Address);
 3425     __ mov($dst$$Register->successor(), 0);
 3426   %}
 3427   ins_pipe(iload_mem);
 3428 %}
 3429 
 3430 // Load Unsigned Byte (8 bit UNsigned) with immediate mask into Long Register
 3431 instruct loadUB2L_limmI(iRegL dst, memoryB mem, limmIlow8 mask) %{
 3432   match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
 3433 
 3434   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 3435   size(12);
 3436   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
 3437             "MOV   $dst.hi,0\n\t"
 3438             "AND  $dst.lo,$dst.lo,$mask" %}
 3439   ins_encode %{
 3440     __ ldrb($dst$$Register, $mem$$Address);
 3441     __ mov($dst$$Register->successor(), 0);
 3442     __ andr($dst$$Register, $dst$$Register, limmI_low($mask$$constant, 8));
 3443   %}
 3444   ins_pipe(iload_mem);
 3445 %}
 3446 
 3447 // Load Short (16bit signed)
 3448 
 3449 instruct loadS(iRegI dst, memoryS mem) %{
 3450   match(Set dst (LoadS mem));
 3451   ins_cost(MEMORY_REF_COST);
 3452 
 3453   size(4);
 3454   format %{ "LDRSH   $dst,$mem\t! short" %}
 3455   ins_encode %{
 3456     __ ldrsh($dst$$Register, $mem$$Address);
 3457   %}
 3458   ins_pipe(iload_mask_mem);
 3459 %}
 3460 
 3461 // Load Short (16 bit signed) to Byte (8 bit signed)
 3462 instruct loadS2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
 3463   match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
 3464   ins_cost(MEMORY_REF_COST);
 3465 
 3466   size(4);
 3467 
 3468   format %{ "LDRSB   $dst,$mem\t! short -> byte" %}
 3469   ins_encode %{
 3470     __ ldrsb($dst$$Register, $mem$$Address);
 3471   %}
 3472   ins_pipe(iload_mask_mem);
 3473 %}
 3474 
 3475 // Load Short (16bit signed) into a Long Register
 3476 instruct loadS2L(iRegL dst, memoryS mem) %{
 3477   match(Set dst (ConvI2L (LoadS mem)));
 3478   ins_cost(MEMORY_REF_COST);
 3479 
 3480   size(8);
 3481   format %{ "LDRSH $dst.lo,$mem\t! short -> long\n\t"
 3482             "ASR   $dst.hi,$dst.lo,31" %}
 3483   ins_encode %{
 3484     __ ldrsh($dst$$Register, $mem$$Address);
 3485     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
 3486   %}
 3487   ins_pipe(iload_mask_mem);
 3488 %}
 3489 
 3490 // Load Unsigned Short/Char (16bit UNsigned)
 3491 
 3492 
 3493 instruct loadUS(iRegI dst, memoryS mem) %{
 3494   match(Set dst (LoadUS mem));
 3495   ins_cost(MEMORY_REF_COST);
 3496 
 3497   size(4);
 3498   format %{ "LDRH   $dst,$mem\t! ushort/char" %}
 3499   ins_encode %{
 3500     __ ldrh($dst$$Register, $mem$$Address);
 3501   %}
 3502   ins_pipe(iload_mem);
 3503 %}
 3504 
 3505 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
 3506 instruct loadUS2B(iRegI dst, memoryB mem, immI_24 twentyfour) %{
 3507   match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
 3508   ins_cost(MEMORY_REF_COST);
 3509 
 3510   size(4);
 3511   format %{ "LDRSB   $dst,$mem\t! ushort -> byte" %}
 3512   ins_encode %{
 3513     __ ldrsb($dst$$Register, $mem$$Address);
 3514   %}
 3515   ins_pipe(iload_mask_mem);
 3516 %}
 3517 
 3518 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register
 3519 instruct loadUS2L(iRegL dst, memoryS mem) %{
 3520   match(Set dst (ConvI2L (LoadUS mem)));
 3521   ins_cost(MEMORY_REF_COST);
 3522 
 3523   size(8);
 3524   format %{ "LDRH  $dst.lo,$mem\t! short -> long\n\t"
 3525             "MOV   $dst.hi, 0" %}
 3526   ins_encode %{
 3527     __ ldrh($dst$$Register, $mem$$Address);
 3528     __ mov($dst$$Register->successor(), 0);
 3529   %}
 3530   ins_pipe(iload_mem);
 3531 %}
 3532 
 3533 // Load Unsigned Short/Char (16bit UNsigned) with mask 0xFF into a Long Register
 3534 instruct loadUS2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
 3535   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
 3536   ins_cost(MEMORY_REF_COST);
 3537 
 3538   size(8);
 3539   format %{ "LDRB  $dst.lo,$mem\t! \n\t"
 3540             "MOV   $dst.hi, 0" %}
 3541   ins_encode %{
 3542     __ ldrb($dst$$Register, $mem$$Address);
 3543     __ mov($dst$$Register->successor(), 0);
 3544   %}
 3545   ins_pipe(iload_mem);
 3546 %}
 3547 
 3548 // Load Unsigned Short/Char (16bit UNsigned) with a immediate mask into a Long Register
 3549 instruct loadUS2L_limmI(iRegL dst, memoryS mem, limmI mask) %{
 3550   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
 3551   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 3552 
 3553   size(12);
 3554   format %{ "LDRH   $dst,$mem\t! ushort/char & mask -> long\n\t"
 3555             "MOV    $dst.hi, 0\n\t"
 3556             "AND    $dst,$dst,$mask" %}
 3557   ins_encode %{
 3558     __ ldrh($dst$$Register, $mem$$Address);
 3559     __ mov($dst$$Register->successor(), 0);
 3560     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
 3561   %}
 3562   ins_pipe(iload_mem);
 3563 %}
 3564 
 3565 // Load Integer
 3566 
 3567 
 3568 instruct loadI(iRegI dst, memoryI mem) %{
 3569   match(Set dst (LoadI mem));
 3570   ins_cost(MEMORY_REF_COST);
 3571 
 3572   size(4);
 3573   format %{ "ldr_s32 $dst,$mem\t! int" %}
 3574   ins_encode %{
 3575     __ ldr_s32($dst$$Register, $mem$$Address);
 3576   %}
 3577   ins_pipe(iload_mem);
 3578 %}
 3579 
 3580 // Load Integer to Byte (8 bit signed)
 3581 instruct loadI2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
 3582   match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
 3583   ins_cost(MEMORY_REF_COST);
 3584 
 3585   size(4);
 3586 
 3587   format %{ "LDRSB   $dst,$mem\t! int -> byte" %}
 3588   ins_encode %{
 3589     __ ldrsb($dst$$Register, $mem$$Address);
 3590   %}
 3591   ins_pipe(iload_mask_mem);
 3592 %}
 3593 
 3594 // Load Integer to Unsigned Byte (8 bit UNsigned)
 3595 instruct loadI2UB(iRegI dst, memoryB mem, immI_255 mask) %{
 3596   match(Set dst (AndI (LoadI mem) mask));
 3597   ins_cost(MEMORY_REF_COST);
 3598 
 3599   size(4);
 3600 
 3601   format %{ "LDRB   $dst,$mem\t! int -> ubyte" %}
 3602   ins_encode %{
 3603     __ ldrb($dst$$Register, $mem$$Address);
 3604   %}
 3605   ins_pipe(iload_mask_mem);
 3606 %}
 3607 
 3608 // Load Integer to Short (16 bit signed)
 3609 instruct loadI2S(iRegI dst, memoryS mem, immI_16 sixteen) %{
 3610   match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
 3611   ins_cost(MEMORY_REF_COST);
 3612 
 3613   size(4);
 3614   format %{ "LDRSH   $dst,$mem\t! int -> short" %}
 3615   ins_encode %{
 3616     __ ldrsh($dst$$Register, $mem$$Address);
 3617   %}
 3618   ins_pipe(iload_mask_mem);
 3619 %}
 3620 
 3621 // Load Integer to Unsigned Short (16 bit UNsigned)
 3622 instruct loadI2US(iRegI dst, memoryS mem, immI_65535 mask) %{
 3623   match(Set dst (AndI (LoadI mem) mask));
 3624   ins_cost(MEMORY_REF_COST);
 3625 
 3626   size(4);
 3627   format %{ "LDRH   $dst,$mem\t! int -> ushort/char" %}
 3628   ins_encode %{
 3629     __ ldrh($dst$$Register, $mem$$Address);
 3630   %}
 3631   ins_pipe(iload_mask_mem);
 3632 %}
 3633 
 3634 // Load Integer into a Long Register
 3635 instruct loadI2L(iRegL dst, memoryI mem) %{
 3636   match(Set dst (ConvI2L (LoadI mem)));
 3637   ins_cost(MEMORY_REF_COST);
 3638 
 3639   size(8);
 3640   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
 3641             "ASR   $dst.hi,$dst.lo,31\t! int->long" %}
 3642   ins_encode %{
 3643     __ ldr($dst$$Register, $mem$$Address);
 3644     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
 3645   %}
 3646   ins_pipe(iload_mask_mem);
 3647 %}
 3648 
 3649 // Load Integer with mask 0xFF into a Long Register
 3650 instruct loadI2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
 3651   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3652   ins_cost(MEMORY_REF_COST);
 3653 
 3654   size(8);
 3655   format %{ "LDRB   $dst.lo,$mem\t! int & 0xFF -> long\n\t"
 3656             "MOV    $dst.hi, 0" %}
 3657   ins_encode %{
 3658     __ ldrb($dst$$Register, $mem$$Address);
 3659     __ mov($dst$$Register->successor(), 0);
 3660   %}
 3661   ins_pipe(iload_mem);
 3662 %}
 3663 
 3664 // Load Integer with mask 0xFFFF into a Long Register
 3665 instruct loadI2L_immI_65535(iRegL dst, memoryS mem, immI_65535 mask) %{
 3666   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3667   ins_cost(MEMORY_REF_COST);
 3668 
 3669   size(8);
 3670   format %{ "LDRH   $dst,$mem\t! int & 0xFFFF -> long\n\t"
 3671             "MOV    $dst.hi, 0" %}
 3672   ins_encode %{
 3673     __ ldrh($dst$$Register, $mem$$Address);
 3674     __ mov($dst$$Register->successor(), 0);
 3675   %}
 3676   ins_pipe(iload_mask_mem);
 3677 %}
 3678 
 3679 // Load Integer with a 31-bit immediate mask into a Long Register
 3680 instruct loadI2L_limmU31(iRegL dst, memoryI mem, limmU31 mask) %{
 3681   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3682   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 3683 
 3684   size(12);
 3685   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
 3686             "MOV    $dst.hi, 0\n\t"
 3687             "AND   $dst,$dst,$mask" %}
 3688 
 3689   ins_encode %{
 3690     __ ldr($dst$$Register, $mem$$Address);
 3691     __ mov($dst$$Register->successor(), 0);
 3692     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
 3693   %}
 3694   ins_pipe(iload_mem);
 3695 %}
 3696 
 3697 // Load Integer with a 31-bit mask into a Long Register
 3698 // FIXME: use iRegI mask, remove tmp?
 3699 instruct loadI2L_immU31(iRegL dst, memoryI mem, immU31 mask, iRegI tmp) %{
 3700   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3701   effect(TEMP dst, TEMP tmp);
 3702 
 3703   ins_cost(MEMORY_REF_COST + 4*DEFAULT_COST);
 3704   size(20);
 3705   format %{ "LDR      $mem,$dst\t! int & 31-bit mask -> long\n\t"
 3706             "MOV      $dst.hi, 0\n\t"
 3707             "MOV_SLOW $tmp,$mask\n\t"
 3708             "AND      $dst,$tmp,$dst" %}
 3709   ins_encode %{
 3710     __ ldr($dst$$Register, $mem$$Address);
 3711     __ mov($dst$$Register->successor(), 0);
 3712     __ mov_slow($tmp$$Register, $mask$$constant);
 3713     __ andr($dst$$Register, $dst$$Register, $tmp$$Register);
 3714   %}
 3715   ins_pipe(iload_mem);
 3716 %}
 3717 
 3718 // Load Unsigned Integer into a Long Register
 3719 instruct loadUI2L(iRegL dst, memoryI mem, immL_32bits mask) %{
 3720   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
 3721   ins_cost(MEMORY_REF_COST);
 3722 
 3723   size(8);
 3724   format %{ "LDR   $dst.lo,$mem\t! uint -> long\n\t"
 3725             "MOV   $dst.hi,0" %}
 3726   ins_encode %{
 3727     __ ldr($dst$$Register, $mem$$Address);
 3728     __ mov($dst$$Register->successor(), 0);
 3729   %}
 3730   ins_pipe(iload_mem);
 3731 %}
 3732 
 3733 // Load Long
 3734 
 3735 
 3736 instruct loadL(iRegLd dst, memoryL mem ) %{
 3737   predicate(!((LoadLNode*)n)->require_atomic_access());
 3738   match(Set dst (LoadL mem));
 3739   effect(TEMP dst);
 3740   ins_cost(MEMORY_REF_COST);
 3741 
 3742   size(4);
 3743   format %{ "ldr_64  $dst,$mem\t! long" %}
 3744   ins_encode %{
 3745     __ ldr_64($dst$$Register, $mem$$Address);
 3746   %}
 3747   ins_pipe(iload_mem);
 3748 %}
 3749 
 3750 instruct loadL_2instr(iRegL dst, memorylong mem ) %{
 3751   predicate(!((LoadLNode*)n)->require_atomic_access());
 3752   match(Set dst (LoadL mem));
 3753   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
 3754 
 3755   size(8);
 3756   format %{ "LDR    $dst.lo,$mem \t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
 3757             "LDR    $dst.hi,$mem+4 or $mem" %}
 3758   ins_encode %{
 3759     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 3760     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 3761 
 3762     if ($dst$$Register == reg_to_register_object($mem$$base)) {
 3763       __ ldr($dst$$Register->successor(), Amemhi);
 3764       __ ldr($dst$$Register, Amemlo);
 3765     } else {
 3766       __ ldr($dst$$Register, Amemlo);
 3767       __ ldr($dst$$Register->successor(), Amemhi);
 3768     }
 3769   %}
 3770   ins_pipe(iload_mem);
 3771 %}
 3772 
 3773 instruct loadL_volatile(iRegL dst, indirect mem ) %{
 3774   predicate(((LoadLNode*)n)->require_atomic_access());
 3775   match(Set dst (LoadL mem));
 3776   ins_cost(MEMORY_REF_COST);
 3777 
 3778   size(4);
 3779   format %{ "LDMIA    $dst,$mem\t! long" %}
 3780   ins_encode %{
 3781     // FIXME: why is ldmia considered atomic?  Should be ldrexd
 3782     RegisterSet set($dst$$Register);
 3783     set = set | reg_to_register_object($dst$$reg + 1);
 3784     __ ldmia(reg_to_register_object($mem$$base), set);
 3785   %}
 3786   ins_pipe(iload_mem);
 3787 %}
 3788 
 3789 instruct loadL_volatile_fp(iRegL dst, memoryD mem ) %{
 3790   predicate(((LoadLNode*)n)->require_atomic_access());
 3791   match(Set dst (LoadL mem));
 3792   ins_cost(MEMORY_REF_COST);
 3793 
 3794   size(8);
 3795   format %{ "FLDD      S14, $mem"
 3796             "FMRRD    $dst, S14\t! long \n't" %}
 3797   ins_encode %{
 3798     __ fldd(S14, $mem$$Address);
 3799     __ fmrrd($dst$$Register, $dst$$Register->successor(), S14);
 3800   %}
 3801   ins_pipe(iload_mem);
 3802 %}
 3803 
 3804 instruct loadL_unaligned(iRegL dst, memorylong mem ) %{
 3805   match(Set dst (LoadL_unaligned mem));
 3806   ins_cost(MEMORY_REF_COST);
 3807 
 3808   size(8);
 3809   format %{ "LDR    $dst.lo,$mem\t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
 3810             "LDR    $dst.hi,$mem+4" %}
 3811   ins_encode %{
 3812     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 3813     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 3814 
 3815     if ($dst$$Register == reg_to_register_object($mem$$base)) {
 3816       __ ldr($dst$$Register->successor(), Amemhi);
 3817       __ ldr($dst$$Register, Amemlo);
 3818     } else {
 3819       __ ldr($dst$$Register, Amemlo);
 3820       __ ldr($dst$$Register->successor(), Amemhi);
 3821     }
 3822   %}
 3823   ins_pipe(iload_mem);
 3824 %}
 3825 
 3826 // Load Range
 3827 instruct loadRange(iRegI dst, memoryI mem) %{
 3828   match(Set dst (LoadRange mem));
 3829   ins_cost(MEMORY_REF_COST);
 3830 
 3831   size(4);
 3832   format %{ "LDR_u32 $dst,$mem\t! range" %}
 3833   ins_encode %{
 3834     __ ldr_u32($dst$$Register, $mem$$Address);
 3835   %}
 3836   ins_pipe(iload_mem);
 3837 %}
 3838 
 3839 // Load Pointer
 3840 
 3841 
 3842 instruct loadP(iRegP dst, memoryP mem) %{
 3843   predicate(!(UseG1GC && n->as_Load()->barrier_data() != 0));
 3844   match(Set dst (LoadP mem));
 3845   ins_cost(MEMORY_REF_COST);
 3846   size(4);
 3847 
 3848   format %{ "LDR   $dst,$mem\t! ptr" %}
 3849   ins_encode %{
 3850     __ ldr($dst$$Register, $mem$$Address);
 3851   %}
 3852   ins_pipe(iload_mem);
 3853 %}
 3854 
 3855 #ifdef XXX
 3856 // FIXME XXXX
 3857 //instruct loadSP(iRegP dst, memoryP mem) %{
 3858 instruct loadSP(SPRegP dst, memoryP mem, iRegP tmp) %{
 3859   match(Set dst (LoadP mem));
 3860   effect(TEMP tmp);
 3861   ins_cost(MEMORY_REF_COST+1);
 3862   size(8);
 3863 
 3864   format %{ "LDR   $tmp,$mem\t! ptr\n\t"
 3865             "MOV   $dst,$tmp\t! ptr" %}
 3866   ins_encode %{
 3867     __ ldr($tmp$$Register, $mem$$Address);
 3868     __ mov($dst$$Register, $tmp$$Register);
 3869   %}
 3870   ins_pipe(iload_mem);
 3871 %}
 3872 #endif
 3873 
 3874 #ifdef _LP64
 3875 // Load Compressed Pointer
 3876 
 3877 // XXX This variant shouldn't be necessary if 6217251 is implemented
 3878 instruct loadNoff(iRegN dst, memoryScaledI mem, aimmX off, iRegP tmp) %{
 3879   match(Set dst (LoadN (AddP mem off)));
 3880   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
 3881   effect(TEMP tmp);
 3882   size(4 * 2);
 3883 
 3884   format %{ "ldr_u32 $dst,$mem+$off\t! compressed ptr temp=$tmp" %}
 3885   ins_encode %{
 3886     Register base = reg_to_register_object($mem$$base);
 3887     __ add($tmp$$Register, base, $off$$constant);
 3888     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 3889     __ ldr_u32($dst$$Register, nmem);
 3890   %}
 3891   ins_pipe(iload_mem);
 3892 %}
 3893 
 3894 instruct loadN(iRegN dst, memoryI mem) %{
 3895   match(Set dst (LoadN mem));
 3896   ins_cost(MEMORY_REF_COST);
 3897   size(4);
 3898 
 3899   format %{ "ldr_u32 $dst,$mem\t! compressed ptr" %}
 3900   ins_encode %{
 3901     __ ldr_u32($dst$$Register, $mem$$Address);
 3902   %}
 3903   ins_pipe(iload_mem);
 3904 %}
 3905 #endif
 3906 
 3907 // Load Klass Pointer
 3908 instruct loadKlass(iRegP dst, memoryI mem) %{
 3909   match(Set dst (LoadKlass mem));
 3910   ins_cost(MEMORY_REF_COST);
 3911   size(4);
 3912 
 3913   format %{ "LDR   $dst,$mem\t! klass ptr" %}
 3914   ins_encode %{
 3915     __ ldr($dst$$Register, $mem$$Address);
 3916   %}
 3917   ins_pipe(iload_mem);
 3918 %}
 3919 
 3920 #ifdef _LP64
 3921 // Load narrow Klass Pointer
 3922 instruct loadNKlass(iRegN dst, memoryI mem) %{
 3923   match(Set dst (LoadNKlass mem));
 3924   ins_cost(MEMORY_REF_COST);
 3925   size(4);
 3926 
 3927   format %{ "ldr_u32 $dst,$mem\t! compressed klass ptr" %}
 3928   ins_encode %{
 3929     __ ldr_u32($dst$$Register, $mem$$Address);
 3930   %}
 3931   ins_pipe(iload_mem);
 3932 %}
 3933 #endif
 3934 
 3935 
 3936 instruct loadD(regD dst, memoryD mem) %{
 3937   match(Set dst (LoadD mem));
 3938   ins_cost(MEMORY_REF_COST);
 3939 
 3940   size(4);
 3941   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
 3942   // only LDREXD and STREXD are 64-bit single-copy atomic
 3943   format %{ "FLDD   $dst,$mem" %}
 3944   ins_encode %{
 3945     __ ldr_double($dst$$FloatRegister, $mem$$Address);
 3946   %}
 3947   ins_pipe(floadD_mem);
 3948 %}
 3949 
 3950 // Load Double - UNaligned
 3951 instruct loadD_unaligned(regD_low dst, memoryF2 mem ) %{
 3952   match(Set dst (LoadD_unaligned mem));
 3953   ins_cost(MEMORY_REF_COST*2+DEFAULT_COST);
 3954   size(8);
 3955   format %{ "FLDS    $dst.lo,$mem\t! misaligned double\n"
 3956           "\tFLDS    $dst.hi,$mem+4\t!" %}
 3957   ins_encode %{
 3958     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 3959     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 3960       __ flds($dst$$FloatRegister, Amemlo);
 3961       __ flds($dst$$FloatRegister->successor(), Amemhi);
 3962   %}
 3963   ins_pipe(iload_mem);
 3964 %}
 3965 
 3966 
 3967 instruct loadF(regF dst, memoryF mem) %{
 3968   match(Set dst (LoadF mem));
 3969 
 3970   ins_cost(MEMORY_REF_COST);
 3971   size(4);
 3972   format %{ "FLDS    $dst,$mem" %}
 3973   ins_encode %{
 3974     __ ldr_float($dst$$FloatRegister, $mem$$Address);
 3975   %}
 3976   ins_pipe(floadF_mem);
 3977 %}
 3978 
 3979 
 3980 // // Load Constant
 3981 instruct loadConI( iRegI dst, immI src ) %{
 3982   match(Set dst src);
 3983   ins_cost(DEFAULT_COST * 3/2);
 3984   format %{ "MOV_SLOW    $dst, $src" %}
 3985   ins_encode %{
 3986     __ mov_slow($dst$$Register, $src$$constant);
 3987   %}
 3988   ins_pipe(ialu_hi_lo_reg);
 3989 %}
 3990 
 3991 instruct loadConIMov( iRegI dst, immIMov src ) %{
 3992   match(Set dst src);
 3993   size(4);
 3994   format %{ "MOV    $dst, $src" %}
 3995   ins_encode %{
 3996     __ mov($dst$$Register, $src$$constant);
 3997   %}
 3998   ins_pipe(ialu_imm);
 3999 %}
 4000 
 4001 instruct loadConIMovn( iRegI dst, immIRotn src ) %{
 4002   match(Set dst src);
 4003   size(4);
 4004   format %{ "MVN    $dst, ~$src" %}
 4005   ins_encode %{
 4006     __ mvn($dst$$Register, ~$src$$constant);
 4007   %}
 4008   ins_pipe(ialu_imm_n);
 4009 %}
 4010 
 4011 instruct loadConI16( iRegI dst, immI16 src ) %{
 4012   match(Set dst src);
 4013   size(4);
 4014   format %{ "MOVW    $dst, $src" %}
 4015   ins_encode %{
 4016     __ movw($dst$$Register, $src$$constant);
 4017   %}
 4018   ins_pipe(ialu_imm_n);
 4019 %}
 4020 
 4021 instruct loadConP(iRegP dst, immP src) %{
 4022   match(Set dst src);
 4023   ins_cost(DEFAULT_COST * 3/2);
 4024   format %{ "MOV_SLOW    $dst,$src\t!ptr" %}
 4025   ins_encode %{
 4026     relocInfo::relocType constant_reloc = _opnds[1]->constant_reloc();
 4027     intptr_t val = $src$$constant;
 4028     if (constant_reloc == relocInfo::oop_type) {
 4029       __ mov_oop($dst$$Register, (jobject)val);
 4030     } else if (constant_reloc == relocInfo::metadata_type) {
 4031       __ mov_metadata($dst$$Register, (Metadata*)val);
 4032     } else {
 4033       __ mov_slow($dst$$Register, val);
 4034     }
 4035   %}
 4036   ins_pipe(loadConP);
 4037 %}
 4038 
 4039 
 4040 instruct loadConL(iRegL dst, immL src) %{
 4041   match(Set dst src);
 4042   ins_cost(DEFAULT_COST * 4);
 4043   format %{ "MOV_SLOW   $dst.lo, $src & 0x0FFFFFFFFL \t! long\n\t"
 4044             "MOV_SLOW   $dst.hi, $src >> 32" %}
 4045   ins_encode %{
 4046     __ mov_slow(reg_to_register_object($dst$$reg), $src$$constant & 0x0FFFFFFFFL);
 4047     __ mov_slow(reg_to_register_object($dst$$reg + 1), ((julong)($src$$constant)) >> 32);
 4048   %}
 4049   ins_pipe(loadConL);
 4050 %}
 4051 
 4052 instruct loadConL16( iRegL dst, immL16 src ) %{
 4053   match(Set dst src);
 4054   ins_cost(DEFAULT_COST * 2);
 4055 
 4056   size(8);
 4057   format %{ "MOVW    $dst.lo, $src \n\t"
 4058             "MOVW    $dst.hi, 0 \n\t" %}
 4059   ins_encode %{
 4060     __ movw($dst$$Register, $src$$constant);
 4061     __ movw($dst$$Register->successor(), 0);
 4062   %}
 4063   ins_pipe(ialu_imm);
 4064 %}
 4065 
 4066 instruct loadConF_imm8(regF dst, imm8F src) %{
 4067   match(Set dst src);
 4068   ins_cost(DEFAULT_COST);
 4069   size(4);
 4070 
 4071   format %{ "FCONSTS      $dst, $src"%}
 4072 
 4073   ins_encode %{
 4074     __ fconsts($dst$$FloatRegister, Assembler::float_num($src$$constant).imm8());
 4075   %}
 4076   ins_pipe(loadConFD); // FIXME
 4077 %}
 4078 
 4079 
 4080 instruct loadConF(regF dst, immF src, iRegI tmp) %{
 4081   match(Set dst src);
 4082   ins_cost(DEFAULT_COST * 2);
 4083   effect(TEMP tmp);
 4084   size(3*4);
 4085 
 4086   format %{ "MOV_SLOW  $tmp, $src\n\t"
 4087             "FMSR      $dst, $tmp"%}
 4088 
 4089   ins_encode %{
 4090     // FIXME revisit once 6961697 is in
 4091     union {
 4092       jfloat f;
 4093       int i;
 4094     } v;
 4095     v.f = $src$$constant;
 4096     __ mov_slow($tmp$$Register, v.i);
 4097     __ fmsr($dst$$FloatRegister, $tmp$$Register);
 4098   %}
 4099   ins_pipe(loadConFD); // FIXME
 4100 %}
 4101 
 4102 instruct loadConD_imm8(regD dst, imm8D src) %{
 4103   match(Set dst src);
 4104   ins_cost(DEFAULT_COST);
 4105   size(4);
 4106 
 4107   format %{ "FCONSTD      $dst, $src"%}
 4108 
 4109   ins_encode %{
 4110     __ fconstd($dst$$FloatRegister, Assembler::double_num($src$$constant).imm8());
 4111   %}
 4112   ins_pipe(loadConFD); // FIXME
 4113 %}
 4114 
 4115 instruct loadConD(regD dst, immD src, iRegP tmp) %{
 4116   match(Set dst src);
 4117   effect(TEMP tmp);
 4118   ins_cost(MEMORY_REF_COST);
 4119   format %{ "FLDD  $dst, [$constanttablebase + $constantoffset]\t! load from constant table: double=$src" %}
 4120 
 4121   ins_encode %{
 4122     Register r = $constanttablebase;
 4123     int offset  = $constantoffset($src);
 4124     if (!is_memoryD(offset)) {                // can't use a predicate
 4125                                               // in load constant instructs
 4126       __ add_slow($tmp$$Register, r, offset);
 4127       r = $tmp$$Register;
 4128       offset = 0;
 4129     }
 4130     __ ldr_double($dst$$FloatRegister, Address(r, offset));
 4131   %}
 4132   ins_pipe(loadConFD);
 4133 %}
 4134 
 4135 // Prefetch instructions.
 4136 // Must be safe to execute with invalid address (cannot fault).
 4137 
 4138 instruct prefetchAlloc_mp( memoryP mem ) %{
 4139   predicate(VM_Version::has_multiprocessing_extensions());
 4140   match( PrefetchAllocation mem );
 4141   ins_cost(MEMORY_REF_COST);
 4142   size(4);
 4143 
 4144   format %{ "PLDW $mem\t! Prefetch allocation" %}
 4145   ins_encode %{
 4146     __ pldw($mem$$Address);
 4147   %}
 4148   ins_pipe(iload_mem);
 4149 %}
 4150 
 4151 instruct prefetchAlloc_sp( memoryP mem ) %{
 4152   predicate(!VM_Version::has_multiprocessing_extensions());
 4153   match( PrefetchAllocation mem );
 4154   ins_cost(MEMORY_REF_COST);
 4155   size(4);
 4156 
 4157   format %{ "PLD $mem\t! Prefetch allocation" %}
 4158   ins_encode %{
 4159     __ pld($mem$$Address);
 4160   %}
 4161   ins_pipe(iload_mem);
 4162 %}
 4163 
 4164 
 4165 //----------Store Instructions-------------------------------------------------
 4166 // Store Byte
 4167 instruct storeB(memoryB mem, store_RegI src) %{
 4168   match(Set mem (StoreB mem src));
 4169   ins_cost(MEMORY_REF_COST);
 4170 
 4171   size(4);
 4172   format %{ "STRB    $src,$mem\t! byte" %}
 4173   ins_encode %{
 4174     __ strb($src$$Register, $mem$$Address);
 4175   %}
 4176   ins_pipe(istore_mem_reg);
 4177 %}
 4178 
 4179 // Store Char/Short
 4180 
 4181 
 4182 instruct storeC(memoryS mem, store_RegI src) %{
 4183   match(Set mem (StoreC mem src));
 4184   ins_cost(MEMORY_REF_COST);
 4185 
 4186   size(4);
 4187   format %{ "STRH    $src,$mem\t! short" %}
 4188   ins_encode %{
 4189     __ strh($src$$Register, $mem$$Address);
 4190   %}
 4191   ins_pipe(istore_mem_reg);
 4192 %}
 4193 
 4194 // Store Integer
 4195 
 4196 
 4197 instruct storeI(memoryI mem, store_RegI src) %{
 4198   match(Set mem (StoreI mem src));
 4199   ins_cost(MEMORY_REF_COST);
 4200 
 4201   size(4);
 4202   format %{ "str_32 $src,$mem" %}
 4203   ins_encode %{
 4204     __ str_32($src$$Register, $mem$$Address);
 4205   %}
 4206   ins_pipe(istore_mem_reg);
 4207 %}
 4208 
 4209 // Store Long
 4210 
 4211 
 4212 instruct storeL(memoryL mem, store_RegLd src) %{
 4213   predicate(!((StoreLNode*)n)->require_atomic_access());
 4214   match(Set mem (StoreL mem src));
 4215   ins_cost(MEMORY_REF_COST);
 4216 
 4217   size(4);
 4218   format %{ "str_64  $src,$mem\t! long\n\t" %}
 4219 
 4220   ins_encode %{
 4221     __ str_64($src$$Register, $mem$$Address);
 4222   %}
 4223   ins_pipe(istore_mem_reg);
 4224 %}
 4225 
 4226 instruct storeL_2instr(memorylong mem, iRegL src) %{
 4227   predicate(!((StoreLNode*)n)->require_atomic_access());
 4228   match(Set mem (StoreL mem src));
 4229   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
 4230 
 4231   size(8);
 4232   format %{ "STR    $src.lo,$mem\t! long\n\t"
 4233             "STR    $src.hi,$mem+4" %}
 4234 
 4235   ins_encode %{
 4236     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 4237     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 4238     __ str($src$$Register, Amemlo);
 4239     __ str($src$$Register->successor(), Amemhi);
 4240   %}
 4241   ins_pipe(istore_mem_reg);
 4242 %}
 4243 
 4244 instruct storeL_volatile(indirect mem, iRegL src) %{
 4245   predicate(((StoreLNode*)n)->require_atomic_access());
 4246   match(Set mem (StoreL mem src));
 4247   ins_cost(MEMORY_REF_COST);
 4248   size(4);
 4249   format %{ "STMIA    $src,$mem\t! long" %}
 4250   ins_encode %{
 4251     // FIXME: why is stmia considered atomic?  Should be strexd
 4252     RegisterSet set($src$$Register);
 4253     set = set | reg_to_register_object($src$$reg + 1);
 4254     __ stmia(reg_to_register_object($mem$$base), set);
 4255   %}
 4256   ins_pipe(istore_mem_reg);
 4257 %}
 4258 
 4259 instruct storeL_volatile_fp(memoryD mem, iRegL src) %{
 4260   predicate(((StoreLNode*)n)->require_atomic_access());
 4261   match(Set mem (StoreL mem src));
 4262   ins_cost(MEMORY_REF_COST);
 4263   size(8);
 4264   format %{ "FMDRR    S14, $src\t! long \n\t"
 4265             "FSTD     S14, $mem" %}
 4266   ins_encode %{
 4267     __ fmdrr(S14, $src$$Register, $src$$Register->successor());
 4268     __ fstd(S14, $mem$$Address);
 4269   %}
 4270   ins_pipe(istore_mem_reg);
 4271 %}
 4272 
 4273 #ifdef XXX
 4274 // Move SP Pointer
 4275 //instruct movSP(sp_ptr_RegP dst, SPRegP src) %{
 4276 //instruct movSP(iRegP dst, SPRegP src) %{
 4277 instruct movSP(store_ptr_RegP dst, SPRegP src) %{
 4278   match(Set dst src);
 4279 //predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con == TypeFunc::FramePtr);
 4280   ins_cost(MEMORY_REF_COST);
 4281   size(4);
 4282 
 4283   format %{ "MOV    $dst,$src\t! SP ptr\n\t" %}
 4284   ins_encode %{
 4285     assert(false, "XXX1 got here");
 4286     __ mov($dst$$Register, SP);
 4287     __ mov($dst$$Register, $src$$Register);
 4288   %}
 4289   ins_pipe(ialu_reg);
 4290 %}
 4291 #endif
 4292 
 4293 
 4294 // Store Pointer
 4295 
 4296 
 4297 instruct storeP(memoryP mem, store_ptr_RegP src) %{
 4298   predicate(!(UseG1GC && n->as_Store()->barrier_data() != 0));
 4299   match(Set mem (StoreP mem src));
 4300   ins_cost(MEMORY_REF_COST);
 4301   size(4);
 4302 
 4303   format %{ "STR    $src,$mem\t! ptr" %}
 4304   ins_encode %{
 4305     __ str($src$$Register, $mem$$Address);
 4306   %}
 4307   ins_pipe(istore_mem_spORreg);
 4308 %}
 4309 
 4310 
 4311 #ifdef _LP64
 4312 // Store Compressed Pointer
 4313 
 4314 
 4315 instruct storeN(memoryI mem, store_RegN src) %{
 4316   match(Set mem (StoreN mem src));
 4317   ins_cost(MEMORY_REF_COST);
 4318   size(4);
 4319 
 4320   format %{ "str_32 $src,$mem\t! compressed ptr" %}
 4321   ins_encode %{
 4322     __ str_32($src$$Register, $mem$$Address);
 4323   %}
 4324   ins_pipe(istore_mem_reg);
 4325 %}
 4326 
 4327 
 4328 // Store Compressed Klass Pointer
 4329 instruct storeNKlass(memoryI mem, store_RegN src) %{
 4330   match(Set mem (StoreNKlass mem src));
 4331   ins_cost(MEMORY_REF_COST);
 4332   size(4);
 4333 
 4334   format %{ "str_32 $src,$mem\t! compressed klass ptr" %}
 4335   ins_encode %{
 4336     __ str_32($src$$Register, $mem$$Address);
 4337   %}
 4338   ins_pipe(istore_mem_reg);
 4339 %}
 4340 #endif
 4341 
 4342 // Store Double
 4343 
 4344 
 4345 instruct storeD(memoryD mem, regD src) %{
 4346   match(Set mem (StoreD mem src));
 4347   ins_cost(MEMORY_REF_COST);
 4348 
 4349   size(4);
 4350   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
 4351   // only LDREXD and STREXD are 64-bit single-copy atomic
 4352   format %{ "FSTD   $src,$mem" %}
 4353   ins_encode %{
 4354     __ str_double($src$$FloatRegister, $mem$$Address);
 4355   %}
 4356   ins_pipe(fstoreD_mem_reg);
 4357 %}
 4358 
 4359 
 4360 // Store Float
 4361 
 4362 
 4363 instruct storeF( memoryF mem, regF src) %{
 4364   match(Set mem (StoreF mem src));
 4365   ins_cost(MEMORY_REF_COST);
 4366 
 4367   size(4);
 4368   format %{ "FSTS    $src,$mem" %}
 4369   ins_encode %{
 4370     __ str_float($src$$FloatRegister, $mem$$Address);
 4371   %}
 4372   ins_pipe(fstoreF_mem_reg);
 4373 %}
 4374 
 4375 
 4376 //----------MemBar Instructions-----------------------------------------------
 4377 // Memory barrier flavors
 4378 
 4379 // pattern-match out unnecessary membars
 4380 instruct membar_storestore() %{
 4381   match(MemBarStoreStore);
 4382   match(StoreStoreFence);
 4383   ins_cost(4*MEMORY_REF_COST);
 4384 
 4385   size(4);
 4386   format %{ "MEMBAR-storestore" %}
 4387   ins_encode %{
 4388     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore), noreg);
 4389   %}
 4390   ins_pipe(long_memory_op);
 4391 %}
 4392 
 4393 instruct membar_acquire() %{
 4394   match(MemBarAcquire);
 4395   match(LoadFence);
 4396   ins_cost(4*MEMORY_REF_COST);
 4397 
 4398   size(4);
 4399   format %{ "MEMBAR-acquire" %}
 4400   ins_encode %{
 4401     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), noreg);
 4402   %}
 4403   ins_pipe(long_memory_op);
 4404 %}
 4405 
 4406 instruct membar_acquire_lock() %{
 4407   match(MemBarAcquireLock);
 4408   ins_cost(0);
 4409 
 4410   size(0);
 4411   format %{ "!MEMBAR-acquire (CAS in prior FastLock so empty encoding)" %}
 4412   ins_encode( );
 4413   ins_pipe(empty);
 4414 %}
 4415 
 4416 instruct membar_release() %{
 4417   match(MemBarRelease);
 4418   match(StoreFence);
 4419   ins_cost(4*MEMORY_REF_COST);
 4420 
 4421   size(4);
 4422   format %{ "MEMBAR-release" %}
 4423   ins_encode %{
 4424     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), noreg);
 4425   %}
 4426   ins_pipe(long_memory_op);
 4427 %}
 4428 
 4429 instruct membar_release_lock() %{
 4430   match(MemBarReleaseLock);
 4431   ins_cost(0);
 4432 
 4433   size(0);
 4434   format %{ "!MEMBAR-release (CAS in succeeding FastUnlock so empty encoding)" %}
 4435   ins_encode( );
 4436   ins_pipe(empty);
 4437 %}
 4438 
 4439 instruct membar_storeload() %{
 4440   match(MemBarStoreLoad);
 4441   ins_cost(4*MEMORY_REF_COST);
 4442 
 4443   size(4);
 4444   format %{ "MEMBAR-storeload" %}
 4445   ins_encode %{
 4446     __ membar(MacroAssembler::StoreLoad, noreg);
 4447   %}
 4448   ins_pipe(long_memory_op);
 4449 %}
 4450 
 4451 instruct membar_volatile() %{
 4452   match(MemBarVolatile);
 4453   ins_cost(4*MEMORY_REF_COST);
 4454 
 4455   size(4);
 4456   format %{ "MEMBAR-volatile" %}
 4457   ins_encode %{
 4458     __ membar(MacroAssembler::StoreLoad, noreg);
 4459   %}
 4460   ins_pipe(long_memory_op);
 4461 %}
 4462 
 4463 instruct unnecessary_membar_volatile() %{
 4464   match(MemBarVolatile);
 4465   predicate(Matcher::post_store_load_barrier(n));
 4466   ins_cost(0);
 4467 
 4468   size(0);
 4469   format %{ "!MEMBAR-volatile (unnecessary so empty encoding)" %}
 4470   ins_encode( );
 4471   ins_pipe(empty);
 4472 %}
 4473 
 4474 instruct membar_full() %{
 4475   match(MemBarFull);
 4476   ins_cost(4*MEMORY_REF_COST);
 4477 
 4478   size(4);
 4479   format %{ "MEMBAR-full" %}
 4480   ins_encode %{
 4481     __ membar(MacroAssembler::StoreLoad, noreg);
 4482   %}
 4483   ins_pipe(long_memory_op);
 4484 %}
 4485 
 4486 //----------Register Move Instructions-----------------------------------------
 4487 
 4488 // Cast Index to Pointer for unsafe natives
 4489 instruct castX2P(iRegX src, iRegP dst) %{
 4490   match(Set dst (CastX2P src));
 4491 
 4492   format %{ "MOV    $dst,$src\t! IntX->Ptr if $dst != $src" %}
 4493   ins_encode %{
 4494     if ($dst$$Register !=  $src$$Register) {
 4495       __ mov($dst$$Register, $src$$Register);
 4496     }
 4497   %}
 4498   ins_pipe(ialu_reg);
 4499 %}
 4500 
 4501 // Cast Pointer to Index for unsafe natives
 4502 instruct castP2X(iRegP src, iRegX dst) %{
 4503   match(Set dst (CastP2X src));
 4504 
 4505   format %{ "MOV    $dst,$src\t! Ptr->IntX if $dst != $src" %}
 4506   ins_encode %{
 4507     if ($dst$$Register !=  $src$$Register) {
 4508       __ mov($dst$$Register, $src$$Register);
 4509     }
 4510   %}
 4511   ins_pipe(ialu_reg);
 4512 %}
 4513 
 4514 //----------Conditional Move---------------------------------------------------
 4515 // Conditional move
 4516 instruct cmovIP_reg(cmpOpP cmp, flagsRegP pcc, iRegI dst, iRegI src) %{
 4517   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
 4518   ins_cost(150);
 4519   size(4);
 4520   format %{ "MOV$cmp  $dst,$src\t! int" %}
 4521   ins_encode %{
 4522     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4523   %}
 4524   ins_pipe(ialu_reg);
 4525 %}
 4526 
 4527 
 4528 instruct cmovIP_immMov(cmpOpP cmp, flagsRegP pcc, iRegI dst, immIMov src) %{
 4529   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
 4530   ins_cost(140);
 4531   size(4);
 4532   format %{ "MOV$cmp  $dst,$src" %}
 4533   ins_encode %{
 4534     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4535   %}
 4536   ins_pipe(ialu_imm);
 4537 %}
 4538 
 4539 instruct cmovIP_imm16(cmpOpP cmp, flagsRegP pcc, iRegI dst, immI16 src) %{
 4540   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
 4541   ins_cost(140);
 4542   size(4);
 4543   format %{ "MOVw$cmp  $dst,$src" %}
 4544   ins_encode %{
 4545     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4546   %}
 4547   ins_pipe(ialu_imm);
 4548 %}
 4549 
 4550 instruct cmovI_reg(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src) %{
 4551   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4552   ins_cost(150);
 4553   size(4);
 4554   format %{ "MOV$cmp  $dst,$src" %}
 4555   ins_encode %{
 4556     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4557   %}
 4558   ins_pipe(ialu_reg);
 4559 %}
 4560 
 4561 
 4562 instruct cmovI_immMov(cmpOp cmp, flagsReg icc, iRegI dst, immIMov src) %{
 4563   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4564   ins_cost(140);
 4565   size(4);
 4566   format %{ "MOV$cmp  $dst,$src" %}
 4567   ins_encode %{
 4568     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4569   %}
 4570   ins_pipe(ialu_imm);
 4571 %}
 4572 
 4573 instruct cmovII_imm16(cmpOp cmp, flagsReg icc, iRegI dst, immI16 src) %{
 4574   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4575   ins_cost(140);
 4576   size(4);
 4577   format %{ "MOVw$cmp  $dst,$src" %}
 4578   ins_encode %{
 4579     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4580   %}
 4581   ins_pipe(ialu_imm);
 4582 %}
 4583 
 4584 instruct cmovII_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, iRegI src) %{
 4585   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4586   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4587             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4588             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4589             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4590   ins_cost(150);
 4591   size(4);
 4592   format %{ "MOV$cmp  $dst,$src" %}
 4593   ins_encode %{
 4594     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4595   %}
 4596   ins_pipe(ialu_reg);
 4597 %}
 4598 
 4599 instruct cmovII_immMov_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immIMov src) %{
 4600   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4601   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4602             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4603             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4604             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4605   ins_cost(140);
 4606   size(4);
 4607   format %{ "MOV$cmp  $dst,$src" %}
 4608   ins_encode %{
 4609     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4610   %}
 4611   ins_pipe(ialu_imm);
 4612 %}
 4613 
 4614 instruct cmovII_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immI16 src) %{
 4615   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4616   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4617             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4618             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4619             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4620   ins_cost(140);
 4621   size(4);
 4622   format %{ "MOVW$cmp  $dst,$src" %}
 4623   ins_encode %{
 4624     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4625   %}
 4626   ins_pipe(ialu_imm);
 4627 %}
 4628 
 4629 instruct cmovIIu_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
 4630   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4631   ins_cost(150);
 4632   size(4);
 4633   format %{ "MOV$cmp  $dst,$src" %}
 4634   ins_encode %{
 4635     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4636   %}
 4637   ins_pipe(ialu_reg);
 4638 %}
 4639 
 4640 instruct cmovIIu_immMov(cmpOpU cmp, flagsRegU icc, iRegI dst, immIMov src) %{
 4641   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4642   ins_cost(140);
 4643   size(4);
 4644   format %{ "MOV$cmp  $dst,$src" %}
 4645   ins_encode %{
 4646     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4647   %}
 4648   ins_pipe(ialu_imm);
 4649 %}
 4650 
 4651 instruct cmovIIu_imm16(cmpOpU cmp, flagsRegU icc, iRegI dst, immI16 src) %{
 4652   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4653   ins_cost(140);
 4654   size(4);
 4655   format %{ "MOVW$cmp  $dst,$src" %}
 4656   ins_encode %{
 4657     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4658   %}
 4659   ins_pipe(ialu_imm);
 4660 %}
 4661 
 4662 // Conditional move
 4663 instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{
 4664   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
 4665   ins_cost(150);
 4666   size(4);
 4667   format %{ "MOV$cmp  $dst,$src" %}
 4668   ins_encode %{
 4669     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4670   %}
 4671   ins_pipe(ialu_reg);
 4672 %}
 4673 
 4674 instruct cmovPP_imm(cmpOpP cmp, flagsRegP pcc, iRegP dst, immP0 src) %{
 4675   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
 4676   ins_cost(140);
 4677   size(4);
 4678   format %{ "MOV$cmp  $dst,$src" %}
 4679   ins_encode %{
 4680     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4681   %}
 4682   ins_pipe(ialu_imm);
 4683 %}
 4684 
 4685 // This instruction also works with CmpN so we don't need cmovPN_reg.
 4686 instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{
 4687   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4688   ins_cost(150);
 4689 
 4690   size(4);
 4691   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4692   ins_encode %{
 4693     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4694   %}
 4695   ins_pipe(ialu_reg);
 4696 %}
 4697 
 4698 instruct cmovPI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, iRegP src) %{
 4699   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4700   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4701             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4702             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4703             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4704   ins_cost(150);
 4705 
 4706   size(4);
 4707   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4708   ins_encode %{
 4709     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4710   %}
 4711   ins_pipe(ialu_reg);
 4712 %}
 4713 
 4714 instruct cmovPIu_reg(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src) %{
 4715   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4716   ins_cost(150);
 4717 
 4718   size(4);
 4719   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4720   ins_encode %{
 4721     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4722   %}
 4723   ins_pipe(ialu_reg);
 4724 %}
 4725 
 4726 instruct cmovPI_imm(cmpOp cmp, flagsReg icc, iRegP dst, immP0 src) %{
 4727   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4728   ins_cost(140);
 4729 
 4730   size(4);
 4731   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4732   ins_encode %{
 4733     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4734   %}
 4735   ins_pipe(ialu_imm);
 4736 %}
 4737 
 4738 instruct cmovPI_imm_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, immP0 src) %{
 4739   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4740   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4741             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4742             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4743             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4744   ins_cost(140);
 4745 
 4746   size(4);
 4747   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4748   ins_encode %{
 4749     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4750   %}
 4751   ins_pipe(ialu_imm);
 4752 %}
 4753 
 4754 instruct cmovPIu_imm(cmpOpU cmp, flagsRegU icc, iRegP dst, immP0 src) %{
 4755   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4756   ins_cost(140);
 4757 
 4758   size(4);
 4759   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4760   ins_encode %{
 4761     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4762   %}
 4763   ins_pipe(ialu_imm);
 4764 %}
 4765 
 4766 
 4767 // Conditional move
 4768 instruct cmovFP_reg(cmpOpP cmp, flagsRegP pcc, regF dst, regF src) %{
 4769   match(Set dst (CMoveF (Binary cmp pcc) (Binary dst src)));
 4770   ins_cost(150);
 4771   size(4);
 4772   format %{ "FCPYS$cmp $dst,$src" %}
 4773   ins_encode %{
 4774     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4775   %}
 4776   ins_pipe(int_conditional_float_move);
 4777 %}
 4778 
 4779 instruct cmovFI_reg(cmpOp cmp, flagsReg icc, regF dst, regF src) %{
 4780   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
 4781   ins_cost(150);
 4782 
 4783   size(4);
 4784   format %{ "FCPYS$cmp $dst,$src" %}
 4785   ins_encode %{
 4786     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4787   %}
 4788   ins_pipe(int_conditional_float_move);
 4789 %}
 4790 
 4791 instruct cmovFI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regF dst, regF src) %{
 4792   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
 4793   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4794             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4795             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4796             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4797   ins_cost(150);
 4798 
 4799   size(4);
 4800   format %{ "FCPYS$cmp $dst,$src" %}
 4801   ins_encode %{
 4802     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4803   %}
 4804   ins_pipe(int_conditional_float_move);
 4805 %}
 4806 
 4807 instruct cmovFIu_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src) %{
 4808   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
 4809   ins_cost(150);
 4810 
 4811   size(4);
 4812   format %{ "FCPYS$cmp $dst,$src" %}
 4813   ins_encode %{
 4814     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4815   %}
 4816   ins_pipe(int_conditional_float_move);
 4817 %}
 4818 
 4819 // Conditional move
 4820 instruct cmovDP_reg(cmpOpP cmp, flagsRegP pcc, regD dst, regD src) %{
 4821   match(Set dst (CMoveD (Binary cmp pcc) (Binary dst src)));
 4822   ins_cost(150);
 4823   size(4);
 4824   format %{ "FCPYD$cmp $dst,$src" %}
 4825   ins_encode %{
 4826     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4827   %}
 4828   ins_pipe(int_conditional_double_move);
 4829 %}
 4830 
 4831 instruct cmovDI_reg(cmpOp cmp, flagsReg icc, regD dst, regD src) %{
 4832   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
 4833   ins_cost(150);
 4834 
 4835   size(4);
 4836   format %{ "FCPYD$cmp $dst,$src" %}
 4837   ins_encode %{
 4838     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4839   %}
 4840   ins_pipe(int_conditional_double_move);
 4841 %}
 4842 
 4843 instruct cmovDI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regD dst, regD src) %{
 4844   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
 4845   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);
 4846   ins_cost(150);
 4847 
 4848   size(4);
 4849   format %{ "FCPYD$cmp $dst,$src" %}
 4850   ins_encode %{
 4851     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4852   %}
 4853   ins_pipe(int_conditional_double_move);
 4854 %}
 4855 
 4856 instruct cmovDIu_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src) %{
 4857   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
 4858   ins_cost(150);
 4859 
 4860   size(4);
 4861   format %{ "FCPYD$cmp $dst,$src" %}
 4862   ins_encode %{
 4863     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4864   %}
 4865   ins_pipe(int_conditional_double_move);
 4866 %}
 4867 
 4868 // Conditional move
 4869 instruct cmovLP_reg(cmpOpP cmp, flagsRegP pcc, iRegL dst, iRegL src) %{
 4870   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
 4871   ins_cost(150);
 4872 
 4873   size(8);
 4874   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 4875             "MOV$cmp  $dst.hi,$src.hi" %}
 4876   ins_encode %{
 4877     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4878     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 4879   %}
 4880   ins_pipe(ialu_reg);
 4881 %}
 4882 
 4883 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 4884 // (hi($con$$constant), lo($con$$constant)) becomes
 4885 instruct cmovLP_immRot(cmpOpP cmp, flagsRegP pcc, iRegL dst, immLlowRot src) %{
 4886   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
 4887   ins_cost(140);
 4888 
 4889   size(8);
 4890   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 4891             "MOV$cmp  $dst.hi,0" %}
 4892   ins_encode %{
 4893     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4894     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 4895   %}
 4896   ins_pipe(ialu_imm);
 4897 %}
 4898 
 4899 instruct cmovLP_imm16(cmpOpP cmp, flagsRegP pcc, iRegL dst, immL16 src) %{
 4900   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
 4901   ins_cost(140);
 4902 
 4903   size(8);
 4904   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 4905             "MOV$cmp  $dst.hi,0" %}
 4906   ins_encode %{
 4907     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4908     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 4909   %}
 4910   ins_pipe(ialu_imm);
 4911 %}
 4912 
 4913 instruct cmovLI_reg(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src) %{
 4914   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 4915   ins_cost(150);
 4916 
 4917   size(8);
 4918   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 4919             "MOV$cmp  $dst.hi,$src.hi" %}
 4920   ins_encode %{
 4921     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4922     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 4923   %}
 4924   ins_pipe(ialu_reg);
 4925 %}
 4926 
 4927 instruct cmovLI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, iRegL src) %{
 4928   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 4929   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4930             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4931             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4932             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4933   ins_cost(150);
 4934 
 4935   size(8);
 4936   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 4937             "MOV$cmp  $dst.hi,$src.hi" %}
 4938   ins_encode %{
 4939     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4940     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 4941   %}
 4942   ins_pipe(ialu_reg);
 4943 %}
 4944 
 4945 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 4946 // (hi($con$$constant), lo($con$$constant)) becomes
 4947 instruct cmovLI_immRot(cmpOp cmp, flagsReg icc, iRegL dst, immLlowRot src) %{
 4948   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 4949   ins_cost(140);
 4950 
 4951   size(8);
 4952   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 4953             "MOV$cmp  $dst.hi,0" %}
 4954   ins_encode %{
 4955     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4956     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 4957   %}
 4958   ins_pipe(ialu_imm);
 4959 %}
 4960 
 4961 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 4962 // (hi($con$$constant), lo($con$$constant)) becomes
 4963 instruct cmovLI_immRot_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immLlowRot src) %{
 4964   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 4965   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4966             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4967             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4968             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4969   ins_cost(140);
 4970 
 4971   size(8);
 4972   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 4973             "MOV$cmp  $dst.hi,0" %}
 4974   ins_encode %{
 4975     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4976     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 4977   %}
 4978   ins_pipe(ialu_imm);
 4979 %}
 4980 
 4981 instruct cmovLI_imm16(cmpOp cmp, flagsReg icc, iRegL dst, immL16 src) %{
 4982   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 4983   ins_cost(140);
 4984 
 4985   size(8);
 4986   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 4987             "MOV$cmp  $dst.hi,0" %}
 4988   ins_encode %{
 4989     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4990     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 4991   %}
 4992   ins_pipe(ialu_imm);
 4993 %}
 4994 
 4995 instruct cmovLI_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immL16 src) %{
 4996   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 4997   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4998             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4999             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 5000             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 5001   ins_cost(140);
 5002 
 5003   size(8);
 5004   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5005             "MOV$cmp  $dst.hi,0" %}
 5006   ins_encode %{
 5007     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5008     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5009   %}
 5010   ins_pipe(ialu_imm);
 5011 %}
 5012 
 5013 instruct cmovLIu_reg(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src) %{
 5014   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5015   ins_cost(150);
 5016 
 5017   size(8);
 5018   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 5019             "MOV$cmp  $dst.hi,$src.hi" %}
 5020   ins_encode %{
 5021     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 5022     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 5023   %}
 5024   ins_pipe(ialu_reg);
 5025 %}
 5026 
 5027 
 5028 //----------OS and Locking Instructions----------------------------------------
 5029 
 5030 // This name is KNOWN by the ADLC and cannot be changed.
 5031 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
 5032 // for this guy.
 5033 instruct tlsLoadP(RthreadRegP dst) %{
 5034   match(Set dst (ThreadLocal));
 5035 
 5036   size(0);
 5037   ins_cost(0);
 5038   format %{ "! TLS is in $dst" %}
 5039   ins_encode( /*empty encoding*/ );
 5040   ins_pipe(ialu_none);
 5041 %}
 5042 
 5043 instruct checkCastPP( iRegP dst ) %{
 5044   match(Set dst (CheckCastPP dst));
 5045 
 5046   size(0);
 5047   format %{ "! checkcastPP of $dst" %}
 5048   ins_encode( /*empty encoding*/ );
 5049   ins_pipe(empty);
 5050 %}
 5051 
 5052 
 5053 instruct castPP( iRegP dst ) %{
 5054   match(Set dst (CastPP dst));
 5055   format %{ "! castPP of $dst" %}
 5056   ins_encode( /*empty encoding*/ );
 5057   ins_pipe(empty);
 5058 %}
 5059 
 5060 instruct castII( iRegI dst ) %{
 5061   match(Set dst (CastII dst));
 5062   format %{ "! castII of $dst" %}
 5063   ins_encode( /*empty encoding*/ );
 5064   ins_cost(0);
 5065   ins_pipe(empty);
 5066 %}
 5067 
 5068 instruct castLL( iRegL dst ) %{
 5069   match(Set dst (CastLL dst));
 5070   format %{ "! castLL of $dst" %}
 5071   ins_encode( /*empty encoding*/ );
 5072   ins_cost(0);
 5073   ins_pipe(empty);
 5074 %}
 5075 
 5076 instruct castFF( regF dst ) %{
 5077   match(Set dst (CastFF dst));
 5078   format %{ "! castFF of $dst" %}
 5079   ins_encode( /*empty encoding*/ );
 5080   ins_cost(0);
 5081   ins_pipe(empty);
 5082 %}
 5083 
 5084 instruct castDD( regD dst ) %{
 5085   match(Set dst (CastDD dst));
 5086   format %{ "! castDD of $dst" %}
 5087   ins_encode( /*empty encoding*/ );
 5088   ins_cost(0);
 5089   ins_pipe(empty);
 5090 %}
 5091 
 5092 instruct castVVD( vecD dst ) %{
 5093   match(Set dst (CastVV dst));
 5094   format %{ "! castVV of $dst" %}
 5095   ins_encode( /*empty encoding*/ );
 5096   ins_cost(0);
 5097   ins_pipe(empty);
 5098 %}
 5099 
 5100 instruct castVVX( vecX dst ) %{
 5101   match(Set dst (CastVV dst));
 5102   format %{ "! castVV of $dst" %}
 5103   ins_encode( /*empty encoding*/ );
 5104   ins_cost(0);
 5105   ins_pipe(empty);
 5106 %}
 5107 
 5108 
 5109 //----------Arithmetic Instructions--------------------------------------------
 5110 // Addition Instructions
 5111 // Register Addition
 5112 instruct addI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 5113   match(Set dst (AddI src1 src2));
 5114 
 5115   size(4);
 5116   format %{ "add_32 $dst,$src1,$src2\t! int" %}
 5117   ins_encode %{
 5118     __ add_32($dst$$Register, $src1$$Register, $src2$$Register);
 5119   %}
 5120   ins_pipe(ialu_reg_reg);
 5121 %}
 5122 
 5123 instruct addshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5124   match(Set dst (AddI (LShiftI src1 src2) src3));
 5125 
 5126   size(4);
 5127   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
 5128   ins_encode %{
 5129     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 5130   %}
 5131   ins_pipe(ialu_reg_reg);
 5132 %}
 5133 
 5134 
 5135 instruct addshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5136   match(Set dst (AddI (LShiftI src1 src2) src3));
 5137 
 5138   size(4);
 5139   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
 5140   ins_encode %{
 5141     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
 5142   %}
 5143   ins_pipe(ialu_reg_reg);
 5144 %}
 5145 
 5146 instruct addsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5147   match(Set dst (AddI (RShiftI src1 src2) src3));
 5148 
 5149   size(4);
 5150   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
 5151   ins_encode %{
 5152     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
 5153   %}
 5154   ins_pipe(ialu_reg_reg);
 5155 %}
 5156 
 5157 instruct addsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5158   match(Set dst (AddI (RShiftI src1 src2) src3));
 5159 
 5160   size(4);
 5161   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
 5162   ins_encode %{
 5163     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
 5164   %}
 5165   ins_pipe(ialu_reg_reg);
 5166 %}
 5167 
 5168 instruct addshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5169   match(Set dst (AddI (URShiftI src1 src2) src3));
 5170 
 5171   size(4);
 5172   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
 5173   ins_encode %{
 5174     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 5175   %}
 5176   ins_pipe(ialu_reg_reg);
 5177 %}
 5178 
 5179 instruct addshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5180   match(Set dst (AddI (URShiftI src1 src2) src3));
 5181 
 5182   size(4);
 5183   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
 5184   ins_encode %{
 5185     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 5186   %}
 5187   ins_pipe(ialu_reg_reg);
 5188 %}
 5189 
 5190 // Immediate Addition
 5191 instruct addI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
 5192   match(Set dst (AddI src1 src2));
 5193 
 5194   size(4);
 5195   format %{ "add_32 $dst,$src1,$src2\t! int" %}
 5196   ins_encode %{
 5197     __ add_32($dst$$Register, $src1$$Register, $src2$$constant);
 5198   %}
 5199   ins_pipe(ialu_reg_imm);
 5200 %}
 5201 
 5202 // Pointer Register Addition
 5203 instruct addP_reg_reg(iRegP dst, iRegP src1, iRegX src2) %{
 5204   match(Set dst (AddP src1 src2));
 5205 
 5206   size(4);
 5207   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
 5208   ins_encode %{
 5209     __ add($dst$$Register, $src1$$Register, $src2$$Register);
 5210   %}
 5211   ins_pipe(ialu_reg_reg);
 5212 %}
 5213 
 5214 
 5215 // shifted iRegX operand
 5216 operand shiftedX(iRegX src2, shimmX src3) %{
 5217 //constraint(ALLOC_IN_RC(sp_ptr_reg));
 5218   match(LShiftX src2 src3);
 5219 
 5220   op_cost(1);
 5221   format %{ "$src2 << $src3" %}
 5222   interface(MEMORY_INTER) %{
 5223     base($src2);
 5224     index(0xff);
 5225     scale($src3);
 5226     disp(0x0);
 5227   %}
 5228 %}
 5229 
 5230 instruct addshlP_reg_reg_imm(iRegP dst, iRegP src1, shiftedX src2) %{
 5231   match(Set dst (AddP src1 src2));
 5232 
 5233   ins_cost(DEFAULT_COST * 3/2);
 5234   size(4);
 5235   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
 5236   ins_encode %{
 5237     Register base = reg_to_register_object($src2$$base);
 5238     __ add($dst$$Register, $src1$$Register, AsmOperand(base, lsl, $src2$$scale));
 5239   %}
 5240   ins_pipe(ialu_reg_reg);
 5241 %}
 5242 
 5243 // Pointer Immediate Addition
 5244 instruct addP_reg_aimmX(iRegP dst, iRegP src1, aimmX src2) %{
 5245   match(Set dst (AddP src1 src2));
 5246 
 5247   size(4);
 5248   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
 5249   ins_encode %{
 5250     __ add($dst$$Register, $src1$$Register, $src2$$constant);
 5251   %}
 5252   ins_pipe(ialu_reg_imm);
 5253 %}
 5254 
 5255 // Long Addition
 5256 instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg ccr) %{
 5257   match(Set dst (AddL src1 src2));
 5258   effect(KILL ccr);
 5259   size(8);
 5260   format %{ "ADDS    $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
 5261             "ADC     $dst.hi,$src1.hi,$src2.hi" %}
 5262   ins_encode %{
 5263     __ adds($dst$$Register, $src1$$Register, $src2$$Register);
 5264     __ adc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 5265   %}
 5266   ins_pipe(ialu_reg_reg);
 5267 %}
 5268 
 5269 // TODO
 5270 
 5271 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5272 // (hi($con$$constant), lo($con$$constant)) becomes
 5273 instruct addL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg ccr) %{
 5274   match(Set dst (AddL src1 con));
 5275   effect(KILL ccr);
 5276   size(8);
 5277   format %{ "ADDS    $dst.lo,$src1.lo,$con\t! long\n\t"
 5278             "ADC     $dst.hi,$src1.hi,0" %}
 5279   ins_encode %{
 5280     __ adds($dst$$Register, $src1$$Register, $con$$constant);
 5281     __ adc($dst$$Register->successor(), $src1$$Register->successor(), 0);
 5282   %}
 5283   ins_pipe(ialu_reg_imm);
 5284 %}
 5285 
 5286 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
 5287 
 5288 instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegLd newval, iRegI res, iRegLd tmp, flagsReg ccr ) %{
 5289   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
 5290   effect( KILL ccr, TEMP tmp);
 5291   size(32);
 5292   format %{ "loop: \n\t"
 5293             "LDREXD   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
 5294             "CMP      $tmp.lo, $oldval.lo\n\t"
 5295             "CMP.eq   $tmp.hi, $oldval.hi\n\t"
 5296             "STREXD.eq $tmp, $newval, $mem\n\t"
 5297             "MOV.ne   $tmp, 0 \n\t"
 5298             "XORS.eq  $tmp,$tmp, 1 \n\t"
 5299             "B.eq     loop \n\t"
 5300             "MOV      $res, $tmp" %}
 5301   ins_encode %{
 5302     Label loop;
 5303     __ bind(loop);
 5304     __ ldrexd($tmp$$Register, $mem$$Address);
 5305     __ cmp($tmp$$Register, $oldval$$Register);
 5306     __ cmp($tmp$$Register->successor(), $oldval$$Register->successor(), eq);
 5307     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5308     __ mov($tmp$$Register, 0, ne);
 5309     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
 5310     __ b(loop, eq);
 5311     __ mov($res$$Register, $tmp$$Register);
 5312   %}
 5313   ins_pipe( long_memory_op );
 5314 %}
 5315 
 5316 
 5317 instruct compareAndSwapI_bool(memoryex mem, iRegI oldval, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
 5318   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
 5319   effect( KILL ccr, TEMP tmp);
 5320   size(28);
 5321   format %{ "loop: \n\t"
 5322             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
 5323             "CMP      $tmp, $oldval\n\t"
 5324             "STREX.eq $tmp, $newval, $mem\n\t"
 5325             "MOV.ne   $tmp, 0 \n\t"
 5326             "XORS.eq  $tmp,$tmp, 1 \n\t"
 5327             "B.eq     loop \n\t"
 5328             "MOV      $res, $tmp" %}
 5329 
 5330   ins_encode %{
 5331     Label loop;
 5332     __ bind(loop);
 5333     __ ldrex($tmp$$Register,$mem$$Address);
 5334     __ cmp($tmp$$Register, $oldval$$Register);
 5335     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5336     __ mov($tmp$$Register, 0, ne);
 5337     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
 5338     __ b(loop, eq);
 5339     __ mov($res$$Register, $tmp$$Register);
 5340   %}
 5341   ins_pipe( long_memory_op );
 5342 %}
 5343 
 5344 instruct compareAndSwapP_bool(memoryex mem, iRegP oldval, iRegP newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
 5345   predicate(!(UseG1GC && n->as_LoadStore()->barrier_data() != 0));
 5346   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
 5347   effect( KILL ccr, TEMP tmp);
 5348   size(28);
 5349   format %{ "loop: \n\t"
 5350             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
 5351             "CMP      $tmp, $oldval\n\t"
 5352             "STREX.eq $tmp, $newval, $mem\n\t"
 5353             "MOV.ne   $tmp, 0 \n\t"
 5354             "EORS.eq  $tmp,$tmp, 1 \n\t"
 5355             "B.eq     loop \n\t"
 5356             "MOV      $res, $tmp" %}
 5357 
 5358   ins_encode %{
 5359     Label loop;
 5360     __ bind(loop);
 5361     __ ldrex($tmp$$Register,$mem$$Address);
 5362     __ cmp($tmp$$Register, $oldval$$Register);
 5363     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5364     __ mov($tmp$$Register, 0, ne);
 5365     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
 5366     __ b(loop, eq);
 5367     __ mov($res$$Register, $tmp$$Register);
 5368   %}
 5369   ins_pipe( long_memory_op );
 5370 %}
 5371 
 5372 instruct xaddI_aimmI_no_res(memoryex mem, aimmI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5373   predicate(n->as_LoadStore()->result_not_used());
 5374   match(Set dummy (GetAndAddI mem add));
 5375   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
 5376   size(20);
 5377   format %{ "loop: \n\t"
 5378             "LDREX    $tmp1, $mem\n\t"
 5379             "ADD      $tmp1, $tmp1, $add\n\t"
 5380             "STREX    $tmp2, $tmp1, $mem\n\t"
 5381             "CMP      $tmp2, 0 \n\t"
 5382             "B.ne     loop \n\t" %}
 5383 
 5384   ins_encode %{
 5385     Label loop;
 5386     __ bind(loop);
 5387     __ ldrex($tmp1$$Register,$mem$$Address);
 5388     __ add($tmp1$$Register, $tmp1$$Register, $add$$constant);
 5389     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5390     __ cmp($tmp2$$Register, 0);
 5391     __ b(loop, ne);
 5392   %}
 5393   ins_pipe( long_memory_op );
 5394 %}
 5395 
 5396 instruct xaddI_reg_no_res(memoryex mem, iRegI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5397   predicate(n->as_LoadStore()->result_not_used());
 5398   match(Set dummy (GetAndAddI mem add));
 5399   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
 5400   size(20);
 5401   format %{ "loop: \n\t"
 5402             "LDREX    $tmp1, $mem\n\t"
 5403             "ADD      $tmp1, $tmp1, $add\n\t"
 5404             "STREX    $tmp2, $tmp1, $mem\n\t"
 5405             "CMP      $tmp2, 0 \n\t"
 5406             "B.ne     loop \n\t" %}
 5407 
 5408   ins_encode %{
 5409     Label loop;
 5410     __ bind(loop);
 5411     __ ldrex($tmp1$$Register,$mem$$Address);
 5412     __ add($tmp1$$Register, $tmp1$$Register, $add$$Register);
 5413     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5414     __ cmp($tmp2$$Register, 0);
 5415     __ b(loop, ne);
 5416   %}
 5417   ins_pipe( long_memory_op );
 5418 %}
 5419 
 5420 instruct xaddI_aimmI(memoryex mem, aimmI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5421   match(Set res (GetAndAddI mem add));
 5422   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5423   size(20);
 5424   format %{ "loop: \n\t"
 5425             "LDREX    $res, $mem\n\t"
 5426             "ADD      $tmp1, $res, $add\n\t"
 5427             "STREX    $tmp2, $tmp1, $mem\n\t"
 5428             "CMP      $tmp2, 0 \n\t"
 5429             "B.ne     loop \n\t" %}
 5430 
 5431   ins_encode %{
 5432     Label loop;
 5433     __ bind(loop);
 5434     __ ldrex($res$$Register,$mem$$Address);
 5435     __ add($tmp1$$Register, $res$$Register, $add$$constant);
 5436     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5437     __ cmp($tmp2$$Register, 0);
 5438     __ b(loop, ne);
 5439   %}
 5440   ins_pipe( long_memory_op );
 5441 %}
 5442 
 5443 instruct xaddI_reg(memoryex mem, iRegI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5444   match(Set res (GetAndAddI mem add));
 5445   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5446   size(20);
 5447   format %{ "loop: \n\t"
 5448             "LDREX    $res, $mem\n\t"
 5449             "ADD      $tmp1, $res, $add\n\t"
 5450             "STREX    $tmp2, $tmp1, $mem\n\t"
 5451             "CMP      $tmp2, 0 \n\t"
 5452             "B.ne     loop \n\t" %}
 5453 
 5454   ins_encode %{
 5455     Label loop;
 5456     __ bind(loop);
 5457     __ ldrex($res$$Register,$mem$$Address);
 5458     __ add($tmp1$$Register, $res$$Register, $add$$Register);
 5459     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5460     __ cmp($tmp2$$Register, 0);
 5461     __ b(loop, ne);
 5462   %}
 5463   ins_pipe( long_memory_op );
 5464 %}
 5465 
 5466 instruct xaddL_reg_no_res(memoryex mem, iRegL add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5467   predicate(n->as_LoadStore()->result_not_used());
 5468   match(Set dummy (GetAndAddL mem add));
 5469   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
 5470   size(24);
 5471   format %{ "loop: \n\t"
 5472             "LDREXD   $tmp1, $mem\n\t"
 5473             "ADDS     $tmp1.lo, $tmp1.lo, $add.lo\n\t"
 5474             "ADC      $tmp1.hi, $tmp1.hi, $add.hi\n\t"
 5475             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5476             "CMP      $tmp2, 0 \n\t"
 5477             "B.ne     loop \n\t" %}
 5478 
 5479   ins_encode %{
 5480     Label loop;
 5481     __ bind(loop);
 5482     __ ldrexd($tmp1$$Register, $mem$$Address);
 5483     __ adds($tmp1$$Register, $tmp1$$Register, $add$$Register);
 5484     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), $add$$Register->successor());
 5485     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5486     __ cmp($tmp2$$Register, 0);
 5487     __ b(loop, ne);
 5488   %}
 5489   ins_pipe( long_memory_op );
 5490 %}
 5491 
 5492 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5493 // (hi($con$$constant), lo($con$$constant)) becomes
 5494 instruct xaddL_immRot_no_res(memoryex mem, immLlowRot add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5495   predicate(n->as_LoadStore()->result_not_used());
 5496   match(Set dummy (GetAndAddL mem add));
 5497   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
 5498   size(24);
 5499   format %{ "loop: \n\t"
 5500             "LDREXD   $tmp1, $mem\n\t"
 5501             "ADDS     $tmp1.lo, $tmp1.lo, $add\n\t"
 5502             "ADC      $tmp1.hi, $tmp1.hi, 0\n\t"
 5503             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5504             "CMP      $tmp2, 0 \n\t"
 5505             "B.ne     loop \n\t" %}
 5506 
 5507   ins_encode %{
 5508     Label loop;
 5509     __ bind(loop);
 5510     __ ldrexd($tmp1$$Register, $mem$$Address);
 5511     __ adds($tmp1$$Register, $tmp1$$Register, $add$$constant);
 5512     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), 0);
 5513     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5514     __ cmp($tmp2$$Register, 0);
 5515     __ b(loop, ne);
 5516   %}
 5517   ins_pipe( long_memory_op );
 5518 %}
 5519 
 5520 instruct xaddL_reg(memoryex mem, iRegL add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5521   match(Set res (GetAndAddL mem add));
 5522   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5523   size(24);
 5524   format %{ "loop: \n\t"
 5525             "LDREXD   $res, $mem\n\t"
 5526             "ADDS     $tmp1.lo, $res.lo, $add.lo\n\t"
 5527             "ADC      $tmp1.hi, $res.hi, $add.hi\n\t"
 5528             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5529             "CMP      $tmp2, 0 \n\t"
 5530             "B.ne     loop \n\t" %}
 5531 
 5532   ins_encode %{
 5533     Label loop;
 5534     __ bind(loop);
 5535     __ ldrexd($res$$Register, $mem$$Address);
 5536     __ adds($tmp1$$Register, $res$$Register, $add$$Register);
 5537     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), $add$$Register->successor());
 5538     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5539     __ cmp($tmp2$$Register, 0);
 5540     __ b(loop, ne);
 5541   %}
 5542   ins_pipe( long_memory_op );
 5543 %}
 5544 
 5545 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5546 // (hi($con$$constant), lo($con$$constant)) becomes
 5547 instruct xaddL_immRot(memoryex mem, immLlowRot add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5548   match(Set res (GetAndAddL mem add));
 5549   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5550   size(24);
 5551   format %{ "loop: \n\t"
 5552             "LDREXD   $res, $mem\n\t"
 5553             "ADDS     $tmp1.lo, $res.lo, $add\n\t"
 5554             "ADC      $tmp1.hi, $res.hi, 0\n\t"
 5555             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5556             "CMP      $tmp2, 0 \n\t"
 5557             "B.ne     loop \n\t" %}
 5558 
 5559   ins_encode %{
 5560     Label loop;
 5561     __ bind(loop);
 5562     __ ldrexd($res$$Register, $mem$$Address);
 5563     __ adds($tmp1$$Register, $res$$Register, $add$$constant);
 5564     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), 0);
 5565     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5566     __ cmp($tmp2$$Register, 0);
 5567     __ b(loop, ne);
 5568   %}
 5569   ins_pipe( long_memory_op );
 5570 %}
 5571 
 5572 instruct xchgI(memoryex mem, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr) %{
 5573   match(Set res (GetAndSetI mem newval));
 5574   effect(KILL ccr, TEMP tmp, TEMP res);
 5575   size(16);
 5576   format %{ "loop: \n\t"
 5577             "LDREX    $res, $mem\n\t"
 5578             "STREX    $tmp, $newval, $mem\n\t"
 5579             "CMP      $tmp, 0 \n\t"
 5580             "B.ne     loop \n\t" %}
 5581 
 5582   ins_encode %{
 5583     Label loop;
 5584     __ bind(loop);
 5585     __ ldrex($res$$Register,$mem$$Address);
 5586     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
 5587     __ cmp($tmp$$Register, 0);
 5588     __ b(loop, ne);
 5589   %}
 5590   ins_pipe( long_memory_op );
 5591 %}
 5592 
 5593 instruct xchgL(memoryex mem, iRegLd newval, iRegLd res, iRegI tmp, flagsReg ccr) %{
 5594   match(Set res (GetAndSetL mem newval));
 5595   effect( KILL ccr, TEMP tmp, TEMP res);
 5596   size(16);
 5597   format %{ "loop: \n\t"
 5598             "LDREXD   $res, $mem\n\t"
 5599             "STREXD   $tmp, $newval, $mem\n\t"
 5600             "CMP      $tmp, 0 \n\t"
 5601             "B.ne     loop \n\t" %}
 5602 
 5603   ins_encode %{
 5604     Label loop;
 5605     __ bind(loop);
 5606     __ ldrexd($res$$Register, $mem$$Address);
 5607     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address);
 5608     __ cmp($tmp$$Register, 0);
 5609     __ b(loop, ne);
 5610   %}
 5611   ins_pipe( long_memory_op );
 5612 %}
 5613 
 5614 instruct xchgP(memoryex mem, iRegP newval, iRegP res, iRegI tmp, flagsReg ccr) %{
 5615   predicate(!(UseG1GC && n->as_LoadStore()->barrier_data() != 0));
 5616   match(Set res (GetAndSetP mem newval));
 5617   effect(KILL ccr, TEMP tmp, TEMP res);
 5618   size(16);
 5619   format %{ "loop: \n\t"
 5620             "LDREX    $res, $mem\n\t"
 5621             "STREX    $tmp, $newval, $mem\n\t"
 5622             "CMP      $tmp, 0 \n\t"
 5623             "B.ne     loop \n\t" %}
 5624 
 5625   ins_encode %{
 5626     Label loop;
 5627     __ bind(loop);
 5628     __ ldrex($res$$Register,$mem$$Address);
 5629     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
 5630     __ cmp($tmp$$Register, 0);
 5631     __ b(loop, ne);
 5632   %}
 5633   ins_pipe( long_memory_op );
 5634 %}
 5635 
 5636 //---------------------
 5637 // Subtraction Instructions
 5638 // Register Subtraction
 5639 instruct subI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 5640   match(Set dst (SubI src1 src2));
 5641 
 5642   size(4);
 5643   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
 5644   ins_encode %{
 5645     __ sub_32($dst$$Register, $src1$$Register, $src2$$Register);
 5646   %}
 5647   ins_pipe(ialu_reg_reg);
 5648 %}
 5649 
 5650 instruct subshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5651   match(Set dst (SubI src1 (LShiftI src2 src3)));
 5652 
 5653   size(4);
 5654   format %{ "SUB    $dst,$src1,$src2<<$src3" %}
 5655   ins_encode %{
 5656     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 5657   %}
 5658   ins_pipe(ialu_reg_reg);
 5659 %}
 5660 
 5661 instruct subshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 5662   match(Set dst (SubI src1 (LShiftI src2 src3)));
 5663 
 5664   size(4);
 5665   format %{ "sub_32 $dst,$src1,$src2<<$src3\t! int" %}
 5666   ins_encode %{
 5667     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 5668   %}
 5669   ins_pipe(ialu_reg_reg);
 5670 %}
 5671 
 5672 instruct subsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5673   match(Set dst (SubI src1 (RShiftI src2 src3)));
 5674 
 5675   size(4);
 5676   format %{ "SUB    $dst,$src1,$src2>>$src3" %}
 5677   ins_encode %{
 5678     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 5679   %}
 5680   ins_pipe(ialu_reg_reg);
 5681 %}
 5682 
 5683 instruct subsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 5684   match(Set dst (SubI src1 (RShiftI src2 src3)));
 5685 
 5686   size(4);
 5687   format %{ "sub_32 $dst,$src1,$src2>>$src3\t! int" %}
 5688   ins_encode %{
 5689     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 5690   %}
 5691   ins_pipe(ialu_reg_reg);
 5692 %}
 5693 
 5694 instruct subshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5695   match(Set dst (SubI src1 (URShiftI src2 src3)));
 5696 
 5697   size(4);
 5698   format %{ "SUB    $dst,$src1,$src2>>>$src3" %}
 5699   ins_encode %{
 5700     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 5701   %}
 5702   ins_pipe(ialu_reg_reg);
 5703 %}
 5704 
 5705 instruct subshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 5706   match(Set dst (SubI src1 (URShiftI src2 src3)));
 5707 
 5708   size(4);
 5709   format %{ "sub_32 $dst,$src1,$src2>>>$src3\t! int" %}
 5710   ins_encode %{
 5711     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 5712   %}
 5713   ins_pipe(ialu_reg_reg);
 5714 %}
 5715 
 5716 instruct rsbshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5717   match(Set dst (SubI (LShiftI src1 src2) src3));
 5718 
 5719   size(4);
 5720   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
 5721   ins_encode %{
 5722     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 5723   %}
 5724   ins_pipe(ialu_reg_reg);
 5725 %}
 5726 
 5727 instruct rsbshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5728   match(Set dst (SubI (LShiftI src1 src2) src3));
 5729 
 5730   size(4);
 5731   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
 5732   ins_encode %{
 5733     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
 5734   %}
 5735   ins_pipe(ialu_reg_reg);
 5736 %}
 5737 
 5738 instruct rsbsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5739   match(Set dst (SubI (RShiftI src1 src2) src3));
 5740 
 5741   size(4);
 5742   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
 5743   ins_encode %{
 5744     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
 5745   %}
 5746   ins_pipe(ialu_reg_reg);
 5747 %}
 5748 
 5749 instruct rsbsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5750   match(Set dst (SubI (RShiftI src1 src2) src3));
 5751 
 5752   size(4);
 5753   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
 5754   ins_encode %{
 5755     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
 5756   %}
 5757   ins_pipe(ialu_reg_reg);
 5758 %}
 5759 
 5760 instruct rsbshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5761   match(Set dst (SubI (URShiftI src1 src2) src3));
 5762 
 5763   size(4);
 5764   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
 5765   ins_encode %{
 5766     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 5767   %}
 5768   ins_pipe(ialu_reg_reg);
 5769 %}
 5770 
 5771 instruct rsbshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5772   match(Set dst (SubI (URShiftI src1 src2) src3));
 5773 
 5774   size(4);
 5775   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
 5776   ins_encode %{
 5777     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 5778   %}
 5779   ins_pipe(ialu_reg_reg);
 5780 %}
 5781 
 5782 // Immediate Subtraction
 5783 instruct subI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
 5784   match(Set dst (SubI src1 src2));
 5785 
 5786   size(4);
 5787   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
 5788   ins_encode %{
 5789     __ sub_32($dst$$Register, $src1$$Register, $src2$$constant);
 5790   %}
 5791   ins_pipe(ialu_reg_imm);
 5792 %}
 5793 
 5794 instruct subI_reg_immRotneg(iRegI dst, iRegI src1, aimmIneg src2) %{
 5795   match(Set dst (AddI src1 src2));
 5796 
 5797   size(4);
 5798   format %{ "sub_32 $dst,$src1,-($src2)\t! int" %}
 5799   ins_encode %{
 5800     __ sub_32($dst$$Register, $src1$$Register, -$src2$$constant);
 5801   %}
 5802   ins_pipe(ialu_reg_imm);
 5803 %}
 5804 
 5805 instruct subI_immRot_reg(iRegI dst, immIRot src1, iRegI src2) %{
 5806   match(Set dst (SubI src1 src2));
 5807 
 5808   size(4);
 5809   format %{ "RSB    $dst,$src2,src1" %}
 5810   ins_encode %{
 5811     __ rsb($dst$$Register, $src2$$Register, $src1$$constant);
 5812   %}
 5813   ins_pipe(ialu_zero_reg);
 5814 %}
 5815 
 5816 // Register Subtraction
 5817 instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg icc ) %{
 5818   match(Set dst (SubL src1 src2));
 5819   effect (KILL icc);
 5820 
 5821   size(8);
 5822   format %{ "SUBS   $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
 5823             "SBC    $dst.hi,$src1.hi,$src2.hi" %}
 5824   ins_encode %{
 5825     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
 5826     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 5827   %}
 5828   ins_pipe(ialu_reg_reg);
 5829 %}
 5830 
 5831 // TODO
 5832 
 5833 // Immediate Subtraction
 5834 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5835 // (hi($con$$constant), lo($con$$constant)) becomes
 5836 instruct subL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg icc) %{
 5837   match(Set dst (SubL src1 con));
 5838   effect (KILL icc);
 5839 
 5840   size(8);
 5841   format %{ "SUB    $dst.lo,$src1.lo,$con\t! long\n\t"
 5842             "SBC    $dst.hi,$src1.hi,0" %}
 5843   ins_encode %{
 5844     __ subs($dst$$Register, $src1$$Register, $con$$constant);
 5845     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), 0);
 5846   %}
 5847   ins_pipe(ialu_reg_imm);
 5848 %}
 5849 
 5850 // Long negation
 5851 instruct negL_reg_reg(iRegL dst, immL0 zero, iRegL src2, flagsReg icc) %{
 5852   match(Set dst (SubL zero src2));
 5853   effect (KILL icc);
 5854 
 5855   size(8);
 5856   format %{ "RSBS   $dst.lo,$src2.lo,0\t! long\n\t"
 5857             "RSC    $dst.hi,$src2.hi,0" %}
 5858   ins_encode %{
 5859     __ rsbs($dst$$Register, $src2$$Register, 0);
 5860     __ rsc($dst$$Register->successor(), $src2$$Register->successor(), 0);
 5861   %}
 5862   ins_pipe(ialu_zero_reg);
 5863 %}
 5864 
 5865 // Multiplication Instructions
 5866 // Integer Multiplication
 5867 // Register Multiplication
 5868 instruct mulI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 5869   match(Set dst (MulI src1 src2));
 5870 
 5871   size(4);
 5872   format %{ "mul_32 $dst,$src1,$src2" %}
 5873   ins_encode %{
 5874     __ mul_32($dst$$Register, $src1$$Register, $src2$$Register);
 5875   %}
 5876   ins_pipe(imul_reg_reg);
 5877 %}
 5878 
 5879 instruct mulL_lo1_hi2(iRegL dst, iRegL src1, iRegL src2) %{
 5880   effect(DEF dst, USE src1, USE src2);
 5881   size(4);
 5882   format %{ "MUL  $dst.hi,$src1.lo,$src2.hi\t! long" %}
 5883   ins_encode %{
 5884     __ mul($dst$$Register->successor(), $src1$$Register, $src2$$Register->successor());
 5885   %}
 5886   ins_pipe(imul_reg_reg);
 5887 %}
 5888 
 5889 instruct mulL_hi1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
 5890   effect(USE_DEF dst, USE src1, USE src2);
 5891   size(8);
 5892   format %{ "MLA  $dst.hi,$src1.hi,$src2.lo,$dst.hi\t! long\n\t"
 5893             "MOV  $dst.lo, 0"%}
 5894   ins_encode %{
 5895     __ mla($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register, $dst$$Register->successor());
 5896     __ mov($dst$$Register, 0);
 5897   %}
 5898   ins_pipe(imul_reg_reg);
 5899 %}
 5900 
 5901 instruct mulL_lo1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
 5902   effect(USE_DEF dst, USE src1, USE src2);
 5903   size(4);
 5904   format %{ "UMLAL  $dst.lo,$dst.hi,$src1,$src2\t! long" %}
 5905   ins_encode %{
 5906     __ umlal($dst$$Register, $dst$$Register->successor(), $src1$$Register, $src2$$Register);
 5907   %}
 5908   ins_pipe(imul_reg_reg);
 5909 %}
 5910 
 5911 instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 5912   match(Set dst (MulL src1 src2));
 5913 
 5914   expand %{
 5915     mulL_lo1_hi2(dst, src1, src2);
 5916     mulL_hi1_lo2(dst, src1, src2);
 5917     mulL_lo1_lo2(dst, src1, src2);
 5918   %}
 5919 %}
 5920 
 5921 // Integer Division
 5922 // Register Division
 5923 instruct divI_reg_reg(R1RegI dst, R0RegI src1, R2RegI src2, LRRegP lr, flagsReg ccr) %{
 5924   match(Set dst (DivI src1 src2));
 5925   effect( KILL ccr, KILL src1, KILL src2, KILL lr);
 5926   ins_cost((2+71)*DEFAULT_COST);
 5927 
 5928   format %{ "DIV   $dst,$src1,$src2 ! call to StubRoutines::Arm::idiv_irem_entry()" %}
 5929   ins_encode %{
 5930     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
 5931   %}
 5932   ins_pipe(sdiv_reg_reg);
 5933 %}
 5934 
 5935 // Register Long Division
 5936 instruct divL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
 5937   match(Set dst (DivL src1 src2));
 5938   effect(CALL);
 5939   ins_cost(DEFAULT_COST*71);
 5940   format %{ "DIVL  $src1,$src2,$dst\t! long ! call to SharedRuntime::ldiv" %}
 5941   ins_encode %{
 5942     address target = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);
 5943     __ call(target, relocInfo::runtime_call_type);
 5944   %}
 5945   ins_pipe(divL_reg_reg);
 5946 %}
 5947 
 5948 // Integer Remainder
 5949 // Register Remainder
 5950 instruct modI_reg_reg(R0RegI dst, R0RegI src1, R2RegI src2, R1RegI temp, LRRegP lr, flagsReg ccr ) %{
 5951   match(Set dst (ModI src1 src2));
 5952   effect( KILL ccr, KILL temp, KILL src2, KILL lr);
 5953 
 5954   format %{ "MODI   $dst,$src1,$src2\t ! call to StubRoutines::Arm::idiv_irem_entry" %}
 5955   ins_encode %{
 5956     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
 5957   %}
 5958   ins_pipe(sdiv_reg_reg);
 5959 %}
 5960 
 5961 // Register Long Remainder
 5962 instruct modL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
 5963   match(Set dst (ModL src1 src2));
 5964   effect(CALL);
 5965   ins_cost(MEMORY_REF_COST); // FIXME
 5966   format %{ "modL    $dst,$src1,$src2\t ! call to SharedRuntime::lrem" %}
 5967   ins_encode %{
 5968     address target = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
 5969     __ call(target, relocInfo::runtime_call_type);
 5970   %}
 5971   ins_pipe(divL_reg_reg);
 5972 %}
 5973 
 5974 // Integer Shift Instructions
 5975 
 5976 // Register Shift Left
 5977 instruct shlI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 5978   match(Set dst (LShiftI src1 src2));
 5979 
 5980   size(4);
 5981   format %{ "LSL  $dst,$src1,$src2 \n\t" %}
 5982   ins_encode %{
 5983     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 5984   %}
 5985   ins_pipe(ialu_reg_reg);
 5986 %}
 5987 
 5988 // Register Shift Left Immediate
 5989 instruct shlI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
 5990   match(Set dst (LShiftI src1 src2));
 5991 
 5992   size(4);
 5993   format %{ "LSL    $dst,$src1,$src2\t! int" %}
 5994   ins_encode %{
 5995     __ logical_shift_left($dst$$Register, $src1$$Register, $src2$$constant);
 5996   %}
 5997   ins_pipe(ialu_reg_imm);
 5998 %}
 5999 
 6000 instruct shlL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
 6001   effect(USE_DEF dst, USE src1, USE src2);
 6002   size(4);
 6003   format %{"OR  $dst.hi,$dst.hi,($src1.hi << $src2)"  %}
 6004   ins_encode %{
 6005     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$Register));
 6006   %}
 6007   ins_pipe(ialu_reg_reg);
 6008 %}
 6009 
 6010 instruct shlL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
 6011   effect(USE_DEF dst, USE src1, USE src2);
 6012   size(4);
 6013   format %{ "LSL  $dst.lo,$src1.lo,$src2 \n\t" %}
 6014   ins_encode %{
 6015     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 6016   %}
 6017   ins_pipe(ialu_reg_reg);
 6018 %}
 6019 
 6020 instruct shlL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
 6021   effect(DEF dst, USE src1, USE src2, KILL ccr);
 6022   size(16);
 6023   format %{ "SUBS  $dst.hi,$src2,32 \n\t"
 6024             "LSLpl $dst.hi,$src1.lo,$dst.hi \n\t"
 6025             "RSBmi $dst.hi,$dst.hi,0 \n\t"
 6026             "LSRmi $dst.hi,$src1.lo,$dst.hi" %}
 6027 
 6028   ins_encode %{
 6029     // $src1$$Register and $dst$$Register->successor() can't be the same
 6030     __ subs($dst$$Register->successor(), $src2$$Register, 32);
 6031     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $dst$$Register->successor()), pl);
 6032     __ rsb($dst$$Register->successor(), $dst$$Register->successor(), 0, mi);
 6033     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsr, $dst$$Register->successor()), mi);
 6034   %}
 6035   ins_pipe(ialu_reg_reg);
 6036 %}
 6037 
 6038 instruct shlL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
 6039   match(Set dst (LShiftL src1 src2));
 6040 
 6041   expand %{
 6042     flagsReg ccr;
 6043     shlL_reg_reg_overlap(dst, src1, src2, ccr);
 6044     shlL_reg_reg_merge_hi(dst, src1, src2);
 6045     shlL_reg_reg_merge_lo(dst, src1, src2);
 6046   %}
 6047 %}
 6048 
 6049 // Register Shift Left Immediate
 6050 instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
 6051   match(Set dst (LShiftL src1 src2));
 6052 
 6053   size(8);
 6054   format %{ "LSL   $dst.hi,$src1.lo,$src2-32\t! or mov if $src2==32\n\t"
 6055             "MOV   $dst.lo, 0" %}
 6056   ins_encode %{
 6057     if ($src2$$constant == 32) {
 6058       __ mov($dst$$Register->successor(), $src1$$Register);
 6059     } else {
 6060       __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $src2$$constant-32));
 6061     }
 6062     __ mov($dst$$Register, 0);
 6063   %}
 6064   ins_pipe(ialu_reg_imm);
 6065 %}
 6066 
 6067 instruct shlL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
 6068   match(Set dst (LShiftL src1 src2));
 6069 
 6070   size(12);
 6071   format %{ "LSL   $dst.hi,$src1.lo,$src2\n\t"
 6072             "OR    $dst.hi, $dst.hi, $src1.lo >> 32-$src2\n\t"
 6073             "LSL   $dst.lo,$src1.lo,$src2" %}
 6074   ins_encode %{
 6075     // The order of the following 3 instructions matters: src1.lo and
 6076     // dst.hi can't overlap but src.hi and dst.hi can.
 6077     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$constant));
 6078     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register, lsr, 32-$src2$$constant));
 6079     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
 6080   %}
 6081   ins_pipe(ialu_reg_imm);
 6082 %}
 6083 
 6084 // Register Arithmetic Shift Right
 6085 instruct sarI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6086   match(Set dst (RShiftI src1 src2));
 6087   size(4);
 6088   format %{ "ASR    $dst,$src1,$src2\t! int" %}
 6089   ins_encode %{
 6090     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
 6091   %}
 6092   ins_pipe(ialu_reg_reg);
 6093 %}
 6094 
 6095 // Register Arithmetic Shift Right Immediate
 6096 instruct sarI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
 6097   match(Set dst (RShiftI src1 src2));
 6098 
 6099   size(4);
 6100   format %{ "ASR    $dst,$src1,$src2" %}
 6101   ins_encode %{
 6102     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
 6103   %}
 6104   ins_pipe(ialu_reg_imm);
 6105 %}
 6106 
 6107 // Register Shift Right Arithmetic Long
 6108 instruct sarL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
 6109   effect(USE_DEF dst, USE src1, USE src2);
 6110   size(4);
 6111   format %{ "OR  $dst.lo,$dst.lo,($src1.lo >> $src2)"  %}
 6112   ins_encode %{
 6113     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6114   %}
 6115   ins_pipe(ialu_reg_reg);
 6116 %}
 6117 
 6118 instruct sarL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
 6119   effect(USE_DEF dst, USE src1, USE src2);
 6120   size(4);
 6121   format %{ "ASR  $dst.hi,$src1.hi,$src2 \n\t" %}
 6122   ins_encode %{
 6123     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$Register));
 6124   %}
 6125   ins_pipe(ialu_reg_reg);
 6126 %}
 6127 
 6128 instruct sarL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
 6129   effect(DEF dst, USE src1, USE src2, KILL ccr);
 6130   size(16);
 6131   format %{ "SUBS  $dst.lo,$src2,32 \n\t"
 6132             "ASRpl $dst.lo,$src1.hi,$dst.lo \n\t"
 6133             "RSBmi $dst.lo,$dst.lo,0 \n\t"
 6134             "LSLmi $dst.lo,$src1.hi,$dst.lo" %}
 6135 
 6136   ins_encode %{
 6137     // $src1$$Register->successor() and $dst$$Register can't be the same
 6138     __ subs($dst$$Register, $src2$$Register, 32);
 6139     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $dst$$Register), pl);
 6140     __ rsb($dst$$Register, $dst$$Register, 0, mi);
 6141     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
 6142   %}
 6143   ins_pipe(ialu_reg_reg);
 6144 %}
 6145 
 6146 instruct sarL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
 6147   match(Set dst (RShiftL src1 src2));
 6148 
 6149   expand %{
 6150     flagsReg ccr;
 6151     sarL_reg_reg_overlap(dst, src1, src2, ccr);
 6152     sarL_reg_reg_merge_lo(dst, src1, src2);
 6153     sarL_reg_reg_merge_hi(dst, src1, src2);
 6154   %}
 6155 %}
 6156 
 6157 // Register Shift Left Immediate
 6158 instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
 6159   match(Set dst (RShiftL src1 src2));
 6160 
 6161   size(8);
 6162   format %{ "ASR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
 6163             "ASR   $dst.hi,$src1.hi, $src2" %}
 6164   ins_encode %{
 6165     if ($src2$$constant == 32) {
 6166       __ mov($dst$$Register, $src1$$Register->successor());
 6167     } else{
 6168       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $src2$$constant-32));
 6169     }
 6170     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, 0));
 6171   %}
 6172 
 6173   ins_pipe(ialu_reg_imm);
 6174 %}
 6175 
 6176 instruct sarL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
 6177   match(Set dst (RShiftL src1 src2));
 6178   size(12);
 6179   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
 6180             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
 6181             "ASR   $dst.hi,$src1.hi,$src2" %}
 6182   ins_encode %{
 6183     // The order of the following 3 instructions matters: src1.lo and
 6184     // dst.hi can't overlap but src.hi and dst.hi can.
 6185     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6186     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
 6187     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$constant));
 6188   %}
 6189   ins_pipe(ialu_reg_imm);
 6190 %}
 6191 
 6192 // Register Shift Right
 6193 instruct shrI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6194   match(Set dst (URShiftI src1 src2));
 6195   size(4);
 6196   format %{ "LSR    $dst,$src1,$src2\t! int" %}
 6197   ins_encode %{
 6198     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6199   %}
 6200   ins_pipe(ialu_reg_reg);
 6201 %}
 6202 
 6203 // Register Shift Right Immediate
 6204 instruct shrI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
 6205   match(Set dst (URShiftI src1 src2));
 6206 
 6207   size(4);
 6208   format %{ "LSR    $dst,$src1,$src2" %}
 6209   ins_encode %{
 6210     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6211   %}
 6212   ins_pipe(ialu_reg_imm);
 6213 %}
 6214 
 6215 // Register Shift Right
 6216 instruct shrL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
 6217   effect(USE_DEF dst, USE src1, USE src2);
 6218   size(4);
 6219   format %{ "OR   $dst.lo,$dst,($src1.lo >>> $src2)"  %}
 6220   ins_encode %{
 6221     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6222   %}
 6223   ins_pipe(ialu_reg_reg);
 6224 %}
 6225 
 6226 instruct shrL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
 6227   effect(USE_DEF dst, USE src1, USE src2);
 6228   size(4);
 6229   format %{ "LSR  $dst.hi,$src1.hi,$src2 \n\t" %}
 6230   ins_encode %{
 6231     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$Register));
 6232   %}
 6233   ins_pipe(ialu_reg_reg);
 6234 %}
 6235 
 6236 instruct shrL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
 6237   effect(DEF dst, USE src1, USE src2, KILL ccr);
 6238   size(16);
 6239   format %{ "SUBS  $dst,$src2,32 \n\t"
 6240             "LSRpl $dst,$src1.hi,$dst \n\t"
 6241             "RSBmi $dst,$dst,0 \n\t"
 6242             "LSLmi $dst,$src1.hi,$dst" %}
 6243 
 6244   ins_encode %{
 6245     // $src1$$Register->successor() and $dst$$Register can't be the same
 6246     __ subs($dst$$Register, $src2$$Register, 32);
 6247     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $dst$$Register), pl);
 6248     __ rsb($dst$$Register, $dst$$Register, 0, mi);
 6249     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
 6250   %}
 6251   ins_pipe(ialu_reg_reg);
 6252 %}
 6253 
 6254 instruct shrL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
 6255   match(Set dst (URShiftL src1 src2));
 6256 
 6257   expand %{
 6258     flagsReg ccr;
 6259     shrL_reg_reg_overlap(dst, src1, src2, ccr);
 6260     shrL_reg_reg_merge_lo(dst, src1, src2);
 6261     shrL_reg_reg_merge_hi(dst, src1, src2);
 6262   %}
 6263 %}
 6264 
 6265 // Register Shift Right Immediate
 6266 instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
 6267   match(Set dst (URShiftL src1 src2));
 6268 
 6269   size(8);
 6270   format %{ "LSR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
 6271             "MOV   $dst.hi, 0" %}
 6272   ins_encode %{
 6273     if ($src2$$constant == 32) {
 6274       __ mov($dst$$Register, $src1$$Register->successor());
 6275     } else {
 6276       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $src2$$constant-32));
 6277     }
 6278     __ mov($dst$$Register->successor(), 0);
 6279   %}
 6280 
 6281   ins_pipe(ialu_reg_imm);
 6282 %}
 6283 
 6284 instruct shrL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
 6285   match(Set dst (URShiftL src1 src2));
 6286 
 6287   size(12);
 6288   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
 6289             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
 6290             "LSR   $dst.hi,$src1.hi,$src2" %}
 6291   ins_encode %{
 6292     // The order of the following 3 instructions matters: src1.lo and
 6293     // dst.hi can't overlap but src.hi and dst.hi can.
 6294     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6295     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
 6296     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$constant));
 6297   %}
 6298   ins_pipe(ialu_reg_imm);
 6299 %}
 6300 
 6301 
 6302 instruct shrP_reg_imm5(iRegX dst, iRegP src1, immU5 src2) %{
 6303   match(Set dst (URShiftI (CastP2X src1) src2));
 6304   size(4);
 6305   format %{ "LSR    $dst,$src1,$src2\t! Cast ptr $src1 to int and shift" %}
 6306   ins_encode %{
 6307     __ logical_shift_right($dst$$Register, $src1$$Register, $src2$$constant);
 6308   %}
 6309   ins_pipe(ialu_reg_imm);
 6310 %}
 6311 
 6312 //----------Floating Point Arithmetic Instructions-----------------------------
 6313 
 6314 //  Add float single precision
 6315 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
 6316   match(Set dst (AddF src1 src2));
 6317 
 6318   size(4);
 6319   format %{ "FADDS  $dst,$src1,$src2" %}
 6320   ins_encode %{
 6321     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6322   %}
 6323 
 6324   ins_pipe(faddF_reg_reg);
 6325 %}
 6326 
 6327 //  Add float double precision
 6328 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
 6329   match(Set dst (AddD src1 src2));
 6330 
 6331   size(4);
 6332   format %{ "FADDD  $dst,$src1,$src2" %}
 6333   ins_encode %{
 6334     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6335   %}
 6336 
 6337   ins_pipe(faddD_reg_reg);
 6338 %}
 6339 
 6340 //  Sub float single precision
 6341 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
 6342   match(Set dst (SubF src1 src2));
 6343 
 6344   size(4);
 6345   format %{ "FSUBS  $dst,$src1,$src2" %}
 6346   ins_encode %{
 6347     __ sub_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6348   %}
 6349   ins_pipe(faddF_reg_reg);
 6350 %}
 6351 
 6352 //  Sub float double precision
 6353 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
 6354   match(Set dst (SubD src1 src2));
 6355 
 6356   size(4);
 6357   format %{ "FSUBD  $dst,$src1,$src2" %}
 6358   ins_encode %{
 6359     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6360   %}
 6361   ins_pipe(faddD_reg_reg);
 6362 %}
 6363 
 6364 //  Mul float single precision
 6365 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
 6366   match(Set dst (MulF src1 src2));
 6367 
 6368   size(4);
 6369   format %{ "FMULS  $dst,$src1,$src2" %}
 6370   ins_encode %{
 6371     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6372   %}
 6373 
 6374   ins_pipe(fmulF_reg_reg);
 6375 %}
 6376 
 6377 //  Mul float double precision
 6378 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
 6379   match(Set dst (MulD src1 src2));
 6380 
 6381   size(4);
 6382   format %{ "FMULD  $dst,$src1,$src2" %}
 6383   ins_encode %{
 6384     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6385   %}
 6386 
 6387   ins_pipe(fmulD_reg_reg);
 6388 %}
 6389 
 6390 //  Div float single precision
 6391 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
 6392   match(Set dst (DivF src1 src2));
 6393 
 6394   size(4);
 6395   format %{ "FDIVS  $dst,$src1,$src2" %}
 6396   ins_encode %{
 6397     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6398   %}
 6399 
 6400   ins_pipe(fdivF_reg_reg);
 6401 %}
 6402 
 6403 //  Div float double precision
 6404 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
 6405   match(Set dst (DivD src1 src2));
 6406 
 6407   size(4);
 6408   format %{ "FDIVD  $dst,$src1,$src2" %}
 6409   ins_encode %{
 6410     __ div_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6411   %}
 6412 
 6413   ins_pipe(fdivD_reg_reg);
 6414 %}
 6415 
 6416 //  Absolute float double precision
 6417 instruct absD_reg(regD dst, regD src) %{
 6418   match(Set dst (AbsD src));
 6419 
 6420   size(4);
 6421   format %{ "FABSd  $dst,$src" %}
 6422   ins_encode %{
 6423     __ abs_double($dst$$FloatRegister, $src$$FloatRegister);
 6424   %}
 6425   ins_pipe(faddD_reg);
 6426 %}
 6427 
 6428 //  Absolute float single precision
 6429 instruct absF_reg(regF dst, regF src) %{
 6430   match(Set dst (AbsF src));
 6431   format %{ "FABSs  $dst,$src" %}
 6432   ins_encode %{
 6433     __ abs_float($dst$$FloatRegister, $src$$FloatRegister);
 6434   %}
 6435   ins_pipe(faddF_reg);
 6436 %}
 6437 
 6438 instruct negF_reg(regF dst, regF src) %{
 6439   match(Set dst (NegF src));
 6440 
 6441   size(4);
 6442   format %{ "FNEGs  $dst,$src" %}
 6443   ins_encode %{
 6444     __ neg_float($dst$$FloatRegister, $src$$FloatRegister);
 6445   %}
 6446   ins_pipe(faddF_reg);
 6447 %}
 6448 
 6449 instruct negD_reg(regD dst, regD src) %{
 6450   match(Set dst (NegD src));
 6451 
 6452   format %{ "FNEGd  $dst,$src" %}
 6453   ins_encode %{
 6454     __ neg_double($dst$$FloatRegister, $src$$FloatRegister);
 6455   %}
 6456   ins_pipe(faddD_reg);
 6457 %}
 6458 
 6459 //  Sqrt float double precision
 6460 instruct sqrtF_reg_reg(regF dst, regF src) %{
 6461   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
 6462 
 6463   size(4);
 6464   format %{ "FSQRTS $dst,$src" %}
 6465   ins_encode %{
 6466     __ sqrt_float($dst$$FloatRegister, $src$$FloatRegister);
 6467   %}
 6468   ins_pipe(fdivF_reg_reg);
 6469 %}
 6470 
 6471 //  Sqrt float double precision
 6472 instruct sqrtD_reg_reg(regD dst, regD src) %{
 6473   match(Set dst (SqrtD src));
 6474 
 6475   size(4);
 6476   format %{ "FSQRTD $dst,$src" %}
 6477   ins_encode %{
 6478     __ sqrt_double($dst$$FloatRegister, $src$$FloatRegister);
 6479   %}
 6480   ins_pipe(fdivD_reg_reg);
 6481 %}
 6482 
 6483 //----------Logical Instructions-----------------------------------------------
 6484 // And Instructions
 6485 // Register And
 6486 instruct andI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6487   match(Set dst (AndI src1 src2));
 6488 
 6489   size(4);
 6490   format %{ "and_32 $dst,$src1,$src2" %}
 6491   ins_encode %{
 6492     __ and_32($dst$$Register, $src1$$Register, $src2$$Register);
 6493   %}
 6494   ins_pipe(ialu_reg_reg);
 6495 %}
 6496 
 6497 instruct andshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6498   match(Set dst (AndI src1 (LShiftI src2 src3)));
 6499 
 6500   size(4);
 6501   format %{ "AND    $dst,$src1,$src2<<$src3" %}
 6502   ins_encode %{
 6503     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 6504   %}
 6505   ins_pipe(ialu_reg_reg);
 6506 %}
 6507 
 6508 instruct andshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6509   match(Set dst (AndI src1 (LShiftI src2 src3)));
 6510 
 6511   size(4);
 6512   format %{ "and_32 $dst,$src1,$src2<<$src3" %}
 6513   ins_encode %{
 6514     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 6515   %}
 6516   ins_pipe(ialu_reg_reg);
 6517 %}
 6518 
 6519 instruct andsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6520   match(Set dst (AndI src1 (RShiftI src2 src3)));
 6521 
 6522   size(4);
 6523   format %{ "AND    $dst,$src1,$src2>>$src3" %}
 6524   ins_encode %{
 6525     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 6526   %}
 6527   ins_pipe(ialu_reg_reg);
 6528 %}
 6529 
 6530 instruct andsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6531   match(Set dst (AndI src1 (RShiftI src2 src3)));
 6532 
 6533   size(4);
 6534   format %{ "and_32 $dst,$src1,$src2>>$src3" %}
 6535   ins_encode %{
 6536     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 6537   %}
 6538   ins_pipe(ialu_reg_reg);
 6539 %}
 6540 
 6541 instruct andshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6542   match(Set dst (AndI src1 (URShiftI src2 src3)));
 6543 
 6544   size(4);
 6545   format %{ "AND    $dst,$src1,$src2>>>$src3" %}
 6546   ins_encode %{
 6547     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 6548   %}
 6549   ins_pipe(ialu_reg_reg);
 6550 %}
 6551 
 6552 instruct andshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6553   match(Set dst (AndI src1 (URShiftI src2 src3)));
 6554 
 6555   size(4);
 6556   format %{ "and_32 $dst,$src1,$src2>>>$src3" %}
 6557   ins_encode %{
 6558     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 6559   %}
 6560   ins_pipe(ialu_reg_reg);
 6561 %}
 6562 
 6563 // Immediate And
 6564 instruct andI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
 6565   match(Set dst (AndI src1 src2));
 6566 
 6567   size(4);
 6568   format %{ "and_32 $dst,$src1,$src2\t! int" %}
 6569   ins_encode %{
 6570     __ and_32($dst$$Register, $src1$$Register, $src2$$constant);
 6571   %}
 6572   ins_pipe(ialu_reg_imm);
 6573 %}
 6574 
 6575 instruct andI_reg_limmn(iRegI dst, iRegI src1, limmIn src2) %{
 6576   match(Set dst (AndI src1 src2));
 6577 
 6578   size(4);
 6579   format %{ "bic    $dst,$src1,~$src2\t! int" %}
 6580   ins_encode %{
 6581     __ bic($dst$$Register, $src1$$Register, ~$src2$$constant);
 6582   %}
 6583   ins_pipe(ialu_reg_imm);
 6584 %}
 6585 
 6586 // Register And Long
 6587 instruct andL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 6588   match(Set dst (AndL src1 src2));
 6589 
 6590   ins_cost(DEFAULT_COST);
 6591   size(8);
 6592   format %{ "AND    $dst,$src1,$src2\t! long" %}
 6593   ins_encode %{
 6594     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
 6595     __ andr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 6596   %}
 6597   ins_pipe(ialu_reg_reg);
 6598 %}
 6599 
 6600 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 6601 // (hi($con$$constant), lo($con$$constant)) becomes
 6602 instruct andL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
 6603   match(Set dst (AndL src1 con));
 6604   ins_cost(DEFAULT_COST);
 6605   size(8);
 6606   format %{ "AND    $dst,$src1,$con\t! long" %}
 6607   ins_encode %{
 6608     __ andr($dst$$Register, $src1$$Register, $con$$constant);
 6609     __ andr($dst$$Register->successor(), $src1$$Register->successor(), 0);
 6610   %}
 6611   ins_pipe(ialu_reg_imm);
 6612 %}
 6613 
 6614 // Or Instructions
 6615 // Register Or
 6616 instruct orI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6617   match(Set dst (OrI src1 src2));
 6618 
 6619   size(4);
 6620   format %{ "orr_32 $dst,$src1,$src2\t! int" %}
 6621   ins_encode %{
 6622     __ orr_32($dst$$Register, $src1$$Register, $src2$$Register);
 6623   %}
 6624   ins_pipe(ialu_reg_reg);
 6625 %}
 6626 
 6627 instruct orshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6628   match(Set dst (OrI src1 (LShiftI src2 src3)));
 6629 
 6630   size(4);
 6631   format %{ "OR    $dst,$src1,$src2<<$src3" %}
 6632   ins_encode %{
 6633     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 6634   %}
 6635   ins_pipe(ialu_reg_reg);
 6636 %}
 6637 
 6638 instruct orshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6639   match(Set dst (OrI src1 (LShiftI src2 src3)));
 6640 
 6641   size(4);
 6642   format %{ "orr_32 $dst,$src1,$src2<<$src3" %}
 6643   ins_encode %{
 6644     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 6645   %}
 6646   ins_pipe(ialu_reg_reg);
 6647 %}
 6648 
 6649 instruct orsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6650   match(Set dst (OrI src1 (RShiftI src2 src3)));
 6651 
 6652   size(4);
 6653   format %{ "OR    $dst,$src1,$src2>>$src3" %}
 6654   ins_encode %{
 6655     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 6656   %}
 6657   ins_pipe(ialu_reg_reg);
 6658 %}
 6659 
 6660 instruct orsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6661   match(Set dst (OrI src1 (RShiftI src2 src3)));
 6662 
 6663   size(4);
 6664   format %{ "orr_32 $dst,$src1,$src2>>$src3" %}
 6665   ins_encode %{
 6666     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 6667   %}
 6668   ins_pipe(ialu_reg_reg);
 6669 %}
 6670 
 6671 instruct orshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6672   match(Set dst (OrI src1 (URShiftI src2 src3)));
 6673 
 6674   size(4);
 6675   format %{ "OR    $dst,$src1,$src2>>>$src3" %}
 6676   ins_encode %{
 6677     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 6678   %}
 6679   ins_pipe(ialu_reg_reg);
 6680 %}
 6681 
 6682 instruct orshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6683   match(Set dst (OrI src1 (URShiftI src2 src3)));
 6684 
 6685   size(4);
 6686   format %{ "orr_32 $dst,$src1,$src2>>>$src3" %}
 6687   ins_encode %{
 6688     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 6689   %}
 6690   ins_pipe(ialu_reg_reg);
 6691 %}
 6692 
 6693 // Immediate Or
 6694 instruct orI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
 6695   match(Set dst (OrI src1 src2));
 6696 
 6697   size(4);
 6698   format %{ "orr_32  $dst,$src1,$src2" %}
 6699   ins_encode %{
 6700     __ orr_32($dst$$Register, $src1$$Register, $src2$$constant);
 6701   %}
 6702   ins_pipe(ialu_reg_imm);
 6703 %}
 6704 // TODO: orn_32 with limmIn
 6705 
 6706 // Register Or Long
 6707 instruct orL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 6708   match(Set dst (OrL src1 src2));
 6709 
 6710   ins_cost(DEFAULT_COST);
 6711   size(8);
 6712   format %{ "OR     $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
 6713             "OR     $dst.hi,$src1.hi,$src2.hi" %}
 6714   ins_encode %{
 6715     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
 6716     __ orr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 6717   %}
 6718   ins_pipe(ialu_reg_reg);
 6719 %}
 6720 
 6721 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 6722 // (hi($con$$constant), lo($con$$constant)) becomes
 6723 instruct orL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
 6724   match(Set dst (OrL src1 con));
 6725   ins_cost(DEFAULT_COST);
 6726   size(8);
 6727   format %{ "OR     $dst.lo,$src1.lo,$con\t! long\n\t"
 6728             "OR     $dst.hi,$src1.hi,$con" %}
 6729   ins_encode %{
 6730     __ orr($dst$$Register, $src1$$Register, $con$$constant);
 6731     __ orr($dst$$Register->successor(), $src1$$Register->successor(), 0);
 6732   %}
 6733   ins_pipe(ialu_reg_imm);
 6734 %}
 6735 
 6736 #ifdef TODO
 6737 // Use SPRegP to match Rthread (TLS register) without spilling.
 6738 // Use store_ptr_RegP to match Rthread (TLS register) without spilling.
 6739 // Use sp_ptr_RegP to match Rthread (TLS register) without spilling.
 6740 instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
 6741   match(Set dst (OrI src1 (CastP2X src2)));
 6742   size(4);
 6743   format %{ "OR     $dst,$src1,$src2" %}
 6744   ins_encode %{
 6745     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
 6746   %}
 6747   ins_pipe(ialu_reg_reg);
 6748 %}
 6749 #endif
 6750 
 6751 // Xor Instructions
 6752 // Register Xor
 6753 instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6754   match(Set dst (XorI src1 src2));
 6755 
 6756   size(4);
 6757   format %{ "eor_32 $dst,$src1,$src2" %}
 6758   ins_encode %{
 6759     __ eor_32($dst$$Register, $src1$$Register, $src2$$Register);
 6760   %}
 6761   ins_pipe(ialu_reg_reg);
 6762 %}
 6763 
 6764 instruct xorshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6765   match(Set dst (XorI src1 (LShiftI src2 src3)));
 6766 
 6767   size(4);
 6768   format %{ "XOR    $dst,$src1,$src2<<$src3" %}
 6769   ins_encode %{
 6770     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 6771   %}
 6772   ins_pipe(ialu_reg_reg);
 6773 %}
 6774 
 6775 instruct xorshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6776   match(Set dst (XorI src1 (LShiftI src2 src3)));
 6777 
 6778   size(4);
 6779   format %{ "eor_32 $dst,$src1,$src2<<$src3" %}
 6780   ins_encode %{
 6781     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 6782   %}
 6783   ins_pipe(ialu_reg_reg);
 6784 %}
 6785 
 6786 instruct xorsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6787   match(Set dst (XorI src1 (RShiftI src2 src3)));
 6788 
 6789   size(4);
 6790   format %{ "XOR    $dst,$src1,$src2>>$src3" %}
 6791   ins_encode %{
 6792     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 6793   %}
 6794   ins_pipe(ialu_reg_reg);
 6795 %}
 6796 
 6797 instruct xorsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6798   match(Set dst (XorI src1 (RShiftI src2 src3)));
 6799 
 6800   size(4);
 6801   format %{ "eor_32 $dst,$src1,$src2>>$src3" %}
 6802   ins_encode %{
 6803     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 6804   %}
 6805   ins_pipe(ialu_reg_reg);
 6806 %}
 6807 
 6808 instruct xorshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6809   match(Set dst (XorI src1 (URShiftI src2 src3)));
 6810 
 6811   size(4);
 6812   format %{ "XOR    $dst,$src1,$src2>>>$src3" %}
 6813   ins_encode %{
 6814     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 6815   %}
 6816   ins_pipe(ialu_reg_reg);
 6817 %}
 6818 
 6819 instruct xorshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6820   match(Set dst (XorI src1 (URShiftI src2 src3)));
 6821 
 6822   size(4);
 6823   format %{ "eor_32 $dst,$src1,$src2>>>$src3" %}
 6824   ins_encode %{
 6825     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 6826   %}
 6827   ins_pipe(ialu_reg_reg);
 6828 %}
 6829 
 6830 // Immediate Xor
 6831 instruct xorI_reg_imm(iRegI dst, iRegI src1, limmI src2) %{
 6832   match(Set dst (XorI src1 src2));
 6833 
 6834   size(4);
 6835   format %{ "eor_32 $dst,$src1,$src2" %}
 6836   ins_encode %{
 6837     __ eor_32($dst$$Register, $src1$$Register, $src2$$constant);
 6838   %}
 6839   ins_pipe(ialu_reg_imm);
 6840 %}
 6841 
 6842 // Register Xor Long
 6843 instruct xorL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 6844   match(Set dst (XorL src1 src2));
 6845   ins_cost(DEFAULT_COST);
 6846   size(8);
 6847   format %{ "XOR     $dst.hi,$src1.hi,$src2.hi\t! long\n\t"
 6848             "XOR     $dst.lo,$src1.lo,$src2.lo\t! long" %}
 6849   ins_encode %{
 6850     __ eor($dst$$Register, $src1$$Register, $src2$$Register);
 6851     __ eor($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 6852   %}
 6853   ins_pipe(ialu_reg_reg);
 6854 %}
 6855 
 6856 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 6857 // (hi($con$$constant), lo($con$$constant)) becomes
 6858 instruct xorL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
 6859   match(Set dst (XorL src1 con));
 6860   ins_cost(DEFAULT_COST);
 6861   size(8);
 6862   format %{ "XOR     $dst.hi,$src1.hi,$con\t! long\n\t"
 6863             "XOR     $dst.lo,$src1.lo,0\t! long" %}
 6864   ins_encode %{
 6865     __ eor($dst$$Register, $src1$$Register, $con$$constant);
 6866     __ eor($dst$$Register->successor(), $src1$$Register->successor(), 0);
 6867   %}
 6868   ins_pipe(ialu_reg_imm);
 6869 %}
 6870 
 6871 instruct cmpLTMask_reg_reg( iRegI dst, iRegI p, iRegI q, flagsReg ccr ) %{
 6872   match(Set dst (CmpLTMask p q));
 6873   effect( KILL ccr );
 6874   ins_cost(DEFAULT_COST*3);
 6875   format %{ "CMP    $p,$q\n\t"
 6876             "MOV    $dst, #0\n\t"
 6877             "MOV.lt $dst, #-1" %}
 6878   ins_encode %{
 6879     __ cmp($p$$Register, $q$$Register);
 6880     __ mov($dst$$Register, 0);
 6881     __ mvn($dst$$Register, 0, lt);
 6882   %}
 6883   ins_pipe(ialu_reg_reg_ialu);
 6884 %}
 6885 
 6886 instruct cmpLTMask_reg_imm( iRegI dst, iRegI p, aimmI q, flagsReg ccr ) %{
 6887   match(Set dst (CmpLTMask p q));
 6888   effect( KILL ccr );
 6889   ins_cost(DEFAULT_COST*3);
 6890   format %{ "CMP    $p,$q\n\t"
 6891             "MOV    $dst, #0\n\t"
 6892             "MOV.lt $dst, #-1" %}
 6893   ins_encode %{
 6894     __ cmp($p$$Register, $q$$constant);
 6895     __ mov($dst$$Register, 0);
 6896     __ mvn($dst$$Register, 0, lt);
 6897   %}
 6898   ins_pipe(ialu_reg_reg_ialu);
 6899 %}
 6900 
 6901 instruct cadd_cmpLTMask3( iRegI p, iRegI q, iRegI y, iRegI z, flagsReg ccr ) %{
 6902   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
 6903   effect( KILL ccr );
 6904   ins_cost(DEFAULT_COST*2);
 6905   format %{ "CMP    $p,$q\n\t"
 6906             "ADD.lt $z,$y,$z" %}
 6907   ins_encode %{
 6908     __ cmp($p$$Register, $q$$Register);
 6909     __ add($z$$Register, $y$$Register, $z$$Register, lt);
 6910   %}
 6911   ins_pipe( cadd_cmpltmask );
 6912 %}
 6913 
 6914 // FIXME: remove unused "dst"
 6915 instruct cadd_cmpLTMask4( iRegI dst, iRegI p, aimmI q, iRegI y, iRegI z, flagsReg ccr ) %{
 6916   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
 6917   effect( KILL ccr );
 6918   ins_cost(DEFAULT_COST*2);
 6919   format %{ "CMP    $p,$q\n\t"
 6920             "ADD.lt $z,$y,$z" %}
 6921   ins_encode %{
 6922     __ cmp($p$$Register, $q$$constant);
 6923     __ add($z$$Register, $y$$Register, $z$$Register, lt);
 6924   %}
 6925   ins_pipe( cadd_cmpltmask );
 6926 %}
 6927 
 6928 instruct cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, flagsReg ccr ) %{
 6929   match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
 6930   effect( KILL ccr );
 6931   ins_cost(DEFAULT_COST*2);
 6932   format %{ "SUBS   $p,$p,$q\n\t"
 6933             "ADD.lt $p,$y,$p" %}
 6934   ins_encode %{
 6935     __ subs($p$$Register, $p$$Register, $q$$Register);
 6936     __ add($p$$Register, $y$$Register, $p$$Register, lt);
 6937   %}
 6938   ins_pipe( cadd_cmpltmask );
 6939 %}
 6940 
 6941 //----------Arithmetic Conversion Instructions---------------------------------
 6942 // The conversions operations are all Alpha sorted.  Please keep it that way!
 6943 
 6944 instruct convD2F_reg(regF dst, regD src) %{
 6945   match(Set dst (ConvD2F src));
 6946   size(4);
 6947   format %{ "FCVTSD  $dst,$src" %}
 6948   ins_encode %{
 6949     __ convert_d2f($dst$$FloatRegister, $src$$FloatRegister);
 6950   %}
 6951   ins_pipe(fcvtD2F);
 6952 %}
 6953 
 6954 // Convert a double to an int in a float register.
 6955 // If the double is a NAN, stuff a zero in instead.
 6956 
 6957 instruct convD2I_reg_reg(iRegI dst, regD src, regF tmp) %{
 6958   match(Set dst (ConvD2I src));
 6959   effect( TEMP tmp );
 6960   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
 6961   format %{ "FTOSIZD  $tmp,$src\n\t"
 6962             "FMRS     $dst, $tmp" %}
 6963   ins_encode %{
 6964     __ ftosizd($tmp$$FloatRegister, $src$$FloatRegister);
 6965     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 6966   %}
 6967   ins_pipe(fcvtD2I);
 6968 %}
 6969 
 6970 // Convert a double to a long in a double register.
 6971 // If the double is a NAN, stuff a zero in instead.
 6972 
 6973 // Double to Long conversion
 6974 instruct convD2L_reg(R0R1RegL dst, regD src) %{
 6975   match(Set dst (ConvD2L src));
 6976   effect(CALL);
 6977   ins_cost(MEMORY_REF_COST); // FIXME
 6978   format %{ "convD2L    $dst,$src\t ! call to SharedRuntime::d2l" %}
 6979   ins_encode %{
 6980 #ifndef __ABI_HARD__
 6981     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
 6982 #else
 6983     if ($src$$FloatRegister != D0) {
 6984       __ mov_double(D0, $src$$FloatRegister);
 6985     }
 6986 #endif
 6987     address target = CAST_FROM_FN_PTR(address, SharedRuntime::d2l);
 6988     __ call(target, relocInfo::runtime_call_type);
 6989   %}
 6990   ins_pipe(fcvtD2L);
 6991 %}
 6992 
 6993 instruct convF2D_reg(regD dst, regF src) %{
 6994   match(Set dst (ConvF2D src));
 6995   size(4);
 6996   format %{ "FCVTDS  $dst,$src" %}
 6997   ins_encode %{
 6998     __ convert_f2d($dst$$FloatRegister, $src$$FloatRegister);
 6999   %}
 7000   ins_pipe(fcvtF2D);
 7001 %}
 7002 
 7003 instruct convF2I_reg_reg(iRegI dst, regF src, regF tmp) %{
 7004   match(Set dst (ConvF2I src));
 7005   effect( TEMP tmp );
 7006   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
 7007   size(8);
 7008   format %{ "FTOSIZS  $tmp,$src\n\t"
 7009             "FMRS     $dst, $tmp" %}
 7010   ins_encode %{
 7011     __ ftosizs($tmp$$FloatRegister, $src$$FloatRegister);
 7012     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 7013   %}
 7014   ins_pipe(fcvtF2I);
 7015 %}
 7016 
 7017 // Float to Long conversion
 7018 instruct convF2L_reg(R0R1RegL dst, regF src, R0RegI arg1) %{
 7019   match(Set dst (ConvF2L src));
 7020   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
 7021   effect(CALL);
 7022   format %{ "convF2L  $dst,$src\t! call to SharedRuntime::f2l" %}
 7023   ins_encode %{
 7024 #ifndef __ABI_HARD__
 7025     __ fmrs($arg1$$Register, $src$$FloatRegister);
 7026 #else
 7027     if($src$$FloatRegister != S0) {
 7028       __ mov_float(S0, $src$$FloatRegister);
 7029     }
 7030 #endif
 7031     address target = CAST_FROM_FN_PTR(address, SharedRuntime::f2l);
 7032     __ call(target, relocInfo::runtime_call_type);
 7033   %}
 7034   ins_pipe(fcvtF2L);
 7035 %}
 7036 
 7037 instruct convI2D_reg_reg(iRegI src, regD_low dst) %{
 7038   match(Set dst (ConvI2D src));
 7039   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
 7040   size(8);
 7041   format %{ "FMSR     $dst,$src \n\t"
 7042             "FSITOD   $dst $dst"%}
 7043   ins_encode %{
 7044       __ fmsr($dst$$FloatRegister, $src$$Register);
 7045       __ fsitod($dst$$FloatRegister, $dst$$FloatRegister);
 7046   %}
 7047   ins_pipe(fcvtI2D);
 7048 %}
 7049 
 7050 instruct convI2F_reg_reg( regF dst, iRegI src ) %{
 7051   match(Set dst (ConvI2F src));
 7052   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
 7053   size(8);
 7054   format %{ "FMSR     $dst,$src \n\t"
 7055             "FSITOS   $dst, $dst"%}
 7056   ins_encode %{
 7057       __ fmsr($dst$$FloatRegister, $src$$Register);
 7058       __ fsitos($dst$$FloatRegister, $dst$$FloatRegister);
 7059   %}
 7060   ins_pipe(fcvtI2F);
 7061 %}
 7062 
 7063 instruct convI2L_reg(iRegL dst, iRegI src) %{
 7064   match(Set dst (ConvI2L src));
 7065   size(8);
 7066   format %{ "MOV    $dst.lo, $src \n\t"
 7067             "ASR    $dst.hi,$src,31\t! int->long" %}
 7068   ins_encode %{
 7069     __ mov($dst$$Register, $src$$Register);
 7070     __ mov($dst$$Register->successor(), AsmOperand($src$$Register, asr, 31));
 7071   %}
 7072   ins_pipe(ialu_reg_reg);
 7073 %}
 7074 
 7075 // Zero-extend convert int to long
 7076 instruct convI2L_reg_zex(iRegL dst, iRegI src, immL_32bits mask ) %{
 7077   match(Set dst (AndL (ConvI2L src) mask) );
 7078   size(8);
 7079   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend int to long\n\t"
 7080             "MOV    $dst.hi, 0"%}
 7081   ins_encode %{
 7082     __ mov($dst$$Register, $src$$Register);
 7083     __ mov($dst$$Register->successor(), 0);
 7084   %}
 7085   ins_pipe(ialu_reg_reg);
 7086 %}
 7087 
 7088 // Zero-extend long
 7089 instruct zerox_long(iRegL dst, iRegL src, immL_32bits mask ) %{
 7090   match(Set dst (AndL src mask) );
 7091   size(8);
 7092   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend long\n\t"
 7093             "MOV    $dst.hi, 0"%}
 7094   ins_encode %{
 7095     __ mov($dst$$Register, $src$$Register);
 7096     __ mov($dst$$Register->successor(), 0);
 7097   %}
 7098   ins_pipe(ialu_reg_reg);
 7099 %}
 7100 
 7101 instruct MoveF2I_reg_reg(iRegI dst, regF src) %{
 7102   match(Set dst (MoveF2I src));
 7103   effect(DEF dst, USE src);
 7104   ins_cost(MEMORY_REF_COST); // FIXME
 7105 
 7106   size(4);
 7107   format %{ "FMRS   $dst,$src\t! MoveF2I" %}
 7108   ins_encode %{
 7109     __ fmrs($dst$$Register, $src$$FloatRegister);
 7110   %}
 7111   ins_pipe(iload_mem); // FIXME
 7112 %}
 7113 
 7114 instruct MoveI2F_reg_reg(regF dst, iRegI src) %{
 7115   match(Set dst (MoveI2F src));
 7116   ins_cost(MEMORY_REF_COST); // FIXME
 7117 
 7118   size(4);
 7119   format %{ "FMSR   $dst,$src\t! MoveI2F" %}
 7120   ins_encode %{
 7121     __ fmsr($dst$$FloatRegister, $src$$Register);
 7122   %}
 7123   ins_pipe(iload_mem); // FIXME
 7124 %}
 7125 
 7126 instruct MoveD2L_reg_reg(iRegL dst, regD src) %{
 7127   match(Set dst (MoveD2L src));
 7128   effect(DEF dst, USE src);
 7129   ins_cost(MEMORY_REF_COST); // FIXME
 7130 
 7131   size(4);
 7132   format %{ "FMRRD    $dst,$src\t! MoveD2L" %}
 7133   ins_encode %{
 7134     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
 7135   %}
 7136   ins_pipe(iload_mem); // FIXME
 7137 %}
 7138 
 7139 instruct MoveL2D_reg_reg(regD dst, iRegL src) %{
 7140   match(Set dst (MoveL2D src));
 7141   effect(DEF dst, USE src);
 7142   ins_cost(MEMORY_REF_COST); // FIXME
 7143 
 7144   size(4);
 7145   format %{ "FMDRR   $dst,$src\t! MoveL2D" %}
 7146   ins_encode %{
 7147     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
 7148   %}
 7149   ins_pipe(ialu_reg_reg); // FIXME
 7150 %}
 7151 
 7152 //-----------
 7153 // Long to Double conversion
 7154 
 7155 // Magic constant, 0x43300000
 7156 instruct loadConI_x43300000(iRegI dst) %{
 7157   effect(DEF dst);
 7158   size(8);
 7159   format %{ "MOV_SLOW  $dst,0x43300000\t! 2^52" %}
 7160   ins_encode %{
 7161     __ mov_slow($dst$$Register, 0x43300000);
 7162   %}
 7163   ins_pipe(ialu_none);
 7164 %}
 7165 
 7166 // Magic constant, 0x41f00000
 7167 instruct loadConI_x41f00000(iRegI dst) %{
 7168   effect(DEF dst);
 7169   size(8);
 7170   format %{ "MOV_SLOW  $dst, 0x41f00000\t! 2^32" %}
 7171   ins_encode %{
 7172     __ mov_slow($dst$$Register, 0x41f00000);
 7173   %}
 7174   ins_pipe(ialu_none);
 7175 %}
 7176 
 7177 instruct loadConI_x0(iRegI dst) %{
 7178   effect(DEF dst);
 7179   size(4);
 7180   format %{ "MOV  $dst, 0x0\t! 0" %}
 7181   ins_encode %{
 7182     __ mov($dst$$Register, 0);
 7183   %}
 7184   ins_pipe(ialu_none);
 7185 %}
 7186 
 7187 // Construct a double from two float halves
 7188 instruct regDHi_regDLo_to_regD(regD_low dst, regD_low src1, regD_low src2) %{
 7189   effect(DEF dst, USE src1, USE src2);
 7190   size(8);
 7191   format %{ "FCPYS  $dst.hi,$src1.hi\n\t"
 7192             "FCPYS  $dst.lo,$src2.lo" %}
 7193   ins_encode %{
 7194     __ fcpys($dst$$FloatRegister->successor(), $src1$$FloatRegister->successor());
 7195     __ fcpys($dst$$FloatRegister, $src2$$FloatRegister);
 7196   %}
 7197   ins_pipe(faddD_reg_reg);
 7198 %}
 7199 
 7200 // Convert integer in high half of a double register (in the lower half of
 7201 // the double register file) to double
 7202 instruct convI2D_regDHi_regD(regD dst, regD_low src) %{
 7203   effect(DEF dst, USE src);
 7204   size(4);
 7205   format %{ "FSITOD  $dst,$src" %}
 7206   ins_encode %{
 7207     __ fsitod($dst$$FloatRegister, $src$$FloatRegister->successor());
 7208   %}
 7209   ins_pipe(fcvtLHi2D);
 7210 %}
 7211 
 7212 // Add float double precision
 7213 instruct addD_regD_regD(regD dst, regD src1, regD src2) %{
 7214   effect(DEF dst, USE src1, USE src2);
 7215   size(4);
 7216   format %{ "FADDD  $dst,$src1,$src2" %}
 7217   ins_encode %{
 7218     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 7219   %}
 7220   ins_pipe(faddD_reg_reg);
 7221 %}
 7222 
 7223 // Sub float double precision
 7224 instruct subD_regD_regD(regD dst, regD src1, regD src2) %{
 7225   effect(DEF dst, USE src1, USE src2);
 7226   size(4);
 7227   format %{ "FSUBD  $dst,$src1,$src2" %}
 7228   ins_encode %{
 7229     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 7230   %}
 7231   ins_pipe(faddD_reg_reg);
 7232 %}
 7233 
 7234 // Mul float double precision
 7235 instruct mulD_regD_regD(regD dst, regD src1, regD src2) %{
 7236   effect(DEF dst, USE src1, USE src2);
 7237   size(4);
 7238   format %{ "FMULD  $dst,$src1,$src2" %}
 7239   ins_encode %{
 7240     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 7241   %}
 7242   ins_pipe(fmulD_reg_reg);
 7243 %}
 7244 
 7245 instruct regL_to_regD(regD dst, iRegL src) %{
 7246   // No match rule to avoid chain rule match.
 7247   effect(DEF dst, USE src);
 7248   ins_cost(MEMORY_REF_COST);
 7249   size(4);
 7250   format %{ "FMDRR   $dst,$src\t! regL to regD" %}
 7251   ins_encode %{
 7252     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
 7253   %}
 7254   ins_pipe(ialu_reg_reg); // FIXME
 7255 %}
 7256 
 7257 instruct regI_regI_to_regD(regD dst, iRegI src1, iRegI src2) %{
 7258   // No match rule to avoid chain rule match.
 7259   effect(DEF dst, USE src1, USE src2);
 7260   ins_cost(MEMORY_REF_COST);
 7261   size(4);
 7262   format %{ "FMDRR   $dst,$src1,$src2\t! regI,regI to regD" %}
 7263   ins_encode %{
 7264     __ fmdrr($dst$$FloatRegister, $src1$$Register, $src2$$Register);
 7265   %}
 7266   ins_pipe(ialu_reg_reg); // FIXME
 7267 %}
 7268 
 7269 instruct convL2D_reg_slow_fxtof(regD dst, iRegL src) %{
 7270   match(Set dst (ConvL2D src));
 7271   ins_cost(DEFAULT_COST*8 + MEMORY_REF_COST*6); // FIXME
 7272 
 7273   expand %{
 7274     regD_low   tmpsrc;
 7275     iRegI      ix43300000;
 7276     iRegI      ix41f00000;
 7277     iRegI      ix0;
 7278     regD_low   dx43300000;
 7279     regD       dx41f00000;
 7280     regD       tmp1;
 7281     regD_low   tmp2;
 7282     regD       tmp3;
 7283     regD       tmp4;
 7284 
 7285     regL_to_regD(tmpsrc, src);
 7286 
 7287     loadConI_x43300000(ix43300000);
 7288     loadConI_x41f00000(ix41f00000);
 7289     loadConI_x0(ix0);
 7290 
 7291     regI_regI_to_regD(dx43300000, ix0, ix43300000);
 7292     regI_regI_to_regD(dx41f00000, ix0, ix41f00000);
 7293 
 7294     convI2D_regDHi_regD(tmp1, tmpsrc);
 7295     regDHi_regDLo_to_regD(tmp2, dx43300000, tmpsrc);
 7296     subD_regD_regD(tmp3, tmp2, dx43300000);
 7297     mulD_regD_regD(tmp4, tmp1, dx41f00000);
 7298     addD_regD_regD(dst, tmp3, tmp4);
 7299   %}
 7300 %}
 7301 
 7302 instruct convL2I_reg(iRegI dst, iRegL src) %{
 7303   match(Set dst (ConvL2I src));
 7304   size(4);
 7305   format %{ "MOV    $dst,$src.lo\t! long->int" %}
 7306   ins_encode %{
 7307     __ mov($dst$$Register, $src$$Register);
 7308   %}
 7309   ins_pipe(ialu_move_reg_I_to_L);
 7310 %}
 7311 
 7312 // Register Shift Right Immediate
 7313 instruct shrL_reg_imm6_L2I(iRegI dst, iRegL src, immI_32_63 cnt) %{
 7314   match(Set dst (ConvL2I (RShiftL src cnt)));
 7315   size(4);
 7316   format %{ "ASR    $dst,$src.hi,($cnt - 32)\t! long->int or mov if $cnt==32" %}
 7317   ins_encode %{
 7318     if ($cnt$$constant == 32) {
 7319       __ mov($dst$$Register, $src$$Register->successor());
 7320     } else {
 7321       __ mov($dst$$Register, AsmOperand($src$$Register->successor(), asr, $cnt$$constant - 32));
 7322     }
 7323   %}
 7324   ins_pipe(ialu_reg_imm);
 7325 %}
 7326 
 7327 
 7328 //----------Control Flow Instructions------------------------------------------
 7329 // Compare Instructions
 7330 // Compare Integers
 7331 instruct compI_iReg(flagsReg icc, iRegI op1, iRegI op2) %{
 7332   match(Set icc (CmpI op1 op2));
 7333   effect( DEF icc, USE op1, USE op2 );
 7334 
 7335   size(4);
 7336   format %{ "cmp_32 $op1,$op2\t! int" %}
 7337   ins_encode %{
 7338     __ cmp_32($op1$$Register, $op2$$Register);
 7339   %}
 7340   ins_pipe(ialu_cconly_reg_reg);
 7341 %}
 7342 
 7343 #ifdef _LP64
 7344 // Compare compressed pointers
 7345 instruct compN_reg2(flagsRegU icc, iRegN op1, iRegN op2) %{
 7346   match(Set icc (CmpN op1 op2));
 7347   effect( DEF icc, USE op1, USE op2 );
 7348 
 7349   size(4);
 7350   format %{ "cmp_32 $op1,$op2\t! int" %}
 7351   ins_encode %{
 7352     __ cmp_32($op1$$Register, $op2$$Register);
 7353   %}
 7354   ins_pipe(ialu_cconly_reg_reg);
 7355 %}
 7356 #endif
 7357 
 7358 instruct compU_iReg(flagsRegU icc, iRegI op1, iRegI op2) %{
 7359   match(Set icc (CmpU op1 op2));
 7360 
 7361   size(4);
 7362   format %{ "cmp_32 $op1,$op2\t! unsigned int" %}
 7363   ins_encode %{
 7364     __ cmp_32($op1$$Register, $op2$$Register);
 7365   %}
 7366   ins_pipe(ialu_cconly_reg_reg);
 7367 %}
 7368 
 7369 instruct compI_iReg_immneg(flagsReg icc, iRegI op1, aimmIneg op2) %{
 7370   match(Set icc (CmpI op1 op2));
 7371   effect( DEF icc, USE op1 );
 7372 
 7373   size(4);
 7374   format %{ "cmn_32 $op1,-$op2\t! int" %}
 7375   ins_encode %{
 7376     __ cmn_32($op1$$Register, -$op2$$constant);
 7377   %}
 7378   ins_pipe(ialu_cconly_reg_imm);
 7379 %}
 7380 
 7381 instruct compI_iReg_imm(flagsReg icc, iRegI op1, aimmI op2) %{
 7382   match(Set icc (CmpI op1 op2));
 7383   effect( DEF icc, USE op1 );
 7384 
 7385   size(4);
 7386   format %{ "cmp_32 $op1,$op2\t! int" %}
 7387   ins_encode %{
 7388     __ cmp_32($op1$$Register, $op2$$constant);
 7389   %}
 7390   ins_pipe(ialu_cconly_reg_imm);
 7391 %}
 7392 
 7393 instruct testI_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immI0 zero ) %{
 7394   match(Set icc (CmpI (AndI op1 op2) zero));
 7395   size(4);
 7396   format %{ "tst_32 $op2,$op1" %}
 7397 
 7398   ins_encode %{
 7399     __ tst_32($op1$$Register, $op2$$Register);
 7400   %}
 7401   ins_pipe(ialu_cconly_reg_reg_zero);
 7402 %}
 7403 
 7404 instruct testshlI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
 7405   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
 7406   size(4);
 7407   format %{ "TST   $op2,$op1<<$op3" %}
 7408 
 7409   ins_encode %{
 7410     __ tst($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$Register));
 7411   %}
 7412   ins_pipe(ialu_cconly_reg_reg_zero);
 7413 %}
 7414 
 7415 instruct testshlI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
 7416   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
 7417   size(4);
 7418   format %{ "tst_32 $op2,$op1<<$op3" %}
 7419 
 7420   ins_encode %{
 7421     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$constant));
 7422   %}
 7423   ins_pipe(ialu_cconly_reg_reg_zero);
 7424 %}
 7425 
 7426 instruct testsarI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
 7427   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
 7428   size(4);
 7429   format %{ "TST   $op2,$op1<<$op3" %}
 7430 
 7431   ins_encode %{
 7432     __ tst($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$Register));
 7433   %}
 7434   ins_pipe(ialu_cconly_reg_reg_zero);
 7435 %}
 7436 
 7437 instruct testsarI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
 7438   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
 7439   size(4);
 7440   format %{ "tst_32 $op2,$op1<<$op3" %}
 7441 
 7442   ins_encode %{
 7443     __ tst_32($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$constant));
 7444   %}
 7445   ins_pipe(ialu_cconly_reg_reg_zero);
 7446 %}
 7447 
 7448 instruct testshrI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
 7449   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
 7450   size(4);
 7451   format %{ "TST   $op2,$op1<<$op3" %}
 7452 
 7453   ins_encode %{
 7454     __ tst($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$Register));
 7455   %}
 7456   ins_pipe(ialu_cconly_reg_reg_zero);
 7457 %}
 7458 
 7459 instruct testshrI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
 7460   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
 7461   size(4);
 7462   format %{ "tst_32 $op2,$op1<<$op3" %}
 7463 
 7464   ins_encode %{
 7465     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$constant));
 7466   %}
 7467   ins_pipe(ialu_cconly_reg_reg_zero);
 7468 %}
 7469 
 7470 instruct testI_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, limmI op2, immI0 zero ) %{
 7471   match(Set icc (CmpI (AndI op1 op2) zero));
 7472   size(4);
 7473   format %{ "tst_32 $op2,$op1" %}
 7474 
 7475   ins_encode %{
 7476     __ tst_32($op1$$Register, $op2$$constant);
 7477   %}
 7478   ins_pipe(ialu_cconly_reg_imm_zero);
 7479 %}
 7480 
 7481 instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7482   match(Set xcc (CmpL op1 op2));
 7483   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
 7484 
 7485   size(8);
 7486   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! long\n\t"
 7487             "SBCS    $tmp,$op1.hi,$op2.hi" %}
 7488   ins_encode %{
 7489     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
 7490     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
 7491   %}
 7492   ins_pipe(ialu_cconly_reg_reg);
 7493 %}
 7494 
 7495 instruct compUL_reg_reg_LTGE(flagsRegUL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7496   match(Set xcc (CmpUL op1 op2));
 7497   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
 7498 
 7499   size(8);
 7500   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! unsigned long\n\t"
 7501             "SBCS    $tmp,$op1.hi,$op2.hi" %}
 7502   ins_encode %{
 7503     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
 7504     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
 7505   %}
 7506   ins_pipe(ialu_cconly_reg_reg);
 7507 %}
 7508 
 7509 instruct compL_reg_reg_EQNE(flagsRegL_EQNE xcc, iRegL op1, iRegL op2) %{
 7510   match(Set xcc (CmpL op1 op2));
 7511   effect( DEF xcc, USE op1, USE op2 );
 7512 
 7513   size(8);
 7514   format %{ "TEQ    $op1.hi,$op2.hi\t\t! long\n\t"
 7515             "TEQ.eq $op1.lo,$op2.lo" %}
 7516   ins_encode %{
 7517     __ teq($op1$$Register->successor(), $op2$$Register->successor());
 7518     __ teq($op1$$Register, $op2$$Register, eq);
 7519   %}
 7520   ins_pipe(ialu_cconly_reg_reg);
 7521 %}
 7522 
 7523 instruct compL_reg_reg_LEGT(flagsRegL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7524   match(Set xcc (CmpL op1 op2));
 7525   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
 7526 
 7527   size(8);
 7528   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! long\n\t"
 7529             "SBCS    $tmp,$op2.hi,$op1.hi" %}
 7530   ins_encode %{
 7531     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
 7532     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
 7533   %}
 7534   ins_pipe(ialu_cconly_reg_reg);
 7535 %}
 7536 
 7537 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7538 // (hi($con$$constant), lo($con$$constant)) becomes
 7539 instruct compL_reg_con_LTGE(flagsRegL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7540   match(Set xcc (CmpL op1 con));
 7541   effect( DEF xcc, USE op1, USE con, TEMP tmp );
 7542 
 7543   size(8);
 7544   format %{ "SUBS    $tmp,$op1.low,$con\t\t! long\n\t"
 7545             "SBCS    $tmp,$op1.hi,0" %}
 7546   ins_encode %{
 7547     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
 7548     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7549   %}
 7550 
 7551   ins_pipe(ialu_cconly_reg_reg);
 7552 %}
 7553 
 7554 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7555 // (hi($con$$constant), lo($con$$constant)) becomes
 7556 instruct compL_reg_con_EQNE(flagsRegL_EQNE xcc, iRegL op1, immLlowRot con) %{
 7557   match(Set xcc (CmpL op1 con));
 7558   effect( DEF xcc, USE op1, USE con );
 7559 
 7560   size(8);
 7561   format %{ "TEQ    $op1.hi,0\t\t! long\n\t"
 7562             "TEQ.eq $op1.lo,$con" %}
 7563   ins_encode %{
 7564     __ teq($op1$$Register->successor(), 0);
 7565     __ teq($op1$$Register, $con$$constant, eq);
 7566   %}
 7567 
 7568   ins_pipe(ialu_cconly_reg_reg);
 7569 %}
 7570 
 7571 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7572 // (hi($con$$constant), lo($con$$constant)) becomes
 7573 instruct compL_reg_con_LEGT(flagsRegL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7574   match(Set xcc (CmpL op1 con));
 7575   effect( DEF xcc, USE op1, USE con, TEMP tmp );
 7576 
 7577   size(8);
 7578   format %{ "RSBS    $tmp,$op1.low,$con\t\t! long\n\t"
 7579             "RSCS    $tmp,$op1.hi,0" %}
 7580   ins_encode %{
 7581     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
 7582     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7583   %}
 7584 
 7585   ins_pipe(ialu_cconly_reg_reg);
 7586 %}
 7587 
 7588 instruct compUL_reg_reg_EQNE(flagsRegUL_EQNE xcc, iRegL op1, iRegL op2) %{
 7589   match(Set xcc (CmpUL op1 op2));
 7590   effect(DEF xcc, USE op1, USE op2);
 7591 
 7592   size(8);
 7593   format %{ "TEQ    $op1.hi,$op2.hi\t\t! unsigned long\n\t"
 7594             "TEQ.eq $op1.lo,$op2.lo" %}
 7595   ins_encode %{
 7596     __ teq($op1$$Register->successor(), $op2$$Register->successor());
 7597     __ teq($op1$$Register, $op2$$Register, eq);
 7598   %}
 7599   ins_pipe(ialu_cconly_reg_reg);
 7600 %}
 7601 
 7602 instruct compUL_reg_reg_LEGT(flagsRegUL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7603   match(Set xcc (CmpUL op1 op2));
 7604   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
 7605 
 7606   size(8);
 7607   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! unsigned long\n\t"
 7608             "SBCS    $tmp,$op2.hi,$op1.hi" %}
 7609   ins_encode %{
 7610     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
 7611     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
 7612   %}
 7613   ins_pipe(ialu_cconly_reg_reg);
 7614 %}
 7615 
 7616 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7617 // (hi($con$$constant), lo($con$$constant)) becomes
 7618 instruct compUL_reg_con_LTGE(flagsRegUL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7619   match(Set xcc (CmpUL op1 con));
 7620   effect(DEF xcc, USE op1, USE con, TEMP tmp);
 7621 
 7622   size(8);
 7623   format %{ "SUBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
 7624             "SBCS    $tmp,$op1.hi,0" %}
 7625   ins_encode %{
 7626     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
 7627     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7628   %}
 7629 
 7630   ins_pipe(ialu_cconly_reg_reg);
 7631 %}
 7632 
 7633 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7634 // (hi($con$$constant), lo($con$$constant)) becomes
 7635 instruct compUL_reg_con_EQNE(flagsRegUL_EQNE xcc, iRegL op1, immLlowRot con) %{
 7636   match(Set xcc (CmpUL op1 con));
 7637   effect(DEF xcc, USE op1, USE con);
 7638 
 7639   size(8);
 7640   format %{ "TEQ    $op1.hi,0\t\t! unsigned long\n\t"
 7641             "TEQ.eq $op1.lo,$con" %}
 7642   ins_encode %{
 7643     __ teq($op1$$Register->successor(), 0);
 7644     __ teq($op1$$Register, $con$$constant, eq);
 7645   %}
 7646 
 7647   ins_pipe(ialu_cconly_reg_reg);
 7648 %}
 7649 
 7650 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7651 // (hi($con$$constant), lo($con$$constant)) becomes
 7652 instruct compUL_reg_con_LEGT(flagsRegUL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7653   match(Set xcc (CmpUL op1 con));
 7654   effect(DEF xcc, USE op1, USE con, TEMP tmp);
 7655 
 7656   size(8);
 7657   format %{ "RSBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
 7658             "RSCS    $tmp,$op1.hi,0" %}
 7659   ins_encode %{
 7660     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
 7661     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7662   %}
 7663 
 7664   ins_pipe(ialu_cconly_reg_reg);
 7665 %}
 7666 
 7667 /* instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ */
 7668 /*   match(Set xcc (CmpL (AndL op1 op2) zero)); */
 7669 /*   ins_encode %{ */
 7670 /*     __ stop("testL_reg_reg unimplemented"); */
 7671 /*   %} */
 7672 /*   ins_pipe(ialu_cconly_reg_reg); */
 7673 /* %} */
 7674 
 7675 /* // useful for checking the alignment of a pointer: */
 7676 /* instruct testL_reg_con(flagsRegL xcc, iRegL op1, immLlowRot con, immL0 zero) %{ */
 7677 /*   match(Set xcc (CmpL (AndL op1 con) zero)); */
 7678 /*   ins_encode %{ */
 7679 /*     __ stop("testL_reg_con unimplemented"); */
 7680 /*   %} */
 7681 /*   ins_pipe(ialu_cconly_reg_reg); */
 7682 /* %} */
 7683 
 7684 instruct compU_iReg_imm(flagsRegU icc, iRegI op1, aimmU31 op2 ) %{
 7685   match(Set icc (CmpU op1 op2));
 7686 
 7687   size(4);
 7688   format %{ "cmp_32 $op1,$op2\t! unsigned" %}
 7689   ins_encode %{
 7690     __ cmp_32($op1$$Register, $op2$$constant);
 7691   %}
 7692   ins_pipe(ialu_cconly_reg_imm);
 7693 %}
 7694 
 7695 // Compare Pointers
 7696 instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{
 7697   match(Set pcc (CmpP op1 op2));
 7698 
 7699   size(4);
 7700   format %{ "CMP    $op1,$op2\t! ptr" %}
 7701   ins_encode %{
 7702     __ cmp($op1$$Register, $op2$$Register);
 7703   %}
 7704   ins_pipe(ialu_cconly_reg_reg);
 7705 %}
 7706 
 7707 instruct compP_iRegP_imm(flagsRegP pcc, iRegP op1, aimmP op2 ) %{
 7708   match(Set pcc (CmpP op1 op2));
 7709 
 7710   size(4);
 7711   format %{ "CMP    $op1,$op2\t! ptr" %}
 7712   ins_encode %{
 7713     assert($op2$$constant == 0 || _opnds[2]->constant_reloc() == relocInfo::none, "reloc in cmp?");
 7714     __ cmp($op1$$Register, $op2$$constant);
 7715   %}
 7716   ins_pipe(ialu_cconly_reg_imm);
 7717 %}
 7718 
 7719 //----------Max and Min--------------------------------------------------------
 7720 // Min Instructions
 7721 // Conditional move for min
 7722 instruct cmovI_reg_lt( iRegI op2, iRegI op1, flagsReg icc ) %{
 7723   effect( USE_DEF op2, USE op1, USE icc );
 7724 
 7725   size(4);
 7726   format %{ "MOV.lt  $op2,$op1\t! min" %}
 7727   ins_encode %{
 7728     __ mov($op2$$Register, $op1$$Register, lt);
 7729   %}
 7730   ins_pipe(ialu_reg_flags);
 7731 %}
 7732 
 7733 // Min Register with Register.
 7734 instruct minI_eReg(iRegI op1, iRegI op2) %{
 7735   match(Set op2 (MinI op1 op2));
 7736   ins_cost(DEFAULT_COST*2);
 7737   expand %{
 7738     flagsReg icc;
 7739     compI_iReg(icc,op1,op2);
 7740     cmovI_reg_lt(op2,op1,icc);
 7741   %}
 7742 %}
 7743 
 7744 // Max Instructions
 7745 // Conditional move for max
 7746 instruct cmovI_reg_gt( iRegI op2, iRegI op1, flagsReg icc ) %{
 7747   effect( USE_DEF op2, USE op1, USE icc );
 7748   format %{ "MOV.gt  $op2,$op1\t! max" %}
 7749   ins_encode %{
 7750     __ mov($op2$$Register, $op1$$Register, gt);
 7751   %}
 7752   ins_pipe(ialu_reg_flags);
 7753 %}
 7754 
 7755 // Max Register with Register
 7756 instruct maxI_eReg(iRegI op1, iRegI op2) %{
 7757   match(Set op2 (MaxI op1 op2));
 7758   ins_cost(DEFAULT_COST*2);
 7759   expand %{
 7760     flagsReg icc;
 7761     compI_iReg(icc,op1,op2);
 7762     cmovI_reg_gt(op2,op1,icc);
 7763   %}
 7764 %}
 7765 
 7766 
 7767 //----------Float Compares----------------------------------------------------
 7768 // Compare floating, generate condition code
 7769 instruct cmpF_cc(flagsRegF fcc, flagsReg icc, regF src1, regF src2) %{
 7770   match(Set icc (CmpF src1 src2));
 7771   effect(KILL fcc);
 7772 
 7773   size(8);
 7774   format %{ "FCMPs  $src1,$src2\n\t"
 7775             "FMSTAT" %}
 7776   ins_encode %{
 7777     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
 7778     __ fmstat();
 7779   %}
 7780   ins_pipe(faddF_fcc_reg_reg_zero);
 7781 %}
 7782 
 7783 instruct cmpF0_cc(flagsRegF fcc, flagsReg icc, regF src1, immF0 src2) %{
 7784   match(Set icc (CmpF src1 src2));
 7785   effect(KILL fcc);
 7786 
 7787   size(8);
 7788   format %{ "FCMPs  $src1,$src2\n\t"
 7789             "FMSTAT" %}
 7790   ins_encode %{
 7791     __ fcmpzs($src1$$FloatRegister);
 7792     __ fmstat();
 7793   %}
 7794   ins_pipe(faddF_fcc_reg_reg_zero);
 7795 %}
 7796 
 7797 instruct cmpD_cc(flagsRegF fcc, flagsReg icc, regD src1, regD src2) %{
 7798   match(Set icc (CmpD src1 src2));
 7799   effect(KILL fcc);
 7800 
 7801   size(8);
 7802   format %{ "FCMPd  $src1,$src2 \n\t"
 7803             "FMSTAT" %}
 7804   ins_encode %{
 7805     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
 7806     __ fmstat();
 7807   %}
 7808   ins_pipe(faddD_fcc_reg_reg_zero);
 7809 %}
 7810 
 7811 instruct cmpD0_cc(flagsRegF fcc, flagsReg icc, regD src1, immD0 src2) %{
 7812   match(Set icc (CmpD src1 src2));
 7813   effect(KILL fcc);
 7814 
 7815   size(8);
 7816   format %{ "FCMPZd  $src1,$src2 \n\t"
 7817             "FMSTAT" %}
 7818   ins_encode %{
 7819     __ fcmpzd($src1$$FloatRegister);
 7820     __ fmstat();
 7821   %}
 7822   ins_pipe(faddD_fcc_reg_reg_zero);
 7823 %}
 7824 
 7825 // Compare floating, generate -1,0,1
 7826 instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsRegF fcc) %{
 7827   match(Set dst (CmpF3 src1 src2));
 7828   effect(KILL fcc);
 7829   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 7830   size(20);
 7831   // same number of instructions as code using conditional moves but
 7832   // doesn't kill integer condition register
 7833   format %{ "FCMPs  $dst,$src1,$src2 \n\t"
 7834             "VMRS   $dst, FPSCR \n\t"
 7835             "OR     $dst, $dst, 0x08000000 \n\t"
 7836             "EOR    $dst, $dst, $dst << 3 \n\t"
 7837             "MOV    $dst, $dst >> 30" %}
 7838   ins_encode %{
 7839     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
 7840     __ floating_cmp($dst$$Register);
 7841   %}
 7842   ins_pipe( floating_cmp );
 7843 %}
 7844 
 7845 instruct cmpF0_reg(iRegI dst, regF src1, immF0 src2, flagsRegF fcc) %{
 7846   match(Set dst (CmpF3 src1 src2));
 7847   effect(KILL fcc);
 7848   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 7849   size(20);
 7850   // same number of instructions as code using conditional moves but
 7851   // doesn't kill integer condition register
 7852   format %{ "FCMPZs $dst,$src1,$src2 \n\t"
 7853             "VMRS   $dst, FPSCR \n\t"
 7854             "OR     $dst, $dst, 0x08000000 \n\t"
 7855             "EOR    $dst, $dst, $dst << 3 \n\t"
 7856             "MOV    $dst, $dst >> 30" %}
 7857   ins_encode %{
 7858     __ fcmpzs($src1$$FloatRegister);
 7859     __ floating_cmp($dst$$Register);
 7860   %}
 7861   ins_pipe( floating_cmp );
 7862 %}
 7863 
 7864 instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsRegF fcc) %{
 7865   match(Set dst (CmpD3 src1 src2));
 7866   effect(KILL fcc);
 7867   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 7868   size(20);
 7869   // same number of instructions as code using conditional moves but
 7870   // doesn't kill integer condition register
 7871   format %{ "FCMPd  $dst,$src1,$src2 \n\t"
 7872             "VMRS   $dst, FPSCR \n\t"
 7873             "OR     $dst, $dst, 0x08000000 \n\t"
 7874             "EOR    $dst, $dst, $dst << 3 \n\t"
 7875             "MOV    $dst, $dst >> 30" %}
 7876   ins_encode %{
 7877     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
 7878     __ floating_cmp($dst$$Register);
 7879   %}
 7880   ins_pipe( floating_cmp );
 7881 %}
 7882 
 7883 instruct cmpD0_reg(iRegI dst, regD src1, immD0 src2, flagsRegF fcc) %{
 7884   match(Set dst (CmpD3 src1 src2));
 7885   effect(KILL fcc);
 7886   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 7887   size(20);
 7888   // same number of instructions as code using conditional moves but
 7889   // doesn't kill integer condition register
 7890   format %{ "FCMPZd $dst,$src1,$src2 \n\t"
 7891             "VMRS   $dst, FPSCR \n\t"
 7892             "OR     $dst, $dst, 0x08000000 \n\t"
 7893             "EOR    $dst, $dst, $dst << 3 \n\t"
 7894             "MOV    $dst, $dst >> 30" %}
 7895   ins_encode %{
 7896     __ fcmpzd($src1$$FloatRegister);
 7897     __ floating_cmp($dst$$Register);
 7898   %}
 7899   ins_pipe( floating_cmp );
 7900 %}
 7901 
 7902 //----------Branches---------------------------------------------------------
 7903 // Jump
 7904 // (compare 'operand indIndex' and 'instruct addP_reg_reg' above)
 7905 // FIXME
 7906 instruct jumpXtnd(iRegX switch_val, iRegP tmp) %{
 7907   match(Jump switch_val);
 7908   effect(TEMP tmp);
 7909   ins_cost(350);
 7910   format %{  "ADD    $tmp, $constanttablebase, $switch_val\n\t"
 7911              "LDR    $tmp,[$tmp + $constantoffset]\n\t"
 7912              "BX     $tmp" %}
 7913   size(20);
 7914   ins_encode %{
 7915     Register table_reg;
 7916     Register label_reg = $tmp$$Register;
 7917     if (constant_offset() == 0) {
 7918       table_reg = $constanttablebase;
 7919       __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
 7920     } else {
 7921       table_reg = $tmp$$Register;
 7922       int offset = $constantoffset;
 7923       if (is_memoryP(offset)) {
 7924         __ add(table_reg, $constanttablebase, $switch_val$$Register);
 7925         __ ldr(label_reg, Address(table_reg, offset));
 7926       } else {
 7927         __ mov_slow(table_reg, $constantoffset);
 7928         __ add(table_reg, $constanttablebase, table_reg);
 7929         __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
 7930       }
 7931     }
 7932     __ jump(label_reg); // ldr + b better than ldr to PC for branch predictor?
 7933     //    __ ldr(PC, Address($table$$Register, $switch_val$$Register));
 7934   %}
 7935   ins_pipe(ialu_reg_reg);
 7936 %}
 7937 
 7938 // // Direct Branch.
 7939 instruct branch(label labl) %{
 7940   match(Goto);
 7941   effect(USE labl);
 7942 
 7943   size(4);
 7944   ins_cost(BRANCH_COST);
 7945   format %{ "B     $labl" %}
 7946   ins_encode %{
 7947     __ b(*($labl$$label));
 7948   %}
 7949   ins_pipe(br);
 7950 %}
 7951 
 7952 // Conditional Direct Branch
 7953 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{
 7954   match(If cmp icc);
 7955   effect(USE labl);
 7956 
 7957   size(4);
 7958   ins_cost(BRANCH_COST);
 7959   format %{ "B$cmp   $icc,$labl" %}
 7960   ins_encode %{
 7961     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 7962   %}
 7963   ins_pipe(br_cc);
 7964 %}
 7965 
 7966 #ifdef ARM
 7967 instruct branchCon_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, label labl) %{
 7968   match(If cmp icc);
 7969   effect(USE labl);
 7970   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);
 7971 
 7972   size(4);
 7973   ins_cost(BRANCH_COST);
 7974   format %{ "B$cmp   $icc,$labl" %}
 7975   ins_encode %{
 7976     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 7977   %}
 7978   ins_pipe(br_cc);
 7979 %}
 7980 #endif
 7981 
 7982 
 7983 instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{
 7984   match(If cmp icc);
 7985   effect(USE labl);
 7986 
 7987   size(4);
 7988   ins_cost(BRANCH_COST);
 7989   format %{ "B$cmp  $icc,$labl" %}
 7990   ins_encode %{
 7991     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 7992   %}
 7993   ins_pipe(br_cc);
 7994 %}
 7995 
 7996 instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{
 7997   match(If cmp pcc);
 7998   effect(USE labl);
 7999 
 8000   size(4);
 8001   ins_cost(BRANCH_COST);
 8002   format %{ "B$cmp  $pcc,$labl" %}
 8003   ins_encode %{
 8004     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8005   %}
 8006   ins_pipe(br_cc);
 8007 %}
 8008 
 8009 instruct branchConL_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, label labl) %{
 8010   match(If cmp xcc);
 8011   effect(USE labl);
 8012   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8013 
 8014   size(4);
 8015   ins_cost(BRANCH_COST);
 8016   format %{ "B$cmp  $xcc,$labl" %}
 8017   ins_encode %{
 8018     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8019   %}
 8020   ins_pipe(br_cc);
 8021 %}
 8022 
 8023 instruct branchConL_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, label labl) %{
 8024   match(If cmp xcc);
 8025   effect(USE labl);
 8026   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8027 
 8028   size(4);
 8029   ins_cost(BRANCH_COST);
 8030   format %{ "B$cmp  $xcc,$labl" %}
 8031   ins_encode %{
 8032     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8033   %}
 8034   ins_pipe(br_cc);
 8035 %}
 8036 
 8037 instruct branchConL_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, label labl) %{
 8038   match(If cmp xcc);
 8039   effect(USE labl);
 8040   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le );
 8041 
 8042   size(4);
 8043   ins_cost(BRANCH_COST);
 8044   format %{ "B$cmp  $xcc,$labl" %}
 8045   ins_encode %{
 8046     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8047   %}
 8048   ins_pipe(br_cc);
 8049 %}
 8050 
 8051 instruct branchConUL_LTGE(cmpOpUL cmp, flagsRegUL_LTGE xcc, label labl) %{
 8052   match(If cmp xcc);
 8053   effect(USE labl);
 8054   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8055 
 8056   size(4);
 8057   ins_cost(BRANCH_COST);
 8058   format %{ "B$cmp  $xcc,$labl" %}
 8059   ins_encode %{
 8060     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8061   %}
 8062   ins_pipe(br_cc);
 8063 %}
 8064 
 8065 instruct branchConUL_EQNE(cmpOpUL cmp, flagsRegUL_EQNE xcc, label labl) %{
 8066   match(If cmp xcc);
 8067   effect(USE labl);
 8068   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8069 
 8070   size(4);
 8071   ins_cost(BRANCH_COST);
 8072   format %{ "B$cmp  $xcc,$labl" %}
 8073   ins_encode %{
 8074     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8075   %}
 8076   ins_pipe(br_cc);
 8077 %}
 8078 
 8079 instruct branchConUL_LEGT(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, label labl) %{
 8080   match(If cmp xcc);
 8081   effect(USE labl);
 8082   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le);
 8083 
 8084   size(4);
 8085   ins_cost(BRANCH_COST);
 8086   format %{ "B$cmp  $xcc,$labl" %}
 8087   ins_encode %{
 8088     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8089   %}
 8090   ins_pipe(br_cc);
 8091 %}
 8092 
 8093 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
 8094   match(CountedLoopEnd cmp icc);
 8095   effect(USE labl);
 8096 
 8097   size(4);
 8098   ins_cost(BRANCH_COST);
 8099   format %{ "B$cmp   $icc,$labl\t! Loop end" %}
 8100   ins_encode %{
 8101     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8102   %}
 8103   ins_pipe(br_cc);
 8104 %}
 8105 
 8106 // instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{
 8107 //   match(CountedLoopEnd cmp icc);
 8108 //   ins_pipe(br_cc);
 8109 // %}
 8110 
 8111 // ============================================================================
 8112 // Long Compare
 8113 //
 8114 // Currently we hold longs in 2 registers.  Comparing such values efficiently
 8115 // is tricky.  The flavor of compare used depends on whether we are testing
 8116 // for LT, LE, or EQ.  For a simple LT test we can check just the sign bit.
 8117 // The GE test is the negated LT test.  The LE test can be had by commuting
 8118 // the operands (yielding a GE test) and then negating; negate again for the
 8119 // GT test.  The EQ test is done by ORcc'ing the high and low halves, and the
 8120 // NE test is negated from that.
 8121 
 8122 // Due to a shortcoming in the ADLC, it mixes up expressions like:
 8123 // (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)).  Note the
 8124 // difference between 'Y' and '0L'.  The tree-matches for the CmpI sections
 8125 // are collapsed internally in the ADLC's dfa-gen code.  The match for
 8126 // (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the
 8127 // foo match ends up with the wrong leaf.  One fix is to not match both
 8128 // reg-reg and reg-zero forms of long-compare.  This is unfortunate because
 8129 // both forms beat the trinary form of long-compare and both are very useful
 8130 // on Intel which has so few registers.
 8131 
 8132 // instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{
 8133 //   match(If cmp xcc);
 8134 //   ins_pipe(br_cc);
 8135 // %}
 8136 
 8137 // Manifest a CmpL3 result in an integer register.  Very painful.
 8138 // This is the test to avoid.
 8139 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
 8140   match(Set dst (CmpL3 src1 src2) );
 8141   effect( KILL ccr );
 8142   ins_cost(6*DEFAULT_COST); // FIXME
 8143   size(32);
 8144   format %{
 8145       "CMP    $src1.hi, $src2.hi\t\t! long\n"
 8146     "\tMOV.gt $dst, 1\n"
 8147     "\tmvn.lt $dst, 0\n"
 8148     "\tB.ne   done\n"
 8149     "\tSUBS   $dst, $src1.lo, $src2.lo\n"
 8150     "\tMOV.hi $dst, 1\n"
 8151     "\tmvn.lo $dst, 0\n"
 8152     "done:"     %}
 8153   ins_encode %{
 8154     Label done;
 8155     __ cmp($src1$$Register->successor(), $src2$$Register->successor());
 8156     __ mov($dst$$Register, 1, gt);
 8157     __ mvn($dst$$Register, 0, lt);
 8158     __ b(done, ne);
 8159     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
 8160     __ mov($dst$$Register, 1, hi);
 8161     __ mvn($dst$$Register, 0, lo);
 8162     __ bind(done);
 8163   %}
 8164   ins_pipe(cmpL_reg);
 8165 %}
 8166 
 8167 // Conditional move
 8168 instruct cmovLL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, iRegL src) %{
 8169   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8170   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8171 
 8172   ins_cost(150);
 8173   size(8);
 8174   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8175             "MOV$cmp  $dst,$src.hi" %}
 8176   ins_encode %{
 8177     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8178     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8179   %}
 8180   ins_pipe(ialu_reg);
 8181 %}
 8182 
 8183 instruct cmovLL_reg_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegL dst, iRegL src) %{
 8184   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8185   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8186 
 8187   ins_cost(150);
 8188   size(8);
 8189   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8190             "MOV$cmp  $dst,$src.hi" %}
 8191   ins_encode %{
 8192     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8193     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8194   %}
 8195   ins_pipe(ialu_reg);
 8196 %}
 8197 
 8198 instruct cmovLL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, iRegL src) %{
 8199   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8200   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8201 
 8202   ins_cost(150);
 8203   size(8);
 8204   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8205             "MOV$cmp  $dst,$src.hi" %}
 8206   ins_encode %{
 8207     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8208     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8209   %}
 8210   ins_pipe(ialu_reg);
 8211 %}
 8212 
 8213 instruct cmovLL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, iRegL src) %{
 8214   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8215   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8216 
 8217   ins_cost(150);
 8218   size(8);
 8219   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8220             "MOV$cmp  $dst,$src.hi" %}
 8221   ins_encode %{
 8222     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8223     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8224   %}
 8225   ins_pipe(ialu_reg);
 8226 %}
 8227 
 8228 instruct cmovLL_reg_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegL dst, iRegL src) %{
 8229   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8230   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8231 
 8232   ins_cost(150);
 8233   size(8);
 8234   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8235             "MOV$cmp  $dst,$src.hi" %}
 8236   ins_encode %{
 8237     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8238     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8239   %}
 8240   ins_pipe(ialu_reg);
 8241 %}
 8242 
 8243 instruct cmovLL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, immL0 src) %{
 8244   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8245   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8246   ins_cost(140);
 8247   size(8);
 8248   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8249             "MOV$cmp  $dst,0" %}
 8250   ins_encode %{
 8251     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8252     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8253   %}
 8254   ins_pipe(ialu_imm);
 8255 %}
 8256 
 8257 instruct cmovLL_imm_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegL dst, immL0 src) %{
 8258   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8259   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8260   ins_cost(140);
 8261   size(8);
 8262   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8263             "MOV$cmp  $dst,0" %}
 8264   ins_encode %{
 8265     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8266     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8267   %}
 8268   ins_pipe(ialu_imm);
 8269 %}
 8270 
 8271 instruct cmovLL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, immL0 src) %{
 8272   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8273   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8274   ins_cost(140);
 8275   size(8);
 8276   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8277             "MOV$cmp  $dst,0" %}
 8278   ins_encode %{
 8279     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8280     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8281   %}
 8282   ins_pipe(ialu_imm);
 8283 %}
 8284 
 8285 instruct cmovLL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, immL0 src) %{
 8286   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8287   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8288   ins_cost(140);
 8289   size(8);
 8290   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8291             "MOV$cmp  $dst,0" %}
 8292   ins_encode %{
 8293     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8294     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8295   %}
 8296   ins_pipe(ialu_imm);
 8297 %}
 8298 
 8299 instruct cmovIL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, iRegI src) %{
 8300   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8301   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8302 
 8303   ins_cost(150);
 8304   size(4);
 8305   format %{ "MOV$cmp  $dst,$src" %}
 8306   ins_encode %{
 8307     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8308   %}
 8309   ins_pipe(ialu_reg);
 8310 %}
 8311 
 8312 instruct cmovIL_reg_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegI dst, iRegI src) %{
 8313   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8314   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8315 
 8316   ins_cost(150);
 8317   size(4);
 8318   format %{ "MOV$cmp  $dst,$src" %}
 8319   ins_encode %{
 8320     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8321   %}
 8322   ins_pipe(ialu_reg);
 8323 %}
 8324 
 8325 instruct cmovIL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, iRegI src) %{
 8326   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8327   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8328 
 8329   ins_cost(150);
 8330   size(4);
 8331   format %{ "MOV$cmp  $dst,$src" %}
 8332   ins_encode %{
 8333     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8334   %}
 8335   ins_pipe(ialu_reg);
 8336 %}
 8337 
 8338 instruct cmovIL_reg_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE xcc, iRegI dst, iRegI src) %{
 8339   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8340   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8341 
 8342   ins_cost(150);
 8343   size(4);
 8344   format %{ "MOV$cmp  $dst,$src" %}
 8345   ins_encode %{
 8346    __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8347   %}
 8348   ins_pipe(ialu_reg);
 8349 %}
 8350 
 8351 instruct cmovIL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, iRegI src) %{
 8352   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8353   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8354 
 8355   ins_cost(150);
 8356   size(4);
 8357   format %{ "MOV$cmp  $dst,$src" %}
 8358   ins_encode %{
 8359     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8360   %}
 8361   ins_pipe(ialu_reg);
 8362 %}
 8363 
 8364 instruct cmovIL_reg_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegI dst, iRegI src) %{
 8365   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8366   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8367 
 8368   ins_cost(150);
 8369   size(4);
 8370   format %{ "MOV$cmp  $dst,$src" %}
 8371   ins_encode %{
 8372     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8373   %}
 8374   ins_pipe(ialu_reg);
 8375 %}
 8376 
 8377 instruct cmovIL_imm16_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immI16 src) %{
 8378   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8379   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8380 
 8381   ins_cost(140);
 8382   size(4);
 8383   format %{ "MOVW$cmp  $dst,$src" %}
 8384   ins_encode %{
 8385     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8386   %}
 8387   ins_pipe(ialu_imm);
 8388 %}
 8389 
 8390 instruct cmovIL_imm16_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegI dst, immI16 src) %{
 8391   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8392   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8393 
 8394   ins_cost(140);
 8395   size(4);
 8396   format %{ "MOVW$cmp  $dst,$src" %}
 8397   ins_encode %{
 8398     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8399   %}
 8400   ins_pipe(ialu_imm);
 8401 %}
 8402 
 8403 instruct cmovIL_imm16_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, immI16 src) %{
 8404   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8405   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8406 
 8407   ins_cost(140);
 8408   size(4);
 8409   format %{ "MOVW$cmp  $dst,$src" %}
 8410   ins_encode %{
 8411     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8412   %}
 8413   ins_pipe(ialu_imm);
 8414 %}
 8415 
 8416 instruct cmovIL_imm16_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE xcc, iRegI dst, immI16 src) %{
 8417   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8418   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8419 
 8420   ins_cost(140);
 8421   size(4);
 8422   format %{ "MOVW$cmp  $dst,$src" %}
 8423   ins_encode %{
 8424     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8425   %}
 8426   ins_pipe(ialu_imm);
 8427 %}
 8428 
 8429 instruct cmovIL_imm16_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immI16 src) %{
 8430   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8431   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8432 
 8433   ins_cost(140);
 8434   size(4);
 8435   format %{ "MOVW$cmp  $dst,$src" %}
 8436   ins_encode %{
 8437     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8438   %}
 8439   ins_pipe(ialu_imm);
 8440 %}
 8441 
 8442 instruct cmovIL_imm16_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegI dst, immI16 src) %{
 8443   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8444   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8445 
 8446   ins_cost(140);
 8447   size(4);
 8448   format %{ "MOVW$cmp  $dst,$src" %}
 8449   ins_encode %{
 8450     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8451   %}
 8452   ins_pipe(ialu_imm);
 8453 %}
 8454 
 8455 instruct cmovIL_immMov_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immIMov src) %{
 8456   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8457   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8458 
 8459   ins_cost(140);
 8460   size(4);
 8461   format %{ "MOV$cmp  $dst,$src" %}
 8462   ins_encode %{
 8463     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8464   %}
 8465   ins_pipe(ialu_imm);
 8466 %}
 8467 
 8468 instruct cmovIL_immMov_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegI dst, immIMov src) %{
 8469   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8470   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8471 
 8472   ins_cost(140);
 8473   size(4);
 8474   format %{ "MOV$cmp  $dst,$src" %}
 8475   ins_encode %{
 8476     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8477   %}
 8478   ins_pipe(ialu_imm);
 8479 %}
 8480 
 8481 instruct cmovIL_immMov_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, immIMov src) %{
 8482   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8483   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8484 
 8485   ins_cost(140);
 8486   size(4);
 8487   format %{ "MOV$cmp  $dst,$src" %}
 8488   ins_encode %{
 8489     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8490   %}
 8491   ins_pipe(ialu_imm);
 8492 %}
 8493 
 8494 instruct cmovIL_immMov_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE xcc, iRegI dst, immIMov src) %{
 8495   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8496   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8497 
 8498   ins_cost(140);
 8499   size(4);
 8500   format %{ "MOV$cmp  $dst,$src" %}
 8501   ins_encode %{
 8502     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8503   %}
 8504   ins_pipe(ialu_imm);
 8505 %}
 8506 
 8507 instruct cmovIL_immMov_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immIMov src) %{
 8508   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8509   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8510 
 8511   ins_cost(140);
 8512   size(4);
 8513   format %{ "MOV$cmp  $dst,$src" %}
 8514   ins_encode %{
 8515     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8516   %}
 8517   ins_pipe(ialu_imm);
 8518 %}
 8519 
 8520 instruct cmovIL_immMov_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegI dst, immIMov src) %{
 8521   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8522   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8523 
 8524   ins_cost(140);
 8525   size(4);
 8526   format %{ "MOV$cmp  $dst,$src" %}
 8527   ins_encode %{
 8528     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8529   %}
 8530   ins_pipe(ialu_imm);
 8531 %}
 8532 
 8533 instruct cmovPL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, iRegP src) %{
 8534   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8535   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8536 
 8537   ins_cost(150);
 8538   size(4);
 8539   format %{ "MOV$cmp  $dst,$src" %}
 8540   ins_encode %{
 8541     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8542   %}
 8543   ins_pipe(ialu_reg);
 8544 %}
 8545 
 8546 instruct cmovPL_reg_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegP dst, iRegP src) %{
 8547   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8548   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8549 
 8550   ins_cost(150);
 8551   size(4);
 8552   format %{ "MOV$cmp  $dst,$src" %}
 8553   ins_encode %{
 8554     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8555   %}
 8556   ins_pipe(ialu_reg);
 8557 %}
 8558 
 8559 instruct cmovPL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, iRegP src) %{
 8560   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8561   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8562 
 8563   ins_cost(150);
 8564   size(4);
 8565   format %{ "MOV$cmp  $dst,$src" %}
 8566   ins_encode %{
 8567     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8568   %}
 8569   ins_pipe(ialu_reg);
 8570 %}
 8571 
 8572 instruct cmovPL_reg_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE xcc, iRegP dst, iRegP src) %{
 8573   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8574   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8575 
 8576   ins_cost(150);
 8577   size(4);
 8578   format %{ "MOV$cmp  $dst,$src" %}
 8579   ins_encode %{
 8580     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8581   %}
 8582   ins_pipe(ialu_reg);
 8583 %}
 8584 
 8585 instruct cmovPL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, iRegP src) %{
 8586   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8587   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8588 
 8589   ins_cost(150);
 8590   size(4);
 8591   format %{ "MOV$cmp  $dst,$src" %}
 8592   ins_encode %{
 8593     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8594   %}
 8595   ins_pipe(ialu_reg);
 8596 %}
 8597 
 8598 instruct cmovPL_reg_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegP dst, iRegP src) %{
 8599   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8600   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8601 
 8602   ins_cost(150);
 8603   size(4);
 8604   format %{ "MOV$cmp  $dst,$src" %}
 8605   ins_encode %{
 8606     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8607   %}
 8608   ins_pipe(ialu_reg);
 8609 %}
 8610 
 8611 instruct cmovPL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, immP0 src) %{
 8612   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8613   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8614 
 8615   ins_cost(140);
 8616   size(4);
 8617   format %{ "MOVW$cmp  $dst,$src" %}
 8618   ins_encode %{
 8619     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8620   %}
 8621   ins_pipe(ialu_imm);
 8622 %}
 8623 
 8624 instruct cmovPL_imm_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegP dst, immP0 src) %{
 8625   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8626   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8627 
 8628   ins_cost(140);
 8629   size(4);
 8630   format %{ "MOVW$cmp  $dst,$src" %}
 8631   ins_encode %{
 8632     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8633   %}
 8634   ins_pipe(ialu_imm);
 8635 %}
 8636 
 8637 instruct cmovPL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, immP0 src) %{
 8638   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8639   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8640 
 8641   ins_cost(140);
 8642   size(4);
 8643   format %{ "MOVW$cmp  $dst,$src" %}
 8644   ins_encode %{
 8645     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8646   %}
 8647   ins_pipe(ialu_imm);
 8648 %}
 8649 
 8650 instruct cmovPL_imm_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE xcc, iRegP dst, immP0 src) %{
 8651   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8652   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8653 
 8654   ins_cost(140);
 8655   size(4);
 8656   format %{ "MOVW$cmp  $dst,$src" %}
 8657   ins_encode %{
 8658     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8659   %}
 8660   ins_pipe(ialu_imm);
 8661 %}
 8662 
 8663 instruct cmovPL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, immP0 src) %{
 8664   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8665   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8666 
 8667   ins_cost(140);
 8668   size(4);
 8669   format %{ "MOVW$cmp  $dst,$src" %}
 8670   ins_encode %{
 8671     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8672   %}
 8673   ins_pipe(ialu_imm);
 8674 %}
 8675 
 8676 instruct cmovPL_imm_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegP dst, immP0 src) %{
 8677   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8678   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8679 
 8680   ins_cost(140);
 8681   size(4);
 8682   format %{ "MOVW$cmp  $dst,$src" %}
 8683   ins_encode %{
 8684     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8685   %}
 8686   ins_pipe(ialu_imm);
 8687 %}
 8688 
 8689 instruct cmovFL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regF dst, regF src) %{
 8690   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
 8691   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8692   ins_cost(150);
 8693   size(4);
 8694   format %{ "FCPYS$cmp $dst,$src" %}
 8695   ins_encode %{
 8696     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8697   %}
 8698   ins_pipe(int_conditional_float_move);
 8699 %}
 8700 
 8701 instruct cmovFL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regF dst, regF src) %{
 8702   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
 8703   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8704   ins_cost(150);
 8705   size(4);
 8706   format %{ "FCPYS$cmp $dst,$src" %}
 8707   ins_encode %{
 8708     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8709   %}
 8710   ins_pipe(int_conditional_float_move);
 8711 %}
 8712 
 8713 instruct cmovFL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regF dst, regF src) %{
 8714   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
 8715   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8716   ins_cost(150);
 8717   size(4);
 8718   format %{ "FCPYS$cmp $dst,$src" %}
 8719   ins_encode %{
 8720     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8721   %}
 8722   ins_pipe(int_conditional_float_move);
 8723 %}
 8724 
 8725 instruct cmovDL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regD dst, regD src) %{
 8726   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
 8727   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8728 
 8729   ins_cost(150);
 8730   size(4);
 8731   format %{ "FCPYD$cmp $dst,$src" %}
 8732   ins_encode %{
 8733     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8734   %}
 8735   ins_pipe(int_conditional_float_move);
 8736 %}
 8737 
 8738 instruct cmovDL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regD dst, regD src) %{
 8739   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
 8740   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8741 
 8742   ins_cost(150);
 8743   size(4);
 8744   format %{ "FCPYD$cmp $dst,$src" %}
 8745   ins_encode %{
 8746     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8747   %}
 8748   ins_pipe(int_conditional_float_move);
 8749 %}
 8750 
 8751 instruct cmovDL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regD dst, regD src) %{
 8752   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
 8753   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8754 
 8755   ins_cost(150);
 8756   size(4);
 8757   format %{ "FCPYD$cmp $dst,$src" %}
 8758   ins_encode %{
 8759     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8760   %}
 8761   ins_pipe(int_conditional_float_move);
 8762 %}
 8763 
 8764 // ============================================================================
 8765 // Safepoint Instruction
 8766 // rather than KILL R12, it would be better to use any reg as
 8767 // TEMP. Can't do that at this point because it crashes the compiler
 8768 instruct safePoint_poll(iRegP poll, R12RegI tmp, flagsReg icc) %{
 8769   match(SafePoint poll);
 8770   effect(USE poll, KILL tmp, KILL icc);
 8771 
 8772   size(4);
 8773   format %{ "LDR   $tmp,[$poll]\t! Safepoint: poll for GC" %}
 8774   ins_encode %{
 8775     __ relocate(relocInfo::poll_type);
 8776     __ ldr($tmp$$Register, Address($poll$$Register));
 8777   %}
 8778   ins_pipe(loadPollP);
 8779 %}
 8780 
 8781 
 8782 // ============================================================================
 8783 // Call Instructions
 8784 // Call Java Static Instruction
 8785 instruct CallStaticJavaDirect( method meth ) %{
 8786   match(CallStaticJava);
 8787   effect(USE meth);
 8788 
 8789   ins_cost(CALL_COST);
 8790   format %{ "CALL,static ==> " %}
 8791   ins_encode( SetInstMark, Java_Static_Call( meth ), call_epilog, ClearInstMark );
 8792   ins_pipe(simple_call);
 8793 %}
 8794 
 8795 // Call Java Dynamic Instruction
 8796 instruct CallDynamicJavaDirect( method meth ) %{
 8797   match(CallDynamicJava);
 8798   effect(USE meth);
 8799 
 8800   ins_cost(CALL_COST);
 8801   format %{ "MOV_OOP    (empty),R_R8\n\t"
 8802             "CALL,dynamic  ; NOP ==> " %}
 8803   ins_encode( SetInstMark, Java_Dynamic_Call( meth ), call_epilog, ClearInstMark );
 8804   ins_pipe(call);
 8805 %}
 8806 
 8807 // Call Runtime Instruction
 8808 instruct CallRuntimeDirect(method meth) %{
 8809   match(CallRuntime);
 8810   effect(USE meth);
 8811   ins_cost(CALL_COST);
 8812   format %{ "CALL,runtime" %}
 8813   ins_encode( SetInstMark, Java_To_Runtime( meth ),
 8814               call_epilog, ClearInstMark );
 8815   ins_pipe(simple_call);
 8816 %}
 8817 
 8818 // Call runtime without safepoint - same as CallRuntime
 8819 instruct CallLeafDirect(method meth) %{
 8820   match(CallLeaf);
 8821   effect(USE meth);
 8822   ins_cost(CALL_COST);
 8823   format %{ "CALL,runtime leaf" %}
 8824   // TODO: need save_last_PC here?
 8825   ins_encode( SetInstMark, Java_To_Runtime( meth ),
 8826               call_epilog, ClearInstMark );
 8827   ins_pipe(simple_call);
 8828 %}
 8829 
 8830 // Call runtime without safepoint - same as CallLeaf
 8831 instruct CallLeafNoFPDirect(method meth) %{
 8832   match(CallLeafNoFP);
 8833   effect(USE meth);
 8834   ins_cost(CALL_COST);
 8835   format %{ "CALL,runtime leaf nofp" %}
 8836   // TODO: need save_last_PC here?
 8837   ins_encode( SetInstMark, Java_To_Runtime( meth ),
 8838               call_epilog, ClearInstMark );
 8839   ins_pipe(simple_call);
 8840 %}
 8841 
 8842 // Tail Call; Jump from runtime stub to Java code.
 8843 // Also known as an 'interprocedural jump'.
 8844 // Target of jump will eventually return to caller.
 8845 // TailJump below removes the return address.
 8846 instruct TailCalljmpInd(IPRegP jump_target, inline_cache_regP method_ptr) %{
 8847   match(TailCall jump_target method_ptr);
 8848 
 8849   ins_cost(CALL_COST);
 8850   format %{ "jump   $jump_target  \t! $method_ptr holds method" %}
 8851   ins_encode %{
 8852     __ jump($jump_target$$Register);
 8853   %}
 8854   ins_pipe(tail_call);
 8855 %}
 8856 
 8857 
 8858 // Return Instruction
 8859 instruct Ret() %{
 8860   match(Return);
 8861 
 8862   format %{ "ret LR" %}
 8863 
 8864   ins_encode %{
 8865     __ ret(LR);
 8866   %}
 8867 
 8868   ins_pipe(br);
 8869 %}
 8870 
 8871 
 8872 // Tail Jump; remove the return address; jump to target.
 8873 // TailCall above leaves the return address around.
 8874 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
 8875 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
 8876 // "restore" before this instruction (in Epilogue), we need to materialize it
 8877 // in %i0.
 8878 instruct tailjmpInd(IPRegP jump_target, RExceptionRegP ex_oop) %{
 8879   match( TailJump jump_target ex_oop );
 8880   ins_cost(CALL_COST);
 8881   format %{ "MOV    Rexception_pc, LR\n\t"
 8882             "jump   $jump_target \t! $ex_oop holds exc. oop" %}
 8883   ins_encode %{
 8884     __ mov(Rexception_pc, LR);
 8885     __ jump($jump_target$$Register);
 8886   %}
 8887   ins_pipe(tail_call);
 8888 %}
 8889 
 8890 // Forward exception.
 8891 instruct ForwardExceptionjmp()
 8892 %{
 8893   match(ForwardException);
 8894   ins_cost(CALL_COST);
 8895 
 8896   format %{ "MOV  Rexception_pc, LR\n\t"
 8897             "b    forward_exception_entry" %}
 8898   ins_encode %{
 8899     __ mov(Rexception_pc, LR);
 8900     // OK to trash Rtemp, because Rtemp is used by stub
 8901     __ jump(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type, Rtemp);
 8902   %}
 8903   ins_pipe(tail_call);
 8904 %}
 8905 
 8906 // Create exception oop: created by stack-crawling runtime code.
 8907 // Created exception is now available to this handler, and is setup
 8908 // just prior to jumping to this handler.  No code emitted.
 8909 instruct CreateException( RExceptionRegP ex_oop )
 8910 %{
 8911   match(Set ex_oop (CreateEx));
 8912   ins_cost(0);
 8913 
 8914   size(0);
 8915   // use the following format syntax
 8916   format %{ "! exception oop is in Rexception_obj; no code emitted" %}
 8917   ins_encode();
 8918   ins_pipe(empty);
 8919 %}
 8920 
 8921 
 8922 // Rethrow exception:
 8923 // The exception oop will come in the first argument position.
 8924 // Then JUMP (not call) to the rethrow stub code.
 8925 instruct RethrowException()
 8926 %{
 8927   match(Rethrow);
 8928   ins_cost(CALL_COST);
 8929 
 8930   // use the following format syntax
 8931   format %{ "b    rethrow_stub" %}
 8932   ins_encode %{
 8933     Register scratch = R1_tmp;
 8934     assert_different_registers(scratch, c_rarg0, LR);
 8935     __ jump(OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type, scratch);
 8936   %}
 8937   ins_pipe(tail_call);
 8938 %}
 8939 
 8940 
 8941 // Die now
 8942 instruct ShouldNotReachHere( )
 8943 %{
 8944   match(Halt);
 8945   ins_cost(CALL_COST);
 8946 
 8947   // Use the following format syntax
 8948   format %{ "ShouldNotReachHere" %}
 8949   ins_encode %{
 8950     if (is_reachable()) {
 8951       const char* str = __ code_string(_halt_reason);
 8952       __ stop(str);
 8953     }
 8954   %}
 8955   ins_pipe(tail_call);
 8956 %}
 8957 
 8958 // ============================================================================
 8959 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
 8960 // array for an instance of the superklass.  Set a hidden internal cache on a
 8961 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
 8962 // not zero for a miss or zero for a hit.  The encoding ALSO sets flags.
 8963 instruct partialSubtypeCheck( R0RegP index, R1RegP sub, R2RegP super, flagsRegP pcc, LRRegP lr ) %{
 8964   match(Set index (PartialSubtypeCheck sub super));
 8965   effect( KILL pcc, KILL lr );
 8966   ins_cost(DEFAULT_COST*10);
 8967   format %{ "CALL   PartialSubtypeCheck" %}
 8968   ins_encode %{
 8969     __ call(StubRoutines::Arm::partial_subtype_check(), relocInfo::runtime_call_type);
 8970   %}
 8971   ins_pipe(partial_subtype_check_pipe);
 8972 %}
 8973 
 8974 /* instruct partialSubtypeCheck_vs_zero( flagsRegP pcc, o1RegP sub, o2RegP super, immP0 zero, o0RegP idx, o7RegP o7 ) %{ */
 8975 /*   match(Set pcc (CmpP (PartialSubtypeCheck sub super) zero)); */
 8976 /*   ins_pipe(partial_subtype_check_pipe); */
 8977 /* %} */
 8978 
 8979 
 8980 // ============================================================================
 8981 // inlined locking and unlocking
 8982 
 8983 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch )
 8984 %{
 8985   match(Set pcc (FastLock object box));
 8986 
 8987   effect(TEMP scratch, TEMP scratch2);
 8988   ins_cost(DEFAULT_COST*3);
 8989 
 8990   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2" %}
 8991   ins_encode %{
 8992     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
 8993   %}
 8994   ins_pipe(long_memory_op);
 8995 %}
 8996 
 8997 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch ) %{
 8998   match(Set pcc (FastUnlock object box));
 8999   effect(TEMP scratch, TEMP scratch2);
 9000   ins_cost(100);
 9001 
 9002   format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2" %}
 9003   ins_encode %{
 9004     __ fast_unlock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
 9005   %}
 9006   ins_pipe(long_memory_op);
 9007 %}
 9008 
 9009 // Count and Base registers are fixed because the allocator cannot
 9010 // kill unknown registers.  The encodings are generic.
 9011 instruct clear_array(iRegX cnt, iRegP base, iRegI temp, iRegX zero, Universe dummy, flagsReg cpsr) %{
 9012   match(Set dummy (ClearArray cnt base));
 9013   effect(TEMP temp, TEMP zero, KILL cpsr);
 9014   ins_cost(300);
 9015   format %{ "MOV    $zero,0\n"
 9016       "        MOV    $temp,$cnt\n"
 9017       "loop:   SUBS   $temp,$temp,4\t! Count down a dword of bytes\n"
 9018       "        STR.ge $zero,[$base+$temp]\n"
 9019       "        B.gt   loop\t\t! Clearing loop\n" %}
 9020   ins_encode %{
 9021     __ mov($zero$$Register, 0);
 9022     __ mov($temp$$Register, $cnt$$Register);
 9023     Label loop;
 9024     __ bind(loop);
 9025     __ subs($temp$$Register, $temp$$Register, 4);
 9026     __ str($zero$$Register, Address($base$$Register, $temp$$Register), ge);
 9027     __ b(loop, gt);
 9028   %}
 9029   ins_pipe(long_memory_op);
 9030 %}
 9031 
 9032 #ifdef XXX
 9033 // FIXME: Why R0/R1/R2/R3?
 9034 instruct string_compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result,
 9035                         iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 9036   predicate(!CompactStrings);
 9037   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
 9038   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, TEMP tmp1, TEMP tmp2);
 9039   ins_cost(300);
 9040   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // TEMP $tmp1, $tmp2" %}
 9041   ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result, tmp1, tmp2) );
 9042 
 9043   ins_pipe(long_memory_op);
 9044 %}
 9045 
 9046 // FIXME: Why R0/R1/R2?
 9047 instruct string_equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2,
 9048                        flagsReg ccr) %{
 9049   predicate(!CompactStrings);
 9050   match(Set result (StrEquals (Binary str1 str2) cnt));
 9051   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp1, TEMP tmp2, TEMP result, KILL ccr);
 9052 
 9053   ins_cost(300);
 9054   format %{ "String Equals $str1,$str2,$cnt -> $result   // TEMP $tmp1, $tmp2" %}
 9055   ins_encode( enc_String_Equals(str1, str2, cnt, result, tmp1, tmp2) );
 9056   ins_pipe(long_memory_op);
 9057 %}
 9058 
 9059 // FIXME: Why R0/R1?
 9060 instruct array_equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result,
 9061                       flagsReg ccr) %{
 9062   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
 9063   match(Set result (AryEq ary1 ary2));
 9064   effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP result, KILL ccr);
 9065 
 9066   ins_cost(300);
 9067   format %{ "Array Equals $ary1,$ary2 -> $result   // TEMP $tmp1,$tmp2,$tmp3" %}
 9068   ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, result));
 9069   ins_pipe(long_memory_op);
 9070 %}
 9071 #endif
 9072 
 9073 //---------- Zeros Count Instructions ------------------------------------------
 9074 
 9075 instruct countLeadingZerosI(iRegI dst, iRegI src) %{
 9076   match(Set dst (CountLeadingZerosI src));
 9077   size(4);
 9078   format %{ "CLZ_32 $dst,$src" %}
 9079   ins_encode %{
 9080     __ clz_32($dst$$Register, $src$$Register);
 9081   %}
 9082   ins_pipe(ialu_reg);
 9083 %}
 9084 
 9085 instruct countLeadingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
 9086   match(Set dst (CountLeadingZerosL src));
 9087   effect(TEMP tmp, TEMP dst, KILL ccr);
 9088   size(16);
 9089   format %{ "CLZ    $dst,$src.hi\n\t"
 9090             "TEQ    $dst,32\n\t"
 9091             "CLZ.eq $tmp,$src.lo\n\t"
 9092             "ADD.eq $dst, $dst, $tmp\n\t" %}
 9093   ins_encode %{
 9094     __ clz($dst$$Register, $src$$Register->successor());
 9095     __ teq($dst$$Register, 32);
 9096     __ clz($tmp$$Register, $src$$Register, eq);
 9097     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
 9098   %}
 9099   ins_pipe(ialu_reg);
 9100 %}
 9101 
 9102 instruct countTrailingZerosI(iRegI dst, iRegI src, iRegI tmp) %{
 9103   match(Set dst (CountTrailingZerosI src));
 9104   effect(TEMP tmp);
 9105   size(8);
 9106   format %{ "RBIT_32 $tmp, $src\n\t"
 9107             "CLZ_32  $dst,$tmp" %}
 9108   ins_encode %{
 9109     __ rbit_32($tmp$$Register, $src$$Register);
 9110     __ clz_32($dst$$Register, $tmp$$Register);
 9111   %}
 9112   ins_pipe(ialu_reg);
 9113 %}
 9114 
 9115 instruct countTrailingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
 9116   match(Set dst (CountTrailingZerosL src));
 9117   effect(TEMP tmp, TEMP dst, KILL ccr);
 9118   size(24);
 9119   format %{ "RBIT   $tmp,$src.lo\n\t"
 9120             "CLZ    $dst,$tmp\n\t"
 9121             "TEQ    $dst,32\n\t"
 9122             "RBIT   $tmp,$src.hi\n\t"
 9123             "CLZ.eq $tmp,$tmp\n\t"
 9124             "ADD.eq $dst,$dst,$tmp\n\t" %}
 9125   ins_encode %{
 9126     __ rbit($tmp$$Register, $src$$Register);
 9127     __ clz($dst$$Register, $tmp$$Register);
 9128     __ teq($dst$$Register, 32);
 9129     __ rbit($tmp$$Register, $src$$Register->successor());
 9130     __ clz($tmp$$Register, $tmp$$Register, eq);
 9131     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
 9132   %}
 9133   ins_pipe(ialu_reg);
 9134 %}
 9135 
 9136 
 9137 //---------- Population Count Instructions -------------------------------------
 9138 
 9139 instruct popCountI(iRegI dst, iRegI src, regD_low tmp) %{
 9140   predicate(UsePopCountInstruction);
 9141   match(Set dst (PopCountI src));
 9142   effect(TEMP tmp);
 9143 
 9144   format %{ "FMSR       $tmp,$src\n\t"
 9145             "VCNT.8     $tmp,$tmp\n\t"
 9146             "VPADDL.U8  $tmp,$tmp\n\t"
 9147             "VPADDL.U16 $tmp,$tmp\n\t"
 9148             "FMRS       $dst,$tmp" %}
 9149   size(20);
 9150 
 9151   ins_encode %{
 9152     __ fmsr($tmp$$FloatRegister, $src$$Register);
 9153     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
 9154     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
 9155     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
 9156     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 9157   %}
 9158   ins_pipe(ialu_reg); // FIXME
 9159 %}
 9160 
 9161 // Note: Long.bitCount(long) returns an int.
 9162 instruct popCountL(iRegI dst, iRegL src, regD_low tmp) %{
 9163   predicate(UsePopCountInstruction);
 9164   match(Set dst (PopCountL src));
 9165   effect(TEMP tmp);
 9166 
 9167   format %{ "FMDRR       $tmp,$src.lo,$src.hi\n\t"
 9168             "VCNT.8      $tmp,$tmp\n\t"
 9169             "VPADDL.U8   $tmp,$tmp\n\t"
 9170             "VPADDL.U16  $tmp,$tmp\n\t"
 9171             "VPADDL.U32  $tmp,$tmp\n\t"
 9172             "FMRS        $dst,$tmp" %}
 9173 
 9174   size(32);
 9175 
 9176   ins_encode %{
 9177     __ fmdrr($tmp$$FloatRegister, $src$$Register, $src$$Register->successor());
 9178     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
 9179     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
 9180     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
 9181     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 32, 0);
 9182     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 9183   %}
 9184   ins_pipe(ialu_reg);
 9185 %}
 9186 
 9187 
 9188 // ============================================================================
 9189 //------------Bytes reverse--------------------------------------------------
 9190 
 9191 instruct bytes_reverse_int(iRegI dst, iRegI src) %{
 9192   match(Set dst (ReverseBytesI src));
 9193 
 9194   size(4);
 9195   format %{ "REV32 $dst,$src" %}
 9196   ins_encode %{
 9197     __ rev($dst$$Register, $src$$Register);
 9198   %}
 9199   ins_pipe( iload_mem ); // FIXME
 9200 %}
 9201 
 9202 instruct bytes_reverse_long(iRegL dst, iRegL src) %{
 9203   match(Set dst (ReverseBytesL src));
 9204   effect(TEMP dst);
 9205   size(8);
 9206   format %{ "REV $dst.lo,$src.lo\n\t"
 9207             "REV $dst.hi,$src.hi" %}
 9208   ins_encode %{
 9209     __ rev($dst$$Register, $src$$Register->successor());
 9210     __ rev($dst$$Register->successor(), $src$$Register);
 9211   %}
 9212   ins_pipe( iload_mem ); // FIXME
 9213 %}
 9214 
 9215 instruct bytes_reverse_unsigned_short(iRegI dst, iRegI src) %{
 9216   match(Set dst (ReverseBytesUS src));
 9217   size(8);
 9218   format %{ "REV32 $dst,$src\n\t"
 9219             "LSR   $dst,$dst,#16" %}
 9220   ins_encode %{
 9221     __ rev($dst$$Register, $src$$Register);
 9222     __ mov($dst$$Register, AsmOperand($dst$$Register, lsr, 16));
 9223   %}
 9224   ins_pipe( iload_mem ); // FIXME
 9225 %}
 9226 
 9227 instruct bytes_reverse_short(iRegI dst, iRegI src) %{
 9228   match(Set dst (ReverseBytesS src));
 9229   size(4);
 9230   format %{ "REVSH $dst,$src" %}
 9231   ins_encode %{
 9232     __ revsh($dst$$Register, $src$$Register);
 9233   %}
 9234   ins_pipe( iload_mem ); // FIXME
 9235 %}
 9236 
 9237 
 9238 // ====================VECTOR INSTRUCTIONS=====================================
 9239 
 9240 // Load Aligned Packed values into a Double Register
 9241 instruct loadV8(vecD dst, memoryD mem) %{
 9242   predicate(n->as_LoadVector()->memory_size() == 8);
 9243   match(Set dst (LoadVector mem));
 9244   ins_cost(MEMORY_REF_COST);
 9245   size(4);
 9246   format %{ "FLDD   $mem,$dst\t! load vector (8 bytes)" %}
 9247   ins_encode %{
 9248     __ ldr_double($dst$$FloatRegister, $mem$$Address);
 9249   %}
 9250   ins_pipe(floadD_mem);
 9251 %}
 9252 
 9253 // Load Aligned Packed values into a Double Register Pair
 9254 instruct loadV16(vecX dst, memoryvld mem) %{
 9255   predicate(n->as_LoadVector()->memory_size() == 16);
 9256   match(Set dst (LoadVector mem));
 9257   ins_cost(MEMORY_REF_COST);
 9258   size(4);
 9259   format %{ "VLD1   $mem,$dst.Q\t! load vector (16 bytes)" %}
 9260   ins_encode %{
 9261     __ vld1($dst$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
 9262   %}
 9263   ins_pipe(floadD_mem); // FIXME
 9264 %}
 9265 
 9266 // Store Vector in Double register to memory
 9267 instruct storeV8(memoryD mem, vecD src) %{
 9268   predicate(n->as_StoreVector()->memory_size() == 8);
 9269   match(Set mem (StoreVector mem src));
 9270   ins_cost(MEMORY_REF_COST);
 9271   size(4);
 9272   format %{ "FSTD   $src,$mem\t! store vector (8 bytes)" %}
 9273   ins_encode %{
 9274     __ str_double($src$$FloatRegister, $mem$$Address);
 9275   %}
 9276   ins_pipe(fstoreD_mem_reg);
 9277 %}
 9278 
 9279 // Store Vector in Double Register Pair to memory
 9280 instruct storeV16(memoryvld mem, vecX src) %{
 9281   predicate(n->as_StoreVector()->memory_size() == 16);
 9282   match(Set mem (StoreVector mem src));
 9283   ins_cost(MEMORY_REF_COST);
 9284   size(4);
 9285   format %{ "VST1   $src,$mem\t! store vector (16 bytes)" %}
 9286   ins_encode %{
 9287     __ vst1($src$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
 9288   %}
 9289   ins_pipe(fstoreD_mem_reg); // FIXME
 9290 %}
 9291 
 9292 // Replicate scalar to packed byte values in Double register
 9293 instruct Repl8B_reg(vecD dst, iRegI src, iRegI tmp) %{
 9294   predicate(n->as_Vector()->length() == 8 &&
 9295             Matcher::vector_element_basic_type(n) == T_BYTE);
 9296   match(Set dst (Replicate src));
 9297   ins_cost(DEFAULT_COST*4);
 9298   effect(TEMP tmp);
 9299   size(16);
 9300 
 9301   // FIXME: could use PKH instruction instead?
 9302   format %{ "LSL      $tmp, $src, 24 \n\t"
 9303             "OR       $tmp, $tmp, ($tmp >> 8) \n\t"
 9304             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
 9305             "FMDRR    $dst,$tmp,$tmp\t" %}
 9306   ins_encode %{
 9307     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 24));
 9308     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 8));
 9309     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
 9310     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 9311   %}
 9312   ins_pipe(ialu_reg); // FIXME
 9313 %}
 9314 
 9315 // Replicate scalar to packed byte values in Double register
 9316 instruct Repl8B_reg_simd(vecD dst, iRegI src) %{
 9317   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9318             Matcher::vector_element_basic_type(n) == T_BYTE);
 9319   match(Set dst (Replicate src));
 9320   size(4);
 9321 
 9322   format %{ "VDUP.8 $dst,$src\t" %}
 9323   ins_encode %{
 9324     bool quad = false;
 9325     __ vdupI($dst$$FloatRegister, $src$$Register,
 9326              MacroAssembler::VELEM_SIZE_8, quad);
 9327   %}
 9328   ins_pipe(ialu_reg); // FIXME
 9329 %}
 9330 
 9331 // Replicate scalar to packed byte values in Double register pair
 9332 instruct Repl16B_reg(vecX dst, iRegI src) %{
 9333   predicate(n->as_Vector()->length_in_bytes() == 16 &&
 9334             Matcher::vector_element_basic_type(n) == T_BYTE);
 9335   match(Set dst (Replicate src));
 9336   size(4);
 9337 
 9338   format %{ "VDUP.8 $dst.Q,$src\t" %}
 9339   ins_encode %{
 9340     bool quad = true;
 9341     __ vdupI($dst$$FloatRegister, $src$$Register,
 9342              MacroAssembler::VELEM_SIZE_8, quad);
 9343   %}
 9344   ins_pipe(ialu_reg); // FIXME
 9345 %}
 9346 
 9347 // Replicate scalar constant to packed byte values in Double register
 9348 instruct Repl8B_immI(vecD dst, immI src, iRegI tmp) %{
 9349   predicate(n->as_Vector()->length() == 8 &&
 9350             Matcher::vector_element_basic_type(n) == T_BYTE);
 9351   match(Set dst (Replicate src));
 9352   ins_cost(DEFAULT_COST*2);
 9353   effect(TEMP tmp);
 9354   size(12);
 9355 
 9356   format %{ "MOV      $tmp, Repl4($src))\n\t"
 9357             "FMDRR    $dst,$tmp,$tmp\t" %}
 9358   ins_encode( LdReplImmI(src, dst, tmp, (4), (1)) );
 9359   ins_pipe(loadConFD); // FIXME
 9360 %}
 9361 
 9362 // Replicate scalar constant to packed byte values in Double register
 9363 // TODO: support negative constants with MVNI?
 9364 instruct Repl8B_immU8(vecD dst, immU8 src) %{
 9365   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9366             Matcher::vector_element_basic_type(n) == T_BYTE);
 9367   match(Set dst (Replicate src));
 9368   size(4);
 9369 
 9370   format %{ "VMOV.U8  $dst,$src" %}
 9371   ins_encode %{
 9372     bool quad = false;
 9373     __ vmovI($dst$$FloatRegister, $src$$constant,
 9374              MacroAssembler::VELEM_SIZE_8, quad);
 9375   %}
 9376   ins_pipe(loadConFD); // FIXME
 9377 %}
 9378 
 9379 // Replicate scalar constant to packed byte values in Double register pair
 9380 instruct Repl16B_immU8(vecX dst, immU8 src) %{
 9381   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd() &&
 9382             Matcher::vector_element_basic_type(n) == T_BYTE);
 9383   match(Set dst (Replicate src));
 9384   size(4);
 9385 
 9386   format %{ "VMOV.U8  $dst.Q,$src" %}
 9387   ins_encode %{
 9388     bool quad = true;
 9389     __ vmovI($dst$$FloatRegister, $src$$constant,
 9390              MacroAssembler::VELEM_SIZE_8, quad);
 9391   %}
 9392   ins_pipe(loadConFD); // FIXME
 9393 %}
 9394 
 9395 // Replicate scalar to packed short/char values into Double register
 9396 instruct Repl4S_reg(vecD dst, iRegI src, iRegI tmp) %{
 9397   predicate(n->as_Vector()->length() == 4 &&
 9398             Matcher::vector_element_basic_type(n) == T_SHORT);
 9399   match(Set dst (Replicate src));
 9400   ins_cost(DEFAULT_COST*3);
 9401   effect(TEMP tmp);
 9402   size(12);
 9403 
 9404   // FIXME: could use PKH instruction instead?
 9405   format %{ "LSL      $tmp, $src, 16 \n\t"
 9406             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
 9407             "FMDRR    $dst,$tmp,$tmp\t" %}
 9408   ins_encode %{
 9409     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 16));
 9410     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
 9411     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 9412   %}
 9413   ins_pipe(ialu_reg); // FIXME
 9414 %}
 9415 
 9416 // Replicate scalar to packed byte values in Double register
 9417 instruct Repl4S_reg_simd(vecD dst, iRegI src) %{
 9418   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9419             Matcher::vector_element_basic_type(n) == T_SHORT);
 9420   match(Set dst (Replicate src));
 9421   size(4);
 9422 
 9423   format %{ "VDUP.16 $dst,$src\t" %}
 9424   ins_encode %{
 9425     bool quad = false;
 9426     __ vdupI($dst$$FloatRegister, $src$$Register,
 9427              MacroAssembler::VELEM_SIZE_16, quad);
 9428   %}
 9429   ins_pipe(ialu_reg); // FIXME
 9430 %}
 9431 
 9432 // Replicate scalar to packed byte values in Double register pair
 9433 instruct Repl8S_reg(vecX dst, iRegI src) %{
 9434   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd() &&
 9435             Matcher::vector_element_basic_type(n) == T_SHORT);
 9436   match(Set dst (Replicate src));
 9437   size(4);
 9438 
 9439   format %{ "VDUP.16 $dst.Q,$src\t" %}
 9440   ins_encode %{
 9441     bool quad = true;
 9442     __ vdupI($dst$$FloatRegister, $src$$Register,
 9443              MacroAssembler::VELEM_SIZE_16, quad);
 9444   %}
 9445   ins_pipe(ialu_reg); // FIXME
 9446 %}
 9447 
 9448 
 9449 // Replicate scalar constant to packed short/char values in Double register
 9450 instruct Repl4S_immI(vecD dst, immI src, iRegP tmp) %{
 9451   predicate(n->as_Vector()->length() == 4 &&
 9452             Matcher::vector_element_basic_type(n) == T_SHORT);
 9453   match(Set dst (Replicate src));
 9454   effect(TEMP tmp);
 9455   size(12);
 9456   ins_cost(DEFAULT_COST*4); // FIXME
 9457 
 9458   format %{ "MOV      $tmp, Repl2($src))\n\t"
 9459             "FMDRR    $dst,$tmp,$tmp\t" %}
 9460   ins_encode( LdReplImmI(src, dst, tmp, (2), (2)) );
 9461   ins_pipe(loadConFD); // FIXME
 9462 %}
 9463 
 9464 // Replicate scalar constant to packed byte values in Double register
 9465 instruct Repl4S_immU8(vecD dst, immU8 src) %{
 9466   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9467             Matcher::vector_element_basic_type(n) == T_SHORT);
 9468   match(Set dst (Replicate src));
 9469   size(4);
 9470 
 9471   format %{ "VMOV.U16  $dst,$src" %}
 9472   ins_encode %{
 9473     bool quad = false;
 9474     __ vmovI($dst$$FloatRegister, $src$$constant,
 9475              MacroAssembler::VELEM_SIZE_16, quad);
 9476   %}
 9477   ins_pipe(loadConFD); // FIXME
 9478 %}
 9479 
 9480 // Replicate scalar constant to packed byte values in Double register pair
 9481 instruct Repl8S_immU8(vecX dst, immU8 src) %{
 9482   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd() &&
 9483             Matcher::vector_element_basic_type(n) == T_SHORT);
 9484   match(Set dst (Replicate src));
 9485   size(4);
 9486 
 9487   format %{ "VMOV.U16  $dst.Q,$src" %}
 9488   ins_encode %{
 9489     bool quad = true;
 9490     __ vmovI($dst$$FloatRegister, $src$$constant,
 9491              MacroAssembler::VELEM_SIZE_16, quad);
 9492   %}
 9493   ins_pipe(loadConFD); // FIXME
 9494 %}
 9495 
 9496 // Replicate scalar to packed int values in Double register
 9497 instruct Repl2I_reg(vecD dst, iRegI src) %{
 9498   predicate(n->as_Vector()->length() == 2 &&
 9499             Matcher::vector_element_basic_type(n) == T_INT);
 9500   match(Set dst (Replicate src));
 9501   size(4);
 9502 
 9503   format %{ "FMDRR    $dst,$src,$src\t" %}
 9504   ins_encode %{
 9505     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
 9506   %}
 9507   ins_pipe(ialu_reg); // FIXME
 9508 %}
 9509 
 9510 // Replicate scalar to packed int values in Double register pair
 9511 instruct Repl4I_reg(vecX dst, iRegI src) %{
 9512   predicate(n->as_Vector()->length() == 4 &&
 9513             Matcher::vector_element_basic_type(n) == T_INT);
 9514   match(Set dst (Replicate src));
 9515   ins_cost(DEFAULT_COST*2);
 9516   size(8);
 9517 
 9518   format %{ "FMDRR    $dst.lo,$src,$src\n\t"
 9519             "FMDRR    $dst.hi,$src,$src" %}
 9520 
 9521   ins_encode %{
 9522     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
 9523     __ fmdrr($dst$$FloatRegister->successor()->successor(),
 9524              $src$$Register, $src$$Register);
 9525   %}
 9526   ins_pipe(ialu_reg); // FIXME
 9527 %}
 9528 
 9529 // Replicate scalar to packed int values in Double register
 9530 instruct Repl2I_reg_simd(vecD dst, iRegI src) %{
 9531   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9532             Matcher::vector_element_basic_type(n) == T_INT);
 9533   match(Set dst (Replicate src));
 9534   size(4);
 9535 
 9536   format %{ "VDUP.32 $dst.D,$src\t" %}
 9537   ins_encode %{
 9538     bool quad = false;
 9539     __ vdupI($dst$$FloatRegister, $src$$Register,
 9540              MacroAssembler::VELEM_SIZE_32, quad);
 9541   %}
 9542   ins_pipe(ialu_reg); // FIXME
 9543 %}
 9544 
 9545 // Replicate scalar to packed int values in Double register pair
 9546 instruct Repl4I_reg_simd(vecX dst, iRegI src) %{
 9547   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd() &&
 9548             Matcher::vector_element_basic_type(n) == T_INT);
 9549   match(Set dst (Replicate src));
 9550   size(4);
 9551 
 9552   format %{ "VDUP.32 $dst.Q,$src\t" %}
 9553   ins_encode %{
 9554     bool quad = true;
 9555     __ vdupI($dst$$FloatRegister, $src$$Register,
 9556              MacroAssembler::VELEM_SIZE_32, quad);
 9557   %}
 9558   ins_pipe(ialu_reg); // FIXME
 9559 %}
 9560 
 9561 
 9562 // Replicate scalar zero constant to packed int values in Double register
 9563 instruct Repl2I_immI(vecD dst, immI src, iRegI tmp) %{
 9564   predicate(n->as_Vector()->length() == 2 &&
 9565             Matcher::vector_element_basic_type(n) == T_INT);
 9566   match(Set dst (Replicate src));
 9567   effect(TEMP tmp);
 9568   size(12);
 9569   ins_cost(DEFAULT_COST*4); // FIXME
 9570 
 9571   format %{ "MOV      $tmp, Repl1($src))\n\t"
 9572             "FMDRR    $dst,$tmp,$tmp\t" %}
 9573   ins_encode( LdReplImmI(src, dst, tmp, (1), (4)) );
 9574   ins_pipe(loadConFD); // FIXME
 9575 %}
 9576 
 9577 // Replicate scalar constant to packed byte values in Double register
 9578 instruct Repl2I_immU8(vecD dst, immU8 src) %{
 9579   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9580             Matcher::vector_element_basic_type(n) == T_INT);
 9581   match(Set dst (Replicate src));
 9582   size(4);
 9583 
 9584   format %{ "VMOV.I32  $dst.D,$src" %}
 9585   ins_encode %{
 9586     bool quad = false;
 9587     __ vmovI($dst$$FloatRegister, $src$$constant,
 9588              MacroAssembler::VELEM_SIZE_32, quad);
 9589   %}
 9590   ins_pipe(loadConFD); // FIXME
 9591 %}
 9592 
 9593 // Replicate scalar constant to packed byte values in Double register pair
 9594 instruct Repl4I_immU8(vecX dst, immU8 src) %{
 9595   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd() &&
 9596             Matcher::vector_element_basic_type(n) == T_INT);
 9597   match(Set dst (Replicate src));
 9598   size(4);
 9599 
 9600   format %{ "VMOV.I32  $dst.Q,$src" %}
 9601   ins_encode %{
 9602     bool quad = true;
 9603     __ vmovI($dst$$FloatRegister, $src$$constant,
 9604              MacroAssembler::VELEM_SIZE_32, quad);
 9605   %}
 9606   ins_pipe(loadConFD); // FIXME
 9607 %}
 9608 
 9609 // Replicate scalar to packed byte values in Double register pair
 9610 instruct Repl2L_reg(vecX dst, iRegL src) %{
 9611   predicate(n->as_Vector()->length() == 2 &&
 9612             Matcher::vector_element_basic_type(n) == T_LONG);
 9613   match(Set dst (Replicate src));
 9614   size(8);
 9615   ins_cost(DEFAULT_COST*2); // FIXME
 9616 
 9617   format %{ "FMDRR $dst.D,$src.lo,$src.hi\t\n"
 9618             "FMDRR $dst.D.next,$src.lo,$src.hi" %}
 9619   ins_encode %{
 9620     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
 9621     __ fmdrr($dst$$FloatRegister->successor()->successor(),
 9622              $src$$Register, $src$$Register->successor());
 9623   %}
 9624   ins_pipe(ialu_reg); // FIXME
 9625 %}
 9626 
 9627 
 9628 // Replicate scalar to packed float values in Double register
 9629 instruct Repl2F_regI(vecD dst, iRegI src) %{
 9630   predicate(n->as_Vector()->length() == 2 &&
 9631             Matcher::vector_element_basic_type(n) == T_FLOAT);
 9632   match(Set dst (Replicate src));
 9633   size(4);
 9634 
 9635   format %{ "FMDRR    $dst.D,$src,$src\t" %}
 9636   ins_encode %{
 9637     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
 9638   %}
 9639   ins_pipe(ialu_reg); // FIXME
 9640 %}
 9641 
 9642 // Replicate scalar to packed float values in Double register
 9643 instruct Repl2F_reg_vfp(vecD dst, regF src) %{
 9644   predicate(n->as_Vector()->length() == 2 &&
 9645             Matcher::vector_element_basic_type(n) == T_FLOAT);
 9646   match(Set dst (Replicate src));
 9647   size(4*2);
 9648   ins_cost(DEFAULT_COST*2); // FIXME
 9649 
 9650   expand %{
 9651     iRegI tmp;
 9652     MoveF2I_reg_reg(tmp, src);
 9653     Repl2F_regI(dst,tmp);
 9654   %}
 9655 %}
 9656 
 9657 // Replicate scalar to packed float values in Double register
 9658 instruct Repl2F_reg_simd(vecD dst, regF src) %{
 9659   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9660             Matcher::vector_element_basic_type(n) == T_FLOAT);
 9661   match(Set dst (Replicate src));
 9662   size(4);
 9663   ins_cost(DEFAULT_COST); // FIXME
 9664 
 9665   format %{ "VDUP.32  $dst.D,$src.D\t" %}
 9666   ins_encode %{
 9667     bool quad = false;
 9668     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
 9669   %}
 9670   ins_pipe(ialu_reg); // FIXME
 9671 %}
 9672 
 9673 // Replicate scalar to packed float values in Double register pair
 9674 instruct Repl4F_reg(vecX dst, regF src, iRegI tmp) %{
 9675   predicate(n->as_Vector()->length() == 4 &&
 9676             Matcher::vector_element_basic_type(n) == T_FLOAT);
 9677   match(Set dst (Replicate src));
 9678   effect(TEMP tmp);
 9679   size(4*3);
 9680   ins_cost(DEFAULT_COST*3); // FIXME
 9681 
 9682   format %{ "FMRS     $tmp,$src\n\t"
 9683             "FMDRR    $dst.D,$tmp,$tmp\n\t"
 9684             "FMDRR    $dst.D.next,$tmp,$tmp\t" %}
 9685   ins_encode %{
 9686     __ fmrs($tmp$$Register, $src$$FloatRegister);
 9687     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 9688     __ fmdrr($dst$$FloatRegister->successor()->successor(),
 9689              $tmp$$Register, $tmp$$Register);
 9690   %}
 9691   ins_pipe(ialu_reg); // FIXME
 9692 %}
 9693 
 9694 // Replicate scalar to packed float values in Double register pair
 9695 instruct Repl4F_reg_simd(vecX dst, regF src) %{
 9696   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd() &&
 9697             Matcher::vector_element_basic_type(n) == T_FLOAT);
 9698   match(Set dst (Replicate src));
 9699   size(4);
 9700   ins_cost(DEFAULT_COST); // FIXME
 9701 
 9702   format %{ "VDUP.32  $dst.Q,$src.D\t" %}
 9703   ins_encode %{
 9704     bool quad = true;
 9705     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
 9706   %}
 9707   ins_pipe(ialu_reg); // FIXME
 9708 %}
 9709 
 9710 // Replicate scalar zero constant to packed float values in Double register
 9711 instruct Repl2F_immI(vecD dst, immF src, iRegI tmp) %{
 9712   predicate(n->as_Vector()->length() == 2 &&
 9713             Matcher::vector_element_basic_type(n) == T_FLOAT);
 9714   match(Set dst (Replicate src));
 9715   effect(TEMP tmp);
 9716   size(12);
 9717   ins_cost(DEFAULT_COST*4); // FIXME
 9718 
 9719   format %{ "MOV      $tmp, Repl1($src))\n\t"
 9720             "FMDRR    $dst,$tmp,$tmp\t" %}
 9721   ins_encode( LdReplImmF(src, dst, tmp) );
 9722   ins_pipe(loadConFD); // FIXME
 9723 %}
 9724 
 9725 // Replicate scalar to packed double float values in Double register pair
 9726 instruct Repl2D_reg(vecX dst, regD src) %{
 9727   predicate(n->as_Vector()->length() == 2 &&
 9728             Matcher::vector_element_basic_type(n) == T_DOUBLE);
 9729   match(Set dst (Replicate src));
 9730   size(4*2);
 9731   ins_cost(DEFAULT_COST*2); // FIXME
 9732 
 9733   format %{ "FCPYD    $dst.D.a,$src\n\t"
 9734             "FCPYD    $dst.D.b,$src\t" %}
 9735   ins_encode %{
 9736     FloatRegister dsta = $dst$$FloatRegister;
 9737     FloatRegister src = $src$$FloatRegister;
 9738     __ fcpyd(dsta, src);
 9739     FloatRegister dstb = dsta->successor()->successor();
 9740     __ fcpyd(dstb, src);
 9741   %}
 9742   ins_pipe(ialu_reg); // FIXME
 9743 %}
 9744 
 9745 // ====================VECTOR ARITHMETIC=======================================
 9746 
 9747 // --------------------------------- ADD --------------------------------------
 9748 
 9749 // Bytes vector add
 9750 instruct vadd8B_reg(vecD dst, vecD src1, vecD src2) %{
 9751   predicate(n->as_Vector()->length() == 8);
 9752   match(Set dst (AddVB src1 src2));
 9753   format %{ "VADD.I8 $dst,$src1,$src2\t! add packed8B" %}
 9754   size(4);
 9755   ins_encode %{
 9756     bool quad = false;
 9757     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9758              MacroAssembler::VELEM_SIZE_8, quad);
 9759   %}
 9760   ins_pipe( ialu_reg_reg ); // FIXME
 9761 %}
 9762 
 9763 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
 9764   predicate(n->as_Vector()->length() == 16);
 9765   match(Set dst (AddVB src1 src2));
 9766   size(4);
 9767   format %{ "VADD.I8 $dst.Q,$src1.Q,$src2.Q\t! add packed16B" %}
 9768   ins_encode %{
 9769     bool quad = true;
 9770     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9771              MacroAssembler::VELEM_SIZE_8, quad);
 9772   %}
 9773   ins_pipe( ialu_reg_reg ); // FIXME
 9774 %}
 9775 
 9776 // Shorts/Chars vector add
 9777 instruct vadd4S_reg(vecD dst, vecD src1, vecD src2) %{
 9778   predicate(n->as_Vector()->length() == 4);
 9779   match(Set dst (AddVS src1 src2));
 9780   size(4);
 9781   format %{ "VADD.I16 $dst,$src1,$src2\t! add packed4S" %}
 9782   ins_encode %{
 9783     bool quad = false;
 9784     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9785              MacroAssembler::VELEM_SIZE_16, quad);
 9786   %}
 9787   ins_pipe( ialu_reg_reg ); // FIXME
 9788 %}
 9789 
 9790 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
 9791   predicate(n->as_Vector()->length() == 8);
 9792   match(Set dst (AddVS src1 src2));
 9793   size(4);
 9794   format %{ "VADD.I16 $dst.Q,$src1.Q,$src2.Q\t! add packed8S" %}
 9795   ins_encode %{
 9796     bool quad = true;
 9797     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9798              MacroAssembler::VELEM_SIZE_16, quad);
 9799   %}
 9800   ins_pipe( ialu_reg_reg ); // FIXME
 9801 %}
 9802 
 9803 // Integers vector add
 9804 instruct vadd2I_reg(vecD dst, vecD src1, vecD src2) %{
 9805   predicate(n->as_Vector()->length() == 2);
 9806   match(Set dst (AddVI src1 src2));
 9807   size(4);
 9808   format %{ "VADD.I32 $dst.D,$src1.D,$src2.D\t! add packed2I" %}
 9809   ins_encode %{
 9810     bool quad = false;
 9811     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9812              MacroAssembler::VELEM_SIZE_32, quad);
 9813   %}
 9814   ins_pipe( ialu_reg_reg ); // FIXME
 9815 %}
 9816 
 9817 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
 9818   predicate(n->as_Vector()->length() == 4);
 9819   match(Set dst (AddVI src1 src2));
 9820   size(4);
 9821   format %{ "VADD.I32 $dst.Q,$src1.Q,$src2.Q\t! add packed4I" %}
 9822   ins_encode %{
 9823     bool quad = true;
 9824     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9825              MacroAssembler::VELEM_SIZE_32, quad);
 9826   %}
 9827   ins_pipe( ialu_reg_reg ); // FIXME
 9828 %}
 9829 
 9830 // Longs vector add
 9831 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
 9832   predicate(n->as_Vector()->length() == 2);
 9833   match(Set dst (AddVL src1 src2));
 9834   size(4);
 9835   format %{ "VADD.I64 $dst.Q,$src1.Q,$src2.Q\t! add packed2L" %}
 9836   ins_encode %{
 9837     bool quad = true;
 9838     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9839              MacroAssembler::VELEM_SIZE_64, quad);
 9840   %}
 9841   ins_pipe( ialu_reg_reg ); // FIXME
 9842 %}
 9843 
 9844 // Floats vector add
 9845 instruct vadd2F_reg(vecD dst, vecD src1, vecD src2) %{
 9846   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
 9847   match(Set dst (AddVF src1 src2));
 9848   size(4);
 9849   format %{ "VADD.F32 $dst,$src1,$src2\t! add packed2F" %}
 9850   ins_encode %{
 9851     bool quad = false;
 9852     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9853              MacroAssembler::VFA_SIZE_F32, quad);
 9854   %}
 9855   ins_pipe( faddD_reg_reg ); // FIXME
 9856 %}
 9857 
 9858 instruct vadd2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
 9859   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
 9860   match(Set dst (AddVF src1 src2));
 9861   ins_cost(DEFAULT_COST*2); // FIXME
 9862 
 9863   size(4*2);
 9864   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
 9865             "FADDS  $dst.b,$src1.b,$src2.b" %}
 9866   ins_encode %{
 9867     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 9868     __ add_float($dst$$FloatRegister->successor(),
 9869              $src1$$FloatRegister->successor(),
 9870              $src2$$FloatRegister->successor());
 9871   %}
 9872 
 9873   ins_pipe(faddF_reg_reg); // FIXME
 9874 %}
 9875 
 9876 instruct vadd4F_reg_simd(vecX dst, vecX src1, vecX src2) %{
 9877   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
 9878   match(Set dst (AddVF src1 src2));
 9879   size(4);
 9880   format %{ "VADD.F32 $dst.Q,$src1.Q,$src2.Q\t! add packed4F" %}
 9881   ins_encode %{
 9882     bool quad = true;
 9883     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9884              MacroAssembler::VFA_SIZE_F32, quad);
 9885   %}
 9886   ins_pipe( faddD_reg_reg ); // FIXME
 9887 %}
 9888 
 9889 instruct vadd4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
 9890   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
 9891   match(Set dst (AddVF src1 src2));
 9892   size(4*4);
 9893   ins_cost(DEFAULT_COST*4); // FIXME
 9894 
 9895   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
 9896             "FADDS  $dst.b,$src1.b,$src2.b\n\t"
 9897             "FADDS  $dst.c,$src1.c,$src2.c\n\t"
 9898             "FADDS  $dst.d,$src1.d,$src2.d" %}
 9899 
 9900   ins_encode %{
 9901     FloatRegister dsta = $dst$$FloatRegister;
 9902     FloatRegister src1a = $src1$$FloatRegister;
 9903     FloatRegister src2a = $src2$$FloatRegister;
 9904     __ add_float(dsta, src1a, src2a);
 9905     FloatRegister dstb = dsta->successor();
 9906     FloatRegister src1b = src1a->successor();
 9907     FloatRegister src2b = src2a->successor();
 9908     __ add_float(dstb, src1b, src2b);
 9909     FloatRegister dstc = dstb->successor();
 9910     FloatRegister src1c = src1b->successor();
 9911     FloatRegister src2c = src2b->successor();
 9912     __ add_float(dstc, src1c, src2c);
 9913     FloatRegister dstd = dstc->successor();
 9914     FloatRegister src1d = src1c->successor();
 9915     FloatRegister src2d = src2c->successor();
 9916     __ add_float(dstd, src1d, src2d);
 9917   %}
 9918 
 9919   ins_pipe(faddF_reg_reg); // FIXME
 9920 %}
 9921 
 9922 instruct vadd2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
 9923   predicate(n->as_Vector()->length() == 2);
 9924   match(Set dst (AddVD src1 src2));
 9925   size(4*2);
 9926   ins_cost(DEFAULT_COST*2); // FIXME
 9927 
 9928   format %{ "FADDD  $dst.a,$src1.a,$src2.a\n\t"
 9929             "FADDD  $dst.b,$src1.b,$src2.b" %}
 9930 
 9931   ins_encode %{
 9932     FloatRegister dsta = $dst$$FloatRegister;
 9933     FloatRegister src1a = $src1$$FloatRegister;
 9934     FloatRegister src2a = $src2$$FloatRegister;
 9935     __ add_double(dsta, src1a, src2a);
 9936     FloatRegister dstb = dsta->successor()->successor();
 9937     FloatRegister src1b = src1a->successor()->successor();
 9938     FloatRegister src2b = src2a->successor()->successor();
 9939     __ add_double(dstb, src1b, src2b);
 9940   %}
 9941 
 9942   ins_pipe(faddF_reg_reg); // FIXME
 9943 %}
 9944 
 9945 
 9946 // Bytes vector sub
 9947 instruct vsub8B_reg(vecD dst, vecD src1, vecD src2) %{
 9948   predicate(n->as_Vector()->length() == 8);
 9949   match(Set dst (SubVB src1 src2));
 9950   size(4);
 9951   format %{ "VSUB.I8 $dst,$src1,$src2\t! sub packed8B" %}
 9952   ins_encode %{
 9953     bool quad = false;
 9954     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9955              MacroAssembler::VELEM_SIZE_8, quad);
 9956   %}
 9957   ins_pipe( ialu_reg_reg ); // FIXME
 9958 %}
 9959 
 9960 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
 9961   predicate(n->as_Vector()->length() == 16);
 9962   match(Set dst (SubVB src1 src2));
 9963   size(4);
 9964   format %{ "VSUB.I8 $dst.Q,$src1.Q,$src2.Q\t! sub packed16B" %}
 9965   ins_encode %{
 9966     bool quad = true;
 9967     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9968              MacroAssembler::VELEM_SIZE_8, quad);
 9969   %}
 9970   ins_pipe( ialu_reg_reg ); // FIXME
 9971 %}
 9972 
 9973 // Shorts/Chars vector sub
 9974 instruct vsub4S_reg(vecD dst, vecD src1, vecD src2) %{
 9975   predicate(n->as_Vector()->length() == 4);
 9976   match(Set dst (SubVS src1 src2));
 9977   size(4);
 9978   format %{ "VSUB.I16 $dst,$src1,$src2\t! sub packed4S" %}
 9979   ins_encode %{
 9980     bool quad = false;
 9981     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9982              MacroAssembler::VELEM_SIZE_16, quad);
 9983   %}
 9984   ins_pipe( ialu_reg_reg ); // FIXME
 9985 %}
 9986 
 9987 instruct vsub16S_reg(vecX dst, vecX src1, vecX src2) %{
 9988   predicate(n->as_Vector()->length() == 8);
 9989   match(Set dst (SubVS src1 src2));
 9990   size(4);
 9991   format %{ "VSUB.I16 $dst.Q,$src1.Q,$src2.Q\t! sub packed8S" %}
 9992   ins_encode %{
 9993     bool quad = true;
 9994     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9995              MacroAssembler::VELEM_SIZE_16, quad);
 9996   %}
 9997   ins_pipe( ialu_reg_reg ); // FIXME
 9998 %}
 9999 
10000 // Integers vector sub
10001 instruct vsub2I_reg(vecD dst, vecD src1, vecD src2) %{
10002   predicate(n->as_Vector()->length() == 2);
10003   match(Set dst (SubVI src1 src2));
10004   size(4);
10005   format %{ "VSUB.I32 $dst,$src1,$src2\t! sub packed2I" %}
10006   ins_encode %{
10007     bool quad = false;
10008     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10009              MacroAssembler::VELEM_SIZE_32, quad);
10010   %}
10011   ins_pipe( ialu_reg_reg ); // FIXME
10012 %}
10013 
10014 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
10015   predicate(n->as_Vector()->length() == 4);
10016   match(Set dst (SubVI src1 src2));
10017   size(4);
10018   format %{ "VSUB.I32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4I" %}
10019   ins_encode %{
10020     bool quad = true;
10021     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10022              MacroAssembler::VELEM_SIZE_32, quad);
10023   %}
10024   ins_pipe( ialu_reg_reg ); // FIXME
10025 %}
10026 
10027 // Longs vector sub
10028 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
10029   predicate(n->as_Vector()->length() == 2);
10030   match(Set dst (SubVL src1 src2));
10031   size(4);
10032   format %{ "VSUB.I64 $dst.Q,$src1.Q,$src2.Q\t! sub packed2L" %}
10033   ins_encode %{
10034     bool quad = true;
10035     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10036              MacroAssembler::VELEM_SIZE_64, quad);
10037   %}
10038   ins_pipe( ialu_reg_reg ); // FIXME
10039 %}
10040 
10041 // Floats vector sub
10042 instruct vsub2F_reg(vecD dst, vecD src1, vecD src2) %{
10043   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
10044   match(Set dst (SubVF src1 src2));
10045   size(4);
10046   format %{ "VSUB.F32 $dst,$src1,$src2\t! sub packed2F" %}
10047   ins_encode %{
10048     bool quad = false;
10049     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10050              MacroAssembler::VFA_SIZE_F32, quad);
10051   %}
10052   ins_pipe( faddF_reg_reg ); // FIXME
10053 %}
10054 
10055 instruct vsub2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10056   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
10057   match(Set dst (SubVF src1 src2));
10058   size(4*2);
10059   ins_cost(DEFAULT_COST*2); // FIXME
10060 
10061   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10062             "FSUBS  $dst.b,$src1.b,$src2.b" %}
10063 
10064   ins_encode %{
10065     FloatRegister dsta = $dst$$FloatRegister;
10066     FloatRegister src1a = $src1$$FloatRegister;
10067     FloatRegister src2a = $src2$$FloatRegister;
10068     __ sub_float(dsta, src1a, src2a);
10069     FloatRegister dstb = dsta->successor();
10070     FloatRegister src1b = src1a->successor();
10071     FloatRegister src2b = src2a->successor();
10072     __ sub_float(dstb, src1b, src2b);
10073   %}
10074 
10075   ins_pipe(faddF_reg_reg); // FIXME
10076 %}
10077 
10078 
10079 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
10080   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
10081   match(Set dst (SubVF src1 src2));
10082   size(4);
10083   format %{ "VSUB.F32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4F" %}
10084   ins_encode %{
10085     bool quad = true;
10086     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10087              MacroAssembler::VFA_SIZE_F32, quad);
10088   %}
10089   ins_pipe( faddF_reg_reg ); // FIXME
10090 %}
10091 
10092 instruct vsub4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10093   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
10094   match(Set dst (SubVF src1 src2));
10095   size(4*4);
10096   ins_cost(DEFAULT_COST*4); // FIXME
10097 
10098   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10099             "FSUBS  $dst.b,$src1.b,$src2.b\n\t"
10100             "FSUBS  $dst.c,$src1.c,$src2.c\n\t"
10101             "FSUBS  $dst.d,$src1.d,$src2.d" %}
10102 
10103   ins_encode %{
10104     FloatRegister dsta = $dst$$FloatRegister;
10105     FloatRegister src1a = $src1$$FloatRegister;
10106     FloatRegister src2a = $src2$$FloatRegister;
10107     __ sub_float(dsta, src1a, src2a);
10108     FloatRegister dstb = dsta->successor();
10109     FloatRegister src1b = src1a->successor();
10110     FloatRegister src2b = src2a->successor();
10111     __ sub_float(dstb, src1b, src2b);
10112     FloatRegister dstc = dstb->successor();
10113     FloatRegister src1c = src1b->successor();
10114     FloatRegister src2c = src2b->successor();
10115     __ sub_float(dstc, src1c, src2c);
10116     FloatRegister dstd = dstc->successor();
10117     FloatRegister src1d = src1c->successor();
10118     FloatRegister src2d = src2c->successor();
10119     __ sub_float(dstd, src1d, src2d);
10120   %}
10121 
10122   ins_pipe(faddF_reg_reg); // FIXME
10123 %}
10124 
10125 instruct vsub2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10126   predicate(n->as_Vector()->length() == 2);
10127   match(Set dst (SubVD src1 src2));
10128   size(4*2);
10129   ins_cost(DEFAULT_COST*2); // FIXME
10130 
10131   format %{ "FSUBD  $dst.a,$src1.a,$src2.a\n\t"
10132             "FSUBD  $dst.b,$src1.b,$src2.b" %}
10133 
10134   ins_encode %{
10135     FloatRegister dsta = $dst$$FloatRegister;
10136     FloatRegister src1a = $src1$$FloatRegister;
10137     FloatRegister src2a = $src2$$FloatRegister;
10138     __ sub_double(dsta, src1a, src2a);
10139     FloatRegister dstb = dsta->successor()->successor();
10140     FloatRegister src1b = src1a->successor()->successor();
10141     FloatRegister src2b = src2a->successor()->successor();
10142     __ sub_double(dstb, src1b, src2b);
10143   %}
10144 
10145   ins_pipe(faddF_reg_reg); // FIXME
10146 %}
10147 
10148 // Shorts/Chars vector mul
10149 instruct vmul4S_reg(vecD dst, vecD src1, vecD src2) %{
10150   predicate(n->as_Vector()->length() == 4);
10151   match(Set dst (MulVS src1 src2));
10152   size(4);
10153   format %{ "VMUL.I16 $dst,$src1,$src2\t! mul packed4S" %}
10154   ins_encode %{
10155     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10156              MacroAssembler::VELEM_SIZE_16, 0);
10157   %}
10158   ins_pipe( ialu_reg_reg ); // FIXME
10159 %}
10160 
10161 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2) %{
10162   predicate(n->as_Vector()->length() == 8);
10163   match(Set dst (MulVS src1 src2));
10164   size(4);
10165   format %{ "VMUL.I16 $dst.Q,$src1.Q,$src2.Q\t! mul packed8S" %}
10166   ins_encode %{
10167     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10168              MacroAssembler::VELEM_SIZE_16, 1);
10169   %}
10170   ins_pipe( ialu_reg_reg ); // FIXME
10171 %}
10172 
10173 // Integers vector mul
10174 instruct vmul2I_reg(vecD dst, vecD src1, vecD src2) %{
10175   predicate(n->as_Vector()->length() == 2);
10176   match(Set dst (MulVI src1 src2));
10177   size(4);
10178   format %{ "VMUL.I32 $dst,$src1,$src2\t! mul packed2I" %}
10179   ins_encode %{
10180     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10181              MacroAssembler::VELEM_SIZE_32, 0);
10182   %}
10183   ins_pipe( ialu_reg_reg ); // FIXME
10184 %}
10185 
10186 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
10187   predicate(n->as_Vector()->length() == 4);
10188   match(Set dst (MulVI src1 src2));
10189   size(4);
10190   format %{ "VMUL.I32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4I" %}
10191   ins_encode %{
10192     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10193              MacroAssembler::VELEM_SIZE_32, 1);
10194   %}
10195   ins_pipe( ialu_reg_reg ); // FIXME
10196 %}
10197 
10198 // Floats vector mul
10199 instruct vmul2F_reg(vecD dst, vecD src1, vecD src2) %{
10200   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
10201   match(Set dst (MulVF src1 src2));
10202   size(4);
10203   format %{ "VMUL.F32 $dst,$src1,$src2\t! mul packed2F" %}
10204   ins_encode %{
10205     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10206              MacroAssembler::VFA_SIZE_F32, 0);
10207   %}
10208   ins_pipe( fmulF_reg_reg ); // FIXME
10209 %}
10210 
10211 instruct vmul2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10212   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
10213   match(Set dst (MulVF src1 src2));
10214   size(4*2);
10215   ins_cost(DEFAULT_COST*2); // FIXME
10216 
10217   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10218             "FMULS  $dst.b,$src1.b,$src2.b" %}
10219   ins_encode %{
10220     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10221     __ mul_float($dst$$FloatRegister->successor(),
10222              $src1$$FloatRegister->successor(),
10223              $src2$$FloatRegister->successor());
10224   %}
10225 
10226   ins_pipe(fmulF_reg_reg); // FIXME
10227 %}
10228 
10229 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
10230   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
10231   match(Set dst (MulVF src1 src2));
10232   size(4);
10233   format %{ "VMUL.F32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4F" %}
10234   ins_encode %{
10235     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10236              MacroAssembler::VFA_SIZE_F32, 1);
10237   %}
10238   ins_pipe( fmulF_reg_reg ); // FIXME
10239 %}
10240 
10241 instruct vmul4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10242   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
10243   match(Set dst (MulVF src1 src2));
10244   size(4*4);
10245   ins_cost(DEFAULT_COST*4); // FIXME
10246 
10247   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10248             "FMULS  $dst.b,$src1.b,$src2.b\n\t"
10249             "FMULS  $dst.c,$src1.c,$src2.c\n\t"
10250             "FMULS  $dst.d,$src1.d,$src2.d" %}
10251 
10252   ins_encode %{
10253     FloatRegister dsta = $dst$$FloatRegister;
10254     FloatRegister src1a = $src1$$FloatRegister;
10255     FloatRegister src2a = $src2$$FloatRegister;
10256     __ mul_float(dsta, src1a, src2a);
10257     FloatRegister dstb = dsta->successor();
10258     FloatRegister src1b = src1a->successor();
10259     FloatRegister src2b = src2a->successor();
10260     __ mul_float(dstb, src1b, src2b);
10261     FloatRegister dstc = dstb->successor();
10262     FloatRegister src1c = src1b->successor();
10263     FloatRegister src2c = src2b->successor();
10264     __ mul_float(dstc, src1c, src2c);
10265     FloatRegister dstd = dstc->successor();
10266     FloatRegister src1d = src1c->successor();
10267     FloatRegister src2d = src2c->successor();
10268     __ mul_float(dstd, src1d, src2d);
10269   %}
10270 
10271   ins_pipe(fmulF_reg_reg); // FIXME
10272 %}
10273 
10274 instruct vmul2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10275   predicate(n->as_Vector()->length() == 2);
10276   match(Set dst (MulVD src1 src2));
10277   size(4*2);
10278   ins_cost(DEFAULT_COST*2); // FIXME
10279 
10280   format %{ "FMULD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10281             "FMULD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10282   ins_encode %{
10283     FloatRegister dsta = $dst$$FloatRegister;
10284     FloatRegister src1a = $src1$$FloatRegister;
10285     FloatRegister src2a = $src2$$FloatRegister;
10286     __ mul_double(dsta, src1a, src2a);
10287     FloatRegister dstb = dsta->successor()->successor();
10288     FloatRegister src1b = src1a->successor()->successor();
10289     FloatRegister src2b = src2a->successor()->successor();
10290     __ mul_double(dstb, src1b, src2b);
10291   %}
10292 
10293   ins_pipe(fmulD_reg_reg); // FIXME
10294 %}
10295 
10296 
10297 // Floats vector div
10298 instruct vdiv2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10299   predicate(n->as_Vector()->length() == 2);
10300   match(Set dst (DivVF src1 src2));
10301   size(4*2);
10302   ins_cost(DEFAULT_COST*2); // FIXME
10303 
10304   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10305             "FDIVS  $dst.b,$src1.b,$src2.b" %}
10306   ins_encode %{
10307     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10308     __ div_float($dst$$FloatRegister->successor(),
10309              $src1$$FloatRegister->successor(),
10310              $src2$$FloatRegister->successor());
10311   %}
10312 
10313   ins_pipe(fdivF_reg_reg); // FIXME
10314 %}
10315 
10316 instruct vdiv4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10317   predicate(n->as_Vector()->length() == 4);
10318   match(Set dst (DivVF src1 src2));
10319   size(4*4);
10320   ins_cost(DEFAULT_COST*4); // FIXME
10321 
10322   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10323             "FDIVS  $dst.b,$src1.b,$src2.b\n\t"
10324             "FDIVS  $dst.c,$src1.c,$src2.c\n\t"
10325             "FDIVS  $dst.d,$src1.d,$src2.d" %}
10326 
10327   ins_encode %{
10328     FloatRegister dsta = $dst$$FloatRegister;
10329     FloatRegister src1a = $src1$$FloatRegister;
10330     FloatRegister src2a = $src2$$FloatRegister;
10331     __ div_float(dsta, src1a, src2a);
10332     FloatRegister dstb = dsta->successor();
10333     FloatRegister src1b = src1a->successor();
10334     FloatRegister src2b = src2a->successor();
10335     __ div_float(dstb, src1b, src2b);
10336     FloatRegister dstc = dstb->successor();
10337     FloatRegister src1c = src1b->successor();
10338     FloatRegister src2c = src2b->successor();
10339     __ div_float(dstc, src1c, src2c);
10340     FloatRegister dstd = dstc->successor();
10341     FloatRegister src1d = src1c->successor();
10342     FloatRegister src2d = src2c->successor();
10343     __ div_float(dstd, src1d, src2d);
10344   %}
10345 
10346   ins_pipe(fdivF_reg_reg); // FIXME
10347 %}
10348 
10349 instruct vdiv2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10350   predicate(n->as_Vector()->length() == 2);
10351   match(Set dst (DivVD src1 src2));
10352   size(4*2);
10353   ins_cost(DEFAULT_COST*2); // FIXME
10354 
10355   format %{ "FDIVD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10356             "FDIVD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10357   ins_encode %{
10358     FloatRegister dsta = $dst$$FloatRegister;
10359     FloatRegister src1a = $src1$$FloatRegister;
10360     FloatRegister src2a = $src2$$FloatRegister;
10361     __ div_double(dsta, src1a, src2a);
10362     FloatRegister dstb = dsta->successor()->successor();
10363     FloatRegister src1b = src1a->successor()->successor();
10364     FloatRegister src2b = src2a->successor()->successor();
10365     __ div_double(dstb, src1b, src2b);
10366   %}
10367 
10368   ins_pipe(fdivD_reg_reg); // FIXME
10369 %}
10370 
10371 // --------------------------------- NEG --------------------------------------
10372 
10373 instruct vneg8B_reg(vecD dst, vecD src) %{
10374   predicate(n->as_Vector()->length_in_bytes() == 8);
10375   effect(DEF dst, USE src);
10376   size(4);
10377   ins_cost(DEFAULT_COST); // FIXME
10378   format %{ "VNEG.S8 $dst.D,$src.D\t! neg packed8B" %}
10379   ins_encode %{
10380     bool quad = false;
10381     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
10382               MacroAssembler::VELEM_SIZE_8, quad);
10383   %}
10384   ins_pipe( ialu_reg_reg ); // FIXME
10385 %}
10386 
10387 instruct vneg16B_reg(vecX dst, vecX src) %{
10388   predicate(n->as_Vector()->length_in_bytes() == 16);
10389   effect(DEF dst, USE src);
10390   size(4);
10391   ins_cost(DEFAULT_COST); // FIXME
10392   format %{ "VNEG.S8 $dst.Q,$src.Q\t! neg0 packed16B" %}
10393   ins_encode %{
10394     bool _float = false;
10395     bool quad = true;
10396     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
10397               MacroAssembler::VELEM_SIZE_8, quad);
10398   %}
10399   ins_pipe( ialu_reg_reg ); // FIXME
10400 %}
10401 
10402 // ------------------------------ ShiftCount ----------------------------------
10403 
10404 instruct vslcntD(vecD dst, iRegI cnt) %{
10405   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
10406   match(Set dst (LShiftCntV cnt));
10407   size(4);
10408   ins_cost(DEFAULT_COST); // FIXME
10409   expand %{
10410     Repl8B_reg_simd(dst, cnt);
10411   %}
10412 %}
10413 
10414 instruct vslcntX(vecX dst, iRegI cnt) %{
10415   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
10416   match(Set dst (LShiftCntV cnt));
10417   size(4);
10418   ins_cost(DEFAULT_COST); // FIXME
10419   expand %{
10420     Repl16B_reg(dst, cnt);
10421   %}
10422 %}
10423 
10424 // Low bits of vector "shift" elements are used, so it
10425 // doesn't matter if we treat it as ints or bytes here.
10426 instruct vsrcntD(vecD dst, iRegI cnt) %{
10427   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
10428   match(Set dst (RShiftCntV cnt));
10429   size(4*2);
10430   ins_cost(DEFAULT_COST*2); // FIXME
10431 
10432   format %{ "VDUP.8 $dst.D,$cnt\n\t"
10433             "VNEG.S8 $dst.D,$dst.D\t! neg packed8B" %}
10434   ins_encode %{
10435     bool quad = false;
10436     __ vdupI($dst$$FloatRegister, $cnt$$Register,
10437              MacroAssembler::VELEM_SIZE_8, quad);
10438     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
10439               MacroAssembler::VELEM_SIZE_8, quad);
10440   %}
10441   ins_pipe( ialu_reg_reg ); // FIXME
10442 %}
10443 
10444 instruct vsrcntX(vecX dst, iRegI cnt) %{
10445   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
10446   match(Set dst (RShiftCntV cnt));
10447   size(4*2);
10448   ins_cost(DEFAULT_COST*2); // FIXME
10449   format %{ "VDUP.8 $dst.Q,$cnt\n\t"
10450             "VNEG.S8 $dst.Q,$dst.Q\t! neg packed16B" %}
10451   ins_encode %{
10452     bool quad = true;
10453     __ vdupI($dst$$FloatRegister, $cnt$$Register,
10454              MacroAssembler::VELEM_SIZE_8, quad);
10455     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
10456               MacroAssembler::VELEM_SIZE_8, quad);
10457   %}
10458   ins_pipe( ialu_reg_reg ); // FIXME
10459 %}
10460 
10461 // ------------------------------ LogicalShift --------------------------------
10462 
10463 // Byte vector logical left/right shift based on sign
10464 instruct vsh8B_reg(vecD dst, vecD src, vecD shift) %{
10465   predicate(n->as_Vector()->length() == 8);
10466   effect(DEF dst, USE src, USE shift);
10467   size(4);
10468   ins_cost(DEFAULT_COST); // FIXME
10469   format %{
10470     "VSHL.U8 $dst.D,$src.D,$shift.D\t! logical left/right shift packed8B"
10471   %}
10472   ins_encode %{
10473     bool quad = false;
10474     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10475               MacroAssembler::VELEM_SIZE_8, quad);
10476   %}
10477   ins_pipe( ialu_reg_reg ); // FIXME
10478 %}
10479 
10480 instruct vsh16B_reg(vecX dst, vecX src, vecX shift) %{
10481   predicate(n->as_Vector()->length() == 16);
10482   effect(DEF dst, USE src, USE shift);
10483   size(4);
10484   ins_cost(DEFAULT_COST); // FIXME
10485   format %{
10486     "VSHL.U8 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed16B"
10487   %}
10488   ins_encode %{
10489     bool quad = true;
10490     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10491               MacroAssembler::VELEM_SIZE_8, quad);
10492   %}
10493   ins_pipe( ialu_reg_reg ); // FIXME
10494 %}
10495 
10496 // Shorts/Char vector logical left/right shift based on sign
10497 instruct vsh4S_reg(vecD dst, vecD src, vecD shift) %{
10498   predicate(n->as_Vector()->length() == 4);
10499   effect(DEF dst, USE src, USE shift);
10500   size(4);
10501   ins_cost(DEFAULT_COST); // FIXME
10502   format %{
10503     "VSHL.U16 $dst.D,$src.D,$shift.D\t! logical left/right shift packed4S"
10504   %}
10505   ins_encode %{
10506     bool quad = false;
10507     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10508               MacroAssembler::VELEM_SIZE_16, quad);
10509   %}
10510   ins_pipe( ialu_reg_reg ); // FIXME
10511 %}
10512 
10513 instruct vsh8S_reg(vecX dst, vecX src, vecX shift) %{
10514   predicate(n->as_Vector()->length() == 8);
10515   effect(DEF dst, USE src, USE shift);
10516   size(4);
10517   ins_cost(DEFAULT_COST); // FIXME
10518   format %{
10519     "VSHL.U16 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed8S"
10520   %}
10521   ins_encode %{
10522     bool quad = true;
10523     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10524               MacroAssembler::VELEM_SIZE_16, quad);
10525   %}
10526   ins_pipe( ialu_reg_reg ); // FIXME
10527 %}
10528 
10529 // Integers vector logical left/right shift based on sign
10530 instruct vsh2I_reg(vecD dst, vecD src, vecD shift) %{
10531   predicate(n->as_Vector()->length() == 2);
10532   effect(DEF dst, USE src, USE shift);
10533   size(4);
10534   ins_cost(DEFAULT_COST); // FIXME
10535   format %{
10536     "VSHL.U32 $dst.D,$src.D,$shift.D\t! logical left/right shift packed2I"
10537   %}
10538   ins_encode %{
10539     bool quad = false;
10540     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10541               MacroAssembler::VELEM_SIZE_32, quad);
10542   %}
10543   ins_pipe( ialu_reg_reg ); // FIXME
10544 %}
10545 
10546 instruct vsh4I_reg(vecX dst, vecX src, vecX shift) %{
10547   predicate(n->as_Vector()->length() == 4);
10548   effect(DEF dst, USE src, USE shift);
10549   size(4);
10550   ins_cost(DEFAULT_COST); // FIXME
10551   format %{
10552     "VSHL.U32 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed4I"
10553   %}
10554   ins_encode %{
10555     bool quad = true;
10556     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10557               MacroAssembler::VELEM_SIZE_32, quad);
10558   %}
10559   ins_pipe( ialu_reg_reg ); // FIXME
10560 %}
10561 
10562 // Longs vector logical left/right shift based on sign
10563 instruct vsh2L_reg(vecX dst, vecX src, vecX shift) %{
10564   predicate(n->as_Vector()->length() == 2);
10565   effect(DEF dst, USE src, USE shift);
10566   size(4);
10567   ins_cost(DEFAULT_COST); // FIXME
10568   format %{
10569     "VSHL.U64 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed2L"
10570   %}
10571   ins_encode %{
10572     bool quad = true;
10573     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10574               MacroAssembler::VELEM_SIZE_64, quad);
10575   %}
10576   ins_pipe( ialu_reg_reg ); // FIXME
10577 %}
10578 
10579 // ------------------------------ LogicalLeftShift ----------------------------
10580 
10581 // Byte vector logical left shift
10582 instruct vsl8B_reg(vecD dst, vecD src, vecD shift) %{
10583   predicate(n->as_Vector()->length() == 8);
10584   match(Set dst (LShiftVB src shift));
10585   size(4*1);
10586   ins_cost(DEFAULT_COST*1); // FIXME
10587   expand %{
10588     vsh8B_reg(dst, src, shift);
10589   %}
10590 %}
10591 
10592 instruct vsl16B_reg(vecX dst, vecX src, vecX shift) %{
10593   predicate(n->as_Vector()->length() == 16);
10594   match(Set dst (LShiftVB src shift));
10595   size(4*1);
10596   ins_cost(DEFAULT_COST*1); // FIXME
10597   expand %{
10598     vsh16B_reg(dst, src, shift);
10599   %}
10600 %}
10601 
10602 instruct vsl8B_immI(vecD dst, vecD src, immI shift) %{
10603   predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n));
10604   match(Set dst (LShiftVB src (LShiftCntV shift)));
10605   size(4);
10606   ins_cost(DEFAULT_COST); // FIXME
10607   format %{
10608     "VSHL.I8 $dst.D,$src.D,$shift\t! logical left shift packed8B"
10609   %}
10610   ins_encode %{
10611     bool quad = false;
10612     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10613              quad);
10614   %}
10615   ins_pipe( ialu_reg_reg ); // FIXME
10616 %}
10617 
10618 instruct vsl16B_immI(vecX dst, vecX src, immI shift) %{
10619   predicate(n->as_Vector()->length() == 16 && assert_not_var_shift(n));
10620   match(Set dst (LShiftVB src (LShiftCntV shift)));
10621   size(4);
10622   ins_cost(DEFAULT_COST); // FIXME
10623   format %{
10624     "VSHL.I8 $dst.Q,$src.Q,$shift\t! logical left shift packed16B"
10625   %}
10626   ins_encode %{
10627     bool quad = true;
10628     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10629              quad);
10630   %}
10631   ins_pipe( ialu_reg_reg ); // FIXME
10632 %}
10633 
10634 // Shorts/Chars vector logical left shift
10635 instruct vsl4S_reg(vecD dst, vecD src, vecD shift) %{
10636   predicate(n->as_Vector()->length() == 4);
10637   match(Set dst (LShiftVS src shift));
10638   size(4*1);
10639   ins_cost(DEFAULT_COST*1); // FIXME
10640   expand %{
10641     vsh4S_reg(dst, src, shift);
10642   %}
10643 %}
10644 
10645 instruct vsl8S_reg(vecX dst, vecX src, vecX shift) %{
10646   predicate(n->as_Vector()->length() == 8);
10647   match(Set dst (LShiftVS src shift));
10648   size(4*1);
10649   ins_cost(DEFAULT_COST*1); // FIXME
10650   expand %{
10651     vsh8S_reg(dst, src, shift);
10652   %}
10653 %}
10654 
10655 instruct vsl4S_immI(vecD dst, vecD src, immI shift) %{
10656   predicate(n->as_Vector()->length() == 4 && assert_not_var_shift(n));
10657   match(Set dst (LShiftVS src (LShiftCntV shift)));
10658   size(4);
10659   ins_cost(DEFAULT_COST); // FIXME
10660   format %{
10661     "VSHL.I16 $dst.D,$src.D,$shift\t! logical left shift packed4S"
10662   %}
10663   ins_encode %{
10664     bool quad = false;
10665     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10666              quad);
10667   %}
10668   ins_pipe( ialu_reg_reg ); // FIXME
10669 %}
10670 
10671 instruct vsl8S_immI(vecX dst, vecX src, immI shift) %{
10672   predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n));
10673   match(Set dst (LShiftVS src shift));
10674   size(4);
10675   ins_cost(DEFAULT_COST); // FIXME
10676   format %{
10677     "VSHL.I16 $dst.Q,$src.Q,$shift\t! logical left shift packed8S"
10678   %}
10679   ins_encode %{
10680     bool quad = true;
10681     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10682              quad);
10683   %}
10684   ins_pipe( ialu_reg_reg ); // FIXME
10685 %}
10686 
10687 // Integers vector logical left shift
10688 instruct vsl2I_reg(vecD dst, vecD src, vecD shift) %{
10689   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10690   match(Set dst (LShiftVI src shift));
10691   size(4*1);
10692   ins_cost(DEFAULT_COST*1); // FIXME
10693   expand %{
10694     vsh2I_reg(dst, src, shift);
10695   %}
10696 %}
10697 
10698 instruct vsl4I_reg(vecX dst, vecX src, vecX shift) %{
10699   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10700   match(Set dst (LShiftVI src shift));
10701   size(4*1);
10702   ins_cost(DEFAULT_COST*1); // FIXME
10703   expand %{
10704     vsh4I_reg(dst, src, shift);
10705   %}
10706 %}
10707 
10708 instruct vsl2I_immI(vecD dst, vecD src, immI shift) %{
10709   predicate(n->as_Vector()->length() == 2 &&
10710             VM_Version::has_simd() &&
10711             assert_not_var_shift(n));
10712   match(Set dst (LShiftVI src (LShiftCntV shift)));
10713   size(4);
10714   ins_cost(DEFAULT_COST); // FIXME
10715   format %{
10716     "VSHL.I32 $dst.D,$src.D,$shift\t! logical left shift packed2I"
10717   %}
10718   ins_encode %{
10719     bool quad = false;
10720     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10721              quad);
10722   %}
10723   ins_pipe( ialu_reg_reg ); // FIXME
10724 %}
10725 
10726 instruct vsl4I_immI(vecX dst, vecX src, immI shift) %{
10727   predicate(n->as_Vector()->length() == 4 &&
10728             VM_Version::has_simd() &&
10729             assert_not_var_shift(n));
10730   match(Set dst (LShiftVI src (LShiftCntV shift)));
10731   size(4);
10732   ins_cost(DEFAULT_COST); // FIXME
10733   format %{
10734     "VSHL.I32 $dst.Q,$src.Q,$shift\t! logical left shift packed4I"
10735   %}
10736   ins_encode %{
10737     bool quad = true;
10738     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10739              quad);
10740   %}
10741   ins_pipe( ialu_reg_reg ); // FIXME
10742 %}
10743 
10744 // Longs vector logical left shift
10745 instruct vsl2L_reg(vecX dst, vecX src, vecX shift) %{
10746   predicate(n->as_Vector()->length() == 2);
10747   match(Set dst (LShiftVL src shift));
10748   size(4*1);
10749   ins_cost(DEFAULT_COST*1); // FIXME
10750   expand %{
10751     vsh2L_reg(dst, src, shift);
10752   %}
10753 %}
10754 
10755 instruct vsl2L_immI(vecX dst, vecX src, immI shift) %{
10756   predicate(n->as_Vector()->length() == 2 && assert_not_var_shift(n));
10757   match(Set dst (LShiftVL src (LShiftCntV shift)));
10758   size(4);
10759   ins_cost(DEFAULT_COST); // FIXME
10760   format %{
10761     "VSHL.I64 $dst.Q,$src.Q,$shift\t! logical left shift packed2L"
10762   %}
10763   ins_encode %{
10764     bool quad = true;
10765     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
10766              quad);
10767   %}
10768   ins_pipe( ialu_reg_reg ); // FIXME
10769 %}
10770 
10771 // ----------------------- LogicalRightShift -----------------------------------
10772 
10773 // Bytes/Shorts vector logical right shift produces incorrect Java result
10774 // for negative data because java code convert short value into int with
10775 // sign extension before a shift.
10776 
10777 // Right shift with vector shift count on aarch32 SIMD is implemented as left
10778 // shift by negative shift count value.
10779 //
10780 // Method is_var_shift() denotes that vector shift count is a variable shift:
10781 // 1) for this case, vector shift count should be negated before conducting
10782 //    right shifts. E.g., vsrl4S_reg_var rule.
10783 // 2) for the opposite case, vector shift count is generated via RShiftCntV
10784 //    rules and is already negated there. Hence, no negation is needed.
10785 //    E.g., vsrl4S_reg rule.
10786 
10787 // Chars vector logical right shift
10788 instruct vsrl4S_reg(vecD dst, vecD src, vecD shift) %{
10789   predicate(n->as_Vector()->length() == 4 && !n->as_ShiftV()->is_var_shift());
10790   match(Set dst (URShiftVS src shift));
10791   size(4);
10792   ins_cost(DEFAULT_COST);
10793   expand %{
10794     vsh4S_reg(dst, src, shift);
10795   %}
10796 %}
10797 
10798 instruct vsrl4S_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{
10799   predicate(n->as_Vector()->length() == 4 && n->as_ShiftV()->is_var_shift());
10800   match(Set dst (URShiftVS src shift));
10801   effect(TEMP tmp);
10802   size(4*2);
10803   ins_cost(DEFAULT_COST*2);
10804   format %{
10805     "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B"
10806     "VSHL.U16 $dst.D,$src.D,$tmp.D\t! logical right shift packed4S"
10807   %}
10808   ins_encode %{
10809     bool quad = false;
10810     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
10811              MacroAssembler::VELEM_SIZE_8, quad);
10812     __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
10813               MacroAssembler::VELEM_SIZE_16, quad);
10814   %}
10815   ins_pipe(ialu_reg_reg);
10816 %}
10817 
10818 instruct vsrl8S_reg(vecX dst, vecX src, vecX shift) %{
10819   predicate(n->as_Vector()->length() == 8 && !n->as_ShiftV()->is_var_shift());
10820   match(Set dst (URShiftVS src shift));
10821   size(4);
10822   ins_cost(DEFAULT_COST);
10823   expand %{
10824     vsh8S_reg(dst, src, shift);
10825   %}
10826 %}
10827 
10828 instruct vsrl8S_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
10829   predicate(n->as_Vector()->length() == 8 && n->as_ShiftV()->is_var_shift());
10830   match(Set dst (URShiftVS src shift));
10831   effect(TEMP tmp);
10832   size(4*2);
10833   ins_cost(DEFAULT_COST*2);
10834   format %{
10835     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
10836     "VSHL.U16 $dst.Q,$src.Q,$tmp.Q\t! logical right shift packed8S"
10837   %}
10838   ins_encode %{
10839     bool quad = true;
10840     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
10841              MacroAssembler::VELEM_SIZE_8, quad);
10842     __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
10843               MacroAssembler::VELEM_SIZE_16, quad);
10844   %}
10845   ins_pipe(ialu_reg_reg);
10846 %}
10847 
10848 instruct vsrl4S_immI(vecD dst, vecD src, immI shift) %{
10849   predicate(n->as_Vector()->length() == 4 && assert_not_var_shift(n));
10850   match(Set dst (URShiftVS src (RShiftCntV shift)));
10851   size(4);
10852   ins_cost(DEFAULT_COST); // FIXME
10853   format %{
10854     "VSHR.U16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
10855   %}
10856   ins_encode %{
10857     bool quad = false;
10858     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10859              quad);
10860   %}
10861   ins_pipe( ialu_reg_reg ); // FIXME
10862 %}
10863 
10864 instruct vsrl8S_immI(vecX dst, vecX src, immI shift) %{
10865   predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n));
10866   match(Set dst (URShiftVS src (RShiftCntV shift)));
10867   size(4);
10868   ins_cost(DEFAULT_COST); // FIXME
10869   format %{
10870     "VSHR.U16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
10871   %}
10872   ins_encode %{
10873     bool quad = true;
10874     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10875              quad);
10876   %}
10877   ins_pipe( ialu_reg_reg ); // FIXME
10878 %}
10879 
10880 // Integers vector logical right shift
10881 instruct vsrl2I_reg(vecD dst, vecD src, vecD shift) %{
10882   predicate(n->as_Vector()->length() == 2 &&
10883             VM_Version::has_simd() &&
10884             !n->as_ShiftV()->is_var_shift());
10885   match(Set dst (URShiftVI src shift));
10886   size(4);
10887   ins_cost(DEFAULT_COST);
10888   expand %{
10889     vsh2I_reg(dst, src, shift);
10890   %}
10891 %}
10892 
10893 instruct vsrl2I_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{
10894   predicate(n->as_Vector()->length() == 2 &&
10895             VM_Version::has_simd() &&
10896             n->as_ShiftV()->is_var_shift());
10897   match(Set dst (URShiftVI src shift));
10898   effect(TEMP tmp);
10899   size(4*2);
10900   ins_cost(DEFAULT_COST*2);
10901   format %{
10902     "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B"
10903     "VSHL.U32 $dst.D,$src.D,$tmp.D\t! logical right shift packed2I"
10904   %}
10905   ins_encode %{
10906     bool quad = false;
10907     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
10908              MacroAssembler::VELEM_SIZE_8, quad);
10909     __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
10910               MacroAssembler::VELEM_SIZE_32, quad);
10911   %}
10912   ins_pipe(ialu_reg_reg);
10913 %}
10914 
10915 instruct vsrl4I_reg(vecX dst, vecX src, vecX shift) %{
10916   predicate(n->as_Vector()->length() == 4 &&
10917             VM_Version::has_simd() &&
10918             !n->as_ShiftV()->is_var_shift());
10919   match(Set dst (URShiftVI src shift));
10920   size(4);
10921   ins_cost(DEFAULT_COST);
10922   expand %{
10923     vsh4I_reg(dst, src, shift);
10924   %}
10925 %}
10926 
10927 instruct vsrl4I_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
10928   predicate(n->as_Vector()->length() == 4 &&
10929             VM_Version::has_simd() &&
10930             n->as_ShiftV()->is_var_shift());
10931   match(Set dst (URShiftVI src shift));
10932   effect(TEMP tmp);
10933   size(4*2);
10934   ins_cost(DEFAULT_COST*2);
10935   format %{
10936     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
10937     "VSHL.U32 $dst.Q,$src.Q,$tmp.Q\t! logical right shift packed4I"
10938   %}
10939   ins_encode %{
10940     bool quad = true;
10941     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
10942              MacroAssembler::VELEM_SIZE_8, quad);
10943     __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
10944               MacroAssembler::VELEM_SIZE_32, quad);
10945   %}
10946   ins_pipe(ialu_reg_reg);
10947 %}
10948 
10949 instruct vsrl2I_immI(vecD dst, vecD src, immI shift) %{
10950   predicate(n->as_Vector()->length() == 2 &&
10951             VM_Version::has_simd() &&
10952             assert_not_var_shift(n));
10953   match(Set dst (URShiftVI src (RShiftCntV shift)));
10954   size(4);
10955   ins_cost(DEFAULT_COST); // FIXME
10956   format %{
10957     "VSHR.U32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
10958   %}
10959   ins_encode %{
10960     bool quad = false;
10961     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10962              quad);
10963   %}
10964   ins_pipe( ialu_reg_reg ); // FIXME
10965 %}
10966 
10967 instruct vsrl4I_immI(vecX dst, vecX src, immI shift) %{
10968   predicate(n->as_Vector()->length() == 4 &&
10969             VM_Version::has_simd() &&
10970             assert_not_var_shift(n));
10971   match(Set dst (URShiftVI src (RShiftCntV shift)));
10972   size(4);
10973   ins_cost(DEFAULT_COST); // FIXME
10974   format %{
10975     "VSHR.U32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
10976   %}
10977   ins_encode %{
10978     bool quad = true;
10979     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10980              quad);
10981   %}
10982   ins_pipe( ialu_reg_reg ); // FIXME
10983 %}
10984 
10985 // Longs vector logical right shift
10986 instruct vsrl2L_reg(vecX dst, vecX src, vecX shift) %{
10987   predicate(n->as_Vector()->length() == 2 && !n->as_ShiftV()->is_var_shift());
10988   match(Set dst (URShiftVL src shift));
10989   size(4);
10990   ins_cost(DEFAULT_COST);
10991   expand %{
10992     vsh2L_reg(dst, src, shift);
10993   %}
10994 %}
10995 
10996 instruct vsrl2L_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
10997   predicate(n->as_Vector()->length() == 2 && n->as_ShiftV()->is_var_shift());
10998   match(Set dst (URShiftVL src shift));
10999   effect(TEMP tmp, DEF dst, USE src, USE shift);
11000   size(4*2);
11001   ins_cost(DEFAULT_COST*2);
11002   format %{
11003     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
11004     "VSHL.U64 $dst.Q,$src.Q,$tmp.Q\t! logical right shift packed2L"
11005   %}
11006   ins_encode %{
11007     bool quad = true;
11008     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11009              MacroAssembler::VELEM_SIZE_8, quad);
11010     __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11011               MacroAssembler::VELEM_SIZE_64, quad);
11012   %}
11013   ins_pipe(ialu_reg_reg);
11014 %}
11015 
11016 instruct vsrl2L_immI(vecX dst, vecX src, immI shift) %{
11017   predicate(n->as_Vector()->length() == 2 && assert_not_var_shift(n));
11018   match(Set dst (URShiftVL src (RShiftCntV shift)));
11019   size(4);
11020   ins_cost(DEFAULT_COST); // FIXME
11021   format %{
11022     "VSHR.U64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
11023   %}
11024   ins_encode %{
11025     bool quad = true;
11026     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
11027              quad);
11028   %}
11029   ins_pipe( ialu_reg_reg ); // FIXME
11030 %}
11031 
11032 // ------------------- ArithmeticRightShift -----------------------------------
11033 
11034 // Bytes vector arithmetic left/right shift based on sign
11035 instruct vsha8B_reg(vecD dst, vecD src, vecD shift) %{
11036   predicate(n->as_Vector()->length() == 8);
11037   effect(DEF dst, USE src, USE shift);
11038   size(4);
11039   ins_cost(DEFAULT_COST); // FIXME
11040   format %{
11041     "VSHL.S8 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed8B"
11042   %}
11043   ins_encode %{
11044     bool quad = false;
11045     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11046               MacroAssembler::VELEM_SIZE_8, quad);
11047   %}
11048   ins_pipe( ialu_reg_reg ); // FIXME
11049 %}
11050 
11051 instruct vsha16B_reg(vecX dst, vecX src, vecX shift) %{
11052   predicate(n->as_Vector()->length() == 16);
11053   effect(DEF dst, USE src, USE shift);
11054   size(4);
11055   ins_cost(DEFAULT_COST); // FIXME
11056   format %{
11057     "VSHL.S8 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed16B"
11058   %}
11059   ins_encode %{
11060     bool quad = true;
11061     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11062               MacroAssembler::VELEM_SIZE_8, quad);
11063   %}
11064   ins_pipe( ialu_reg_reg ); // FIXME
11065 %}
11066 
11067 // Shorts vector arithmetic left/right shift based on sign
11068 instruct vsha4S_reg(vecD dst, vecD src, vecD shift) %{
11069   predicate(n->as_Vector()->length() == 4);
11070   effect(DEF dst, USE src, USE shift);
11071   size(4);
11072   ins_cost(DEFAULT_COST); // FIXME
11073   format %{
11074     "VSHL.S16 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed4S"
11075   %}
11076   ins_encode %{
11077     bool quad = false;
11078     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11079               MacroAssembler::VELEM_SIZE_16, quad);
11080   %}
11081   ins_pipe( ialu_reg_reg ); // FIXME
11082 %}
11083 
11084 instruct vsha8S_reg(vecX dst, vecX src, vecX shift) %{
11085   predicate(n->as_Vector()->length() == 8);
11086   effect(DEF dst, USE src, USE shift);
11087   size(4);
11088   ins_cost(DEFAULT_COST); // FIXME
11089   format %{
11090     "VSHL.S16 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed8S"
11091   %}
11092   ins_encode %{
11093     bool quad = true;
11094     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11095               MacroAssembler::VELEM_SIZE_16, quad);
11096   %}
11097   ins_pipe( ialu_reg_reg ); // FIXME
11098 %}
11099 
11100 // Integers vector arithmetic left/right shift based on sign
11101 instruct vsha2I_reg(vecD dst, vecD src, vecD shift) %{
11102   predicate(n->as_Vector()->length() == 2);
11103   effect(DEF dst, USE src, USE shift);
11104   size(4);
11105   ins_cost(DEFAULT_COST); // FIXME
11106   format %{
11107     "VSHL.S32 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed2I"
11108   %}
11109   ins_encode %{
11110     bool quad = false;
11111     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11112               MacroAssembler::VELEM_SIZE_32, quad);
11113   %}
11114   ins_pipe( ialu_reg_reg ); // FIXME
11115 %}
11116 
11117 instruct vsha4I_reg(vecX dst, vecX src, vecX shift) %{
11118   predicate(n->as_Vector()->length() == 4);
11119   effect(DEF dst, USE src, USE shift);
11120   size(4);
11121   ins_cost(DEFAULT_COST); // FIXME
11122   format %{
11123     "VSHL.S32 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed4I"
11124   %}
11125   ins_encode %{
11126     bool quad = true;
11127     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11128               MacroAssembler::VELEM_SIZE_32, quad);
11129   %}
11130   ins_pipe( ialu_reg_reg ); // FIXME
11131 %}
11132 
11133 // Longs vector arithmetic left/right shift based on sign
11134 instruct vsha2L_reg(vecX dst, vecX src, vecX shift) %{
11135   predicate(n->as_Vector()->length() == 2);
11136   effect(DEF dst, USE src, USE shift);
11137   size(4);
11138   ins_cost(DEFAULT_COST); // FIXME
11139   format %{
11140     "VSHL.S64 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed2L"
11141   %}
11142   ins_encode %{
11143     bool quad = true;
11144     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11145               MacroAssembler::VELEM_SIZE_64, quad);
11146   %}
11147   ins_pipe( ialu_reg_reg ); // FIXME
11148 %}
11149 
11150 // Byte vector arithmetic right shift
11151 instruct vsra8B_reg(vecD dst, vecD src, vecD shift) %{
11152   predicate(n->as_Vector()->length() == 8 && !n->as_ShiftV()->is_var_shift());
11153   match(Set dst (RShiftVB src shift));
11154   size(4);
11155   ins_cost(DEFAULT_COST); // FIXME
11156   expand %{
11157     vsha8B_reg(dst, src, shift);
11158   %}
11159 %}
11160 
11161 instruct vsra8B_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{
11162   predicate(n->as_Vector()->length() == 8 && n->as_ShiftV()->is_var_shift());
11163   match(Set dst (RShiftVB src shift));
11164   effect(TEMP tmp);
11165   size(4*2);
11166   ins_cost(DEFAULT_COST*2);
11167   format %{
11168     "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B"
11169     "VSHL.S8 $dst.D,$src.D,$tmp.D\t! arithmetic right shift packed8B"
11170   %}
11171   ins_encode %{
11172     bool quad = false;
11173     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11174              MacroAssembler::VELEM_SIZE_8, quad);
11175     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11176               MacroAssembler::VELEM_SIZE_8, quad);
11177   %}
11178   ins_pipe(ialu_reg_reg);
11179 %}
11180 
11181 instruct vsra16B_reg(vecX dst, vecX src, vecX shift) %{
11182   predicate(n->as_Vector()->length() == 16 && !n->as_ShiftV()->is_var_shift());
11183   match(Set dst (RShiftVB src shift));
11184   size(4);
11185   ins_cost(DEFAULT_COST); // FIXME
11186   expand %{
11187     vsha16B_reg(dst, src, shift);
11188   %}
11189 %}
11190 
11191 instruct vsra16B_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
11192   predicate(n->as_Vector()->length() == 16 && n->as_ShiftV()->is_var_shift());
11193   match(Set dst (RShiftVB src shift));
11194   effect(TEMP tmp);
11195   size(4*2);
11196   ins_cost(DEFAULT_COST*2);
11197   format %{
11198     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
11199     "VSHL.S8 $dst.Q,$src.Q,$tmp.Q\t! arithmetic right shift packed16B"
11200   %}
11201   ins_encode %{
11202     bool quad = true;
11203     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11204              MacroAssembler::VELEM_SIZE_8, quad);
11205     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11206               MacroAssembler::VELEM_SIZE_8, quad);
11207   %}
11208   ins_pipe(ialu_reg_reg);
11209 %}
11210 
11211 instruct vsra8B_immI(vecD dst, vecD src, immI shift) %{
11212   predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n));
11213   match(Set dst (RShiftVB src (RShiftCntV shift)));
11214   size(4);
11215   ins_cost(DEFAULT_COST); // FIXME
11216   format %{
11217     "VSHR.S8 $dst.D,$src.D,$shift\t! arithmetic right shift packed8B"
11218   %}
11219   ins_encode %{
11220     bool quad = false;
11221     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
11222              quad);
11223   %}
11224   ins_pipe( ialu_reg_reg ); // FIXME
11225 %}
11226 
11227 instruct vsra16B_immI(vecX dst, vecX src, immI shift) %{
11228   predicate(n->as_Vector()->length() == 16 && assert_not_var_shift(n));
11229   match(Set dst (RShiftVB src (RShiftCntV shift)));
11230   size(4);
11231   ins_cost(DEFAULT_COST); // FIXME
11232   format %{
11233     "VSHR.S8 $dst.Q,$src.Q,$shift\t! arithmetic right shift packed16B"
11234   %}
11235   ins_encode %{
11236     bool quad = true;
11237     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
11238              quad);
11239   %}
11240   ins_pipe( ialu_reg_reg ); // FIXME
11241 %}
11242 
11243 // Shorts vector arithmetic right shift
11244 instruct vsra4S_reg(vecD dst, vecD src, vecD shift) %{
11245   predicate(n->as_Vector()->length() == 4 && !n->as_ShiftV()->is_var_shift());
11246   match(Set dst (RShiftVS src shift));
11247   size(4);
11248   ins_cost(DEFAULT_COST); // FIXME
11249   expand %{
11250     vsha4S_reg(dst, src, shift);
11251   %}
11252 %}
11253 
11254 instruct vsra4S_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{
11255   predicate(n->as_Vector()->length() == 4 && n->as_ShiftV()->is_var_shift());
11256   match(Set dst (RShiftVS src shift));
11257   effect(TEMP tmp);
11258   size(4*2);
11259   ins_cost(DEFAULT_COST*2);
11260   format %{
11261     "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B"
11262     "VSHL.S16 $dst.D,$src.D,$tmp.D\t! arithmetic right shift packed4S"
11263   %}
11264   ins_encode %{
11265     bool quad = false;
11266     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11267              MacroAssembler::VELEM_SIZE_8, quad);
11268     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11269               MacroAssembler::VELEM_SIZE_16, quad);
11270   %}
11271   ins_pipe(ialu_reg_reg);
11272 %}
11273 
11274 instruct vsra8S_reg(vecX dst, vecX src, vecX shift) %{
11275   predicate(n->as_Vector()->length() == 8 && !n->as_ShiftV()->is_var_shift());
11276   match(Set dst (RShiftVS src shift));
11277   size(4);
11278   ins_cost(DEFAULT_COST); // FIXME
11279   expand %{
11280     vsha8S_reg(dst, src, shift);
11281   %}
11282 %}
11283 
11284 instruct vsra8S_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
11285   predicate(n->as_Vector()->length() == 8 && n->as_ShiftV()->is_var_shift());
11286   match(Set dst (RShiftVS src shift));
11287   effect(TEMP tmp);
11288   size(4*2);
11289   ins_cost(DEFAULT_COST*2);
11290   format %{
11291     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
11292     "VSHL.S16 $dst.Q,$src.Q,$tmp.Q\t! arithmetic right shift packed8S"
11293   %}
11294   ins_encode %{
11295     bool quad = true;
11296     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11297              MacroAssembler::VELEM_SIZE_8, quad);
11298     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11299               MacroAssembler::VELEM_SIZE_16, quad);
11300   %}
11301   ins_pipe(ialu_reg_reg);
11302 %}
11303 
11304 instruct vsra4S_immI(vecD dst, vecD src, immI shift) %{
11305   predicate(n->as_Vector()->length() == 4 && assert_not_var_shift(n));
11306   match(Set dst (RShiftVS src (RShiftCntV shift)));
11307   size(4);
11308   ins_cost(DEFAULT_COST); // FIXME
11309   format %{
11310     "VSHR.S16 $dst.D,$src.D,$shift\t! arithmetic right shift packed4S"
11311   %}
11312   ins_encode %{
11313     bool quad = false;
11314     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
11315              quad);
11316   %}
11317   ins_pipe( ialu_reg_reg ); // FIXME
11318 %}
11319 
11320 instruct vsra8S_immI(vecX dst, vecX src, immI shift) %{
11321   predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n));
11322   match(Set dst (RShiftVS src (RShiftCntV shift)));
11323   size(4);
11324   ins_cost(DEFAULT_COST); // FIXME
11325   format %{
11326     "VSHR.S16 $dst.Q,$src.Q,$shift\t! arithmetic right shift packed8S"
11327   %}
11328   ins_encode %{
11329     bool quad = true;
11330     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
11331              quad);
11332   %}
11333   ins_pipe( ialu_reg_reg ); // FIXME
11334 %}
11335 
11336 // Integers vector arithmetic right shift
11337 instruct vsra2I_reg(vecD dst, vecD src, vecD shift) %{
11338   predicate(n->as_Vector()->length() == 2 && !n->as_ShiftV()->is_var_shift());
11339   match(Set dst (RShiftVI src shift));
11340   size(4);
11341   ins_cost(DEFAULT_COST); // FIXME
11342   expand %{
11343     vsha2I_reg(dst, src, shift);
11344   %}
11345 %}
11346 
11347 instruct vsra2I_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{
11348   predicate(n->as_Vector()->length() == 2 && n->as_ShiftV()->is_var_shift());
11349   match(Set dst (RShiftVI src shift));
11350   effect(TEMP tmp);
11351   size(4*2);
11352   ins_cost(DEFAULT_COST*2);
11353   format %{
11354     "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B"
11355     "VSHL.S32 $dst.D,$src.D,$tmp.D\t! arithmetic right shift packed2I"
11356   %}
11357   ins_encode %{
11358     bool quad = false;
11359     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11360              MacroAssembler::VELEM_SIZE_8, quad);
11361     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11362               MacroAssembler::VELEM_SIZE_32, quad);
11363   %}
11364   ins_pipe(ialu_reg_reg);
11365 %}
11366 
11367 instruct vsra4I_reg(vecX dst, vecX src, vecX shift) %{
11368   predicate(n->as_Vector()->length() == 4 && !n->as_ShiftV()->is_var_shift());
11369   match(Set dst (RShiftVI src shift));
11370   size(4);
11371   ins_cost(DEFAULT_COST); // FIXME
11372   expand %{
11373     vsha4I_reg(dst, src, shift);
11374   %}
11375 %}
11376 
11377 instruct vsra4I_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
11378   predicate(n->as_Vector()->length() == 4 && n->as_ShiftV()->is_var_shift());
11379   match(Set dst (RShiftVI src shift));
11380   effect(TEMP tmp);
11381   size(4*2);
11382   ins_cost(DEFAULT_COST*2);
11383   format %{
11384     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
11385     "VSHL.S32 $dst.Q,$src.Q,$tmp.Q\t! arithmetic right shift packed4I"
11386   %}
11387   ins_encode %{
11388     bool quad = true;
11389     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11390              MacroAssembler::VELEM_SIZE_8, quad);
11391     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11392               MacroAssembler::VELEM_SIZE_32, quad);
11393   %}
11394   ins_pipe(ialu_reg_reg);
11395 %}
11396 
11397 instruct vsra2I_immI(vecD dst, vecD src, immI shift) %{
11398   predicate(n->as_Vector()->length() == 2 && assert_not_var_shift(n));
11399   match(Set dst (RShiftVI src (RShiftCntV shift)));
11400   size(4);
11401   ins_cost(DEFAULT_COST); // FIXME
11402   format %{
11403     "VSHR.S32 $dst.D,$src.D,$shift\t! arithmetic right shift packed2I"
11404   %}
11405   ins_encode %{
11406     bool quad = false;
11407     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11408              quad);
11409   %}
11410   ins_pipe( ialu_reg_reg ); // FIXME
11411 %}
11412 
11413 instruct vsra4I_immI(vecX dst, vecX src, immI shift) %{
11414   predicate(n->as_Vector()->length() == 4 && assert_not_var_shift(n));
11415   match(Set dst (RShiftVI src (RShiftCntV shift)));
11416   size(4);
11417   ins_cost(DEFAULT_COST); // FIXME
11418   format %{
11419     "VSHR.S32 $dst.Q,$src.Q,$shift\t! arithmetic right shift packed4I"
11420   %}
11421   ins_encode %{
11422     bool quad = true;
11423     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11424              quad);
11425   %}
11426   ins_pipe( ialu_reg_reg ); // FIXME
11427 %}
11428 
11429 // Longs vector arithmetic right shift
11430 instruct vsra2L_reg(vecX dst, vecX src, vecX shift) %{
11431   predicate(n->as_Vector()->length() == 2 && !n->as_ShiftV()->is_var_shift());
11432   match(Set dst (RShiftVL src shift));
11433   size(4);
11434   ins_cost(DEFAULT_COST); // FIXME
11435   expand %{
11436     vsha2L_reg(dst, src, shift);
11437   %}
11438 %}
11439 
11440 instruct vsra2L_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
11441   predicate(n->as_Vector()->length() == 2 && n->as_ShiftV()->is_var_shift());
11442   match(Set dst (RShiftVL src shift));
11443   effect(TEMP tmp);
11444   size(4*2);
11445   ins_cost(DEFAULT_COST*2);
11446   format %{
11447     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
11448     "VSHL.S64 $dst.Q,$src.Q,$tmp.Q\t! arithmetic right shift packed2L"
11449   %}
11450   ins_encode %{
11451     bool quad = true;
11452     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11453              MacroAssembler::VELEM_SIZE_8, quad);
11454     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11455               MacroAssembler::VELEM_SIZE_64, quad);
11456   %}
11457   ins_pipe(ialu_reg_reg);
11458 %}
11459 
11460 instruct vsra2L_immI(vecX dst, vecX src, immI shift) %{
11461   predicate(n->as_Vector()->length() == 2 && assert_not_var_shift(n));
11462   match(Set dst (RShiftVL src (RShiftCntV shift)));
11463   size(4);
11464   ins_cost(DEFAULT_COST); // FIXME
11465   format %{
11466     "VSHR.S64 $dst.Q,$src.Q,$shift\t! arithmetic right shift packed2L"
11467   %}
11468   ins_encode %{
11469     bool quad = true;
11470     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
11471              quad);
11472   %}
11473   ins_pipe( ialu_reg_reg ); // FIXME
11474 %}
11475 
11476 // --------------------------------- AND --------------------------------------
11477 
11478 instruct vandD(vecD dst, vecD src1, vecD src2) %{
11479   predicate(n->as_Vector()->length_in_bytes() == 8);
11480   match(Set dst (AndV src1 src2));
11481   format %{ "VAND    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11482   ins_encode %{
11483     bool quad = false;
11484     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11485              quad);
11486   %}
11487   ins_pipe( ialu_reg_reg ); // FIXME
11488 %}
11489 
11490 instruct vandX(vecX dst, vecX src1, vecX src2) %{
11491   predicate(n->as_Vector()->length_in_bytes() == 16);
11492   match(Set dst (AndV src1 src2));
11493   format %{ "VAND    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11494   ins_encode %{
11495     bool quad = true;
11496     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11497              quad);
11498   %}
11499   ins_pipe( ialu_reg_reg ); // FIXME
11500 %}
11501 
11502 // --------------------------------- OR ---------------------------------------
11503 
11504 instruct vorD(vecD dst, vecD src1, vecD src2) %{
11505   predicate(n->as_Vector()->length_in_bytes() == 8);
11506   match(Set dst (OrV src1 src2));
11507   format %{ "VOR     $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11508   ins_encode %{
11509     bool quad = false;
11510     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11511             quad);
11512   %}
11513   ins_pipe( ialu_reg_reg ); // FIXME
11514 %}
11515 
11516 instruct vorX(vecX dst, vecX src1, vecX src2) %{
11517   predicate(n->as_Vector()->length_in_bytes() == 16);
11518   match(Set dst (OrV src1 src2));
11519   format %{ "VOR     $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11520   ins_encode %{
11521     bool quad = true;
11522     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11523             quad);
11524   %}
11525   ins_pipe( ialu_reg_reg ); // FIXME
11526 %}
11527 
11528 // --------------------------------- XOR --------------------------------------
11529 
11530 instruct vxorD(vecD dst, vecD src1, vecD src2) %{
11531   predicate(n->as_Vector()->length_in_bytes() == 8);
11532   match(Set dst (XorV src1 src2));
11533   format %{ "VXOR    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11534   ins_encode %{
11535     bool quad = false;
11536     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11537              quad);
11538   %}
11539   ins_pipe( ialu_reg_reg ); // FIXME
11540 %}
11541 
11542 instruct vxorX(vecX dst, vecX src1, vecX src2) %{
11543   predicate(n->as_Vector()->length_in_bytes() == 16);
11544   match(Set dst (XorV src1 src2));
11545   format %{ "VXOR    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11546   ins_encode %{
11547     bool quad = true;
11548     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11549              quad);
11550   %}
11551   ins_pipe( ialu_reg_reg ); // FIXME
11552 %}
11553 
11554 
11555 //----------PEEPHOLE RULES-----------------------------------------------------
11556 // These must follow all instruction definitions as they use the names
11557 // defined in the instructions definitions.
11558 //
11559 // peepmatch ( root_instr_name [preceding_instruction]* );
11560 //
11561 // peepconstraint %{
11562 // (instruction_number.operand_name relational_op instruction_number.operand_name
11563 //  [, ...] );
11564 // // instruction numbers are zero-based using left to right order in peepmatch
11565 //
11566 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
11567 // // provide an instruction_number.operand_name for each operand that appears
11568 // // in the replacement instruction's match rule
11569 //
11570 // ---------VM FLAGS---------------------------------------------------------
11571 //
11572 // All peephole optimizations can be turned off using -XX:-OptoPeephole
11573 //
11574 // Each peephole rule is given an identifying number starting with zero and
11575 // increasing by one in the order seen by the parser.  An individual peephole
11576 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
11577 // on the command-line.
11578 //
11579 // ---------CURRENT LIMITATIONS----------------------------------------------
11580 //
11581 // Only match adjacent instructions in same basic block
11582 // Only equality constraints
11583 // Only constraints between operands, not (0.dest_reg == EAX_enc)
11584 // Only one replacement instruction
11585 //
11586 // ---------EXAMPLE----------------------------------------------------------
11587 //
11588 // // pertinent parts of existing instructions in architecture description
11589 // instruct movI(eRegI dst, eRegI src) %{
11590 //   match(Set dst (CopyI src));
11591 // %}
11592 //
11593 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
11594 //   match(Set dst (AddI dst src));
11595 //   effect(KILL cr);
11596 // %}
11597 //
11598 // // Change (inc mov) to lea
11599 // peephole %{
11600 //   // increment preceded by register-register move
11601 //   peepmatch ( incI_eReg movI );
11602 //   // require that the destination register of the increment
11603 //   // match the destination register of the move
11604 //   peepconstraint ( 0.dst == 1.dst );
11605 //   // construct a replacement instruction that sets
11606 //   // the destination to ( move's source register + one )
11607 //   peepreplace ( incI_eReg_immI1( 0.dst 1.src 0.src ) );
11608 // %}
11609 //
11610 
11611 // // Change load of spilled value to only a spill
11612 // instruct storeI(memory mem, eRegI src) %{
11613 //   match(Set mem (StoreI mem src));
11614 // %}
11615 //
11616 // instruct loadI(eRegI dst, memory mem) %{
11617 //   match(Set dst (LoadI mem));
11618 // %}
11619 //
11620 // peephole %{
11621 //   peepmatch ( loadI storeI );
11622 //   peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
11623 //   peepreplace ( storeI( 1.mem 1.mem 1.src ) );
11624 // %}
11625 
11626 //----------SMARTSPILL RULES---------------------------------------------------
11627 // These must follow all instruction definitions as they use the names
11628 // defined in the instructions definitions.
11629 //
11630 // ARM will probably not have any of these rules due to RISC instruction set.
11631 
11632 //----------PIPELINE-----------------------------------------------------------
11633 // Rules which define the behavior of the target architectures pipeline.