1 //
    2 // Copyright (c) 2008, 2025, 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_exception_handler(C2_MacroAssembler *masm);
  109   static int emit_deopt_handler(C2_MacroAssembler* masm);
  110 
  111   static uint size_exception_handler() {
  112     return ( 3 * 4 );
  113   }
  114 
  115 
  116   static uint size_deopt_handler() {
  117     return ( 9 * 4 );
  118   }
  119 
  120 };
  121 
  122 class Node::PD {
  123 public:
  124   enum NodeFlags {
  125     _last_flag = Node::_last_flag
  126   };
  127 };
  128 
  129 // Assert that the given node is not a var shift.
  130 bool assert_not_var_shift(const Node *n);
  131 %}
  132 
  133 source %{
  134 
  135 // Assert that the given node is not a var shift.
  136 bool assert_not_var_shift(const Node *n) {
  137   assert(!n->as_ShiftV()->is_var_shift(), "illegal var shift");
  138   return true;
  139 }
  140 
  141 #define __ masm->
  142 
  143 static FloatRegister reg_to_FloatRegister_object(int register_encoding);
  144 static Register reg_to_register_object(int register_encoding);
  145 
  146 void PhaseOutput::pd_perform_mach_node_analysis() {
  147 }
  148 
  149 int MachNode::pd_alignment_required() const {
  150   return 1;
  151 }
  152 
  153 int MachNode::compute_padding(int current_offset) const {
  154   return 0;
  155 }
  156 
  157 // ****************************************************************************
  158 
  159 // REQUIRED FUNCTIONALITY
  160 
  161 // emit an interrupt that is caught by the debugger (for debugging compiler)
  162 void emit_break(C2_MacroAssembler *masm) {
  163   __ breakpoint();
  164 }
  165 
  166 #ifndef PRODUCT
  167 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream *st ) const {
  168   st->print("TA");
  169 }
  170 #endif
  171 
  172 void MachBreakpointNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
  173   emit_break(masm);
  174 }
  175 
  176 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
  177   return MachNode::size(ra_);
  178 }
  179 
  180 
  181 void emit_nop(C2_MacroAssembler *masm) {
  182   __ nop();
  183 }
  184 
  185 
  186 void emit_call_reloc(C2_MacroAssembler *masm, const MachCallNode *n, MachOper *m, RelocationHolder const& rspec) {
  187   int ret_addr_offset0 = n->as_MachCall()->ret_addr_offset();
  188   int call_site_offset = __ code()->insts()->mark_off();
  189   __ set_inst_mark(); // needed in emit_to_interp_stub() to locate the call
  190   address target = (address)m->method();
  191   assert(n->as_MachCall()->entry_point() == target, "sanity");
  192   assert(maybe_far_call(n) == !__ reachable_from_cache(target), "sanity");
  193   assert(cache_reachable() == __ cache_fully_reachable(), "sanity");
  194 
  195   assert(target != nullptr, "need real address");
  196 
  197   int ret_addr_offset = -1;
  198   if (rspec.type() == relocInfo::runtime_call_type) {
  199     __ call(target, rspec);
  200     ret_addr_offset = __ offset();
  201   } else {
  202     // scratches Rtemp
  203     ret_addr_offset = __ patchable_call(target, rspec, true);
  204   }
  205   assert(ret_addr_offset - call_site_offset == ret_addr_offset0, "fix ret_addr_offset()");
  206 }
  207 
  208 //=============================================================================
  209 // REQUIRED FUNCTIONALITY for encoding
  210 void emit_lo(C2_MacroAssembler *masm, int val) {  }
  211 void emit_hi(C2_MacroAssembler *masm, int val) {  }
  212 
  213 
  214 //=============================================================================
  215 const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask();
  216 
  217 int ConstantTable::calculate_table_base_offset() const {
  218   int offset = -(size() / 2);
  219   // flds, fldd: 8-bit  offset multiplied by 4: +/- 1024
  220   // ldr, ldrb : 12-bit offset:                 +/- 4096
  221   if (!Assembler::is_simm10(offset)) {
  222     offset = Assembler::min_simm10;
  223   }
  224   return offset;
  225 }
  226 
  227 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
  228 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
  229   ShouldNotReachHere();
  230 }
  231 
  232 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const {
  233   Compile* C = ra_->C;
  234   ConstantTable& constant_table = C->output()->constant_table();
  235 
  236   Register r = as_Register(ra_->get_encode(this));
  237   CodeSection* consts_section = __ code()->consts();
  238   CodeSection* insts_section = __ code()->insts();
  239   // constants section size is aligned according to the align_at_start settings of the next section
  240   int consts_size = insts_section->align_at_start(consts_section->size());
  241   assert(constant_table.size() == consts_size, "must be: %d == %d", constant_table.size(), consts_size);
  242 
  243   // Materialize the constant table base.
  244   address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
  245   RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
  246   __ mov_address(r, baseaddr, rspec);
  247 }
  248 
  249 uint MachConstantBaseNode::size(PhaseRegAlloc*) const {
  250   return 8;
  251 }
  252 
  253 #ifndef PRODUCT
  254 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
  255   char reg[128];
  256   ra_->dump_register(this, reg, sizeof(reg));
  257   st->print("MOV_SLOW    &constanttable,%s\t! constant table base", reg);
  258 }
  259 #endif
  260 
  261 #ifndef PRODUCT
  262 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  263   Compile* C = ra_->C;
  264 
  265   for (int i = 0; i < OptoPrologueNops; i++) {
  266     st->print_cr("NOP"); st->print("\t");
  267   }
  268 
  269   size_t framesize = C->output()->frame_size_in_bytes();
  270   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  271   int bangsize = C->output()->bang_size_in_bytes();
  272   // Remove two words for return addr and rbp,
  273   framesize -= 2*wordSize;
  274   bangsize -= 2*wordSize;
  275 
  276   // Calls to C2R adapters often do not accept exceptional returns.
  277   // We require that their callers must bang for them.  But be careful, because
  278   // some VM calls (such as call site linkage) can use several kilobytes of
  279   // stack.  But the stack safety zone should account for that.
  280   // See bugs 4446381, 4468289, 4497237.
  281   if (C->output()->need_stack_bang(bangsize)) {
  282     st->print_cr("! stack bang (%d bytes)", bangsize); st->print("\t");
  283   }
  284   st->print_cr("PUSH   R_FP|R_LR_LR"); st->print("\t");
  285   if (framesize != 0) {
  286     st->print   ("SUB    R_SP, R_SP, %zu", framesize);
  287   }
  288 
  289   if (C->stub_function() == nullptr) {
  290     st->print("ldr t0, [guard]\n\t");
  291     st->print("ldr t1, [Rthread, #thread_disarmed_guard_value_offset]\n\t");
  292     st->print("cmp t0, t1\n\t");
  293     st->print("beq skip\n\t");
  294     st->print("blr #nmethod_entry_barrier_stub\n\t");
  295     st->print("b skip\n\t");
  296     st->print("guard: int\n\t");
  297     st->print("skip:\n\t");
  298   }
  299 }
  300 #endif
  301 
  302 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
  303   Compile* C = ra_->C;
  304 
  305   for (int i = 0; i < OptoPrologueNops; i++) {
  306     __ nop();
  307   }
  308 
  309   size_t framesize = C->output()->frame_size_in_bytes();
  310   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  311   int bangsize = C->output()->bang_size_in_bytes();
  312   // Remove two words for return addr and fp,
  313   framesize -= 2*wordSize;
  314   bangsize -= 2*wordSize;
  315 
  316   // Calls to C2R adapters often do not accept exceptional returns.
  317   // We require that their callers must bang for them.  But be careful, because
  318   // some VM calls (such as call site linkage) can use several kilobytes of
  319   // stack.  But the stack safety zone should account for that.
  320   // See bugs 4446381, 4468289, 4497237.
  321   if (C->output()->need_stack_bang(bangsize)) {
  322     __ arm_stack_overflow_check(bangsize, Rtemp);
  323   }
  324 
  325   __ raw_push(FP, LR);
  326   if (framesize != 0) {
  327     __ sub_slow(SP, SP, framesize);
  328   }
  329 
  330   if (C->stub_function() == nullptr) {
  331     BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
  332     bs->nmethod_entry_barrier(masm);
  333   }
  334 
  335   // offset from scratch buffer is not valid
  336   if (strcmp(__ code()->name(), "Compile::Fill_buffer") == 0) {
  337     C->output()->set_frame_complete( __ offset() );
  338   }
  339 
  340   if (C->has_mach_constant_base_node()) {
  341     // NOTE: We set the table base offset here because users might be
  342     // emitted before MachConstantBaseNode.
  343     ConstantTable& constant_table = C->output()->constant_table();
  344     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
  345   }
  346 }
  347 
  348 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
  349   return MachNode::size(ra_);
  350 }
  351 
  352 int MachPrologNode::reloc() const {
  353   return 10; // a large enough number
  354 }
  355 
  356 //=============================================================================
  357 #ifndef PRODUCT
  358 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  359   Compile* C = ra_->C;
  360 
  361   size_t framesize = C->output()->frame_size_in_bytes();
  362   framesize -= 2*wordSize;
  363 
  364   if (framesize != 0) {
  365     st->print("ADD    R_SP, R_SP, %zu\n\t",framesize);
  366   }
  367   st->print("POP    R_FP|R_LR_LR");
  368 
  369   if (do_polling() && ra_->C->is_method_compilation()) {
  370     st->print("\n\t");
  371     st->print("MOV    Rtemp, #PollAddr\t! Load Polling address\n\t");
  372     st->print("LDR    Rtemp,[Rtemp]\t!Poll for Safepointing");
  373   }
  374 }
  375 #endif
  376 
  377 void MachEpilogNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
  378   Compile* C = ra_->C;
  379 
  380   size_t framesize = C->output()->frame_size_in_bytes();
  381   framesize -= 2*wordSize;
  382   if (framesize != 0) {
  383     __ add_slow(SP, SP, framesize);
  384   }
  385   __ raw_pop(FP, LR);
  386 
  387   // If this does safepoint polling, then do it here
  388   if (do_polling() && ra_->C->is_method_compilation()) {
  389     __ read_polling_page(Rtemp, relocInfo::poll_return_type);
  390   }
  391 }
  392 
  393 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
  394   return MachNode::size(ra_);
  395 }
  396 
  397 int MachEpilogNode::reloc() const {
  398   return 16; // a large enough number
  399 }
  400 
  401 const Pipeline * MachEpilogNode::pipeline() const {
  402   return MachNode::pipeline_class();
  403 }
  404 
  405 //=============================================================================
  406 
  407 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
  408 enum RC { rc_bad, rc_int, rc_float, rc_stack };
  409 static enum RC rc_class( OptoReg::Name reg ) {
  410   if (!OptoReg::is_valid(reg)) return rc_bad;
  411   if (OptoReg::is_stack(reg)) return rc_stack;
  412   VMReg r = OptoReg::as_VMReg(reg);
  413   if (r->is_Register()) return rc_int;
  414   assert(r->is_FloatRegister(), "must be");
  415   return rc_float;
  416 }
  417 
  418 static inline bool is_iRegLd_memhd(OptoReg::Name src_first, OptoReg::Name src_second, int offset) {
  419   int rlo = Matcher::_regEncode[src_first];
  420   int rhi = Matcher::_regEncode[src_second];
  421   if (!((rlo&1)==0 && (rlo+1 == rhi))) {
  422     tty->print_cr("CAUGHT BAD LDRD/STRD");
  423   }
  424   return (rlo&1)==0 && (rlo+1 == rhi) && is_memoryHD(offset);
  425 }
  426 
  427 uint MachSpillCopyNode::implementation( C2_MacroAssembler *masm,
  428                                         PhaseRegAlloc *ra_,
  429                                         bool do_size,
  430                                         outputStream* st ) const {
  431   // Get registers to move
  432   OptoReg::Name src_second = ra_->get_reg_second(in(1));
  433   OptoReg::Name src_first = ra_->get_reg_first(in(1));
  434   OptoReg::Name dst_second = ra_->get_reg_second(this );
  435   OptoReg::Name dst_first = ra_->get_reg_first(this );
  436 
  437   enum RC src_second_rc = rc_class(src_second);
  438   enum RC src_first_rc = rc_class(src_first);
  439   enum RC dst_second_rc = rc_class(dst_second);
  440   enum RC dst_first_rc = rc_class(dst_first);
  441 
  442   assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
  443 
  444   // Generate spill code!
  445   int size = 0;
  446 
  447   if (src_first == dst_first && src_second == dst_second)
  448     return size;            // Self copy, no move
  449 
  450 #ifdef TODO
  451   if (bottom_type()->isa_vect() != nullptr) {
  452   }
  453 #endif
  454 
  455   // Shared code does not expect instruction set capability based bailouts here.
  456   // Handle offset unreachable bailout with minimal change in shared code.
  457   // Bailout only for real instruction emit.
  458   // This requires a single comment change in shared code. ( see output.cpp "Normal" instruction case )
  459 
  460   // --------------------------------------
  461   // Check for mem-mem move.  Load into unused float registers and fall into
  462   // the float-store case.
  463   if (src_first_rc == rc_stack && dst_first_rc == rc_stack) {
  464     int offset = ra_->reg2offset(src_first);
  465     if (masm && !is_memoryfp(offset)) {
  466       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  467       return 0;
  468     } else {
  469       if (src_second_rc != rc_bad) {
  470         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
  471         src_first     = OptoReg::Name(R_mem_copy_lo_num);
  472         src_second    = OptoReg::Name(R_mem_copy_hi_num);
  473         src_first_rc  = rc_float;
  474         src_second_rc = rc_float;
  475         if (masm) {
  476           __ ldr_double(Rmemcopy, Address(SP, offset));
  477         } else if (!do_size) {
  478           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  479         }
  480       } else {
  481         src_first     = OptoReg::Name(R_mem_copy_lo_num);
  482         src_first_rc  = rc_float;
  483         if (masm) {
  484           __ ldr_float(Rmemcopy, Address(SP, offset));
  485         } else if (!do_size) {
  486           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  487         }
  488       }
  489       size += 4;
  490     }
  491   }
  492 
  493   if (src_second_rc == rc_stack && dst_second_rc == rc_stack) {
  494     Unimplemented();
  495   }
  496 
  497   // --------------------------------------
  498   // Check for integer reg-reg copy
  499   if (src_first_rc == rc_int && dst_first_rc == rc_int) {
  500     // Else normal reg-reg copy
  501     assert( src_second != dst_first, "smashed second before evacuating it" );
  502     if (masm) {
  503       __ mov(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
  504 #ifndef PRODUCT
  505     } else if (!do_size) {
  506       st->print("MOV    R_%s, R_%s\t# spill",
  507                 Matcher::regName[dst_first],
  508                 Matcher::regName[src_first]);
  509 #endif
  510     }
  511     size += 4;
  512   }
  513 
  514   // Check for integer store
  515   if (src_first_rc == rc_int && dst_first_rc == rc_stack) {
  516     int offset = ra_->reg2offset(dst_first);
  517     if (masm && !is_memoryI(offset)) {
  518       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  519       return 0;
  520     } else {
  521       if (src_second_rc != rc_bad && is_iRegLd_memhd(src_first, src_second, offset)) {
  522         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
  523         if (masm) {
  524           __ str_64(reg_to_register_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  525 #ifndef PRODUCT
  526         } else if (!do_size) {
  527           if (size != 0) st->print("\n\t");
  528           st->print(STR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
  529 #endif
  530         }
  531         return size + 4;
  532       } else {
  533         if (masm) {
  534           __ str_32(reg_to_register_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  535 #ifndef PRODUCT
  536         } else if (!do_size) {
  537           if (size != 0) st->print("\n\t");
  538           st->print(STR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
  539 #endif
  540         }
  541       }
  542     }
  543     size += 4;
  544   }
  545 
  546   // Check for integer load
  547   if (dst_first_rc == rc_int && src_first_rc == rc_stack) {
  548     int offset = ra_->reg2offset(src_first);
  549     if (masm && !is_memoryI(offset)) {
  550       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  551       return 0;
  552     } else {
  553       if (src_second_rc != rc_bad && is_iRegLd_memhd(dst_first, dst_second, offset)) {
  554         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
  555         if (masm) {
  556           __ ldr_64(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  557 #ifndef PRODUCT
  558         } else if (!do_size) {
  559           if (size != 0) st->print("\n\t");
  560           st->print(LDR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
  561 #endif
  562         }
  563         return size + 4;
  564       } else {
  565         if (masm) {
  566           __ ldr_32(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  567 #ifndef PRODUCT
  568         } else if (!do_size) {
  569           if (size != 0) st->print("\n\t");
  570           st->print(LDR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
  571 #endif
  572         }
  573       }
  574     }
  575     size += 4;
  576   }
  577 
  578   // Check for float reg-reg copy
  579   if (src_first_rc == rc_float && dst_first_rc == rc_float) {
  580     if (src_second_rc != rc_bad) {
  581       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");
  582       if (masm) {
  583       __ mov_double(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
  584 #ifndef PRODUCT
  585       } else if (!do_size) {
  586         st->print(MOV_DOUBLE "    R_%s, R_%s\t# spill",
  587                   Matcher::regName[dst_first],
  588                   Matcher::regName[src_first]);
  589 #endif
  590       }
  591       return 4;
  592     }
  593     if (masm) {
  594       __ mov_float(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
  595 #ifndef PRODUCT
  596     } else if (!do_size) {
  597       st->print(MOV_FLOAT "    R_%s, R_%s\t# spill",
  598                 Matcher::regName[dst_first],
  599                 Matcher::regName[src_first]);
  600 #endif
  601     }
  602     size = 4;
  603   }
  604 
  605   // Check for float store
  606   if (src_first_rc == rc_float && dst_first_rc == rc_stack) {
  607     int offset = ra_->reg2offset(dst_first);
  608     if (masm && !is_memoryfp(offset)) {
  609       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  610       return 0;
  611     } else {
  612       // Further check for aligned-adjacent pair, so we can use a double store
  613       if (src_second_rc != rc_bad) {
  614         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");
  615         if (masm) {
  616           __ str_double(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  617 #ifndef PRODUCT
  618         } else if (!do_size) {
  619           if (size != 0) st->print("\n\t");
  620           st->print(STR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  621 #endif
  622         }
  623         return size + 4;
  624       } else {
  625         if (masm) {
  626           __ str_float(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  627 #ifndef PRODUCT
  628         } else if (!do_size) {
  629           if (size != 0) st->print("\n\t");
  630           st->print(STR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  631 #endif
  632         }
  633       }
  634     }
  635     size += 4;
  636   }
  637 
  638   // Check for float load
  639   if (dst_first_rc == rc_float && src_first_rc == rc_stack) {
  640     int offset = ra_->reg2offset(src_first);
  641     if (masm && !is_memoryfp(offset)) {
  642       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  643       return 0;
  644     } else {
  645       // Further check for aligned-adjacent pair, so we can use a double store
  646       if (src_second_rc != rc_bad) {
  647         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");
  648         if (masm) {
  649           __ ldr_double(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  650 #ifndef PRODUCT
  651         } else if (!do_size) {
  652           if (size != 0) st->print("\n\t");
  653           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
  654 #endif
  655         }
  656         return size + 4;
  657       } else {
  658         if (masm) {
  659           __ ldr_float(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  660 #ifndef PRODUCT
  661         } else if (!do_size) {
  662           if (size != 0) st->print("\n\t");
  663           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
  664 #endif
  665         }
  666       }
  667     }
  668     size += 4;
  669   }
  670 
  671   // check for int reg -> float reg move
  672   if (src_first_rc == rc_int && dst_first_rc == rc_float) {
  673     // Further check for aligned-adjacent pair, so we can use a single instruction
  674     if (src_second_rc != rc_bad) {
  675       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
  676       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
  677       assert(src_second_rc == rc_int && dst_second_rc == rc_float, "unsupported");
  678       if (masm) {
  679         __ 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]));
  680 #ifndef PRODUCT
  681       } else if (!do_size) {
  682         if (size != 0) st->print("\n\t");
  683         st->print("FMDRR   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first), OptoReg::regname(src_second));
  684 #endif
  685       }
  686       return size + 4;
  687     } else {
  688       if (masm) {
  689         __ fmsr(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
  690 #ifndef PRODUCT
  691       } else if (!do_size) {
  692         if (size != 0) st->print("\n\t");
  693         st->print(FMSR "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
  694 #endif
  695       }
  696       size += 4;
  697     }
  698   }
  699 
  700   // check for float reg -> int reg move
  701   if (src_first_rc == rc_float && dst_first_rc == rc_int) {
  702     // Further check for aligned-adjacent pair, so we can use a single instruction
  703     if (src_second_rc != rc_bad) {
  704       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
  705       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
  706       assert(src_second_rc == rc_float && dst_second_rc == rc_int, "unsupported");
  707       if (masm) {
  708         __ 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]));
  709 #ifndef PRODUCT
  710       } else if (!do_size) {
  711         if (size != 0) st->print("\n\t");
  712         st->print("FMRRD   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(dst_second), OptoReg::regname(src_first));
  713 #endif
  714       }
  715       return size + 4;
  716     } else {
  717       if (masm) {
  718         __ fmrs(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
  719 #ifndef PRODUCT
  720       } else if (!do_size) {
  721         if (size != 0) st->print("\n\t");
  722         st->print(FMRS "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
  723 #endif
  724       }
  725       size += 4;
  726     }
  727   }
  728 
  729   // --------------------------------------------------------------------
  730   // Check for hi bits still needing moving.  Only happens for misaligned
  731   // arguments to native calls.
  732   if (src_second == dst_second)
  733     return size;               // Self copy; no move
  734   assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" );
  735 
  736   // Check for integer reg-reg copy.  Hi bits are stuck up in the top
  737   // 32-bits of a 64-bit register, but are needed in low bits of another
  738   // register (else it's a hi-bits-to-hi-bits copy which should have
  739   // happened already as part of a 64-bit move)
  740   if (src_second_rc == rc_int && dst_second_rc == rc_int) {
  741     if (masm) {
  742       __ mov(reg_to_register_object(Matcher::_regEncode[dst_second]), reg_to_register_object(Matcher::_regEncode[src_second]));
  743 #ifndef PRODUCT
  744     } else if (!do_size) {
  745       if (size != 0) st->print("\n\t");
  746       st->print("MOV    R_%s, R_%s\t# spill high",
  747                 Matcher::regName[dst_second],
  748                 Matcher::regName[src_second]);
  749 #endif
  750     }
  751     return size+4;
  752   }
  753 
  754   // Check for high word integer store
  755   if (src_second_rc == rc_int && dst_second_rc == rc_stack) {
  756     int offset = ra_->reg2offset(dst_second);
  757 
  758     if (masm && !is_memoryP(offset)) {
  759       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  760       return 0;
  761     } else {
  762       if (masm) {
  763         __ str(reg_to_register_object(Matcher::_regEncode[src_second]), Address(SP, offset));
  764 #ifndef PRODUCT
  765       } else if (!do_size) {
  766         if (size != 0) st->print("\n\t");
  767         st->print("STR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_second), offset);
  768 #endif
  769       }
  770     }
  771     return size + 4;
  772   }
  773 
  774   // Check for high word integer load
  775   if (dst_second_rc == rc_int && src_second_rc == rc_stack) {
  776     int offset = ra_->reg2offset(src_second);
  777     if (masm && !is_memoryP(offset)) {
  778       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  779       return 0;
  780     } else {
  781       if (masm) {
  782         __ ldr(reg_to_register_object(Matcher::_regEncode[dst_second]), Address(SP, offset));
  783 #ifndef PRODUCT
  784       } else if (!do_size) {
  785         if (size != 0) st->print("\n\t");
  786         st->print("LDR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_second), offset);
  787 #endif
  788       }
  789     }
  790     return size + 4;
  791   }
  792 
  793   Unimplemented();
  794   return 0; // Mute compiler
  795 }
  796 
  797 #ifndef PRODUCT
  798 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  799   implementation( nullptr, ra_, false, st );
  800 }
  801 #endif
  802 
  803 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
  804   implementation( masm, ra_, false, nullptr );
  805 }
  806 
  807 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
  808   return implementation( nullptr, ra_, true, nullptr );
  809 }
  810 
  811 //=============================================================================
  812 #ifndef PRODUCT
  813 void MachNopNode::format( PhaseRegAlloc *, outputStream *st ) const {
  814   st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
  815 }
  816 #endif
  817 
  818 void MachNopNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc * ) const {
  819   for(int i = 0; i < _count; i += 1) {
  820     __ nop();
  821   }
  822 }
  823 
  824 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
  825   return 4 * _count;
  826 }
  827 
  828 
  829 //=============================================================================
  830 #ifndef PRODUCT
  831 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  832   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  833   int reg = ra_->get_reg_first(this);
  834   st->print("ADD    %s,R_SP+#%d",Matcher::regName[reg], offset);
  835 }
  836 #endif
  837 
  838 void BoxLockNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
  839   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  840   int reg = ra_->get_encode(this);
  841   Register dst = reg_to_register_object(reg);
  842 
  843   if (is_aimm(offset)) {
  844     __ add(dst, SP, offset);
  845   } else {
  846     __ mov_slow(dst, offset);
  847     __ add(dst, SP, dst);
  848   }
  849 }
  850 
  851 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
  852   // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_)
  853   assert(ra_ == ra_->C->regalloc(), "sanity");
  854   return ra_->C->output()->scratch_emit_size(this);
  855 }
  856 
  857 //=============================================================================
  858 #ifndef PRODUCT
  859 #define R_RTEMP "R_R12"
  860 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  861   st->print_cr("\nUEP:");
  862   st->print_cr("\tLDR   " R_RTEMP ",[R_R0 + oopDesc::klass_offset_in_bytes]\t! Inline cache check");
  863   st->print_cr("\tCMP   " R_RTEMP ",R_R8" );
  864   st->print   ("\tB.NE  SharedRuntime::handle_ic_miss_stub");
  865 }
  866 #endif
  867 
  868 void MachUEPNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
  869   __ ic_check(InteriorEntryAlignment);
  870 }
  871 
  872 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
  873   return MachNode::size(ra_);
  874 }
  875 
  876 
  877 //=============================================================================
  878 
  879 // Emit exception handler code.
  880 int HandlerImpl::emit_exception_handler(C2_MacroAssembler* masm) {
  881   address base = __ start_a_stub(size_exception_handler());
  882   if (base == nullptr) {
  883     ciEnv::current()->record_failure("CodeCache is full");
  884     return 0;  // CodeBuffer::expand failed
  885   }
  886 
  887   int offset = __ offset();
  888 
  889   // OK to trash LR, because exception blob will kill it
  890   __ jump(OptoRuntime::exception_blob()->entry_point(), relocInfo::runtime_call_type, LR_tmp);
  891 
  892   assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
  893 
  894   __ end_a_stub();
  895 
  896   return offset;
  897 }
  898 
  899 int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm) {
  900   // Can't use any of the current frame's registers as we may have deopted
  901   // at a poll and everything can be live.
  902   address base = __ start_a_stub(size_deopt_handler());
  903   if (base == nullptr) {
  904     ciEnv::current()->record_failure("CodeCache is full");
  905     return 0;  // CodeBuffer::expand failed
  906   }
  907 
  908   int offset = __ offset();
  909   address deopt_pc = __ pc();
  910 
  911   __ sub(SP, SP, wordSize); // make room for saved PC
  912   __ push(LR); // save LR that may be live when we get here
  913   __ mov_relative_address(LR, deopt_pc);
  914   __ str(LR, Address(SP, wordSize)); // save deopt PC
  915   __ pop(LR); // restore LR
  916   __ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, noreg);
  917 
  918   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
  919 
  920   __ end_a_stub();
  921   return offset;
  922 }
  923 
  924 bool Matcher::match_rule_supported(int opcode) {
  925   if (!has_match_rule(opcode))
  926     return false;
  927 
  928   switch (opcode) {
  929   case Op_PopCountI:
  930   case Op_PopCountL:
  931     if (!UsePopCountInstruction)
  932       return false;
  933     break;
  934   case Op_LShiftCntV:
  935   case Op_RShiftCntV:
  936   case Op_AddVB:
  937   case Op_AddVS:
  938   case Op_AddVI:
  939   case Op_AddVL:
  940   case Op_SubVB:
  941   case Op_SubVS:
  942   case Op_SubVI:
  943   case Op_SubVL:
  944   case Op_MulVS:
  945   case Op_MulVI:
  946   case Op_LShiftVB:
  947   case Op_LShiftVS:
  948   case Op_LShiftVI:
  949   case Op_LShiftVL:
  950   case Op_RShiftVB:
  951   case Op_RShiftVS:
  952   case Op_RShiftVI:
  953   case Op_RShiftVL:
  954   case Op_URShiftVB:
  955   case Op_URShiftVS:
  956   case Op_URShiftVI:
  957   case Op_URShiftVL:
  958   case Op_AndV:
  959   case Op_OrV:
  960   case Op_XorV:
  961     return VM_Version::has_simd();
  962   case Op_LoadVector:
  963   case Op_StoreVector:
  964   case Op_AddVF:
  965   case Op_SubVF:
  966   case Op_MulVF:
  967     return VM_Version::has_vfp() || VM_Version::has_simd();
  968   case Op_AddVD:
  969   case Op_SubVD:
  970   case Op_MulVD:
  971   case Op_DivVF:
  972   case Op_DivVD:
  973     return VM_Version::has_vfp();
  974   }
  975 
  976   return true;  // Per default match rules are supported.
  977 }
  978 
  979 bool Matcher::match_rule_supported_auto_vectorization(int opcode, int vlen, BasicType bt) {
  980   return match_rule_supported_vector(opcode, vlen, bt);
  981 }
  982 
  983 bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
  984 
  985   // TODO
  986   // identify extra cases that we might want to provide match rules for
  987   // e.g. Op_ vector nodes and other intrinsics while guarding with vlen
  988   bool ret_value = match_rule_supported(opcode) && vector_size_supported(bt, vlen);
  989   // Add rules here.
  990 
  991   return ret_value;  // Per default match rules are supported.
  992 }
  993 
  994 bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType bt) {
  995   return false;
  996 }
  997 
  998 bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) {
  999   return false;
 1000 }
 1001 
 1002 bool Matcher::vector_rearrange_requires_load_shuffle(BasicType elem_bt, int vlen) {
 1003   return false;
 1004 }
 1005 
 1006 const RegMask* Matcher::predicate_reg_mask(void) {
 1007   return nullptr;
 1008 }
 1009 
 1010 // Vector calling convention not yet implemented.
 1011 bool Matcher::supports_vector_calling_convention(void) {
 1012   return false;
 1013 }
 1014 
 1015 OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
 1016   Unimplemented();
 1017   return OptoRegPair(0, 0);
 1018 }
 1019 
 1020 // Vector width in bytes
 1021 int Matcher::vector_width_in_bytes(BasicType bt) {
 1022   return MaxVectorSize;
 1023 }
 1024 
 1025 int Matcher::scalable_vector_reg_size(const BasicType bt) {
 1026   return -1;
 1027 }
 1028 
 1029 // Vector ideal reg corresponding to specified size in bytes
 1030 uint Matcher::vector_ideal_reg(int size) {
 1031   assert(MaxVectorSize >= size, "");
 1032   switch(size) {
 1033     case  8: return Op_VecD;
 1034     case 16: return Op_VecX;
 1035   }
 1036   ShouldNotReachHere();
 1037   return 0;
 1038 }
 1039 
 1040 // Limits on vector size (number of elements) loaded into vector.
 1041 int Matcher::max_vector_size(const BasicType bt) {
 1042   assert(is_java_primitive(bt), "only primitive type vectors");
 1043   return vector_width_in_bytes(bt)/type2aelembytes(bt);
 1044 }
 1045 
 1046 int Matcher::min_vector_size(const BasicType bt) {
 1047   assert(is_java_primitive(bt), "only primitive type vectors");
 1048   return 8/type2aelembytes(bt);
 1049 }
 1050 
 1051 int Matcher::max_vector_size_auto_vectorization(const BasicType bt) {
 1052   return Matcher::max_vector_size(bt);
 1053 }
 1054 
 1055 // Is this branch offset short enough that a short branch can be used?
 1056 //
 1057 // NOTE: If the platform does not provide any short branch variants, then
 1058 //       this method should return false for offset 0.
 1059 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
 1060   // The passed offset is relative to address of the branch.
 1061   // On ARM a branch displacement is calculated relative to address
 1062   // of the branch + 8.
 1063   //
 1064   // offset -= 8;
 1065   // return (Assembler::is_simm24(offset));
 1066   return false;
 1067 }
 1068 
 1069 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) {
 1070   ShouldNotReachHere(); // generic vector operands not supported
 1071   return nullptr;
 1072 }
 1073 
 1074 bool Matcher::is_reg2reg_move(MachNode* m) {
 1075   ShouldNotReachHere();  // generic vector operands not supported
 1076   return false;
 1077 }
 1078 
 1079 bool Matcher::is_generic_vector(MachOper* opnd)  {
 1080   ShouldNotReachHere();  // generic vector operands not supported
 1081   return false;
 1082 }
 1083 
 1084 // Should the matcher clone input 'm' of node 'n'?
 1085 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
 1086   if (is_vshift_con_pattern(n, m)) { // ShiftV src (ShiftCntV con)
 1087     mstack.push(m, Visit);           // m = ShiftCntV
 1088     return true;
 1089   }
 1090   return false;
 1091 }
 1092 
 1093 // Should the Matcher clone shifts on addressing modes, expecting them
 1094 // to be subsumed into complex addressing expressions or compute them
 1095 // into registers?
 1096 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
 1097   return clone_base_plus_offset_address(m, mstack, address_visited);
 1098 }
 1099 
 1100 // Return whether or not this register is ever used as an argument.  This
 1101 // function is used on startup to build the trampoline stubs in generateOptoStub.
 1102 // Registers not mentioned will be killed by the VM call in the trampoline, and
 1103 // arguments in those registers not be available to the callee.
 1104 bool Matcher::can_be_java_arg( int reg ) {
 1105   if (reg == R_R0_num ||
 1106       reg == R_R1_num ||
 1107       reg == R_R2_num ||
 1108       reg == R_R3_num) return true;
 1109 
 1110   if (reg >= R_S0_num &&
 1111       reg <= R_S13_num) return true;
 1112   return false;
 1113 }
 1114 
 1115 bool Matcher::is_spillable_arg( int reg ) {
 1116   return can_be_java_arg(reg);
 1117 }
 1118 
 1119 uint Matcher::int_pressure_limit()
 1120 {
 1121   return (INTPRESSURE == -1) ? 12 : INTPRESSURE;
 1122 }
 1123 
 1124 uint Matcher::float_pressure_limit()
 1125 {
 1126   return (FLOATPRESSURE == -1) ? 30 : FLOATPRESSURE;
 1127 }
 1128 
 1129 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
 1130   return false;
 1131 }
 1132 
 1133 // Register for DIVI projection of divmodI
 1134 RegMask Matcher::divI_proj_mask() {
 1135   ShouldNotReachHere();
 1136   return RegMask();
 1137 }
 1138 
 1139 // Register for MODI projection of divmodI
 1140 RegMask Matcher::modI_proj_mask() {
 1141   ShouldNotReachHere();
 1142   return RegMask();
 1143 }
 1144 
 1145 // Register for DIVL projection of divmodL
 1146 RegMask Matcher::divL_proj_mask() {
 1147   ShouldNotReachHere();
 1148   return RegMask();
 1149 }
 1150 
 1151 // Register for MODL projection of divmodL
 1152 RegMask Matcher::modL_proj_mask() {
 1153   ShouldNotReachHere();
 1154   return RegMask();
 1155 }
 1156 
 1157 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
 1158   return FP_REGP_mask();
 1159 }
 1160 
 1161 bool maybe_far_call(const CallNode *n) {
 1162   return !MacroAssembler::_reachable_from_cache(n->as_Call()->entry_point());
 1163 }
 1164 
 1165 bool maybe_far_call(const MachCallNode *n) {
 1166   return !MacroAssembler::_reachable_from_cache(n->as_MachCall()->entry_point());
 1167 }
 1168 
 1169 %}
 1170 
 1171 //----------ENCODING BLOCK-----------------------------------------------------
 1172 // This block specifies the encoding classes used by the compiler to output
 1173 // byte streams.  Encoding classes are parameterized macros used by
 1174 // Machine Instruction Nodes in order to generate the bit encoding of the
 1175 // instruction.  Operands specify their base encoding interface with the
 1176 // interface keyword.  There are currently supported four interfaces,
 1177 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
 1178 // operand to generate a function which returns its register number when
 1179 // queried.   CONST_INTER causes an operand to generate a function which
 1180 // returns the value of the constant when queried.  MEMORY_INTER causes an
 1181 // operand to generate four functions which return the Base Register, the
 1182 // Index Register, the Scale Value, and the Offset Value of the operand when
 1183 // queried.  COND_INTER causes an operand to generate six functions which
 1184 // return the encoding code (ie - encoding bits for the instruction)
 1185 // associated with each basic boolean condition for a conditional instruction.
 1186 //
 1187 // Instructions specify two basic values for encoding.  Again, a function
 1188 // is available to check if the constant displacement is an oop. They use the
 1189 // ins_encode keyword to specify their encoding classes (which must be
 1190 // a sequence of enc_class names, and their parameters, specified in
 1191 // the encoding block), and they use the
 1192 // opcode keyword to specify, in order, their primary, secondary, and
 1193 // tertiary opcode.  Only the opcode sections which a particular instruction
 1194 // needs for encoding need to be specified.
 1195 encode %{
 1196   // Set instruction mark in MacroAssembler. This is used only in
 1197   // instructions that emit bytes directly to the CodeBuffer wraped
 1198   // in the MacroAssembler. Should go away once all "instruct" are
 1199   // patched to emit bytes only using methods in MacroAssembler.
 1200   enc_class SetInstMark %{
 1201     __ set_inst_mark();
 1202   %}
 1203 
 1204   enc_class ClearInstMark %{
 1205     __ clear_inst_mark();
 1206   %}
 1207 
 1208   enc_class call_epilog %{
 1209     // nothing
 1210   %}
 1211 
 1212   enc_class Java_To_Runtime (method meth) %{
 1213     // CALL directly to the runtime
 1214     emit_call_reloc(masm, as_MachCall(), $meth, runtime_call_Relocation::spec());
 1215   %}
 1216 
 1217   enc_class Java_Static_Call (method meth) %{
 1218     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
 1219     // who we intended to call.
 1220 
 1221     if ( !_method) {
 1222       emit_call_reloc(masm, as_MachCall(), $meth, runtime_call_Relocation::spec());
 1223     } else {
 1224       int method_index = resolved_method_index(masm);
 1225       RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
 1226                                                   : static_call_Relocation::spec(method_index);
 1227       emit_call_reloc(masm, as_MachCall(), $meth, rspec);
 1228 
 1229       // Emit stubs for static call.
 1230       address stub = CompiledDirectCall::emit_to_interp_stub(masm);
 1231       if (stub == nullptr) {
 1232         ciEnv::current()->record_failure("CodeCache is full");
 1233         return;
 1234       }
 1235     }
 1236   %}
 1237 
 1238   enc_class save_last_PC %{
 1239     // preserve mark
 1240     address mark = __ inst_mark();
 1241     DEBUG_ONLY(int off0 = __ offset());
 1242     int ret_addr_offset = as_MachCall()->ret_addr_offset();
 1243     __ adr(LR, mark + ret_addr_offset);
 1244     __ str(LR, Address(Rthread, JavaThread::last_Java_pc_offset()));
 1245     DEBUG_ONLY(int off1 = __ offset());
 1246     assert(off1 - off0 == 2 * Assembler::InstructionSize, "correct size prediction");
 1247     // restore mark
 1248     __ set_inst_mark(mark);
 1249   %}
 1250 
 1251   enc_class preserve_SP %{
 1252     // preserve mark
 1253     address mark = __ inst_mark();
 1254     DEBUG_ONLY(int off0 = __ offset());
 1255     // FP is preserved across all calls, even compiled calls.
 1256     // Use it to preserve SP in places where the callee might change the SP.
 1257     __ mov(Rmh_SP_save, SP);
 1258     DEBUG_ONLY(int off1 = __ offset());
 1259     assert(off1 - off0 == 4, "correct size prediction");
 1260     // restore mark
 1261     __ set_inst_mark(mark);
 1262   %}
 1263 
 1264   enc_class restore_SP %{
 1265     __ mov(SP, Rmh_SP_save);
 1266   %}
 1267 
 1268   enc_class Java_Dynamic_Call (method meth) %{
 1269     Register R8_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode());
 1270     assert(R8_ic_reg == Ricklass, "should be");
 1271     __ set_inst_mark();
 1272     __ movw(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) & 0xffff);
 1273     __ movt(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) >> 16);
 1274     address  virtual_call_oop_addr = __ inst_mark();
 1275     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
 1276     // who we intended to call.
 1277     int method_index = resolved_method_index(masm);
 1278     __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index));
 1279     emit_call_reloc(masm, as_MachCall(), $meth, RelocationHolder::none);
 1280   %}
 1281 
 1282   enc_class LdReplImmI(immI src, regD dst, iRegI tmp, int cnt, int wth) %{
 1283     // FIXME: load from constant table?
 1284     // Load a constant replicated "count" times with width "width"
 1285     int count = $cnt$$constant;
 1286     int width = $wth$$constant;
 1287     assert(count*width == 4, "sanity");
 1288     int val = $src$$constant;
 1289     if (width < 4) {
 1290       int bit_width = width * 8;
 1291       val &= (((int)1) << bit_width) - 1; // mask off sign bits
 1292       for (int i = 0; i < count - 1; i++) {
 1293         val |= (val << bit_width);
 1294       }
 1295     }
 1296 
 1297     if (val == -1) {
 1298       __ mvn($tmp$$Register, 0);
 1299     } else if (val == 0) {
 1300       __ mov($tmp$$Register, 0);
 1301     } else {
 1302       __ movw($tmp$$Register, val & 0xffff);
 1303       __ movt($tmp$$Register, (unsigned int)val >> 16);
 1304     }
 1305     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 1306   %}
 1307 
 1308   enc_class LdReplImmF(immF src, regD dst, iRegI tmp) %{
 1309     // Replicate float con 2 times and pack into vector (8 bytes) in regD.
 1310     float fval = $src$$constant;
 1311     int val = *((int*)&fval);
 1312 
 1313     if (val == -1) {
 1314       __ mvn($tmp$$Register, 0);
 1315     } else if (val == 0) {
 1316       __ mov($tmp$$Register, 0);
 1317     } else {
 1318       __ movw($tmp$$Register, val & 0xffff);
 1319       __ movt($tmp$$Register, (unsigned int)val >> 16);
 1320     }
 1321     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 1322   %}
 1323 
 1324   enc_class enc_String_Compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result, iRegI tmp1, iRegI tmp2) %{
 1325     Label Ldone, Lloop;
 1326 
 1327     Register   str1_reg = $str1$$Register;
 1328     Register   str2_reg = $str2$$Register;
 1329     Register   cnt1_reg = $cnt1$$Register; // int
 1330     Register   cnt2_reg = $cnt2$$Register; // int
 1331     Register   tmp1_reg = $tmp1$$Register;
 1332     Register   tmp2_reg = $tmp2$$Register;
 1333     Register result_reg = $result$$Register;
 1334 
 1335     assert_different_registers(str1_reg, str2_reg, cnt1_reg, cnt2_reg, tmp1_reg, tmp2_reg);
 1336 
 1337     // Compute the minimum of the string lengths(str1_reg) and the
 1338     // difference of the string lengths (stack)
 1339 
 1340     // See if the lengths are different, and calculate min in str1_reg.
 1341     // Stash diff in tmp2 in case we need it for a tie-breaker.
 1342     __ subs_32(tmp2_reg, cnt1_reg, cnt2_reg);
 1343     __ mov(cnt1_reg, AsmOperand(cnt1_reg, lsl, exact_log2(sizeof(jchar)))); // scale the limit
 1344     __ mov(cnt1_reg, AsmOperand(cnt2_reg, lsl, exact_log2(sizeof(jchar))), pl); // scale the limit
 1345 
 1346     // reallocate cnt1_reg, cnt2_reg, result_reg
 1347     // Note:  limit_reg holds the string length pre-scaled by 2
 1348     Register limit_reg = cnt1_reg;
 1349     Register  chr2_reg = cnt2_reg;
 1350     Register  chr1_reg = tmp1_reg;
 1351     // str{12} are the base pointers
 1352 
 1353     // Is the minimum length zero?
 1354     __ cmp_32(limit_reg, 0);
 1355     if (result_reg != tmp2_reg) {
 1356       __ mov(result_reg, tmp2_reg, eq);
 1357     }
 1358     __ b(Ldone, eq);
 1359 
 1360     // Load first characters
 1361     __ ldrh(chr1_reg, Address(str1_reg, 0));
 1362     __ ldrh(chr2_reg, Address(str2_reg, 0));
 1363 
 1364     // Compare first characters
 1365     __ subs(chr1_reg, chr1_reg, chr2_reg);
 1366     if (result_reg != chr1_reg) {
 1367       __ mov(result_reg, chr1_reg, ne);
 1368     }
 1369     __ b(Ldone, ne);
 1370 
 1371     {
 1372       // Check after comparing first character to see if strings are equivalent
 1373       // Check if the strings start at same location
 1374       __ cmp(str1_reg, str2_reg);
 1375       // Check if the length difference is zero
 1376       __ cond_cmp(tmp2_reg, 0, eq);
 1377       __ mov(result_reg, 0, eq); // result is zero
 1378       __ b(Ldone, eq);
 1379       // Strings might not be equal
 1380     }
 1381 
 1382     __ subs(chr1_reg, limit_reg, 1 * sizeof(jchar));
 1383     if (result_reg != tmp2_reg) {
 1384       __ mov(result_reg, tmp2_reg, eq);
 1385     }
 1386     __ b(Ldone, eq);
 1387 
 1388     // Shift str1_reg and str2_reg to the end of the arrays, negate limit
 1389     __ add(str1_reg, str1_reg, limit_reg);
 1390     __ add(str2_reg, str2_reg, limit_reg);
 1391     __ neg(limit_reg, chr1_reg);  // limit = -(limit-2)
 1392 
 1393     // Compare the rest of the characters
 1394     __ bind(Lloop);
 1395     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
 1396     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
 1397     __ subs(chr1_reg, chr1_reg, chr2_reg);
 1398     if (result_reg != chr1_reg) {
 1399       __ mov(result_reg, chr1_reg, ne);
 1400     }
 1401     __ b(Ldone, ne);
 1402 
 1403     __ adds(limit_reg, limit_reg, sizeof(jchar));
 1404     __ b(Lloop, ne);
 1405 
 1406     // If strings are equal up to min length, return the length difference.
 1407     if (result_reg != tmp2_reg) {
 1408       __ mov(result_reg, tmp2_reg);
 1409     }
 1410 
 1411     // Otherwise, return the difference between the first mismatched chars.
 1412     __ bind(Ldone);
 1413   %}
 1414 
 1415   enc_class enc_String_Equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2) %{
 1416     Label Lchar, Lchar_loop, Ldone, Lequal;
 1417 
 1418     Register   str1_reg = $str1$$Register;
 1419     Register   str2_reg = $str2$$Register;
 1420     Register    cnt_reg = $cnt$$Register; // int
 1421     Register   tmp1_reg = $tmp1$$Register;
 1422     Register   tmp2_reg = $tmp2$$Register;
 1423     Register result_reg = $result$$Register;
 1424 
 1425     assert_different_registers(str1_reg, str2_reg, cnt_reg, tmp1_reg, tmp2_reg, result_reg);
 1426 
 1427     __ cmp(str1_reg, str2_reg); //same char[] ?
 1428     __ b(Lequal, eq);
 1429 
 1430     __ cbz_32(cnt_reg, Lequal); // count == 0
 1431 
 1432     //rename registers
 1433     Register limit_reg = cnt_reg;
 1434     Register  chr1_reg = tmp1_reg;
 1435     Register  chr2_reg = tmp2_reg;
 1436 
 1437     __ logical_shift_left(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
 1438 
 1439     //check for alignment and position the pointers to the ends
 1440     __ orr(chr1_reg, str1_reg, str2_reg);
 1441     __ tst(chr1_reg, 0x3);
 1442 
 1443     // notZero means at least one not 4-byte aligned.
 1444     // We could optimize the case when both arrays are not aligned
 1445     // but it is not frequent case and it requires additional checks.
 1446     __ b(Lchar, ne);
 1447 
 1448     // Compare char[] arrays aligned to 4 bytes.
 1449     __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg,
 1450                           chr1_reg, chr2_reg, Ldone);
 1451 
 1452     __ b(Lequal); // equal
 1453 
 1454     // char by char compare
 1455     __ bind(Lchar);
 1456     __ mov(result_reg, 0);
 1457     __ add(str1_reg, limit_reg, str1_reg);
 1458     __ add(str2_reg, limit_reg, str2_reg);
 1459     __ neg(limit_reg, limit_reg); //negate count
 1460 
 1461     // Lchar_loop
 1462     __ bind(Lchar_loop);
 1463     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
 1464     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
 1465     __ cmp(chr1_reg, chr2_reg);
 1466     __ b(Ldone, ne);
 1467     __ adds(limit_reg, limit_reg, sizeof(jchar));
 1468     __ b(Lchar_loop, ne);
 1469 
 1470     __ bind(Lequal);
 1471     __ mov(result_reg, 1);  //equal
 1472 
 1473     __ bind(Ldone);
 1474   %}
 1475 
 1476   enc_class enc_Array_Equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result) %{
 1477     Label Ldone, Lloop, Lequal;
 1478 
 1479     Register   ary1_reg = $ary1$$Register;
 1480     Register   ary2_reg = $ary2$$Register;
 1481     Register   tmp1_reg = $tmp1$$Register;
 1482     Register   tmp2_reg = $tmp2$$Register;
 1483     Register   tmp3_reg = $tmp3$$Register;
 1484     Register result_reg = $result$$Register;
 1485 
 1486     assert_different_registers(ary1_reg, ary2_reg, tmp1_reg, tmp2_reg, tmp3_reg, result_reg);
 1487 
 1488     int length_offset  = arrayOopDesc::length_offset_in_bytes();
 1489     int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
 1490 
 1491     // return true if the same array
 1492     __ teq(ary1_reg, ary2_reg);
 1493     __ mov(result_reg, 1, eq);
 1494     __ b(Ldone, eq); // equal
 1495 
 1496     __ tst(ary1_reg, ary1_reg);
 1497     __ mov(result_reg, 0, eq);
 1498     __ b(Ldone, eq);    // not equal
 1499 
 1500     __ tst(ary2_reg, ary2_reg);
 1501     __ mov(result_reg, 0, eq);
 1502     __ b(Ldone, eq);    // not equal
 1503 
 1504     //load the lengths of arrays
 1505     __ ldr_s32(tmp1_reg, Address(ary1_reg, length_offset)); // int
 1506     __ ldr_s32(tmp2_reg, Address(ary2_reg, length_offset)); // int
 1507 
 1508     // return false if the two arrays are not equal length
 1509     __ teq_32(tmp1_reg, tmp2_reg);
 1510     __ mov(result_reg, 0, ne);
 1511     __ b(Ldone, ne);    // not equal
 1512 
 1513     __ tst(tmp1_reg, tmp1_reg);
 1514     __ mov(result_reg, 1, eq);
 1515     __ b(Ldone, eq);    // zero-length arrays are equal
 1516 
 1517     // load array addresses
 1518     __ add(ary1_reg, ary1_reg, base_offset);
 1519     __ add(ary2_reg, ary2_reg, base_offset);
 1520 
 1521     // renaming registers
 1522     Register chr1_reg  =  tmp3_reg;   // for characters in ary1
 1523     Register chr2_reg  =  tmp2_reg;   // for characters in ary2
 1524     Register limit_reg =  tmp1_reg;   // length
 1525 
 1526     // set byte count
 1527     __ logical_shift_left_32(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
 1528 
 1529     // Compare char[] arrays aligned to 4 bytes.
 1530     __ char_arrays_equals(ary1_reg, ary2_reg, limit_reg, result_reg,
 1531                           chr1_reg, chr2_reg, Ldone);
 1532     __ bind(Lequal);
 1533     __ mov(result_reg, 1);  //equal
 1534 
 1535     __ bind(Ldone);
 1536     %}
 1537 %}
 1538 
 1539 //----------FRAME--------------------------------------------------------------
 1540 // Definition of frame structure and management information.
 1541 //
 1542 //  S T A C K   L A Y O U T    Allocators stack-slot number
 1543 //                             |   (to get allocators register number
 1544 //  G  Owned by    |        |  v    add VMRegImpl::stack0)
 1545 //  r   CALLER     |        |
 1546 //  o     |        +--------+      pad to even-align allocators stack-slot
 1547 //  w     V        |  pad0  |        numbers; owned by CALLER
 1548 //  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
 1549 //  h     ^        |   in   |  5
 1550 //        |        |  args  |  4   Holes in incoming args owned by SELF
 1551 //  |     |        |        |  3
 1552 //  |     |        +--------+
 1553 //  V     |        | old out|      Empty on Intel, window on Sparc
 1554 //        |    old |preserve|      Must be even aligned.
 1555 //        |     SP-+--------+----> Matcher::_old_SP, 8 (or 16 in LP64)-byte aligned
 1556 //        |        |   in   |  3   area for Intel ret address
 1557 //     Owned by    |preserve|      Empty on Sparc.
 1558 //       SELF      +--------+
 1559 //        |        |  pad2  |  2   pad to align old SP
 1560 //        |        +--------+  1
 1561 //        |        | locks  |  0
 1562 //        |        +--------+----> VMRegImpl::stack0, 8 (or 16 in LP64)-byte aligned
 1563 //        |        |  pad1  | 11   pad to align new SP
 1564 //        |        +--------+
 1565 //        |        |        | 10
 1566 //        |        | spills |  9   spills
 1567 //        V        |        |  8   (pad0 slot for callee)
 1568 //      -----------+--------+----> Matcher::_out_arg_limit, unaligned
 1569 //        ^        |  out   |  7
 1570 //        |        |  args  |  6   Holes in outgoing args owned by CALLEE
 1571 //     Owned by    +--------+
 1572 //      CALLEE     | new out|  6   Empty on Intel, window on Sparc
 1573 //        |    new |preserve|      Must be even-aligned.
 1574 //        |     SP-+--------+----> Matcher::_new_SP, even aligned
 1575 //        |        |        |
 1576 //
 1577 // Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
 1578 //         known from SELF's arguments and the Java calling convention.
 1579 //         Region 6-7 is determined per call site.
 1580 // Note 2: If the calling convention leaves holes in the incoming argument
 1581 //         area, those holes are owned by SELF.  Holes in the outgoing area
 1582 //         are owned by the CALLEE.  Holes should not be necessary in the
 1583 //         incoming area, as the Java calling convention is completely under
 1584 //         the control of the AD file.  Doubles can be sorted and packed to
 1585 //         avoid holes.  Holes in the outgoing arguments may be necessary for
 1586 //         varargs C calling conventions.
 1587 // Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
 1588 //         even aligned with pad0 as needed.
 1589 //         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
 1590 //         region 6-11 is even aligned; it may be padded out more so that
 1591 //         the region from SP to FP meets the minimum stack alignment.
 1592 
 1593 frame %{
 1594   // These two registers define part of the calling convention
 1595   // between compiled code and the interpreter.
 1596   inline_cache_reg(R_Ricklass);          // Inline Cache Register or Method* for I2C
 1597 
 1598   // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
 1599   cisc_spilling_operand_name(indOffset);
 1600 
 1601   // Number of stack slots consumed by a Monitor enter
 1602   sync_stack_slots(1 * VMRegImpl::slots_per_word);
 1603 
 1604   // Compiled code's Frame Pointer
 1605   frame_pointer(R_R13);
 1606 
 1607   // Stack alignment requirement
 1608   stack_alignment(StackAlignmentInBytes);
 1609   //  LP64: Alignment size in bytes (128-bit -> 16 bytes)
 1610   // !LP64: Alignment size in bytes (64-bit  ->  8 bytes)
 1611 
 1612   // Number of outgoing stack slots killed above the out_preserve_stack_slots
 1613   // for calls to C.  Supports the var-args backing area for register parms.
 1614   // ADLC doesn't support parsing expressions, so I folded the math by hand.
 1615   varargs_C_out_slots_killed( 0);
 1616 
 1617   // The after-PROLOG location of the return address.  Location of
 1618   // return address specifies a type (REG or STACK) and a number
 1619   // representing the register number (i.e. - use a register name) or
 1620   // stack slot.
 1621   // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
 1622   // Otherwise, it is above the locks and verification slot and alignment word
 1623   return_addr(STACK - 1*VMRegImpl::slots_per_word +
 1624               align_up((Compile::current()->in_preserve_stack_slots() +
 1625                         Compile::current()->fixed_slots()),
 1626                        stack_alignment_in_slots()));
 1627 
 1628   // Location of compiled Java return values.  Same as C
 1629   return_value %{
 1630     return c2::return_value(ideal_reg);
 1631   %}
 1632 
 1633 %}
 1634 
 1635 //----------ATTRIBUTES---------------------------------------------------------
 1636 //----------Instruction Attributes---------------------------------------------
 1637 ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute
 1638 ins_attrib ins_size(32);           // Required size attribute (in bits)
 1639 ins_attrib ins_short_branch(0);    // Required flag: is this instruction a
 1640                                    // non-matching short branch variant of some
 1641                                                             // long branch?
 1642 
 1643 //----------OPERANDS-----------------------------------------------------------
 1644 // Operand definitions must precede instruction definitions for correct parsing
 1645 // in the ADLC because operands constitute user defined types which are used in
 1646 // instruction definitions.
 1647 
 1648 //----------Simple Operands----------------------------------------------------
 1649 // Immediate Operands
 1650 // Integer Immediate: 32-bit
 1651 operand immI() %{
 1652   match(ConI);
 1653 
 1654   op_cost(0);
 1655   // formats are generated automatically for constants and base registers
 1656   format %{ %}
 1657   interface(CONST_INTER);
 1658 %}
 1659 
 1660 // Integer Immediate: 8-bit unsigned - for VMOV
 1661 operand immU8() %{
 1662   predicate(0 <= n->get_int() && (n->get_int() <= 255));
 1663   match(ConI);
 1664   op_cost(0);
 1665 
 1666   format %{ %}
 1667   interface(CONST_INTER);
 1668 %}
 1669 
 1670 // Integer Immediate: 16-bit
 1671 operand immI16() %{
 1672   predicate((n->get_int() >> 16) == 0 && VM_Version::supports_movw());
 1673   match(ConI);
 1674   op_cost(0);
 1675 
 1676   format %{ %}
 1677   interface(CONST_INTER);
 1678 %}
 1679 
 1680 // Integer Immediate: offset for half and double word loads and stores
 1681 operand immIHD() %{
 1682   predicate(is_memoryHD(n->get_int()));
 1683   match(ConI);
 1684   op_cost(0);
 1685   format %{ %}
 1686   interface(CONST_INTER);
 1687 %}
 1688 
 1689 // Integer Immediate: offset for fp loads and stores
 1690 operand immIFP() %{
 1691   predicate(is_memoryfp(n->get_int()) && ((n->get_int() & 3) == 0));
 1692   match(ConI);
 1693   op_cost(0);
 1694 
 1695   format %{ %}
 1696   interface(CONST_INTER);
 1697 %}
 1698 
 1699 // Valid scale values for addressing modes and shifts
 1700 operand immU5() %{
 1701   predicate(0 <= n->get_int() && (n->get_int() <= 31));
 1702   match(ConI);
 1703   op_cost(0);
 1704 
 1705   format %{ %}
 1706   interface(CONST_INTER);
 1707 %}
 1708 
 1709 // Integer Immediate: 6-bit
 1710 operand immU6Big() %{
 1711   predicate(n->get_int() >= 32 && n->get_int() <= 63);
 1712   match(ConI);
 1713   op_cost(0);
 1714   format %{ %}
 1715   interface(CONST_INTER);
 1716 %}
 1717 
 1718 // Integer Immediate: 0-bit
 1719 operand immI0() %{
 1720   predicate(n->get_int() == 0);
 1721   match(ConI);
 1722   op_cost(0);
 1723 
 1724   format %{ %}
 1725   interface(CONST_INTER);
 1726 %}
 1727 
 1728 // Int Immediate non-negative
 1729 operand immU31()
 1730 %{
 1731   predicate(n->get_int() >= 0);
 1732   match(ConI);
 1733 
 1734   op_cost(0);
 1735   format %{ %}
 1736   interface(CONST_INTER);
 1737 %}
 1738 
 1739 // Integer Immediate: the values 32-63
 1740 operand immI_32_63() %{
 1741   predicate(n->get_int() >= 32 && n->get_int() <= 63);
 1742   match(ConI);
 1743   op_cost(0);
 1744 
 1745   format %{ %}
 1746   interface(CONST_INTER);
 1747 %}
 1748 
 1749 // Immediates for special shifts (sign extend)
 1750 
 1751 // Integer Immediate: the value 16
 1752 operand immI_16() %{
 1753   predicate(n->get_int() == 16);
 1754   match(ConI);
 1755   op_cost(0);
 1756 
 1757   format %{ %}
 1758   interface(CONST_INTER);
 1759 %}
 1760 
 1761 // Integer Immediate: the value 24
 1762 operand immI_24() %{
 1763   predicate(n->get_int() == 24);
 1764   match(ConI);
 1765   op_cost(0);
 1766 
 1767   format %{ %}
 1768   interface(CONST_INTER);
 1769 %}
 1770 
 1771 // Integer Immediate: the value 255
 1772 operand immI_255() %{
 1773   predicate( n->get_int() == 255 );
 1774   match(ConI);
 1775   op_cost(0);
 1776 
 1777   format %{ %}
 1778   interface(CONST_INTER);
 1779 %}
 1780 
 1781 // Integer Immediate: the value 65535
 1782 operand immI_65535() %{
 1783   predicate(n->get_int() == 65535);
 1784   match(ConI);
 1785   op_cost(0);
 1786 
 1787   format %{ %}
 1788   interface(CONST_INTER);
 1789 %}
 1790 
 1791 // Integer Immediates for arithmetic instructions
 1792 
 1793 operand aimmI() %{
 1794   predicate(is_aimm(n->get_int()));
 1795   match(ConI);
 1796   op_cost(0);
 1797 
 1798   format %{ %}
 1799   interface(CONST_INTER);
 1800 %}
 1801 
 1802 operand aimmIneg() %{
 1803   predicate(is_aimm(-n->get_int()));
 1804   match(ConI);
 1805   op_cost(0);
 1806 
 1807   format %{ %}
 1808   interface(CONST_INTER);
 1809 %}
 1810 
 1811 operand aimmU31() %{
 1812   predicate((0 <= n->get_int()) && is_aimm(n->get_int()));
 1813   match(ConI);
 1814   op_cost(0);
 1815 
 1816   format %{ %}
 1817   interface(CONST_INTER);
 1818 %}
 1819 
 1820 // Integer Immediates for logical instructions
 1821 
 1822 operand limmI() %{
 1823   predicate(is_limmI(n->get_int()));
 1824   match(ConI);
 1825   op_cost(0);
 1826 
 1827   format %{ %}
 1828   interface(CONST_INTER);
 1829 %}
 1830 
 1831 operand limmIlow8() %{
 1832   predicate(is_limmI_low(n->get_int(), 8));
 1833   match(ConI);
 1834   op_cost(0);
 1835 
 1836   format %{ %}
 1837   interface(CONST_INTER);
 1838 %}
 1839 
 1840 operand limmU31() %{
 1841   predicate(0 <= n->get_int() && is_limmI(n->get_int()));
 1842   match(ConI);
 1843   op_cost(0);
 1844 
 1845   format %{ %}
 1846   interface(CONST_INTER);
 1847 %}
 1848 
 1849 operand limmIn() %{
 1850   predicate(is_limmI(~n->get_int()));
 1851   match(ConI);
 1852   op_cost(0);
 1853 
 1854   format %{ %}
 1855   interface(CONST_INTER);
 1856 %}
 1857 
 1858 // Pointer Immediate: 32 or 64-bit
 1859 operand immP() %{
 1860   match(ConP);
 1861 
 1862   op_cost(5);
 1863   // formats are generated automatically for constants and base registers
 1864   format %{ %}
 1865   interface(CONST_INTER);
 1866 %}
 1867 
 1868 operand immP0() %{
 1869   predicate(n->get_ptr() == 0);
 1870   match(ConP);
 1871   op_cost(0);
 1872 
 1873   format %{ %}
 1874   interface(CONST_INTER);
 1875 %}
 1876 
 1877 operand immL() %{
 1878   match(ConL);
 1879   op_cost(40);
 1880   // formats are generated automatically for constants and base registers
 1881   format %{ %}
 1882   interface(CONST_INTER);
 1883 %}
 1884 
 1885 operand immL0() %{
 1886   predicate(n->get_long() == 0L);
 1887   match(ConL);
 1888   op_cost(0);
 1889   // formats are generated automatically for constants and base registers
 1890   format %{ %}
 1891   interface(CONST_INTER);
 1892 %}
 1893 
 1894 // Long Immediate: 16-bit
 1895 operand immL16() %{
 1896   predicate(n->get_long() >= 0 && n->get_long() < (1<<16)  && VM_Version::supports_movw());
 1897   match(ConL);
 1898   op_cost(0);
 1899 
 1900   format %{ %}
 1901   interface(CONST_INTER);
 1902 %}
 1903 
 1904 // Long Immediate: low 32-bit mask
 1905 operand immL_32bits() %{
 1906   predicate(n->get_long() == 0xFFFFFFFFL);
 1907   match(ConL);
 1908   op_cost(0);
 1909 
 1910   format %{ %}
 1911   interface(CONST_INTER);
 1912 %}
 1913 
 1914 // Double Immediate
 1915 operand immD() %{
 1916   match(ConD);
 1917 
 1918   op_cost(40);
 1919   format %{ %}
 1920   interface(CONST_INTER);
 1921 %}
 1922 
 1923 // Double Immediate: +0.0d.
 1924 operand immD0() %{
 1925   predicate(jlong_cast(n->getd()) == 0);
 1926 
 1927   match(ConD);
 1928   op_cost(0);
 1929   format %{ %}
 1930   interface(CONST_INTER);
 1931 %}
 1932 
 1933 operand imm8D() %{
 1934   predicate(Assembler::double_num(n->getd()).can_be_imm8());
 1935   match(ConD);
 1936 
 1937   op_cost(0);
 1938   format %{ %}
 1939   interface(CONST_INTER);
 1940 %}
 1941 
 1942 // Float Immediate
 1943 operand immF() %{
 1944   match(ConF);
 1945 
 1946   op_cost(20);
 1947   format %{ %}
 1948   interface(CONST_INTER);
 1949 %}
 1950 
 1951 // Float Immediate: +0.0f
 1952 operand immF0() %{
 1953   predicate(jint_cast(n->getf()) == 0);
 1954   match(ConF);
 1955 
 1956   op_cost(0);
 1957   format %{ %}
 1958   interface(CONST_INTER);
 1959 %}
 1960 
 1961 // Float Immediate: encoded as 8 bits
 1962 operand imm8F() %{
 1963   predicate(Assembler::float_num(n->getf()).can_be_imm8());
 1964   match(ConF);
 1965 
 1966   op_cost(0);
 1967   format %{ %}
 1968   interface(CONST_INTER);
 1969 %}
 1970 
 1971 // Integer Register Operands
 1972 // Integer Register
 1973 operand iRegI() %{
 1974   constraint(ALLOC_IN_RC(int_reg));
 1975   match(RegI);
 1976   match(R0RegI);
 1977   match(R1RegI);
 1978   match(R2RegI);
 1979   match(R3RegI);
 1980   match(R12RegI);
 1981 
 1982   format %{ %}
 1983   interface(REG_INTER);
 1984 %}
 1985 
 1986 // Pointer Register
 1987 operand iRegP() %{
 1988   constraint(ALLOC_IN_RC(ptr_reg));
 1989   match(RegP);
 1990   match(R0RegP);
 1991   match(R1RegP);
 1992   match(R2RegP);
 1993   match(RExceptionRegP);
 1994   match(R8RegP);
 1995   match(R9RegP);
 1996   match(RthreadRegP); // FIXME: move to sp_ptr_RegP?
 1997   match(R12RegP);
 1998   match(LRRegP);
 1999 
 2000   match(sp_ptr_RegP);
 2001   match(store_ptr_RegP);
 2002 
 2003   format %{ %}
 2004   interface(REG_INTER);
 2005 %}
 2006 
 2007 // GPRs + Rthread + SP
 2008 operand sp_ptr_RegP() %{
 2009   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2010   match(RegP);
 2011   match(iRegP);
 2012   match(SPRegP); // FIXME: check cost
 2013 
 2014   format %{ %}
 2015   interface(REG_INTER);
 2016 %}
 2017 
 2018 
 2019 operand R0RegP() %{
 2020   constraint(ALLOC_IN_RC(R0_regP));
 2021   match(iRegP);
 2022 
 2023   format %{ %}
 2024   interface(REG_INTER);
 2025 %}
 2026 
 2027 operand R1RegP() %{
 2028   constraint(ALLOC_IN_RC(R1_regP));
 2029   match(iRegP);
 2030 
 2031   format %{ %}
 2032   interface(REG_INTER);
 2033 %}
 2034 
 2035 operand R8RegP() %{
 2036   constraint(ALLOC_IN_RC(R8_regP));
 2037   match(iRegP);
 2038 
 2039   format %{ %}
 2040   interface(REG_INTER);
 2041 %}
 2042 
 2043 operand R9RegP() %{
 2044   constraint(ALLOC_IN_RC(R9_regP));
 2045   match(iRegP);
 2046 
 2047   format %{ %}
 2048   interface(REG_INTER);
 2049 %}
 2050 
 2051 operand R12RegP() %{
 2052   constraint(ALLOC_IN_RC(R12_regP));
 2053   match(iRegP);
 2054 
 2055   format %{ %}
 2056   interface(REG_INTER);
 2057 %}
 2058 
 2059 operand R2RegP() %{
 2060   constraint(ALLOC_IN_RC(R2_regP));
 2061   match(iRegP);
 2062 
 2063   format %{ %}
 2064   interface(REG_INTER);
 2065 %}
 2066 
 2067 operand RExceptionRegP() %{
 2068   constraint(ALLOC_IN_RC(Rexception_regP));
 2069   match(iRegP);
 2070 
 2071   format %{ %}
 2072   interface(REG_INTER);
 2073 %}
 2074 
 2075 operand RthreadRegP() %{
 2076   constraint(ALLOC_IN_RC(Rthread_regP));
 2077   match(iRegP);
 2078 
 2079   format %{ %}
 2080   interface(REG_INTER);
 2081 %}
 2082 
 2083 operand IPRegP() %{
 2084   constraint(ALLOC_IN_RC(IP_regP));
 2085   match(iRegP);
 2086 
 2087   format %{ %}
 2088   interface(REG_INTER);
 2089 %}
 2090 
 2091 operand SPRegP() %{
 2092   constraint(ALLOC_IN_RC(SP_regP));
 2093   match(iRegP);
 2094 
 2095   format %{ %}
 2096   interface(REG_INTER);
 2097 %}
 2098 
 2099 operand LRRegP() %{
 2100   constraint(ALLOC_IN_RC(LR_regP));
 2101   match(iRegP);
 2102 
 2103   format %{ %}
 2104   interface(REG_INTER);
 2105 %}
 2106 
 2107 operand R0RegI() %{
 2108   constraint(ALLOC_IN_RC(R0_regI));
 2109   match(iRegI);
 2110 
 2111   format %{ %}
 2112   interface(REG_INTER);
 2113 %}
 2114 
 2115 operand R1RegI() %{
 2116   constraint(ALLOC_IN_RC(R1_regI));
 2117   match(iRegI);
 2118 
 2119   format %{ %}
 2120   interface(REG_INTER);
 2121 %}
 2122 
 2123 operand R2RegI() %{
 2124   constraint(ALLOC_IN_RC(R2_regI));
 2125   match(iRegI);
 2126 
 2127   format %{ %}
 2128   interface(REG_INTER);
 2129 %}
 2130 
 2131 operand R3RegI() %{
 2132   constraint(ALLOC_IN_RC(R3_regI));
 2133   match(iRegI);
 2134 
 2135   format %{ %}
 2136   interface(REG_INTER);
 2137 %}
 2138 
 2139 operand R12RegI() %{
 2140   constraint(ALLOC_IN_RC(R12_regI));
 2141   match(iRegI);
 2142 
 2143   format %{ %}
 2144   interface(REG_INTER);
 2145 %}
 2146 
 2147 // Long Register
 2148 operand iRegL() %{
 2149   constraint(ALLOC_IN_RC(long_reg));
 2150   match(RegL);
 2151   match(R0R1RegL);
 2152   match(R2R3RegL);
 2153 //match(iRegLex);
 2154 
 2155   format %{ %}
 2156   interface(REG_INTER);
 2157 %}
 2158 
 2159 operand iRegLd() %{
 2160   constraint(ALLOC_IN_RC(long_reg_align));
 2161   match(iRegL); // FIXME: allows unaligned R11/R12?
 2162 
 2163   format %{ %}
 2164   interface(REG_INTER);
 2165 %}
 2166 
 2167 // first long arg, or return value
 2168 operand R0R1RegL() %{
 2169   constraint(ALLOC_IN_RC(R0R1_regL));
 2170   match(iRegL);
 2171 
 2172   format %{ %}
 2173   interface(REG_INTER);
 2174 %}
 2175 
 2176 operand R2R3RegL() %{
 2177   constraint(ALLOC_IN_RC(R2R3_regL));
 2178   match(iRegL);
 2179 
 2180   format %{ %}
 2181   interface(REG_INTER);
 2182 %}
 2183 
 2184 // Condition Code Flag Register
 2185 operand flagsReg() %{
 2186   constraint(ALLOC_IN_RC(int_flags));
 2187   match(RegFlags);
 2188 
 2189   format %{ "apsr" %}
 2190   interface(REG_INTER);
 2191 %}
 2192 
 2193 // Result of compare to 0 (TST)
 2194 operand flagsReg_EQNELTGE() %{
 2195   constraint(ALLOC_IN_RC(int_flags));
 2196   match(RegFlags);
 2197 
 2198   format %{ "apsr_EQNELTGE" %}
 2199   interface(REG_INTER);
 2200 %}
 2201 
 2202 // Condition Code Register, unsigned comparisons.
 2203 operand flagsRegU() %{
 2204   constraint(ALLOC_IN_RC(int_flags));
 2205   match(RegFlags);
 2206 #ifdef TODO
 2207   match(RegFlagsP);
 2208 #endif
 2209 
 2210   format %{ "apsr_U" %}
 2211   interface(REG_INTER);
 2212 %}
 2213 
 2214 // Condition Code Register, pointer comparisons.
 2215 operand flagsRegP() %{
 2216   constraint(ALLOC_IN_RC(int_flags));
 2217   match(RegFlags);
 2218 
 2219   format %{ "apsr_P" %}
 2220   interface(REG_INTER);
 2221 %}
 2222 
 2223 // Condition Code Register, long comparisons.
 2224 operand flagsRegL_LTGE() %{
 2225   constraint(ALLOC_IN_RC(int_flags));
 2226   match(RegFlags);
 2227 
 2228   format %{ "apsr_L_LTGE" %}
 2229   interface(REG_INTER);
 2230 %}
 2231 
 2232 operand flagsRegL_EQNE() %{
 2233   constraint(ALLOC_IN_RC(int_flags));
 2234   match(RegFlags);
 2235 
 2236   format %{ "apsr_L_EQNE" %}
 2237   interface(REG_INTER);
 2238 %}
 2239 
 2240 operand flagsRegL_LEGT() %{
 2241   constraint(ALLOC_IN_RC(int_flags));
 2242   match(RegFlags);
 2243 
 2244   format %{ "apsr_L_LEGT" %}
 2245   interface(REG_INTER);
 2246 %}
 2247 
 2248 operand flagsRegUL_LTGE() %{
 2249   constraint(ALLOC_IN_RC(int_flags));
 2250   match(RegFlags);
 2251 
 2252   format %{ "apsr_UL_LTGE" %}
 2253   interface(REG_INTER);
 2254 %}
 2255 
 2256 operand flagsRegUL_EQNE() %{
 2257   constraint(ALLOC_IN_RC(int_flags));
 2258   match(RegFlags);
 2259 
 2260   format %{ "apsr_UL_EQNE" %}
 2261   interface(REG_INTER);
 2262 %}
 2263 
 2264 operand flagsRegUL_LEGT() %{
 2265   constraint(ALLOC_IN_RC(int_flags));
 2266   match(RegFlags);
 2267 
 2268   format %{ "apsr_UL_LEGT" %}
 2269   interface(REG_INTER);
 2270 %}
 2271 
 2272 // Condition Code Register, floating comparisons, unordered same as "less".
 2273 operand flagsRegF() %{
 2274   constraint(ALLOC_IN_RC(float_flags));
 2275   match(RegFlags);
 2276 
 2277   format %{ "fpscr_F" %}
 2278   interface(REG_INTER);
 2279 %}
 2280 
 2281 // Vectors
 2282 operand vecD() %{
 2283   constraint(ALLOC_IN_RC(actual_dflt_reg));
 2284   match(VecD);
 2285 
 2286   format %{ %}
 2287   interface(REG_INTER);
 2288 %}
 2289 
 2290 operand vecX() %{
 2291   constraint(ALLOC_IN_RC(vectorx_reg));
 2292   match(VecX);
 2293 
 2294   format %{ %}
 2295   interface(REG_INTER);
 2296 %}
 2297 
 2298 operand regD() %{
 2299   constraint(ALLOC_IN_RC(actual_dflt_reg));
 2300   match(RegD);
 2301   match(regD_low);
 2302 
 2303   format %{ %}
 2304   interface(REG_INTER);
 2305 %}
 2306 
 2307 operand regF() %{
 2308   constraint(ALLOC_IN_RC(sflt_reg));
 2309   match(RegF);
 2310 
 2311   format %{ %}
 2312   interface(REG_INTER);
 2313 %}
 2314 
 2315 operand regD_low() %{
 2316   constraint(ALLOC_IN_RC(dflt_low_reg));
 2317   match(RegD);
 2318 
 2319   format %{ %}
 2320   interface(REG_INTER);
 2321 %}
 2322 
 2323 // Special Registers
 2324 
 2325 // Method Register
 2326 operand inline_cache_regP(iRegP reg) %{
 2327   constraint(ALLOC_IN_RC(Ricklass_regP));
 2328   match(reg);
 2329   format %{ %}
 2330   interface(REG_INTER);
 2331 %}
 2332 
 2333 //----------Complex Operands---------------------------------------------------
 2334 // Indirect Memory Reference
 2335 operand indirect(sp_ptr_RegP reg) %{
 2336   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2337   match(reg);
 2338 
 2339   op_cost(100);
 2340   format %{ "[$reg]" %}
 2341   interface(MEMORY_INTER) %{
 2342     base($reg);
 2343     index(0xf); // PC => no index
 2344     scale(0x0);
 2345     disp(0x0);
 2346   %}
 2347 %}
 2348 
 2349 
 2350 // Indirect with Offset in ]-4096, 4096[
 2351 operand indOffset12(sp_ptr_RegP reg, immI12 offset) %{
 2352   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2353   match(AddP reg offset);
 2354 
 2355   op_cost(100);
 2356   format %{ "[$reg + $offset]" %}
 2357   interface(MEMORY_INTER) %{
 2358     base($reg);
 2359     index(0xf); // PC => no index
 2360     scale(0x0);
 2361     disp($offset);
 2362   %}
 2363 %}
 2364 
 2365 // Indirect with offset for float load/store
 2366 operand indOffsetFP(sp_ptr_RegP reg, immIFP offset) %{
 2367   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2368   match(AddP reg offset);
 2369 
 2370   op_cost(100);
 2371   format %{ "[$reg + $offset]" %}
 2372   interface(MEMORY_INTER) %{
 2373     base($reg);
 2374     index(0xf); // PC => no index
 2375     scale(0x0);
 2376     disp($offset);
 2377   %}
 2378 %}
 2379 
 2380 // Indirect with Offset for half and double words
 2381 operand indOffsetHD(sp_ptr_RegP reg, immIHD offset) %{
 2382   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2383   match(AddP reg offset);
 2384 
 2385   op_cost(100);
 2386   format %{ "[$reg + $offset]" %}
 2387   interface(MEMORY_INTER) %{
 2388     base($reg);
 2389     index(0xf); // PC => no index
 2390     scale(0x0);
 2391     disp($offset);
 2392   %}
 2393 %}
 2394 
 2395 // Indirect with Offset and Offset+4 in ]-1024, 1024[
 2396 operand indOffsetFPx2(sp_ptr_RegP reg, immX10x2 offset) %{
 2397   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2398   match(AddP reg offset);
 2399 
 2400   op_cost(100);
 2401   format %{ "[$reg + $offset]" %}
 2402   interface(MEMORY_INTER) %{
 2403     base($reg);
 2404     index(0xf); // PC => no index
 2405     scale(0x0);
 2406     disp($offset);
 2407   %}
 2408 %}
 2409 
 2410 // Indirect with Offset and Offset+4 in ]-4096, 4096[
 2411 operand indOffset12x2(sp_ptr_RegP reg, immI12x2 offset) %{
 2412   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2413   match(AddP reg offset);
 2414 
 2415   op_cost(100);
 2416   format %{ "[$reg + $offset]" %}
 2417   interface(MEMORY_INTER) %{
 2418     base($reg);
 2419     index(0xf); // PC => no index
 2420     scale(0x0);
 2421     disp($offset);
 2422   %}
 2423 %}
 2424 
 2425 // Indirect with Register Index
 2426 operand indIndex(iRegP addr, iRegX index) %{
 2427   constraint(ALLOC_IN_RC(ptr_reg));
 2428   match(AddP addr index);
 2429 
 2430   op_cost(100);
 2431   format %{ "[$addr + $index]" %}
 2432   interface(MEMORY_INTER) %{
 2433     base($addr);
 2434     index($index);
 2435     scale(0x0);
 2436     disp(0x0);
 2437   %}
 2438 %}
 2439 
 2440 // Indirect Memory Times Scale Plus Index Register
 2441 operand indIndexScale(iRegP addr, iRegX index, immU5 scale) %{
 2442   constraint(ALLOC_IN_RC(ptr_reg));
 2443   match(AddP addr (LShiftX index scale));
 2444 
 2445   op_cost(100);
 2446   format %{"[$addr + $index << $scale]" %}
 2447   interface(MEMORY_INTER) %{
 2448     base($addr);
 2449     index($index);
 2450     scale($scale);
 2451     disp(0x0);
 2452   %}
 2453 %}
 2454 
 2455 // Operands for expressing Control Flow
 2456 // NOTE:  Label is a predefined operand which should not be redefined in
 2457 //        the AD file.  It is generically handled within the ADLC.
 2458 
 2459 //----------Conditional Branch Operands----------------------------------------
 2460 // Comparison Op  - This is the operation of the comparison, and is limited to
 2461 //                  the following set of codes:
 2462 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
 2463 //
 2464 // Other attributes of the comparison, such as unsignedness, are specified
 2465 // by the comparison instruction that sets a condition code flags register.
 2466 // That result is represented by a flags operand whose subtype is appropriate
 2467 // to the unsignedness (etc.) of the comparison.
 2468 //
 2469 // Later, the instruction which matches both the Comparison Op (a Bool) and
 2470 // the flags (produced by the Cmp) specifies the coding of the comparison op
 2471 // by matching a specific subtype of Bool operand below, such as cmpOpU.
 2472 
 2473 operand cmpOp() %{
 2474   match(Bool);
 2475 
 2476   format %{ "" %}
 2477   interface(COND_INTER) %{
 2478     equal(0x0);
 2479     not_equal(0x1);
 2480     less(0xb);
 2481     greater_equal(0xa);
 2482     less_equal(0xd);
 2483     greater(0xc);
 2484     overflow(0x0); // unsupported/unimplemented
 2485     no_overflow(0x0); // unsupported/unimplemented
 2486   %}
 2487 %}
 2488 
 2489 // integer comparison with 0, signed
 2490 operand cmpOp0() %{
 2491   match(Bool);
 2492 
 2493   format %{ "" %}
 2494   interface(COND_INTER) %{
 2495     equal(0x0);
 2496     not_equal(0x1);
 2497     less(0x4);
 2498     greater_equal(0x5);
 2499     less_equal(0xd); // unsupported
 2500     greater(0xc); // unsupported
 2501     overflow(0x0); // unsupported/unimplemented
 2502     no_overflow(0x0); // unsupported/unimplemented
 2503   %}
 2504 %}
 2505 
 2506 // Comparison Op, unsigned
 2507 operand cmpOpU() %{
 2508   match(Bool);
 2509 
 2510   format %{ "u" %}
 2511   interface(COND_INTER) %{
 2512     equal(0x0);
 2513     not_equal(0x1);
 2514     less(0x3);
 2515     greater_equal(0x2);
 2516     less_equal(0x9);
 2517     greater(0x8);
 2518     overflow(0x0); // unsupported/unimplemented
 2519     no_overflow(0x0); // unsupported/unimplemented
 2520   %}
 2521 %}
 2522 
 2523 // Comparison Op, pointer (same as unsigned)
 2524 operand cmpOpP() %{
 2525   match(Bool);
 2526 
 2527   format %{ "p" %}
 2528   interface(COND_INTER) %{
 2529     equal(0x0);
 2530     not_equal(0x1);
 2531     less(0x3);
 2532     greater_equal(0x2);
 2533     less_equal(0x9);
 2534     greater(0x8);
 2535     overflow(0x0); // unsupported/unimplemented
 2536     no_overflow(0x0); // unsupported/unimplemented
 2537   %}
 2538 %}
 2539 
 2540 operand cmpOpL() %{
 2541   match(Bool);
 2542 
 2543   format %{ "L" %}
 2544   interface(COND_INTER) %{
 2545     equal(0x0);
 2546     not_equal(0x1);
 2547     less(0xb);
 2548     greater_equal(0xa);
 2549     less_equal(0xd);
 2550     greater(0xc);
 2551     overflow(0x0); // unsupported/unimplemented
 2552     no_overflow(0x0); // unsupported/unimplemented
 2553   %}
 2554 %}
 2555 
 2556 operand cmpOpL_commute() %{
 2557   match(Bool);
 2558 
 2559   format %{ "L" %}
 2560   interface(COND_INTER) %{
 2561     equal(0x0);
 2562     not_equal(0x1);
 2563     less(0xc);
 2564     greater_equal(0xd);
 2565     less_equal(0xa);
 2566     greater(0xb);
 2567     overflow(0x0); // unsupported/unimplemented
 2568     no_overflow(0x0); // unsupported/unimplemented
 2569   %}
 2570 %}
 2571 
 2572 operand cmpOpUL() %{
 2573   match(Bool);
 2574 
 2575   format %{ "UL" %}
 2576   interface(COND_INTER) %{
 2577     equal(0x0);
 2578     not_equal(0x1);
 2579     less(0x3);
 2580     greater_equal(0x2);
 2581     less_equal(0x9);
 2582     greater(0x8);
 2583     overflow(0x0); // unsupported/unimplemented
 2584     no_overflow(0x0); // unsupported/unimplemented
 2585   %}
 2586 %}
 2587 
 2588 operand cmpOpUL_commute() %{
 2589   match(Bool);
 2590 
 2591   format %{ "UL" %}
 2592   interface(COND_INTER) %{
 2593     equal(0x0);
 2594     not_equal(0x1);
 2595     less(0x8);
 2596     greater_equal(0x9);
 2597     less_equal(0x2);
 2598     greater(0x3);
 2599     overflow(0x0); // unsupported/unimplemented
 2600     no_overflow(0x0); // unsupported/unimplemented
 2601   %}
 2602 %}
 2603 
 2604 
 2605 //----------OPERAND CLASSES----------------------------------------------------
 2606 // Operand Classes are groups of operands that are used to simplify
 2607 // instruction definitions by not requiring the AD writer to specify separate
 2608 // instructions for every form of operand when the instruction accepts
 2609 // multiple operand types with the same basic encoding and format.  The classic
 2610 // case of this is memory operands.
 2611 
 2612 opclass memoryI ( indirect, indOffset12, indIndex, indIndexScale );
 2613 opclass memoryP ( indirect, indOffset12, indIndex, indIndexScale );
 2614 opclass memoryF ( indirect, indOffsetFP );
 2615 opclass memoryF2 ( indirect, indOffsetFPx2 );
 2616 opclass memoryD ( indirect, indOffsetFP );
 2617 opclass memoryfp( indirect, indOffsetFP );
 2618 opclass memoryB ( indirect, indIndex, indOffsetHD );
 2619 opclass memoryS ( indirect, indIndex, indOffsetHD );
 2620 opclass memoryL ( indirect, indIndex, indOffsetHD );
 2621 
 2622 opclass memoryScaledI(indIndexScale);
 2623 opclass memoryScaledP(indIndexScale);
 2624 
 2625 // when ldrex/strex is used:
 2626 opclass memoryex ( indirect );
 2627 opclass indIndexMemory( indIndex );
 2628 opclass memorylong ( indirect, indOffset12x2 );
 2629 opclass memoryvld ( indirect /* , write back mode not implemented */ );
 2630 
 2631 //----------PIPELINE-----------------------------------------------------------
 2632 pipeline %{
 2633 
 2634 //----------ATTRIBUTES---------------------------------------------------------
 2635 attributes %{
 2636   fixed_size_instructions;           // Fixed size instructions
 2637   max_instructions_per_bundle = 4;   // Up to 4 instructions per bundle
 2638   instruction_unit_size = 4;         // An instruction is 4 bytes long
 2639   instruction_fetch_unit_size = 16;  // The processor fetches one line
 2640   instruction_fetch_units = 1;       // of 16 bytes
 2641 
 2642   // List of nop instructions
 2643   nops( Nop_A0, Nop_A1, Nop_MS, Nop_FA, Nop_BR );
 2644 %}
 2645 
 2646 //----------RESOURCES----------------------------------------------------------
 2647 // Resources are the functional units available to the machine
 2648 resources(A0, A1, MS, BR, FA, FM, IDIV, FDIV, IALU = A0 | A1);
 2649 
 2650 //----------PIPELINE DESCRIPTION-----------------------------------------------
 2651 // Pipeline Description specifies the stages in the machine's pipeline
 2652 
 2653 pipe_desc(A, P, F, B, I, J, S, R, E, C, M, W, X, T, D);
 2654 
 2655 //----------PIPELINE CLASSES---------------------------------------------------
 2656 // Pipeline Classes describe the stages in which input and output are
 2657 // referenced by the hardware pipeline.
 2658 
 2659 // Integer ALU reg-reg operation
 2660 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 2661     single_instruction;
 2662     dst   : E(write);
 2663     src1  : R(read);
 2664     src2  : R(read);
 2665     IALU  : R;
 2666 %}
 2667 
 2668 // Integer ALU reg-reg long operation
 2669 pipe_class ialu_reg_reg_2(iRegL dst, iRegL src1, iRegL src2) %{
 2670     instruction_count(2);
 2671     dst   : E(write);
 2672     src1  : R(read);
 2673     src2  : R(read);
 2674     IALU  : R;
 2675     IALU  : R;
 2676 %}
 2677 
 2678 // Integer ALU reg-reg long dependent operation
 2679 pipe_class ialu_reg_reg_2_dep(iRegL dst, iRegL src1, iRegL src2, flagsReg cr) %{
 2680     instruction_count(1); multiple_bundles;
 2681     dst   : E(write);
 2682     src1  : R(read);
 2683     src2  : R(read);
 2684     cr    : E(write);
 2685     IALU  : R(2);
 2686 %}
 2687 
 2688 // Integer ALU reg-imm operation
 2689 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) %{
 2690     single_instruction;
 2691     dst   : E(write);
 2692     src1  : R(read);
 2693     IALU  : R;
 2694 %}
 2695 
 2696 // Integer ALU reg-reg operation with condition code
 2697 pipe_class ialu_cc_reg_reg(iRegI dst, iRegI src1, iRegI src2, flagsReg cr) %{
 2698     single_instruction;
 2699     dst   : E(write);
 2700     cr    : E(write);
 2701     src1  : R(read);
 2702     src2  : R(read);
 2703     IALU  : R;
 2704 %}
 2705 
 2706 // Integer ALU zero-reg operation
 2707 pipe_class ialu_zero_reg(iRegI dst, immI0 zero, iRegI src2) %{
 2708     single_instruction;
 2709     dst   : E(write);
 2710     src2  : R(read);
 2711     IALU  : R;
 2712 %}
 2713 
 2714 // Integer ALU zero-reg operation with condition code only
 2715 pipe_class ialu_cconly_zero_reg(flagsReg cr, iRegI src) %{
 2716     single_instruction;
 2717     cr    : E(write);
 2718     src   : R(read);
 2719     IALU  : R;
 2720 %}
 2721 
 2722 // Integer ALU reg-reg operation with condition code only
 2723 pipe_class ialu_cconly_reg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
 2724     single_instruction;
 2725     cr    : E(write);
 2726     src1  : R(read);
 2727     src2  : R(read);
 2728     IALU  : R;
 2729 %}
 2730 
 2731 // Integer ALU reg-imm operation with condition code only
 2732 pipe_class ialu_cconly_reg_imm(flagsReg cr, iRegI src1) %{
 2733     single_instruction;
 2734     cr    : E(write);
 2735     src1  : R(read);
 2736     IALU  : R;
 2737 %}
 2738 
 2739 // Integer ALU reg-reg-zero operation with condition code only
 2740 pipe_class ialu_cconly_reg_reg_zero(flagsReg cr, iRegI src1, iRegI src2, immI0 zero) %{
 2741     single_instruction;
 2742     cr    : E(write);
 2743     src1  : R(read);
 2744     src2  : R(read);
 2745     IALU  : R;
 2746 %}
 2747 
 2748 // Integer ALU reg-imm-zero operation with condition code only
 2749 pipe_class ialu_cconly_reg_imm_zero(flagsReg cr, iRegI src1, immI0 zero) %{
 2750     single_instruction;
 2751     cr    : E(write);
 2752     src1  : R(read);
 2753     IALU  : R;
 2754 %}
 2755 
 2756 // Integer ALU reg-reg operation with condition code, src1 modified
 2757 pipe_class ialu_cc_rwreg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
 2758     single_instruction;
 2759     cr    : E(write);
 2760     src1  : E(write);
 2761     src1  : R(read);
 2762     src2  : R(read);
 2763     IALU  : R;
 2764 %}
 2765 
 2766 pipe_class cmpL_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg cr ) %{
 2767     multiple_bundles;
 2768     dst   : E(write)+4;
 2769     cr    : E(write);
 2770     src1  : R(read);
 2771     src2  : R(read);
 2772     IALU  : R(3);
 2773     BR    : R(2);
 2774 %}
 2775 
 2776 // Integer ALU operation
 2777 pipe_class ialu_none(iRegI dst) %{
 2778     single_instruction;
 2779     dst   : E(write);
 2780     IALU  : R;
 2781 %}
 2782 
 2783 // Integer ALU reg operation
 2784 pipe_class ialu_reg(iRegI dst, iRegI src) %{
 2785     single_instruction; may_have_no_code;
 2786     dst   : E(write);
 2787     src   : R(read);
 2788     IALU  : R;
 2789 %}
 2790 
 2791 // Integer ALU reg conditional operation
 2792 // This instruction has a 1 cycle stall, and cannot execute
 2793 // in the same cycle as the instruction setting the condition
 2794 // code. We kludge this by pretending to read the condition code
 2795 // 1 cycle earlier, and by marking the functional units as busy
 2796 // for 2 cycles with the result available 1 cycle later than
 2797 // is really the case.
 2798 pipe_class ialu_reg_flags( iRegI op2_out, iRegI op2_in, iRegI op1, flagsReg cr ) %{
 2799     single_instruction;
 2800     op2_out : C(write);
 2801     op1     : R(read);
 2802     cr      : R(read);       // This is really E, with a 1 cycle stall
 2803     BR      : R(2);
 2804     MS      : R(2);
 2805 %}
 2806 
 2807 // Integer ALU reg operation
 2808 pipe_class ialu_move_reg_L_to_I(iRegI dst, iRegL src) %{
 2809     single_instruction; may_have_no_code;
 2810     dst   : E(write);
 2811     src   : R(read);
 2812     IALU  : R;
 2813 %}
 2814 pipe_class ialu_move_reg_I_to_L(iRegL dst, iRegI src) %{
 2815     single_instruction; may_have_no_code;
 2816     dst   : E(write);
 2817     src   : R(read);
 2818     IALU  : R;
 2819 %}
 2820 
 2821 // Two integer ALU reg operations
 2822 pipe_class ialu_reg_2(iRegL dst, iRegL src) %{
 2823     instruction_count(2);
 2824     dst   : E(write);
 2825     src   : R(read);
 2826     A0    : R;
 2827     A1    : R;
 2828 %}
 2829 
 2830 // Two integer ALU reg operations
 2831 pipe_class ialu_move_reg_L_to_L(iRegL dst, iRegL src) %{
 2832     instruction_count(2); may_have_no_code;
 2833     dst   : E(write);
 2834     src   : R(read);
 2835     A0    : R;
 2836     A1    : R;
 2837 %}
 2838 
 2839 // Integer ALU imm operation
 2840 pipe_class ialu_imm(iRegI dst) %{
 2841     single_instruction;
 2842     dst   : E(write);
 2843     IALU  : R;
 2844 %}
 2845 
 2846 pipe_class ialu_imm_n(iRegI dst) %{
 2847     single_instruction;
 2848     dst   : E(write);
 2849     IALU  : R;
 2850 %}
 2851 
 2852 // Integer ALU reg-reg with carry operation
 2853 pipe_class ialu_reg_reg_cy(iRegI dst, iRegI src1, iRegI src2, iRegI cy) %{
 2854     single_instruction;
 2855     dst   : E(write);
 2856     src1  : R(read);
 2857     src2  : R(read);
 2858     IALU  : R;
 2859 %}
 2860 
 2861 // Integer ALU cc operation
 2862 pipe_class ialu_cc(iRegI dst, flagsReg cc) %{
 2863     single_instruction;
 2864     dst   : E(write);
 2865     cc    : R(read);
 2866     IALU  : R;
 2867 %}
 2868 
 2869 // Integer ALU cc / second IALU operation
 2870 pipe_class ialu_reg_ialu( iRegI dst, iRegI src ) %{
 2871     instruction_count(1); multiple_bundles;
 2872     dst   : E(write)+1;
 2873     src   : R(read);
 2874     IALU  : R;
 2875 %}
 2876 
 2877 // Integer ALU cc / second IALU operation
 2878 pipe_class ialu_reg_reg_ialu( iRegI dst, iRegI p, iRegI q ) %{
 2879     instruction_count(1); multiple_bundles;
 2880     dst   : E(write)+1;
 2881     p     : R(read);
 2882     q     : R(read);
 2883     IALU  : R;
 2884 %}
 2885 
 2886 // Integer ALU hi-lo-reg operation
 2887 pipe_class ialu_hi_lo_reg(iRegI dst, immI src) %{
 2888     instruction_count(1); multiple_bundles;
 2889     dst   : E(write)+1;
 2890     IALU  : R(2);
 2891 %}
 2892 
 2893 // Long Constant
 2894 pipe_class loadConL( iRegL dst, immL src ) %{
 2895     instruction_count(2); multiple_bundles;
 2896     dst   : E(write)+1;
 2897     IALU  : R(2);
 2898     IALU  : R(2);
 2899 %}
 2900 
 2901 // Pointer Constant
 2902 pipe_class loadConP( iRegP dst, immP src ) %{
 2903     instruction_count(0); multiple_bundles;
 2904     fixed_latency(6);
 2905 %}
 2906 
 2907 // Long Constant small
 2908 pipe_class loadConLlo( iRegL dst, immL src ) %{
 2909     instruction_count(2);
 2910     dst   : E(write);
 2911     IALU  : R;
 2912     IALU  : R;
 2913 %}
 2914 
 2915 // [PHH] This is wrong for 64-bit.  See LdImmF/D.
 2916 pipe_class loadConFD(regF dst, immF src, iRegP tmp) %{
 2917     instruction_count(1); multiple_bundles;
 2918     src   : R(read);
 2919     dst   : M(write)+1;
 2920     IALU  : R;
 2921     MS    : E;
 2922 %}
 2923 
 2924 // Integer ALU nop operation
 2925 pipe_class ialu_nop() %{
 2926     single_instruction;
 2927     IALU  : R;
 2928 %}
 2929 
 2930 // Integer ALU nop operation
 2931 pipe_class ialu_nop_A0() %{
 2932     single_instruction;
 2933     A0    : R;
 2934 %}
 2935 
 2936 // Integer ALU nop operation
 2937 pipe_class ialu_nop_A1() %{
 2938     single_instruction;
 2939     A1    : R;
 2940 %}
 2941 
 2942 // Integer Multiply reg-reg operation
 2943 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 2944     single_instruction;
 2945     dst   : E(write);
 2946     src1  : R(read);
 2947     src2  : R(read);
 2948     MS    : R(5);
 2949 %}
 2950 
 2951 pipe_class mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 2952     single_instruction;
 2953     dst   : E(write)+4;
 2954     src1  : R(read);
 2955     src2  : R(read);
 2956     MS    : R(6);
 2957 %}
 2958 
 2959 // Integer Divide reg-reg
 2960 pipe_class sdiv_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI temp, flagsReg cr) %{
 2961     instruction_count(1); multiple_bundles;
 2962     dst   : E(write);
 2963     temp  : E(write);
 2964     src1  : R(read);
 2965     src2  : R(read);
 2966     temp  : R(read);
 2967     MS    : R(38);
 2968 %}
 2969 
 2970 // Long Divide
 2971 pipe_class divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 2972     dst  : E(write)+71;
 2973     src1 : R(read);
 2974     src2 : R(read)+1;
 2975     MS   : R(70);
 2976 %}
 2977 
 2978 // Floating Point Add Float
 2979 pipe_class faddF_reg_reg(regF dst, regF src1, regF src2) %{
 2980     single_instruction;
 2981     dst   : X(write);
 2982     src1  : E(read);
 2983     src2  : E(read);
 2984     FA    : R;
 2985 %}
 2986 
 2987 // Floating Point Add Double
 2988 pipe_class faddD_reg_reg(regD dst, regD src1, regD src2) %{
 2989     single_instruction;
 2990     dst   : X(write);
 2991     src1  : E(read);
 2992     src2  : E(read);
 2993     FA    : R;
 2994 %}
 2995 
 2996 // Floating Point Conditional Move based on integer flags
 2997 pipe_class int_conditional_float_move (cmpOp cmp, flagsReg cr, regF dst, regF src) %{
 2998     single_instruction;
 2999     dst   : X(write);
 3000     src   : E(read);
 3001     cr    : R(read);
 3002     FA    : R(2);
 3003     BR    : R(2);
 3004 %}
 3005 
 3006 // Floating Point Conditional Move based on integer flags
 3007 pipe_class int_conditional_double_move (cmpOp cmp, flagsReg cr, regD dst, regD src) %{
 3008     single_instruction;
 3009     dst   : X(write);
 3010     src   : E(read);
 3011     cr    : R(read);
 3012     FA    : R(2);
 3013     BR    : R(2);
 3014 %}
 3015 
 3016 // Floating Point Multiply Float
 3017 pipe_class fmulF_reg_reg(regF dst, regF src1, regF src2) %{
 3018     single_instruction;
 3019     dst   : X(write);
 3020     src1  : E(read);
 3021     src2  : E(read);
 3022     FM    : R;
 3023 %}
 3024 
 3025 // Floating Point Multiply Double
 3026 pipe_class fmulD_reg_reg(regD dst, regD src1, regD src2) %{
 3027     single_instruction;
 3028     dst   : X(write);
 3029     src1  : E(read);
 3030     src2  : E(read);
 3031     FM    : R;
 3032 %}
 3033 
 3034 // Floating Point Divide Float
 3035 pipe_class fdivF_reg_reg(regF dst, regF src1, regF src2) %{
 3036     single_instruction;
 3037     dst   : X(write);
 3038     src1  : E(read);
 3039     src2  : E(read);
 3040     FM    : R;
 3041     FDIV  : C(14);
 3042 %}
 3043 
 3044 // Floating Point Divide Double
 3045 pipe_class fdivD_reg_reg(regD dst, regD src1, regD src2) %{
 3046     single_instruction;
 3047     dst   : X(write);
 3048     src1  : E(read);
 3049     src2  : E(read);
 3050     FM    : R;
 3051     FDIV  : C(17);
 3052 %}
 3053 
 3054 // Floating Point Move/Negate/Abs Float
 3055 pipe_class faddF_reg(regF dst, regF src) %{
 3056     single_instruction;
 3057     dst   : W(write);
 3058     src   : E(read);
 3059     FA    : R(1);
 3060 %}
 3061 
 3062 // Floating Point Move/Negate/Abs Double
 3063 pipe_class faddD_reg(regD dst, regD src) %{
 3064     single_instruction;
 3065     dst   : W(write);
 3066     src   : E(read);
 3067     FA    : R;
 3068 %}
 3069 
 3070 // Floating Point Convert F->D
 3071 pipe_class fcvtF2D(regD dst, regF src) %{
 3072     single_instruction;
 3073     dst   : X(write);
 3074     src   : E(read);
 3075     FA    : R;
 3076 %}
 3077 
 3078 // Floating Point Convert I->D
 3079 pipe_class fcvtI2D(regD dst, regF src) %{
 3080     single_instruction;
 3081     dst   : X(write);
 3082     src   : E(read);
 3083     FA    : R;
 3084 %}
 3085 
 3086 // Floating Point Convert LHi->D
 3087 pipe_class fcvtLHi2D(regD dst, regD src) %{
 3088     single_instruction;
 3089     dst   : X(write);
 3090     src   : E(read);
 3091     FA    : R;
 3092 %}
 3093 
 3094 // Floating Point Convert L->D
 3095 pipe_class fcvtL2D(regD dst, iRegL src) %{
 3096     single_instruction;
 3097     dst   : X(write);
 3098     src   : E(read);
 3099     FA    : R;
 3100 %}
 3101 
 3102 // Floating Point Convert L->F
 3103 pipe_class fcvtL2F(regF dst, iRegL src) %{
 3104     single_instruction;
 3105     dst   : X(write);
 3106     src   : E(read);
 3107     FA    : R;
 3108 %}
 3109 
 3110 // Floating Point Convert D->F
 3111 pipe_class fcvtD2F(regD dst, regF src) %{
 3112     single_instruction;
 3113     dst   : X(write);
 3114     src   : E(read);
 3115     FA    : R;
 3116 %}
 3117 
 3118 // Floating Point Convert I->L
 3119 pipe_class fcvtI2L(regD dst, regF src) %{
 3120     single_instruction;
 3121     dst   : X(write);
 3122     src   : E(read);
 3123     FA    : R;
 3124 %}
 3125 
 3126 // Floating Point Convert D->F
 3127 pipe_class fcvtD2I(iRegI dst, regD src, flagsReg cr) %{
 3128     instruction_count(1); multiple_bundles;
 3129     dst   : X(write)+6;
 3130     src   : E(read);
 3131     FA    : R;
 3132 %}
 3133 
 3134 // Floating Point Convert D->L
 3135 pipe_class fcvtD2L(regD dst, regD src, flagsReg cr) %{
 3136     instruction_count(1); multiple_bundles;
 3137     dst   : X(write)+6;
 3138     src   : E(read);
 3139     FA    : R;
 3140 %}
 3141 
 3142 // Floating Point Convert F->I
 3143 pipe_class fcvtF2I(regF dst, regF src, flagsReg cr) %{
 3144     instruction_count(1); multiple_bundles;
 3145     dst   : X(write)+6;
 3146     src   : E(read);
 3147     FA    : R;
 3148 %}
 3149 
 3150 // Floating Point Convert F->L
 3151 pipe_class fcvtF2L(regD dst, regF src, flagsReg cr) %{
 3152     instruction_count(1); multiple_bundles;
 3153     dst   : X(write)+6;
 3154     src   : E(read);
 3155     FA    : R;
 3156 %}
 3157 
 3158 // Floating Point Convert I->F
 3159 pipe_class fcvtI2F(regF dst, regF src) %{
 3160     single_instruction;
 3161     dst   : X(write);
 3162     src   : E(read);
 3163     FA    : R;
 3164 %}
 3165 
 3166 // Floating Point Compare
 3167 pipe_class faddF_fcc_reg_reg_zero(flagsRegF cr, regF src1, regF src2, immI0 zero) %{
 3168     single_instruction;
 3169     cr    : X(write);
 3170     src1  : E(read);
 3171     src2  : E(read);
 3172     FA    : R;
 3173 %}
 3174 
 3175 // Floating Point Compare
 3176 pipe_class faddD_fcc_reg_reg_zero(flagsRegF cr, regD src1, regD src2, immI0 zero) %{
 3177     single_instruction;
 3178     cr    : X(write);
 3179     src1  : E(read);
 3180     src2  : E(read);
 3181     FA    : R;
 3182 %}
 3183 
 3184 // Floating Add Nop
 3185 pipe_class fadd_nop() %{
 3186     single_instruction;
 3187     FA  : R;
 3188 %}
 3189 
 3190 // Integer Store to Memory
 3191 pipe_class istore_mem_reg(memoryI mem, iRegI src) %{
 3192     single_instruction;
 3193     mem   : R(read);
 3194     src   : C(read);
 3195     MS    : R;
 3196 %}
 3197 
 3198 // Integer Store to Memory
 3199 pipe_class istore_mem_spORreg(memoryI mem, sp_ptr_RegP src) %{
 3200     single_instruction;
 3201     mem   : R(read);
 3202     src   : C(read);
 3203     MS    : R;
 3204 %}
 3205 
 3206 // Float Store
 3207 pipe_class fstoreF_mem_reg(memoryF mem, RegF src) %{
 3208     single_instruction;
 3209     mem : R(read);
 3210     src : C(read);
 3211     MS  : R;
 3212 %}
 3213 
 3214 // Float Store
 3215 pipe_class fstoreF_mem_zero(memoryF mem, immF0 src) %{
 3216     single_instruction;
 3217     mem : R(read);
 3218     MS  : R;
 3219 %}
 3220 
 3221 // Double Store
 3222 pipe_class fstoreD_mem_reg(memoryD mem, RegD src) %{
 3223     instruction_count(1);
 3224     mem : R(read);
 3225     src : C(read);
 3226     MS  : R;
 3227 %}
 3228 
 3229 // Double Store
 3230 pipe_class fstoreD_mem_zero(memoryD mem, immD0 src) %{
 3231     single_instruction;
 3232     mem : R(read);
 3233     MS  : R;
 3234 %}
 3235 
 3236 // Integer Load (when sign bit propagation not needed)
 3237 pipe_class iload_mem(iRegI dst, memoryI mem) %{
 3238     single_instruction;
 3239     mem : R(read);
 3240     dst : C(write);
 3241     MS  : R;
 3242 %}
 3243 
 3244 // Integer Load (when sign bit propagation or masking is needed)
 3245 pipe_class iload_mask_mem(iRegI dst, memoryI mem) %{
 3246     single_instruction;
 3247     mem : R(read);
 3248     dst : M(write);
 3249     MS  : R;
 3250 %}
 3251 
 3252 // Float Load
 3253 pipe_class floadF_mem(regF dst, memoryF mem) %{
 3254     single_instruction;
 3255     mem : R(read);
 3256     dst : M(write);
 3257     MS  : R;
 3258 %}
 3259 
 3260 // Float Load
 3261 pipe_class floadD_mem(regD dst, memoryD mem) %{
 3262     instruction_count(1); multiple_bundles; // Again, unaligned argument is only multiple case
 3263     mem : R(read);
 3264     dst : M(write);
 3265     MS  : R;
 3266 %}
 3267 
 3268 // Memory Nop
 3269 pipe_class mem_nop() %{
 3270     single_instruction;
 3271     MS  : R;
 3272 %}
 3273 
 3274 pipe_class sethi(iRegP dst, immI src) %{
 3275     single_instruction;
 3276     dst  : E(write);
 3277     IALU : R;
 3278 %}
 3279 
 3280 pipe_class loadPollP(iRegP poll) %{
 3281     single_instruction;
 3282     poll : R(read);
 3283     MS   : R;
 3284 %}
 3285 
 3286 pipe_class br(Universe br, label labl) %{
 3287     single_instruction_with_delay_slot;
 3288     BR  : R;
 3289 %}
 3290 
 3291 pipe_class br_cc(Universe br, cmpOp cmp, flagsReg cr, label labl) %{
 3292     single_instruction_with_delay_slot;
 3293     cr    : E(read);
 3294     BR    : R;
 3295 %}
 3296 
 3297 pipe_class br_reg(Universe br, cmpOp cmp, iRegI op1, label labl) %{
 3298     single_instruction_with_delay_slot;
 3299     op1 : E(read);
 3300     BR  : R;
 3301     MS  : R;
 3302 %}
 3303 
 3304 pipe_class br_nop() %{
 3305     single_instruction;
 3306     BR  : R;
 3307 %}
 3308 
 3309 pipe_class simple_call(method meth) %{
 3310     instruction_count(2); multiple_bundles; force_serialization;
 3311     fixed_latency(100);
 3312     BR  : R(1);
 3313     MS  : R(1);
 3314     A0  : R(1);
 3315 %}
 3316 
 3317 pipe_class compiled_call(method meth) %{
 3318     instruction_count(1); multiple_bundles; force_serialization;
 3319     fixed_latency(100);
 3320     MS  : R(1);
 3321 %}
 3322 
 3323 pipe_class call(method meth) %{
 3324     instruction_count(0); multiple_bundles; force_serialization;
 3325     fixed_latency(100);
 3326 %}
 3327 
 3328 pipe_class tail_call(Universe ignore, label labl) %{
 3329     single_instruction; has_delay_slot;
 3330     fixed_latency(100);
 3331     BR  : R(1);
 3332     MS  : R(1);
 3333 %}
 3334 
 3335 pipe_class ret(Universe ignore) %{
 3336     single_instruction; has_delay_slot;
 3337     BR  : R(1);
 3338     MS  : R(1);
 3339 %}
 3340 
 3341 // The real do-nothing guy
 3342 pipe_class empty( ) %{
 3343     instruction_count(0);
 3344 %}
 3345 
 3346 pipe_class long_memory_op() %{
 3347     instruction_count(0); multiple_bundles; force_serialization;
 3348     fixed_latency(25);
 3349     MS  : R(1);
 3350 %}
 3351 
 3352 // Check-cast
 3353 pipe_class partial_subtype_check_pipe(Universe ignore, iRegP array, iRegP match ) %{
 3354     array : R(read);
 3355     match  : R(read);
 3356     IALU   : R(2);
 3357     BR     : R(2);
 3358     MS     : R;
 3359 %}
 3360 
 3361 // Convert FPU flags into +1,0,-1
 3362 pipe_class floating_cmp( iRegI dst, regF src1, regF src2 ) %{
 3363     src1  : E(read);
 3364     src2  : E(read);
 3365     dst   : E(write);
 3366     FA    : R;
 3367     MS    : R(2);
 3368     BR    : R(2);
 3369 %}
 3370 
 3371 // Compare for p < q, and conditionally add y
 3372 pipe_class cadd_cmpltmask( iRegI p, iRegI q, iRegI y ) %{
 3373     p     : E(read);
 3374     q     : E(read);
 3375     y     : E(read);
 3376     IALU  : R(3)
 3377 %}
 3378 
 3379 // Perform a compare, then move conditionally in a branch delay slot.
 3380 pipe_class min_max( iRegI src2, iRegI srcdst ) %{
 3381     src2   : E(read);
 3382     srcdst : E(read);
 3383     IALU   : R;
 3384     BR     : R;
 3385 %}
 3386 
 3387 // Define the class for the Nop node
 3388 define %{
 3389    MachNop = ialu_nop;
 3390 %}
 3391 
 3392 %}
 3393 
 3394 //----------INSTRUCTIONS-------------------------------------------------------
 3395 
 3396 //------------Special Nop instructions for bundling - no match rules-----------
 3397 // Nop using the A0 functional unit
 3398 instruct Nop_A0() %{
 3399   ins_pipe(ialu_nop_A0);
 3400 %}
 3401 
 3402 // Nop using the A1 functional unit
 3403 instruct Nop_A1( ) %{
 3404   ins_pipe(ialu_nop_A1);
 3405 %}
 3406 
 3407 // Nop using the memory functional unit
 3408 instruct Nop_MS( ) %{
 3409   ins_pipe(mem_nop);
 3410 %}
 3411 
 3412 // Nop using the floating add functional unit
 3413 instruct Nop_FA( ) %{
 3414   ins_pipe(fadd_nop);
 3415 %}
 3416 
 3417 // Nop using the branch functional unit
 3418 instruct Nop_BR( ) %{
 3419   ins_pipe(br_nop);
 3420 %}
 3421 
 3422 //----------Load/Store/Move Instructions---------------------------------------
 3423 //----------Load Instructions--------------------------------------------------
 3424 // Load Byte (8bit signed)
 3425 instruct loadB(iRegI dst, memoryB mem) %{
 3426   match(Set dst (LoadB mem));
 3427   ins_cost(MEMORY_REF_COST);
 3428 
 3429   size(4);
 3430   format %{ "LDRSB   $dst,$mem\t! byte -> int" %}
 3431   ins_encode %{
 3432     __ ldrsb($dst$$Register, $mem$$Address);
 3433   %}
 3434   ins_pipe(iload_mask_mem);
 3435 %}
 3436 
 3437 // Load Byte (8bit signed) into a Long Register
 3438 instruct loadB2L(iRegL dst, memoryB mem) %{
 3439   match(Set dst (ConvI2L (LoadB mem)));
 3440   ins_cost(MEMORY_REF_COST);
 3441 
 3442   size(8);
 3443   format %{ "LDRSB $dst.lo,$mem\t! byte -> long\n\t"
 3444             "ASR   $dst.hi,$dst.lo,31" %}
 3445   ins_encode %{
 3446     __ ldrsb($dst$$Register, $mem$$Address);
 3447     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
 3448   %}
 3449   ins_pipe(iload_mask_mem);
 3450 %}
 3451 
 3452 // Load Unsigned Byte (8bit UNsigned) into an int reg
 3453 instruct loadUB(iRegI dst, memoryB mem) %{
 3454   match(Set dst (LoadUB mem));
 3455   ins_cost(MEMORY_REF_COST);
 3456 
 3457   size(4);
 3458   format %{ "LDRB   $dst,$mem\t! ubyte -> int" %}
 3459   ins_encode %{
 3460     __ ldrb($dst$$Register, $mem$$Address);
 3461   %}
 3462   ins_pipe(iload_mem);
 3463 %}
 3464 
 3465 // Load Unsigned Byte (8bit UNsigned) into a Long Register
 3466 instruct loadUB2L(iRegL dst, memoryB mem) %{
 3467   match(Set dst (ConvI2L (LoadUB mem)));
 3468   ins_cost(MEMORY_REF_COST);
 3469 
 3470   size(8);
 3471   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
 3472             "MOV   $dst.hi,0" %}
 3473   ins_encode %{
 3474     __ ldrb($dst$$Register, $mem$$Address);
 3475     __ mov($dst$$Register->successor(), 0);
 3476   %}
 3477   ins_pipe(iload_mem);
 3478 %}
 3479 
 3480 // Load Unsigned Byte (8 bit UNsigned) with immediate mask into Long Register
 3481 instruct loadUB2L_limmI(iRegL dst, memoryB mem, limmIlow8 mask) %{
 3482   match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
 3483 
 3484   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 3485   size(12);
 3486   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
 3487             "MOV   $dst.hi,0\n\t"
 3488             "AND  $dst.lo,$dst.lo,$mask" %}
 3489   ins_encode %{
 3490     __ ldrb($dst$$Register, $mem$$Address);
 3491     __ mov($dst$$Register->successor(), 0);
 3492     __ andr($dst$$Register, $dst$$Register, limmI_low($mask$$constant, 8));
 3493   %}
 3494   ins_pipe(iload_mem);
 3495 %}
 3496 
 3497 // Load Short (16bit signed)
 3498 
 3499 instruct loadS(iRegI dst, memoryS mem) %{
 3500   match(Set dst (LoadS mem));
 3501   ins_cost(MEMORY_REF_COST);
 3502 
 3503   size(4);
 3504   format %{ "LDRSH   $dst,$mem\t! short" %}
 3505   ins_encode %{
 3506     __ ldrsh($dst$$Register, $mem$$Address);
 3507   %}
 3508   ins_pipe(iload_mask_mem);
 3509 %}
 3510 
 3511 // Load Short (16 bit signed) to Byte (8 bit signed)
 3512 instruct loadS2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
 3513   match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
 3514   ins_cost(MEMORY_REF_COST);
 3515 
 3516   size(4);
 3517 
 3518   format %{ "LDRSB   $dst,$mem\t! short -> byte" %}
 3519   ins_encode %{
 3520     __ ldrsb($dst$$Register, $mem$$Address);
 3521   %}
 3522   ins_pipe(iload_mask_mem);
 3523 %}
 3524 
 3525 // Load Short (16bit signed) into a Long Register
 3526 instruct loadS2L(iRegL dst, memoryS mem) %{
 3527   match(Set dst (ConvI2L (LoadS mem)));
 3528   ins_cost(MEMORY_REF_COST);
 3529 
 3530   size(8);
 3531   format %{ "LDRSH $dst.lo,$mem\t! short -> long\n\t"
 3532             "ASR   $dst.hi,$dst.lo,31" %}
 3533   ins_encode %{
 3534     __ ldrsh($dst$$Register, $mem$$Address);
 3535     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
 3536   %}
 3537   ins_pipe(iload_mask_mem);
 3538 %}
 3539 
 3540 // Load Unsigned Short/Char (16bit UNsigned)
 3541 
 3542 
 3543 instruct loadUS(iRegI dst, memoryS mem) %{
 3544   match(Set dst (LoadUS mem));
 3545   ins_cost(MEMORY_REF_COST);
 3546 
 3547   size(4);
 3548   format %{ "LDRH   $dst,$mem\t! ushort/char" %}
 3549   ins_encode %{
 3550     __ ldrh($dst$$Register, $mem$$Address);
 3551   %}
 3552   ins_pipe(iload_mem);
 3553 %}
 3554 
 3555 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
 3556 instruct loadUS2B(iRegI dst, memoryB mem, immI_24 twentyfour) %{
 3557   match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
 3558   ins_cost(MEMORY_REF_COST);
 3559 
 3560   size(4);
 3561   format %{ "LDRSB   $dst,$mem\t! ushort -> byte" %}
 3562   ins_encode %{
 3563     __ ldrsb($dst$$Register, $mem$$Address);
 3564   %}
 3565   ins_pipe(iload_mask_mem);
 3566 %}
 3567 
 3568 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register
 3569 instruct loadUS2L(iRegL dst, memoryS mem) %{
 3570   match(Set dst (ConvI2L (LoadUS mem)));
 3571   ins_cost(MEMORY_REF_COST);
 3572 
 3573   size(8);
 3574   format %{ "LDRH  $dst.lo,$mem\t! short -> long\n\t"
 3575             "MOV   $dst.hi, 0" %}
 3576   ins_encode %{
 3577     __ ldrh($dst$$Register, $mem$$Address);
 3578     __ mov($dst$$Register->successor(), 0);
 3579   %}
 3580   ins_pipe(iload_mem);
 3581 %}
 3582 
 3583 // Load Unsigned Short/Char (16bit UNsigned) with mask 0xFF into a Long Register
 3584 instruct loadUS2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
 3585   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
 3586   ins_cost(MEMORY_REF_COST);
 3587 
 3588   size(8);
 3589   format %{ "LDRB  $dst.lo,$mem\t! \n\t"
 3590             "MOV   $dst.hi, 0" %}
 3591   ins_encode %{
 3592     __ ldrb($dst$$Register, $mem$$Address);
 3593     __ mov($dst$$Register->successor(), 0);
 3594   %}
 3595   ins_pipe(iload_mem);
 3596 %}
 3597 
 3598 // Load Unsigned Short/Char (16bit UNsigned) with a immediate mask into a Long Register
 3599 instruct loadUS2L_limmI(iRegL dst, memoryS mem, limmI mask) %{
 3600   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
 3601   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 3602 
 3603   size(12);
 3604   format %{ "LDRH   $dst,$mem\t! ushort/char & mask -> long\n\t"
 3605             "MOV    $dst.hi, 0\n\t"
 3606             "AND    $dst,$dst,$mask" %}
 3607   ins_encode %{
 3608     __ ldrh($dst$$Register, $mem$$Address);
 3609     __ mov($dst$$Register->successor(), 0);
 3610     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
 3611   %}
 3612   ins_pipe(iload_mem);
 3613 %}
 3614 
 3615 // Load Integer
 3616 
 3617 
 3618 instruct loadI(iRegI dst, memoryI mem) %{
 3619   match(Set dst (LoadI mem));
 3620   ins_cost(MEMORY_REF_COST);
 3621 
 3622   size(4);
 3623   format %{ "ldr_s32 $dst,$mem\t! int" %}
 3624   ins_encode %{
 3625     __ ldr_s32($dst$$Register, $mem$$Address);
 3626   %}
 3627   ins_pipe(iload_mem);
 3628 %}
 3629 
 3630 // Load Integer to Byte (8 bit signed)
 3631 instruct loadI2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
 3632   match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
 3633   ins_cost(MEMORY_REF_COST);
 3634 
 3635   size(4);
 3636 
 3637   format %{ "LDRSB   $dst,$mem\t! int -> byte" %}
 3638   ins_encode %{
 3639     __ ldrsb($dst$$Register, $mem$$Address);
 3640   %}
 3641   ins_pipe(iload_mask_mem);
 3642 %}
 3643 
 3644 // Load Integer to Unsigned Byte (8 bit UNsigned)
 3645 instruct loadI2UB(iRegI dst, memoryB mem, immI_255 mask) %{
 3646   match(Set dst (AndI (LoadI mem) mask));
 3647   ins_cost(MEMORY_REF_COST);
 3648 
 3649   size(4);
 3650 
 3651   format %{ "LDRB   $dst,$mem\t! int -> ubyte" %}
 3652   ins_encode %{
 3653     __ ldrb($dst$$Register, $mem$$Address);
 3654   %}
 3655   ins_pipe(iload_mask_mem);
 3656 %}
 3657 
 3658 // Load Integer to Short (16 bit signed)
 3659 instruct loadI2S(iRegI dst, memoryS mem, immI_16 sixteen) %{
 3660   match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
 3661   ins_cost(MEMORY_REF_COST);
 3662 
 3663   size(4);
 3664   format %{ "LDRSH   $dst,$mem\t! int -> short" %}
 3665   ins_encode %{
 3666     __ ldrsh($dst$$Register, $mem$$Address);
 3667   %}
 3668   ins_pipe(iload_mask_mem);
 3669 %}
 3670 
 3671 // Load Integer to Unsigned Short (16 bit UNsigned)
 3672 instruct loadI2US(iRegI dst, memoryS mem, immI_65535 mask) %{
 3673   match(Set dst (AndI (LoadI mem) mask));
 3674   ins_cost(MEMORY_REF_COST);
 3675 
 3676   size(4);
 3677   format %{ "LDRH   $dst,$mem\t! int -> ushort/char" %}
 3678   ins_encode %{
 3679     __ ldrh($dst$$Register, $mem$$Address);
 3680   %}
 3681   ins_pipe(iload_mask_mem);
 3682 %}
 3683 
 3684 // Load Integer into a Long Register
 3685 instruct loadI2L(iRegL dst, memoryI mem) %{
 3686   match(Set dst (ConvI2L (LoadI mem)));
 3687   ins_cost(MEMORY_REF_COST);
 3688 
 3689   size(8);
 3690   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
 3691             "ASR   $dst.hi,$dst.lo,31\t! int->long" %}
 3692   ins_encode %{
 3693     __ ldr($dst$$Register, $mem$$Address);
 3694     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
 3695   %}
 3696   ins_pipe(iload_mask_mem);
 3697 %}
 3698 
 3699 // Load Integer with mask 0xFF into a Long Register
 3700 instruct loadI2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
 3701   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3702   ins_cost(MEMORY_REF_COST);
 3703 
 3704   size(8);
 3705   format %{ "LDRB   $dst.lo,$mem\t! int & 0xFF -> long\n\t"
 3706             "MOV    $dst.hi, 0" %}
 3707   ins_encode %{
 3708     __ ldrb($dst$$Register, $mem$$Address);
 3709     __ mov($dst$$Register->successor(), 0);
 3710   %}
 3711   ins_pipe(iload_mem);
 3712 %}
 3713 
 3714 // Load Integer with mask 0xFFFF into a Long Register
 3715 instruct loadI2L_immI_65535(iRegL dst, memoryS mem, immI_65535 mask) %{
 3716   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3717   ins_cost(MEMORY_REF_COST);
 3718 
 3719   size(8);
 3720   format %{ "LDRH   $dst,$mem\t! int & 0xFFFF -> long\n\t"
 3721             "MOV    $dst.hi, 0" %}
 3722   ins_encode %{
 3723     __ ldrh($dst$$Register, $mem$$Address);
 3724     __ mov($dst$$Register->successor(), 0);
 3725   %}
 3726   ins_pipe(iload_mask_mem);
 3727 %}
 3728 
 3729 // Load Integer with a 31-bit immediate mask into a Long Register
 3730 instruct loadI2L_limmU31(iRegL dst, memoryI mem, limmU31 mask) %{
 3731   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3732   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 3733 
 3734   size(12);
 3735   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
 3736             "MOV    $dst.hi, 0\n\t"
 3737             "AND   $dst,$dst,$mask" %}
 3738 
 3739   ins_encode %{
 3740     __ ldr($dst$$Register, $mem$$Address);
 3741     __ mov($dst$$Register->successor(), 0);
 3742     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
 3743   %}
 3744   ins_pipe(iload_mem);
 3745 %}
 3746 
 3747 // Load Integer with a 31-bit mask into a Long Register
 3748 // FIXME: use iRegI mask, remove tmp?
 3749 instruct loadI2L_immU31(iRegL dst, memoryI mem, immU31 mask, iRegI tmp) %{
 3750   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3751   effect(TEMP dst, TEMP tmp);
 3752 
 3753   ins_cost(MEMORY_REF_COST + 4*DEFAULT_COST);
 3754   size(20);
 3755   format %{ "LDR      $mem,$dst\t! int & 31-bit mask -> long\n\t"
 3756             "MOV      $dst.hi, 0\n\t"
 3757             "MOV_SLOW $tmp,$mask\n\t"
 3758             "AND      $dst,$tmp,$dst" %}
 3759   ins_encode %{
 3760     __ ldr($dst$$Register, $mem$$Address);
 3761     __ mov($dst$$Register->successor(), 0);
 3762     __ mov_slow($tmp$$Register, $mask$$constant);
 3763     __ andr($dst$$Register, $dst$$Register, $tmp$$Register);
 3764   %}
 3765   ins_pipe(iload_mem);
 3766 %}
 3767 
 3768 // Load Unsigned Integer into a Long Register
 3769 instruct loadUI2L(iRegL dst, memoryI mem, immL_32bits mask) %{
 3770   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
 3771   ins_cost(MEMORY_REF_COST);
 3772 
 3773   size(8);
 3774   format %{ "LDR   $dst.lo,$mem\t! uint -> long\n\t"
 3775             "MOV   $dst.hi,0" %}
 3776   ins_encode %{
 3777     __ ldr($dst$$Register, $mem$$Address);
 3778     __ mov($dst$$Register->successor(), 0);
 3779   %}
 3780   ins_pipe(iload_mem);
 3781 %}
 3782 
 3783 // Load Long
 3784 
 3785 
 3786 instruct loadL(iRegLd dst, memoryL mem ) %{
 3787   predicate(!((LoadLNode*)n)->require_atomic_access());
 3788   match(Set dst (LoadL mem));
 3789   effect(TEMP dst);
 3790   ins_cost(MEMORY_REF_COST);
 3791 
 3792   size(4);
 3793   format %{ "ldr_64  $dst,$mem\t! long" %}
 3794   ins_encode %{
 3795     __ ldr_64($dst$$Register, $mem$$Address);
 3796   %}
 3797   ins_pipe(iload_mem);
 3798 %}
 3799 
 3800 instruct loadL_2instr(iRegL dst, memorylong mem ) %{
 3801   predicate(!((LoadLNode*)n)->require_atomic_access());
 3802   match(Set dst (LoadL mem));
 3803   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
 3804 
 3805   size(8);
 3806   format %{ "LDR    $dst.lo,$mem \t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
 3807             "LDR    $dst.hi,$mem+4 or $mem" %}
 3808   ins_encode %{
 3809     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 3810     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 3811 
 3812     if ($dst$$Register == reg_to_register_object($mem$$base)) {
 3813       __ ldr($dst$$Register->successor(), Amemhi);
 3814       __ ldr($dst$$Register, Amemlo);
 3815     } else {
 3816       __ ldr($dst$$Register, Amemlo);
 3817       __ ldr($dst$$Register->successor(), Amemhi);
 3818     }
 3819   %}
 3820   ins_pipe(iload_mem);
 3821 %}
 3822 
 3823 instruct loadL_volatile(iRegL dst, indirect mem ) %{
 3824   predicate(((LoadLNode*)n)->require_atomic_access());
 3825   match(Set dst (LoadL mem));
 3826   ins_cost(MEMORY_REF_COST);
 3827 
 3828   size(4);
 3829   format %{ "LDMIA    $dst,$mem\t! long" %}
 3830   ins_encode %{
 3831     // FIXME: why is ldmia considered atomic?  Should be ldrexd
 3832     RegisterSet set($dst$$Register);
 3833     set = set | reg_to_register_object($dst$$reg + 1);
 3834     __ ldmia(reg_to_register_object($mem$$base), set);
 3835   %}
 3836   ins_pipe(iload_mem);
 3837 %}
 3838 
 3839 instruct loadL_volatile_fp(iRegL dst, memoryD mem ) %{
 3840   predicate(((LoadLNode*)n)->require_atomic_access());
 3841   match(Set dst (LoadL mem));
 3842   ins_cost(MEMORY_REF_COST);
 3843 
 3844   size(8);
 3845   format %{ "FLDD      S14, $mem"
 3846             "FMRRD    $dst, S14\t! long \n't" %}
 3847   ins_encode %{
 3848     __ fldd(S14, $mem$$Address);
 3849     __ fmrrd($dst$$Register, $dst$$Register->successor(), S14);
 3850   %}
 3851   ins_pipe(iload_mem);
 3852 %}
 3853 
 3854 instruct loadL_unaligned(iRegL dst, memorylong mem ) %{
 3855   match(Set dst (LoadL_unaligned mem));
 3856   ins_cost(MEMORY_REF_COST);
 3857 
 3858   size(8);
 3859   format %{ "LDR    $dst.lo,$mem\t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
 3860             "LDR    $dst.hi,$mem+4" %}
 3861   ins_encode %{
 3862     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 3863     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 3864 
 3865     if ($dst$$Register == reg_to_register_object($mem$$base)) {
 3866       __ ldr($dst$$Register->successor(), Amemhi);
 3867       __ ldr($dst$$Register, Amemlo);
 3868     } else {
 3869       __ ldr($dst$$Register, Amemlo);
 3870       __ ldr($dst$$Register->successor(), Amemhi);
 3871     }
 3872   %}
 3873   ins_pipe(iload_mem);
 3874 %}
 3875 
 3876 // Load Range
 3877 instruct loadRange(iRegI dst, memoryI mem) %{
 3878   match(Set dst (LoadRange mem));
 3879   ins_cost(MEMORY_REF_COST);
 3880 
 3881   size(4);
 3882   format %{ "LDR_u32 $dst,$mem\t! range" %}
 3883   ins_encode %{
 3884     __ ldr_u32($dst$$Register, $mem$$Address);
 3885   %}
 3886   ins_pipe(iload_mem);
 3887 %}
 3888 
 3889 // Load Pointer
 3890 
 3891 
 3892 instruct loadP(iRegP dst, memoryP mem) %{
 3893   predicate(!(UseG1GC && n->as_Load()->barrier_data() != 0));
 3894   match(Set dst (LoadP mem));
 3895   ins_cost(MEMORY_REF_COST);
 3896   size(4);
 3897 
 3898   format %{ "LDR   $dst,$mem\t! ptr" %}
 3899   ins_encode %{
 3900     __ ldr($dst$$Register, $mem$$Address);
 3901   %}
 3902   ins_pipe(iload_mem);
 3903 %}
 3904 
 3905 #ifdef XXX
 3906 // FIXME XXXX
 3907 //instruct loadSP(iRegP dst, memoryP mem) %{
 3908 instruct loadSP(SPRegP dst, memoryP mem, iRegP tmp) %{
 3909   match(Set dst (LoadP mem));
 3910   effect(TEMP tmp);
 3911   ins_cost(MEMORY_REF_COST+1);
 3912   size(8);
 3913 
 3914   format %{ "LDR   $tmp,$mem\t! ptr\n\t"
 3915             "MOV   $dst,$tmp\t! ptr" %}
 3916   ins_encode %{
 3917     __ ldr($tmp$$Register, $mem$$Address);
 3918     __ mov($dst$$Register, $tmp$$Register);
 3919   %}
 3920   ins_pipe(iload_mem);
 3921 %}
 3922 #endif
 3923 
 3924 #ifdef _LP64
 3925 // Load Compressed Pointer
 3926 
 3927 // XXX This variant shouldn't be necessary if 6217251 is implemented
 3928 instruct loadNoff(iRegN dst, memoryScaledI mem, aimmX off, iRegP tmp) %{
 3929   match(Set dst (LoadN (AddP mem off)));
 3930   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
 3931   effect(TEMP tmp);
 3932   size(4 * 2);
 3933 
 3934   format %{ "ldr_u32 $dst,$mem+$off\t! compressed ptr temp=$tmp" %}
 3935   ins_encode %{
 3936     Register base = reg_to_register_object($mem$$base);
 3937     __ add($tmp$$Register, base, $off$$constant);
 3938     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 3939     __ ldr_u32($dst$$Register, nmem);
 3940   %}
 3941   ins_pipe(iload_mem);
 3942 %}
 3943 
 3944 instruct loadN(iRegN dst, memoryI mem) %{
 3945   match(Set dst (LoadN mem));
 3946   ins_cost(MEMORY_REF_COST);
 3947   size(4);
 3948 
 3949   format %{ "ldr_u32 $dst,$mem\t! compressed ptr" %}
 3950   ins_encode %{
 3951     __ ldr_u32($dst$$Register, $mem$$Address);
 3952   %}
 3953   ins_pipe(iload_mem);
 3954 %}
 3955 #endif
 3956 
 3957 // Load Klass Pointer
 3958 instruct loadKlass(iRegP dst, memoryI mem) %{
 3959   match(Set dst (LoadKlass mem));
 3960   ins_cost(MEMORY_REF_COST);
 3961   size(4);
 3962 
 3963   format %{ "LDR   $dst,$mem\t! klass ptr" %}
 3964   ins_encode %{
 3965     __ ldr($dst$$Register, $mem$$Address);
 3966   %}
 3967   ins_pipe(iload_mem);
 3968 %}
 3969 
 3970 #ifdef _LP64
 3971 // Load narrow Klass Pointer
 3972 instruct loadNKlass(iRegN dst, memoryI mem) %{
 3973   match(Set dst (LoadNKlass mem));
 3974   ins_cost(MEMORY_REF_COST);
 3975   size(4);
 3976 
 3977   format %{ "ldr_u32 $dst,$mem\t! compressed klass ptr" %}
 3978   ins_encode %{
 3979     __ ldr_u32($dst$$Register, $mem$$Address);
 3980   %}
 3981   ins_pipe(iload_mem);
 3982 %}
 3983 #endif
 3984 
 3985 
 3986 instruct loadD(regD dst, memoryD mem) %{
 3987   match(Set dst (LoadD mem));
 3988   ins_cost(MEMORY_REF_COST);
 3989 
 3990   size(4);
 3991   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
 3992   // only LDREXD and STREXD are 64-bit single-copy atomic
 3993   format %{ "FLDD   $dst,$mem" %}
 3994   ins_encode %{
 3995     __ ldr_double($dst$$FloatRegister, $mem$$Address);
 3996   %}
 3997   ins_pipe(floadD_mem);
 3998 %}
 3999 
 4000 // Load Double - UNaligned
 4001 instruct loadD_unaligned(regD_low dst, memoryF2 mem ) %{
 4002   match(Set dst (LoadD_unaligned mem));
 4003   ins_cost(MEMORY_REF_COST*2+DEFAULT_COST);
 4004   size(8);
 4005   format %{ "FLDS    $dst.lo,$mem\t! misaligned double\n"
 4006           "\tFLDS    $dst.hi,$mem+4\t!" %}
 4007   ins_encode %{
 4008     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 4009     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 4010       __ flds($dst$$FloatRegister, Amemlo);
 4011       __ flds($dst$$FloatRegister->successor(), Amemhi);
 4012   %}
 4013   ins_pipe(iload_mem);
 4014 %}
 4015 
 4016 
 4017 instruct loadF(regF dst, memoryF mem) %{
 4018   match(Set dst (LoadF mem));
 4019 
 4020   ins_cost(MEMORY_REF_COST);
 4021   size(4);
 4022   format %{ "FLDS    $dst,$mem" %}
 4023   ins_encode %{
 4024     __ ldr_float($dst$$FloatRegister, $mem$$Address);
 4025   %}
 4026   ins_pipe(floadF_mem);
 4027 %}
 4028 
 4029 
 4030 // // Load Constant
 4031 instruct loadConI( iRegI dst, immI src ) %{
 4032   match(Set dst src);
 4033   ins_cost(DEFAULT_COST * 3/2);
 4034   format %{ "MOV_SLOW    $dst, $src" %}
 4035   ins_encode %{
 4036     __ mov_slow($dst$$Register, $src$$constant);
 4037   %}
 4038   ins_pipe(ialu_hi_lo_reg);
 4039 %}
 4040 
 4041 instruct loadConIMov( iRegI dst, immIMov src ) %{
 4042   match(Set dst src);
 4043   size(4);
 4044   format %{ "MOV    $dst, $src" %}
 4045   ins_encode %{
 4046     __ mov($dst$$Register, $src$$constant);
 4047   %}
 4048   ins_pipe(ialu_imm);
 4049 %}
 4050 
 4051 instruct loadConIMovn( iRegI dst, immIRotn src ) %{
 4052   match(Set dst src);
 4053   size(4);
 4054   format %{ "MVN    $dst, ~$src" %}
 4055   ins_encode %{
 4056     __ mvn($dst$$Register, ~$src$$constant);
 4057   %}
 4058   ins_pipe(ialu_imm_n);
 4059 %}
 4060 
 4061 instruct loadConI16( iRegI dst, immI16 src ) %{
 4062   match(Set dst src);
 4063   size(4);
 4064   format %{ "MOVW    $dst, $src" %}
 4065   ins_encode %{
 4066     __ movw($dst$$Register, $src$$constant);
 4067   %}
 4068   ins_pipe(ialu_imm_n);
 4069 %}
 4070 
 4071 instruct loadConP(iRegP dst, immP src) %{
 4072   match(Set dst src);
 4073   ins_cost(DEFAULT_COST * 3/2);
 4074   format %{ "MOV_SLOW    $dst,$src\t!ptr" %}
 4075   ins_encode %{
 4076     relocInfo::relocType constant_reloc = _opnds[1]->constant_reloc();
 4077     intptr_t val = $src$$constant;
 4078     if (constant_reloc == relocInfo::oop_type) {
 4079       __ mov_oop($dst$$Register, (jobject)val);
 4080     } else if (constant_reloc == relocInfo::metadata_type) {
 4081       __ mov_metadata($dst$$Register, (Metadata*)val);
 4082     } else {
 4083       __ mov_slow($dst$$Register, val);
 4084     }
 4085   %}
 4086   ins_pipe(loadConP);
 4087 %}
 4088 
 4089 
 4090 instruct loadConL(iRegL dst, immL src) %{
 4091   match(Set dst src);
 4092   ins_cost(DEFAULT_COST * 4);
 4093   format %{ "MOV_SLOW   $dst.lo, $src & 0x0FFFFFFFFL \t! long\n\t"
 4094             "MOV_SLOW   $dst.hi, $src >> 32" %}
 4095   ins_encode %{
 4096     __ mov_slow(reg_to_register_object($dst$$reg), $src$$constant & 0x0FFFFFFFFL);
 4097     __ mov_slow(reg_to_register_object($dst$$reg + 1), ((julong)($src$$constant)) >> 32);
 4098   %}
 4099   ins_pipe(loadConL);
 4100 %}
 4101 
 4102 instruct loadConL16( iRegL dst, immL16 src ) %{
 4103   match(Set dst src);
 4104   ins_cost(DEFAULT_COST * 2);
 4105 
 4106   size(8);
 4107   format %{ "MOVW    $dst.lo, $src \n\t"
 4108             "MOVW    $dst.hi, 0 \n\t" %}
 4109   ins_encode %{
 4110     __ movw($dst$$Register, $src$$constant);
 4111     __ movw($dst$$Register->successor(), 0);
 4112   %}
 4113   ins_pipe(ialu_imm);
 4114 %}
 4115 
 4116 instruct loadConF_imm8(regF dst, imm8F src) %{
 4117   match(Set dst src);
 4118   ins_cost(DEFAULT_COST);
 4119   size(4);
 4120 
 4121   format %{ "FCONSTS      $dst, $src"%}
 4122 
 4123   ins_encode %{
 4124     __ fconsts($dst$$FloatRegister, Assembler::float_num($src$$constant).imm8());
 4125   %}
 4126   ins_pipe(loadConFD); // FIXME
 4127 %}
 4128 
 4129 
 4130 instruct loadConF(regF dst, immF src, iRegI tmp) %{
 4131   match(Set dst src);
 4132   ins_cost(DEFAULT_COST * 2);
 4133   effect(TEMP tmp);
 4134   size(3*4);
 4135 
 4136   format %{ "MOV_SLOW  $tmp, $src\n\t"
 4137             "FMSR      $dst, $tmp"%}
 4138 
 4139   ins_encode %{
 4140     // FIXME revisit once 6961697 is in
 4141     union {
 4142       jfloat f;
 4143       int i;
 4144     } v;
 4145     v.f = $src$$constant;
 4146     __ mov_slow($tmp$$Register, v.i);
 4147     __ fmsr($dst$$FloatRegister, $tmp$$Register);
 4148   %}
 4149   ins_pipe(loadConFD); // FIXME
 4150 %}
 4151 
 4152 instruct loadConD_imm8(regD dst, imm8D src) %{
 4153   match(Set dst src);
 4154   ins_cost(DEFAULT_COST);
 4155   size(4);
 4156 
 4157   format %{ "FCONSTD      $dst, $src"%}
 4158 
 4159   ins_encode %{
 4160     __ fconstd($dst$$FloatRegister, Assembler::double_num($src$$constant).imm8());
 4161   %}
 4162   ins_pipe(loadConFD); // FIXME
 4163 %}
 4164 
 4165 instruct loadConD(regD dst, immD src, iRegP tmp) %{
 4166   match(Set dst src);
 4167   effect(TEMP tmp);
 4168   ins_cost(MEMORY_REF_COST);
 4169   format %{ "FLDD  $dst, [$constanttablebase + $constantoffset]\t! load from constant table: double=$src" %}
 4170 
 4171   ins_encode %{
 4172     Register r = $constanttablebase;
 4173     int offset  = $constantoffset($src);
 4174     if (!is_memoryD(offset)) {                // can't use a predicate
 4175                                               // in load constant instructs
 4176       __ add_slow($tmp$$Register, r, offset);
 4177       r = $tmp$$Register;
 4178       offset = 0;
 4179     }
 4180     __ ldr_double($dst$$FloatRegister, Address(r, offset));
 4181   %}
 4182   ins_pipe(loadConFD);
 4183 %}
 4184 
 4185 // Prefetch instructions.
 4186 // Must be safe to execute with invalid address (cannot fault).
 4187 
 4188 instruct prefetchAlloc_mp( memoryP mem ) %{
 4189   predicate(VM_Version::has_multiprocessing_extensions());
 4190   match( PrefetchAllocation mem );
 4191   ins_cost(MEMORY_REF_COST);
 4192   size(4);
 4193 
 4194   format %{ "PLDW $mem\t! Prefetch allocation" %}
 4195   ins_encode %{
 4196     __ pldw($mem$$Address);
 4197   %}
 4198   ins_pipe(iload_mem);
 4199 %}
 4200 
 4201 instruct prefetchAlloc_sp( memoryP mem ) %{
 4202   predicate(!VM_Version::has_multiprocessing_extensions());
 4203   match( PrefetchAllocation mem );
 4204   ins_cost(MEMORY_REF_COST);
 4205   size(4);
 4206 
 4207   format %{ "PLD $mem\t! Prefetch allocation" %}
 4208   ins_encode %{
 4209     __ pld($mem$$Address);
 4210   %}
 4211   ins_pipe(iload_mem);
 4212 %}
 4213 
 4214 
 4215 //----------Store Instructions-------------------------------------------------
 4216 // Store Byte
 4217 instruct storeB(memoryB mem, store_RegI src) %{
 4218   match(Set mem (StoreB mem src));
 4219   ins_cost(MEMORY_REF_COST);
 4220 
 4221   size(4);
 4222   format %{ "STRB    $src,$mem\t! byte" %}
 4223   ins_encode %{
 4224     __ strb($src$$Register, $mem$$Address);
 4225   %}
 4226   ins_pipe(istore_mem_reg);
 4227 %}
 4228 
 4229 // Store Char/Short
 4230 
 4231 
 4232 instruct storeC(memoryS mem, store_RegI src) %{
 4233   match(Set mem (StoreC mem src));
 4234   ins_cost(MEMORY_REF_COST);
 4235 
 4236   size(4);
 4237   format %{ "STRH    $src,$mem\t! short" %}
 4238   ins_encode %{
 4239     __ strh($src$$Register, $mem$$Address);
 4240   %}
 4241   ins_pipe(istore_mem_reg);
 4242 %}
 4243 
 4244 // Store Integer
 4245 
 4246 
 4247 instruct storeI(memoryI mem, store_RegI src) %{
 4248   match(Set mem (StoreI mem src));
 4249   ins_cost(MEMORY_REF_COST);
 4250 
 4251   size(4);
 4252   format %{ "str_32 $src,$mem" %}
 4253   ins_encode %{
 4254     __ str_32($src$$Register, $mem$$Address);
 4255   %}
 4256   ins_pipe(istore_mem_reg);
 4257 %}
 4258 
 4259 // Store Long
 4260 
 4261 
 4262 instruct storeL(memoryL mem, store_RegLd src) %{
 4263   predicate(!((StoreLNode*)n)->require_atomic_access());
 4264   match(Set mem (StoreL mem src));
 4265   ins_cost(MEMORY_REF_COST);
 4266 
 4267   size(4);
 4268   format %{ "str_64  $src,$mem\t! long\n\t" %}
 4269 
 4270   ins_encode %{
 4271     __ str_64($src$$Register, $mem$$Address);
 4272   %}
 4273   ins_pipe(istore_mem_reg);
 4274 %}
 4275 
 4276 instruct storeL_2instr(memorylong mem, iRegL src) %{
 4277   predicate(!((StoreLNode*)n)->require_atomic_access());
 4278   match(Set mem (StoreL mem src));
 4279   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
 4280 
 4281   size(8);
 4282   format %{ "STR    $src.lo,$mem\t! long\n\t"
 4283             "STR    $src.hi,$mem+4" %}
 4284 
 4285   ins_encode %{
 4286     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 4287     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 4288     __ str($src$$Register, Amemlo);
 4289     __ str($src$$Register->successor(), Amemhi);
 4290   %}
 4291   ins_pipe(istore_mem_reg);
 4292 %}
 4293 
 4294 instruct storeL_volatile(indirect mem, iRegL src) %{
 4295   predicate(((StoreLNode*)n)->require_atomic_access());
 4296   match(Set mem (StoreL mem src));
 4297   ins_cost(MEMORY_REF_COST);
 4298   size(4);
 4299   format %{ "STMIA    $src,$mem\t! long" %}
 4300   ins_encode %{
 4301     // FIXME: why is stmia considered atomic?  Should be strexd
 4302     RegisterSet set($src$$Register);
 4303     set = set | reg_to_register_object($src$$reg + 1);
 4304     __ stmia(reg_to_register_object($mem$$base), set);
 4305   %}
 4306   ins_pipe(istore_mem_reg);
 4307 %}
 4308 
 4309 instruct storeL_volatile_fp(memoryD mem, iRegL src) %{
 4310   predicate(((StoreLNode*)n)->require_atomic_access());
 4311   match(Set mem (StoreL mem src));
 4312   ins_cost(MEMORY_REF_COST);
 4313   size(8);
 4314   format %{ "FMDRR    S14, $src\t! long \n\t"
 4315             "FSTD     S14, $mem" %}
 4316   ins_encode %{
 4317     __ fmdrr(S14, $src$$Register, $src$$Register->successor());
 4318     __ fstd(S14, $mem$$Address);
 4319   %}
 4320   ins_pipe(istore_mem_reg);
 4321 %}
 4322 
 4323 #ifdef XXX
 4324 // Move SP Pointer
 4325 //instruct movSP(sp_ptr_RegP dst, SPRegP src) %{
 4326 //instruct movSP(iRegP dst, SPRegP src) %{
 4327 instruct movSP(store_ptr_RegP dst, SPRegP src) %{
 4328   match(Set dst src);
 4329 //predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con == TypeFunc::FramePtr);
 4330   ins_cost(MEMORY_REF_COST);
 4331   size(4);
 4332 
 4333   format %{ "MOV    $dst,$src\t! SP ptr\n\t" %}
 4334   ins_encode %{
 4335     assert(false, "XXX1 got here");
 4336     __ mov($dst$$Register, SP);
 4337     __ mov($dst$$Register, $src$$Register);
 4338   %}
 4339   ins_pipe(ialu_reg);
 4340 %}
 4341 #endif
 4342 
 4343 
 4344 // Store Pointer
 4345 
 4346 
 4347 instruct storeP(memoryP mem, store_ptr_RegP src) %{
 4348   predicate(!(UseG1GC && n->as_Store()->barrier_data() != 0));
 4349   match(Set mem (StoreP mem src));
 4350   ins_cost(MEMORY_REF_COST);
 4351   size(4);
 4352 
 4353   format %{ "STR    $src,$mem\t! ptr" %}
 4354   ins_encode %{
 4355     __ str($src$$Register, $mem$$Address);
 4356   %}
 4357   ins_pipe(istore_mem_spORreg);
 4358 %}
 4359 
 4360 
 4361 #ifdef _LP64
 4362 // Store Compressed Pointer
 4363 
 4364 
 4365 instruct storeN(memoryI mem, store_RegN src) %{
 4366   match(Set mem (StoreN mem src));
 4367   ins_cost(MEMORY_REF_COST);
 4368   size(4);
 4369 
 4370   format %{ "str_32 $src,$mem\t! compressed ptr" %}
 4371   ins_encode %{
 4372     __ str_32($src$$Register, $mem$$Address);
 4373   %}
 4374   ins_pipe(istore_mem_reg);
 4375 %}
 4376 
 4377 
 4378 // Store Compressed Klass Pointer
 4379 instruct storeNKlass(memoryI mem, store_RegN src) %{
 4380   match(Set mem (StoreNKlass mem src));
 4381   ins_cost(MEMORY_REF_COST);
 4382   size(4);
 4383 
 4384   format %{ "str_32 $src,$mem\t! compressed klass ptr" %}
 4385   ins_encode %{
 4386     __ str_32($src$$Register, $mem$$Address);
 4387   %}
 4388   ins_pipe(istore_mem_reg);
 4389 %}
 4390 #endif
 4391 
 4392 // Store Double
 4393 
 4394 
 4395 instruct storeD(memoryD mem, regD src) %{
 4396   match(Set mem (StoreD mem src));
 4397   ins_cost(MEMORY_REF_COST);
 4398 
 4399   size(4);
 4400   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
 4401   // only LDREXD and STREXD are 64-bit single-copy atomic
 4402   format %{ "FSTD   $src,$mem" %}
 4403   ins_encode %{
 4404     __ str_double($src$$FloatRegister, $mem$$Address);
 4405   %}
 4406   ins_pipe(fstoreD_mem_reg);
 4407 %}
 4408 
 4409 
 4410 // Store Float
 4411 
 4412 
 4413 instruct storeF( memoryF mem, regF src) %{
 4414   match(Set mem (StoreF mem src));
 4415   ins_cost(MEMORY_REF_COST);
 4416 
 4417   size(4);
 4418   format %{ "FSTS    $src,$mem" %}
 4419   ins_encode %{
 4420     __ str_float($src$$FloatRegister, $mem$$Address);
 4421   %}
 4422   ins_pipe(fstoreF_mem_reg);
 4423 %}
 4424 
 4425 
 4426 //----------MemBar Instructions-----------------------------------------------
 4427 // Memory barrier flavors
 4428 
 4429 // pattern-match out unnecessary membars
 4430 instruct membar_storestore() %{
 4431   match(MemBarStoreStore);
 4432   match(StoreStoreFence);
 4433   ins_cost(4*MEMORY_REF_COST);
 4434 
 4435   size(4);
 4436   format %{ "MEMBAR-storestore" %}
 4437   ins_encode %{
 4438     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore), noreg);
 4439   %}
 4440   ins_pipe(long_memory_op);
 4441 %}
 4442 
 4443 instruct membar_acquire() %{
 4444   match(MemBarAcquire);
 4445   match(LoadFence);
 4446   ins_cost(4*MEMORY_REF_COST);
 4447 
 4448   size(4);
 4449   format %{ "MEMBAR-acquire" %}
 4450   ins_encode %{
 4451     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), noreg);
 4452   %}
 4453   ins_pipe(long_memory_op);
 4454 %}
 4455 
 4456 instruct membar_acquire_lock() %{
 4457   match(MemBarAcquireLock);
 4458   ins_cost(0);
 4459 
 4460   size(0);
 4461   format %{ "!MEMBAR-acquire (CAS in prior FastLock so empty encoding)" %}
 4462   ins_encode( );
 4463   ins_pipe(empty);
 4464 %}
 4465 
 4466 instruct membar_release() %{
 4467   match(MemBarRelease);
 4468   match(StoreFence);
 4469   ins_cost(4*MEMORY_REF_COST);
 4470 
 4471   size(4);
 4472   format %{ "MEMBAR-release" %}
 4473   ins_encode %{
 4474     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), noreg);
 4475   %}
 4476   ins_pipe(long_memory_op);
 4477 %}
 4478 
 4479 instruct membar_release_lock() %{
 4480   match(MemBarReleaseLock);
 4481   ins_cost(0);
 4482 
 4483   size(0);
 4484   format %{ "!MEMBAR-release (CAS in succeeding FastUnlock so empty encoding)" %}
 4485   ins_encode( );
 4486   ins_pipe(empty);
 4487 %}
 4488 
 4489 instruct membar_volatile() %{
 4490   match(MemBarVolatile);
 4491   ins_cost(4*MEMORY_REF_COST);
 4492 
 4493   size(4);
 4494   format %{ "MEMBAR-volatile" %}
 4495   ins_encode %{
 4496     __ membar(MacroAssembler::StoreLoad, noreg);
 4497   %}
 4498   ins_pipe(long_memory_op);
 4499 %}
 4500 
 4501 instruct unnecessary_membar_volatile() %{
 4502   match(MemBarVolatile);
 4503   predicate(Matcher::post_store_load_barrier(n));
 4504   ins_cost(0);
 4505 
 4506   size(0);
 4507   format %{ "!MEMBAR-volatile (unnecessary so empty encoding)" %}
 4508   ins_encode( );
 4509   ins_pipe(empty);
 4510 %}
 4511 
 4512 //----------Register Move Instructions-----------------------------------------
 4513 
 4514 // Cast Index to Pointer for unsafe natives
 4515 instruct castX2P(iRegX src, iRegP dst) %{
 4516   match(Set dst (CastX2P src));
 4517 
 4518   format %{ "MOV    $dst,$src\t! IntX->Ptr if $dst != $src" %}
 4519   ins_encode %{
 4520     if ($dst$$Register !=  $src$$Register) {
 4521       __ mov($dst$$Register, $src$$Register);
 4522     }
 4523   %}
 4524   ins_pipe(ialu_reg);
 4525 %}
 4526 
 4527 // Cast Pointer to Index for unsafe natives
 4528 instruct castP2X(iRegP src, iRegX dst) %{
 4529   match(Set dst (CastP2X src));
 4530 
 4531   format %{ "MOV    $dst,$src\t! Ptr->IntX if $dst != $src" %}
 4532   ins_encode %{
 4533     if ($dst$$Register !=  $src$$Register) {
 4534       __ mov($dst$$Register, $src$$Register);
 4535     }
 4536   %}
 4537   ins_pipe(ialu_reg);
 4538 %}
 4539 
 4540 //----------Conditional Move---------------------------------------------------
 4541 // Conditional move
 4542 instruct cmovIP_reg(cmpOpP cmp, flagsRegP pcc, iRegI dst, iRegI src) %{
 4543   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
 4544   ins_cost(150);
 4545   size(4);
 4546   format %{ "MOV$cmp  $dst,$src\t! int" %}
 4547   ins_encode %{
 4548     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4549   %}
 4550   ins_pipe(ialu_reg);
 4551 %}
 4552 
 4553 
 4554 instruct cmovIP_immMov(cmpOpP cmp, flagsRegP pcc, iRegI dst, immIMov src) %{
 4555   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
 4556   ins_cost(140);
 4557   size(4);
 4558   format %{ "MOV$cmp  $dst,$src" %}
 4559   ins_encode %{
 4560     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4561   %}
 4562   ins_pipe(ialu_imm);
 4563 %}
 4564 
 4565 instruct cmovIP_imm16(cmpOpP cmp, flagsRegP pcc, iRegI dst, immI16 src) %{
 4566   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
 4567   ins_cost(140);
 4568   size(4);
 4569   format %{ "MOVw$cmp  $dst,$src" %}
 4570   ins_encode %{
 4571     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4572   %}
 4573   ins_pipe(ialu_imm);
 4574 %}
 4575 
 4576 instruct cmovI_reg(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src) %{
 4577   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4578   ins_cost(150);
 4579   size(4);
 4580   format %{ "MOV$cmp  $dst,$src" %}
 4581   ins_encode %{
 4582     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4583   %}
 4584   ins_pipe(ialu_reg);
 4585 %}
 4586 
 4587 
 4588 instruct cmovI_immMov(cmpOp cmp, flagsReg icc, iRegI dst, immIMov src) %{
 4589   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4590   ins_cost(140);
 4591   size(4);
 4592   format %{ "MOV$cmp  $dst,$src" %}
 4593   ins_encode %{
 4594     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4595   %}
 4596   ins_pipe(ialu_imm);
 4597 %}
 4598 
 4599 instruct cmovII_imm16(cmpOp cmp, flagsReg icc, iRegI dst, immI16 src) %{
 4600   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4601   ins_cost(140);
 4602   size(4);
 4603   format %{ "MOVw$cmp  $dst,$src" %}
 4604   ins_encode %{
 4605     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4606   %}
 4607   ins_pipe(ialu_imm);
 4608 %}
 4609 
 4610 instruct cmovII_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, iRegI src) %{
 4611   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4612   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4613             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4614             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4615             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4616   ins_cost(150);
 4617   size(4);
 4618   format %{ "MOV$cmp  $dst,$src" %}
 4619   ins_encode %{
 4620     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4621   %}
 4622   ins_pipe(ialu_reg);
 4623 %}
 4624 
 4625 instruct cmovII_immMov_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immIMov src) %{
 4626   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4627   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4628             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4629             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4630             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4631   ins_cost(140);
 4632   size(4);
 4633   format %{ "MOV$cmp  $dst,$src" %}
 4634   ins_encode %{
 4635     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4636   %}
 4637   ins_pipe(ialu_imm);
 4638 %}
 4639 
 4640 instruct cmovII_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immI16 src) %{
 4641   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4642   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4643             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4644             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4645             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4646   ins_cost(140);
 4647   size(4);
 4648   format %{ "MOVW$cmp  $dst,$src" %}
 4649   ins_encode %{
 4650     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4651   %}
 4652   ins_pipe(ialu_imm);
 4653 %}
 4654 
 4655 instruct cmovIIu_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
 4656   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4657   ins_cost(150);
 4658   size(4);
 4659   format %{ "MOV$cmp  $dst,$src" %}
 4660   ins_encode %{
 4661     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4662   %}
 4663   ins_pipe(ialu_reg);
 4664 %}
 4665 
 4666 instruct cmovIIu_immMov(cmpOpU cmp, flagsRegU icc, iRegI dst, immIMov src) %{
 4667   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4668   ins_cost(140);
 4669   size(4);
 4670   format %{ "MOV$cmp  $dst,$src" %}
 4671   ins_encode %{
 4672     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4673   %}
 4674   ins_pipe(ialu_imm);
 4675 %}
 4676 
 4677 instruct cmovIIu_imm16(cmpOpU cmp, flagsRegU icc, iRegI dst, immI16 src) %{
 4678   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4679   ins_cost(140);
 4680   size(4);
 4681   format %{ "MOVW$cmp  $dst,$src" %}
 4682   ins_encode %{
 4683     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4684   %}
 4685   ins_pipe(ialu_imm);
 4686 %}
 4687 
 4688 // Conditional move
 4689 instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{
 4690   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
 4691   ins_cost(150);
 4692   size(4);
 4693   format %{ "MOV$cmp  $dst,$src" %}
 4694   ins_encode %{
 4695     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4696   %}
 4697   ins_pipe(ialu_reg);
 4698 %}
 4699 
 4700 instruct cmovPP_imm(cmpOpP cmp, flagsRegP pcc, iRegP dst, immP0 src) %{
 4701   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
 4702   ins_cost(140);
 4703   size(4);
 4704   format %{ "MOV$cmp  $dst,$src" %}
 4705   ins_encode %{
 4706     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4707   %}
 4708   ins_pipe(ialu_imm);
 4709 %}
 4710 
 4711 // This instruction also works with CmpN so we don't need cmovPN_reg.
 4712 instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{
 4713   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4714   ins_cost(150);
 4715 
 4716   size(4);
 4717   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4718   ins_encode %{
 4719     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4720   %}
 4721   ins_pipe(ialu_reg);
 4722 %}
 4723 
 4724 instruct cmovPI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, iRegP src) %{
 4725   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4726   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4727             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4728             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4729             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4730   ins_cost(150);
 4731 
 4732   size(4);
 4733   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4734   ins_encode %{
 4735     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4736   %}
 4737   ins_pipe(ialu_reg);
 4738 %}
 4739 
 4740 instruct cmovPIu_reg(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src) %{
 4741   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4742   ins_cost(150);
 4743 
 4744   size(4);
 4745   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4746   ins_encode %{
 4747     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4748   %}
 4749   ins_pipe(ialu_reg);
 4750 %}
 4751 
 4752 instruct cmovPI_imm(cmpOp cmp, flagsReg icc, iRegP dst, immP0 src) %{
 4753   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4754   ins_cost(140);
 4755 
 4756   size(4);
 4757   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4758   ins_encode %{
 4759     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4760   %}
 4761   ins_pipe(ialu_imm);
 4762 %}
 4763 
 4764 instruct cmovPI_imm_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, immP0 src) %{
 4765   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4766   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4767             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4768             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4769             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4770   ins_cost(140);
 4771 
 4772   size(4);
 4773   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4774   ins_encode %{
 4775     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4776   %}
 4777   ins_pipe(ialu_imm);
 4778 %}
 4779 
 4780 instruct cmovPIu_imm(cmpOpU cmp, flagsRegU icc, iRegP dst, immP0 src) %{
 4781   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4782   ins_cost(140);
 4783 
 4784   size(4);
 4785   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4786   ins_encode %{
 4787     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4788   %}
 4789   ins_pipe(ialu_imm);
 4790 %}
 4791 
 4792 
 4793 // Conditional move
 4794 instruct cmovFP_reg(cmpOpP cmp, flagsRegP pcc, regF dst, regF src) %{
 4795   match(Set dst (CMoveF (Binary cmp pcc) (Binary dst src)));
 4796   ins_cost(150);
 4797   size(4);
 4798   format %{ "FCPYS$cmp $dst,$src" %}
 4799   ins_encode %{
 4800     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4801   %}
 4802   ins_pipe(int_conditional_float_move);
 4803 %}
 4804 
 4805 instruct cmovFI_reg(cmpOp cmp, flagsReg icc, regF dst, regF src) %{
 4806   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
 4807   ins_cost(150);
 4808 
 4809   size(4);
 4810   format %{ "FCPYS$cmp $dst,$src" %}
 4811   ins_encode %{
 4812     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4813   %}
 4814   ins_pipe(int_conditional_float_move);
 4815 %}
 4816 
 4817 instruct cmovFI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regF dst, regF src) %{
 4818   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
 4819   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4820             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4821             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4822             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4823   ins_cost(150);
 4824 
 4825   size(4);
 4826   format %{ "FCPYS$cmp $dst,$src" %}
 4827   ins_encode %{
 4828     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4829   %}
 4830   ins_pipe(int_conditional_float_move);
 4831 %}
 4832 
 4833 instruct cmovFIu_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src) %{
 4834   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
 4835   ins_cost(150);
 4836 
 4837   size(4);
 4838   format %{ "FCPYS$cmp $dst,$src" %}
 4839   ins_encode %{
 4840     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4841   %}
 4842   ins_pipe(int_conditional_float_move);
 4843 %}
 4844 
 4845 // Conditional move
 4846 instruct cmovDP_reg(cmpOpP cmp, flagsRegP pcc, regD dst, regD src) %{
 4847   match(Set dst (CMoveD (Binary cmp pcc) (Binary dst src)));
 4848   ins_cost(150);
 4849   size(4);
 4850   format %{ "FCPYD$cmp $dst,$src" %}
 4851   ins_encode %{
 4852     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4853   %}
 4854   ins_pipe(int_conditional_double_move);
 4855 %}
 4856 
 4857 instruct cmovDI_reg(cmpOp cmp, flagsReg icc, regD dst, regD src) %{
 4858   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
 4859   ins_cost(150);
 4860 
 4861   size(4);
 4862   format %{ "FCPYD$cmp $dst,$src" %}
 4863   ins_encode %{
 4864     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4865   %}
 4866   ins_pipe(int_conditional_double_move);
 4867 %}
 4868 
 4869 instruct cmovDI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regD dst, regD src) %{
 4870   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
 4871   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);
 4872   ins_cost(150);
 4873 
 4874   size(4);
 4875   format %{ "FCPYD$cmp $dst,$src" %}
 4876   ins_encode %{
 4877     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4878   %}
 4879   ins_pipe(int_conditional_double_move);
 4880 %}
 4881 
 4882 instruct cmovDIu_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src) %{
 4883   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
 4884   ins_cost(150);
 4885 
 4886   size(4);
 4887   format %{ "FCPYD$cmp $dst,$src" %}
 4888   ins_encode %{
 4889     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4890   %}
 4891   ins_pipe(int_conditional_double_move);
 4892 %}
 4893 
 4894 // Conditional move
 4895 instruct cmovLP_reg(cmpOpP cmp, flagsRegP pcc, iRegL dst, iRegL src) %{
 4896   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
 4897   ins_cost(150);
 4898 
 4899   size(8);
 4900   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 4901             "MOV$cmp  $dst.hi,$src.hi" %}
 4902   ins_encode %{
 4903     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4904     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 4905   %}
 4906   ins_pipe(ialu_reg);
 4907 %}
 4908 
 4909 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 4910 // (hi($con$$constant), lo($con$$constant)) becomes
 4911 instruct cmovLP_immRot(cmpOpP cmp, flagsRegP pcc, iRegL dst, immLlowRot src) %{
 4912   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
 4913   ins_cost(140);
 4914 
 4915   size(8);
 4916   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 4917             "MOV$cmp  $dst.hi,0" %}
 4918   ins_encode %{
 4919     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4920     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 4921   %}
 4922   ins_pipe(ialu_imm);
 4923 %}
 4924 
 4925 instruct cmovLP_imm16(cmpOpP cmp, flagsRegP pcc, iRegL dst, immL16 src) %{
 4926   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
 4927   ins_cost(140);
 4928 
 4929   size(8);
 4930   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 4931             "MOV$cmp  $dst.hi,0" %}
 4932   ins_encode %{
 4933     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4934     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 4935   %}
 4936   ins_pipe(ialu_imm);
 4937 %}
 4938 
 4939 instruct cmovLI_reg(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src) %{
 4940   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 4941   ins_cost(150);
 4942 
 4943   size(8);
 4944   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 4945             "MOV$cmp  $dst.hi,$src.hi" %}
 4946   ins_encode %{
 4947     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4948     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 4949   %}
 4950   ins_pipe(ialu_reg);
 4951 %}
 4952 
 4953 instruct cmovLI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, iRegL src) %{
 4954   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 4955   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4956             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4957             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4958             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4959   ins_cost(150);
 4960 
 4961   size(8);
 4962   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 4963             "MOV$cmp  $dst.hi,$src.hi" %}
 4964   ins_encode %{
 4965     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4966     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 4967   %}
 4968   ins_pipe(ialu_reg);
 4969 %}
 4970 
 4971 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 4972 // (hi($con$$constant), lo($con$$constant)) becomes
 4973 instruct cmovLI_immRot(cmpOp cmp, flagsReg icc, iRegL dst, immLlowRot src) %{
 4974   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 4975   ins_cost(140);
 4976 
 4977   size(8);
 4978   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 4979             "MOV$cmp  $dst.hi,0" %}
 4980   ins_encode %{
 4981     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4982     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 4983   %}
 4984   ins_pipe(ialu_imm);
 4985 %}
 4986 
 4987 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 4988 // (hi($con$$constant), lo($con$$constant)) becomes
 4989 instruct cmovLI_immRot_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immLlowRot src) %{
 4990   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 4991   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4992             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4993             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4994             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4995   ins_cost(140);
 4996 
 4997   size(8);
 4998   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 4999             "MOV$cmp  $dst.hi,0" %}
 5000   ins_encode %{
 5001     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5002     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5003   %}
 5004   ins_pipe(ialu_imm);
 5005 %}
 5006 
 5007 instruct cmovLI_imm16(cmpOp cmp, flagsReg icc, iRegL dst, immL16 src) %{
 5008   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5009   ins_cost(140);
 5010 
 5011   size(8);
 5012   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5013             "MOV$cmp  $dst.hi,0" %}
 5014   ins_encode %{
 5015     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5016     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5017   %}
 5018   ins_pipe(ialu_imm);
 5019 %}
 5020 
 5021 instruct cmovLI_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immL16 src) %{
 5022   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5023   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 5024             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 5025             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 5026             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 5027   ins_cost(140);
 5028 
 5029   size(8);
 5030   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5031             "MOV$cmp  $dst.hi,0" %}
 5032   ins_encode %{
 5033     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5034     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5035   %}
 5036   ins_pipe(ialu_imm);
 5037 %}
 5038 
 5039 instruct cmovLIu_reg(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src) %{
 5040   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5041   ins_cost(150);
 5042 
 5043   size(8);
 5044   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 5045             "MOV$cmp  $dst.hi,$src.hi" %}
 5046   ins_encode %{
 5047     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 5048     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 5049   %}
 5050   ins_pipe(ialu_reg);
 5051 %}
 5052 
 5053 
 5054 //----------OS and Locking Instructions----------------------------------------
 5055 
 5056 // This name is KNOWN by the ADLC and cannot be changed.
 5057 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
 5058 // for this guy.
 5059 instruct tlsLoadP(RthreadRegP dst) %{
 5060   match(Set dst (ThreadLocal));
 5061 
 5062   size(0);
 5063   ins_cost(0);
 5064   format %{ "! TLS is in $dst" %}
 5065   ins_encode( /*empty encoding*/ );
 5066   ins_pipe(ialu_none);
 5067 %}
 5068 
 5069 instruct checkCastPP( iRegP dst ) %{
 5070   match(Set dst (CheckCastPP dst));
 5071 
 5072   size(0);
 5073   format %{ "! checkcastPP of $dst" %}
 5074   ins_encode( /*empty encoding*/ );
 5075   ins_pipe(empty);
 5076 %}
 5077 
 5078 
 5079 instruct castPP( iRegP dst ) %{
 5080   match(Set dst (CastPP dst));
 5081   format %{ "! castPP of $dst" %}
 5082   ins_encode( /*empty encoding*/ );
 5083   ins_pipe(empty);
 5084 %}
 5085 
 5086 instruct castII( iRegI dst ) %{
 5087   match(Set dst (CastII dst));
 5088   format %{ "! castII of $dst" %}
 5089   ins_encode( /*empty encoding*/ );
 5090   ins_cost(0);
 5091   ins_pipe(empty);
 5092 %}
 5093 
 5094 instruct castLL( iRegL dst ) %{
 5095   match(Set dst (CastLL dst));
 5096   format %{ "! castLL of $dst" %}
 5097   ins_encode( /*empty encoding*/ );
 5098   ins_cost(0);
 5099   ins_pipe(empty);
 5100 %}
 5101 
 5102 instruct castFF( regF dst ) %{
 5103   match(Set dst (CastFF dst));
 5104   format %{ "! castFF of $dst" %}
 5105   ins_encode( /*empty encoding*/ );
 5106   ins_cost(0);
 5107   ins_pipe(empty);
 5108 %}
 5109 
 5110 instruct castDD( regD dst ) %{
 5111   match(Set dst (CastDD dst));
 5112   format %{ "! castDD of $dst" %}
 5113   ins_encode( /*empty encoding*/ );
 5114   ins_cost(0);
 5115   ins_pipe(empty);
 5116 %}
 5117 
 5118 instruct castVVD( vecD dst ) %{
 5119   match(Set dst (CastVV dst));
 5120   format %{ "! castVV of $dst" %}
 5121   ins_encode( /*empty encoding*/ );
 5122   ins_cost(0);
 5123   ins_pipe(empty);
 5124 %}
 5125 
 5126 instruct castVVX( vecX dst ) %{
 5127   match(Set dst (CastVV dst));
 5128   format %{ "! castVV of $dst" %}
 5129   ins_encode( /*empty encoding*/ );
 5130   ins_cost(0);
 5131   ins_pipe(empty);
 5132 %}
 5133 
 5134 
 5135 //----------Arithmetic Instructions--------------------------------------------
 5136 // Addition Instructions
 5137 // Register Addition
 5138 instruct addI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 5139   match(Set dst (AddI src1 src2));
 5140 
 5141   size(4);
 5142   format %{ "add_32 $dst,$src1,$src2\t! int" %}
 5143   ins_encode %{
 5144     __ add_32($dst$$Register, $src1$$Register, $src2$$Register);
 5145   %}
 5146   ins_pipe(ialu_reg_reg);
 5147 %}
 5148 
 5149 instruct addshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5150   match(Set dst (AddI (LShiftI src1 src2) src3));
 5151 
 5152   size(4);
 5153   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
 5154   ins_encode %{
 5155     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 5156   %}
 5157   ins_pipe(ialu_reg_reg);
 5158 %}
 5159 
 5160 
 5161 instruct addshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5162   match(Set dst (AddI (LShiftI src1 src2) src3));
 5163 
 5164   size(4);
 5165   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
 5166   ins_encode %{
 5167     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
 5168   %}
 5169   ins_pipe(ialu_reg_reg);
 5170 %}
 5171 
 5172 instruct addsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5173   match(Set dst (AddI (RShiftI src1 src2) src3));
 5174 
 5175   size(4);
 5176   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
 5177   ins_encode %{
 5178     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
 5179   %}
 5180   ins_pipe(ialu_reg_reg);
 5181 %}
 5182 
 5183 instruct addsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5184   match(Set dst (AddI (RShiftI src1 src2) src3));
 5185 
 5186   size(4);
 5187   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
 5188   ins_encode %{
 5189     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
 5190   %}
 5191   ins_pipe(ialu_reg_reg);
 5192 %}
 5193 
 5194 instruct addshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5195   match(Set dst (AddI (URShiftI src1 src2) src3));
 5196 
 5197   size(4);
 5198   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
 5199   ins_encode %{
 5200     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 5201   %}
 5202   ins_pipe(ialu_reg_reg);
 5203 %}
 5204 
 5205 instruct addshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5206   match(Set dst (AddI (URShiftI src1 src2) src3));
 5207 
 5208   size(4);
 5209   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
 5210   ins_encode %{
 5211     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 5212   %}
 5213   ins_pipe(ialu_reg_reg);
 5214 %}
 5215 
 5216 // Immediate Addition
 5217 instruct addI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
 5218   match(Set dst (AddI src1 src2));
 5219 
 5220   size(4);
 5221   format %{ "add_32 $dst,$src1,$src2\t! int" %}
 5222   ins_encode %{
 5223     __ add_32($dst$$Register, $src1$$Register, $src2$$constant);
 5224   %}
 5225   ins_pipe(ialu_reg_imm);
 5226 %}
 5227 
 5228 // Pointer Register Addition
 5229 instruct addP_reg_reg(iRegP dst, iRegP src1, iRegX src2) %{
 5230   match(Set dst (AddP src1 src2));
 5231 
 5232   size(4);
 5233   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
 5234   ins_encode %{
 5235     __ add($dst$$Register, $src1$$Register, $src2$$Register);
 5236   %}
 5237   ins_pipe(ialu_reg_reg);
 5238 %}
 5239 
 5240 
 5241 // shifted iRegX operand
 5242 operand shiftedX(iRegX src2, shimmX src3) %{
 5243 //constraint(ALLOC_IN_RC(sp_ptr_reg));
 5244   match(LShiftX src2 src3);
 5245 
 5246   op_cost(1);
 5247   format %{ "$src2 << $src3" %}
 5248   interface(MEMORY_INTER) %{
 5249     base($src2);
 5250     index(0xff);
 5251     scale($src3);
 5252     disp(0x0);
 5253   %}
 5254 %}
 5255 
 5256 instruct addshlP_reg_reg_imm(iRegP dst, iRegP src1, shiftedX src2) %{
 5257   match(Set dst (AddP src1 src2));
 5258 
 5259   ins_cost(DEFAULT_COST * 3/2);
 5260   size(4);
 5261   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
 5262   ins_encode %{
 5263     Register base = reg_to_register_object($src2$$base);
 5264     __ add($dst$$Register, $src1$$Register, AsmOperand(base, lsl, $src2$$scale));
 5265   %}
 5266   ins_pipe(ialu_reg_reg);
 5267 %}
 5268 
 5269 // Pointer Immediate Addition
 5270 instruct addP_reg_aimmX(iRegP dst, iRegP src1, aimmX src2) %{
 5271   match(Set dst (AddP src1 src2));
 5272 
 5273   size(4);
 5274   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
 5275   ins_encode %{
 5276     __ add($dst$$Register, $src1$$Register, $src2$$constant);
 5277   %}
 5278   ins_pipe(ialu_reg_imm);
 5279 %}
 5280 
 5281 // Long Addition
 5282 instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg ccr) %{
 5283   match(Set dst (AddL src1 src2));
 5284   effect(KILL ccr);
 5285   size(8);
 5286   format %{ "ADDS    $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
 5287             "ADC     $dst.hi,$src1.hi,$src2.hi" %}
 5288   ins_encode %{
 5289     __ adds($dst$$Register, $src1$$Register, $src2$$Register);
 5290     __ adc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 5291   %}
 5292   ins_pipe(ialu_reg_reg);
 5293 %}
 5294 
 5295 // TODO
 5296 
 5297 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5298 // (hi($con$$constant), lo($con$$constant)) becomes
 5299 instruct addL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg ccr) %{
 5300   match(Set dst (AddL src1 con));
 5301   effect(KILL ccr);
 5302   size(8);
 5303   format %{ "ADDS    $dst.lo,$src1.lo,$con\t! long\n\t"
 5304             "ADC     $dst.hi,$src1.hi,0" %}
 5305   ins_encode %{
 5306     __ adds($dst$$Register, $src1$$Register, $con$$constant);
 5307     __ adc($dst$$Register->successor(), $src1$$Register->successor(), 0);
 5308   %}
 5309   ins_pipe(ialu_reg_imm);
 5310 %}
 5311 
 5312 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
 5313 
 5314 instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegLd newval, iRegI res, iRegLd tmp, flagsReg ccr ) %{
 5315   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
 5316   effect( KILL ccr, TEMP tmp);
 5317   size(32);
 5318   format %{ "loop: \n\t"
 5319             "LDREXD   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
 5320             "CMP      $tmp.lo, $oldval.lo\n\t"
 5321             "CMP.eq   $tmp.hi, $oldval.hi\n\t"
 5322             "STREXD.eq $tmp, $newval, $mem\n\t"
 5323             "MOV.ne   $tmp, 0 \n\t"
 5324             "XORS.eq  $tmp,$tmp, 1 \n\t"
 5325             "B.eq     loop \n\t"
 5326             "MOV      $res, $tmp" %}
 5327   ins_encode %{
 5328     Label loop;
 5329     __ bind(loop);
 5330     __ ldrexd($tmp$$Register, $mem$$Address);
 5331     __ cmp($tmp$$Register, $oldval$$Register);
 5332     __ cmp($tmp$$Register->successor(), $oldval$$Register->successor(), eq);
 5333     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5334     __ mov($tmp$$Register, 0, ne);
 5335     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
 5336     __ b(loop, eq);
 5337     __ mov($res$$Register, $tmp$$Register);
 5338   %}
 5339   ins_pipe( long_memory_op );
 5340 %}
 5341 
 5342 
 5343 instruct compareAndSwapI_bool(memoryex mem, iRegI oldval, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
 5344   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
 5345   effect( KILL ccr, TEMP tmp);
 5346   size(28);
 5347   format %{ "loop: \n\t"
 5348             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
 5349             "CMP      $tmp, $oldval\n\t"
 5350             "STREX.eq $tmp, $newval, $mem\n\t"
 5351             "MOV.ne   $tmp, 0 \n\t"
 5352             "XORS.eq  $tmp,$tmp, 1 \n\t"
 5353             "B.eq     loop \n\t"
 5354             "MOV      $res, $tmp" %}
 5355 
 5356   ins_encode %{
 5357     Label loop;
 5358     __ bind(loop);
 5359     __ ldrex($tmp$$Register,$mem$$Address);
 5360     __ cmp($tmp$$Register, $oldval$$Register);
 5361     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5362     __ mov($tmp$$Register, 0, ne);
 5363     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
 5364     __ b(loop, eq);
 5365     __ mov($res$$Register, $tmp$$Register);
 5366   %}
 5367   ins_pipe( long_memory_op );
 5368 %}
 5369 
 5370 instruct compareAndSwapP_bool(memoryex mem, iRegP oldval, iRegP newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
 5371   predicate(!(UseG1GC && n->as_LoadStore()->barrier_data() != 0));
 5372   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
 5373   effect( KILL ccr, TEMP tmp);
 5374   size(28);
 5375   format %{ "loop: \n\t"
 5376             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
 5377             "CMP      $tmp, $oldval\n\t"
 5378             "STREX.eq $tmp, $newval, $mem\n\t"
 5379             "MOV.ne   $tmp, 0 \n\t"
 5380             "EORS.eq  $tmp,$tmp, 1 \n\t"
 5381             "B.eq     loop \n\t"
 5382             "MOV      $res, $tmp" %}
 5383 
 5384   ins_encode %{
 5385     Label loop;
 5386     __ bind(loop);
 5387     __ ldrex($tmp$$Register,$mem$$Address);
 5388     __ cmp($tmp$$Register, $oldval$$Register);
 5389     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5390     __ mov($tmp$$Register, 0, ne);
 5391     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
 5392     __ b(loop, eq);
 5393     __ mov($res$$Register, $tmp$$Register);
 5394   %}
 5395   ins_pipe( long_memory_op );
 5396 %}
 5397 
 5398 instruct xaddI_aimmI_no_res(memoryex mem, aimmI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5399   predicate(n->as_LoadStore()->result_not_used());
 5400   match(Set dummy (GetAndAddI mem add));
 5401   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
 5402   size(20);
 5403   format %{ "loop: \n\t"
 5404             "LDREX    $tmp1, $mem\n\t"
 5405             "ADD      $tmp1, $tmp1, $add\n\t"
 5406             "STREX    $tmp2, $tmp1, $mem\n\t"
 5407             "CMP      $tmp2, 0 \n\t"
 5408             "B.ne     loop \n\t" %}
 5409 
 5410   ins_encode %{
 5411     Label loop;
 5412     __ bind(loop);
 5413     __ ldrex($tmp1$$Register,$mem$$Address);
 5414     __ add($tmp1$$Register, $tmp1$$Register, $add$$constant);
 5415     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5416     __ cmp($tmp2$$Register, 0);
 5417     __ b(loop, ne);
 5418   %}
 5419   ins_pipe( long_memory_op );
 5420 %}
 5421 
 5422 instruct xaddI_reg_no_res(memoryex mem, iRegI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5423   predicate(n->as_LoadStore()->result_not_used());
 5424   match(Set dummy (GetAndAddI mem add));
 5425   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
 5426   size(20);
 5427   format %{ "loop: \n\t"
 5428             "LDREX    $tmp1, $mem\n\t"
 5429             "ADD      $tmp1, $tmp1, $add\n\t"
 5430             "STREX    $tmp2, $tmp1, $mem\n\t"
 5431             "CMP      $tmp2, 0 \n\t"
 5432             "B.ne     loop \n\t" %}
 5433 
 5434   ins_encode %{
 5435     Label loop;
 5436     __ bind(loop);
 5437     __ ldrex($tmp1$$Register,$mem$$Address);
 5438     __ add($tmp1$$Register, $tmp1$$Register, $add$$Register);
 5439     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5440     __ cmp($tmp2$$Register, 0);
 5441     __ b(loop, ne);
 5442   %}
 5443   ins_pipe( long_memory_op );
 5444 %}
 5445 
 5446 instruct xaddI_aimmI(memoryex mem, aimmI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5447   match(Set res (GetAndAddI mem add));
 5448   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5449   size(20);
 5450   format %{ "loop: \n\t"
 5451             "LDREX    $res, $mem\n\t"
 5452             "ADD      $tmp1, $res, $add\n\t"
 5453             "STREX    $tmp2, $tmp1, $mem\n\t"
 5454             "CMP      $tmp2, 0 \n\t"
 5455             "B.ne     loop \n\t" %}
 5456 
 5457   ins_encode %{
 5458     Label loop;
 5459     __ bind(loop);
 5460     __ ldrex($res$$Register,$mem$$Address);
 5461     __ add($tmp1$$Register, $res$$Register, $add$$constant);
 5462     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5463     __ cmp($tmp2$$Register, 0);
 5464     __ b(loop, ne);
 5465   %}
 5466   ins_pipe( long_memory_op );
 5467 %}
 5468 
 5469 instruct xaddI_reg(memoryex mem, iRegI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5470   match(Set res (GetAndAddI mem add));
 5471   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5472   size(20);
 5473   format %{ "loop: \n\t"
 5474             "LDREX    $res, $mem\n\t"
 5475             "ADD      $tmp1, $res, $add\n\t"
 5476             "STREX    $tmp2, $tmp1, $mem\n\t"
 5477             "CMP      $tmp2, 0 \n\t"
 5478             "B.ne     loop \n\t" %}
 5479 
 5480   ins_encode %{
 5481     Label loop;
 5482     __ bind(loop);
 5483     __ ldrex($res$$Register,$mem$$Address);
 5484     __ add($tmp1$$Register, $res$$Register, $add$$Register);
 5485     __ strex($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 instruct xaddL_reg_no_res(memoryex mem, iRegL add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5493   predicate(n->as_LoadStore()->result_not_used());
 5494   match(Set dummy (GetAndAddL mem add));
 5495   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
 5496   size(24);
 5497   format %{ "loop: \n\t"
 5498             "LDREXD   $tmp1, $mem\n\t"
 5499             "ADDS     $tmp1.lo, $tmp1.lo, $add.lo\n\t"
 5500             "ADC      $tmp1.hi, $tmp1.hi, $add.hi\n\t"
 5501             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5502             "CMP      $tmp2, 0 \n\t"
 5503             "B.ne     loop \n\t" %}
 5504 
 5505   ins_encode %{
 5506     Label loop;
 5507     __ bind(loop);
 5508     __ ldrexd($tmp1$$Register, $mem$$Address);
 5509     __ adds($tmp1$$Register, $tmp1$$Register, $add$$Register);
 5510     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), $add$$Register->successor());
 5511     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5512     __ cmp($tmp2$$Register, 0);
 5513     __ b(loop, ne);
 5514   %}
 5515   ins_pipe( long_memory_op );
 5516 %}
 5517 
 5518 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5519 // (hi($con$$constant), lo($con$$constant)) becomes
 5520 instruct xaddL_immRot_no_res(memoryex mem, immLlowRot add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5521   predicate(n->as_LoadStore()->result_not_used());
 5522   match(Set dummy (GetAndAddL mem add));
 5523   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
 5524   size(24);
 5525   format %{ "loop: \n\t"
 5526             "LDREXD   $tmp1, $mem\n\t"
 5527             "ADDS     $tmp1.lo, $tmp1.lo, $add\n\t"
 5528             "ADC      $tmp1.hi, $tmp1.hi, 0\n\t"
 5529             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5530             "CMP      $tmp2, 0 \n\t"
 5531             "B.ne     loop \n\t" %}
 5532 
 5533   ins_encode %{
 5534     Label loop;
 5535     __ bind(loop);
 5536     __ ldrexd($tmp1$$Register, $mem$$Address);
 5537     __ adds($tmp1$$Register, $tmp1$$Register, $add$$constant);
 5538     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), 0);
 5539     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5540     __ cmp($tmp2$$Register, 0);
 5541     __ b(loop, ne);
 5542   %}
 5543   ins_pipe( long_memory_op );
 5544 %}
 5545 
 5546 instruct xaddL_reg(memoryex mem, iRegL add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5547   match(Set res (GetAndAddL mem add));
 5548   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5549   size(24);
 5550   format %{ "loop: \n\t"
 5551             "LDREXD   $res, $mem\n\t"
 5552             "ADDS     $tmp1.lo, $res.lo, $add.lo\n\t"
 5553             "ADC      $tmp1.hi, $res.hi, $add.hi\n\t"
 5554             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5555             "CMP      $tmp2, 0 \n\t"
 5556             "B.ne     loop \n\t" %}
 5557 
 5558   ins_encode %{
 5559     Label loop;
 5560     __ bind(loop);
 5561     __ ldrexd($res$$Register, $mem$$Address);
 5562     __ adds($tmp1$$Register, $res$$Register, $add$$Register);
 5563     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), $add$$Register->successor());
 5564     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5565     __ cmp($tmp2$$Register, 0);
 5566     __ b(loop, ne);
 5567   %}
 5568   ins_pipe( long_memory_op );
 5569 %}
 5570 
 5571 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5572 // (hi($con$$constant), lo($con$$constant)) becomes
 5573 instruct xaddL_immRot(memoryex mem, immLlowRot add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5574   match(Set res (GetAndAddL mem add));
 5575   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5576   size(24);
 5577   format %{ "loop: \n\t"
 5578             "LDREXD   $res, $mem\n\t"
 5579             "ADDS     $tmp1.lo, $res.lo, $add\n\t"
 5580             "ADC      $tmp1.hi, $res.hi, 0\n\t"
 5581             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5582             "CMP      $tmp2, 0 \n\t"
 5583             "B.ne     loop \n\t" %}
 5584 
 5585   ins_encode %{
 5586     Label loop;
 5587     __ bind(loop);
 5588     __ ldrexd($res$$Register, $mem$$Address);
 5589     __ adds($tmp1$$Register, $res$$Register, $add$$constant);
 5590     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), 0);
 5591     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5592     __ cmp($tmp2$$Register, 0);
 5593     __ b(loop, ne);
 5594   %}
 5595   ins_pipe( long_memory_op );
 5596 %}
 5597 
 5598 instruct xchgI(memoryex mem, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr) %{
 5599   match(Set res (GetAndSetI mem newval));
 5600   effect(KILL ccr, TEMP tmp, TEMP res);
 5601   size(16);
 5602   format %{ "loop: \n\t"
 5603             "LDREX    $res, $mem\n\t"
 5604             "STREX    $tmp, $newval, $mem\n\t"
 5605             "CMP      $tmp, 0 \n\t"
 5606             "B.ne     loop \n\t" %}
 5607 
 5608   ins_encode %{
 5609     Label loop;
 5610     __ bind(loop);
 5611     __ ldrex($res$$Register,$mem$$Address);
 5612     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
 5613     __ cmp($tmp$$Register, 0);
 5614     __ b(loop, ne);
 5615   %}
 5616   ins_pipe( long_memory_op );
 5617 %}
 5618 
 5619 instruct xchgL(memoryex mem, iRegLd newval, iRegLd res, iRegI tmp, flagsReg ccr) %{
 5620   match(Set res (GetAndSetL mem newval));
 5621   effect( KILL ccr, TEMP tmp, TEMP res);
 5622   size(16);
 5623   format %{ "loop: \n\t"
 5624             "LDREXD   $res, $mem\n\t"
 5625             "STREXD   $tmp, $newval, $mem\n\t"
 5626             "CMP      $tmp, 0 \n\t"
 5627             "B.ne     loop \n\t" %}
 5628 
 5629   ins_encode %{
 5630     Label loop;
 5631     __ bind(loop);
 5632     __ ldrexd($res$$Register, $mem$$Address);
 5633     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address);
 5634     __ cmp($tmp$$Register, 0);
 5635     __ b(loop, ne);
 5636   %}
 5637   ins_pipe( long_memory_op );
 5638 %}
 5639 
 5640 instruct xchgP(memoryex mem, iRegP newval, iRegP res, iRegI tmp, flagsReg ccr) %{
 5641   predicate(!(UseG1GC && n->as_LoadStore()->barrier_data() != 0));
 5642   match(Set res (GetAndSetP mem newval));
 5643   effect(KILL ccr, TEMP tmp, TEMP res);
 5644   size(16);
 5645   format %{ "loop: \n\t"
 5646             "LDREX    $res, $mem\n\t"
 5647             "STREX    $tmp, $newval, $mem\n\t"
 5648             "CMP      $tmp, 0 \n\t"
 5649             "B.ne     loop \n\t" %}
 5650 
 5651   ins_encode %{
 5652     Label loop;
 5653     __ bind(loop);
 5654     __ ldrex($res$$Register,$mem$$Address);
 5655     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
 5656     __ cmp($tmp$$Register, 0);
 5657     __ b(loop, ne);
 5658   %}
 5659   ins_pipe( long_memory_op );
 5660 %}
 5661 
 5662 //---------------------
 5663 // Subtraction Instructions
 5664 // Register Subtraction
 5665 instruct subI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 5666   match(Set dst (SubI src1 src2));
 5667 
 5668   size(4);
 5669   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
 5670   ins_encode %{
 5671     __ sub_32($dst$$Register, $src1$$Register, $src2$$Register);
 5672   %}
 5673   ins_pipe(ialu_reg_reg);
 5674 %}
 5675 
 5676 instruct subshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5677   match(Set dst (SubI src1 (LShiftI src2 src3)));
 5678 
 5679   size(4);
 5680   format %{ "SUB    $dst,$src1,$src2<<$src3" %}
 5681   ins_encode %{
 5682     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 5683   %}
 5684   ins_pipe(ialu_reg_reg);
 5685 %}
 5686 
 5687 instruct subshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 5688   match(Set dst (SubI src1 (LShiftI src2 src3)));
 5689 
 5690   size(4);
 5691   format %{ "sub_32 $dst,$src1,$src2<<$src3\t! int" %}
 5692   ins_encode %{
 5693     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 5694   %}
 5695   ins_pipe(ialu_reg_reg);
 5696 %}
 5697 
 5698 instruct subsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5699   match(Set dst (SubI src1 (RShiftI src2 src3)));
 5700 
 5701   size(4);
 5702   format %{ "SUB    $dst,$src1,$src2>>$src3" %}
 5703   ins_encode %{
 5704     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 5705   %}
 5706   ins_pipe(ialu_reg_reg);
 5707 %}
 5708 
 5709 instruct subsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 5710   match(Set dst (SubI src1 (RShiftI src2 src3)));
 5711 
 5712   size(4);
 5713   format %{ "sub_32 $dst,$src1,$src2>>$src3\t! int" %}
 5714   ins_encode %{
 5715     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 5716   %}
 5717   ins_pipe(ialu_reg_reg);
 5718 %}
 5719 
 5720 instruct subshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5721   match(Set dst (SubI src1 (URShiftI src2 src3)));
 5722 
 5723   size(4);
 5724   format %{ "SUB    $dst,$src1,$src2>>>$src3" %}
 5725   ins_encode %{
 5726     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 5727   %}
 5728   ins_pipe(ialu_reg_reg);
 5729 %}
 5730 
 5731 instruct subshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 5732   match(Set dst (SubI src1 (URShiftI src2 src3)));
 5733 
 5734   size(4);
 5735   format %{ "sub_32 $dst,$src1,$src2>>>$src3\t! int" %}
 5736   ins_encode %{
 5737     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 5738   %}
 5739   ins_pipe(ialu_reg_reg);
 5740 %}
 5741 
 5742 instruct rsbshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5743   match(Set dst (SubI (LShiftI src1 src2) src3));
 5744 
 5745   size(4);
 5746   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
 5747   ins_encode %{
 5748     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 5749   %}
 5750   ins_pipe(ialu_reg_reg);
 5751 %}
 5752 
 5753 instruct rsbshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5754   match(Set dst (SubI (LShiftI src1 src2) src3));
 5755 
 5756   size(4);
 5757   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
 5758   ins_encode %{
 5759     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
 5760   %}
 5761   ins_pipe(ialu_reg_reg);
 5762 %}
 5763 
 5764 instruct rsbsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5765   match(Set dst (SubI (RShiftI src1 src2) src3));
 5766 
 5767   size(4);
 5768   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
 5769   ins_encode %{
 5770     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
 5771   %}
 5772   ins_pipe(ialu_reg_reg);
 5773 %}
 5774 
 5775 instruct rsbsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5776   match(Set dst (SubI (RShiftI src1 src2) src3));
 5777 
 5778   size(4);
 5779   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
 5780   ins_encode %{
 5781     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
 5782   %}
 5783   ins_pipe(ialu_reg_reg);
 5784 %}
 5785 
 5786 instruct rsbshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5787   match(Set dst (SubI (URShiftI src1 src2) src3));
 5788 
 5789   size(4);
 5790   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
 5791   ins_encode %{
 5792     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 5793   %}
 5794   ins_pipe(ialu_reg_reg);
 5795 %}
 5796 
 5797 instruct rsbshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5798   match(Set dst (SubI (URShiftI src1 src2) src3));
 5799 
 5800   size(4);
 5801   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
 5802   ins_encode %{
 5803     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 5804   %}
 5805   ins_pipe(ialu_reg_reg);
 5806 %}
 5807 
 5808 // Immediate Subtraction
 5809 instruct subI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
 5810   match(Set dst (SubI src1 src2));
 5811 
 5812   size(4);
 5813   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
 5814   ins_encode %{
 5815     __ sub_32($dst$$Register, $src1$$Register, $src2$$constant);
 5816   %}
 5817   ins_pipe(ialu_reg_imm);
 5818 %}
 5819 
 5820 instruct subI_reg_immRotneg(iRegI dst, iRegI src1, aimmIneg src2) %{
 5821   match(Set dst (AddI src1 src2));
 5822 
 5823   size(4);
 5824   format %{ "sub_32 $dst,$src1,-($src2)\t! int" %}
 5825   ins_encode %{
 5826     __ sub_32($dst$$Register, $src1$$Register, -$src2$$constant);
 5827   %}
 5828   ins_pipe(ialu_reg_imm);
 5829 %}
 5830 
 5831 instruct subI_immRot_reg(iRegI dst, immIRot src1, iRegI src2) %{
 5832   match(Set dst (SubI src1 src2));
 5833 
 5834   size(4);
 5835   format %{ "RSB    $dst,$src2,src1" %}
 5836   ins_encode %{
 5837     __ rsb($dst$$Register, $src2$$Register, $src1$$constant);
 5838   %}
 5839   ins_pipe(ialu_zero_reg);
 5840 %}
 5841 
 5842 // Register Subtraction
 5843 instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg icc ) %{
 5844   match(Set dst (SubL src1 src2));
 5845   effect (KILL icc);
 5846 
 5847   size(8);
 5848   format %{ "SUBS   $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
 5849             "SBC    $dst.hi,$src1.hi,$src2.hi" %}
 5850   ins_encode %{
 5851     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
 5852     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 5853   %}
 5854   ins_pipe(ialu_reg_reg);
 5855 %}
 5856 
 5857 // TODO
 5858 
 5859 // Immediate Subtraction
 5860 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5861 // (hi($con$$constant), lo($con$$constant)) becomes
 5862 instruct subL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg icc) %{
 5863   match(Set dst (SubL src1 con));
 5864   effect (KILL icc);
 5865 
 5866   size(8);
 5867   format %{ "SUB    $dst.lo,$src1.lo,$con\t! long\n\t"
 5868             "SBC    $dst.hi,$src1.hi,0" %}
 5869   ins_encode %{
 5870     __ subs($dst$$Register, $src1$$Register, $con$$constant);
 5871     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), 0);
 5872   %}
 5873   ins_pipe(ialu_reg_imm);
 5874 %}
 5875 
 5876 // Long negation
 5877 instruct negL_reg_reg(iRegL dst, immL0 zero, iRegL src2, flagsReg icc) %{
 5878   match(Set dst (SubL zero src2));
 5879   effect (KILL icc);
 5880 
 5881   size(8);
 5882   format %{ "RSBS   $dst.lo,$src2.lo,0\t! long\n\t"
 5883             "RSC    $dst.hi,$src2.hi,0" %}
 5884   ins_encode %{
 5885     __ rsbs($dst$$Register, $src2$$Register, 0);
 5886     __ rsc($dst$$Register->successor(), $src2$$Register->successor(), 0);
 5887   %}
 5888   ins_pipe(ialu_zero_reg);
 5889 %}
 5890 
 5891 // Multiplication Instructions
 5892 // Integer Multiplication
 5893 // Register Multiplication
 5894 instruct mulI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 5895   match(Set dst (MulI src1 src2));
 5896 
 5897   size(4);
 5898   format %{ "mul_32 $dst,$src1,$src2" %}
 5899   ins_encode %{
 5900     __ mul_32($dst$$Register, $src1$$Register, $src2$$Register);
 5901   %}
 5902   ins_pipe(imul_reg_reg);
 5903 %}
 5904 
 5905 instruct mulL_lo1_hi2(iRegL dst, iRegL src1, iRegL src2) %{
 5906   effect(DEF dst, USE src1, USE src2);
 5907   size(4);
 5908   format %{ "MUL  $dst.hi,$src1.lo,$src2.hi\t! long" %}
 5909   ins_encode %{
 5910     __ mul($dst$$Register->successor(), $src1$$Register, $src2$$Register->successor());
 5911   %}
 5912   ins_pipe(imul_reg_reg);
 5913 %}
 5914 
 5915 instruct mulL_hi1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
 5916   effect(USE_DEF dst, USE src1, USE src2);
 5917   size(8);
 5918   format %{ "MLA  $dst.hi,$src1.hi,$src2.lo,$dst.hi\t! long\n\t"
 5919             "MOV  $dst.lo, 0"%}
 5920   ins_encode %{
 5921     __ mla($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register, $dst$$Register->successor());
 5922     __ mov($dst$$Register, 0);
 5923   %}
 5924   ins_pipe(imul_reg_reg);
 5925 %}
 5926 
 5927 instruct mulL_lo1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
 5928   effect(USE_DEF dst, USE src1, USE src2);
 5929   size(4);
 5930   format %{ "UMLAL  $dst.lo,$dst.hi,$src1,$src2\t! long" %}
 5931   ins_encode %{
 5932     __ umlal($dst$$Register, $dst$$Register->successor(), $src1$$Register, $src2$$Register);
 5933   %}
 5934   ins_pipe(imul_reg_reg);
 5935 %}
 5936 
 5937 instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 5938   match(Set dst (MulL src1 src2));
 5939 
 5940   expand %{
 5941     mulL_lo1_hi2(dst, src1, src2);
 5942     mulL_hi1_lo2(dst, src1, src2);
 5943     mulL_lo1_lo2(dst, src1, src2);
 5944   %}
 5945 %}
 5946 
 5947 // Integer Division
 5948 // Register Division
 5949 instruct divI_reg_reg(R1RegI dst, R0RegI src1, R2RegI src2, LRRegP lr, flagsReg ccr) %{
 5950   match(Set dst (DivI src1 src2));
 5951   effect( KILL ccr, KILL src1, KILL src2, KILL lr);
 5952   ins_cost((2+71)*DEFAULT_COST);
 5953 
 5954   format %{ "DIV   $dst,$src1,$src2 ! 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 Division
 5962 instruct divL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
 5963   match(Set dst (DivL src1 src2));
 5964   effect(CALL);
 5965   ins_cost(DEFAULT_COST*71);
 5966   format %{ "DIVL  $src1,$src2,$dst\t! long ! call to SharedRuntime::ldiv" %}
 5967   ins_encode %{
 5968     address target = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);
 5969     __ call(target, relocInfo::runtime_call_type);
 5970   %}
 5971   ins_pipe(divL_reg_reg);
 5972 %}
 5973 
 5974 // Integer Remainder
 5975 // Register Remainder
 5976 instruct modI_reg_reg(R0RegI dst, R0RegI src1, R2RegI src2, R1RegI temp, LRRegP lr, flagsReg ccr ) %{
 5977   match(Set dst (ModI src1 src2));
 5978   effect( KILL ccr, KILL temp, KILL src2, KILL lr);
 5979 
 5980   format %{ "MODI   $dst,$src1,$src2\t ! call to StubRoutines::Arm::idiv_irem_entry" %}
 5981   ins_encode %{
 5982     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
 5983   %}
 5984   ins_pipe(sdiv_reg_reg);
 5985 %}
 5986 
 5987 // Register Long Remainder
 5988 instruct modL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
 5989   match(Set dst (ModL src1 src2));
 5990   effect(CALL);
 5991   ins_cost(MEMORY_REF_COST); // FIXME
 5992   format %{ "modL    $dst,$src1,$src2\t ! call to SharedRuntime::lrem" %}
 5993   ins_encode %{
 5994     address target = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
 5995     __ call(target, relocInfo::runtime_call_type);
 5996   %}
 5997   ins_pipe(divL_reg_reg);
 5998 %}
 5999 
 6000 // Integer Shift Instructions
 6001 
 6002 // Register Shift Left
 6003 instruct shlI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6004   match(Set dst (LShiftI src1 src2));
 6005 
 6006   size(4);
 6007   format %{ "LSL  $dst,$src1,$src2 \n\t" %}
 6008   ins_encode %{
 6009     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 6010   %}
 6011   ins_pipe(ialu_reg_reg);
 6012 %}
 6013 
 6014 // Register Shift Left Immediate
 6015 instruct shlI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
 6016   match(Set dst (LShiftI src1 src2));
 6017 
 6018   size(4);
 6019   format %{ "LSL    $dst,$src1,$src2\t! int" %}
 6020   ins_encode %{
 6021     __ logical_shift_left($dst$$Register, $src1$$Register, $src2$$constant);
 6022   %}
 6023   ins_pipe(ialu_reg_imm);
 6024 %}
 6025 
 6026 instruct shlL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
 6027   effect(USE_DEF dst, USE src1, USE src2);
 6028   size(4);
 6029   format %{"OR  $dst.hi,$dst.hi,($src1.hi << $src2)"  %}
 6030   ins_encode %{
 6031     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$Register));
 6032   %}
 6033   ins_pipe(ialu_reg_reg);
 6034 %}
 6035 
 6036 instruct shlL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
 6037   effect(USE_DEF dst, USE src1, USE src2);
 6038   size(4);
 6039   format %{ "LSL  $dst.lo,$src1.lo,$src2 \n\t" %}
 6040   ins_encode %{
 6041     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 6042   %}
 6043   ins_pipe(ialu_reg_reg);
 6044 %}
 6045 
 6046 instruct shlL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
 6047   effect(DEF dst, USE src1, USE src2, KILL ccr);
 6048   size(16);
 6049   format %{ "SUBS  $dst.hi,$src2,32 \n\t"
 6050             "LSLpl $dst.hi,$src1.lo,$dst.hi \n\t"
 6051             "RSBmi $dst.hi,$dst.hi,0 \n\t"
 6052             "LSRmi $dst.hi,$src1.lo,$dst.hi" %}
 6053 
 6054   ins_encode %{
 6055     // $src1$$Register and $dst$$Register->successor() can't be the same
 6056     __ subs($dst$$Register->successor(), $src2$$Register, 32);
 6057     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $dst$$Register->successor()), pl);
 6058     __ rsb($dst$$Register->successor(), $dst$$Register->successor(), 0, mi);
 6059     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsr, $dst$$Register->successor()), mi);
 6060   %}
 6061   ins_pipe(ialu_reg_reg);
 6062 %}
 6063 
 6064 instruct shlL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
 6065   match(Set dst (LShiftL src1 src2));
 6066 
 6067   expand %{
 6068     flagsReg ccr;
 6069     shlL_reg_reg_overlap(dst, src1, src2, ccr);
 6070     shlL_reg_reg_merge_hi(dst, src1, src2);
 6071     shlL_reg_reg_merge_lo(dst, src1, src2);
 6072   %}
 6073 %}
 6074 
 6075 // Register Shift Left Immediate
 6076 instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
 6077   match(Set dst (LShiftL src1 src2));
 6078 
 6079   size(8);
 6080   format %{ "LSL   $dst.hi,$src1.lo,$src2-32\t! or mov if $src2==32\n\t"
 6081             "MOV   $dst.lo, 0" %}
 6082   ins_encode %{
 6083     if ($src2$$constant == 32) {
 6084       __ mov($dst$$Register->successor(), $src1$$Register);
 6085     } else {
 6086       __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $src2$$constant-32));
 6087     }
 6088     __ mov($dst$$Register, 0);
 6089   %}
 6090   ins_pipe(ialu_reg_imm);
 6091 %}
 6092 
 6093 instruct shlL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
 6094   match(Set dst (LShiftL src1 src2));
 6095 
 6096   size(12);
 6097   format %{ "LSL   $dst.hi,$src1.lo,$src2\n\t"
 6098             "OR    $dst.hi, $dst.hi, $src1.lo >> 32-$src2\n\t"
 6099             "LSL   $dst.lo,$src1.lo,$src2" %}
 6100   ins_encode %{
 6101     // The order of the following 3 instructions matters: src1.lo and
 6102     // dst.hi can't overlap but src.hi and dst.hi can.
 6103     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$constant));
 6104     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register, lsr, 32-$src2$$constant));
 6105     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
 6106   %}
 6107   ins_pipe(ialu_reg_imm);
 6108 %}
 6109 
 6110 // Register Arithmetic Shift Right
 6111 instruct sarI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6112   match(Set dst (RShiftI src1 src2));
 6113   size(4);
 6114   format %{ "ASR    $dst,$src1,$src2\t! int" %}
 6115   ins_encode %{
 6116     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
 6117   %}
 6118   ins_pipe(ialu_reg_reg);
 6119 %}
 6120 
 6121 // Register Arithmetic Shift Right Immediate
 6122 instruct sarI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
 6123   match(Set dst (RShiftI src1 src2));
 6124 
 6125   size(4);
 6126   format %{ "ASR    $dst,$src1,$src2" %}
 6127   ins_encode %{
 6128     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
 6129   %}
 6130   ins_pipe(ialu_reg_imm);
 6131 %}
 6132 
 6133 // Register Shift Right Arithmetic Long
 6134 instruct sarL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
 6135   effect(USE_DEF dst, USE src1, USE src2);
 6136   size(4);
 6137   format %{ "OR  $dst.lo,$dst.lo,($src1.lo >> $src2)"  %}
 6138   ins_encode %{
 6139     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6140   %}
 6141   ins_pipe(ialu_reg_reg);
 6142 %}
 6143 
 6144 instruct sarL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
 6145   effect(USE_DEF dst, USE src1, USE src2);
 6146   size(4);
 6147   format %{ "ASR  $dst.hi,$src1.hi,$src2 \n\t" %}
 6148   ins_encode %{
 6149     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$Register));
 6150   %}
 6151   ins_pipe(ialu_reg_reg);
 6152 %}
 6153 
 6154 instruct sarL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
 6155   effect(DEF dst, USE src1, USE src2, KILL ccr);
 6156   size(16);
 6157   format %{ "SUBS  $dst.lo,$src2,32 \n\t"
 6158             "ASRpl $dst.lo,$src1.hi,$dst.lo \n\t"
 6159             "RSBmi $dst.lo,$dst.lo,0 \n\t"
 6160             "LSLmi $dst.lo,$src1.hi,$dst.lo" %}
 6161 
 6162   ins_encode %{
 6163     // $src1$$Register->successor() and $dst$$Register can't be the same
 6164     __ subs($dst$$Register, $src2$$Register, 32);
 6165     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $dst$$Register), pl);
 6166     __ rsb($dst$$Register, $dst$$Register, 0, mi);
 6167     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
 6168   %}
 6169   ins_pipe(ialu_reg_reg);
 6170 %}
 6171 
 6172 instruct sarL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
 6173   match(Set dst (RShiftL src1 src2));
 6174 
 6175   expand %{
 6176     flagsReg ccr;
 6177     sarL_reg_reg_overlap(dst, src1, src2, ccr);
 6178     sarL_reg_reg_merge_lo(dst, src1, src2);
 6179     sarL_reg_reg_merge_hi(dst, src1, src2);
 6180   %}
 6181 %}
 6182 
 6183 // Register Shift Left Immediate
 6184 instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
 6185   match(Set dst (RShiftL src1 src2));
 6186 
 6187   size(8);
 6188   format %{ "ASR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
 6189             "ASR   $dst.hi,$src1.hi, $src2" %}
 6190   ins_encode %{
 6191     if ($src2$$constant == 32) {
 6192       __ mov($dst$$Register, $src1$$Register->successor());
 6193     } else{
 6194       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $src2$$constant-32));
 6195     }
 6196     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, 0));
 6197   %}
 6198 
 6199   ins_pipe(ialu_reg_imm);
 6200 %}
 6201 
 6202 instruct sarL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
 6203   match(Set dst (RShiftL src1 src2));
 6204   size(12);
 6205   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
 6206             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
 6207             "ASR   $dst.hi,$src1.hi,$src2" %}
 6208   ins_encode %{
 6209     // The order of the following 3 instructions matters: src1.lo and
 6210     // dst.hi can't overlap but src.hi and dst.hi can.
 6211     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6212     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
 6213     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$constant));
 6214   %}
 6215   ins_pipe(ialu_reg_imm);
 6216 %}
 6217 
 6218 // Register Shift Right
 6219 instruct shrI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6220   match(Set dst (URShiftI src1 src2));
 6221   size(4);
 6222   format %{ "LSR    $dst,$src1,$src2\t! int" %}
 6223   ins_encode %{
 6224     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6225   %}
 6226   ins_pipe(ialu_reg_reg);
 6227 %}
 6228 
 6229 // Register Shift Right Immediate
 6230 instruct shrI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
 6231   match(Set dst (URShiftI src1 src2));
 6232 
 6233   size(4);
 6234   format %{ "LSR    $dst,$src1,$src2" %}
 6235   ins_encode %{
 6236     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6237   %}
 6238   ins_pipe(ialu_reg_imm);
 6239 %}
 6240 
 6241 // Register Shift Right
 6242 instruct shrL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
 6243   effect(USE_DEF dst, USE src1, USE src2);
 6244   size(4);
 6245   format %{ "OR   $dst.lo,$dst,($src1.lo >>> $src2)"  %}
 6246   ins_encode %{
 6247     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6248   %}
 6249   ins_pipe(ialu_reg_reg);
 6250 %}
 6251 
 6252 instruct shrL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
 6253   effect(USE_DEF dst, USE src1, USE src2);
 6254   size(4);
 6255   format %{ "LSR  $dst.hi,$src1.hi,$src2 \n\t" %}
 6256   ins_encode %{
 6257     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$Register));
 6258   %}
 6259   ins_pipe(ialu_reg_reg);
 6260 %}
 6261 
 6262 instruct shrL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
 6263   effect(DEF dst, USE src1, USE src2, KILL ccr);
 6264   size(16);
 6265   format %{ "SUBS  $dst,$src2,32 \n\t"
 6266             "LSRpl $dst,$src1.hi,$dst \n\t"
 6267             "RSBmi $dst,$dst,0 \n\t"
 6268             "LSLmi $dst,$src1.hi,$dst" %}
 6269 
 6270   ins_encode %{
 6271     // $src1$$Register->successor() and $dst$$Register can't be the same
 6272     __ subs($dst$$Register, $src2$$Register, 32);
 6273     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $dst$$Register), pl);
 6274     __ rsb($dst$$Register, $dst$$Register, 0, mi);
 6275     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
 6276   %}
 6277   ins_pipe(ialu_reg_reg);
 6278 %}
 6279 
 6280 instruct shrL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
 6281   match(Set dst (URShiftL src1 src2));
 6282 
 6283   expand %{
 6284     flagsReg ccr;
 6285     shrL_reg_reg_overlap(dst, src1, src2, ccr);
 6286     shrL_reg_reg_merge_lo(dst, src1, src2);
 6287     shrL_reg_reg_merge_hi(dst, src1, src2);
 6288   %}
 6289 %}
 6290 
 6291 // Register Shift Right Immediate
 6292 instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
 6293   match(Set dst (URShiftL src1 src2));
 6294 
 6295   size(8);
 6296   format %{ "LSR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
 6297             "MOV   $dst.hi, 0" %}
 6298   ins_encode %{
 6299     if ($src2$$constant == 32) {
 6300       __ mov($dst$$Register, $src1$$Register->successor());
 6301     } else {
 6302       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $src2$$constant-32));
 6303     }
 6304     __ mov($dst$$Register->successor(), 0);
 6305   %}
 6306 
 6307   ins_pipe(ialu_reg_imm);
 6308 %}
 6309 
 6310 instruct shrL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
 6311   match(Set dst (URShiftL src1 src2));
 6312 
 6313   size(12);
 6314   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
 6315             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
 6316             "LSR   $dst.hi,$src1.hi,$src2" %}
 6317   ins_encode %{
 6318     // The order of the following 3 instructions matters: src1.lo and
 6319     // dst.hi can't overlap but src.hi and dst.hi can.
 6320     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6321     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
 6322     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$constant));
 6323   %}
 6324   ins_pipe(ialu_reg_imm);
 6325 %}
 6326 
 6327 
 6328 instruct shrP_reg_imm5(iRegX dst, iRegP src1, immU5 src2) %{
 6329   match(Set dst (URShiftI (CastP2X src1) src2));
 6330   size(4);
 6331   format %{ "LSR    $dst,$src1,$src2\t! Cast ptr $src1 to int and shift" %}
 6332   ins_encode %{
 6333     __ logical_shift_right($dst$$Register, $src1$$Register, $src2$$constant);
 6334   %}
 6335   ins_pipe(ialu_reg_imm);
 6336 %}
 6337 
 6338 //----------Floating Point Arithmetic Instructions-----------------------------
 6339 
 6340 //  Add float single precision
 6341 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
 6342   match(Set dst (AddF src1 src2));
 6343 
 6344   size(4);
 6345   format %{ "FADDS  $dst,$src1,$src2" %}
 6346   ins_encode %{
 6347     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6348   %}
 6349 
 6350   ins_pipe(faddF_reg_reg);
 6351 %}
 6352 
 6353 //  Add float double precision
 6354 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
 6355   match(Set dst (AddD src1 src2));
 6356 
 6357   size(4);
 6358   format %{ "FADDD  $dst,$src1,$src2" %}
 6359   ins_encode %{
 6360     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6361   %}
 6362 
 6363   ins_pipe(faddD_reg_reg);
 6364 %}
 6365 
 6366 //  Sub float single precision
 6367 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
 6368   match(Set dst (SubF src1 src2));
 6369 
 6370   size(4);
 6371   format %{ "FSUBS  $dst,$src1,$src2" %}
 6372   ins_encode %{
 6373     __ sub_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6374   %}
 6375   ins_pipe(faddF_reg_reg);
 6376 %}
 6377 
 6378 //  Sub float double precision
 6379 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
 6380   match(Set dst (SubD src1 src2));
 6381 
 6382   size(4);
 6383   format %{ "FSUBD  $dst,$src1,$src2" %}
 6384   ins_encode %{
 6385     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6386   %}
 6387   ins_pipe(faddD_reg_reg);
 6388 %}
 6389 
 6390 //  Mul float single precision
 6391 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
 6392   match(Set dst (MulF src1 src2));
 6393 
 6394   size(4);
 6395   format %{ "FMULS  $dst,$src1,$src2" %}
 6396   ins_encode %{
 6397     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6398   %}
 6399 
 6400   ins_pipe(fmulF_reg_reg);
 6401 %}
 6402 
 6403 //  Mul float double precision
 6404 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
 6405   match(Set dst (MulD src1 src2));
 6406 
 6407   size(4);
 6408   format %{ "FMULD  $dst,$src1,$src2" %}
 6409   ins_encode %{
 6410     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6411   %}
 6412 
 6413   ins_pipe(fmulD_reg_reg);
 6414 %}
 6415 
 6416 //  Div float single precision
 6417 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
 6418   match(Set dst (DivF src1 src2));
 6419 
 6420   size(4);
 6421   format %{ "FDIVS  $dst,$src1,$src2" %}
 6422   ins_encode %{
 6423     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6424   %}
 6425 
 6426   ins_pipe(fdivF_reg_reg);
 6427 %}
 6428 
 6429 //  Div float double precision
 6430 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
 6431   match(Set dst (DivD src1 src2));
 6432 
 6433   size(4);
 6434   format %{ "FDIVD  $dst,$src1,$src2" %}
 6435   ins_encode %{
 6436     __ div_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6437   %}
 6438 
 6439   ins_pipe(fdivD_reg_reg);
 6440 %}
 6441 
 6442 //  Absolute float double precision
 6443 instruct absD_reg(regD dst, regD src) %{
 6444   match(Set dst (AbsD src));
 6445 
 6446   size(4);
 6447   format %{ "FABSd  $dst,$src" %}
 6448   ins_encode %{
 6449     __ abs_double($dst$$FloatRegister, $src$$FloatRegister);
 6450   %}
 6451   ins_pipe(faddD_reg);
 6452 %}
 6453 
 6454 //  Absolute float single precision
 6455 instruct absF_reg(regF dst, regF src) %{
 6456   match(Set dst (AbsF src));
 6457   format %{ "FABSs  $dst,$src" %}
 6458   ins_encode %{
 6459     __ abs_float($dst$$FloatRegister, $src$$FloatRegister);
 6460   %}
 6461   ins_pipe(faddF_reg);
 6462 %}
 6463 
 6464 instruct negF_reg(regF dst, regF src) %{
 6465   match(Set dst (NegF src));
 6466 
 6467   size(4);
 6468   format %{ "FNEGs  $dst,$src" %}
 6469   ins_encode %{
 6470     __ neg_float($dst$$FloatRegister, $src$$FloatRegister);
 6471   %}
 6472   ins_pipe(faddF_reg);
 6473 %}
 6474 
 6475 instruct negD_reg(regD dst, regD src) %{
 6476   match(Set dst (NegD src));
 6477 
 6478   format %{ "FNEGd  $dst,$src" %}
 6479   ins_encode %{
 6480     __ neg_double($dst$$FloatRegister, $src$$FloatRegister);
 6481   %}
 6482   ins_pipe(faddD_reg);
 6483 %}
 6484 
 6485 //  Sqrt float double precision
 6486 instruct sqrtF_reg_reg(regF dst, regF src) %{
 6487   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
 6488 
 6489   size(4);
 6490   format %{ "FSQRTS $dst,$src" %}
 6491   ins_encode %{
 6492     __ sqrt_float($dst$$FloatRegister, $src$$FloatRegister);
 6493   %}
 6494   ins_pipe(fdivF_reg_reg);
 6495 %}
 6496 
 6497 //  Sqrt float double precision
 6498 instruct sqrtD_reg_reg(regD dst, regD src) %{
 6499   match(Set dst (SqrtD src));
 6500 
 6501   size(4);
 6502   format %{ "FSQRTD $dst,$src" %}
 6503   ins_encode %{
 6504     __ sqrt_double($dst$$FloatRegister, $src$$FloatRegister);
 6505   %}
 6506   ins_pipe(fdivD_reg_reg);
 6507 %}
 6508 
 6509 //----------Logical Instructions-----------------------------------------------
 6510 // And Instructions
 6511 // Register And
 6512 instruct andI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6513   match(Set dst (AndI src1 src2));
 6514 
 6515   size(4);
 6516   format %{ "and_32 $dst,$src1,$src2" %}
 6517   ins_encode %{
 6518     __ and_32($dst$$Register, $src1$$Register, $src2$$Register);
 6519   %}
 6520   ins_pipe(ialu_reg_reg);
 6521 %}
 6522 
 6523 instruct andshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6524   match(Set dst (AndI src1 (LShiftI src2 src3)));
 6525 
 6526   size(4);
 6527   format %{ "AND    $dst,$src1,$src2<<$src3" %}
 6528   ins_encode %{
 6529     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 6530   %}
 6531   ins_pipe(ialu_reg_reg);
 6532 %}
 6533 
 6534 instruct andshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6535   match(Set dst (AndI src1 (LShiftI src2 src3)));
 6536 
 6537   size(4);
 6538   format %{ "and_32 $dst,$src1,$src2<<$src3" %}
 6539   ins_encode %{
 6540     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 6541   %}
 6542   ins_pipe(ialu_reg_reg);
 6543 %}
 6544 
 6545 instruct andsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6546   match(Set dst (AndI src1 (RShiftI src2 src3)));
 6547 
 6548   size(4);
 6549   format %{ "AND    $dst,$src1,$src2>>$src3" %}
 6550   ins_encode %{
 6551     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 6552   %}
 6553   ins_pipe(ialu_reg_reg);
 6554 %}
 6555 
 6556 instruct andsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6557   match(Set dst (AndI src1 (RShiftI src2 src3)));
 6558 
 6559   size(4);
 6560   format %{ "and_32 $dst,$src1,$src2>>$src3" %}
 6561   ins_encode %{
 6562     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 6563   %}
 6564   ins_pipe(ialu_reg_reg);
 6565 %}
 6566 
 6567 instruct andshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6568   match(Set dst (AndI src1 (URShiftI src2 src3)));
 6569 
 6570   size(4);
 6571   format %{ "AND    $dst,$src1,$src2>>>$src3" %}
 6572   ins_encode %{
 6573     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 6574   %}
 6575   ins_pipe(ialu_reg_reg);
 6576 %}
 6577 
 6578 instruct andshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6579   match(Set dst (AndI src1 (URShiftI src2 src3)));
 6580 
 6581   size(4);
 6582   format %{ "and_32 $dst,$src1,$src2>>>$src3" %}
 6583   ins_encode %{
 6584     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 6585   %}
 6586   ins_pipe(ialu_reg_reg);
 6587 %}
 6588 
 6589 // Immediate And
 6590 instruct andI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
 6591   match(Set dst (AndI src1 src2));
 6592 
 6593   size(4);
 6594   format %{ "and_32 $dst,$src1,$src2\t! int" %}
 6595   ins_encode %{
 6596     __ and_32($dst$$Register, $src1$$Register, $src2$$constant);
 6597   %}
 6598   ins_pipe(ialu_reg_imm);
 6599 %}
 6600 
 6601 instruct andI_reg_limmn(iRegI dst, iRegI src1, limmIn src2) %{
 6602   match(Set dst (AndI src1 src2));
 6603 
 6604   size(4);
 6605   format %{ "bic    $dst,$src1,~$src2\t! int" %}
 6606   ins_encode %{
 6607     __ bic($dst$$Register, $src1$$Register, ~$src2$$constant);
 6608   %}
 6609   ins_pipe(ialu_reg_imm);
 6610 %}
 6611 
 6612 // Register And Long
 6613 instruct andL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 6614   match(Set dst (AndL src1 src2));
 6615 
 6616   ins_cost(DEFAULT_COST);
 6617   size(8);
 6618   format %{ "AND    $dst,$src1,$src2\t! long" %}
 6619   ins_encode %{
 6620     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
 6621     __ andr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 6622   %}
 6623   ins_pipe(ialu_reg_reg);
 6624 %}
 6625 
 6626 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 6627 // (hi($con$$constant), lo($con$$constant)) becomes
 6628 instruct andL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
 6629   match(Set dst (AndL src1 con));
 6630   ins_cost(DEFAULT_COST);
 6631   size(8);
 6632   format %{ "AND    $dst,$src1,$con\t! long" %}
 6633   ins_encode %{
 6634     __ andr($dst$$Register, $src1$$Register, $con$$constant);
 6635     __ andr($dst$$Register->successor(), $src1$$Register->successor(), 0);
 6636   %}
 6637   ins_pipe(ialu_reg_imm);
 6638 %}
 6639 
 6640 // Or Instructions
 6641 // Register Or
 6642 instruct orI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6643   match(Set dst (OrI src1 src2));
 6644 
 6645   size(4);
 6646   format %{ "orr_32 $dst,$src1,$src2\t! int" %}
 6647   ins_encode %{
 6648     __ orr_32($dst$$Register, $src1$$Register, $src2$$Register);
 6649   %}
 6650   ins_pipe(ialu_reg_reg);
 6651 %}
 6652 
 6653 instruct orshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6654   match(Set dst (OrI src1 (LShiftI src2 src3)));
 6655 
 6656   size(4);
 6657   format %{ "OR    $dst,$src1,$src2<<$src3" %}
 6658   ins_encode %{
 6659     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 6660   %}
 6661   ins_pipe(ialu_reg_reg);
 6662 %}
 6663 
 6664 instruct orshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6665   match(Set dst (OrI src1 (LShiftI src2 src3)));
 6666 
 6667   size(4);
 6668   format %{ "orr_32 $dst,$src1,$src2<<$src3" %}
 6669   ins_encode %{
 6670     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 6671   %}
 6672   ins_pipe(ialu_reg_reg);
 6673 %}
 6674 
 6675 instruct orsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6676   match(Set dst (OrI src1 (RShiftI src2 src3)));
 6677 
 6678   size(4);
 6679   format %{ "OR    $dst,$src1,$src2>>$src3" %}
 6680   ins_encode %{
 6681     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 6682   %}
 6683   ins_pipe(ialu_reg_reg);
 6684 %}
 6685 
 6686 instruct orsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6687   match(Set dst (OrI src1 (RShiftI src2 src3)));
 6688 
 6689   size(4);
 6690   format %{ "orr_32 $dst,$src1,$src2>>$src3" %}
 6691   ins_encode %{
 6692     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 6693   %}
 6694   ins_pipe(ialu_reg_reg);
 6695 %}
 6696 
 6697 instruct orshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6698   match(Set dst (OrI src1 (URShiftI src2 src3)));
 6699 
 6700   size(4);
 6701   format %{ "OR    $dst,$src1,$src2>>>$src3" %}
 6702   ins_encode %{
 6703     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 6704   %}
 6705   ins_pipe(ialu_reg_reg);
 6706 %}
 6707 
 6708 instruct orshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6709   match(Set dst (OrI src1 (URShiftI src2 src3)));
 6710 
 6711   size(4);
 6712   format %{ "orr_32 $dst,$src1,$src2>>>$src3" %}
 6713   ins_encode %{
 6714     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 6715   %}
 6716   ins_pipe(ialu_reg_reg);
 6717 %}
 6718 
 6719 // Immediate Or
 6720 instruct orI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
 6721   match(Set dst (OrI src1 src2));
 6722 
 6723   size(4);
 6724   format %{ "orr_32  $dst,$src1,$src2" %}
 6725   ins_encode %{
 6726     __ orr_32($dst$$Register, $src1$$Register, $src2$$constant);
 6727   %}
 6728   ins_pipe(ialu_reg_imm);
 6729 %}
 6730 // TODO: orn_32 with limmIn
 6731 
 6732 // Register Or Long
 6733 instruct orL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 6734   match(Set dst (OrL src1 src2));
 6735 
 6736   ins_cost(DEFAULT_COST);
 6737   size(8);
 6738   format %{ "OR     $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
 6739             "OR     $dst.hi,$src1.hi,$src2.hi" %}
 6740   ins_encode %{
 6741     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
 6742     __ orr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 6743   %}
 6744   ins_pipe(ialu_reg_reg);
 6745 %}
 6746 
 6747 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 6748 // (hi($con$$constant), lo($con$$constant)) becomes
 6749 instruct orL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
 6750   match(Set dst (OrL src1 con));
 6751   ins_cost(DEFAULT_COST);
 6752   size(8);
 6753   format %{ "OR     $dst.lo,$src1.lo,$con\t! long\n\t"
 6754             "OR     $dst.hi,$src1.hi,$con" %}
 6755   ins_encode %{
 6756     __ orr($dst$$Register, $src1$$Register, $con$$constant);
 6757     __ orr($dst$$Register->successor(), $src1$$Register->successor(), 0);
 6758   %}
 6759   ins_pipe(ialu_reg_imm);
 6760 %}
 6761 
 6762 #ifdef TODO
 6763 // Use SPRegP to match Rthread (TLS register) without spilling.
 6764 // Use store_ptr_RegP to match Rthread (TLS register) without spilling.
 6765 // Use sp_ptr_RegP to match Rthread (TLS register) without spilling.
 6766 instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
 6767   match(Set dst (OrI src1 (CastP2X src2)));
 6768   size(4);
 6769   format %{ "OR     $dst,$src1,$src2" %}
 6770   ins_encode %{
 6771     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
 6772   %}
 6773   ins_pipe(ialu_reg_reg);
 6774 %}
 6775 #endif
 6776 
 6777 // Xor Instructions
 6778 // Register Xor
 6779 instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6780   match(Set dst (XorI src1 src2));
 6781 
 6782   size(4);
 6783   format %{ "eor_32 $dst,$src1,$src2" %}
 6784   ins_encode %{
 6785     __ eor_32($dst$$Register, $src1$$Register, $src2$$Register);
 6786   %}
 6787   ins_pipe(ialu_reg_reg);
 6788 %}
 6789 
 6790 instruct xorshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6791   match(Set dst (XorI src1 (LShiftI src2 src3)));
 6792 
 6793   size(4);
 6794   format %{ "XOR    $dst,$src1,$src2<<$src3" %}
 6795   ins_encode %{
 6796     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 6797   %}
 6798   ins_pipe(ialu_reg_reg);
 6799 %}
 6800 
 6801 instruct xorshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6802   match(Set dst (XorI src1 (LShiftI src2 src3)));
 6803 
 6804   size(4);
 6805   format %{ "eor_32 $dst,$src1,$src2<<$src3" %}
 6806   ins_encode %{
 6807     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 6808   %}
 6809   ins_pipe(ialu_reg_reg);
 6810 %}
 6811 
 6812 instruct xorsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6813   match(Set dst (XorI src1 (RShiftI src2 src3)));
 6814 
 6815   size(4);
 6816   format %{ "XOR    $dst,$src1,$src2>>$src3" %}
 6817   ins_encode %{
 6818     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 6819   %}
 6820   ins_pipe(ialu_reg_reg);
 6821 %}
 6822 
 6823 instruct xorsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6824   match(Set dst (XorI src1 (RShiftI src2 src3)));
 6825 
 6826   size(4);
 6827   format %{ "eor_32 $dst,$src1,$src2>>$src3" %}
 6828   ins_encode %{
 6829     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 6830   %}
 6831   ins_pipe(ialu_reg_reg);
 6832 %}
 6833 
 6834 instruct xorshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6835   match(Set dst (XorI src1 (URShiftI src2 src3)));
 6836 
 6837   size(4);
 6838   format %{ "XOR    $dst,$src1,$src2>>>$src3" %}
 6839   ins_encode %{
 6840     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 6841   %}
 6842   ins_pipe(ialu_reg_reg);
 6843 %}
 6844 
 6845 instruct xorshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6846   match(Set dst (XorI src1 (URShiftI src2 src3)));
 6847 
 6848   size(4);
 6849   format %{ "eor_32 $dst,$src1,$src2>>>$src3" %}
 6850   ins_encode %{
 6851     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 6852   %}
 6853   ins_pipe(ialu_reg_reg);
 6854 %}
 6855 
 6856 // Immediate Xor
 6857 instruct xorI_reg_imm(iRegI dst, iRegI src1, limmI src2) %{
 6858   match(Set dst (XorI src1 src2));
 6859 
 6860   size(4);
 6861   format %{ "eor_32 $dst,$src1,$src2" %}
 6862   ins_encode %{
 6863     __ eor_32($dst$$Register, $src1$$Register, $src2$$constant);
 6864   %}
 6865   ins_pipe(ialu_reg_imm);
 6866 %}
 6867 
 6868 // Register Xor Long
 6869 instruct xorL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 6870   match(Set dst (XorL src1 src2));
 6871   ins_cost(DEFAULT_COST);
 6872   size(8);
 6873   format %{ "XOR     $dst.hi,$src1.hi,$src2.hi\t! long\n\t"
 6874             "XOR     $dst.lo,$src1.lo,$src2.lo\t! long" %}
 6875   ins_encode %{
 6876     __ eor($dst$$Register, $src1$$Register, $src2$$Register);
 6877     __ eor($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 6878   %}
 6879   ins_pipe(ialu_reg_reg);
 6880 %}
 6881 
 6882 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 6883 // (hi($con$$constant), lo($con$$constant)) becomes
 6884 instruct xorL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
 6885   match(Set dst (XorL src1 con));
 6886   ins_cost(DEFAULT_COST);
 6887   size(8);
 6888   format %{ "XOR     $dst.hi,$src1.hi,$con\t! long\n\t"
 6889             "XOR     $dst.lo,$src1.lo,0\t! long" %}
 6890   ins_encode %{
 6891     __ eor($dst$$Register, $src1$$Register, $con$$constant);
 6892     __ eor($dst$$Register->successor(), $src1$$Register->successor(), 0);
 6893   %}
 6894   ins_pipe(ialu_reg_imm);
 6895 %}
 6896 
 6897 instruct cmpLTMask_reg_reg( iRegI dst, iRegI p, iRegI q, flagsReg ccr ) %{
 6898   match(Set dst (CmpLTMask p q));
 6899   effect( KILL ccr );
 6900   ins_cost(DEFAULT_COST*3);
 6901   format %{ "CMP    $p,$q\n\t"
 6902             "MOV    $dst, #0\n\t"
 6903             "MOV.lt $dst, #-1" %}
 6904   ins_encode %{
 6905     __ cmp($p$$Register, $q$$Register);
 6906     __ mov($dst$$Register, 0);
 6907     __ mvn($dst$$Register, 0, lt);
 6908   %}
 6909   ins_pipe(ialu_reg_reg_ialu);
 6910 %}
 6911 
 6912 instruct cmpLTMask_reg_imm( iRegI dst, iRegI p, aimmI q, flagsReg ccr ) %{
 6913   match(Set dst (CmpLTMask p q));
 6914   effect( KILL ccr );
 6915   ins_cost(DEFAULT_COST*3);
 6916   format %{ "CMP    $p,$q\n\t"
 6917             "MOV    $dst, #0\n\t"
 6918             "MOV.lt $dst, #-1" %}
 6919   ins_encode %{
 6920     __ cmp($p$$Register, $q$$constant);
 6921     __ mov($dst$$Register, 0);
 6922     __ mvn($dst$$Register, 0, lt);
 6923   %}
 6924   ins_pipe(ialu_reg_reg_ialu);
 6925 %}
 6926 
 6927 instruct cadd_cmpLTMask3( iRegI p, iRegI q, iRegI y, iRegI z, flagsReg ccr ) %{
 6928   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
 6929   effect( KILL ccr );
 6930   ins_cost(DEFAULT_COST*2);
 6931   format %{ "CMP    $p,$q\n\t"
 6932             "ADD.lt $z,$y,$z" %}
 6933   ins_encode %{
 6934     __ cmp($p$$Register, $q$$Register);
 6935     __ add($z$$Register, $y$$Register, $z$$Register, lt);
 6936   %}
 6937   ins_pipe( cadd_cmpltmask );
 6938 %}
 6939 
 6940 // FIXME: remove unused "dst"
 6941 instruct cadd_cmpLTMask4( iRegI dst, iRegI p, aimmI q, iRegI y, iRegI z, flagsReg ccr ) %{
 6942   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
 6943   effect( KILL ccr );
 6944   ins_cost(DEFAULT_COST*2);
 6945   format %{ "CMP    $p,$q\n\t"
 6946             "ADD.lt $z,$y,$z" %}
 6947   ins_encode %{
 6948     __ cmp($p$$Register, $q$$constant);
 6949     __ add($z$$Register, $y$$Register, $z$$Register, lt);
 6950   %}
 6951   ins_pipe( cadd_cmpltmask );
 6952 %}
 6953 
 6954 instruct cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, flagsReg ccr ) %{
 6955   match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
 6956   effect( KILL ccr );
 6957   ins_cost(DEFAULT_COST*2);
 6958   format %{ "SUBS   $p,$p,$q\n\t"
 6959             "ADD.lt $p,$y,$p" %}
 6960   ins_encode %{
 6961     __ subs($p$$Register, $p$$Register, $q$$Register);
 6962     __ add($p$$Register, $y$$Register, $p$$Register, lt);
 6963   %}
 6964   ins_pipe( cadd_cmpltmask );
 6965 %}
 6966 
 6967 //----------Arithmetic Conversion Instructions---------------------------------
 6968 // The conversions operations are all Alpha sorted.  Please keep it that way!
 6969 
 6970 instruct convD2F_reg(regF dst, regD src) %{
 6971   match(Set dst (ConvD2F src));
 6972   size(4);
 6973   format %{ "FCVTSD  $dst,$src" %}
 6974   ins_encode %{
 6975     __ convert_d2f($dst$$FloatRegister, $src$$FloatRegister);
 6976   %}
 6977   ins_pipe(fcvtD2F);
 6978 %}
 6979 
 6980 // Convert a double to an int in a float register.
 6981 // If the double is a NAN, stuff a zero in instead.
 6982 
 6983 instruct convD2I_reg_reg(iRegI dst, regD src, regF tmp) %{
 6984   match(Set dst (ConvD2I src));
 6985   effect( TEMP tmp );
 6986   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
 6987   format %{ "FTOSIZD  $tmp,$src\n\t"
 6988             "FMRS     $dst, $tmp" %}
 6989   ins_encode %{
 6990     __ ftosizd($tmp$$FloatRegister, $src$$FloatRegister);
 6991     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 6992   %}
 6993   ins_pipe(fcvtD2I);
 6994 %}
 6995 
 6996 // Convert a double to a long in a double register.
 6997 // If the double is a NAN, stuff a zero in instead.
 6998 
 6999 // Double to Long conversion
 7000 instruct convD2L_reg(R0R1RegL dst, regD src) %{
 7001   match(Set dst (ConvD2L src));
 7002   effect(CALL);
 7003   ins_cost(MEMORY_REF_COST); // FIXME
 7004   format %{ "convD2L    $dst,$src\t ! call to SharedRuntime::d2l" %}
 7005   ins_encode %{
 7006 #ifndef __ABI_HARD__
 7007     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
 7008 #else
 7009     if ($src$$FloatRegister != D0) {
 7010       __ mov_double(D0, $src$$FloatRegister);
 7011     }
 7012 #endif
 7013     address target = CAST_FROM_FN_PTR(address, SharedRuntime::d2l);
 7014     __ call(target, relocInfo::runtime_call_type);
 7015   %}
 7016   ins_pipe(fcvtD2L);
 7017 %}
 7018 
 7019 instruct convF2D_reg(regD dst, regF src) %{
 7020   match(Set dst (ConvF2D src));
 7021   size(4);
 7022   format %{ "FCVTDS  $dst,$src" %}
 7023   ins_encode %{
 7024     __ convert_f2d($dst$$FloatRegister, $src$$FloatRegister);
 7025   %}
 7026   ins_pipe(fcvtF2D);
 7027 %}
 7028 
 7029 instruct convF2I_reg_reg(iRegI dst, regF src, regF tmp) %{
 7030   match(Set dst (ConvF2I src));
 7031   effect( TEMP tmp );
 7032   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
 7033   size(8);
 7034   format %{ "FTOSIZS  $tmp,$src\n\t"
 7035             "FMRS     $dst, $tmp" %}
 7036   ins_encode %{
 7037     __ ftosizs($tmp$$FloatRegister, $src$$FloatRegister);
 7038     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 7039   %}
 7040   ins_pipe(fcvtF2I);
 7041 %}
 7042 
 7043 // Float to Long conversion
 7044 instruct convF2L_reg(R0R1RegL dst, regF src, R0RegI arg1) %{
 7045   match(Set dst (ConvF2L src));
 7046   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
 7047   effect(CALL);
 7048   format %{ "convF2L  $dst,$src\t! call to SharedRuntime::f2l" %}
 7049   ins_encode %{
 7050 #ifndef __ABI_HARD__
 7051     __ fmrs($arg1$$Register, $src$$FloatRegister);
 7052 #else
 7053     if($src$$FloatRegister != S0) {
 7054       __ mov_float(S0, $src$$FloatRegister);
 7055     }
 7056 #endif
 7057     address target = CAST_FROM_FN_PTR(address, SharedRuntime::f2l);
 7058     __ call(target, relocInfo::runtime_call_type);
 7059   %}
 7060   ins_pipe(fcvtF2L);
 7061 %}
 7062 
 7063 instruct convI2D_reg_reg(iRegI src, regD_low dst) %{
 7064   match(Set dst (ConvI2D src));
 7065   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
 7066   size(8);
 7067   format %{ "FMSR     $dst,$src \n\t"
 7068             "FSITOD   $dst $dst"%}
 7069   ins_encode %{
 7070       __ fmsr($dst$$FloatRegister, $src$$Register);
 7071       __ fsitod($dst$$FloatRegister, $dst$$FloatRegister);
 7072   %}
 7073   ins_pipe(fcvtI2D);
 7074 %}
 7075 
 7076 instruct convI2F_reg_reg( regF dst, iRegI src ) %{
 7077   match(Set dst (ConvI2F src));
 7078   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
 7079   size(8);
 7080   format %{ "FMSR     $dst,$src \n\t"
 7081             "FSITOS   $dst, $dst"%}
 7082   ins_encode %{
 7083       __ fmsr($dst$$FloatRegister, $src$$Register);
 7084       __ fsitos($dst$$FloatRegister, $dst$$FloatRegister);
 7085   %}
 7086   ins_pipe(fcvtI2F);
 7087 %}
 7088 
 7089 instruct convI2L_reg(iRegL dst, iRegI src) %{
 7090   match(Set dst (ConvI2L src));
 7091   size(8);
 7092   format %{ "MOV    $dst.lo, $src \n\t"
 7093             "ASR    $dst.hi,$src,31\t! int->long" %}
 7094   ins_encode %{
 7095     __ mov($dst$$Register, $src$$Register);
 7096     __ mov($dst$$Register->successor(), AsmOperand($src$$Register, asr, 31));
 7097   %}
 7098   ins_pipe(ialu_reg_reg);
 7099 %}
 7100 
 7101 // Zero-extend convert int to long
 7102 instruct convI2L_reg_zex(iRegL dst, iRegI src, immL_32bits mask ) %{
 7103   match(Set dst (AndL (ConvI2L src) mask) );
 7104   size(8);
 7105   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend int to long\n\t"
 7106             "MOV    $dst.hi, 0"%}
 7107   ins_encode %{
 7108     __ mov($dst$$Register, $src$$Register);
 7109     __ mov($dst$$Register->successor(), 0);
 7110   %}
 7111   ins_pipe(ialu_reg_reg);
 7112 %}
 7113 
 7114 // Zero-extend long
 7115 instruct zerox_long(iRegL dst, iRegL src, immL_32bits mask ) %{
 7116   match(Set dst (AndL src mask) );
 7117   size(8);
 7118   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend long\n\t"
 7119             "MOV    $dst.hi, 0"%}
 7120   ins_encode %{
 7121     __ mov($dst$$Register, $src$$Register);
 7122     __ mov($dst$$Register->successor(), 0);
 7123   %}
 7124   ins_pipe(ialu_reg_reg);
 7125 %}
 7126 
 7127 instruct MoveF2I_reg_reg(iRegI dst, regF src) %{
 7128   match(Set dst (MoveF2I src));
 7129   effect(DEF dst, USE src);
 7130   ins_cost(MEMORY_REF_COST); // FIXME
 7131 
 7132   size(4);
 7133   format %{ "FMRS   $dst,$src\t! MoveF2I" %}
 7134   ins_encode %{
 7135     __ fmrs($dst$$Register, $src$$FloatRegister);
 7136   %}
 7137   ins_pipe(iload_mem); // FIXME
 7138 %}
 7139 
 7140 instruct MoveI2F_reg_reg(regF dst, iRegI src) %{
 7141   match(Set dst (MoveI2F src));
 7142   ins_cost(MEMORY_REF_COST); // FIXME
 7143 
 7144   size(4);
 7145   format %{ "FMSR   $dst,$src\t! MoveI2F" %}
 7146   ins_encode %{
 7147     __ fmsr($dst$$FloatRegister, $src$$Register);
 7148   %}
 7149   ins_pipe(iload_mem); // FIXME
 7150 %}
 7151 
 7152 instruct MoveD2L_reg_reg(iRegL dst, regD src) %{
 7153   match(Set dst (MoveD2L src));
 7154   effect(DEF dst, USE src);
 7155   ins_cost(MEMORY_REF_COST); // FIXME
 7156 
 7157   size(4);
 7158   format %{ "FMRRD    $dst,$src\t! MoveD2L" %}
 7159   ins_encode %{
 7160     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
 7161   %}
 7162   ins_pipe(iload_mem); // FIXME
 7163 %}
 7164 
 7165 instruct MoveL2D_reg_reg(regD dst, iRegL src) %{
 7166   match(Set dst (MoveL2D src));
 7167   effect(DEF dst, USE src);
 7168   ins_cost(MEMORY_REF_COST); // FIXME
 7169 
 7170   size(4);
 7171   format %{ "FMDRR   $dst,$src\t! MoveL2D" %}
 7172   ins_encode %{
 7173     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
 7174   %}
 7175   ins_pipe(ialu_reg_reg); // FIXME
 7176 %}
 7177 
 7178 //-----------
 7179 // Long to Double conversion
 7180 
 7181 // Magic constant, 0x43300000
 7182 instruct loadConI_x43300000(iRegI dst) %{
 7183   effect(DEF dst);
 7184   size(8);
 7185   format %{ "MOV_SLOW  $dst,0x43300000\t! 2^52" %}
 7186   ins_encode %{
 7187     __ mov_slow($dst$$Register, 0x43300000);
 7188   %}
 7189   ins_pipe(ialu_none);
 7190 %}
 7191 
 7192 // Magic constant, 0x41f00000
 7193 instruct loadConI_x41f00000(iRegI dst) %{
 7194   effect(DEF dst);
 7195   size(8);
 7196   format %{ "MOV_SLOW  $dst, 0x41f00000\t! 2^32" %}
 7197   ins_encode %{
 7198     __ mov_slow($dst$$Register, 0x41f00000);
 7199   %}
 7200   ins_pipe(ialu_none);
 7201 %}
 7202 
 7203 instruct loadConI_x0(iRegI dst) %{
 7204   effect(DEF dst);
 7205   size(4);
 7206   format %{ "MOV  $dst, 0x0\t! 0" %}
 7207   ins_encode %{
 7208     __ mov($dst$$Register, 0);
 7209   %}
 7210   ins_pipe(ialu_none);
 7211 %}
 7212 
 7213 // Construct a double from two float halves
 7214 instruct regDHi_regDLo_to_regD(regD_low dst, regD_low src1, regD_low src2) %{
 7215   effect(DEF dst, USE src1, USE src2);
 7216   size(8);
 7217   format %{ "FCPYS  $dst.hi,$src1.hi\n\t"
 7218             "FCPYS  $dst.lo,$src2.lo" %}
 7219   ins_encode %{
 7220     __ fcpys($dst$$FloatRegister->successor(), $src1$$FloatRegister->successor());
 7221     __ fcpys($dst$$FloatRegister, $src2$$FloatRegister);
 7222   %}
 7223   ins_pipe(faddD_reg_reg);
 7224 %}
 7225 
 7226 // Convert integer in high half of a double register (in the lower half of
 7227 // the double register file) to double
 7228 instruct convI2D_regDHi_regD(regD dst, regD_low src) %{
 7229   effect(DEF dst, USE src);
 7230   size(4);
 7231   format %{ "FSITOD  $dst,$src" %}
 7232   ins_encode %{
 7233     __ fsitod($dst$$FloatRegister, $src$$FloatRegister->successor());
 7234   %}
 7235   ins_pipe(fcvtLHi2D);
 7236 %}
 7237 
 7238 // Add float double precision
 7239 instruct addD_regD_regD(regD dst, regD src1, regD src2) %{
 7240   effect(DEF dst, USE src1, USE src2);
 7241   size(4);
 7242   format %{ "FADDD  $dst,$src1,$src2" %}
 7243   ins_encode %{
 7244     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 7245   %}
 7246   ins_pipe(faddD_reg_reg);
 7247 %}
 7248 
 7249 // Sub float double precision
 7250 instruct subD_regD_regD(regD dst, regD src1, regD src2) %{
 7251   effect(DEF dst, USE src1, USE src2);
 7252   size(4);
 7253   format %{ "FSUBD  $dst,$src1,$src2" %}
 7254   ins_encode %{
 7255     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 7256   %}
 7257   ins_pipe(faddD_reg_reg);
 7258 %}
 7259 
 7260 // Mul float double precision
 7261 instruct mulD_regD_regD(regD dst, regD src1, regD src2) %{
 7262   effect(DEF dst, USE src1, USE src2);
 7263   size(4);
 7264   format %{ "FMULD  $dst,$src1,$src2" %}
 7265   ins_encode %{
 7266     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 7267   %}
 7268   ins_pipe(fmulD_reg_reg);
 7269 %}
 7270 
 7271 instruct regL_to_regD(regD dst, iRegL src) %{
 7272   // No match rule to avoid chain rule match.
 7273   effect(DEF dst, USE src);
 7274   ins_cost(MEMORY_REF_COST);
 7275   size(4);
 7276   format %{ "FMDRR   $dst,$src\t! regL to regD" %}
 7277   ins_encode %{
 7278     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
 7279   %}
 7280   ins_pipe(ialu_reg_reg); // FIXME
 7281 %}
 7282 
 7283 instruct regI_regI_to_regD(regD dst, iRegI src1, iRegI src2) %{
 7284   // No match rule to avoid chain rule match.
 7285   effect(DEF dst, USE src1, USE src2);
 7286   ins_cost(MEMORY_REF_COST);
 7287   size(4);
 7288   format %{ "FMDRR   $dst,$src1,$src2\t! regI,regI to regD" %}
 7289   ins_encode %{
 7290     __ fmdrr($dst$$FloatRegister, $src1$$Register, $src2$$Register);
 7291   %}
 7292   ins_pipe(ialu_reg_reg); // FIXME
 7293 %}
 7294 
 7295 instruct convL2D_reg_slow_fxtof(regD dst, iRegL src) %{
 7296   match(Set dst (ConvL2D src));
 7297   ins_cost(DEFAULT_COST*8 + MEMORY_REF_COST*6); // FIXME
 7298 
 7299   expand %{
 7300     regD_low   tmpsrc;
 7301     iRegI      ix43300000;
 7302     iRegI      ix41f00000;
 7303     iRegI      ix0;
 7304     regD_low   dx43300000;
 7305     regD       dx41f00000;
 7306     regD       tmp1;
 7307     regD_low   tmp2;
 7308     regD       tmp3;
 7309     regD       tmp4;
 7310 
 7311     regL_to_regD(tmpsrc, src);
 7312 
 7313     loadConI_x43300000(ix43300000);
 7314     loadConI_x41f00000(ix41f00000);
 7315     loadConI_x0(ix0);
 7316 
 7317     regI_regI_to_regD(dx43300000, ix0, ix43300000);
 7318     regI_regI_to_regD(dx41f00000, ix0, ix41f00000);
 7319 
 7320     convI2D_regDHi_regD(tmp1, tmpsrc);
 7321     regDHi_regDLo_to_regD(tmp2, dx43300000, tmpsrc);
 7322     subD_regD_regD(tmp3, tmp2, dx43300000);
 7323     mulD_regD_regD(tmp4, tmp1, dx41f00000);
 7324     addD_regD_regD(dst, tmp3, tmp4);
 7325   %}
 7326 %}
 7327 
 7328 instruct convL2I_reg(iRegI dst, iRegL src) %{
 7329   match(Set dst (ConvL2I src));
 7330   size(4);
 7331   format %{ "MOV    $dst,$src.lo\t! long->int" %}
 7332   ins_encode %{
 7333     __ mov($dst$$Register, $src$$Register);
 7334   %}
 7335   ins_pipe(ialu_move_reg_I_to_L);
 7336 %}
 7337 
 7338 // Register Shift Right Immediate
 7339 instruct shrL_reg_imm6_L2I(iRegI dst, iRegL src, immI_32_63 cnt) %{
 7340   match(Set dst (ConvL2I (RShiftL src cnt)));
 7341   size(4);
 7342   format %{ "ASR    $dst,$src.hi,($cnt - 32)\t! long->int or mov if $cnt==32" %}
 7343   ins_encode %{
 7344     if ($cnt$$constant == 32) {
 7345       __ mov($dst$$Register, $src$$Register->successor());
 7346     } else {
 7347       __ mov($dst$$Register, AsmOperand($src$$Register->successor(), asr, $cnt$$constant - 32));
 7348     }
 7349   %}
 7350   ins_pipe(ialu_reg_imm);
 7351 %}
 7352 
 7353 
 7354 //----------Control Flow Instructions------------------------------------------
 7355 // Compare Instructions
 7356 // Compare Integers
 7357 instruct compI_iReg(flagsReg icc, iRegI op1, iRegI op2) %{
 7358   match(Set icc (CmpI op1 op2));
 7359   effect( DEF icc, USE op1, USE op2 );
 7360 
 7361   size(4);
 7362   format %{ "cmp_32 $op1,$op2\t! int" %}
 7363   ins_encode %{
 7364     __ cmp_32($op1$$Register, $op2$$Register);
 7365   %}
 7366   ins_pipe(ialu_cconly_reg_reg);
 7367 %}
 7368 
 7369 #ifdef _LP64
 7370 // Compare compressed pointers
 7371 instruct compN_reg2(flagsRegU icc, iRegN op1, iRegN op2) %{
 7372   match(Set icc (CmpN op1 op2));
 7373   effect( DEF icc, USE op1, USE op2 );
 7374 
 7375   size(4);
 7376   format %{ "cmp_32 $op1,$op2\t! int" %}
 7377   ins_encode %{
 7378     __ cmp_32($op1$$Register, $op2$$Register);
 7379   %}
 7380   ins_pipe(ialu_cconly_reg_reg);
 7381 %}
 7382 #endif
 7383 
 7384 instruct compU_iReg(flagsRegU icc, iRegI op1, iRegI op2) %{
 7385   match(Set icc (CmpU op1 op2));
 7386 
 7387   size(4);
 7388   format %{ "cmp_32 $op1,$op2\t! unsigned int" %}
 7389   ins_encode %{
 7390     __ cmp_32($op1$$Register, $op2$$Register);
 7391   %}
 7392   ins_pipe(ialu_cconly_reg_reg);
 7393 %}
 7394 
 7395 instruct compI_iReg_immneg(flagsReg icc, iRegI op1, aimmIneg op2) %{
 7396   match(Set icc (CmpI op1 op2));
 7397   effect( DEF icc, USE op1 );
 7398 
 7399   size(4);
 7400   format %{ "cmn_32 $op1,-$op2\t! int" %}
 7401   ins_encode %{
 7402     __ cmn_32($op1$$Register, -$op2$$constant);
 7403   %}
 7404   ins_pipe(ialu_cconly_reg_imm);
 7405 %}
 7406 
 7407 instruct compI_iReg_imm(flagsReg icc, iRegI op1, aimmI op2) %{
 7408   match(Set icc (CmpI op1 op2));
 7409   effect( DEF icc, USE op1 );
 7410 
 7411   size(4);
 7412   format %{ "cmp_32 $op1,$op2\t! int" %}
 7413   ins_encode %{
 7414     __ cmp_32($op1$$Register, $op2$$constant);
 7415   %}
 7416   ins_pipe(ialu_cconly_reg_imm);
 7417 %}
 7418 
 7419 instruct testI_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immI0 zero ) %{
 7420   match(Set icc (CmpI (AndI op1 op2) zero));
 7421   size(4);
 7422   format %{ "tst_32 $op2,$op1" %}
 7423 
 7424   ins_encode %{
 7425     __ tst_32($op1$$Register, $op2$$Register);
 7426   %}
 7427   ins_pipe(ialu_cconly_reg_reg_zero);
 7428 %}
 7429 
 7430 instruct testshlI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
 7431   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
 7432   size(4);
 7433   format %{ "TST   $op2,$op1<<$op3" %}
 7434 
 7435   ins_encode %{
 7436     __ tst($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$Register));
 7437   %}
 7438   ins_pipe(ialu_cconly_reg_reg_zero);
 7439 %}
 7440 
 7441 instruct testshlI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
 7442   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
 7443   size(4);
 7444   format %{ "tst_32 $op2,$op1<<$op3" %}
 7445 
 7446   ins_encode %{
 7447     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$constant));
 7448   %}
 7449   ins_pipe(ialu_cconly_reg_reg_zero);
 7450 %}
 7451 
 7452 instruct testsarI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
 7453   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
 7454   size(4);
 7455   format %{ "TST   $op2,$op1<<$op3" %}
 7456 
 7457   ins_encode %{
 7458     __ tst($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$Register));
 7459   %}
 7460   ins_pipe(ialu_cconly_reg_reg_zero);
 7461 %}
 7462 
 7463 instruct testsarI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
 7464   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
 7465   size(4);
 7466   format %{ "tst_32 $op2,$op1<<$op3" %}
 7467 
 7468   ins_encode %{
 7469     __ tst_32($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$constant));
 7470   %}
 7471   ins_pipe(ialu_cconly_reg_reg_zero);
 7472 %}
 7473 
 7474 instruct testshrI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
 7475   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
 7476   size(4);
 7477   format %{ "TST   $op2,$op1<<$op3" %}
 7478 
 7479   ins_encode %{
 7480     __ tst($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$Register));
 7481   %}
 7482   ins_pipe(ialu_cconly_reg_reg_zero);
 7483 %}
 7484 
 7485 instruct testshrI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
 7486   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
 7487   size(4);
 7488   format %{ "tst_32 $op2,$op1<<$op3" %}
 7489 
 7490   ins_encode %{
 7491     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$constant));
 7492   %}
 7493   ins_pipe(ialu_cconly_reg_reg_zero);
 7494 %}
 7495 
 7496 instruct testI_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, limmI op2, immI0 zero ) %{
 7497   match(Set icc (CmpI (AndI op1 op2) zero));
 7498   size(4);
 7499   format %{ "tst_32 $op2,$op1" %}
 7500 
 7501   ins_encode %{
 7502     __ tst_32($op1$$Register, $op2$$constant);
 7503   %}
 7504   ins_pipe(ialu_cconly_reg_imm_zero);
 7505 %}
 7506 
 7507 instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7508   match(Set xcc (CmpL op1 op2));
 7509   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
 7510 
 7511   size(8);
 7512   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! long\n\t"
 7513             "SBCS    $tmp,$op1.hi,$op2.hi" %}
 7514   ins_encode %{
 7515     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
 7516     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
 7517   %}
 7518   ins_pipe(ialu_cconly_reg_reg);
 7519 %}
 7520 
 7521 instruct compUL_reg_reg_LTGE(flagsRegUL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7522   match(Set xcc (CmpUL op1 op2));
 7523   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
 7524 
 7525   size(8);
 7526   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! unsigned long\n\t"
 7527             "SBCS    $tmp,$op1.hi,$op2.hi" %}
 7528   ins_encode %{
 7529     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
 7530     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
 7531   %}
 7532   ins_pipe(ialu_cconly_reg_reg);
 7533 %}
 7534 
 7535 instruct compL_reg_reg_EQNE(flagsRegL_EQNE xcc, iRegL op1, iRegL op2) %{
 7536   match(Set xcc (CmpL op1 op2));
 7537   effect( DEF xcc, USE op1, USE op2 );
 7538 
 7539   size(8);
 7540   format %{ "TEQ    $op1.hi,$op2.hi\t\t! long\n\t"
 7541             "TEQ.eq $op1.lo,$op2.lo" %}
 7542   ins_encode %{
 7543     __ teq($op1$$Register->successor(), $op2$$Register->successor());
 7544     __ teq($op1$$Register, $op2$$Register, eq);
 7545   %}
 7546   ins_pipe(ialu_cconly_reg_reg);
 7547 %}
 7548 
 7549 instruct compL_reg_reg_LEGT(flagsRegL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7550   match(Set xcc (CmpL op1 op2));
 7551   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
 7552 
 7553   size(8);
 7554   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! long\n\t"
 7555             "SBCS    $tmp,$op2.hi,$op1.hi" %}
 7556   ins_encode %{
 7557     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
 7558     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
 7559   %}
 7560   ins_pipe(ialu_cconly_reg_reg);
 7561 %}
 7562 
 7563 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7564 // (hi($con$$constant), lo($con$$constant)) becomes
 7565 instruct compL_reg_con_LTGE(flagsRegL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7566   match(Set xcc (CmpL op1 con));
 7567   effect( DEF xcc, USE op1, USE con, TEMP tmp );
 7568 
 7569   size(8);
 7570   format %{ "SUBS    $tmp,$op1.low,$con\t\t! long\n\t"
 7571             "SBCS    $tmp,$op1.hi,0" %}
 7572   ins_encode %{
 7573     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
 7574     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7575   %}
 7576 
 7577   ins_pipe(ialu_cconly_reg_reg);
 7578 %}
 7579 
 7580 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7581 // (hi($con$$constant), lo($con$$constant)) becomes
 7582 instruct compL_reg_con_EQNE(flagsRegL_EQNE xcc, iRegL op1, immLlowRot con) %{
 7583   match(Set xcc (CmpL op1 con));
 7584   effect( DEF xcc, USE op1, USE con );
 7585 
 7586   size(8);
 7587   format %{ "TEQ    $op1.hi,0\t\t! long\n\t"
 7588             "TEQ.eq $op1.lo,$con" %}
 7589   ins_encode %{
 7590     __ teq($op1$$Register->successor(), 0);
 7591     __ teq($op1$$Register, $con$$constant, eq);
 7592   %}
 7593 
 7594   ins_pipe(ialu_cconly_reg_reg);
 7595 %}
 7596 
 7597 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7598 // (hi($con$$constant), lo($con$$constant)) becomes
 7599 instruct compL_reg_con_LEGT(flagsRegL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7600   match(Set xcc (CmpL op1 con));
 7601   effect( DEF xcc, USE op1, USE con, TEMP tmp );
 7602 
 7603   size(8);
 7604   format %{ "RSBS    $tmp,$op1.low,$con\t\t! long\n\t"
 7605             "RSCS    $tmp,$op1.hi,0" %}
 7606   ins_encode %{
 7607     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
 7608     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7609   %}
 7610 
 7611   ins_pipe(ialu_cconly_reg_reg);
 7612 %}
 7613 
 7614 instruct compUL_reg_reg_EQNE(flagsRegUL_EQNE xcc, iRegL op1, iRegL op2) %{
 7615   match(Set xcc (CmpUL op1 op2));
 7616   effect(DEF xcc, USE op1, USE op2);
 7617 
 7618   size(8);
 7619   format %{ "TEQ    $op1.hi,$op2.hi\t\t! unsigned long\n\t"
 7620             "TEQ.eq $op1.lo,$op2.lo" %}
 7621   ins_encode %{
 7622     __ teq($op1$$Register->successor(), $op2$$Register->successor());
 7623     __ teq($op1$$Register, $op2$$Register, eq);
 7624   %}
 7625   ins_pipe(ialu_cconly_reg_reg);
 7626 %}
 7627 
 7628 instruct compUL_reg_reg_LEGT(flagsRegUL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7629   match(Set xcc (CmpUL op1 op2));
 7630   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
 7631 
 7632   size(8);
 7633   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! unsigned long\n\t"
 7634             "SBCS    $tmp,$op2.hi,$op1.hi" %}
 7635   ins_encode %{
 7636     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
 7637     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
 7638   %}
 7639   ins_pipe(ialu_cconly_reg_reg);
 7640 %}
 7641 
 7642 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7643 // (hi($con$$constant), lo($con$$constant)) becomes
 7644 instruct compUL_reg_con_LTGE(flagsRegUL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7645   match(Set xcc (CmpUL op1 con));
 7646   effect(DEF xcc, USE op1, USE con, TEMP tmp);
 7647 
 7648   size(8);
 7649   format %{ "SUBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
 7650             "SBCS    $tmp,$op1.hi,0" %}
 7651   ins_encode %{
 7652     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
 7653     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7654   %}
 7655 
 7656   ins_pipe(ialu_cconly_reg_reg);
 7657 %}
 7658 
 7659 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7660 // (hi($con$$constant), lo($con$$constant)) becomes
 7661 instruct compUL_reg_con_EQNE(flagsRegUL_EQNE xcc, iRegL op1, immLlowRot con) %{
 7662   match(Set xcc (CmpUL op1 con));
 7663   effect(DEF xcc, USE op1, USE con);
 7664 
 7665   size(8);
 7666   format %{ "TEQ    $op1.hi,0\t\t! unsigned long\n\t"
 7667             "TEQ.eq $op1.lo,$con" %}
 7668   ins_encode %{
 7669     __ teq($op1$$Register->successor(), 0);
 7670     __ teq($op1$$Register, $con$$constant, eq);
 7671   %}
 7672 
 7673   ins_pipe(ialu_cconly_reg_reg);
 7674 %}
 7675 
 7676 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7677 // (hi($con$$constant), lo($con$$constant)) becomes
 7678 instruct compUL_reg_con_LEGT(flagsRegUL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7679   match(Set xcc (CmpUL op1 con));
 7680   effect(DEF xcc, USE op1, USE con, TEMP tmp);
 7681 
 7682   size(8);
 7683   format %{ "RSBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
 7684             "RSCS    $tmp,$op1.hi,0" %}
 7685   ins_encode %{
 7686     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
 7687     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7688   %}
 7689 
 7690   ins_pipe(ialu_cconly_reg_reg);
 7691 %}
 7692 
 7693 /* instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ */
 7694 /*   match(Set xcc (CmpL (AndL op1 op2) zero)); */
 7695 /*   ins_encode %{ */
 7696 /*     __ stop("testL_reg_reg unimplemented"); */
 7697 /*   %} */
 7698 /*   ins_pipe(ialu_cconly_reg_reg); */
 7699 /* %} */
 7700 
 7701 /* // useful for checking the alignment of a pointer: */
 7702 /* instruct testL_reg_con(flagsRegL xcc, iRegL op1, immLlowRot con, immL0 zero) %{ */
 7703 /*   match(Set xcc (CmpL (AndL op1 con) zero)); */
 7704 /*   ins_encode %{ */
 7705 /*     __ stop("testL_reg_con unimplemented"); */
 7706 /*   %} */
 7707 /*   ins_pipe(ialu_cconly_reg_reg); */
 7708 /* %} */
 7709 
 7710 instruct compU_iReg_imm(flagsRegU icc, iRegI op1, aimmU31 op2 ) %{
 7711   match(Set icc (CmpU op1 op2));
 7712 
 7713   size(4);
 7714   format %{ "cmp_32 $op1,$op2\t! unsigned" %}
 7715   ins_encode %{
 7716     __ cmp_32($op1$$Register, $op2$$constant);
 7717   %}
 7718   ins_pipe(ialu_cconly_reg_imm);
 7719 %}
 7720 
 7721 // Compare Pointers
 7722 instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{
 7723   match(Set pcc (CmpP op1 op2));
 7724 
 7725   size(4);
 7726   format %{ "CMP    $op1,$op2\t! ptr" %}
 7727   ins_encode %{
 7728     __ cmp($op1$$Register, $op2$$Register);
 7729   %}
 7730   ins_pipe(ialu_cconly_reg_reg);
 7731 %}
 7732 
 7733 instruct compP_iRegP_imm(flagsRegP pcc, iRegP op1, aimmP op2 ) %{
 7734   match(Set pcc (CmpP op1 op2));
 7735 
 7736   size(4);
 7737   format %{ "CMP    $op1,$op2\t! ptr" %}
 7738   ins_encode %{
 7739     assert($op2$$constant == 0 || _opnds[2]->constant_reloc() == relocInfo::none, "reloc in cmp?");
 7740     __ cmp($op1$$Register, $op2$$constant);
 7741   %}
 7742   ins_pipe(ialu_cconly_reg_imm);
 7743 %}
 7744 
 7745 //----------Max and Min--------------------------------------------------------
 7746 // Min Instructions
 7747 // Conditional move for min
 7748 instruct cmovI_reg_lt( iRegI op2, iRegI op1, flagsReg icc ) %{
 7749   effect( USE_DEF op2, USE op1, USE icc );
 7750 
 7751   size(4);
 7752   format %{ "MOV.lt  $op2,$op1\t! min" %}
 7753   ins_encode %{
 7754     __ mov($op2$$Register, $op1$$Register, lt);
 7755   %}
 7756   ins_pipe(ialu_reg_flags);
 7757 %}
 7758 
 7759 // Min Register with Register.
 7760 instruct minI_eReg(iRegI op1, iRegI op2) %{
 7761   match(Set op2 (MinI op1 op2));
 7762   ins_cost(DEFAULT_COST*2);
 7763   expand %{
 7764     flagsReg icc;
 7765     compI_iReg(icc,op1,op2);
 7766     cmovI_reg_lt(op2,op1,icc);
 7767   %}
 7768 %}
 7769 
 7770 // Max Instructions
 7771 // Conditional move for max
 7772 instruct cmovI_reg_gt( iRegI op2, iRegI op1, flagsReg icc ) %{
 7773   effect( USE_DEF op2, USE op1, USE icc );
 7774   format %{ "MOV.gt  $op2,$op1\t! max" %}
 7775   ins_encode %{
 7776     __ mov($op2$$Register, $op1$$Register, gt);
 7777   %}
 7778   ins_pipe(ialu_reg_flags);
 7779 %}
 7780 
 7781 // Max Register with Register
 7782 instruct maxI_eReg(iRegI op1, iRegI op2) %{
 7783   match(Set op2 (MaxI op1 op2));
 7784   ins_cost(DEFAULT_COST*2);
 7785   expand %{
 7786     flagsReg icc;
 7787     compI_iReg(icc,op1,op2);
 7788     cmovI_reg_gt(op2,op1,icc);
 7789   %}
 7790 %}
 7791 
 7792 
 7793 //----------Float Compares----------------------------------------------------
 7794 // Compare floating, generate condition code
 7795 instruct cmpF_cc(flagsRegF fcc, flagsReg icc, regF src1, regF src2) %{
 7796   match(Set icc (CmpF src1 src2));
 7797   effect(KILL fcc);
 7798 
 7799   size(8);
 7800   format %{ "FCMPs  $src1,$src2\n\t"
 7801             "FMSTAT" %}
 7802   ins_encode %{
 7803     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
 7804     __ fmstat();
 7805   %}
 7806   ins_pipe(faddF_fcc_reg_reg_zero);
 7807 %}
 7808 
 7809 instruct cmpF0_cc(flagsRegF fcc, flagsReg icc, regF src1, immF0 src2) %{
 7810   match(Set icc (CmpF src1 src2));
 7811   effect(KILL fcc);
 7812 
 7813   size(8);
 7814   format %{ "FCMPs  $src1,$src2\n\t"
 7815             "FMSTAT" %}
 7816   ins_encode %{
 7817     __ fcmpzs($src1$$FloatRegister);
 7818     __ fmstat();
 7819   %}
 7820   ins_pipe(faddF_fcc_reg_reg_zero);
 7821 %}
 7822 
 7823 instruct cmpD_cc(flagsRegF fcc, flagsReg icc, regD src1, regD src2) %{
 7824   match(Set icc (CmpD src1 src2));
 7825   effect(KILL fcc);
 7826 
 7827   size(8);
 7828   format %{ "FCMPd  $src1,$src2 \n\t"
 7829             "FMSTAT" %}
 7830   ins_encode %{
 7831     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
 7832     __ fmstat();
 7833   %}
 7834   ins_pipe(faddD_fcc_reg_reg_zero);
 7835 %}
 7836 
 7837 instruct cmpD0_cc(flagsRegF fcc, flagsReg icc, regD src1, immD0 src2) %{
 7838   match(Set icc (CmpD src1 src2));
 7839   effect(KILL fcc);
 7840 
 7841   size(8);
 7842   format %{ "FCMPZd  $src1,$src2 \n\t"
 7843             "FMSTAT" %}
 7844   ins_encode %{
 7845     __ fcmpzd($src1$$FloatRegister);
 7846     __ fmstat();
 7847   %}
 7848   ins_pipe(faddD_fcc_reg_reg_zero);
 7849 %}
 7850 
 7851 // Compare floating, generate -1,0,1
 7852 instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsRegF fcc) %{
 7853   match(Set dst (CmpF3 src1 src2));
 7854   effect(KILL fcc);
 7855   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 7856   size(20);
 7857   // same number of instructions as code using conditional moves but
 7858   // doesn't kill integer condition register
 7859   format %{ "FCMPs  $dst,$src1,$src2 \n\t"
 7860             "VMRS   $dst, FPSCR \n\t"
 7861             "OR     $dst, $dst, 0x08000000 \n\t"
 7862             "EOR    $dst, $dst, $dst << 3 \n\t"
 7863             "MOV    $dst, $dst >> 30" %}
 7864   ins_encode %{
 7865     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
 7866     __ floating_cmp($dst$$Register);
 7867   %}
 7868   ins_pipe( floating_cmp );
 7869 %}
 7870 
 7871 instruct cmpF0_reg(iRegI dst, regF src1, immF0 src2, flagsRegF fcc) %{
 7872   match(Set dst (CmpF3 src1 src2));
 7873   effect(KILL fcc);
 7874   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 7875   size(20);
 7876   // same number of instructions as code using conditional moves but
 7877   // doesn't kill integer condition register
 7878   format %{ "FCMPZs $dst,$src1,$src2 \n\t"
 7879             "VMRS   $dst, FPSCR \n\t"
 7880             "OR     $dst, $dst, 0x08000000 \n\t"
 7881             "EOR    $dst, $dst, $dst << 3 \n\t"
 7882             "MOV    $dst, $dst >> 30" %}
 7883   ins_encode %{
 7884     __ fcmpzs($src1$$FloatRegister);
 7885     __ floating_cmp($dst$$Register);
 7886   %}
 7887   ins_pipe( floating_cmp );
 7888 %}
 7889 
 7890 instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsRegF fcc) %{
 7891   match(Set dst (CmpD3 src1 src2));
 7892   effect(KILL fcc);
 7893   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 7894   size(20);
 7895   // same number of instructions as code using conditional moves but
 7896   // doesn't kill integer condition register
 7897   format %{ "FCMPd  $dst,$src1,$src2 \n\t"
 7898             "VMRS   $dst, FPSCR \n\t"
 7899             "OR     $dst, $dst, 0x08000000 \n\t"
 7900             "EOR    $dst, $dst, $dst << 3 \n\t"
 7901             "MOV    $dst, $dst >> 30" %}
 7902   ins_encode %{
 7903     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
 7904     __ floating_cmp($dst$$Register);
 7905   %}
 7906   ins_pipe( floating_cmp );
 7907 %}
 7908 
 7909 instruct cmpD0_reg(iRegI dst, regD src1, immD0 src2, flagsRegF fcc) %{
 7910   match(Set dst (CmpD3 src1 src2));
 7911   effect(KILL fcc);
 7912   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 7913   size(20);
 7914   // same number of instructions as code using conditional moves but
 7915   // doesn't kill integer condition register
 7916   format %{ "FCMPZd $dst,$src1,$src2 \n\t"
 7917             "VMRS   $dst, FPSCR \n\t"
 7918             "OR     $dst, $dst, 0x08000000 \n\t"
 7919             "EOR    $dst, $dst, $dst << 3 \n\t"
 7920             "MOV    $dst, $dst >> 30" %}
 7921   ins_encode %{
 7922     __ fcmpzd($src1$$FloatRegister);
 7923     __ floating_cmp($dst$$Register);
 7924   %}
 7925   ins_pipe( floating_cmp );
 7926 %}
 7927 
 7928 //----------Branches---------------------------------------------------------
 7929 // Jump
 7930 // (compare 'operand indIndex' and 'instruct addP_reg_reg' above)
 7931 // FIXME
 7932 instruct jumpXtnd(iRegX switch_val, iRegP tmp) %{
 7933   match(Jump switch_val);
 7934   effect(TEMP tmp);
 7935   ins_cost(350);
 7936   format %{  "ADD    $tmp, $constanttablebase, $switch_val\n\t"
 7937              "LDR    $tmp,[$tmp + $constantoffset]\n\t"
 7938              "BX     $tmp" %}
 7939   size(20);
 7940   ins_encode %{
 7941     Register table_reg;
 7942     Register label_reg = $tmp$$Register;
 7943     if (constant_offset() == 0) {
 7944       table_reg = $constanttablebase;
 7945       __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
 7946     } else {
 7947       table_reg = $tmp$$Register;
 7948       int offset = $constantoffset;
 7949       if (is_memoryP(offset)) {
 7950         __ add(table_reg, $constanttablebase, $switch_val$$Register);
 7951         __ ldr(label_reg, Address(table_reg, offset));
 7952       } else {
 7953         __ mov_slow(table_reg, $constantoffset);
 7954         __ add(table_reg, $constanttablebase, table_reg);
 7955         __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
 7956       }
 7957     }
 7958     __ jump(label_reg); // ldr + b better than ldr to PC for branch predictor?
 7959     //    __ ldr(PC, Address($table$$Register, $switch_val$$Register));
 7960   %}
 7961   ins_pipe(ialu_reg_reg);
 7962 %}
 7963 
 7964 // // Direct Branch.
 7965 instruct branch(label labl) %{
 7966   match(Goto);
 7967   effect(USE labl);
 7968 
 7969   size(4);
 7970   ins_cost(BRANCH_COST);
 7971   format %{ "B     $labl" %}
 7972   ins_encode %{
 7973     __ b(*($labl$$label));
 7974   %}
 7975   ins_pipe(br);
 7976 %}
 7977 
 7978 // Conditional Direct Branch
 7979 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{
 7980   match(If cmp icc);
 7981   effect(USE labl);
 7982 
 7983   size(4);
 7984   ins_cost(BRANCH_COST);
 7985   format %{ "B$cmp   $icc,$labl" %}
 7986   ins_encode %{
 7987     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 7988   %}
 7989   ins_pipe(br_cc);
 7990 %}
 7991 
 7992 #ifdef ARM
 7993 instruct branchCon_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, label labl) %{
 7994   match(If cmp icc);
 7995   effect(USE labl);
 7996   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);
 7997 
 7998   size(4);
 7999   ins_cost(BRANCH_COST);
 8000   format %{ "B$cmp   $icc,$labl" %}
 8001   ins_encode %{
 8002     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8003   %}
 8004   ins_pipe(br_cc);
 8005 %}
 8006 #endif
 8007 
 8008 
 8009 instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{
 8010   match(If cmp icc);
 8011   effect(USE labl);
 8012 
 8013   size(4);
 8014   ins_cost(BRANCH_COST);
 8015   format %{ "B$cmp  $icc,$labl" %}
 8016   ins_encode %{
 8017     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8018   %}
 8019   ins_pipe(br_cc);
 8020 %}
 8021 
 8022 instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{
 8023   match(If cmp pcc);
 8024   effect(USE labl);
 8025 
 8026   size(4);
 8027   ins_cost(BRANCH_COST);
 8028   format %{ "B$cmp  $pcc,$labl" %}
 8029   ins_encode %{
 8030     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8031   %}
 8032   ins_pipe(br_cc);
 8033 %}
 8034 
 8035 instruct branchConL_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, label labl) %{
 8036   match(If cmp xcc);
 8037   effect(USE labl);
 8038   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8039 
 8040   size(4);
 8041   ins_cost(BRANCH_COST);
 8042   format %{ "B$cmp  $xcc,$labl" %}
 8043   ins_encode %{
 8044     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8045   %}
 8046   ins_pipe(br_cc);
 8047 %}
 8048 
 8049 instruct branchConL_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, label labl) %{
 8050   match(If cmp xcc);
 8051   effect(USE labl);
 8052   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8053 
 8054   size(4);
 8055   ins_cost(BRANCH_COST);
 8056   format %{ "B$cmp  $xcc,$labl" %}
 8057   ins_encode %{
 8058     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8059   %}
 8060   ins_pipe(br_cc);
 8061 %}
 8062 
 8063 instruct branchConL_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, label labl) %{
 8064   match(If cmp xcc);
 8065   effect(USE labl);
 8066   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le );
 8067 
 8068   size(4);
 8069   ins_cost(BRANCH_COST);
 8070   format %{ "B$cmp  $xcc,$labl" %}
 8071   ins_encode %{
 8072     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8073   %}
 8074   ins_pipe(br_cc);
 8075 %}
 8076 
 8077 instruct branchConUL_LTGE(cmpOpUL cmp, flagsRegUL_LTGE xcc, label labl) %{
 8078   match(If cmp xcc);
 8079   effect(USE labl);
 8080   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8081 
 8082   size(4);
 8083   ins_cost(BRANCH_COST);
 8084   format %{ "B$cmp  $xcc,$labl" %}
 8085   ins_encode %{
 8086     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8087   %}
 8088   ins_pipe(br_cc);
 8089 %}
 8090 
 8091 instruct branchConUL_EQNE(cmpOpUL cmp, flagsRegUL_EQNE xcc, label labl) %{
 8092   match(If cmp xcc);
 8093   effect(USE labl);
 8094   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8095 
 8096   size(4);
 8097   ins_cost(BRANCH_COST);
 8098   format %{ "B$cmp  $xcc,$labl" %}
 8099   ins_encode %{
 8100     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8101   %}
 8102   ins_pipe(br_cc);
 8103 %}
 8104 
 8105 instruct branchConUL_LEGT(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, label labl) %{
 8106   match(If cmp xcc);
 8107   effect(USE labl);
 8108   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le);
 8109 
 8110   size(4);
 8111   ins_cost(BRANCH_COST);
 8112   format %{ "B$cmp  $xcc,$labl" %}
 8113   ins_encode %{
 8114     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8115   %}
 8116   ins_pipe(br_cc);
 8117 %}
 8118 
 8119 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
 8120   match(CountedLoopEnd cmp icc);
 8121   effect(USE labl);
 8122 
 8123   size(4);
 8124   ins_cost(BRANCH_COST);
 8125   format %{ "B$cmp   $icc,$labl\t! Loop end" %}
 8126   ins_encode %{
 8127     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8128   %}
 8129   ins_pipe(br_cc);
 8130 %}
 8131 
 8132 // instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{
 8133 //   match(CountedLoopEnd cmp icc);
 8134 //   ins_pipe(br_cc);
 8135 // %}
 8136 
 8137 // ============================================================================
 8138 // Long Compare
 8139 //
 8140 // Currently we hold longs in 2 registers.  Comparing such values efficiently
 8141 // is tricky.  The flavor of compare used depends on whether we are testing
 8142 // for LT, LE, or EQ.  For a simple LT test we can check just the sign bit.
 8143 // The GE test is the negated LT test.  The LE test can be had by commuting
 8144 // the operands (yielding a GE test) and then negating; negate again for the
 8145 // GT test.  The EQ test is done by ORcc'ing the high and low halves, and the
 8146 // NE test is negated from that.
 8147 
 8148 // Due to a shortcoming in the ADLC, it mixes up expressions like:
 8149 // (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)).  Note the
 8150 // difference between 'Y' and '0L'.  The tree-matches for the CmpI sections
 8151 // are collapsed internally in the ADLC's dfa-gen code.  The match for
 8152 // (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the
 8153 // foo match ends up with the wrong leaf.  One fix is to not match both
 8154 // reg-reg and reg-zero forms of long-compare.  This is unfortunate because
 8155 // both forms beat the trinary form of long-compare and both are very useful
 8156 // on Intel which has so few registers.
 8157 
 8158 // instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{
 8159 //   match(If cmp xcc);
 8160 //   ins_pipe(br_cc);
 8161 // %}
 8162 
 8163 // Manifest a CmpL3 result in an integer register.  Very painful.
 8164 // This is the test to avoid.
 8165 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
 8166   match(Set dst (CmpL3 src1 src2) );
 8167   effect( KILL ccr );
 8168   ins_cost(6*DEFAULT_COST); // FIXME
 8169   size(32);
 8170   format %{
 8171       "CMP    $src1.hi, $src2.hi\t\t! long\n"
 8172     "\tMOV.gt $dst, 1\n"
 8173     "\tmvn.lt $dst, 0\n"
 8174     "\tB.ne   done\n"
 8175     "\tSUBS   $dst, $src1.lo, $src2.lo\n"
 8176     "\tMOV.hi $dst, 1\n"
 8177     "\tmvn.lo $dst, 0\n"
 8178     "done:"     %}
 8179   ins_encode %{
 8180     Label done;
 8181     __ cmp($src1$$Register->successor(), $src2$$Register->successor());
 8182     __ mov($dst$$Register, 1, gt);
 8183     __ mvn($dst$$Register, 0, lt);
 8184     __ b(done, ne);
 8185     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
 8186     __ mov($dst$$Register, 1, hi);
 8187     __ mvn($dst$$Register, 0, lo);
 8188     __ bind(done);
 8189   %}
 8190   ins_pipe(cmpL_reg);
 8191 %}
 8192 
 8193 // Conditional move
 8194 instruct cmovLL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, iRegL src) %{
 8195   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8196   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8197 
 8198   ins_cost(150);
 8199   size(8);
 8200   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8201             "MOV$cmp  $dst,$src.hi" %}
 8202   ins_encode %{
 8203     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8204     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8205   %}
 8206   ins_pipe(ialu_reg);
 8207 %}
 8208 
 8209 instruct cmovLL_reg_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegL dst, iRegL src) %{
 8210   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8211   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8212 
 8213   ins_cost(150);
 8214   size(8);
 8215   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8216             "MOV$cmp  $dst,$src.hi" %}
 8217   ins_encode %{
 8218     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8219     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8220   %}
 8221   ins_pipe(ialu_reg);
 8222 %}
 8223 
 8224 instruct cmovLL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, iRegL src) %{
 8225   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8226   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8227 
 8228   ins_cost(150);
 8229   size(8);
 8230   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8231             "MOV$cmp  $dst,$src.hi" %}
 8232   ins_encode %{
 8233     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8234     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8235   %}
 8236   ins_pipe(ialu_reg);
 8237 %}
 8238 
 8239 instruct cmovLL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, iRegL src) %{
 8240   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8241   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8242 
 8243   ins_cost(150);
 8244   size(8);
 8245   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8246             "MOV$cmp  $dst,$src.hi" %}
 8247   ins_encode %{
 8248     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8249     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8250   %}
 8251   ins_pipe(ialu_reg);
 8252 %}
 8253 
 8254 instruct cmovLL_reg_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegL dst, iRegL src) %{
 8255   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8256   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8257 
 8258   ins_cost(150);
 8259   size(8);
 8260   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8261             "MOV$cmp  $dst,$src.hi" %}
 8262   ins_encode %{
 8263     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8264     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8265   %}
 8266   ins_pipe(ialu_reg);
 8267 %}
 8268 
 8269 instruct cmovLL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, immL0 src) %{
 8270   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8271   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8272   ins_cost(140);
 8273   size(8);
 8274   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8275             "MOV$cmp  $dst,0" %}
 8276   ins_encode %{
 8277     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8278     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8279   %}
 8280   ins_pipe(ialu_imm);
 8281 %}
 8282 
 8283 instruct cmovLL_imm_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegL dst, immL0 src) %{
 8284   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8285   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8286   ins_cost(140);
 8287   size(8);
 8288   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8289             "MOV$cmp  $dst,0" %}
 8290   ins_encode %{
 8291     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8292     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8293   %}
 8294   ins_pipe(ialu_imm);
 8295 %}
 8296 
 8297 instruct cmovLL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, immL0 src) %{
 8298   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8299   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8300   ins_cost(140);
 8301   size(8);
 8302   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8303             "MOV$cmp  $dst,0" %}
 8304   ins_encode %{
 8305     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8306     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8307   %}
 8308   ins_pipe(ialu_imm);
 8309 %}
 8310 
 8311 instruct cmovLL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, immL0 src) %{
 8312   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8313   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8314   ins_cost(140);
 8315   size(8);
 8316   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8317             "MOV$cmp  $dst,0" %}
 8318   ins_encode %{
 8319     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8320     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8321   %}
 8322   ins_pipe(ialu_imm);
 8323 %}
 8324 
 8325 instruct cmovIL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE 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::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 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_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE 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::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 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_EQNE(cmpOpL cmp, flagsRegL_EQNE 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::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 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_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE 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::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 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_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, iRegI src) %{
 8378   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8379   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8380 
 8381   ins_cost(150);
 8382   size(4);
 8383   format %{ "MOV$cmp  $dst,$src" %}
 8384   ins_encode %{
 8385     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8386   %}
 8387   ins_pipe(ialu_reg);
 8388 %}
 8389 
 8390 instruct cmovIL_reg_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegI dst, iRegI src) %{
 8391   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8392   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8393 
 8394   ins_cost(150);
 8395   size(4);
 8396   format %{ "MOV$cmp  $dst,$src" %}
 8397   ins_encode %{
 8398     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8399   %}
 8400   ins_pipe(ialu_reg);
 8401 %}
 8402 
 8403 instruct cmovIL_imm16_LTGE(cmpOpL cmp, flagsRegL_LTGE 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::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 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_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE 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::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 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_EQNE(cmpOpL cmp, flagsRegL_EQNE 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::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 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_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE 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::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 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_imm16_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immI16 src) %{
 8456   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8457   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8458 
 8459   ins_cost(140);
 8460   size(4);
 8461   format %{ "MOVW$cmp  $dst,$src" %}
 8462   ins_encode %{
 8463     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8464   %}
 8465   ins_pipe(ialu_imm);
 8466 %}
 8467 
 8468 instruct cmovIL_imm16_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegI dst, immI16 src) %{
 8469   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8470   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8471 
 8472   ins_cost(140);
 8473   size(4);
 8474   format %{ "MOVW$cmp  $dst,$src" %}
 8475   ins_encode %{
 8476     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8477   %}
 8478   ins_pipe(ialu_imm);
 8479 %}
 8480 
 8481 instruct cmovIL_immMov_LTGE(cmpOpL cmp, flagsRegL_LTGE 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::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 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_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE 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::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 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_EQNE(cmpOpL cmp, flagsRegL_EQNE 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::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 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_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE 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::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 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 cmovIL_immMov_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immIMov src) %{
 8534   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8535   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8536 
 8537   ins_cost(140);
 8538   size(4);
 8539   format %{ "MOV$cmp  $dst,$src" %}
 8540   ins_encode %{
 8541     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8542   %}
 8543   ins_pipe(ialu_imm);
 8544 %}
 8545 
 8546 instruct cmovIL_immMov_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegI dst, immIMov src) %{
 8547   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8548   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8549 
 8550   ins_cost(140);
 8551   size(4);
 8552   format %{ "MOV$cmp  $dst,$src" %}
 8553   ins_encode %{
 8554     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8555   %}
 8556   ins_pipe(ialu_imm);
 8557 %}
 8558 
 8559 instruct cmovPL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE 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::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 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_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE 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::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 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_EQNE(cmpOpL cmp, flagsRegL_EQNE 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::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 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_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE 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::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 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_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, iRegP src) %{
 8612   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8613   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8614 
 8615   ins_cost(150);
 8616   size(4);
 8617   format %{ "MOV$cmp  $dst,$src" %}
 8618   ins_encode %{
 8619     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8620   %}
 8621   ins_pipe(ialu_reg);
 8622 %}
 8623 
 8624 instruct cmovPL_reg_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegP dst, iRegP src) %{
 8625   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8626   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8627 
 8628   ins_cost(150);
 8629   size(4);
 8630   format %{ "MOV$cmp  $dst,$src" %}
 8631   ins_encode %{
 8632     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8633   %}
 8634   ins_pipe(ialu_reg);
 8635 %}
 8636 
 8637 instruct cmovPL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE 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::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 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_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE 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::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 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_EQNE(cmpOpL cmp, flagsRegL_EQNE 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::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 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_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE 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::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 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 cmovPL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, immP0 src) %{
 8690   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8691   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8692 
 8693   ins_cost(140);
 8694   size(4);
 8695   format %{ "MOVW$cmp  $dst,$src" %}
 8696   ins_encode %{
 8697     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8698   %}
 8699   ins_pipe(ialu_imm);
 8700 %}
 8701 
 8702 instruct cmovPL_imm_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegP dst, immP0 src) %{
 8703   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8704   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8705 
 8706   ins_cost(140);
 8707   size(4);
 8708   format %{ "MOVW$cmp  $dst,$src" %}
 8709   ins_encode %{
 8710     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8711   %}
 8712   ins_pipe(ialu_imm);
 8713 %}
 8714 
 8715 instruct cmovFL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regF dst, regF src) %{
 8716   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
 8717   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8718   ins_cost(150);
 8719   size(4);
 8720   format %{ "FCPYS$cmp $dst,$src" %}
 8721   ins_encode %{
 8722     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8723   %}
 8724   ins_pipe(int_conditional_float_move);
 8725 %}
 8726 
 8727 instruct cmovFL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regF dst, regF src) %{
 8728   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
 8729   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8730   ins_cost(150);
 8731   size(4);
 8732   format %{ "FCPYS$cmp $dst,$src" %}
 8733   ins_encode %{
 8734     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8735   %}
 8736   ins_pipe(int_conditional_float_move);
 8737 %}
 8738 
 8739 instruct cmovFL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regF dst, regF src) %{
 8740   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
 8741   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8742   ins_cost(150);
 8743   size(4);
 8744   format %{ "FCPYS$cmp $dst,$src" %}
 8745   ins_encode %{
 8746     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8747   %}
 8748   ins_pipe(int_conditional_float_move);
 8749 %}
 8750 
 8751 instruct cmovDL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE 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::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 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 instruct cmovDL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regD dst, regD src) %{
 8765   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
 8766   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8767 
 8768   ins_cost(150);
 8769   size(4);
 8770   format %{ "FCPYD$cmp $dst,$src" %}
 8771   ins_encode %{
 8772     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8773   %}
 8774   ins_pipe(int_conditional_float_move);
 8775 %}
 8776 
 8777 instruct cmovDL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regD dst, regD src) %{
 8778   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
 8779   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt);
 8780 
 8781   ins_cost(150);
 8782   size(4);
 8783   format %{ "FCPYD$cmp $dst,$src" %}
 8784   ins_encode %{
 8785     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8786   %}
 8787   ins_pipe(int_conditional_float_move);
 8788 %}
 8789 
 8790 // ============================================================================
 8791 // Safepoint Instruction
 8792 // rather than KILL R12, it would be better to use any reg as
 8793 // TEMP. Can't do that at this point because it crashes the compiler
 8794 instruct safePoint_poll(iRegP poll, R12RegI tmp, flagsReg icc) %{
 8795   match(SafePoint poll);
 8796   effect(USE poll, KILL tmp, KILL icc);
 8797 
 8798   size(4);
 8799   format %{ "LDR   $tmp,[$poll]\t! Safepoint: poll for GC" %}
 8800   ins_encode %{
 8801     __ relocate(relocInfo::poll_type);
 8802     __ ldr($tmp$$Register, Address($poll$$Register));
 8803   %}
 8804   ins_pipe(loadPollP);
 8805 %}
 8806 
 8807 
 8808 // ============================================================================
 8809 // Call Instructions
 8810 // Call Java Static Instruction
 8811 instruct CallStaticJavaDirect( method meth ) %{
 8812   match(CallStaticJava);
 8813   predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke());
 8814   effect(USE meth);
 8815 
 8816   ins_cost(CALL_COST);
 8817   format %{ "CALL,static ==> " %}
 8818   ins_encode( SetInstMark, Java_Static_Call( meth ), call_epilog, ClearInstMark );
 8819   ins_pipe(simple_call);
 8820 %}
 8821 
 8822 // Call Java Static Instruction (method handle version)
 8823 instruct CallStaticJavaHandle( method meth ) %{
 8824   match(CallStaticJava);
 8825   predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke());
 8826   effect(USE meth);
 8827   // FP is saved by all callees (for interpreter stack correction).
 8828   // We use it here for a similar purpose, in {preserve,restore}_FP.
 8829 
 8830   ins_cost(CALL_COST);
 8831   format %{ "CALL,static/MethodHandle ==> " %}
 8832   ins_encode( SetInstMark, preserve_SP, Java_Static_Call( meth ), restore_SP, call_epilog, ClearInstMark );
 8833   ins_pipe(simple_call);
 8834 %}
 8835 
 8836 // Call Java Dynamic Instruction
 8837 instruct CallDynamicJavaDirect( method meth ) %{
 8838   match(CallDynamicJava);
 8839   effect(USE meth);
 8840 
 8841   ins_cost(CALL_COST);
 8842   format %{ "MOV_OOP    (empty),R_R8\n\t"
 8843             "CALL,dynamic  ; NOP ==> " %}
 8844   ins_encode( SetInstMark, Java_Dynamic_Call( meth ), call_epilog, ClearInstMark );
 8845   ins_pipe(call);
 8846 %}
 8847 
 8848 // Call Runtime Instruction
 8849 instruct CallRuntimeDirect(method meth) %{
 8850   match(CallRuntime);
 8851   effect(USE meth);
 8852   ins_cost(CALL_COST);
 8853   format %{ "CALL,runtime" %}
 8854   ins_encode( SetInstMark, Java_To_Runtime( meth ),
 8855               call_epilog, ClearInstMark );
 8856   ins_pipe(simple_call);
 8857 %}
 8858 
 8859 // Call runtime without safepoint - same as CallRuntime
 8860 instruct CallLeafDirect(method meth) %{
 8861   match(CallLeaf);
 8862   effect(USE meth);
 8863   ins_cost(CALL_COST);
 8864   format %{ "CALL,runtime leaf" %}
 8865   // TODO: need save_last_PC here?
 8866   ins_encode( SetInstMark, Java_To_Runtime( meth ),
 8867               call_epilog, ClearInstMark );
 8868   ins_pipe(simple_call);
 8869 %}
 8870 
 8871 // Call runtime without safepoint - same as CallLeaf
 8872 instruct CallLeafNoFPDirect(method meth) %{
 8873   match(CallLeafNoFP);
 8874   effect(USE meth);
 8875   ins_cost(CALL_COST);
 8876   format %{ "CALL,runtime leaf nofp" %}
 8877   // TODO: need save_last_PC here?
 8878   ins_encode( SetInstMark, Java_To_Runtime( meth ),
 8879               call_epilog, ClearInstMark );
 8880   ins_pipe(simple_call);
 8881 %}
 8882 
 8883 // Tail Call; Jump from runtime stub to Java code.
 8884 // Also known as an 'interprocedural jump'.
 8885 // Target of jump will eventually return to caller.
 8886 // TailJump below removes the return address.
 8887 instruct TailCalljmpInd(IPRegP jump_target, inline_cache_regP method_ptr) %{
 8888   match(TailCall jump_target method_ptr);
 8889 
 8890   ins_cost(CALL_COST);
 8891   format %{ "jump   $jump_target  \t! $method_ptr holds method" %}
 8892   ins_encode %{
 8893     __ jump($jump_target$$Register);
 8894   %}
 8895   ins_pipe(tail_call);
 8896 %}
 8897 
 8898 
 8899 // Return Instruction
 8900 instruct Ret() %{
 8901   match(Return);
 8902 
 8903   format %{ "ret LR" %}
 8904 
 8905   ins_encode %{
 8906     __ ret(LR);
 8907   %}
 8908 
 8909   ins_pipe(br);
 8910 %}
 8911 
 8912 
 8913 // Tail Jump; remove the return address; jump to target.
 8914 // TailCall above leaves the return address around.
 8915 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
 8916 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
 8917 // "restore" before this instruction (in Epilogue), we need to materialize it
 8918 // in %i0.
 8919 instruct tailjmpInd(IPRegP jump_target, RExceptionRegP ex_oop) %{
 8920   match( TailJump jump_target ex_oop );
 8921   ins_cost(CALL_COST);
 8922   format %{ "MOV    Rexception_pc, LR\n\t"
 8923             "jump   $jump_target \t! $ex_oop holds exc. oop" %}
 8924   ins_encode %{
 8925     __ mov(Rexception_pc, LR);
 8926     __ jump($jump_target$$Register);
 8927   %}
 8928   ins_pipe(tail_call);
 8929 %}
 8930 
 8931 // Forward exception.
 8932 instruct ForwardExceptionjmp()
 8933 %{
 8934   match(ForwardException);
 8935   ins_cost(CALL_COST);
 8936 
 8937   format %{ "MOV  Rexception_pc, LR\n\t"
 8938             "b    forward_exception_entry" %}
 8939   ins_encode %{
 8940     __ mov(Rexception_pc, LR);
 8941     // OK to trash Rtemp, because Rtemp is used by stub
 8942     __ jump(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type, Rtemp);
 8943   %}
 8944   ins_pipe(tail_call);
 8945 %}
 8946 
 8947 // Create exception oop: created by stack-crawling runtime code.
 8948 // Created exception is now available to this handler, and is setup
 8949 // just prior to jumping to this handler.  No code emitted.
 8950 instruct CreateException( RExceptionRegP ex_oop )
 8951 %{
 8952   match(Set ex_oop (CreateEx));
 8953   ins_cost(0);
 8954 
 8955   size(0);
 8956   // use the following format syntax
 8957   format %{ "! exception oop is in Rexception_obj; no code emitted" %}
 8958   ins_encode();
 8959   ins_pipe(empty);
 8960 %}
 8961 
 8962 
 8963 // Rethrow exception:
 8964 // The exception oop will come in the first argument position.
 8965 // Then JUMP (not call) to the rethrow stub code.
 8966 instruct RethrowException()
 8967 %{
 8968   match(Rethrow);
 8969   ins_cost(CALL_COST);
 8970 
 8971   // use the following format syntax
 8972   format %{ "b    rethrow_stub" %}
 8973   ins_encode %{
 8974     Register scratch = R1_tmp;
 8975     assert_different_registers(scratch, c_rarg0, LR);
 8976     __ jump(OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type, scratch);
 8977   %}
 8978   ins_pipe(tail_call);
 8979 %}
 8980 
 8981 
 8982 // Die now
 8983 instruct ShouldNotReachHere( )
 8984 %{
 8985   match(Halt);
 8986   ins_cost(CALL_COST);
 8987 
 8988   // Use the following format syntax
 8989   format %{ "ShouldNotReachHere" %}
 8990   ins_encode %{
 8991     if (is_reachable()) {
 8992       const char* str = __ code_string(_halt_reason);
 8993       __ stop(str);
 8994     }
 8995   %}
 8996   ins_pipe(tail_call);
 8997 %}
 8998 
 8999 // ============================================================================
 9000 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
 9001 // array for an instance of the superklass.  Set a hidden internal cache on a
 9002 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
 9003 // not zero for a miss or zero for a hit.  The encoding ALSO sets flags.
 9004 instruct partialSubtypeCheck( R0RegP index, R1RegP sub, R2RegP super, flagsRegP pcc, LRRegP lr ) %{
 9005   match(Set index (PartialSubtypeCheck sub super));
 9006   effect( KILL pcc, KILL lr );
 9007   ins_cost(DEFAULT_COST*10);
 9008   format %{ "CALL   PartialSubtypeCheck" %}
 9009   ins_encode %{
 9010     __ call(StubRoutines::Arm::partial_subtype_check(), relocInfo::runtime_call_type);
 9011   %}
 9012   ins_pipe(partial_subtype_check_pipe);
 9013 %}
 9014 
 9015 /* instruct partialSubtypeCheck_vs_zero( flagsRegP pcc, o1RegP sub, o2RegP super, immP0 zero, o0RegP idx, o7RegP o7 ) %{ */
 9016 /*   match(Set pcc (CmpP (PartialSubtypeCheck sub super) zero)); */
 9017 /*   ins_pipe(partial_subtype_check_pipe); */
 9018 /* %} */
 9019 
 9020 
 9021 // ============================================================================
 9022 // inlined locking and unlocking
 9023 
 9024 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch )
 9025 %{
 9026   match(Set pcc (FastLock object box));
 9027 
 9028   effect(TEMP scratch, TEMP scratch2);
 9029   ins_cost(DEFAULT_COST*3);
 9030 
 9031   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2" %}
 9032   ins_encode %{
 9033     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
 9034   %}
 9035   ins_pipe(long_memory_op);
 9036 %}
 9037 
 9038 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch ) %{
 9039   match(Set pcc (FastUnlock object box));
 9040   effect(TEMP scratch, TEMP scratch2);
 9041   ins_cost(100);
 9042 
 9043   format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2" %}
 9044   ins_encode %{
 9045     __ fast_unlock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
 9046   %}
 9047   ins_pipe(long_memory_op);
 9048 %}
 9049 
 9050 // Count and Base registers are fixed because the allocator cannot
 9051 // kill unknown registers.  The encodings are generic.
 9052 instruct clear_array(iRegX cnt, iRegP base, iRegI temp, iRegX zero, Universe dummy, flagsReg cpsr) %{
 9053   match(Set dummy (ClearArray cnt base));
 9054   effect(TEMP temp, TEMP zero, KILL cpsr);
 9055   ins_cost(300);
 9056   format %{ "MOV    $zero,0\n"
 9057       "        MOV    $temp,$cnt\n"
 9058       "loop:   SUBS   $temp,$temp,4\t! Count down a dword of bytes\n"
 9059       "        STR.ge $zero,[$base+$temp]\t! delay slot"
 9060       "        B.gt   loop\t\t! Clearing loop\n" %}
 9061   ins_encode %{
 9062     __ mov($zero$$Register, 0);
 9063     __ mov($temp$$Register, $cnt$$Register);
 9064     Label loop;
 9065     __ bind(loop);
 9066     __ subs($temp$$Register, $temp$$Register, 4);
 9067     __ str($zero$$Register, Address($base$$Register, $temp$$Register), ge);
 9068     __ b(loop, gt);
 9069   %}
 9070   ins_pipe(long_memory_op);
 9071 %}
 9072 
 9073 #ifdef XXX
 9074 // FIXME: Why R0/R1/R2/R3?
 9075 instruct string_compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result,
 9076                         iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 9077   predicate(!CompactStrings);
 9078   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
 9079   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, TEMP tmp1, TEMP tmp2);
 9080   ins_cost(300);
 9081   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // TEMP $tmp1, $tmp2" %}
 9082   ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result, tmp1, tmp2) );
 9083 
 9084   ins_pipe(long_memory_op);
 9085 %}
 9086 
 9087 // FIXME: Why R0/R1/R2?
 9088 instruct string_equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2,
 9089                        flagsReg ccr) %{
 9090   predicate(!CompactStrings);
 9091   match(Set result (StrEquals (Binary str1 str2) cnt));
 9092   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp1, TEMP tmp2, TEMP result, KILL ccr);
 9093 
 9094   ins_cost(300);
 9095   format %{ "String Equals $str1,$str2,$cnt -> $result   // TEMP $tmp1, $tmp2" %}
 9096   ins_encode( enc_String_Equals(str1, str2, cnt, result, tmp1, tmp2) );
 9097   ins_pipe(long_memory_op);
 9098 %}
 9099 
 9100 // FIXME: Why R0/R1?
 9101 instruct array_equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result,
 9102                       flagsReg ccr) %{
 9103   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
 9104   match(Set result (AryEq ary1 ary2));
 9105   effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP result, KILL ccr);
 9106 
 9107   ins_cost(300);
 9108   format %{ "Array Equals $ary1,$ary2 -> $result   // TEMP $tmp1,$tmp2,$tmp3" %}
 9109   ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, result));
 9110   ins_pipe(long_memory_op);
 9111 %}
 9112 #endif
 9113 
 9114 //---------- Zeros Count Instructions ------------------------------------------
 9115 
 9116 instruct countLeadingZerosI(iRegI dst, iRegI src) %{
 9117   match(Set dst (CountLeadingZerosI src));
 9118   size(4);
 9119   format %{ "CLZ_32 $dst,$src" %}
 9120   ins_encode %{
 9121     __ clz_32($dst$$Register, $src$$Register);
 9122   %}
 9123   ins_pipe(ialu_reg);
 9124 %}
 9125 
 9126 instruct countLeadingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
 9127   match(Set dst (CountLeadingZerosL src));
 9128   effect(TEMP tmp, TEMP dst, KILL ccr);
 9129   size(16);
 9130   format %{ "CLZ    $dst,$src.hi\n\t"
 9131             "TEQ    $dst,32\n\t"
 9132             "CLZ.eq $tmp,$src.lo\n\t"
 9133             "ADD.eq $dst, $dst, $tmp\n\t" %}
 9134   ins_encode %{
 9135     __ clz($dst$$Register, $src$$Register->successor());
 9136     __ teq($dst$$Register, 32);
 9137     __ clz($tmp$$Register, $src$$Register, eq);
 9138     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
 9139   %}
 9140   ins_pipe(ialu_reg);
 9141 %}
 9142 
 9143 instruct countTrailingZerosI(iRegI dst, iRegI src, iRegI tmp) %{
 9144   match(Set dst (CountTrailingZerosI src));
 9145   effect(TEMP tmp);
 9146   size(8);
 9147   format %{ "RBIT_32 $tmp, $src\n\t"
 9148             "CLZ_32  $dst,$tmp" %}
 9149   ins_encode %{
 9150     __ rbit_32($tmp$$Register, $src$$Register);
 9151     __ clz_32($dst$$Register, $tmp$$Register);
 9152   %}
 9153   ins_pipe(ialu_reg);
 9154 %}
 9155 
 9156 instruct countTrailingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
 9157   match(Set dst (CountTrailingZerosL src));
 9158   effect(TEMP tmp, TEMP dst, KILL ccr);
 9159   size(24);
 9160   format %{ "RBIT   $tmp,$src.lo\n\t"
 9161             "CLZ    $dst,$tmp\n\t"
 9162             "TEQ    $dst,32\n\t"
 9163             "RBIT   $tmp,$src.hi\n\t"
 9164             "CLZ.eq $tmp,$tmp\n\t"
 9165             "ADD.eq $dst,$dst,$tmp\n\t" %}
 9166   ins_encode %{
 9167     __ rbit($tmp$$Register, $src$$Register);
 9168     __ clz($dst$$Register, $tmp$$Register);
 9169     __ teq($dst$$Register, 32);
 9170     __ rbit($tmp$$Register, $src$$Register->successor());
 9171     __ clz($tmp$$Register, $tmp$$Register, eq);
 9172     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
 9173   %}
 9174   ins_pipe(ialu_reg);
 9175 %}
 9176 
 9177 
 9178 //---------- Population Count Instructions -------------------------------------
 9179 
 9180 instruct popCountI(iRegI dst, iRegI src, regD_low tmp) %{
 9181   predicate(UsePopCountInstruction);
 9182   match(Set dst (PopCountI src));
 9183   effect(TEMP tmp);
 9184 
 9185   format %{ "FMSR       $tmp,$src\n\t"
 9186             "VCNT.8     $tmp,$tmp\n\t"
 9187             "VPADDL.U8  $tmp,$tmp\n\t"
 9188             "VPADDL.U16 $tmp,$tmp\n\t"
 9189             "FMRS       $dst,$tmp" %}
 9190   size(20);
 9191 
 9192   ins_encode %{
 9193     __ fmsr($tmp$$FloatRegister, $src$$Register);
 9194     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
 9195     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
 9196     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
 9197     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 9198   %}
 9199   ins_pipe(ialu_reg); // FIXME
 9200 %}
 9201 
 9202 // Note: Long.bitCount(long) returns an int.
 9203 instruct popCountL(iRegI dst, iRegL src, regD_low tmp) %{
 9204   predicate(UsePopCountInstruction);
 9205   match(Set dst (PopCountL src));
 9206   effect(TEMP tmp);
 9207 
 9208   format %{ "FMDRR       $tmp,$src.lo,$src.hi\n\t"
 9209             "VCNT.8      $tmp,$tmp\n\t"
 9210             "VPADDL.U8   $tmp,$tmp\n\t"
 9211             "VPADDL.U16  $tmp,$tmp\n\t"
 9212             "VPADDL.U32  $tmp,$tmp\n\t"
 9213             "FMRS        $dst,$tmp" %}
 9214 
 9215   size(32);
 9216 
 9217   ins_encode %{
 9218     __ fmdrr($tmp$$FloatRegister, $src$$Register, $src$$Register->successor());
 9219     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
 9220     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
 9221     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
 9222     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 32, 0);
 9223     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 9224   %}
 9225   ins_pipe(ialu_reg);
 9226 %}
 9227 
 9228 
 9229 // ============================================================================
 9230 //------------Bytes reverse--------------------------------------------------
 9231 
 9232 instruct bytes_reverse_int(iRegI dst, iRegI src) %{
 9233   match(Set dst (ReverseBytesI src));
 9234 
 9235   size(4);
 9236   format %{ "REV32 $dst,$src" %}
 9237   ins_encode %{
 9238     __ rev($dst$$Register, $src$$Register);
 9239   %}
 9240   ins_pipe( iload_mem ); // FIXME
 9241 %}
 9242 
 9243 instruct bytes_reverse_long(iRegL dst, iRegL src) %{
 9244   match(Set dst (ReverseBytesL src));
 9245   effect(TEMP dst);
 9246   size(8);
 9247   format %{ "REV $dst.lo,$src.lo\n\t"
 9248             "REV $dst.hi,$src.hi" %}
 9249   ins_encode %{
 9250     __ rev($dst$$Register, $src$$Register->successor());
 9251     __ rev($dst$$Register->successor(), $src$$Register);
 9252   %}
 9253   ins_pipe( iload_mem ); // FIXME
 9254 %}
 9255 
 9256 instruct bytes_reverse_unsigned_short(iRegI dst, iRegI src) %{
 9257   match(Set dst (ReverseBytesUS src));
 9258   size(4);
 9259   format %{ "REV16 $dst,$src" %}
 9260   ins_encode %{
 9261     __ rev16($dst$$Register, $src$$Register);
 9262   %}
 9263   ins_pipe( iload_mem ); // FIXME
 9264 %}
 9265 
 9266 instruct bytes_reverse_short(iRegI dst, iRegI src) %{
 9267   match(Set dst (ReverseBytesS src));
 9268   size(4);
 9269   format %{ "REVSH $dst,$src" %}
 9270   ins_encode %{
 9271     __ revsh($dst$$Register, $src$$Register);
 9272   %}
 9273   ins_pipe( iload_mem ); // FIXME
 9274 %}
 9275 
 9276 
 9277 // ====================VECTOR INSTRUCTIONS=====================================
 9278 
 9279 // Load Aligned Packed values into a Double Register
 9280 instruct loadV8(vecD dst, memoryD mem) %{
 9281   predicate(n->as_LoadVector()->memory_size() == 8);
 9282   match(Set dst (LoadVector mem));
 9283   ins_cost(MEMORY_REF_COST);
 9284   size(4);
 9285   format %{ "FLDD   $mem,$dst\t! load vector (8 bytes)" %}
 9286   ins_encode %{
 9287     __ ldr_double($dst$$FloatRegister, $mem$$Address);
 9288   %}
 9289   ins_pipe(floadD_mem);
 9290 %}
 9291 
 9292 // Load Aligned Packed values into a Double Register Pair
 9293 instruct loadV16(vecX dst, memoryvld mem) %{
 9294   predicate(n->as_LoadVector()->memory_size() == 16);
 9295   match(Set dst (LoadVector mem));
 9296   ins_cost(MEMORY_REF_COST);
 9297   size(4);
 9298   format %{ "VLD1   $mem,$dst.Q\t! load vector (16 bytes)" %}
 9299   ins_encode %{
 9300     __ vld1($dst$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
 9301   %}
 9302   ins_pipe(floadD_mem); // FIXME
 9303 %}
 9304 
 9305 // Store Vector in Double register to memory
 9306 instruct storeV8(memoryD mem, vecD src) %{
 9307   predicate(n->as_StoreVector()->memory_size() == 8);
 9308   match(Set mem (StoreVector mem src));
 9309   ins_cost(MEMORY_REF_COST);
 9310   size(4);
 9311   format %{ "FSTD   $src,$mem\t! store vector (8 bytes)" %}
 9312   ins_encode %{
 9313     __ str_double($src$$FloatRegister, $mem$$Address);
 9314   %}
 9315   ins_pipe(fstoreD_mem_reg);
 9316 %}
 9317 
 9318 // Store Vector in Double Register Pair to memory
 9319 instruct storeV16(memoryvld mem, vecX src) %{
 9320   predicate(n->as_StoreVector()->memory_size() == 16);
 9321   match(Set mem (StoreVector mem src));
 9322   ins_cost(MEMORY_REF_COST);
 9323   size(4);
 9324   format %{ "VST1   $src,$mem\t! store vector (16 bytes)" %}
 9325   ins_encode %{
 9326     __ vst1($src$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
 9327   %}
 9328   ins_pipe(fstoreD_mem_reg); // FIXME
 9329 %}
 9330 
 9331 // Replicate scalar to packed byte values in Double register
 9332 instruct Repl8B_reg(vecD dst, iRegI src, iRegI tmp) %{
 9333   predicate(n->as_Vector()->length() == 8 &&
 9334             Matcher::vector_element_basic_type(n) == T_BYTE);
 9335   match(Set dst (Replicate src));
 9336   ins_cost(DEFAULT_COST*4);
 9337   effect(TEMP tmp);
 9338   size(16);
 9339 
 9340   // FIXME: could use PKH instruction instead?
 9341   format %{ "LSL      $tmp, $src, 24 \n\t"
 9342             "OR       $tmp, $tmp, ($tmp >> 8) \n\t"
 9343             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
 9344             "FMDRR    $dst,$tmp,$tmp\t" %}
 9345   ins_encode %{
 9346     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 24));
 9347     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 8));
 9348     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
 9349     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 9350   %}
 9351   ins_pipe(ialu_reg); // FIXME
 9352 %}
 9353 
 9354 // Replicate scalar to packed byte values in Double register
 9355 instruct Repl8B_reg_simd(vecD dst, iRegI src) %{
 9356   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9357             Matcher::vector_element_basic_type(n) == T_BYTE);
 9358   match(Set dst (Replicate src));
 9359   size(4);
 9360 
 9361   format %{ "VDUP.8 $dst,$src\t" %}
 9362   ins_encode %{
 9363     bool quad = false;
 9364     __ vdupI($dst$$FloatRegister, $src$$Register,
 9365              MacroAssembler::VELEM_SIZE_8, quad);
 9366   %}
 9367   ins_pipe(ialu_reg); // FIXME
 9368 %}
 9369 
 9370 // Replicate scalar to packed byte values in Double register pair
 9371 instruct Repl16B_reg(vecX dst, iRegI src) %{
 9372   predicate(n->as_Vector()->length_in_bytes() == 16 &&
 9373             Matcher::vector_element_basic_type(n) == T_BYTE);
 9374   match(Set dst (Replicate src));
 9375   size(4);
 9376 
 9377   format %{ "VDUP.8 $dst.Q,$src\t" %}
 9378   ins_encode %{
 9379     bool quad = true;
 9380     __ vdupI($dst$$FloatRegister, $src$$Register,
 9381              MacroAssembler::VELEM_SIZE_8, quad);
 9382   %}
 9383   ins_pipe(ialu_reg); // FIXME
 9384 %}
 9385 
 9386 // Replicate scalar constant to packed byte values in Double register
 9387 instruct Repl8B_immI(vecD dst, immI src, iRegI tmp) %{
 9388   predicate(n->as_Vector()->length() == 8 &&
 9389             Matcher::vector_element_basic_type(n) == T_BYTE);
 9390   match(Set dst (Replicate src));
 9391   ins_cost(DEFAULT_COST*2);
 9392   effect(TEMP tmp);
 9393   size(12);
 9394 
 9395   format %{ "MOV      $tmp, Repl4($src))\n\t"
 9396             "FMDRR    $dst,$tmp,$tmp\t" %}
 9397   ins_encode( LdReplImmI(src, dst, tmp, (4), (1)) );
 9398   ins_pipe(loadConFD); // FIXME
 9399 %}
 9400 
 9401 // Replicate scalar constant to packed byte values in Double register
 9402 // TODO: support negative constants with MVNI?
 9403 instruct Repl8B_immU8(vecD dst, immU8 src) %{
 9404   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9405             Matcher::vector_element_basic_type(n) == T_BYTE);
 9406   match(Set dst (Replicate src));
 9407   size(4);
 9408 
 9409   format %{ "VMOV.U8  $dst,$src" %}
 9410   ins_encode %{
 9411     bool quad = false;
 9412     __ vmovI($dst$$FloatRegister, $src$$constant,
 9413              MacroAssembler::VELEM_SIZE_8, quad);
 9414   %}
 9415   ins_pipe(loadConFD); // FIXME
 9416 %}
 9417 
 9418 // Replicate scalar constant to packed byte values in Double register pair
 9419 instruct Repl16B_immU8(vecX dst, immU8 src) %{
 9420   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd() &&
 9421             Matcher::vector_element_basic_type(n) == T_BYTE);
 9422   match(Set dst (Replicate src));
 9423   size(4);
 9424 
 9425   format %{ "VMOV.U8  $dst.Q,$src" %}
 9426   ins_encode %{
 9427     bool quad = true;
 9428     __ vmovI($dst$$FloatRegister, $src$$constant,
 9429              MacroAssembler::VELEM_SIZE_8, quad);
 9430   %}
 9431   ins_pipe(loadConFD); // FIXME
 9432 %}
 9433 
 9434 // Replicate scalar to packed short/char values into Double register
 9435 instruct Repl4S_reg(vecD dst, iRegI src, iRegI tmp) %{
 9436   predicate(n->as_Vector()->length() == 4 &&
 9437             Matcher::vector_element_basic_type(n) == T_SHORT);
 9438   match(Set dst (Replicate src));
 9439   ins_cost(DEFAULT_COST*3);
 9440   effect(TEMP tmp);
 9441   size(12);
 9442 
 9443   // FIXME: could use PKH instruction instead?
 9444   format %{ "LSL      $tmp, $src, 16 \n\t"
 9445             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
 9446             "FMDRR    $dst,$tmp,$tmp\t" %}
 9447   ins_encode %{
 9448     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 16));
 9449     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
 9450     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 9451   %}
 9452   ins_pipe(ialu_reg); // FIXME
 9453 %}
 9454 
 9455 // Replicate scalar to packed byte values in Double register
 9456 instruct Repl4S_reg_simd(vecD dst, iRegI src) %{
 9457   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9458             Matcher::vector_element_basic_type(n) == T_SHORT);
 9459   match(Set dst (Replicate src));
 9460   size(4);
 9461 
 9462   format %{ "VDUP.16 $dst,$src\t" %}
 9463   ins_encode %{
 9464     bool quad = false;
 9465     __ vdupI($dst$$FloatRegister, $src$$Register,
 9466              MacroAssembler::VELEM_SIZE_16, quad);
 9467   %}
 9468   ins_pipe(ialu_reg); // FIXME
 9469 %}
 9470 
 9471 // Replicate scalar to packed byte values in Double register pair
 9472 instruct Repl8S_reg(vecX dst, iRegI src) %{
 9473   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd() &&
 9474             Matcher::vector_element_basic_type(n) == T_SHORT);
 9475   match(Set dst (Replicate src));
 9476   size(4);
 9477 
 9478   format %{ "VDUP.16 $dst.Q,$src\t" %}
 9479   ins_encode %{
 9480     bool quad = true;
 9481     __ vdupI($dst$$FloatRegister, $src$$Register,
 9482              MacroAssembler::VELEM_SIZE_16, quad);
 9483   %}
 9484   ins_pipe(ialu_reg); // FIXME
 9485 %}
 9486 
 9487 
 9488 // Replicate scalar constant to packed short/char values in Double register
 9489 instruct Repl4S_immI(vecD dst, immI src, iRegP tmp) %{
 9490   predicate(n->as_Vector()->length() == 4 &&
 9491             Matcher::vector_element_basic_type(n) == T_SHORT);
 9492   match(Set dst (Replicate src));
 9493   effect(TEMP tmp);
 9494   size(12);
 9495   ins_cost(DEFAULT_COST*4); // FIXME
 9496 
 9497   format %{ "MOV      $tmp, Repl2($src))\n\t"
 9498             "FMDRR    $dst,$tmp,$tmp\t" %}
 9499   ins_encode( LdReplImmI(src, dst, tmp, (2), (2)) );
 9500   ins_pipe(loadConFD); // FIXME
 9501 %}
 9502 
 9503 // Replicate scalar constant to packed byte values in Double register
 9504 instruct Repl4S_immU8(vecD dst, immU8 src) %{
 9505   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9506             Matcher::vector_element_basic_type(n) == T_SHORT);
 9507   match(Set dst (Replicate src));
 9508   size(4);
 9509 
 9510   format %{ "VMOV.U16  $dst,$src" %}
 9511   ins_encode %{
 9512     bool quad = false;
 9513     __ vmovI($dst$$FloatRegister, $src$$constant,
 9514              MacroAssembler::VELEM_SIZE_16, quad);
 9515   %}
 9516   ins_pipe(loadConFD); // FIXME
 9517 %}
 9518 
 9519 // Replicate scalar constant to packed byte values in Double register pair
 9520 instruct Repl8S_immU8(vecX dst, immU8 src) %{
 9521   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd() &&
 9522             Matcher::vector_element_basic_type(n) == T_SHORT);
 9523   match(Set dst (Replicate src));
 9524   size(4);
 9525 
 9526   format %{ "VMOV.U16  $dst.Q,$src" %}
 9527   ins_encode %{
 9528     bool quad = true;
 9529     __ vmovI($dst$$FloatRegister, $src$$constant,
 9530              MacroAssembler::VELEM_SIZE_16, quad);
 9531   %}
 9532   ins_pipe(loadConFD); // FIXME
 9533 %}
 9534 
 9535 // Replicate scalar to packed int values in Double register
 9536 instruct Repl2I_reg(vecD dst, iRegI src) %{
 9537   predicate(n->as_Vector()->length() == 2 &&
 9538             Matcher::vector_element_basic_type(n) == T_INT);
 9539   match(Set dst (Replicate src));
 9540   size(4);
 9541 
 9542   format %{ "FMDRR    $dst,$src,$src\t" %}
 9543   ins_encode %{
 9544     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
 9545   %}
 9546   ins_pipe(ialu_reg); // FIXME
 9547 %}
 9548 
 9549 // Replicate scalar to packed int values in Double register pair
 9550 instruct Repl4I_reg(vecX dst, iRegI src) %{
 9551   predicate(n->as_Vector()->length() == 4 &&
 9552             Matcher::vector_element_basic_type(n) == T_INT);
 9553   match(Set dst (Replicate src));
 9554   ins_cost(DEFAULT_COST*2);
 9555   size(8);
 9556 
 9557   format %{ "FMDRR    $dst.lo,$src,$src\n\t"
 9558             "FMDRR    $dst.hi,$src,$src" %}
 9559 
 9560   ins_encode %{
 9561     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
 9562     __ fmdrr($dst$$FloatRegister->successor()->successor(),
 9563              $src$$Register, $src$$Register);
 9564   %}
 9565   ins_pipe(ialu_reg); // FIXME
 9566 %}
 9567 
 9568 // Replicate scalar to packed int values in Double register
 9569 instruct Repl2I_reg_simd(vecD dst, iRegI src) %{
 9570   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9571             Matcher::vector_element_basic_type(n) == T_INT);
 9572   match(Set dst (Replicate src));
 9573   size(4);
 9574 
 9575   format %{ "VDUP.32 $dst.D,$src\t" %}
 9576   ins_encode %{
 9577     bool quad = false;
 9578     __ vdupI($dst$$FloatRegister, $src$$Register,
 9579              MacroAssembler::VELEM_SIZE_32, quad);
 9580   %}
 9581   ins_pipe(ialu_reg); // FIXME
 9582 %}
 9583 
 9584 // Replicate scalar to packed int values in Double register pair
 9585 instruct Repl4I_reg_simd(vecX dst, iRegI src) %{
 9586   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd() &&
 9587             Matcher::vector_element_basic_type(n) == T_INT);
 9588   match(Set dst (Replicate src));
 9589   size(4);
 9590 
 9591   format %{ "VDUP.32 $dst.Q,$src\t" %}
 9592   ins_encode %{
 9593     bool quad = true;
 9594     __ vdupI($dst$$FloatRegister, $src$$Register,
 9595              MacroAssembler::VELEM_SIZE_32, quad);
 9596   %}
 9597   ins_pipe(ialu_reg); // FIXME
 9598 %}
 9599 
 9600 
 9601 // Replicate scalar zero constant to packed int values in Double register
 9602 instruct Repl2I_immI(vecD dst, immI src, iRegI tmp) %{
 9603   predicate(n->as_Vector()->length() == 2 &&
 9604             Matcher::vector_element_basic_type(n) == T_INT);
 9605   match(Set dst (Replicate src));
 9606   effect(TEMP tmp);
 9607   size(12);
 9608   ins_cost(DEFAULT_COST*4); // FIXME
 9609 
 9610   format %{ "MOV      $tmp, Repl1($src))\n\t"
 9611             "FMDRR    $dst,$tmp,$tmp\t" %}
 9612   ins_encode( LdReplImmI(src, dst, tmp, (1), (4)) );
 9613   ins_pipe(loadConFD); // FIXME
 9614 %}
 9615 
 9616 // Replicate scalar constant to packed byte values in Double register
 9617 instruct Repl2I_immU8(vecD dst, immU8 src) %{
 9618   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9619             Matcher::vector_element_basic_type(n) == T_INT);
 9620   match(Set dst (Replicate src));
 9621   size(4);
 9622 
 9623   format %{ "VMOV.I32  $dst.D,$src" %}
 9624   ins_encode %{
 9625     bool quad = false;
 9626     __ vmovI($dst$$FloatRegister, $src$$constant,
 9627              MacroAssembler::VELEM_SIZE_32, quad);
 9628   %}
 9629   ins_pipe(loadConFD); // FIXME
 9630 %}
 9631 
 9632 // Replicate scalar constant to packed byte values in Double register pair
 9633 instruct Repl4I_immU8(vecX dst, immU8 src) %{
 9634   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd() &&
 9635             Matcher::vector_element_basic_type(n) == T_INT);
 9636   match(Set dst (Replicate src));
 9637   size(4);
 9638 
 9639   format %{ "VMOV.I32  $dst.Q,$src" %}
 9640   ins_encode %{
 9641     bool quad = true;
 9642     __ vmovI($dst$$FloatRegister, $src$$constant,
 9643              MacroAssembler::VELEM_SIZE_32, quad);
 9644   %}
 9645   ins_pipe(loadConFD); // FIXME
 9646 %}
 9647 
 9648 // Replicate scalar to packed byte values in Double register pair
 9649 instruct Repl2L_reg(vecX dst, iRegL src) %{
 9650   predicate(n->as_Vector()->length() == 2 &&
 9651             Matcher::vector_element_basic_type(n) == T_LONG);
 9652   match(Set dst (Replicate src));
 9653   size(8);
 9654   ins_cost(DEFAULT_COST*2); // FIXME
 9655 
 9656   format %{ "FMDRR $dst.D,$src.lo,$src.hi\t\n"
 9657             "FMDRR $dst.D.next,$src.lo,$src.hi" %}
 9658   ins_encode %{
 9659     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
 9660     __ fmdrr($dst$$FloatRegister->successor()->successor(),
 9661              $src$$Register, $src$$Register->successor());
 9662   %}
 9663   ins_pipe(ialu_reg); // FIXME
 9664 %}
 9665 
 9666 
 9667 // Replicate scalar to packed float values in Double register
 9668 instruct Repl2F_regI(vecD dst, iRegI src) %{
 9669   predicate(n->as_Vector()->length() == 2 &&
 9670             Matcher::vector_element_basic_type(n) == T_FLOAT);
 9671   match(Set dst (Replicate src));
 9672   size(4);
 9673 
 9674   format %{ "FMDRR    $dst.D,$src,$src\t" %}
 9675   ins_encode %{
 9676     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
 9677   %}
 9678   ins_pipe(ialu_reg); // FIXME
 9679 %}
 9680 
 9681 // Replicate scalar to packed float values in Double register
 9682 instruct Repl2F_reg_vfp(vecD dst, regF src) %{
 9683   predicate(n->as_Vector()->length() == 2 &&
 9684             Matcher::vector_element_basic_type(n) == T_FLOAT);
 9685   match(Set dst (Replicate src));
 9686   size(4*2);
 9687   ins_cost(DEFAULT_COST*2); // FIXME
 9688 
 9689   expand %{
 9690     iRegI tmp;
 9691     MoveF2I_reg_reg(tmp, src);
 9692     Repl2F_regI(dst,tmp);
 9693   %}
 9694 %}
 9695 
 9696 // Replicate scalar to packed float values in Double register
 9697 instruct Repl2F_reg_simd(vecD dst, regF src) %{
 9698   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd() &&
 9699             Matcher::vector_element_basic_type(n) == T_FLOAT);
 9700   match(Set dst (Replicate src));
 9701   size(4);
 9702   ins_cost(DEFAULT_COST); // FIXME
 9703 
 9704   format %{ "VDUP.32  $dst.D,$src.D\t" %}
 9705   ins_encode %{
 9706     bool quad = false;
 9707     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
 9708   %}
 9709   ins_pipe(ialu_reg); // FIXME
 9710 %}
 9711 
 9712 // Replicate scalar to packed float values in Double register pair
 9713 instruct Repl4F_reg(vecX dst, regF src, iRegI tmp) %{
 9714   predicate(n->as_Vector()->length() == 4 &&
 9715             Matcher::vector_element_basic_type(n) == T_FLOAT);
 9716   match(Set dst (Replicate src));
 9717   effect(TEMP tmp);
 9718   size(4*3);
 9719   ins_cost(DEFAULT_COST*3); // FIXME
 9720 
 9721   format %{ "FMRS     $tmp,$src\n\t"
 9722             "FMDRR    $dst.D,$tmp,$tmp\n\t"
 9723             "FMDRR    $dst.D.next,$tmp,$tmp\t" %}
 9724   ins_encode %{
 9725     __ fmrs($tmp$$Register, $src$$FloatRegister);
 9726     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 9727     __ fmdrr($dst$$FloatRegister->successor()->successor(),
 9728              $tmp$$Register, $tmp$$Register);
 9729   %}
 9730   ins_pipe(ialu_reg); // FIXME
 9731 %}
 9732 
 9733 // Replicate scalar to packed float values in Double register pair
 9734 instruct Repl4F_reg_simd(vecX dst, regF src) %{
 9735   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd() &&
 9736             Matcher::vector_element_basic_type(n) == T_FLOAT);
 9737   match(Set dst (Replicate src));
 9738   size(4);
 9739   ins_cost(DEFAULT_COST); // FIXME
 9740 
 9741   format %{ "VDUP.32  $dst.Q,$src.D\t" %}
 9742   ins_encode %{
 9743     bool quad = true;
 9744     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
 9745   %}
 9746   ins_pipe(ialu_reg); // FIXME
 9747 %}
 9748 
 9749 // Replicate scalar zero constant to packed float values in Double register
 9750 instruct Repl2F_immI(vecD dst, immF src, iRegI tmp) %{
 9751   predicate(n->as_Vector()->length() == 2 &&
 9752             Matcher::vector_element_basic_type(n) == T_FLOAT);
 9753   match(Set dst (Replicate src));
 9754   effect(TEMP tmp);
 9755   size(12);
 9756   ins_cost(DEFAULT_COST*4); // FIXME
 9757 
 9758   format %{ "MOV      $tmp, Repl1($src))\n\t"
 9759             "FMDRR    $dst,$tmp,$tmp\t" %}
 9760   ins_encode( LdReplImmF(src, dst, tmp) );
 9761   ins_pipe(loadConFD); // FIXME
 9762 %}
 9763 
 9764 // Replicate scalar to packed double float values in Double register pair
 9765 instruct Repl2D_reg(vecX dst, regD src) %{
 9766   predicate(n->as_Vector()->length() == 2 &&
 9767             Matcher::vector_element_basic_type(n) == T_DOUBLE);
 9768   match(Set dst (Replicate src));
 9769   size(4*2);
 9770   ins_cost(DEFAULT_COST*2); // FIXME
 9771 
 9772   format %{ "FCPYD    $dst.D.a,$src\n\t"
 9773             "FCPYD    $dst.D.b,$src\t" %}
 9774   ins_encode %{
 9775     FloatRegister dsta = $dst$$FloatRegister;
 9776     FloatRegister src = $src$$FloatRegister;
 9777     __ fcpyd(dsta, src);
 9778     FloatRegister dstb = dsta->successor()->successor();
 9779     __ fcpyd(dstb, src);
 9780   %}
 9781   ins_pipe(ialu_reg); // FIXME
 9782 %}
 9783 
 9784 // ====================VECTOR ARITHMETIC=======================================
 9785 
 9786 // --------------------------------- ADD --------------------------------------
 9787 
 9788 // Bytes vector add
 9789 instruct vadd8B_reg(vecD dst, vecD src1, vecD src2) %{
 9790   predicate(n->as_Vector()->length() == 8);
 9791   match(Set dst (AddVB src1 src2));
 9792   format %{ "VADD.I8 $dst,$src1,$src2\t! add packed8B" %}
 9793   size(4);
 9794   ins_encode %{
 9795     bool quad = false;
 9796     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9797              MacroAssembler::VELEM_SIZE_8, quad);
 9798   %}
 9799   ins_pipe( ialu_reg_reg ); // FIXME
 9800 %}
 9801 
 9802 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
 9803   predicate(n->as_Vector()->length() == 16);
 9804   match(Set dst (AddVB src1 src2));
 9805   size(4);
 9806   format %{ "VADD.I8 $dst.Q,$src1.Q,$src2.Q\t! add packed16B" %}
 9807   ins_encode %{
 9808     bool quad = true;
 9809     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9810              MacroAssembler::VELEM_SIZE_8, quad);
 9811   %}
 9812   ins_pipe( ialu_reg_reg ); // FIXME
 9813 %}
 9814 
 9815 // Shorts/Chars vector add
 9816 instruct vadd4S_reg(vecD dst, vecD src1, vecD src2) %{
 9817   predicate(n->as_Vector()->length() == 4);
 9818   match(Set dst (AddVS src1 src2));
 9819   size(4);
 9820   format %{ "VADD.I16 $dst,$src1,$src2\t! add packed4S" %}
 9821   ins_encode %{
 9822     bool quad = false;
 9823     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9824              MacroAssembler::VELEM_SIZE_16, quad);
 9825   %}
 9826   ins_pipe( ialu_reg_reg ); // FIXME
 9827 %}
 9828 
 9829 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
 9830   predicate(n->as_Vector()->length() == 8);
 9831   match(Set dst (AddVS src1 src2));
 9832   size(4);
 9833   format %{ "VADD.I16 $dst.Q,$src1.Q,$src2.Q\t! add packed8S" %}
 9834   ins_encode %{
 9835     bool quad = true;
 9836     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9837              MacroAssembler::VELEM_SIZE_16, quad);
 9838   %}
 9839   ins_pipe( ialu_reg_reg ); // FIXME
 9840 %}
 9841 
 9842 // Integers vector add
 9843 instruct vadd2I_reg(vecD dst, vecD src1, vecD src2) %{
 9844   predicate(n->as_Vector()->length() == 2);
 9845   match(Set dst (AddVI src1 src2));
 9846   size(4);
 9847   format %{ "VADD.I32 $dst.D,$src1.D,$src2.D\t! add packed2I" %}
 9848   ins_encode %{
 9849     bool quad = false;
 9850     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9851              MacroAssembler::VELEM_SIZE_32, quad);
 9852   %}
 9853   ins_pipe( ialu_reg_reg ); // FIXME
 9854 %}
 9855 
 9856 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
 9857   predicate(n->as_Vector()->length() == 4);
 9858   match(Set dst (AddVI src1 src2));
 9859   size(4);
 9860   format %{ "VADD.I32 $dst.Q,$src1.Q,$src2.Q\t! add packed4I" %}
 9861   ins_encode %{
 9862     bool quad = true;
 9863     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9864              MacroAssembler::VELEM_SIZE_32, quad);
 9865   %}
 9866   ins_pipe( ialu_reg_reg ); // FIXME
 9867 %}
 9868 
 9869 // Longs vector add
 9870 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
 9871   predicate(n->as_Vector()->length() == 2);
 9872   match(Set dst (AddVL src1 src2));
 9873   size(4);
 9874   format %{ "VADD.I64 $dst.Q,$src1.Q,$src2.Q\t! add packed2L" %}
 9875   ins_encode %{
 9876     bool quad = true;
 9877     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9878              MacroAssembler::VELEM_SIZE_64, quad);
 9879   %}
 9880   ins_pipe( ialu_reg_reg ); // FIXME
 9881 %}
 9882 
 9883 // Floats vector add
 9884 instruct vadd2F_reg(vecD dst, vecD src1, vecD src2) %{
 9885   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
 9886   match(Set dst (AddVF src1 src2));
 9887   size(4);
 9888   format %{ "VADD.F32 $dst,$src1,$src2\t! add packed2F" %}
 9889   ins_encode %{
 9890     bool quad = false;
 9891     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9892              MacroAssembler::VFA_SIZE_F32, quad);
 9893   %}
 9894   ins_pipe( faddD_reg_reg ); // FIXME
 9895 %}
 9896 
 9897 instruct vadd2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
 9898   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
 9899   match(Set dst (AddVF src1 src2));
 9900   ins_cost(DEFAULT_COST*2); // FIXME
 9901 
 9902   size(4*2);
 9903   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
 9904             "FADDS  $dst.b,$src1.b,$src2.b" %}
 9905   ins_encode %{
 9906     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 9907     __ add_float($dst$$FloatRegister->successor(),
 9908              $src1$$FloatRegister->successor(),
 9909              $src2$$FloatRegister->successor());
 9910   %}
 9911 
 9912   ins_pipe(faddF_reg_reg); // FIXME
 9913 %}
 9914 
 9915 instruct vadd4F_reg_simd(vecX dst, vecX src1, vecX src2) %{
 9916   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
 9917   match(Set dst (AddVF src1 src2));
 9918   size(4);
 9919   format %{ "VADD.F32 $dst.Q,$src1.Q,$src2.Q\t! add packed4F" %}
 9920   ins_encode %{
 9921     bool quad = true;
 9922     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9923              MacroAssembler::VFA_SIZE_F32, quad);
 9924   %}
 9925   ins_pipe( faddD_reg_reg ); // FIXME
 9926 %}
 9927 
 9928 instruct vadd4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
 9929   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
 9930   match(Set dst (AddVF src1 src2));
 9931   size(4*4);
 9932   ins_cost(DEFAULT_COST*4); // FIXME
 9933 
 9934   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
 9935             "FADDS  $dst.b,$src1.b,$src2.b\n\t"
 9936             "FADDS  $dst.c,$src1.c,$src2.c\n\t"
 9937             "FADDS  $dst.d,$src1.d,$src2.d" %}
 9938 
 9939   ins_encode %{
 9940     FloatRegister dsta = $dst$$FloatRegister;
 9941     FloatRegister src1a = $src1$$FloatRegister;
 9942     FloatRegister src2a = $src2$$FloatRegister;
 9943     __ add_float(dsta, src1a, src2a);
 9944     FloatRegister dstb = dsta->successor();
 9945     FloatRegister src1b = src1a->successor();
 9946     FloatRegister src2b = src2a->successor();
 9947     __ add_float(dstb, src1b, src2b);
 9948     FloatRegister dstc = dstb->successor();
 9949     FloatRegister src1c = src1b->successor();
 9950     FloatRegister src2c = src2b->successor();
 9951     __ add_float(dstc, src1c, src2c);
 9952     FloatRegister dstd = dstc->successor();
 9953     FloatRegister src1d = src1c->successor();
 9954     FloatRegister src2d = src2c->successor();
 9955     __ add_float(dstd, src1d, src2d);
 9956   %}
 9957 
 9958   ins_pipe(faddF_reg_reg); // FIXME
 9959 %}
 9960 
 9961 instruct vadd2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
 9962   predicate(n->as_Vector()->length() == 2);
 9963   match(Set dst (AddVD src1 src2));
 9964   size(4*2);
 9965   ins_cost(DEFAULT_COST*2); // FIXME
 9966 
 9967   format %{ "FADDD  $dst.a,$src1.a,$src2.a\n\t"
 9968             "FADDD  $dst.b,$src1.b,$src2.b" %}
 9969 
 9970   ins_encode %{
 9971     FloatRegister dsta = $dst$$FloatRegister;
 9972     FloatRegister src1a = $src1$$FloatRegister;
 9973     FloatRegister src2a = $src2$$FloatRegister;
 9974     __ add_double(dsta, src1a, src2a);
 9975     FloatRegister dstb = dsta->successor()->successor();
 9976     FloatRegister src1b = src1a->successor()->successor();
 9977     FloatRegister src2b = src2a->successor()->successor();
 9978     __ add_double(dstb, src1b, src2b);
 9979   %}
 9980 
 9981   ins_pipe(faddF_reg_reg); // FIXME
 9982 %}
 9983 
 9984 
 9985 // Bytes vector sub
 9986 instruct vsub8B_reg(vecD dst, vecD src1, vecD src2) %{
 9987   predicate(n->as_Vector()->length() == 8);
 9988   match(Set dst (SubVB src1 src2));
 9989   size(4);
 9990   format %{ "VSUB.I8 $dst,$src1,$src2\t! sub packed8B" %}
 9991   ins_encode %{
 9992     bool quad = false;
 9993     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9994              MacroAssembler::VELEM_SIZE_8, quad);
 9995   %}
 9996   ins_pipe( ialu_reg_reg ); // FIXME
 9997 %}
 9998 
 9999 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
10000   predicate(n->as_Vector()->length() == 16);
10001   match(Set dst (SubVB src1 src2));
10002   size(4);
10003   format %{ "VSUB.I8 $dst.Q,$src1.Q,$src2.Q\t! sub packed16B" %}
10004   ins_encode %{
10005     bool quad = true;
10006     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10007              MacroAssembler::VELEM_SIZE_8, quad);
10008   %}
10009   ins_pipe( ialu_reg_reg ); // FIXME
10010 %}
10011 
10012 // Shorts/Chars vector sub
10013 instruct vsub4S_reg(vecD dst, vecD src1, vecD src2) %{
10014   predicate(n->as_Vector()->length() == 4);
10015   match(Set dst (SubVS src1 src2));
10016   size(4);
10017   format %{ "VSUB.I16 $dst,$src1,$src2\t! sub packed4S" %}
10018   ins_encode %{
10019     bool quad = false;
10020     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10021              MacroAssembler::VELEM_SIZE_16, quad);
10022   %}
10023   ins_pipe( ialu_reg_reg ); // FIXME
10024 %}
10025 
10026 instruct vsub16S_reg(vecX dst, vecX src1, vecX src2) %{
10027   predicate(n->as_Vector()->length() == 8);
10028   match(Set dst (SubVS src1 src2));
10029   size(4);
10030   format %{ "VSUB.I16 $dst.Q,$src1.Q,$src2.Q\t! sub packed8S" %}
10031   ins_encode %{
10032     bool quad = true;
10033     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10034              MacroAssembler::VELEM_SIZE_16, quad);
10035   %}
10036   ins_pipe( ialu_reg_reg ); // FIXME
10037 %}
10038 
10039 // Integers vector sub
10040 instruct vsub2I_reg(vecD dst, vecD src1, vecD src2) %{
10041   predicate(n->as_Vector()->length() == 2);
10042   match(Set dst (SubVI src1 src2));
10043   size(4);
10044   format %{ "VSUB.I32 $dst,$src1,$src2\t! sub packed2I" %}
10045   ins_encode %{
10046     bool quad = false;
10047     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10048              MacroAssembler::VELEM_SIZE_32, quad);
10049   %}
10050   ins_pipe( ialu_reg_reg ); // FIXME
10051 %}
10052 
10053 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
10054   predicate(n->as_Vector()->length() == 4);
10055   match(Set dst (SubVI src1 src2));
10056   size(4);
10057   format %{ "VSUB.I32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4I" %}
10058   ins_encode %{
10059     bool quad = true;
10060     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10061              MacroAssembler::VELEM_SIZE_32, quad);
10062   %}
10063   ins_pipe( ialu_reg_reg ); // FIXME
10064 %}
10065 
10066 // Longs vector sub
10067 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
10068   predicate(n->as_Vector()->length() == 2);
10069   match(Set dst (SubVL src1 src2));
10070   size(4);
10071   format %{ "VSUB.I64 $dst.Q,$src1.Q,$src2.Q\t! sub packed2L" %}
10072   ins_encode %{
10073     bool quad = true;
10074     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10075              MacroAssembler::VELEM_SIZE_64, quad);
10076   %}
10077   ins_pipe( ialu_reg_reg ); // FIXME
10078 %}
10079 
10080 // Floats vector sub
10081 instruct vsub2F_reg(vecD dst, vecD src1, vecD src2) %{
10082   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
10083   match(Set dst (SubVF src1 src2));
10084   size(4);
10085   format %{ "VSUB.F32 $dst,$src1,$src2\t! sub packed2F" %}
10086   ins_encode %{
10087     bool quad = false;
10088     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10089              MacroAssembler::VFA_SIZE_F32, quad);
10090   %}
10091   ins_pipe( faddF_reg_reg ); // FIXME
10092 %}
10093 
10094 instruct vsub2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10095   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
10096   match(Set dst (SubVF src1 src2));
10097   size(4*2);
10098   ins_cost(DEFAULT_COST*2); // FIXME
10099 
10100   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10101             "FSUBS  $dst.b,$src1.b,$src2.b" %}
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   %}
10113 
10114   ins_pipe(faddF_reg_reg); // FIXME
10115 %}
10116 
10117 
10118 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
10119   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
10120   match(Set dst (SubVF src1 src2));
10121   size(4);
10122   format %{ "VSUB.F32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4F" %}
10123   ins_encode %{
10124     bool quad = true;
10125     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10126              MacroAssembler::VFA_SIZE_F32, quad);
10127   %}
10128   ins_pipe( faddF_reg_reg ); // FIXME
10129 %}
10130 
10131 instruct vsub4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10132   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
10133   match(Set dst (SubVF src1 src2));
10134   size(4*4);
10135   ins_cost(DEFAULT_COST*4); // FIXME
10136 
10137   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10138             "FSUBS  $dst.b,$src1.b,$src2.b\n\t"
10139             "FSUBS  $dst.c,$src1.c,$src2.c\n\t"
10140             "FSUBS  $dst.d,$src1.d,$src2.d" %}
10141 
10142   ins_encode %{
10143     FloatRegister dsta = $dst$$FloatRegister;
10144     FloatRegister src1a = $src1$$FloatRegister;
10145     FloatRegister src2a = $src2$$FloatRegister;
10146     __ sub_float(dsta, src1a, src2a);
10147     FloatRegister dstb = dsta->successor();
10148     FloatRegister src1b = src1a->successor();
10149     FloatRegister src2b = src2a->successor();
10150     __ sub_float(dstb, src1b, src2b);
10151     FloatRegister dstc = dstb->successor();
10152     FloatRegister src1c = src1b->successor();
10153     FloatRegister src2c = src2b->successor();
10154     __ sub_float(dstc, src1c, src2c);
10155     FloatRegister dstd = dstc->successor();
10156     FloatRegister src1d = src1c->successor();
10157     FloatRegister src2d = src2c->successor();
10158     __ sub_float(dstd, src1d, src2d);
10159   %}
10160 
10161   ins_pipe(faddF_reg_reg); // FIXME
10162 %}
10163 
10164 instruct vsub2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10165   predicate(n->as_Vector()->length() == 2);
10166   match(Set dst (SubVD src1 src2));
10167   size(4*2);
10168   ins_cost(DEFAULT_COST*2); // FIXME
10169 
10170   format %{ "FSUBD  $dst.a,$src1.a,$src2.a\n\t"
10171             "FSUBD  $dst.b,$src1.b,$src2.b" %}
10172 
10173   ins_encode %{
10174     FloatRegister dsta = $dst$$FloatRegister;
10175     FloatRegister src1a = $src1$$FloatRegister;
10176     FloatRegister src2a = $src2$$FloatRegister;
10177     __ sub_double(dsta, src1a, src2a);
10178     FloatRegister dstb = dsta->successor()->successor();
10179     FloatRegister src1b = src1a->successor()->successor();
10180     FloatRegister src2b = src2a->successor()->successor();
10181     __ sub_double(dstb, src1b, src2b);
10182   %}
10183 
10184   ins_pipe(faddF_reg_reg); // FIXME
10185 %}
10186 
10187 // Shorts/Chars vector mul
10188 instruct vmul4S_reg(vecD dst, vecD src1, vecD src2) %{
10189   predicate(n->as_Vector()->length() == 4);
10190   match(Set dst (MulVS src1 src2));
10191   size(4);
10192   format %{ "VMUL.I16 $dst,$src1,$src2\t! mul packed4S" %}
10193   ins_encode %{
10194     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10195              MacroAssembler::VELEM_SIZE_16, 0);
10196   %}
10197   ins_pipe( ialu_reg_reg ); // FIXME
10198 %}
10199 
10200 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2) %{
10201   predicate(n->as_Vector()->length() == 8);
10202   match(Set dst (MulVS src1 src2));
10203   size(4);
10204   format %{ "VMUL.I16 $dst.Q,$src1.Q,$src2.Q\t! mul packed8S" %}
10205   ins_encode %{
10206     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10207              MacroAssembler::VELEM_SIZE_16, 1);
10208   %}
10209   ins_pipe( ialu_reg_reg ); // FIXME
10210 %}
10211 
10212 // Integers vector mul
10213 instruct vmul2I_reg(vecD dst, vecD src1, vecD src2) %{
10214   predicate(n->as_Vector()->length() == 2);
10215   match(Set dst (MulVI src1 src2));
10216   size(4);
10217   format %{ "VMUL.I32 $dst,$src1,$src2\t! mul packed2I" %}
10218   ins_encode %{
10219     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10220              MacroAssembler::VELEM_SIZE_32, 0);
10221   %}
10222   ins_pipe( ialu_reg_reg ); // FIXME
10223 %}
10224 
10225 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
10226   predicate(n->as_Vector()->length() == 4);
10227   match(Set dst (MulVI src1 src2));
10228   size(4);
10229   format %{ "VMUL.I32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4I" %}
10230   ins_encode %{
10231     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10232              MacroAssembler::VELEM_SIZE_32, 1);
10233   %}
10234   ins_pipe( ialu_reg_reg ); // FIXME
10235 %}
10236 
10237 // Floats vector mul
10238 instruct vmul2F_reg(vecD dst, vecD src1, vecD src2) %{
10239   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
10240   match(Set dst (MulVF src1 src2));
10241   size(4);
10242   format %{ "VMUL.F32 $dst,$src1,$src2\t! mul packed2F" %}
10243   ins_encode %{
10244     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10245              MacroAssembler::VFA_SIZE_F32, 0);
10246   %}
10247   ins_pipe( fmulF_reg_reg ); // FIXME
10248 %}
10249 
10250 instruct vmul2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10251   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
10252   match(Set dst (MulVF src1 src2));
10253   size(4*2);
10254   ins_cost(DEFAULT_COST*2); // FIXME
10255 
10256   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10257             "FMULS  $dst.b,$src1.b,$src2.b" %}
10258   ins_encode %{
10259     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10260     __ mul_float($dst$$FloatRegister->successor(),
10261              $src1$$FloatRegister->successor(),
10262              $src2$$FloatRegister->successor());
10263   %}
10264 
10265   ins_pipe(fmulF_reg_reg); // FIXME
10266 %}
10267 
10268 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
10269   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
10270   match(Set dst (MulVF src1 src2));
10271   size(4);
10272   format %{ "VMUL.F32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4F" %}
10273   ins_encode %{
10274     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10275              MacroAssembler::VFA_SIZE_F32, 1);
10276   %}
10277   ins_pipe( fmulF_reg_reg ); // FIXME
10278 %}
10279 
10280 instruct vmul4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10281   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
10282   match(Set dst (MulVF src1 src2));
10283   size(4*4);
10284   ins_cost(DEFAULT_COST*4); // FIXME
10285 
10286   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10287             "FMULS  $dst.b,$src1.b,$src2.b\n\t"
10288             "FMULS  $dst.c,$src1.c,$src2.c\n\t"
10289             "FMULS  $dst.d,$src1.d,$src2.d" %}
10290 
10291   ins_encode %{
10292     FloatRegister dsta = $dst$$FloatRegister;
10293     FloatRegister src1a = $src1$$FloatRegister;
10294     FloatRegister src2a = $src2$$FloatRegister;
10295     __ mul_float(dsta, src1a, src2a);
10296     FloatRegister dstb = dsta->successor();
10297     FloatRegister src1b = src1a->successor();
10298     FloatRegister src2b = src2a->successor();
10299     __ mul_float(dstb, src1b, src2b);
10300     FloatRegister dstc = dstb->successor();
10301     FloatRegister src1c = src1b->successor();
10302     FloatRegister src2c = src2b->successor();
10303     __ mul_float(dstc, src1c, src2c);
10304     FloatRegister dstd = dstc->successor();
10305     FloatRegister src1d = src1c->successor();
10306     FloatRegister src2d = src2c->successor();
10307     __ mul_float(dstd, src1d, src2d);
10308   %}
10309 
10310   ins_pipe(fmulF_reg_reg); // FIXME
10311 %}
10312 
10313 instruct vmul2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10314   predicate(n->as_Vector()->length() == 2);
10315   match(Set dst (MulVD src1 src2));
10316   size(4*2);
10317   ins_cost(DEFAULT_COST*2); // FIXME
10318 
10319   format %{ "FMULD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10320             "FMULD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10321   ins_encode %{
10322     FloatRegister dsta = $dst$$FloatRegister;
10323     FloatRegister src1a = $src1$$FloatRegister;
10324     FloatRegister src2a = $src2$$FloatRegister;
10325     __ mul_double(dsta, src1a, src2a);
10326     FloatRegister dstb = dsta->successor()->successor();
10327     FloatRegister src1b = src1a->successor()->successor();
10328     FloatRegister src2b = src2a->successor()->successor();
10329     __ mul_double(dstb, src1b, src2b);
10330   %}
10331 
10332   ins_pipe(fmulD_reg_reg); // FIXME
10333 %}
10334 
10335 
10336 // Floats vector div
10337 instruct vdiv2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10338   predicate(n->as_Vector()->length() == 2);
10339   match(Set dst (DivVF src1 src2));
10340   size(4*2);
10341   ins_cost(DEFAULT_COST*2); // FIXME
10342 
10343   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10344             "FDIVS  $dst.b,$src1.b,$src2.b" %}
10345   ins_encode %{
10346     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10347     __ div_float($dst$$FloatRegister->successor(),
10348              $src1$$FloatRegister->successor(),
10349              $src2$$FloatRegister->successor());
10350   %}
10351 
10352   ins_pipe(fdivF_reg_reg); // FIXME
10353 %}
10354 
10355 instruct vdiv4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10356   predicate(n->as_Vector()->length() == 4);
10357   match(Set dst (DivVF src1 src2));
10358   size(4*4);
10359   ins_cost(DEFAULT_COST*4); // FIXME
10360 
10361   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10362             "FDIVS  $dst.b,$src1.b,$src2.b\n\t"
10363             "FDIVS  $dst.c,$src1.c,$src2.c\n\t"
10364             "FDIVS  $dst.d,$src1.d,$src2.d" %}
10365 
10366   ins_encode %{
10367     FloatRegister dsta = $dst$$FloatRegister;
10368     FloatRegister src1a = $src1$$FloatRegister;
10369     FloatRegister src2a = $src2$$FloatRegister;
10370     __ div_float(dsta, src1a, src2a);
10371     FloatRegister dstb = dsta->successor();
10372     FloatRegister src1b = src1a->successor();
10373     FloatRegister src2b = src2a->successor();
10374     __ div_float(dstb, src1b, src2b);
10375     FloatRegister dstc = dstb->successor();
10376     FloatRegister src1c = src1b->successor();
10377     FloatRegister src2c = src2b->successor();
10378     __ div_float(dstc, src1c, src2c);
10379     FloatRegister dstd = dstc->successor();
10380     FloatRegister src1d = src1c->successor();
10381     FloatRegister src2d = src2c->successor();
10382     __ div_float(dstd, src1d, src2d);
10383   %}
10384 
10385   ins_pipe(fdivF_reg_reg); // FIXME
10386 %}
10387 
10388 instruct vdiv2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10389   predicate(n->as_Vector()->length() == 2);
10390   match(Set dst (DivVD src1 src2));
10391   size(4*2);
10392   ins_cost(DEFAULT_COST*2); // FIXME
10393 
10394   format %{ "FDIVD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10395             "FDIVD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10396   ins_encode %{
10397     FloatRegister dsta = $dst$$FloatRegister;
10398     FloatRegister src1a = $src1$$FloatRegister;
10399     FloatRegister src2a = $src2$$FloatRegister;
10400     __ div_double(dsta, src1a, src2a);
10401     FloatRegister dstb = dsta->successor()->successor();
10402     FloatRegister src1b = src1a->successor()->successor();
10403     FloatRegister src2b = src2a->successor()->successor();
10404     __ div_double(dstb, src1b, src2b);
10405   %}
10406 
10407   ins_pipe(fdivD_reg_reg); // FIXME
10408 %}
10409 
10410 // --------------------------------- NEG --------------------------------------
10411 
10412 instruct vneg8B_reg(vecD dst, vecD src) %{
10413   predicate(n->as_Vector()->length_in_bytes() == 8);
10414   effect(DEF dst, USE src);
10415   size(4);
10416   ins_cost(DEFAULT_COST); // FIXME
10417   format %{ "VNEG.S8 $dst.D,$src.D\t! neg packed8B" %}
10418   ins_encode %{
10419     bool quad = false;
10420     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
10421               MacroAssembler::VELEM_SIZE_8, quad);
10422   %}
10423   ins_pipe( ialu_reg_reg ); // FIXME
10424 %}
10425 
10426 instruct vneg16B_reg(vecX dst, vecX src) %{
10427   predicate(n->as_Vector()->length_in_bytes() == 16);
10428   effect(DEF dst, USE src);
10429   size(4);
10430   ins_cost(DEFAULT_COST); // FIXME
10431   format %{ "VNEG.S8 $dst.Q,$src.Q\t! neg0 packed16B" %}
10432   ins_encode %{
10433     bool _float = false;
10434     bool quad = true;
10435     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
10436               MacroAssembler::VELEM_SIZE_8, quad);
10437   %}
10438   ins_pipe( ialu_reg_reg ); // FIXME
10439 %}
10440 
10441 // ------------------------------ ShiftCount ----------------------------------
10442 
10443 instruct vslcntD(vecD dst, iRegI cnt) %{
10444   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
10445   match(Set dst (LShiftCntV cnt));
10446   size(4);
10447   ins_cost(DEFAULT_COST); // FIXME
10448   expand %{
10449     Repl8B_reg_simd(dst, cnt);
10450   %}
10451 %}
10452 
10453 instruct vslcntX(vecX dst, iRegI cnt) %{
10454   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
10455   match(Set dst (LShiftCntV cnt));
10456   size(4);
10457   ins_cost(DEFAULT_COST); // FIXME
10458   expand %{
10459     Repl16B_reg(dst, cnt);
10460   %}
10461 %}
10462 
10463 // Low bits of vector "shift" elements are used, so it
10464 // doesn't matter if we treat it as ints or bytes here.
10465 instruct vsrcntD(vecD dst, iRegI cnt) %{
10466   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
10467   match(Set dst (RShiftCntV cnt));
10468   size(4*2);
10469   ins_cost(DEFAULT_COST*2); // FIXME
10470 
10471   format %{ "VDUP.8 $dst.D,$cnt\n\t"
10472             "VNEG.S8 $dst.D,$dst.D\t! neg packed8B" %}
10473   ins_encode %{
10474     bool quad = false;
10475     __ vdupI($dst$$FloatRegister, $cnt$$Register,
10476              MacroAssembler::VELEM_SIZE_8, quad);
10477     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
10478               MacroAssembler::VELEM_SIZE_8, quad);
10479   %}
10480   ins_pipe( ialu_reg_reg ); // FIXME
10481 %}
10482 
10483 instruct vsrcntX(vecX dst, iRegI cnt) %{
10484   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
10485   match(Set dst (RShiftCntV cnt));
10486   size(4*2);
10487   ins_cost(DEFAULT_COST*2); // FIXME
10488   format %{ "VDUP.8 $dst.Q,$cnt\n\t"
10489             "VNEG.S8 $dst.Q,$dst.Q\t! neg packed16B" %}
10490   ins_encode %{
10491     bool quad = true;
10492     __ vdupI($dst$$FloatRegister, $cnt$$Register,
10493              MacroAssembler::VELEM_SIZE_8, quad);
10494     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
10495               MacroAssembler::VELEM_SIZE_8, quad);
10496   %}
10497   ins_pipe( ialu_reg_reg ); // FIXME
10498 %}
10499 
10500 // ------------------------------ LogicalShift --------------------------------
10501 
10502 // Byte vector logical left/right shift based on sign
10503 instruct vsh8B_reg(vecD dst, vecD src, vecD shift) %{
10504   predicate(n->as_Vector()->length() == 8);
10505   effect(DEF dst, USE src, USE shift);
10506   size(4);
10507   ins_cost(DEFAULT_COST); // FIXME
10508   format %{
10509     "VSHL.U8 $dst.D,$src.D,$shift.D\t! logical left/right shift packed8B"
10510   %}
10511   ins_encode %{
10512     bool quad = false;
10513     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10514               MacroAssembler::VELEM_SIZE_8, quad);
10515   %}
10516   ins_pipe( ialu_reg_reg ); // FIXME
10517 %}
10518 
10519 instruct vsh16B_reg(vecX dst, vecX src, vecX shift) %{
10520   predicate(n->as_Vector()->length() == 16);
10521   effect(DEF dst, USE src, USE shift);
10522   size(4);
10523   ins_cost(DEFAULT_COST); // FIXME
10524   format %{
10525     "VSHL.U8 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed16B"
10526   %}
10527   ins_encode %{
10528     bool quad = true;
10529     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10530               MacroAssembler::VELEM_SIZE_8, quad);
10531   %}
10532   ins_pipe( ialu_reg_reg ); // FIXME
10533 %}
10534 
10535 // Shorts/Char vector logical left/right shift based on sign
10536 instruct vsh4S_reg(vecD dst, vecD src, vecD shift) %{
10537   predicate(n->as_Vector()->length() == 4);
10538   effect(DEF dst, USE src, USE shift);
10539   size(4);
10540   ins_cost(DEFAULT_COST); // FIXME
10541   format %{
10542     "VSHL.U16 $dst.D,$src.D,$shift.D\t! logical left/right shift packed4S"
10543   %}
10544   ins_encode %{
10545     bool quad = false;
10546     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10547               MacroAssembler::VELEM_SIZE_16, quad);
10548   %}
10549   ins_pipe( ialu_reg_reg ); // FIXME
10550 %}
10551 
10552 instruct vsh8S_reg(vecX dst, vecX src, vecX shift) %{
10553   predicate(n->as_Vector()->length() == 8);
10554   effect(DEF dst, USE src, USE shift);
10555   size(4);
10556   ins_cost(DEFAULT_COST); // FIXME
10557   format %{
10558     "VSHL.U16 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed8S"
10559   %}
10560   ins_encode %{
10561     bool quad = true;
10562     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10563               MacroAssembler::VELEM_SIZE_16, quad);
10564   %}
10565   ins_pipe( ialu_reg_reg ); // FIXME
10566 %}
10567 
10568 // Integers vector logical left/right shift based on sign
10569 instruct vsh2I_reg(vecD dst, vecD src, vecD shift) %{
10570   predicate(n->as_Vector()->length() == 2);
10571   effect(DEF dst, USE src, USE shift);
10572   size(4);
10573   ins_cost(DEFAULT_COST); // FIXME
10574   format %{
10575     "VSHL.U32 $dst.D,$src.D,$shift.D\t! logical left/right shift packed2I"
10576   %}
10577   ins_encode %{
10578     bool quad = false;
10579     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10580               MacroAssembler::VELEM_SIZE_32, quad);
10581   %}
10582   ins_pipe( ialu_reg_reg ); // FIXME
10583 %}
10584 
10585 instruct vsh4I_reg(vecX dst, vecX src, vecX shift) %{
10586   predicate(n->as_Vector()->length() == 4);
10587   effect(DEF dst, USE src, USE shift);
10588   size(4);
10589   ins_cost(DEFAULT_COST); // FIXME
10590   format %{
10591     "VSHL.U32 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed4I"
10592   %}
10593   ins_encode %{
10594     bool quad = true;
10595     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10596               MacroAssembler::VELEM_SIZE_32, quad);
10597   %}
10598   ins_pipe( ialu_reg_reg ); // FIXME
10599 %}
10600 
10601 // Longs vector logical left/right shift based on sign
10602 instruct vsh2L_reg(vecX dst, vecX src, vecX shift) %{
10603   predicate(n->as_Vector()->length() == 2);
10604   effect(DEF dst, USE src, USE shift);
10605   size(4);
10606   ins_cost(DEFAULT_COST); // FIXME
10607   format %{
10608     "VSHL.U64 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed2L"
10609   %}
10610   ins_encode %{
10611     bool quad = true;
10612     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10613               MacroAssembler::VELEM_SIZE_64, quad);
10614   %}
10615   ins_pipe( ialu_reg_reg ); // FIXME
10616 %}
10617 
10618 // ------------------------------ LogicalLeftShift ----------------------------
10619 
10620 // Byte vector logical left shift
10621 instruct vsl8B_reg(vecD dst, vecD src, vecD shift) %{
10622   predicate(n->as_Vector()->length() == 8);
10623   match(Set dst (LShiftVB src shift));
10624   size(4*1);
10625   ins_cost(DEFAULT_COST*1); // FIXME
10626   expand %{
10627     vsh8B_reg(dst, src, shift);
10628   %}
10629 %}
10630 
10631 instruct vsl16B_reg(vecX dst, vecX src, vecX shift) %{
10632   predicate(n->as_Vector()->length() == 16);
10633   match(Set dst (LShiftVB src shift));
10634   size(4*1);
10635   ins_cost(DEFAULT_COST*1); // FIXME
10636   expand %{
10637     vsh16B_reg(dst, src, shift);
10638   %}
10639 %}
10640 
10641 instruct vsl8B_immI(vecD dst, vecD src, immI shift) %{
10642   predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n));
10643   match(Set dst (LShiftVB src (LShiftCntV shift)));
10644   size(4);
10645   ins_cost(DEFAULT_COST); // FIXME
10646   format %{
10647     "VSHL.I8 $dst.D,$src.D,$shift\t! logical left shift packed8B"
10648   %}
10649   ins_encode %{
10650     bool quad = false;
10651     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10652              quad);
10653   %}
10654   ins_pipe( ialu_reg_reg ); // FIXME
10655 %}
10656 
10657 instruct vsl16B_immI(vecX dst, vecX src, immI shift) %{
10658   predicate(n->as_Vector()->length() == 16 && assert_not_var_shift(n));
10659   match(Set dst (LShiftVB src (LShiftCntV shift)));
10660   size(4);
10661   ins_cost(DEFAULT_COST); // FIXME
10662   format %{
10663     "VSHL.I8 $dst.Q,$src.Q,$shift\t! logical left shift packed16B"
10664   %}
10665   ins_encode %{
10666     bool quad = true;
10667     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10668              quad);
10669   %}
10670   ins_pipe( ialu_reg_reg ); // FIXME
10671 %}
10672 
10673 // Shorts/Chars vector logical left shift
10674 instruct vsl4S_reg(vecD dst, vecD src, vecD shift) %{
10675   predicate(n->as_Vector()->length() == 4);
10676   match(Set dst (LShiftVS src shift));
10677   size(4*1);
10678   ins_cost(DEFAULT_COST*1); // FIXME
10679   expand %{
10680     vsh4S_reg(dst, src, shift);
10681   %}
10682 %}
10683 
10684 instruct vsl8S_reg(vecX dst, vecX src, vecX shift) %{
10685   predicate(n->as_Vector()->length() == 8);
10686   match(Set dst (LShiftVS src shift));
10687   size(4*1);
10688   ins_cost(DEFAULT_COST*1); // FIXME
10689   expand %{
10690     vsh8S_reg(dst, src, shift);
10691   %}
10692 %}
10693 
10694 instruct vsl4S_immI(vecD dst, vecD src, immI shift) %{
10695   predicate(n->as_Vector()->length() == 4 && assert_not_var_shift(n));
10696   match(Set dst (LShiftVS src (LShiftCntV shift)));
10697   size(4);
10698   ins_cost(DEFAULT_COST); // FIXME
10699   format %{
10700     "VSHL.I16 $dst.D,$src.D,$shift\t! logical left shift packed4S"
10701   %}
10702   ins_encode %{
10703     bool quad = false;
10704     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10705              quad);
10706   %}
10707   ins_pipe( ialu_reg_reg ); // FIXME
10708 %}
10709 
10710 instruct vsl8S_immI(vecX dst, vecX src, immI shift) %{
10711   predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n));
10712   match(Set dst (LShiftVS src shift));
10713   size(4);
10714   ins_cost(DEFAULT_COST); // FIXME
10715   format %{
10716     "VSHL.I16 $dst.Q,$src.Q,$shift\t! logical left shift packed8S"
10717   %}
10718   ins_encode %{
10719     bool quad = true;
10720     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10721              quad);
10722   %}
10723   ins_pipe( ialu_reg_reg ); // FIXME
10724 %}
10725 
10726 // Integers vector logical left shift
10727 instruct vsl2I_reg(vecD dst, vecD src, vecD shift) %{
10728   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10729   match(Set dst (LShiftVI src shift));
10730   size(4*1);
10731   ins_cost(DEFAULT_COST*1); // FIXME
10732   expand %{
10733     vsh2I_reg(dst, src, shift);
10734   %}
10735 %}
10736 
10737 instruct vsl4I_reg(vecX dst, vecX src, vecX shift) %{
10738   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10739   match(Set dst (LShiftVI src shift));
10740   size(4*1);
10741   ins_cost(DEFAULT_COST*1); // FIXME
10742   expand %{
10743     vsh4I_reg(dst, src, shift);
10744   %}
10745 %}
10746 
10747 instruct vsl2I_immI(vecD dst, vecD src, immI shift) %{
10748   predicate(n->as_Vector()->length() == 2 &&
10749             VM_Version::has_simd() &&
10750             assert_not_var_shift(n));
10751   match(Set dst (LShiftVI src (LShiftCntV shift)));
10752   size(4);
10753   ins_cost(DEFAULT_COST); // FIXME
10754   format %{
10755     "VSHL.I32 $dst.D,$src.D,$shift\t! logical left shift packed2I"
10756   %}
10757   ins_encode %{
10758     bool quad = false;
10759     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10760              quad);
10761   %}
10762   ins_pipe( ialu_reg_reg ); // FIXME
10763 %}
10764 
10765 instruct vsl4I_immI(vecX dst, vecX src, immI shift) %{
10766   predicate(n->as_Vector()->length() == 4 &&
10767             VM_Version::has_simd() &&
10768             assert_not_var_shift(n));
10769   match(Set dst (LShiftVI src (LShiftCntV shift)));
10770   size(4);
10771   ins_cost(DEFAULT_COST); // FIXME
10772   format %{
10773     "VSHL.I32 $dst.Q,$src.Q,$shift\t! logical left shift packed4I"
10774   %}
10775   ins_encode %{
10776     bool quad = true;
10777     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10778              quad);
10779   %}
10780   ins_pipe( ialu_reg_reg ); // FIXME
10781 %}
10782 
10783 // Longs vector logical left shift
10784 instruct vsl2L_reg(vecX dst, vecX src, vecX shift) %{
10785   predicate(n->as_Vector()->length() == 2);
10786   match(Set dst (LShiftVL src shift));
10787   size(4*1);
10788   ins_cost(DEFAULT_COST*1); // FIXME
10789   expand %{
10790     vsh2L_reg(dst, src, shift);
10791   %}
10792 %}
10793 
10794 instruct vsl2L_immI(vecX dst, vecX src, immI shift) %{
10795   predicate(n->as_Vector()->length() == 2 && assert_not_var_shift(n));
10796   match(Set dst (LShiftVL src (LShiftCntV shift)));
10797   size(4);
10798   ins_cost(DEFAULT_COST); // FIXME
10799   format %{
10800     "VSHL.I64 $dst.Q,$src.Q,$shift\t! logical left shift packed2L"
10801   %}
10802   ins_encode %{
10803     bool quad = true;
10804     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
10805              quad);
10806   %}
10807   ins_pipe( ialu_reg_reg ); // FIXME
10808 %}
10809 
10810 // ----------------------- LogicalRightShift -----------------------------------
10811 
10812 // Bytes/Shorts vector logical right shift produces incorrect Java result
10813 // for negative data because java code convert short value into int with
10814 // sign extension before a shift.
10815 
10816 // Right shift with vector shift count on aarch32 SIMD is implemented as left
10817 // shift by negative shift count value.
10818 //
10819 // Method is_var_shift() denotes that vector shift count is a variable shift:
10820 // 1) for this case, vector shift count should be negated before conducting
10821 //    right shifts. E.g., vsrl4S_reg_var rule.
10822 // 2) for the opposite case, vector shift count is generated via RShiftCntV
10823 //    rules and is already negated there. Hence, no negation is needed.
10824 //    E.g., vsrl4S_reg rule.
10825 
10826 // Chars vector logical right shift
10827 instruct vsrl4S_reg(vecD dst, vecD src, vecD shift) %{
10828   predicate(n->as_Vector()->length() == 4 && !n->as_ShiftV()->is_var_shift());
10829   match(Set dst (URShiftVS src shift));
10830   size(4);
10831   ins_cost(DEFAULT_COST);
10832   expand %{
10833     vsh4S_reg(dst, src, shift);
10834   %}
10835 %}
10836 
10837 instruct vsrl4S_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{
10838   predicate(n->as_Vector()->length() == 4 && n->as_ShiftV()->is_var_shift());
10839   match(Set dst (URShiftVS src shift));
10840   effect(TEMP tmp);
10841   size(4*2);
10842   ins_cost(DEFAULT_COST*2);
10843   format %{
10844     "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B"
10845     "VSHL.U16 $dst.D,$src.D,$tmp.D\t! logical right shift packed4S"
10846   %}
10847   ins_encode %{
10848     bool quad = false;
10849     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
10850              MacroAssembler::VELEM_SIZE_8, quad);
10851     __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
10852               MacroAssembler::VELEM_SIZE_16, quad);
10853   %}
10854   ins_pipe(ialu_reg_reg);
10855 %}
10856 
10857 instruct vsrl8S_reg(vecX dst, vecX src, vecX shift) %{
10858   predicate(n->as_Vector()->length() == 8 && !n->as_ShiftV()->is_var_shift());
10859   match(Set dst (URShiftVS src shift));
10860   size(4);
10861   ins_cost(DEFAULT_COST);
10862   expand %{
10863     vsh8S_reg(dst, src, shift);
10864   %}
10865 %}
10866 
10867 instruct vsrl8S_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
10868   predicate(n->as_Vector()->length() == 8 && n->as_ShiftV()->is_var_shift());
10869   match(Set dst (URShiftVS src shift));
10870   effect(TEMP tmp);
10871   size(4*2);
10872   ins_cost(DEFAULT_COST*2);
10873   format %{
10874     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
10875     "VSHL.U16 $dst.Q,$src.Q,$tmp.Q\t! logical right shift packed8S"
10876   %}
10877   ins_encode %{
10878     bool quad = true;
10879     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
10880              MacroAssembler::VELEM_SIZE_8, quad);
10881     __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
10882               MacroAssembler::VELEM_SIZE_16, quad);
10883   %}
10884   ins_pipe(ialu_reg_reg);
10885 %}
10886 
10887 instruct vsrl4S_immI(vecD dst, vecD src, immI shift) %{
10888   predicate(n->as_Vector()->length() == 4 && assert_not_var_shift(n));
10889   match(Set dst (URShiftVS src (RShiftCntV shift)));
10890   size(4);
10891   ins_cost(DEFAULT_COST); // FIXME
10892   format %{
10893     "VSHR.U16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
10894   %}
10895   ins_encode %{
10896     bool quad = false;
10897     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10898              quad);
10899   %}
10900   ins_pipe( ialu_reg_reg ); // FIXME
10901 %}
10902 
10903 instruct vsrl8S_immI(vecX dst, vecX src, immI shift) %{
10904   predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n));
10905   match(Set dst (URShiftVS src (RShiftCntV shift)));
10906   size(4);
10907   ins_cost(DEFAULT_COST); // FIXME
10908   format %{
10909     "VSHR.U16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
10910   %}
10911   ins_encode %{
10912     bool quad = true;
10913     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10914              quad);
10915   %}
10916   ins_pipe( ialu_reg_reg ); // FIXME
10917 %}
10918 
10919 // Integers vector logical right shift
10920 instruct vsrl2I_reg(vecD dst, vecD src, vecD shift) %{
10921   predicate(n->as_Vector()->length() == 2 &&
10922             VM_Version::has_simd() &&
10923             !n->as_ShiftV()->is_var_shift());
10924   match(Set dst (URShiftVI src shift));
10925   size(4);
10926   ins_cost(DEFAULT_COST);
10927   expand %{
10928     vsh2I_reg(dst, src, shift);
10929   %}
10930 %}
10931 
10932 instruct vsrl2I_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{
10933   predicate(n->as_Vector()->length() == 2 &&
10934             VM_Version::has_simd() &&
10935             n->as_ShiftV()->is_var_shift());
10936   match(Set dst (URShiftVI src shift));
10937   effect(TEMP tmp);
10938   size(4*2);
10939   ins_cost(DEFAULT_COST*2);
10940   format %{
10941     "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B"
10942     "VSHL.U32 $dst.D,$src.D,$tmp.D\t! logical right shift packed2I"
10943   %}
10944   ins_encode %{
10945     bool quad = false;
10946     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
10947              MacroAssembler::VELEM_SIZE_8, quad);
10948     __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
10949               MacroAssembler::VELEM_SIZE_32, quad);
10950   %}
10951   ins_pipe(ialu_reg_reg);
10952 %}
10953 
10954 instruct vsrl4I_reg(vecX dst, vecX src, vecX shift) %{
10955   predicate(n->as_Vector()->length() == 4 &&
10956             VM_Version::has_simd() &&
10957             !n->as_ShiftV()->is_var_shift());
10958   match(Set dst (URShiftVI src shift));
10959   size(4);
10960   ins_cost(DEFAULT_COST);
10961   expand %{
10962     vsh4I_reg(dst, src, shift);
10963   %}
10964 %}
10965 
10966 instruct vsrl4I_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
10967   predicate(n->as_Vector()->length() == 4 &&
10968             VM_Version::has_simd() &&
10969             n->as_ShiftV()->is_var_shift());
10970   match(Set dst (URShiftVI src shift));
10971   effect(TEMP tmp);
10972   size(4*2);
10973   ins_cost(DEFAULT_COST*2);
10974   format %{
10975     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
10976     "VSHL.U32 $dst.Q,$src.Q,$tmp.Q\t! logical right shift packed4I"
10977   %}
10978   ins_encode %{
10979     bool quad = true;
10980     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
10981              MacroAssembler::VELEM_SIZE_8, quad);
10982     __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
10983               MacroAssembler::VELEM_SIZE_32, quad);
10984   %}
10985   ins_pipe(ialu_reg_reg);
10986 %}
10987 
10988 instruct vsrl2I_immI(vecD dst, vecD src, immI shift) %{
10989   predicate(n->as_Vector()->length() == 2 &&
10990             VM_Version::has_simd() &&
10991             assert_not_var_shift(n));
10992   match(Set dst (URShiftVI src (RShiftCntV shift)));
10993   size(4);
10994   ins_cost(DEFAULT_COST); // FIXME
10995   format %{
10996     "VSHR.U32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
10997   %}
10998   ins_encode %{
10999     bool quad = false;
11000     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11001              quad);
11002   %}
11003   ins_pipe( ialu_reg_reg ); // FIXME
11004 %}
11005 
11006 instruct vsrl4I_immI(vecX dst, vecX src, immI shift) %{
11007   predicate(n->as_Vector()->length() == 4 &&
11008             VM_Version::has_simd() &&
11009             assert_not_var_shift(n));
11010   match(Set dst (URShiftVI src (RShiftCntV shift)));
11011   size(4);
11012   ins_cost(DEFAULT_COST); // FIXME
11013   format %{
11014     "VSHR.U32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
11015   %}
11016   ins_encode %{
11017     bool quad = true;
11018     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11019              quad);
11020   %}
11021   ins_pipe( ialu_reg_reg ); // FIXME
11022 %}
11023 
11024 // Longs vector logical right shift
11025 instruct vsrl2L_reg(vecX dst, vecX src, vecX shift) %{
11026   predicate(n->as_Vector()->length() == 2 && !n->as_ShiftV()->is_var_shift());
11027   match(Set dst (URShiftVL src shift));
11028   size(4);
11029   ins_cost(DEFAULT_COST);
11030   expand %{
11031     vsh2L_reg(dst, src, shift);
11032   %}
11033 %}
11034 
11035 instruct vsrl2L_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
11036   predicate(n->as_Vector()->length() == 2 && n->as_ShiftV()->is_var_shift());
11037   match(Set dst (URShiftVL src shift));
11038   effect(TEMP tmp, DEF dst, USE src, USE shift);
11039   size(4*2);
11040   ins_cost(DEFAULT_COST*2);
11041   format %{
11042     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
11043     "VSHL.U64 $dst.Q,$src.Q,$tmp.Q\t! logical right shift packed2L"
11044   %}
11045   ins_encode %{
11046     bool quad = true;
11047     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11048              MacroAssembler::VELEM_SIZE_8, quad);
11049     __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11050               MacroAssembler::VELEM_SIZE_64, quad);
11051   %}
11052   ins_pipe(ialu_reg_reg);
11053 %}
11054 
11055 instruct vsrl2L_immI(vecX dst, vecX src, immI shift) %{
11056   predicate(n->as_Vector()->length() == 2 && assert_not_var_shift(n));
11057   match(Set dst (URShiftVL src (RShiftCntV shift)));
11058   size(4);
11059   ins_cost(DEFAULT_COST); // FIXME
11060   format %{
11061     "VSHR.U64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
11062   %}
11063   ins_encode %{
11064     bool quad = true;
11065     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
11066              quad);
11067   %}
11068   ins_pipe( ialu_reg_reg ); // FIXME
11069 %}
11070 
11071 // ------------------- ArithmeticRightShift -----------------------------------
11072 
11073 // Bytes vector arithmetic left/right shift based on sign
11074 instruct vsha8B_reg(vecD dst, vecD src, vecD shift) %{
11075   predicate(n->as_Vector()->length() == 8);
11076   effect(DEF dst, USE src, USE shift);
11077   size(4);
11078   ins_cost(DEFAULT_COST); // FIXME
11079   format %{
11080     "VSHL.S8 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed8B"
11081   %}
11082   ins_encode %{
11083     bool quad = false;
11084     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11085               MacroAssembler::VELEM_SIZE_8, quad);
11086   %}
11087   ins_pipe( ialu_reg_reg ); // FIXME
11088 %}
11089 
11090 instruct vsha16B_reg(vecX dst, vecX src, vecX shift) %{
11091   predicate(n->as_Vector()->length() == 16);
11092   effect(DEF dst, USE src, USE shift);
11093   size(4);
11094   ins_cost(DEFAULT_COST); // FIXME
11095   format %{
11096     "VSHL.S8 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed16B"
11097   %}
11098   ins_encode %{
11099     bool quad = true;
11100     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11101               MacroAssembler::VELEM_SIZE_8, quad);
11102   %}
11103   ins_pipe( ialu_reg_reg ); // FIXME
11104 %}
11105 
11106 // Shorts vector arithmetic left/right shift based on sign
11107 instruct vsha4S_reg(vecD dst, vecD src, vecD shift) %{
11108   predicate(n->as_Vector()->length() == 4);
11109   effect(DEF dst, USE src, USE shift);
11110   size(4);
11111   ins_cost(DEFAULT_COST); // FIXME
11112   format %{
11113     "VSHL.S16 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed4S"
11114   %}
11115   ins_encode %{
11116     bool quad = false;
11117     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11118               MacroAssembler::VELEM_SIZE_16, quad);
11119   %}
11120   ins_pipe( ialu_reg_reg ); // FIXME
11121 %}
11122 
11123 instruct vsha8S_reg(vecX dst, vecX src, vecX shift) %{
11124   predicate(n->as_Vector()->length() == 8);
11125   effect(DEF dst, USE src, USE shift);
11126   size(4);
11127   ins_cost(DEFAULT_COST); // FIXME
11128   format %{
11129     "VSHL.S16 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed8S"
11130   %}
11131   ins_encode %{
11132     bool quad = true;
11133     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11134               MacroAssembler::VELEM_SIZE_16, quad);
11135   %}
11136   ins_pipe( ialu_reg_reg ); // FIXME
11137 %}
11138 
11139 // Integers vector arithmetic left/right shift based on sign
11140 instruct vsha2I_reg(vecD dst, vecD src, vecD shift) %{
11141   predicate(n->as_Vector()->length() == 2);
11142   effect(DEF dst, USE src, USE shift);
11143   size(4);
11144   ins_cost(DEFAULT_COST); // FIXME
11145   format %{
11146     "VSHL.S32 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed2I"
11147   %}
11148   ins_encode %{
11149     bool quad = false;
11150     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11151               MacroAssembler::VELEM_SIZE_32, quad);
11152   %}
11153   ins_pipe( ialu_reg_reg ); // FIXME
11154 %}
11155 
11156 instruct vsha4I_reg(vecX dst, vecX src, vecX shift) %{
11157   predicate(n->as_Vector()->length() == 4);
11158   effect(DEF dst, USE src, USE shift);
11159   size(4);
11160   ins_cost(DEFAULT_COST); // FIXME
11161   format %{
11162     "VSHL.S32 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed4I"
11163   %}
11164   ins_encode %{
11165     bool quad = true;
11166     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11167               MacroAssembler::VELEM_SIZE_32, quad);
11168   %}
11169   ins_pipe( ialu_reg_reg ); // FIXME
11170 %}
11171 
11172 // Longs vector arithmetic left/right shift based on sign
11173 instruct vsha2L_reg(vecX dst, vecX src, vecX shift) %{
11174   predicate(n->as_Vector()->length() == 2);
11175   effect(DEF dst, USE src, USE shift);
11176   size(4);
11177   ins_cost(DEFAULT_COST); // FIXME
11178   format %{
11179     "VSHL.S64 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed2L"
11180   %}
11181   ins_encode %{
11182     bool quad = true;
11183     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
11184               MacroAssembler::VELEM_SIZE_64, quad);
11185   %}
11186   ins_pipe( ialu_reg_reg ); // FIXME
11187 %}
11188 
11189 // Byte vector arithmetic right shift
11190 instruct vsra8B_reg(vecD dst, vecD src, vecD shift) %{
11191   predicate(n->as_Vector()->length() == 8 && !n->as_ShiftV()->is_var_shift());
11192   match(Set dst (RShiftVB src shift));
11193   size(4);
11194   ins_cost(DEFAULT_COST); // FIXME
11195   expand %{
11196     vsha8B_reg(dst, src, shift);
11197   %}
11198 %}
11199 
11200 instruct vsra8B_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{
11201   predicate(n->as_Vector()->length() == 8 && n->as_ShiftV()->is_var_shift());
11202   match(Set dst (RShiftVB src shift));
11203   effect(TEMP tmp);
11204   size(4*2);
11205   ins_cost(DEFAULT_COST*2);
11206   format %{
11207     "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B"
11208     "VSHL.S8 $dst.D,$src.D,$tmp.D\t! arithmetic right shift packed8B"
11209   %}
11210   ins_encode %{
11211     bool quad = false;
11212     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11213              MacroAssembler::VELEM_SIZE_8, quad);
11214     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11215               MacroAssembler::VELEM_SIZE_8, quad);
11216   %}
11217   ins_pipe(ialu_reg_reg);
11218 %}
11219 
11220 instruct vsra16B_reg(vecX dst, vecX src, vecX shift) %{
11221   predicate(n->as_Vector()->length() == 16 && !n->as_ShiftV()->is_var_shift());
11222   match(Set dst (RShiftVB src shift));
11223   size(4);
11224   ins_cost(DEFAULT_COST); // FIXME
11225   expand %{
11226     vsha16B_reg(dst, src, shift);
11227   %}
11228 %}
11229 
11230 instruct vsra16B_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
11231   predicate(n->as_Vector()->length() == 16 && n->as_ShiftV()->is_var_shift());
11232   match(Set dst (RShiftVB src shift));
11233   effect(TEMP tmp);
11234   size(4*2);
11235   ins_cost(DEFAULT_COST*2);
11236   format %{
11237     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
11238     "VSHL.S8 $dst.Q,$src.Q,$tmp.Q\t! arithmetic right shift packed16B"
11239   %}
11240   ins_encode %{
11241     bool quad = true;
11242     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11243              MacroAssembler::VELEM_SIZE_8, quad);
11244     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11245               MacroAssembler::VELEM_SIZE_8, quad);
11246   %}
11247   ins_pipe(ialu_reg_reg);
11248 %}
11249 
11250 instruct vsra8B_immI(vecD dst, vecD src, immI shift) %{
11251   predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n));
11252   match(Set dst (RShiftVB src (RShiftCntV shift)));
11253   size(4);
11254   ins_cost(DEFAULT_COST); // FIXME
11255   format %{
11256     "VSHR.S8 $dst.D,$src.D,$shift\t! arithmetic right shift packed8B"
11257   %}
11258   ins_encode %{
11259     bool quad = false;
11260     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
11261              quad);
11262   %}
11263   ins_pipe( ialu_reg_reg ); // FIXME
11264 %}
11265 
11266 instruct vsra16B_immI(vecX dst, vecX src, immI shift) %{
11267   predicate(n->as_Vector()->length() == 16 && assert_not_var_shift(n));
11268   match(Set dst (RShiftVB src (RShiftCntV shift)));
11269   size(4);
11270   ins_cost(DEFAULT_COST); // FIXME
11271   format %{
11272     "VSHR.S8 $dst.Q,$src.Q,$shift\t! arithmetic right shift packed16B"
11273   %}
11274   ins_encode %{
11275     bool quad = true;
11276     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
11277              quad);
11278   %}
11279   ins_pipe( ialu_reg_reg ); // FIXME
11280 %}
11281 
11282 // Shorts vector arithmetic right shift
11283 instruct vsra4S_reg(vecD dst, vecD src, vecD shift) %{
11284   predicate(n->as_Vector()->length() == 4 && !n->as_ShiftV()->is_var_shift());
11285   match(Set dst (RShiftVS src shift));
11286   size(4);
11287   ins_cost(DEFAULT_COST); // FIXME
11288   expand %{
11289     vsha4S_reg(dst, src, shift);
11290   %}
11291 %}
11292 
11293 instruct vsra4S_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{
11294   predicate(n->as_Vector()->length() == 4 && n->as_ShiftV()->is_var_shift());
11295   match(Set dst (RShiftVS src shift));
11296   effect(TEMP tmp);
11297   size(4*2);
11298   ins_cost(DEFAULT_COST*2);
11299   format %{
11300     "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B"
11301     "VSHL.S16 $dst.D,$src.D,$tmp.D\t! arithmetic right shift packed4S"
11302   %}
11303   ins_encode %{
11304     bool quad = false;
11305     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11306              MacroAssembler::VELEM_SIZE_8, quad);
11307     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11308               MacroAssembler::VELEM_SIZE_16, quad);
11309   %}
11310   ins_pipe(ialu_reg_reg);
11311 %}
11312 
11313 instruct vsra8S_reg(vecX dst, vecX src, vecX shift) %{
11314   predicate(n->as_Vector()->length() == 8 && !n->as_ShiftV()->is_var_shift());
11315   match(Set dst (RShiftVS src shift));
11316   size(4);
11317   ins_cost(DEFAULT_COST); // FIXME
11318   expand %{
11319     vsha8S_reg(dst, src, shift);
11320   %}
11321 %}
11322 
11323 instruct vsra8S_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
11324   predicate(n->as_Vector()->length() == 8 && n->as_ShiftV()->is_var_shift());
11325   match(Set dst (RShiftVS src shift));
11326   effect(TEMP tmp);
11327   size(4*2);
11328   ins_cost(DEFAULT_COST*2);
11329   format %{
11330     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
11331     "VSHL.S16 $dst.Q,$src.Q,$tmp.Q\t! arithmetic right shift packed8S"
11332   %}
11333   ins_encode %{
11334     bool quad = true;
11335     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11336              MacroAssembler::VELEM_SIZE_8, quad);
11337     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11338               MacroAssembler::VELEM_SIZE_16, quad);
11339   %}
11340   ins_pipe(ialu_reg_reg);
11341 %}
11342 
11343 instruct vsra4S_immI(vecD dst, vecD src, immI shift) %{
11344   predicate(n->as_Vector()->length() == 4 && assert_not_var_shift(n));
11345   match(Set dst (RShiftVS src (RShiftCntV shift)));
11346   size(4);
11347   ins_cost(DEFAULT_COST); // FIXME
11348   format %{
11349     "VSHR.S16 $dst.D,$src.D,$shift\t! arithmetic right shift packed4S"
11350   %}
11351   ins_encode %{
11352     bool quad = false;
11353     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
11354              quad);
11355   %}
11356   ins_pipe( ialu_reg_reg ); // FIXME
11357 %}
11358 
11359 instruct vsra8S_immI(vecX dst, vecX src, immI shift) %{
11360   predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n));
11361   match(Set dst (RShiftVS src (RShiftCntV shift)));
11362   size(4);
11363   ins_cost(DEFAULT_COST); // FIXME
11364   format %{
11365     "VSHR.S16 $dst.Q,$src.Q,$shift\t! arithmetic right shift packed8S"
11366   %}
11367   ins_encode %{
11368     bool quad = true;
11369     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
11370              quad);
11371   %}
11372   ins_pipe( ialu_reg_reg ); // FIXME
11373 %}
11374 
11375 // Integers vector arithmetic right shift
11376 instruct vsra2I_reg(vecD dst, vecD src, vecD shift) %{
11377   predicate(n->as_Vector()->length() == 2 && !n->as_ShiftV()->is_var_shift());
11378   match(Set dst (RShiftVI src shift));
11379   size(4);
11380   ins_cost(DEFAULT_COST); // FIXME
11381   expand %{
11382     vsha2I_reg(dst, src, shift);
11383   %}
11384 %}
11385 
11386 instruct vsra2I_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{
11387   predicate(n->as_Vector()->length() == 2 && n->as_ShiftV()->is_var_shift());
11388   match(Set dst (RShiftVI src shift));
11389   effect(TEMP tmp);
11390   size(4*2);
11391   ins_cost(DEFAULT_COST*2);
11392   format %{
11393     "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B"
11394     "VSHL.S32 $dst.D,$src.D,$tmp.D\t! arithmetic right shift packed2I"
11395   %}
11396   ins_encode %{
11397     bool quad = false;
11398     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11399              MacroAssembler::VELEM_SIZE_8, quad);
11400     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11401               MacroAssembler::VELEM_SIZE_32, quad);
11402   %}
11403   ins_pipe(ialu_reg_reg);
11404 %}
11405 
11406 instruct vsra4I_reg(vecX dst, vecX src, vecX shift) %{
11407   predicate(n->as_Vector()->length() == 4 && !n->as_ShiftV()->is_var_shift());
11408   match(Set dst (RShiftVI src shift));
11409   size(4);
11410   ins_cost(DEFAULT_COST); // FIXME
11411   expand %{
11412     vsha4I_reg(dst, src, shift);
11413   %}
11414 %}
11415 
11416 instruct vsra4I_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
11417   predicate(n->as_Vector()->length() == 4 && n->as_ShiftV()->is_var_shift());
11418   match(Set dst (RShiftVI src shift));
11419   effect(TEMP tmp);
11420   size(4*2);
11421   ins_cost(DEFAULT_COST*2);
11422   format %{
11423     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
11424     "VSHL.S32 $dst.Q,$src.Q,$tmp.Q\t! arithmetic right shift packed4I"
11425   %}
11426   ins_encode %{
11427     bool quad = true;
11428     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11429              MacroAssembler::VELEM_SIZE_8, quad);
11430     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11431               MacroAssembler::VELEM_SIZE_32, quad);
11432   %}
11433   ins_pipe(ialu_reg_reg);
11434 %}
11435 
11436 instruct vsra2I_immI(vecD dst, vecD src, immI shift) %{
11437   predicate(n->as_Vector()->length() == 2 && assert_not_var_shift(n));
11438   match(Set dst (RShiftVI src (RShiftCntV shift)));
11439   size(4);
11440   ins_cost(DEFAULT_COST); // FIXME
11441   format %{
11442     "VSHR.S32 $dst.D,$src.D,$shift\t! arithmetic right shift packed2I"
11443   %}
11444   ins_encode %{
11445     bool quad = false;
11446     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11447              quad);
11448   %}
11449   ins_pipe( ialu_reg_reg ); // FIXME
11450 %}
11451 
11452 instruct vsra4I_immI(vecX dst, vecX src, immI shift) %{
11453   predicate(n->as_Vector()->length() == 4 && assert_not_var_shift(n));
11454   match(Set dst (RShiftVI src (RShiftCntV shift)));
11455   size(4);
11456   ins_cost(DEFAULT_COST); // FIXME
11457   format %{
11458     "VSHR.S32 $dst.Q,$src.Q,$shift\t! arithmetic right shift packed4I"
11459   %}
11460   ins_encode %{
11461     bool quad = true;
11462     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11463              quad);
11464   %}
11465   ins_pipe( ialu_reg_reg ); // FIXME
11466 %}
11467 
11468 // Longs vector arithmetic right shift
11469 instruct vsra2L_reg(vecX dst, vecX src, vecX shift) %{
11470   predicate(n->as_Vector()->length() == 2 && !n->as_ShiftV()->is_var_shift());
11471   match(Set dst (RShiftVL src shift));
11472   size(4);
11473   ins_cost(DEFAULT_COST); // FIXME
11474   expand %{
11475     vsha2L_reg(dst, src, shift);
11476   %}
11477 %}
11478 
11479 instruct vsra2L_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{
11480   predicate(n->as_Vector()->length() == 2 && n->as_ShiftV()->is_var_shift());
11481   match(Set dst (RShiftVL src shift));
11482   effect(TEMP tmp);
11483   size(4*2);
11484   ins_cost(DEFAULT_COST*2);
11485   format %{
11486     "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B"
11487     "VSHL.S64 $dst.Q,$src.Q,$tmp.Q\t! arithmetic right shift packed2L"
11488   %}
11489   ins_encode %{
11490     bool quad = true;
11491     __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister,
11492              MacroAssembler::VELEM_SIZE_8, quad);
11493     __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister,
11494               MacroAssembler::VELEM_SIZE_64, quad);
11495   %}
11496   ins_pipe(ialu_reg_reg);
11497 %}
11498 
11499 instruct vsra2L_immI(vecX dst, vecX src, immI shift) %{
11500   predicate(n->as_Vector()->length() == 2 && assert_not_var_shift(n));
11501   match(Set dst (RShiftVL src (RShiftCntV shift)));
11502   size(4);
11503   ins_cost(DEFAULT_COST); // FIXME
11504   format %{
11505     "VSHR.S64 $dst.Q,$src.Q,$shift\t! arithmetic right shift packed2L"
11506   %}
11507   ins_encode %{
11508     bool quad = true;
11509     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
11510              quad);
11511   %}
11512   ins_pipe( ialu_reg_reg ); // FIXME
11513 %}
11514 
11515 // --------------------------------- AND --------------------------------------
11516 
11517 instruct vandD(vecD dst, vecD src1, vecD src2) %{
11518   predicate(n->as_Vector()->length_in_bytes() == 8);
11519   match(Set dst (AndV src1 src2));
11520   format %{ "VAND    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11521   ins_encode %{
11522     bool quad = false;
11523     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11524              quad);
11525   %}
11526   ins_pipe( ialu_reg_reg ); // FIXME
11527 %}
11528 
11529 instruct vandX(vecX dst, vecX src1, vecX src2) %{
11530   predicate(n->as_Vector()->length_in_bytes() == 16);
11531   match(Set dst (AndV src1 src2));
11532   format %{ "VAND    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11533   ins_encode %{
11534     bool quad = true;
11535     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11536              quad);
11537   %}
11538   ins_pipe( ialu_reg_reg ); // FIXME
11539 %}
11540 
11541 // --------------------------------- OR ---------------------------------------
11542 
11543 instruct vorD(vecD dst, vecD src1, vecD src2) %{
11544   predicate(n->as_Vector()->length_in_bytes() == 8);
11545   match(Set dst (OrV src1 src2));
11546   format %{ "VOR     $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11547   ins_encode %{
11548     bool quad = false;
11549     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11550             quad);
11551   %}
11552   ins_pipe( ialu_reg_reg ); // FIXME
11553 %}
11554 
11555 instruct vorX(vecX dst, vecX src1, vecX src2) %{
11556   predicate(n->as_Vector()->length_in_bytes() == 16);
11557   match(Set dst (OrV src1 src2));
11558   format %{ "VOR     $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11559   ins_encode %{
11560     bool quad = true;
11561     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11562             quad);
11563   %}
11564   ins_pipe( ialu_reg_reg ); // FIXME
11565 %}
11566 
11567 // --------------------------------- XOR --------------------------------------
11568 
11569 instruct vxorD(vecD dst, vecD src1, vecD src2) %{
11570   predicate(n->as_Vector()->length_in_bytes() == 8);
11571   match(Set dst (XorV src1 src2));
11572   format %{ "VXOR    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11573   ins_encode %{
11574     bool quad = false;
11575     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11576              quad);
11577   %}
11578   ins_pipe( ialu_reg_reg ); // FIXME
11579 %}
11580 
11581 instruct vxorX(vecX dst, vecX src1, vecX src2) %{
11582   predicate(n->as_Vector()->length_in_bytes() == 16);
11583   match(Set dst (XorV src1 src2));
11584   format %{ "VXOR    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11585   ins_encode %{
11586     bool quad = true;
11587     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11588              quad);
11589   %}
11590   ins_pipe( ialu_reg_reg ); // FIXME
11591 %}
11592 
11593 
11594 //----------PEEPHOLE RULES-----------------------------------------------------
11595 // These must follow all instruction definitions as they use the names
11596 // defined in the instructions definitions.
11597 //
11598 // peepmatch ( root_instr_name [preceding_instruction]* );
11599 //
11600 // peepconstraint %{
11601 // (instruction_number.operand_name relational_op instruction_number.operand_name
11602 //  [, ...] );
11603 // // instruction numbers are zero-based using left to right order in peepmatch
11604 //
11605 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
11606 // // provide an instruction_number.operand_name for each operand that appears
11607 // // in the replacement instruction's match rule
11608 //
11609 // ---------VM FLAGS---------------------------------------------------------
11610 //
11611 // All peephole optimizations can be turned off using -XX:-OptoPeephole
11612 //
11613 // Each peephole rule is given an identifying number starting with zero and
11614 // increasing by one in the order seen by the parser.  An individual peephole
11615 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
11616 // on the command-line.
11617 //
11618 // ---------CURRENT LIMITATIONS----------------------------------------------
11619 //
11620 // Only match adjacent instructions in same basic block
11621 // Only equality constraints
11622 // Only constraints between operands, not (0.dest_reg == EAX_enc)
11623 // Only one replacement instruction
11624 //
11625 // ---------EXAMPLE----------------------------------------------------------
11626 //
11627 // // pertinent parts of existing instructions in architecture description
11628 // instruct movI(eRegI dst, eRegI src) %{
11629 //   match(Set dst (CopyI src));
11630 // %}
11631 //
11632 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
11633 //   match(Set dst (AddI dst src));
11634 //   effect(KILL cr);
11635 // %}
11636 //
11637 // // Change (inc mov) to lea
11638 // peephole %{
11639 //   // increment preceded by register-register move
11640 //   peepmatch ( incI_eReg movI );
11641 //   // require that the destination register of the increment
11642 //   // match the destination register of the move
11643 //   peepconstraint ( 0.dst == 1.dst );
11644 //   // construct a replacement instruction that sets
11645 //   // the destination to ( move's source register + one )
11646 //   peepreplace ( incI_eReg_immI1( 0.dst 1.src 0.src ) );
11647 // %}
11648 //
11649 
11650 // // Change load of spilled value to only a spill
11651 // instruct storeI(memory mem, eRegI src) %{
11652 //   match(Set mem (StoreI mem src));
11653 // %}
11654 //
11655 // instruct loadI(eRegI dst, memory mem) %{
11656 //   match(Set dst (LoadI mem));
11657 // %}
11658 //
11659 // peephole %{
11660 //   peepmatch ( loadI storeI );
11661 //   peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
11662 //   peepreplace ( storeI( 1.mem 1.mem 1.src ) );
11663 // %}
11664 
11665 //----------SMARTSPILL RULES---------------------------------------------------
11666 // These must follow all instruction definitions as they use the names
11667 // defined in the instructions definitions.
11668 //
11669 // ARM will probably not have any of these rules due to RISC instruction set.
11670 
11671 //----------PIPELINE-----------------------------------------------------------
11672 // Rules which define the behavior of the target architectures pipeline.