1 //
    2 // Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
    3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4 //
    5 // This code is free software; you can redistribute it and/or modify it
    6 // under the terms of the GNU General Public License version 2 only, as
    7 // published by the Free Software Foundation.
    8 //
    9 // This code is distributed in the hope that it will be useful, but WITHOUT
   10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   12 // version 2 for more details (a copy is included in the LICENSE file that
   13 // accompanied this code).
   14 //
   15 // You should have received a copy of the GNU General Public License version
   16 // 2 along with this work; if not, write to the Free Software Foundation,
   17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   18 //
   19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   20 // or visit www.oracle.com if you need additional information or have any
   21 // questions.
   22 //
   23 
   24 // ARM Architecture Description File
   25 
   26 //----------DEFINITION BLOCK---------------------------------------------------
   27 // Define name --> value mappings to inform the ADLC of an integer valued name
   28 // Current support includes integer values in the range [0, 0x7FFFFFFF]
   29 // Format:
   30 //        int_def  <name>         ( <int_value>, <expression>);
   31 // Generated Code in ad_<arch>.hpp
   32 //        #define  <name>   (<expression>)
   33 //        // value == <int_value>
   34 // Generated code in ad_<arch>.cpp adlc_verification()
   35 //        assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
   36 //
   37 definitions %{
   38 // The default cost (of an ALU instruction).
   39   int_def DEFAULT_COST      (    100,     100);
   40   int_def HUGE_COST         (1000000, 1000000);
   41 
   42 // Memory refs are twice as expensive as run-of-the-mill.
   43   int_def MEMORY_REF_COST   (    200, DEFAULT_COST * 2);
   44 
   45 // Branches are even more expensive.
   46   int_def BRANCH_COST       (    300, DEFAULT_COST * 3);
   47   int_def CALL_COST         (    300, DEFAULT_COST * 3);
   48 %}
   49 
   50 
   51 //----------SOURCE BLOCK-------------------------------------------------------
   52 // This is a block of C++ code which provides values, functions, and
   53 // definitions necessary in the rest of the architecture description
   54 source_hpp %{
   55 // Header information of the source block.
   56 // Method declarations/definitions which are used outside
   57 // the ad-scope can conveniently be defined here.
   58 //
   59 // To keep related declarations/definitions/uses close together,
   60 // we switch between source %{ }% and source_hpp %{ }% freely as needed.
   61 
   62 // Does destination need to be loaded in a register then passed to a
   63 // branch instruction?
   64 extern bool maybe_far_call(const CallNode *n);
   65 extern bool maybe_far_call(const MachCallNode *n);
   66 static inline bool cache_reachable() {
   67   return MacroAssembler::_cache_fully_reachable();
   68 }
   69 
   70 #define ldr_32 ldr
   71 #define str_32 str
   72 #define tst_32 tst
   73 #define teq_32 teq
   74 #if 1
   75 extern bool PrintOptoAssembly;
   76 #endif
   77 
   78 class c2 {
   79 public:
   80   static OptoRegPair return_value(int ideal_reg);
   81 };
   82 
   83 class CallStubImpl {
   84 
   85   //--------------------------------------------------------------
   86   //---<  Used for optimization in Compile::Shorten_branches  >---
   87   //--------------------------------------------------------------
   88 
   89  public:
   90   // Size of call trampoline stub.
   91   static uint size_call_trampoline() {
   92     return 0; // no call trampolines on this platform
   93   }
   94 
   95   // number of relocations needed by a call trampoline stub
   96   static uint reloc_call_trampoline() {
   97     return 0; // no call trampolines on this platform
   98   }
   99 };
  100 
  101 class HandlerImpl {
  102 
  103  public:
  104 
  105   static int emit_exception_handler(CodeBuffer &cbuf);
  106   static int emit_deopt_handler(CodeBuffer& cbuf);
  107 
  108   static uint size_exception_handler() {
  109     return ( 3 * 4 );
  110   }
  111 
  112 
  113   static uint size_deopt_handler() {
  114     return ( 9 * 4 );
  115   }
  116 
  117 };
  118 
  119 class Node::PD {
  120 public:
  121   enum NodeFlags {
  122     _last_flag = Node::_last_flag
  123   };
  124 };
  125 
  126 %}
  127 
  128 source %{
  129 #define __ _masm.
  130 
  131 static FloatRegister reg_to_FloatRegister_object(int register_encoding);
  132 static Register reg_to_register_object(int register_encoding);
  133 
  134 void PhaseOutput::pd_perform_mach_node_analysis() {
  135 }
  136 
  137 int MachNode::pd_alignment_required() const {
  138   return 1;
  139 }
  140 
  141 int MachNode::compute_padding(int current_offset) const {
  142   return 0;
  143 }
  144 
  145 // ****************************************************************************
  146 
  147 // REQUIRED FUNCTIONALITY
  148 
  149 // emit an interrupt that is caught by the debugger (for debugging compiler)
  150 void emit_break(CodeBuffer &cbuf) {
  151   C2_MacroAssembler _masm(&cbuf);
  152   __ breakpoint();
  153 }
  154 
  155 #ifndef PRODUCT
  156 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream *st ) const {
  157   st->print("TA");
  158 }
  159 #endif
  160 
  161 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  162   emit_break(cbuf);
  163 }
  164 
  165 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
  166   return MachNode::size(ra_);
  167 }
  168 
  169 
  170 void emit_nop(CodeBuffer &cbuf) {
  171   C2_MacroAssembler _masm(&cbuf);
  172   __ nop();
  173 }
  174 
  175 
  176 void emit_call_reloc(CodeBuffer &cbuf, const MachCallNode *n, MachOper *m, RelocationHolder const& rspec) {
  177   int ret_addr_offset0 = n->as_MachCall()->ret_addr_offset();
  178   int call_site_offset = cbuf.insts()->mark_off();
  179   C2_MacroAssembler _masm(&cbuf);
  180   __ set_inst_mark(); // needed in emit_to_interp_stub() to locate the call
  181   address target = (address)m->method();
  182   assert(n->as_MachCall()->entry_point() == target, "sanity");
  183   assert(maybe_far_call(n) == !__ reachable_from_cache(target), "sanity");
  184   assert(cache_reachable() == __ cache_fully_reachable(), "sanity");
  185 
  186   assert(target != NULL, "need real address");
  187 
  188   int ret_addr_offset = -1;
  189   if (rspec.type() == relocInfo::runtime_call_type) {
  190     __ call(target, rspec);
  191     ret_addr_offset = __ offset();
  192   } else {
  193     // scratches Rtemp
  194     ret_addr_offset = __ patchable_call(target, rspec, true);
  195   }
  196   assert(ret_addr_offset - call_site_offset == ret_addr_offset0, "fix ret_addr_offset()");
  197 }
  198 
  199 //=============================================================================
  200 // REQUIRED FUNCTIONALITY for encoding
  201 void emit_lo(CodeBuffer &cbuf, int val) {  }
  202 void emit_hi(CodeBuffer &cbuf, int val) {  }
  203 
  204 
  205 //=============================================================================
  206 const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask();
  207 
  208 int ConstantTable::calculate_table_base_offset() const {
  209   int offset = -(size() / 2);
  210   // flds, fldd: 8-bit  offset multiplied by 4: +/- 1024
  211   // ldr, ldrb : 12-bit offset:                 +/- 4096
  212   if (!Assembler::is_simm10(offset)) {
  213     offset = Assembler::min_simm10;
  214   }
  215   return offset;
  216 }
  217 
  218 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
  219 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
  220   ShouldNotReachHere();
  221 }
  222 
  223 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
  224   Compile* C = ra_->C;
  225   ConstantTable& constant_table = C->output()->constant_table();
  226   C2_MacroAssembler _masm(&cbuf);
  227 
  228   Register r = as_Register(ra_->get_encode(this));
  229   CodeSection* consts_section = __ code()->consts();
  230   int consts_size = consts_section->align_at_start(consts_section->size());
  231   assert(constant_table.size() == consts_size, "must be: %d == %d", constant_table.size(), consts_size);
  232 
  233   // Materialize the constant table base.
  234   address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
  235   RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
  236   __ mov_address(r, baseaddr, rspec);
  237 }
  238 
  239 uint MachConstantBaseNode::size(PhaseRegAlloc*) const {
  240   return 8;
  241 }
  242 
  243 #ifndef PRODUCT
  244 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
  245   char reg[128];
  246   ra_->dump_register(this, reg);
  247   st->print("MOV_SLOW    &constanttable,%s\t! constant table base", reg);
  248 }
  249 #endif
  250 
  251 #ifndef PRODUCT
  252 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  253   Compile* C = ra_->C;
  254 
  255   for (int i = 0; i < OptoPrologueNops; i++) {
  256     st->print_cr("NOP"); st->print("\t");
  257   }
  258 
  259   size_t framesize = C->output()->frame_size_in_bytes();
  260   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  261   int bangsize = C->output()->bang_size_in_bytes();
  262   // Remove two words for return addr and rbp,
  263   framesize -= 2*wordSize;
  264   bangsize -= 2*wordSize;
  265 
  266   // Calls to C2R adapters often do not accept exceptional returns.
  267   // We require that their callers must bang for them.  But be careful, because
  268   // some VM calls (such as call site linkage) can use several kilobytes of
  269   // stack.  But the stack safety zone should account for that.
  270   // See bugs 4446381, 4468289, 4497237.
  271   if (C->output()->need_stack_bang(bangsize)) {
  272     st->print_cr("! stack bang (%d bytes)", bangsize); st->print("\t");
  273   }
  274   st->print_cr("PUSH   R_FP|R_LR_LR"); st->print("\t");
  275   if (framesize != 0) {
  276     st->print   ("SUB    R_SP, R_SP, " SIZE_FORMAT,framesize);
  277   }
  278 }
  279 #endif
  280 
  281 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  282   Compile* C = ra_->C;
  283   C2_MacroAssembler _masm(&cbuf);
  284 
  285   for (int i = 0; i < OptoPrologueNops; i++) {
  286     __ nop();
  287   }
  288 
  289   size_t framesize = C->output()->frame_size_in_bytes();
  290   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  291   int bangsize = C->output()->bang_size_in_bytes();
  292   // Remove two words for return addr and fp,
  293   framesize -= 2*wordSize;
  294   bangsize -= 2*wordSize;
  295 
  296   // Calls to C2R adapters often do not accept exceptional returns.
  297   // We require that their callers must bang for them.  But be careful, because
  298   // some VM calls (such as call site linkage) can use several kilobytes of
  299   // stack.  But the stack safety zone should account for that.
  300   // See bugs 4446381, 4468289, 4497237.
  301   if (C->output()->need_stack_bang(bangsize)) {
  302     __ arm_stack_overflow_check(bangsize, Rtemp);
  303   }
  304 
  305   __ raw_push(FP, LR);
  306   if (framesize != 0) {
  307     __ sub_slow(SP, SP, framesize);
  308   }
  309 
  310   // offset from scratch buffer is not valid
  311   if (strcmp(cbuf.name(), "Compile::Fill_buffer") == 0) {
  312     C->output()->set_frame_complete( __ offset() );
  313   }
  314 
  315   if (C->has_mach_constant_base_node()) {
  316     // NOTE: We set the table base offset here because users might be
  317     // emitted before MachConstantBaseNode.
  318     ConstantTable& constant_table = C->output()->constant_table();
  319     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
  320   }
  321 }
  322 
  323 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
  324   return MachNode::size(ra_);
  325 }
  326 
  327 int MachPrologNode::reloc() const {
  328   return 10; // a large enough number
  329 }
  330 
  331 //=============================================================================
  332 #ifndef PRODUCT
  333 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  334   Compile* C = ra_->C;
  335 
  336   size_t framesize = C->output()->frame_size_in_bytes();
  337   framesize -= 2*wordSize;
  338 
  339   if (framesize != 0) {
  340     st->print("ADD    R_SP, R_SP, " SIZE_FORMAT "\n\t",framesize);
  341   }
  342   st->print("POP    R_FP|R_LR_LR");
  343 
  344   if (do_polling() && ra_->C->is_method_compilation()) {
  345     st->print("\n\t");
  346     st->print("MOV    Rtemp, #PollAddr\t! Load Polling address\n\t");
  347     st->print("LDR    Rtemp,[Rtemp]\t!Poll for Safepointing");
  348   }
  349 }
  350 #endif
  351 
  352 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  353   C2_MacroAssembler _masm(&cbuf);
  354   Compile* C = ra_->C;
  355 
  356   size_t framesize = C->output()->frame_size_in_bytes();
  357   framesize -= 2*wordSize;
  358   if (framesize != 0) {
  359     __ add_slow(SP, SP, framesize);
  360   }
  361   __ raw_pop(FP, LR);
  362 
  363   // If this does safepoint polling, then do it here
  364   if (do_polling() && ra_->C->is_method_compilation()) {
  365     __ read_polling_page(Rtemp, relocInfo::poll_return_type);
  366   }
  367 }
  368 
  369 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
  370   return MachNode::size(ra_);
  371 }
  372 
  373 int MachEpilogNode::reloc() const {
  374   return 16; // a large enough number
  375 }
  376 
  377 const Pipeline * MachEpilogNode::pipeline() const {
  378   return MachNode::pipeline_class();
  379 }
  380 
  381 //=============================================================================
  382 
  383 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
  384 enum RC { rc_bad, rc_int, rc_float, rc_stack };
  385 static enum RC rc_class( OptoReg::Name reg ) {
  386   if (!OptoReg::is_valid(reg)) return rc_bad;
  387   if (OptoReg::is_stack(reg)) return rc_stack;
  388   VMReg r = OptoReg::as_VMReg(reg);
  389   if (r->is_Register()) return rc_int;
  390   assert(r->is_FloatRegister(), "must be");
  391   return rc_float;
  392 }
  393 
  394 static inline bool is_iRegLd_memhd(OptoReg::Name src_first, OptoReg::Name src_second, int offset) {
  395   int rlo = Matcher::_regEncode[src_first];
  396   int rhi = Matcher::_regEncode[src_second];
  397   if (!((rlo&1)==0 && (rlo+1 == rhi))) {
  398     tty->print_cr("CAUGHT BAD LDRD/STRD");
  399   }
  400   return (rlo&1)==0 && (rlo+1 == rhi) && is_memoryHD(offset);
  401 }
  402 
  403 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
  404                                         PhaseRegAlloc *ra_,
  405                                         bool do_size,
  406                                         outputStream* st ) const {
  407   // Get registers to move
  408   OptoReg::Name src_second = ra_->get_reg_second(in(1));
  409   OptoReg::Name src_first = ra_->get_reg_first(in(1));
  410   OptoReg::Name dst_second = ra_->get_reg_second(this );
  411   OptoReg::Name dst_first = ra_->get_reg_first(this );
  412 
  413   enum RC src_second_rc = rc_class(src_second);
  414   enum RC src_first_rc = rc_class(src_first);
  415   enum RC dst_second_rc = rc_class(dst_second);
  416   enum RC dst_first_rc = rc_class(dst_first);
  417 
  418   assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
  419 
  420   // Generate spill code!
  421   int size = 0;
  422 
  423   if (src_first == dst_first && src_second == dst_second)
  424     return size;            // Self copy, no move
  425 
  426 #ifdef TODO
  427   if (bottom_type()->isa_vect() != NULL) {
  428   }
  429 #endif
  430 
  431   // Shared code does not expect instruction set capability based bailouts here.
  432   // Handle offset unreachable bailout with minimal change in shared code.
  433   // Bailout only for real instruction emit.
  434   // This requires a single comment change in shared code. ( see output.cpp "Normal" instruction case )
  435 
  436   C2_MacroAssembler _masm(cbuf);
  437 
  438   // --------------------------------------
  439   // Check for mem-mem move.  Load into unused float registers and fall into
  440   // the float-store case.
  441   if (src_first_rc == rc_stack && dst_first_rc == rc_stack) {
  442     int offset = ra_->reg2offset(src_first);
  443     if (cbuf && !is_memoryfp(offset)) {
  444       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  445       return 0;
  446     } else {
  447       if (src_second_rc != rc_bad) {
  448         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
  449         src_first     = OptoReg::Name(R_mem_copy_lo_num);
  450         src_second    = OptoReg::Name(R_mem_copy_hi_num);
  451         src_first_rc  = rc_float;
  452         src_second_rc = rc_float;
  453         if (cbuf) {
  454           __ ldr_double(Rmemcopy, Address(SP, offset));
  455         } else if (!do_size) {
  456           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  457         }
  458       } else {
  459         src_first     = OptoReg::Name(R_mem_copy_lo_num);
  460         src_first_rc  = rc_float;
  461         if (cbuf) {
  462           __ ldr_float(Rmemcopy, Address(SP, offset));
  463         } else if (!do_size) {
  464           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  465         }
  466       }
  467       size += 4;
  468     }
  469   }
  470 
  471   if (src_second_rc == rc_stack && dst_second_rc == rc_stack) {
  472     Unimplemented();
  473   }
  474 
  475   // --------------------------------------
  476   // Check for integer reg-reg copy
  477   if (src_first_rc == rc_int && dst_first_rc == rc_int) {
  478     // Else normal reg-reg copy
  479     assert( src_second != dst_first, "smashed second before evacuating it" );
  480     if (cbuf) {
  481       __ mov(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
  482 #ifndef PRODUCT
  483     } else if (!do_size) {
  484       st->print("MOV    R_%s, R_%s\t# spill",
  485                 Matcher::regName[dst_first],
  486                 Matcher::regName[src_first]);
  487 #endif
  488     }
  489     size += 4;
  490   }
  491 
  492   // Check for integer store
  493   if (src_first_rc == rc_int && dst_first_rc == rc_stack) {
  494     int offset = ra_->reg2offset(dst_first);
  495     if (cbuf && !is_memoryI(offset)) {
  496       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  497       return 0;
  498     } else {
  499       if (src_second_rc != rc_bad && is_iRegLd_memhd(src_first, src_second, offset)) {
  500         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
  501         if (cbuf) {
  502           __ str_64(reg_to_register_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  503 #ifndef PRODUCT
  504         } else if (!do_size) {
  505           if (size != 0) st->print("\n\t");
  506           st->print(STR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
  507 #endif
  508         }
  509         return size + 4;
  510       } else {
  511         if (cbuf) {
  512           __ str_32(reg_to_register_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  513 #ifndef PRODUCT
  514         } else if (!do_size) {
  515           if (size != 0) st->print("\n\t");
  516           st->print(STR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
  517 #endif
  518         }
  519       }
  520     }
  521     size += 4;
  522   }
  523 
  524   // Check for integer load
  525   if (dst_first_rc == rc_int && src_first_rc == rc_stack) {
  526     int offset = ra_->reg2offset(src_first);
  527     if (cbuf && !is_memoryI(offset)) {
  528       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  529       return 0;
  530     } else {
  531       if (src_second_rc != rc_bad && is_iRegLd_memhd(dst_first, dst_second, offset)) {
  532         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
  533         if (cbuf) {
  534           __ ldr_64(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  535 #ifndef PRODUCT
  536         } else if (!do_size) {
  537           if (size != 0) st->print("\n\t");
  538           st->print(LDR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
  539 #endif
  540         }
  541         return size + 4;
  542       } else {
  543         if (cbuf) {
  544           __ ldr_32(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  545 #ifndef PRODUCT
  546         } else if (!do_size) {
  547           if (size != 0) st->print("\n\t");
  548           st->print(LDR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
  549 #endif
  550         }
  551       }
  552     }
  553     size += 4;
  554   }
  555 
  556   // Check for float reg-reg copy
  557   if (src_first_rc == rc_float && dst_first_rc == rc_float) {
  558     if (src_second_rc != rc_bad) {
  559       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");
  560       if (cbuf) {
  561       __ mov_double(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
  562 #ifndef PRODUCT
  563       } else if (!do_size) {
  564         st->print(MOV_DOUBLE "    R_%s, R_%s\t# spill",
  565                   Matcher::regName[dst_first],
  566                   Matcher::regName[src_first]);
  567 #endif
  568       }
  569       return 4;
  570     }
  571     if (cbuf) {
  572       __ mov_float(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
  573 #ifndef PRODUCT
  574     } else if (!do_size) {
  575       st->print(MOV_FLOAT "    R_%s, R_%s\t# spill",
  576                 Matcher::regName[dst_first],
  577                 Matcher::regName[src_first]);
  578 #endif
  579     }
  580     size = 4;
  581   }
  582 
  583   // Check for float store
  584   if (src_first_rc == rc_float && dst_first_rc == rc_stack) {
  585     int offset = ra_->reg2offset(dst_first);
  586     if (cbuf && !is_memoryfp(offset)) {
  587       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  588       return 0;
  589     } else {
  590       // Further check for aligned-adjacent pair, so we can use a double store
  591       if (src_second_rc != rc_bad) {
  592         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");
  593         if (cbuf) {
  594           __ str_double(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  595 #ifndef PRODUCT
  596         } else if (!do_size) {
  597           if (size != 0) st->print("\n\t");
  598           st->print(STR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  599 #endif
  600         }
  601         return size + 4;
  602       } else {
  603         if (cbuf) {
  604           __ str_float(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  605 #ifndef PRODUCT
  606         } else if (!do_size) {
  607           if (size != 0) st->print("\n\t");
  608           st->print(STR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  609 #endif
  610         }
  611       }
  612     }
  613     size += 4;
  614   }
  615 
  616   // Check for float load
  617   if (dst_first_rc == rc_float && src_first_rc == rc_stack) {
  618     int offset = ra_->reg2offset(src_first);
  619     if (cbuf && !is_memoryfp(offset)) {
  620       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  621       return 0;
  622     } else {
  623       // Further check for aligned-adjacent pair, so we can use a double store
  624       if (src_second_rc != rc_bad) {
  625         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");
  626         if (cbuf) {
  627           __ ldr_double(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  628 #ifndef PRODUCT
  629         } else if (!do_size) {
  630           if (size != 0) st->print("\n\t");
  631           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
  632 #endif
  633         }
  634         return size + 4;
  635       } else {
  636         if (cbuf) {
  637           __ ldr_float(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  638 #ifndef PRODUCT
  639         } else if (!do_size) {
  640           if (size != 0) st->print("\n\t");
  641           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
  642 #endif
  643         }
  644       }
  645     }
  646     size += 4;
  647   }
  648 
  649   // check for int reg -> float reg move
  650   if (src_first_rc == rc_int && dst_first_rc == rc_float) {
  651     // Further check for aligned-adjacent pair, so we can use a single instruction
  652     if (src_second_rc != rc_bad) {
  653       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
  654       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
  655       assert(src_second_rc == rc_int && dst_second_rc == rc_float, "unsupported");
  656       if (cbuf) {
  657         __ 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]));
  658 #ifndef PRODUCT
  659       } else if (!do_size) {
  660         if (size != 0) st->print("\n\t");
  661         st->print("FMDRR   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first), OptoReg::regname(src_second));
  662 #endif
  663       }
  664       return size + 4;
  665     } else {
  666       if (cbuf) {
  667         __ fmsr(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
  668 #ifndef PRODUCT
  669       } else if (!do_size) {
  670         if (size != 0) st->print("\n\t");
  671         st->print(FMSR "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
  672 #endif
  673       }
  674       size += 4;
  675     }
  676   }
  677 
  678   // check for float reg -> int reg move
  679   if (src_first_rc == rc_float && dst_first_rc == rc_int) {
  680     // Further check for aligned-adjacent pair, so we can use a single instruction
  681     if (src_second_rc != rc_bad) {
  682       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
  683       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
  684       assert(src_second_rc == rc_float && dst_second_rc == rc_int, "unsupported");
  685       if (cbuf) {
  686         __ 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]));
  687 #ifndef PRODUCT
  688       } else if (!do_size) {
  689         if (size != 0) st->print("\n\t");
  690         st->print("FMRRD   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(dst_second), OptoReg::regname(src_first));
  691 #endif
  692       }
  693       return size + 4;
  694     } else {
  695       if (cbuf) {
  696         __ fmrs(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
  697 #ifndef PRODUCT
  698       } else if (!do_size) {
  699         if (size != 0) st->print("\n\t");
  700         st->print(FMRS "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
  701 #endif
  702       }
  703       size += 4;
  704     }
  705   }
  706 
  707   // --------------------------------------------------------------------
  708   // Check for hi bits still needing moving.  Only happens for misaligned
  709   // arguments to native calls.
  710   if (src_second == dst_second)
  711     return size;               // Self copy; no move
  712   assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" );
  713 
  714   // Check for integer reg-reg copy.  Hi bits are stuck up in the top
  715   // 32-bits of a 64-bit register, but are needed in low bits of another
  716   // register (else it's a hi-bits-to-hi-bits copy which should have
  717   // happened already as part of a 64-bit move)
  718   if (src_second_rc == rc_int && dst_second_rc == rc_int) {
  719     if (cbuf) {
  720       __ mov(reg_to_register_object(Matcher::_regEncode[dst_second]), reg_to_register_object(Matcher::_regEncode[src_second]));
  721 #ifndef PRODUCT
  722     } else if (!do_size) {
  723       if (size != 0) st->print("\n\t");
  724       st->print("MOV    R_%s, R_%s\t# spill high",
  725                 Matcher::regName[dst_second],
  726                 Matcher::regName[src_second]);
  727 #endif
  728     }
  729     return size+4;
  730   }
  731 
  732   // Check for high word integer store
  733   if (src_second_rc == rc_int && dst_second_rc == rc_stack) {
  734     int offset = ra_->reg2offset(dst_second);
  735 
  736     if (cbuf && !is_memoryP(offset)) {
  737       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  738       return 0;
  739     } else {
  740       if (cbuf) {
  741         __ str(reg_to_register_object(Matcher::_regEncode[src_second]), Address(SP, offset));
  742 #ifndef PRODUCT
  743       } else if (!do_size) {
  744         if (size != 0) st->print("\n\t");
  745         st->print("STR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_second), offset);
  746 #endif
  747       }
  748     }
  749     return size + 4;
  750   }
  751 
  752   // Check for high word integer load
  753   if (dst_second_rc == rc_int && src_second_rc == rc_stack) {
  754     int offset = ra_->reg2offset(src_second);
  755     if (cbuf && !is_memoryP(offset)) {
  756       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  757       return 0;
  758     } else {
  759       if (cbuf) {
  760         __ ldr(reg_to_register_object(Matcher::_regEncode[dst_second]), Address(SP, offset));
  761 #ifndef PRODUCT
  762       } else if (!do_size) {
  763         if (size != 0) st->print("\n\t");
  764         st->print("LDR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_second), offset);
  765 #endif
  766       }
  767     }
  768     return size + 4;
  769   }
  770 
  771   Unimplemented();
  772   return 0; // Mute compiler
  773 }
  774 
  775 #ifndef PRODUCT
  776 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  777   implementation( NULL, ra_, false, st );
  778 }
  779 #endif
  780 
  781 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  782   implementation( &cbuf, ra_, false, NULL );
  783 }
  784 
  785 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
  786   return implementation( NULL, ra_, true, NULL );
  787 }
  788 
  789 //=============================================================================
  790 #ifndef PRODUCT
  791 void MachNopNode::format( PhaseRegAlloc *, outputStream *st ) const {
  792   st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
  793 }
  794 #endif
  795 
  796 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
  797   C2_MacroAssembler _masm(&cbuf);
  798   for(int i = 0; i < _count; i += 1) {
  799     __ nop();
  800   }
  801 }
  802 
  803 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
  804   return 4 * _count;
  805 }
  806 
  807 
  808 //=============================================================================
  809 #ifndef PRODUCT
  810 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  811   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  812   int reg = ra_->get_reg_first(this);
  813   st->print("ADD    %s,R_SP+#%d",Matcher::regName[reg], offset);
  814 }
  815 #endif
  816 
  817 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  818   C2_MacroAssembler _masm(&cbuf);
  819   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  820   int reg = ra_->get_encode(this);
  821   Register dst = reg_to_register_object(reg);
  822 
  823   if (is_aimm(offset)) {
  824     __ add(dst, SP, offset);
  825   } else {
  826     __ mov_slow(dst, offset);
  827     __ add(dst, SP, dst);
  828   }
  829 }
  830 
  831 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
  832   // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_)
  833   assert(ra_ == ra_->C->regalloc(), "sanity");
  834   return ra_->C->output()->scratch_emit_size(this);
  835 }
  836 
  837 //=============================================================================
  838 #ifndef PRODUCT
  839 #define R_RTEMP "R_R12"
  840 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  841   st->print_cr("\nUEP:");
  842   if (UseCompressedClassPointers) {
  843     st->print_cr("\tLDR_w " R_RTEMP ",[R_R0 + oopDesc::klass_offset_in_bytes]\t! Inline cache check");
  844     st->print_cr("\tdecode_klass " R_RTEMP);
  845   } else {
  846     st->print_cr("\tLDR   " R_RTEMP ",[R_R0 + oopDesc::klass_offset_in_bytes]\t! Inline cache check");
  847   }
  848   st->print_cr("\tCMP   " R_RTEMP ",R_R8" );
  849   st->print   ("\tB.NE  SharedRuntime::handle_ic_miss_stub");
  850 }
  851 #endif
  852 
  853 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  854   C2_MacroAssembler _masm(&cbuf);
  855   Register iCache  = reg_to_register_object(Matcher::inline_cache_reg_encode());
  856   assert(iCache == Ricklass, "should be");
  857   Register receiver = R0;
  858 
  859   __ load_klass(Rtemp, receiver);
  860   __ cmp(Rtemp, iCache);
  861   __ jump(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type, noreg, ne);
  862 }
  863 
  864 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
  865   return MachNode::size(ra_);
  866 }
  867 
  868 
  869 //=============================================================================
  870 
  871 // Emit exception handler code.
  872 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) {
  873   C2_MacroAssembler _masm(&cbuf);
  874 
  875   address base = __ start_a_stub(size_exception_handler());
  876   if (base == NULL) {
  877     ciEnv::current()->record_failure("CodeCache is full");
  878     return 0;  // CodeBuffer::expand failed
  879   }
  880 
  881   int offset = __ offset();
  882 
  883   // OK to trash LR, because exception blob will kill it
  884   __ jump(OptoRuntime::exception_blob()->entry_point(), relocInfo::runtime_call_type, LR_tmp);
  885 
  886   assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
  887 
  888   __ end_a_stub();
  889 
  890   return offset;
  891 }
  892 
  893 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
  894   // Can't use any of the current frame's registers as we may have deopted
  895   // at a poll and everything can be live.
  896   C2_MacroAssembler _masm(&cbuf);
  897 
  898   address base = __ start_a_stub(size_deopt_handler());
  899   if (base == NULL) {
  900     ciEnv::current()->record_failure("CodeCache is full");
  901     return 0;  // CodeBuffer::expand failed
  902   }
  903 
  904   int offset = __ offset();
  905   address deopt_pc = __ pc();
  906 
  907   __ sub(SP, SP, wordSize); // make room for saved PC
  908   __ push(LR); // save LR that may be live when we get here
  909   __ mov_relative_address(LR, deopt_pc);
  910   __ str(LR, Address(SP, wordSize)); // save deopt PC
  911   __ pop(LR); // restore LR
  912   __ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, noreg);
  913 
  914   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
  915 
  916   __ end_a_stub();
  917   return offset;
  918 }
  919 
  920 const bool Matcher::match_rule_supported(int opcode) {
  921   if (!has_match_rule(opcode))
  922     return false;
  923 
  924   switch (opcode) {
  925   case Op_PopCountI:
  926   case Op_PopCountL:
  927     if (!UsePopCountInstruction)
  928       return false;
  929     break;
  930   case Op_LShiftCntV:
  931   case Op_RShiftCntV:
  932   case Op_AddVB:
  933   case Op_AddVS:
  934   case Op_AddVI:
  935   case Op_AddVL:
  936   case Op_SubVB:
  937   case Op_SubVS:
  938   case Op_SubVI:
  939   case Op_SubVL:
  940   case Op_MulVS:
  941   case Op_MulVI:
  942   case Op_LShiftVB:
  943   case Op_LShiftVS:
  944   case Op_LShiftVI:
  945   case Op_LShiftVL:
  946   case Op_RShiftVB:
  947   case Op_RShiftVS:
  948   case Op_RShiftVI:
  949   case Op_RShiftVL:
  950   case Op_URShiftVB:
  951   case Op_URShiftVS:
  952   case Op_URShiftVI:
  953   case Op_URShiftVL:
  954   case Op_AndV:
  955   case Op_OrV:
  956   case Op_XorV:
  957     return VM_Version::has_simd();
  958   case Op_LoadVector:
  959   case Op_StoreVector:
  960   case Op_AddVF:
  961   case Op_SubVF:
  962   case Op_MulVF:
  963     return VM_Version::has_vfp() || VM_Version::has_simd();
  964   case Op_AddVD:
  965   case Op_SubVD:
  966   case Op_MulVD:
  967   case Op_DivVF:
  968   case Op_DivVD:
  969     return VM_Version::has_vfp();
  970   }
  971 
  972   return true;  // Per default match rules are supported.
  973 }
  974 
  975 const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
  976 
  977   // TODO
  978   // identify extra cases that we might want to provide match rules for
  979   // e.g. Op_ vector nodes and other intrinsics while guarding with vlen
  980   bool ret_value = match_rule_supported(opcode) && vector_size_supported(bt, vlen);
  981   // Add rules here.
  982 
  983   return ret_value;  // Per default match rules are supported.
  984 }
  985 
  986 const bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType bt) {
  987   return false;
  988 }
  989 
  990 const RegMask* Matcher::predicate_reg_mask(void) {
  991   return NULL;
  992 }
  993 
  994 const TypeVect* Matcher::predicate_reg_type(const Type* elemTy, int length) {
  995   return NULL;
  996 }
  997 
  998 // Vector calling convention not yet implemented.
  999 const bool Matcher::supports_vector_calling_convention(void) {
 1000   return false;
 1001 }
 1002 
 1003 OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
 1004   Unimplemented();
 1005   return OptoRegPair(0, 0);
 1006 }
 1007 
 1008 // Vector width in bytes
 1009 const int Matcher::vector_width_in_bytes(BasicType bt) {
 1010   return MaxVectorSize;
 1011 }
 1012 
 1013 const int Matcher::scalable_vector_reg_size(const BasicType bt) {
 1014   return -1;
 1015 }
 1016 
 1017 // Vector ideal reg corresponding to specified size in bytes
 1018 const uint Matcher::vector_ideal_reg(int size) {
 1019   assert(MaxVectorSize >= size, "");
 1020   switch(size) {
 1021     case  8: return Op_VecD;
 1022     case 16: return Op_VecX;
 1023   }
 1024   ShouldNotReachHere();
 1025   return 0;
 1026 }
 1027 
 1028 // Limits on vector size (number of elements) loaded into vector.
 1029 const int Matcher::max_vector_size(const BasicType bt) {
 1030   assert(is_java_primitive(bt), "only primitive type vectors");
 1031   return vector_width_in_bytes(bt)/type2aelembytes(bt);
 1032 }
 1033 
 1034 const int Matcher::min_vector_size(const BasicType bt) {
 1035   assert(is_java_primitive(bt), "only primitive type vectors");
 1036   return 8/type2aelembytes(bt);
 1037 }
 1038 
 1039 // Is this branch offset short enough that a short branch can be used?
 1040 //
 1041 // NOTE: If the platform does not provide any short branch variants, then
 1042 //       this method should return false for offset 0.
 1043 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
 1044   // The passed offset is relative to address of the branch.
 1045   // On ARM a branch displacement is calculated relative to address
 1046   // of the branch + 8.
 1047   //
 1048   // offset -= 8;
 1049   // return (Assembler::is_simm24(offset));
 1050   return false;
 1051 }
 1052 
 1053 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) {
 1054   ShouldNotReachHere(); // generic vector operands not supported
 1055   return NULL;
 1056 }
 1057 
 1058 bool Matcher::is_reg2reg_move(MachNode* m) {
 1059   ShouldNotReachHere();  // generic vector operands not supported
 1060   return false;
 1061 }
 1062 
 1063 bool Matcher::is_generic_vector(MachOper* opnd)  {
 1064   ShouldNotReachHere();  // generic vector operands not supported
 1065   return false;
 1066 }
 1067 
 1068 // Should the matcher clone input 'm' of node 'n'?
 1069 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
 1070   if (is_vshift_con_pattern(n, m)) { // ShiftV src (ShiftCntV con)
 1071     mstack.push(m, Visit);           // m = ShiftCntV
 1072     return true;
 1073   }
 1074   return false;
 1075 }
 1076 
 1077 // Should the Matcher clone shifts on addressing modes, expecting them
 1078 // to be subsumed into complex addressing expressions or compute them
 1079 // into registers?
 1080 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
 1081   return clone_base_plus_offset_address(m, mstack, address_visited);
 1082 }
 1083 
 1084 // Return whether or not this register is ever used as an argument.  This
 1085 // function is used on startup to build the trampoline stubs in generateOptoStub.
 1086 // Registers not mentioned will be killed by the VM call in the trampoline, and
 1087 // arguments in those registers not be available to the callee.
 1088 bool Matcher::can_be_java_arg( int reg ) {
 1089   if (reg == R_R0_num ||
 1090       reg == R_R1_num ||
 1091       reg == R_R2_num ||
 1092       reg == R_R3_num) return true;
 1093 
 1094   if (reg >= R_S0_num &&
 1095       reg <= R_S13_num) return true;
 1096   return false;
 1097 }
 1098 
 1099 bool Matcher::is_spillable_arg( int reg ) {
 1100   return can_be_java_arg(reg);
 1101 }
 1102 
 1103 uint Matcher::int_pressure_limit()
 1104 {
 1105   return (INTPRESSURE == -1) ? 12 : INTPRESSURE;
 1106 }
 1107 
 1108 uint Matcher::float_pressure_limit()
 1109 {
 1110   return (FLOATPRESSURE == -1) ? 30 : FLOATPRESSURE;
 1111 }
 1112 
 1113 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
 1114   return false;
 1115 }
 1116 
 1117 // Register for DIVI projection of divmodI
 1118 RegMask Matcher::divI_proj_mask() {
 1119   ShouldNotReachHere();
 1120   return RegMask();
 1121 }
 1122 
 1123 // Register for MODI projection of divmodI
 1124 RegMask Matcher::modI_proj_mask() {
 1125   ShouldNotReachHere();
 1126   return RegMask();
 1127 }
 1128 
 1129 // Register for DIVL projection of divmodL
 1130 RegMask Matcher::divL_proj_mask() {
 1131   ShouldNotReachHere();
 1132   return RegMask();
 1133 }
 1134 
 1135 // Register for MODL projection of divmodL
 1136 RegMask Matcher::modL_proj_mask() {
 1137   ShouldNotReachHere();
 1138   return RegMask();
 1139 }
 1140 
 1141 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
 1142   return FP_REGP_mask();
 1143 }
 1144 
 1145 bool maybe_far_call(const CallNode *n) {
 1146   return !MacroAssembler::_reachable_from_cache(n->as_Call()->entry_point());
 1147 }
 1148 
 1149 bool maybe_far_call(const MachCallNode *n) {
 1150   return !MacroAssembler::_reachable_from_cache(n->as_MachCall()->entry_point());
 1151 }
 1152 
 1153 %}
 1154 
 1155 //----------ENCODING BLOCK-----------------------------------------------------
 1156 // This block specifies the encoding classes used by the compiler to output
 1157 // byte streams.  Encoding classes are parameterized macros used by
 1158 // Machine Instruction Nodes in order to generate the bit encoding of the
 1159 // instruction.  Operands specify their base encoding interface with the
 1160 // interface keyword.  There are currently supported four interfaces,
 1161 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
 1162 // operand to generate a function which returns its register number when
 1163 // queried.   CONST_INTER causes an operand to generate a function which
 1164 // returns the value of the constant when queried.  MEMORY_INTER causes an
 1165 // operand to generate four functions which return the Base Register, the
 1166 // Index Register, the Scale Value, and the Offset Value of the operand when
 1167 // queried.  COND_INTER causes an operand to generate six functions which
 1168 // return the encoding code (ie - encoding bits for the instruction)
 1169 // associated with each basic boolean condition for a conditional instruction.
 1170 //
 1171 // Instructions specify two basic values for encoding.  Again, a function
 1172 // is available to check if the constant displacement is an oop. They use the
 1173 // ins_encode keyword to specify their encoding classes (which must be
 1174 // a sequence of enc_class names, and their parameters, specified in
 1175 // the encoding block), and they use the
 1176 // opcode keyword to specify, in order, their primary, secondary, and
 1177 // tertiary opcode.  Only the opcode sections which a particular instruction
 1178 // needs for encoding need to be specified.
 1179 encode %{
 1180   enc_class call_epilog %{
 1181     // nothing
 1182   %}
 1183 
 1184   enc_class Java_To_Runtime (method meth) %{
 1185     // CALL directly to the runtime
 1186     emit_call_reloc(cbuf, as_MachCall(), $meth, runtime_call_Relocation::spec());
 1187   %}
 1188 
 1189   enc_class Java_Static_Call (method meth) %{
 1190     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
 1191     // who we intended to call.
 1192 
 1193     if ( !_method) {
 1194       emit_call_reloc(cbuf, as_MachCall(), $meth, runtime_call_Relocation::spec());
 1195     } else {
 1196       int method_index = resolved_method_index(cbuf);
 1197       RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
 1198                                                   : static_call_Relocation::spec(method_index);
 1199       emit_call_reloc(cbuf, as_MachCall(), $meth, rspec);
 1200 
 1201       // Emit stubs for static call.
 1202       address stub = CompiledStaticCall::emit_to_interp_stub(cbuf);
 1203       if (stub == NULL) {
 1204         ciEnv::current()->record_failure("CodeCache is full");
 1205         return;
 1206       }
 1207     }
 1208   %}
 1209 
 1210   enc_class save_last_PC %{
 1211     // preserve mark
 1212     address mark = cbuf.insts()->mark();
 1213     debug_only(int off0 = cbuf.insts_size());
 1214     C2_MacroAssembler _masm(&cbuf);
 1215     int ret_addr_offset = as_MachCall()->ret_addr_offset();
 1216     __ adr(LR, mark + ret_addr_offset);
 1217     __ str(LR, Address(Rthread, JavaThread::last_Java_pc_offset()));
 1218     debug_only(int off1 = cbuf.insts_size());
 1219     assert(off1 - off0 == 2 * Assembler::InstructionSize, "correct size prediction");
 1220     // restore mark
 1221     cbuf.insts()->set_mark(mark);
 1222   %}
 1223 
 1224   enc_class preserve_SP %{
 1225     // preserve mark
 1226     address mark = cbuf.insts()->mark();
 1227     debug_only(int off0 = cbuf.insts_size());
 1228     C2_MacroAssembler _masm(&cbuf);
 1229     // FP is preserved across all calls, even compiled calls.
 1230     // Use it to preserve SP in places where the callee might change the SP.
 1231     __ mov(Rmh_SP_save, SP);
 1232     debug_only(int off1 = cbuf.insts_size());
 1233     assert(off1 - off0 == 4, "correct size prediction");
 1234     // restore mark
 1235     cbuf.insts()->set_mark(mark);
 1236   %}
 1237 
 1238   enc_class restore_SP %{
 1239     C2_MacroAssembler _masm(&cbuf);
 1240     __ mov(SP, Rmh_SP_save);
 1241   %}
 1242 
 1243   enc_class Java_Dynamic_Call (method meth) %{
 1244     C2_MacroAssembler _masm(&cbuf);
 1245     Register R8_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode());
 1246     assert(R8_ic_reg == Ricklass, "should be");
 1247     __ set_inst_mark();
 1248     __ movw(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) & 0xffff);
 1249     __ movt(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) >> 16);
 1250     address  virtual_call_oop_addr = __ inst_mark();
 1251     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
 1252     // who we intended to call.
 1253     int method_index = resolved_method_index(cbuf);
 1254     __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index));
 1255     emit_call_reloc(cbuf, as_MachCall(), $meth, RelocationHolder::none);
 1256   %}
 1257 
 1258   enc_class LdReplImmI(immI src, regD dst, iRegI tmp, int cnt, int wth) %{
 1259     // FIXME: load from constant table?
 1260     // Load a constant replicated "count" times with width "width"
 1261     int count = $cnt$$constant;
 1262     int width = $wth$$constant;
 1263     assert(count*width == 4, "sanity");
 1264     int val = $src$$constant;
 1265     if (width < 4) {
 1266       int bit_width = width * 8;
 1267       val &= (((int)1) << bit_width) - 1; // mask off sign bits
 1268       for (int i = 0; i < count - 1; i++) {
 1269         val |= (val << bit_width);
 1270       }
 1271     }
 1272     C2_MacroAssembler _masm(&cbuf);
 1273 
 1274     if (val == -1) {
 1275       __ mvn($tmp$$Register, 0);
 1276     } else if (val == 0) {
 1277       __ mov($tmp$$Register, 0);
 1278     } else {
 1279       __ movw($tmp$$Register, val & 0xffff);
 1280       __ movt($tmp$$Register, (unsigned int)val >> 16);
 1281     }
 1282     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 1283   %}
 1284 
 1285   enc_class LdReplImmF(immF src, regD dst, iRegI tmp) %{
 1286     // Replicate float con 2 times and pack into vector (8 bytes) in regD.
 1287     float fval = $src$$constant;
 1288     int val = *((int*)&fval);
 1289     C2_MacroAssembler _masm(&cbuf);
 1290 
 1291     if (val == -1) {
 1292       __ mvn($tmp$$Register, 0);
 1293     } else if (val == 0) {
 1294       __ mov($tmp$$Register, 0);
 1295     } else {
 1296       __ movw($tmp$$Register, val & 0xffff);
 1297       __ movt($tmp$$Register, (unsigned int)val >> 16);
 1298     }
 1299     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 1300   %}
 1301 
 1302   enc_class enc_String_Compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result, iRegI tmp1, iRegI tmp2) %{
 1303     Label Ldone, Lloop;
 1304     C2_MacroAssembler _masm(&cbuf);
 1305 
 1306     Register   str1_reg = $str1$$Register;
 1307     Register   str2_reg = $str2$$Register;
 1308     Register   cnt1_reg = $cnt1$$Register; // int
 1309     Register   cnt2_reg = $cnt2$$Register; // int
 1310     Register   tmp1_reg = $tmp1$$Register;
 1311     Register   tmp2_reg = $tmp2$$Register;
 1312     Register result_reg = $result$$Register;
 1313 
 1314     assert_different_registers(str1_reg, str2_reg, cnt1_reg, cnt2_reg, tmp1_reg, tmp2_reg);
 1315 
 1316     // Compute the minimum of the string lengths(str1_reg) and the
 1317     // difference of the string lengths (stack)
 1318 
 1319     // See if the lengths are different, and calculate min in str1_reg.
 1320     // Stash diff in tmp2 in case we need it for a tie-breaker.
 1321     __ subs_32(tmp2_reg, cnt1_reg, cnt2_reg);
 1322     __ mov(cnt1_reg, AsmOperand(cnt1_reg, lsl, exact_log2(sizeof(jchar)))); // scale the limit
 1323     __ mov(cnt1_reg, AsmOperand(cnt2_reg, lsl, exact_log2(sizeof(jchar))), pl); // scale the limit
 1324 
 1325     // reallocate cnt1_reg, cnt2_reg, result_reg
 1326     // Note:  limit_reg holds the string length pre-scaled by 2
 1327     Register limit_reg = cnt1_reg;
 1328     Register  chr2_reg = cnt2_reg;
 1329     Register  chr1_reg = tmp1_reg;
 1330     // str{12} are the base pointers
 1331 
 1332     // Is the minimum length zero?
 1333     __ cmp_32(limit_reg, 0);
 1334     if (result_reg != tmp2_reg) {
 1335       __ mov(result_reg, tmp2_reg, eq);
 1336     }
 1337     __ b(Ldone, eq);
 1338 
 1339     // Load first characters
 1340     __ ldrh(chr1_reg, Address(str1_reg, 0));
 1341     __ ldrh(chr2_reg, Address(str2_reg, 0));
 1342 
 1343     // Compare first characters
 1344     __ subs(chr1_reg, chr1_reg, chr2_reg);
 1345     if (result_reg != chr1_reg) {
 1346       __ mov(result_reg, chr1_reg, ne);
 1347     }
 1348     __ b(Ldone, ne);
 1349 
 1350     {
 1351       // Check after comparing first character to see if strings are equivalent
 1352       // Check if the strings start at same location
 1353       __ cmp(str1_reg, str2_reg);
 1354       // Check if the length difference is zero
 1355       __ cond_cmp(tmp2_reg, 0, eq);
 1356       __ mov(result_reg, 0, eq); // result is zero
 1357       __ b(Ldone, eq);
 1358       // Strings might not be equal
 1359     }
 1360 
 1361     __ subs(chr1_reg, limit_reg, 1 * sizeof(jchar));
 1362     if (result_reg != tmp2_reg) {
 1363       __ mov(result_reg, tmp2_reg, eq);
 1364     }
 1365     __ b(Ldone, eq);
 1366 
 1367     // Shift str1_reg and str2_reg to the end of the arrays, negate limit
 1368     __ add(str1_reg, str1_reg, limit_reg);
 1369     __ add(str2_reg, str2_reg, limit_reg);
 1370     __ neg(limit_reg, chr1_reg);  // limit = -(limit-2)
 1371 
 1372     // Compare the rest of the characters
 1373     __ bind(Lloop);
 1374     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
 1375     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
 1376     __ subs(chr1_reg, chr1_reg, chr2_reg);
 1377     if (result_reg != chr1_reg) {
 1378       __ mov(result_reg, chr1_reg, ne);
 1379     }
 1380     __ b(Ldone, ne);
 1381 
 1382     __ adds(limit_reg, limit_reg, sizeof(jchar));
 1383     __ b(Lloop, ne);
 1384 
 1385     // If strings are equal up to min length, return the length difference.
 1386     if (result_reg != tmp2_reg) {
 1387       __ mov(result_reg, tmp2_reg);
 1388     }
 1389 
 1390     // Otherwise, return the difference between the first mismatched chars.
 1391     __ bind(Ldone);
 1392   %}
 1393 
 1394   enc_class enc_String_Equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2) %{
 1395     Label Lchar, Lchar_loop, Ldone, Lequal;
 1396     C2_MacroAssembler _masm(&cbuf);
 1397 
 1398     Register   str1_reg = $str1$$Register;
 1399     Register   str2_reg = $str2$$Register;
 1400     Register    cnt_reg = $cnt$$Register; // int
 1401     Register   tmp1_reg = $tmp1$$Register;
 1402     Register   tmp2_reg = $tmp2$$Register;
 1403     Register result_reg = $result$$Register;
 1404 
 1405     assert_different_registers(str1_reg, str2_reg, cnt_reg, tmp1_reg, tmp2_reg, result_reg);
 1406 
 1407     __ cmp(str1_reg, str2_reg); //same char[] ?
 1408     __ b(Lequal, eq);
 1409 
 1410     __ cbz_32(cnt_reg, Lequal); // count == 0
 1411 
 1412     //rename registers
 1413     Register limit_reg = cnt_reg;
 1414     Register  chr1_reg = tmp1_reg;
 1415     Register  chr2_reg = tmp2_reg;
 1416 
 1417     __ logical_shift_left(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
 1418 
 1419     //check for alignment and position the pointers to the ends
 1420     __ orr(chr1_reg, str1_reg, str2_reg);
 1421     __ tst(chr1_reg, 0x3);
 1422 
 1423     // notZero means at least one not 4-byte aligned.
 1424     // We could optimize the case when both arrays are not aligned
 1425     // but it is not frequent case and it requires additional checks.
 1426     __ b(Lchar, ne);
 1427 
 1428     // Compare char[] arrays aligned to 4 bytes.
 1429     __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg,
 1430                           chr1_reg, chr2_reg, Ldone);
 1431 
 1432     __ b(Lequal); // equal
 1433 
 1434     // char by char compare
 1435     __ bind(Lchar);
 1436     __ mov(result_reg, 0);
 1437     __ add(str1_reg, limit_reg, str1_reg);
 1438     __ add(str2_reg, limit_reg, str2_reg);
 1439     __ neg(limit_reg, limit_reg); //negate count
 1440 
 1441     // Lchar_loop
 1442     __ bind(Lchar_loop);
 1443     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
 1444     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
 1445     __ cmp(chr1_reg, chr2_reg);
 1446     __ b(Ldone, ne);
 1447     __ adds(limit_reg, limit_reg, sizeof(jchar));
 1448     __ b(Lchar_loop, ne);
 1449 
 1450     __ bind(Lequal);
 1451     __ mov(result_reg, 1);  //equal
 1452 
 1453     __ bind(Ldone);
 1454   %}
 1455 
 1456   enc_class enc_Array_Equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result) %{
 1457     Label Ldone, Lloop, Lequal;
 1458     C2_MacroAssembler _masm(&cbuf);
 1459 
 1460     Register   ary1_reg = $ary1$$Register;
 1461     Register   ary2_reg = $ary2$$Register;
 1462     Register   tmp1_reg = $tmp1$$Register;
 1463     Register   tmp2_reg = $tmp2$$Register;
 1464     Register   tmp3_reg = $tmp3$$Register;
 1465     Register result_reg = $result$$Register;
 1466 
 1467     assert_different_registers(ary1_reg, ary2_reg, tmp1_reg, tmp2_reg, tmp3_reg, result_reg);
 1468 
 1469     int length_offset  = arrayOopDesc::length_offset_in_bytes();
 1470     int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
 1471 
 1472     // return true if the same array
 1473     __ teq(ary1_reg, ary2_reg);
 1474     __ mov(result_reg, 1, eq);
 1475     __ b(Ldone, eq); // equal
 1476 
 1477     __ tst(ary1_reg, ary1_reg);
 1478     __ mov(result_reg, 0, eq);
 1479     __ b(Ldone, eq);    // not equal
 1480 
 1481     __ tst(ary2_reg, ary2_reg);
 1482     __ mov(result_reg, 0, eq);
 1483     __ b(Ldone, eq);    // not equal
 1484 
 1485     //load the lengths of arrays
 1486     __ ldr_s32(tmp1_reg, Address(ary1_reg, length_offset)); // int
 1487     __ ldr_s32(tmp2_reg, Address(ary2_reg, length_offset)); // int
 1488 
 1489     // return false if the two arrays are not equal length
 1490     __ teq_32(tmp1_reg, tmp2_reg);
 1491     __ mov(result_reg, 0, ne);
 1492     __ b(Ldone, ne);    // not equal
 1493 
 1494     __ tst(tmp1_reg, tmp1_reg);
 1495     __ mov(result_reg, 1, eq);
 1496     __ b(Ldone, eq);    // zero-length arrays are equal
 1497 
 1498     // load array addresses
 1499     __ add(ary1_reg, ary1_reg, base_offset);
 1500     __ add(ary2_reg, ary2_reg, base_offset);
 1501 
 1502     // renaming registers
 1503     Register chr1_reg  =  tmp3_reg;   // for characters in ary1
 1504     Register chr2_reg  =  tmp2_reg;   // for characters in ary2
 1505     Register limit_reg =  tmp1_reg;   // length
 1506 
 1507     // set byte count
 1508     __ logical_shift_left_32(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
 1509 
 1510     // Compare char[] arrays aligned to 4 bytes.
 1511     __ char_arrays_equals(ary1_reg, ary2_reg, limit_reg, result_reg,
 1512                           chr1_reg, chr2_reg, Ldone);
 1513     __ bind(Lequal);
 1514     __ mov(result_reg, 1);  //equal
 1515 
 1516     __ bind(Ldone);
 1517     %}
 1518 %}
 1519 
 1520 //----------FRAME--------------------------------------------------------------
 1521 // Definition of frame structure and management information.
 1522 //
 1523 //  S T A C K   L A Y O U T    Allocators stack-slot number
 1524 //                             |   (to get allocators register number
 1525 //  G  Owned by    |        |  v    add VMRegImpl::stack0)
 1526 //  r   CALLER     |        |
 1527 //  o     |        +--------+      pad to even-align allocators stack-slot
 1528 //  w     V        |  pad0  |        numbers; owned by CALLER
 1529 //  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
 1530 //  h     ^        |   in   |  5
 1531 //        |        |  args  |  4   Holes in incoming args owned by SELF
 1532 //  |     |        |        |  3
 1533 //  |     |        +--------+
 1534 //  V     |        | old out|      Empty on Intel, window on Sparc
 1535 //        |    old |preserve|      Must be even aligned.
 1536 //        |     SP-+--------+----> Matcher::_old_SP, 8 (or 16 in LP64)-byte aligned
 1537 //        |        |   in   |  3   area for Intel ret address
 1538 //     Owned by    |preserve|      Empty on Sparc.
 1539 //       SELF      +--------+
 1540 //        |        |  pad2  |  2   pad to align old SP
 1541 //        |        +--------+  1
 1542 //        |        | locks  |  0
 1543 //        |        +--------+----> VMRegImpl::stack0, 8 (or 16 in LP64)-byte aligned
 1544 //        |        |  pad1  | 11   pad to align new SP
 1545 //        |        +--------+
 1546 //        |        |        | 10
 1547 //        |        | spills |  9   spills
 1548 //        V        |        |  8   (pad0 slot for callee)
 1549 //      -----------+--------+----> Matcher::_out_arg_limit, unaligned
 1550 //        ^        |  out   |  7
 1551 //        |        |  args  |  6   Holes in outgoing args owned by CALLEE
 1552 //     Owned by    +--------+
 1553 //      CALLEE     | new out|  6   Empty on Intel, window on Sparc
 1554 //        |    new |preserve|      Must be even-aligned.
 1555 //        |     SP-+--------+----> Matcher::_new_SP, even aligned
 1556 //        |        |        |
 1557 //
 1558 // Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
 1559 //         known from SELF's arguments and the Java calling convention.
 1560 //         Region 6-7 is determined per call site.
 1561 // Note 2: If the calling convention leaves holes in the incoming argument
 1562 //         area, those holes are owned by SELF.  Holes in the outgoing area
 1563 //         are owned by the CALLEE.  Holes should not be nessecary in the
 1564 //         incoming area, as the Java calling convention is completely under
 1565 //         the control of the AD file.  Doubles can be sorted and packed to
 1566 //         avoid holes.  Holes in the outgoing arguments may be nessecary for
 1567 //         varargs C calling conventions.
 1568 // Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
 1569 //         even aligned with pad0 as needed.
 1570 //         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
 1571 //         region 6-11 is even aligned; it may be padded out more so that
 1572 //         the region from SP to FP meets the minimum stack alignment.
 1573 
 1574 frame %{
 1575   // These two registers define part of the calling convention
 1576   // between compiled code and the interpreter.
 1577   inline_cache_reg(R_Ricklass);          // Inline Cache Register or Method* for I2C
 1578 
 1579   // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
 1580   cisc_spilling_operand_name(indOffset);
 1581 
 1582   // Number of stack slots consumed by a Monitor enter
 1583   sync_stack_slots(1 * VMRegImpl::slots_per_word);
 1584 
 1585   // Compiled code's Frame Pointer
 1586   frame_pointer(R_R13);
 1587 
 1588   // Stack alignment requirement
 1589   stack_alignment(StackAlignmentInBytes);
 1590   //  LP64: Alignment size in bytes (128-bit -> 16 bytes)
 1591   // !LP64: Alignment size in bytes (64-bit  ->  8 bytes)
 1592 
 1593   // Number of outgoing stack slots killed above the out_preserve_stack_slots
 1594   // for calls to C.  Supports the var-args backing area for register parms.
 1595   // ADLC doesn't support parsing expressions, so I folded the math by hand.
 1596   varargs_C_out_slots_killed( 0);
 1597 
 1598   // The after-PROLOG location of the return address.  Location of
 1599   // return address specifies a type (REG or STACK) and a number
 1600   // representing the register number (i.e. - use a register name) or
 1601   // stack slot.
 1602   // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
 1603   // Otherwise, it is above the locks and verification slot and alignment word
 1604   return_addr(STACK - 1*VMRegImpl::slots_per_word +
 1605               align_up((Compile::current()->in_preserve_stack_slots() +
 1606                         Compile::current()->fixed_slots()),
 1607                        stack_alignment_in_slots()));
 1608 
 1609   // Location of compiled Java return values.  Same as C
 1610   return_value %{
 1611     return c2::return_value(ideal_reg);
 1612   %}
 1613 
 1614 %}
 1615 
 1616 //----------ATTRIBUTES---------------------------------------------------------
 1617 //----------Instruction Attributes---------------------------------------------
 1618 ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute
 1619 ins_attrib ins_size(32);           // Required size attribute (in bits)
 1620 ins_attrib ins_short_branch(0);    // Required flag: is this instruction a
 1621                                    // non-matching short branch variant of some
 1622                                                             // long branch?
 1623 
 1624 //----------OPERANDS-----------------------------------------------------------
 1625 // Operand definitions must precede instruction definitions for correct parsing
 1626 // in the ADLC because operands constitute user defined types which are used in
 1627 // instruction definitions.
 1628 
 1629 //----------Simple Operands----------------------------------------------------
 1630 // Immediate Operands
 1631 // Integer Immediate: 32-bit
 1632 operand immI() %{
 1633   match(ConI);
 1634 
 1635   op_cost(0);
 1636   // formats are generated automatically for constants and base registers
 1637   format %{ %}
 1638   interface(CONST_INTER);
 1639 %}
 1640 
 1641 // Integer Immediate: 8-bit unsigned - for VMOV
 1642 operand immU8() %{
 1643   predicate(0 <= n->get_int() && (n->get_int() <= 255));
 1644   match(ConI);
 1645   op_cost(0);
 1646 
 1647   format %{ %}
 1648   interface(CONST_INTER);
 1649 %}
 1650 
 1651 // Integer Immediate: 16-bit
 1652 operand immI16() %{
 1653   predicate((n->get_int() >> 16) == 0 && VM_Version::supports_movw());
 1654   match(ConI);
 1655   op_cost(0);
 1656 
 1657   format %{ %}
 1658   interface(CONST_INTER);
 1659 %}
 1660 
 1661 // Integer Immediate: offset for half and double word loads and stores
 1662 operand immIHD() %{
 1663   predicate(is_memoryHD(n->get_int()));
 1664   match(ConI);
 1665   op_cost(0);
 1666   format %{ %}
 1667   interface(CONST_INTER);
 1668 %}
 1669 
 1670 // Integer Immediate: offset for fp loads and stores
 1671 operand immIFP() %{
 1672   predicate(is_memoryfp(n->get_int()) && ((n->get_int() & 3) == 0));
 1673   match(ConI);
 1674   op_cost(0);
 1675 
 1676   format %{ %}
 1677   interface(CONST_INTER);
 1678 %}
 1679 
 1680 // Valid scale values for addressing modes and shifts
 1681 operand immU5() %{
 1682   predicate(0 <= n->get_int() && (n->get_int() <= 31));
 1683   match(ConI);
 1684   op_cost(0);
 1685 
 1686   format %{ %}
 1687   interface(CONST_INTER);
 1688 %}
 1689 
 1690 // Integer Immediate: 6-bit
 1691 operand immU6Big() %{
 1692   predicate(n->get_int() >= 32 && n->get_int() <= 63);
 1693   match(ConI);
 1694   op_cost(0);
 1695   format %{ %}
 1696   interface(CONST_INTER);
 1697 %}
 1698 
 1699 // Integer Immediate: 0-bit
 1700 operand immI0() %{
 1701   predicate(n->get_int() == 0);
 1702   match(ConI);
 1703   op_cost(0);
 1704 
 1705   format %{ %}
 1706   interface(CONST_INTER);
 1707 %}
 1708 
 1709 // Integer Immediate: the value 1
 1710 operand immI_1() %{
 1711   predicate(n->get_int() == 1);
 1712   match(ConI);
 1713   op_cost(0);
 1714 
 1715   format %{ %}
 1716   interface(CONST_INTER);
 1717 %}
 1718 
 1719 // Integer Immediate: the value 2
 1720 operand immI_2() %{
 1721   predicate(n->get_int() == 2);
 1722   match(ConI);
 1723   op_cost(0);
 1724 
 1725   format %{ %}
 1726   interface(CONST_INTER);
 1727 %}
 1728 
 1729 // Integer Immediate: the value 3
 1730 operand immI_3() %{
 1731   predicate(n->get_int() == 3);
 1732   match(ConI);
 1733   op_cost(0);
 1734 
 1735   format %{ %}
 1736   interface(CONST_INTER);
 1737 %}
 1738 
 1739 // Integer Immediate: the value 4
 1740 operand immI_4() %{
 1741   predicate(n->get_int() == 4);
 1742   match(ConI);
 1743   op_cost(0);
 1744 
 1745   format %{ %}
 1746   interface(CONST_INTER);
 1747 %}
 1748 
 1749 // Integer Immediate: the value 8
 1750 operand immI_8() %{
 1751   predicate(n->get_int() == 8);
 1752   match(ConI);
 1753   op_cost(0);
 1754 
 1755   format %{ %}
 1756   interface(CONST_INTER);
 1757 %}
 1758 
 1759 // Int Immediate non-negative
 1760 operand immU31()
 1761 %{
 1762   predicate(n->get_int() >= 0);
 1763   match(ConI);
 1764 
 1765   op_cost(0);
 1766   format %{ %}
 1767   interface(CONST_INTER);
 1768 %}
 1769 
 1770 // Integer Immediate: the values 32-63
 1771 operand immI_32_63() %{
 1772   predicate(n->get_int() >= 32 && n->get_int() <= 63);
 1773   match(ConI);
 1774   op_cost(0);
 1775 
 1776   format %{ %}
 1777   interface(CONST_INTER);
 1778 %}
 1779 
 1780 // Immediates for special shifts (sign extend)
 1781 
 1782 // Integer Immediate: the value 16
 1783 operand immI_16() %{
 1784   predicate(n->get_int() == 16);
 1785   match(ConI);
 1786   op_cost(0);
 1787 
 1788   format %{ %}
 1789   interface(CONST_INTER);
 1790 %}
 1791 
 1792 // Integer Immediate: the value 24
 1793 operand immI_24() %{
 1794   predicate(n->get_int() == 24);
 1795   match(ConI);
 1796   op_cost(0);
 1797 
 1798   format %{ %}
 1799   interface(CONST_INTER);
 1800 %}
 1801 
 1802 // Integer Immediate: the value 255
 1803 operand immI_255() %{
 1804   predicate( n->get_int() == 255 );
 1805   match(ConI);
 1806   op_cost(0);
 1807 
 1808   format %{ %}
 1809   interface(CONST_INTER);
 1810 %}
 1811 
 1812 // Integer Immediate: the value 65535
 1813 operand immI_65535() %{
 1814   predicate(n->get_int() == 65535);
 1815   match(ConI);
 1816   op_cost(0);
 1817 
 1818   format %{ %}
 1819   interface(CONST_INTER);
 1820 %}
 1821 
 1822 // Integer Immediates for arithmetic instructions
 1823 
 1824 operand aimmI() %{
 1825   predicate(is_aimm(n->get_int()));
 1826   match(ConI);
 1827   op_cost(0);
 1828 
 1829   format %{ %}
 1830   interface(CONST_INTER);
 1831 %}
 1832 
 1833 operand aimmIneg() %{
 1834   predicate(is_aimm(-n->get_int()));
 1835   match(ConI);
 1836   op_cost(0);
 1837 
 1838   format %{ %}
 1839   interface(CONST_INTER);
 1840 %}
 1841 
 1842 operand aimmU31() %{
 1843   predicate((0 <= n->get_int()) && is_aimm(n->get_int()));
 1844   match(ConI);
 1845   op_cost(0);
 1846 
 1847   format %{ %}
 1848   interface(CONST_INTER);
 1849 %}
 1850 
 1851 // Integer Immediates for logical instructions
 1852 
 1853 operand limmI() %{
 1854   predicate(is_limmI(n->get_int()));
 1855   match(ConI);
 1856   op_cost(0);
 1857 
 1858   format %{ %}
 1859   interface(CONST_INTER);
 1860 %}
 1861 
 1862 operand limmIlow8() %{
 1863   predicate(is_limmI_low(n->get_int(), 8));
 1864   match(ConI);
 1865   op_cost(0);
 1866 
 1867   format %{ %}
 1868   interface(CONST_INTER);
 1869 %}
 1870 
 1871 operand limmU31() %{
 1872   predicate(0 <= n->get_int() && is_limmI(n->get_int()));
 1873   match(ConI);
 1874   op_cost(0);
 1875 
 1876   format %{ %}
 1877   interface(CONST_INTER);
 1878 %}
 1879 
 1880 operand limmIn() %{
 1881   predicate(is_limmI(~n->get_int()));
 1882   match(ConI);
 1883   op_cost(0);
 1884 
 1885   format %{ %}
 1886   interface(CONST_INTER);
 1887 %}
 1888 
 1889 
 1890 // Long Immediate: the value FF
 1891 operand immL_FF() %{
 1892   predicate( n->get_long() == 0xFFL );
 1893   match(ConL);
 1894   op_cost(0);
 1895 
 1896   format %{ %}
 1897   interface(CONST_INTER);
 1898 %}
 1899 
 1900 // Long Immediate: the value FFFF
 1901 operand immL_FFFF() %{
 1902   predicate( n->get_long() == 0xFFFFL );
 1903   match(ConL);
 1904   op_cost(0);
 1905 
 1906   format %{ %}
 1907   interface(CONST_INTER);
 1908 %}
 1909 
 1910 // Pointer Immediate: 32 or 64-bit
 1911 operand immP() %{
 1912   match(ConP);
 1913 
 1914   op_cost(5);
 1915   // formats are generated automatically for constants and base registers
 1916   format %{ %}
 1917   interface(CONST_INTER);
 1918 %}
 1919 
 1920 operand immP0() %{
 1921   predicate(n->get_ptr() == 0);
 1922   match(ConP);
 1923   op_cost(0);
 1924 
 1925   format %{ %}
 1926   interface(CONST_INTER);
 1927 %}
 1928 
 1929 // Pointer Immediate
 1930 operand immN()
 1931 %{
 1932   match(ConN);
 1933 
 1934   op_cost(10);
 1935   format %{ %}
 1936   interface(CONST_INTER);
 1937 %}
 1938 
 1939 operand immNKlass()
 1940 %{
 1941   match(ConNKlass);
 1942 
 1943   op_cost(10);
 1944   format %{ %}
 1945   interface(CONST_INTER);
 1946 %}
 1947 
 1948 // NULL Pointer Immediate
 1949 operand immN0()
 1950 %{
 1951   predicate(n->get_narrowcon() == 0);
 1952   match(ConN);
 1953 
 1954   op_cost(0);
 1955   format %{ %}
 1956   interface(CONST_INTER);
 1957 %}
 1958 
 1959 operand immL() %{
 1960   match(ConL);
 1961   op_cost(40);
 1962   // formats are generated automatically for constants and base registers
 1963   format %{ %}
 1964   interface(CONST_INTER);
 1965 %}
 1966 
 1967 operand immL0() %{
 1968   predicate(n->get_long() == 0L);
 1969   match(ConL);
 1970   op_cost(0);
 1971   // formats are generated automatically for constants and base registers
 1972   format %{ %}
 1973   interface(CONST_INTER);
 1974 %}
 1975 
 1976 // Long Immediate: 16-bit
 1977 operand immL16() %{
 1978   predicate(n->get_long() >= 0 && n->get_long() < (1<<16)  && VM_Version::supports_movw());
 1979   match(ConL);
 1980   op_cost(0);
 1981 
 1982   format %{ %}
 1983   interface(CONST_INTER);
 1984 %}
 1985 
 1986 // Long Immediate: low 32-bit mask
 1987 operand immL_32bits() %{
 1988   predicate(n->get_long() == 0xFFFFFFFFL);
 1989   match(ConL);
 1990   op_cost(0);
 1991 
 1992   format %{ %}
 1993   interface(CONST_INTER);
 1994 %}
 1995 
 1996 // Double Immediate
 1997 operand immD() %{
 1998   match(ConD);
 1999 
 2000   op_cost(40);
 2001   format %{ %}
 2002   interface(CONST_INTER);
 2003 %}
 2004 
 2005 // Double Immediate: +0.0d.
 2006 operand immD0() %{
 2007   predicate(jlong_cast(n->getd()) == 0);
 2008 
 2009   match(ConD);
 2010   op_cost(0);
 2011   format %{ %}
 2012   interface(CONST_INTER);
 2013 %}
 2014 
 2015 operand imm8D() %{
 2016   predicate(Assembler::double_num(n->getd()).can_be_imm8());
 2017   match(ConD);
 2018 
 2019   op_cost(0);
 2020   format %{ %}
 2021   interface(CONST_INTER);
 2022 %}
 2023 
 2024 // Float Immediate
 2025 operand immF() %{
 2026   match(ConF);
 2027 
 2028   op_cost(20);
 2029   format %{ %}
 2030   interface(CONST_INTER);
 2031 %}
 2032 
 2033 // Float Immediate: +0.0f
 2034 operand immF0() %{
 2035   predicate(jint_cast(n->getf()) == 0);
 2036   match(ConF);
 2037 
 2038   op_cost(0);
 2039   format %{ %}
 2040   interface(CONST_INTER);
 2041 %}
 2042 
 2043 // Float Immediate: encoded as 8 bits
 2044 operand imm8F() %{
 2045   predicate(Assembler::float_num(n->getf()).can_be_imm8());
 2046   match(ConF);
 2047 
 2048   op_cost(0);
 2049   format %{ %}
 2050   interface(CONST_INTER);
 2051 %}
 2052 
 2053 // Integer Register Operands
 2054 // Integer Register
 2055 operand iRegI() %{
 2056   constraint(ALLOC_IN_RC(int_reg));
 2057   match(RegI);
 2058   match(R0RegI);
 2059   match(R1RegI);
 2060   match(R2RegI);
 2061   match(R3RegI);
 2062   match(R12RegI);
 2063 
 2064   format %{ %}
 2065   interface(REG_INTER);
 2066 %}
 2067 
 2068 // Pointer Register
 2069 operand iRegP() %{
 2070   constraint(ALLOC_IN_RC(ptr_reg));
 2071   match(RegP);
 2072   match(R0RegP);
 2073   match(R1RegP);
 2074   match(R2RegP);
 2075   match(RExceptionRegP);
 2076   match(R8RegP);
 2077   match(R9RegP);
 2078   match(RthreadRegP); // FIXME: move to sp_ptr_RegP?
 2079   match(R12RegP);
 2080   match(LRRegP);
 2081 
 2082   match(sp_ptr_RegP);
 2083   match(store_ptr_RegP);
 2084 
 2085   format %{ %}
 2086   interface(REG_INTER);
 2087 %}
 2088 
 2089 // GPRs + Rthread + SP
 2090 operand sp_ptr_RegP() %{
 2091   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2092   match(RegP);
 2093   match(iRegP);
 2094   match(SPRegP); // FIXME: check cost
 2095 
 2096   format %{ %}
 2097   interface(REG_INTER);
 2098 %}
 2099 
 2100 
 2101 operand R0RegP() %{
 2102   constraint(ALLOC_IN_RC(R0_regP));
 2103   match(iRegP);
 2104 
 2105   format %{ %}
 2106   interface(REG_INTER);
 2107 %}
 2108 
 2109 operand R1RegP() %{
 2110   constraint(ALLOC_IN_RC(R1_regP));
 2111   match(iRegP);
 2112 
 2113   format %{ %}
 2114   interface(REG_INTER);
 2115 %}
 2116 
 2117 operand R8RegP() %{
 2118   constraint(ALLOC_IN_RC(R8_regP));
 2119   match(iRegP);
 2120 
 2121   format %{ %}
 2122   interface(REG_INTER);
 2123 %}
 2124 
 2125 operand R9RegP() %{
 2126   constraint(ALLOC_IN_RC(R9_regP));
 2127   match(iRegP);
 2128 
 2129   format %{ %}
 2130   interface(REG_INTER);
 2131 %}
 2132 
 2133 operand R12RegP() %{
 2134   constraint(ALLOC_IN_RC(R12_regP));
 2135   match(iRegP);
 2136 
 2137   format %{ %}
 2138   interface(REG_INTER);
 2139 %}
 2140 
 2141 operand R2RegP() %{
 2142   constraint(ALLOC_IN_RC(R2_regP));
 2143   match(iRegP);
 2144 
 2145   format %{ %}
 2146   interface(REG_INTER);
 2147 %}
 2148 
 2149 operand RExceptionRegP() %{
 2150   constraint(ALLOC_IN_RC(Rexception_regP));
 2151   match(iRegP);
 2152 
 2153   format %{ %}
 2154   interface(REG_INTER);
 2155 %}
 2156 
 2157 operand RthreadRegP() %{
 2158   constraint(ALLOC_IN_RC(Rthread_regP));
 2159   match(iRegP);
 2160 
 2161   format %{ %}
 2162   interface(REG_INTER);
 2163 %}
 2164 
 2165 operand IPRegP() %{
 2166   constraint(ALLOC_IN_RC(IP_regP));
 2167   match(iRegP);
 2168 
 2169   format %{ %}
 2170   interface(REG_INTER);
 2171 %}
 2172 
 2173 operand SPRegP() %{
 2174   constraint(ALLOC_IN_RC(SP_regP));
 2175   match(iRegP);
 2176 
 2177   format %{ %}
 2178   interface(REG_INTER);
 2179 %}
 2180 
 2181 operand LRRegP() %{
 2182   constraint(ALLOC_IN_RC(LR_regP));
 2183   match(iRegP);
 2184 
 2185   format %{ %}
 2186   interface(REG_INTER);
 2187 %}
 2188 
 2189 operand R0RegI() %{
 2190   constraint(ALLOC_IN_RC(R0_regI));
 2191   match(iRegI);
 2192 
 2193   format %{ %}
 2194   interface(REG_INTER);
 2195 %}
 2196 
 2197 operand R1RegI() %{
 2198   constraint(ALLOC_IN_RC(R1_regI));
 2199   match(iRegI);
 2200 
 2201   format %{ %}
 2202   interface(REG_INTER);
 2203 %}
 2204 
 2205 operand R2RegI() %{
 2206   constraint(ALLOC_IN_RC(R2_regI));
 2207   match(iRegI);
 2208 
 2209   format %{ %}
 2210   interface(REG_INTER);
 2211 %}
 2212 
 2213 operand R3RegI() %{
 2214   constraint(ALLOC_IN_RC(R3_regI));
 2215   match(iRegI);
 2216 
 2217   format %{ %}
 2218   interface(REG_INTER);
 2219 %}
 2220 
 2221 operand R12RegI() %{
 2222   constraint(ALLOC_IN_RC(R12_regI));
 2223   match(iRegI);
 2224 
 2225   format %{ %}
 2226   interface(REG_INTER);
 2227 %}
 2228 
 2229 // Long Register
 2230 operand iRegL() %{
 2231   constraint(ALLOC_IN_RC(long_reg));
 2232   match(RegL);
 2233   match(R0R1RegL);
 2234   match(R2R3RegL);
 2235 //match(iRegLex);
 2236 
 2237   format %{ %}
 2238   interface(REG_INTER);
 2239 %}
 2240 
 2241 operand iRegLd() %{
 2242   constraint(ALLOC_IN_RC(long_reg_align));
 2243   match(iRegL); // FIXME: allows unaligned R11/R12?
 2244 
 2245   format %{ %}
 2246   interface(REG_INTER);
 2247 %}
 2248 
 2249 // first long arg, or return value
 2250 operand R0R1RegL() %{
 2251   constraint(ALLOC_IN_RC(R0R1_regL));
 2252   match(iRegL);
 2253 
 2254   format %{ %}
 2255   interface(REG_INTER);
 2256 %}
 2257 
 2258 operand R2R3RegL() %{
 2259   constraint(ALLOC_IN_RC(R2R3_regL));
 2260   match(iRegL);
 2261 
 2262   format %{ %}
 2263   interface(REG_INTER);
 2264 %}
 2265 
 2266 // Condition Code Flag Register
 2267 operand flagsReg() %{
 2268   constraint(ALLOC_IN_RC(int_flags));
 2269   match(RegFlags);
 2270 
 2271   format %{ "apsr" %}
 2272   interface(REG_INTER);
 2273 %}
 2274 
 2275 // Result of compare to 0 (TST)
 2276 operand flagsReg_EQNELTGE() %{
 2277   constraint(ALLOC_IN_RC(int_flags));
 2278   match(RegFlags);
 2279 
 2280   format %{ "apsr_EQNELTGE" %}
 2281   interface(REG_INTER);
 2282 %}
 2283 
 2284 // Condition Code Register, unsigned comparisons.
 2285 operand flagsRegU() %{
 2286   constraint(ALLOC_IN_RC(int_flags));
 2287   match(RegFlags);
 2288 #ifdef TODO
 2289   match(RegFlagsP);
 2290 #endif
 2291 
 2292   format %{ "apsr_U" %}
 2293   interface(REG_INTER);
 2294 %}
 2295 
 2296 // Condition Code Register, pointer comparisons.
 2297 operand flagsRegP() %{
 2298   constraint(ALLOC_IN_RC(int_flags));
 2299   match(RegFlags);
 2300 
 2301   format %{ "apsr_P" %}
 2302   interface(REG_INTER);
 2303 %}
 2304 
 2305 // Condition Code Register, long comparisons.
 2306 operand flagsRegL_LTGE() %{
 2307   constraint(ALLOC_IN_RC(int_flags));
 2308   match(RegFlags);
 2309 
 2310   format %{ "apsr_L_LTGE" %}
 2311   interface(REG_INTER);
 2312 %}
 2313 
 2314 operand flagsRegL_EQNE() %{
 2315   constraint(ALLOC_IN_RC(int_flags));
 2316   match(RegFlags);
 2317 
 2318   format %{ "apsr_L_EQNE" %}
 2319   interface(REG_INTER);
 2320 %}
 2321 
 2322 operand flagsRegL_LEGT() %{
 2323   constraint(ALLOC_IN_RC(int_flags));
 2324   match(RegFlags);
 2325 
 2326   format %{ "apsr_L_LEGT" %}
 2327   interface(REG_INTER);
 2328 %}
 2329 
 2330 operand flagsRegUL_LTGE() %{
 2331   constraint(ALLOC_IN_RC(int_flags));
 2332   match(RegFlags);
 2333 
 2334   format %{ "apsr_UL_LTGE" %}
 2335   interface(REG_INTER);
 2336 %}
 2337 
 2338 operand flagsRegUL_EQNE() %{
 2339   constraint(ALLOC_IN_RC(int_flags));
 2340   match(RegFlags);
 2341 
 2342   format %{ "apsr_UL_EQNE" %}
 2343   interface(REG_INTER);
 2344 %}
 2345 
 2346 operand flagsRegUL_LEGT() %{
 2347   constraint(ALLOC_IN_RC(int_flags));
 2348   match(RegFlags);
 2349 
 2350   format %{ "apsr_UL_LEGT" %}
 2351   interface(REG_INTER);
 2352 %}
 2353 
 2354 // Condition Code Register, floating comparisons, unordered same as "less".
 2355 operand flagsRegF() %{
 2356   constraint(ALLOC_IN_RC(float_flags));
 2357   match(RegFlags);
 2358 
 2359   format %{ "fpscr_F" %}
 2360   interface(REG_INTER);
 2361 %}
 2362 
 2363 // Vectors
 2364 operand vecD() %{
 2365   constraint(ALLOC_IN_RC(actual_dflt_reg));
 2366   match(VecD);
 2367 
 2368   format %{ %}
 2369   interface(REG_INTER);
 2370 %}
 2371 
 2372 operand vecX() %{
 2373   constraint(ALLOC_IN_RC(vectorx_reg));
 2374   match(VecX);
 2375 
 2376   format %{ %}
 2377   interface(REG_INTER);
 2378 %}
 2379 
 2380 operand regD() %{
 2381   constraint(ALLOC_IN_RC(actual_dflt_reg));
 2382   match(RegD);
 2383   match(regD_low);
 2384 
 2385   format %{ %}
 2386   interface(REG_INTER);
 2387 %}
 2388 
 2389 operand regF() %{
 2390   constraint(ALLOC_IN_RC(sflt_reg));
 2391   match(RegF);
 2392 
 2393   format %{ %}
 2394   interface(REG_INTER);
 2395 %}
 2396 
 2397 operand regD_low() %{
 2398   constraint(ALLOC_IN_RC(dflt_low_reg));
 2399   match(RegD);
 2400 
 2401   format %{ %}
 2402   interface(REG_INTER);
 2403 %}
 2404 
 2405 // Special Registers
 2406 
 2407 // Method Register
 2408 operand inline_cache_regP(iRegP reg) %{
 2409   constraint(ALLOC_IN_RC(Ricklass_regP));
 2410   match(reg);
 2411   format %{ %}
 2412   interface(REG_INTER);
 2413 %}
 2414 
 2415 //----------Complex Operands---------------------------------------------------
 2416 // Indirect Memory Reference
 2417 operand indirect(sp_ptr_RegP reg) %{
 2418   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2419   match(reg);
 2420 
 2421   op_cost(100);
 2422   format %{ "[$reg]" %}
 2423   interface(MEMORY_INTER) %{
 2424     base($reg);
 2425     index(0xf); // PC => no index
 2426     scale(0x0);
 2427     disp(0x0);
 2428   %}
 2429 %}
 2430 
 2431 
 2432 // Indirect with Offset in ]-4096, 4096[
 2433 operand indOffset12(sp_ptr_RegP reg, immI12 offset) %{
 2434   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2435   match(AddP reg offset);
 2436 
 2437   op_cost(100);
 2438   format %{ "[$reg + $offset]" %}
 2439   interface(MEMORY_INTER) %{
 2440     base($reg);
 2441     index(0xf); // PC => no index
 2442     scale(0x0);
 2443     disp($offset);
 2444   %}
 2445 %}
 2446 
 2447 // Indirect with offset for float load/store
 2448 operand indOffsetFP(sp_ptr_RegP reg, immIFP offset) %{
 2449   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2450   match(AddP reg offset);
 2451 
 2452   op_cost(100);
 2453   format %{ "[$reg + $offset]" %}
 2454   interface(MEMORY_INTER) %{
 2455     base($reg);
 2456     index(0xf); // PC => no index
 2457     scale(0x0);
 2458     disp($offset);
 2459   %}
 2460 %}
 2461 
 2462 // Indirect with Offset for half and double words
 2463 operand indOffsetHD(sp_ptr_RegP reg, immIHD offset) %{
 2464   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2465   match(AddP reg offset);
 2466 
 2467   op_cost(100);
 2468   format %{ "[$reg + $offset]" %}
 2469   interface(MEMORY_INTER) %{
 2470     base($reg);
 2471     index(0xf); // PC => no index
 2472     scale(0x0);
 2473     disp($offset);
 2474   %}
 2475 %}
 2476 
 2477 // Indirect with Offset and Offset+4 in ]-1024, 1024[
 2478 operand indOffsetFPx2(sp_ptr_RegP reg, immX10x2 offset) %{
 2479   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2480   match(AddP reg offset);
 2481 
 2482   op_cost(100);
 2483   format %{ "[$reg + $offset]" %}
 2484   interface(MEMORY_INTER) %{
 2485     base($reg);
 2486     index(0xf); // PC => no index
 2487     scale(0x0);
 2488     disp($offset);
 2489   %}
 2490 %}
 2491 
 2492 // Indirect with Offset and Offset+4 in ]-4096, 4096[
 2493 operand indOffset12x2(sp_ptr_RegP reg, immI12x2 offset) %{
 2494   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2495   match(AddP reg offset);
 2496 
 2497   op_cost(100);
 2498   format %{ "[$reg + $offset]" %}
 2499   interface(MEMORY_INTER) %{
 2500     base($reg);
 2501     index(0xf); // PC => no index
 2502     scale(0x0);
 2503     disp($offset);
 2504   %}
 2505 %}
 2506 
 2507 // Indirect with Register Index
 2508 operand indIndex(iRegP addr, iRegX index) %{
 2509   constraint(ALLOC_IN_RC(ptr_reg));
 2510   match(AddP addr index);
 2511 
 2512   op_cost(100);
 2513   format %{ "[$addr + $index]" %}
 2514   interface(MEMORY_INTER) %{
 2515     base($addr);
 2516     index($index);
 2517     scale(0x0);
 2518     disp(0x0);
 2519   %}
 2520 %}
 2521 
 2522 // Indirect Memory Times Scale Plus Index Register
 2523 operand indIndexScale(iRegP addr, iRegX index, immU5 scale) %{
 2524   constraint(ALLOC_IN_RC(ptr_reg));
 2525   match(AddP addr (LShiftX index scale));
 2526 
 2527   op_cost(100);
 2528   format %{"[$addr + $index << $scale]" %}
 2529   interface(MEMORY_INTER) %{
 2530     base($addr);
 2531     index($index);
 2532     scale($scale);
 2533     disp(0x0);
 2534   %}
 2535 %}
 2536 
 2537 // Operands for expressing Control Flow
 2538 // NOTE:  Label is a predefined operand which should not be redefined in
 2539 //        the AD file.  It is generically handled within the ADLC.
 2540 
 2541 //----------Conditional Branch Operands----------------------------------------
 2542 // Comparison Op  - This is the operation of the comparison, and is limited to
 2543 //                  the following set of codes:
 2544 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
 2545 //
 2546 // Other attributes of the comparison, such as unsignedness, are specified
 2547 // by the comparison instruction that sets a condition code flags register.
 2548 // That result is represented by a flags operand whose subtype is appropriate
 2549 // to the unsignedness (etc.) of the comparison.
 2550 //
 2551 // Later, the instruction which matches both the Comparison Op (a Bool) and
 2552 // the flags (produced by the Cmp) specifies the coding of the comparison op
 2553 // by matching a specific subtype of Bool operand below, such as cmpOpU.
 2554 
 2555 operand cmpOp() %{
 2556   match(Bool);
 2557 
 2558   format %{ "" %}
 2559   interface(COND_INTER) %{
 2560     equal(0x0);
 2561     not_equal(0x1);
 2562     less(0xb);
 2563     greater_equal(0xa);
 2564     less_equal(0xd);
 2565     greater(0xc);
 2566     overflow(0x0); // unsupported/unimplemented
 2567     no_overflow(0x0); // unsupported/unimplemented
 2568   %}
 2569 %}
 2570 
 2571 // integer comparison with 0, signed
 2572 operand cmpOp0() %{
 2573   match(Bool);
 2574 
 2575   format %{ "" %}
 2576   interface(COND_INTER) %{
 2577     equal(0x0);
 2578     not_equal(0x1);
 2579     less(0x4);
 2580     greater_equal(0x5);
 2581     less_equal(0xd); // unsupported
 2582     greater(0xc); // unsupported
 2583     overflow(0x0); // unsupported/unimplemented
 2584     no_overflow(0x0); // unsupported/unimplemented
 2585   %}
 2586 %}
 2587 
 2588 // Comparison Op, unsigned
 2589 operand cmpOpU() %{
 2590   match(Bool);
 2591 
 2592   format %{ "u" %}
 2593   interface(COND_INTER) %{
 2594     equal(0x0);
 2595     not_equal(0x1);
 2596     less(0x3);
 2597     greater_equal(0x2);
 2598     less_equal(0x9);
 2599     greater(0x8);
 2600     overflow(0x0); // unsupported/unimplemented
 2601     no_overflow(0x0); // unsupported/unimplemented
 2602   %}
 2603 %}
 2604 
 2605 // Comparison Op, pointer (same as unsigned)
 2606 operand cmpOpP() %{
 2607   match(Bool);
 2608 
 2609   format %{ "p" %}
 2610   interface(COND_INTER) %{
 2611     equal(0x0);
 2612     not_equal(0x1);
 2613     less(0x3);
 2614     greater_equal(0x2);
 2615     less_equal(0x9);
 2616     greater(0x8);
 2617     overflow(0x0); // unsupported/unimplemented
 2618     no_overflow(0x0); // unsupported/unimplemented
 2619   %}
 2620 %}
 2621 
 2622 operand cmpOpL() %{
 2623   match(Bool);
 2624 
 2625   format %{ "L" %}
 2626   interface(COND_INTER) %{
 2627     equal(0x0);
 2628     not_equal(0x1);
 2629     less(0xb);
 2630     greater_equal(0xa);
 2631     less_equal(0xd);
 2632     greater(0xc);
 2633     overflow(0x0); // unsupported/unimplemented
 2634     no_overflow(0x0); // unsupported/unimplemented
 2635   %}
 2636 %}
 2637 
 2638 operand cmpOpL_commute() %{
 2639   match(Bool);
 2640 
 2641   format %{ "L" %}
 2642   interface(COND_INTER) %{
 2643     equal(0x0);
 2644     not_equal(0x1);
 2645     less(0xc);
 2646     greater_equal(0xd);
 2647     less_equal(0xa);
 2648     greater(0xb);
 2649     overflow(0x0); // unsupported/unimplemented
 2650     no_overflow(0x0); // unsupported/unimplemented
 2651   %}
 2652 %}
 2653 
 2654 operand cmpOpUL() %{
 2655   match(Bool);
 2656 
 2657   format %{ "UL" %}
 2658   interface(COND_INTER) %{
 2659     equal(0x0);
 2660     not_equal(0x1);
 2661     less(0x3);
 2662     greater_equal(0x2);
 2663     less_equal(0x9);
 2664     greater(0x8);
 2665     overflow(0x0); // unsupported/unimplemented
 2666     no_overflow(0x0); // unsupported/unimplemented
 2667   %}
 2668 %}
 2669 
 2670 operand cmpOpUL_commute() %{
 2671   match(Bool);
 2672 
 2673   format %{ "UL" %}
 2674   interface(COND_INTER) %{
 2675     equal(0x0);
 2676     not_equal(0x1);
 2677     less(0x8);
 2678     greater_equal(0x9);
 2679     less_equal(0x2);
 2680     greater(0x3);
 2681     overflow(0x0); // unsupported/unimplemented
 2682     no_overflow(0x0); // unsupported/unimplemented
 2683   %}
 2684 %}
 2685 
 2686 
 2687 //----------OPERAND CLASSES----------------------------------------------------
 2688 // Operand Classes are groups of operands that are used to simplify
 2689 // instruction definitions by not requiring the AD writer to specify separate
 2690 // instructions for every form of operand when the instruction accepts
 2691 // multiple operand types with the same basic encoding and format.  The classic
 2692 // case of this is memory operands.
 2693 
 2694 opclass memoryI ( indirect, indOffset12, indIndex, indIndexScale );
 2695 opclass memoryP ( indirect, indOffset12, indIndex, indIndexScale );
 2696 opclass memoryF ( indirect, indOffsetFP );
 2697 opclass memoryF2 ( indirect, indOffsetFPx2 );
 2698 opclass memoryD ( indirect, indOffsetFP );
 2699 opclass memoryfp( indirect, indOffsetFP );
 2700 opclass memoryB ( indirect, indIndex, indOffsetHD );
 2701 opclass memoryS ( indirect, indIndex, indOffsetHD );
 2702 opclass memoryL ( indirect, indIndex, indOffsetHD );
 2703 
 2704 opclass memoryScaledI(indIndexScale);
 2705 opclass memoryScaledP(indIndexScale);
 2706 
 2707 // when ldrex/strex is used:
 2708 opclass memoryex ( indirect );
 2709 opclass indIndexMemory( indIndex );
 2710 opclass memorylong ( indirect, indOffset12x2 );
 2711 opclass memoryvld ( indirect /* , write back mode not implemented */ );
 2712 
 2713 //----------PIPELINE-----------------------------------------------------------
 2714 pipeline %{
 2715 
 2716 //----------ATTRIBUTES---------------------------------------------------------
 2717 attributes %{
 2718   fixed_size_instructions;           // Fixed size instructions
 2719   max_instructions_per_bundle = 4;   // Up to 4 instructions per bundle
 2720   instruction_unit_size = 4;         // An instruction is 4 bytes long
 2721   instruction_fetch_unit_size = 16;  // The processor fetches one line
 2722   instruction_fetch_units = 1;       // of 16 bytes
 2723 
 2724   // List of nop instructions
 2725   nops( Nop_A0, Nop_A1, Nop_MS, Nop_FA, Nop_BR );
 2726 %}
 2727 
 2728 //----------RESOURCES----------------------------------------------------------
 2729 // Resources are the functional units available to the machine
 2730 resources(A0, A1, MS, BR, FA, FM, IDIV, FDIV, IALU = A0 | A1);
 2731 
 2732 //----------PIPELINE DESCRIPTION-----------------------------------------------
 2733 // Pipeline Description specifies the stages in the machine's pipeline
 2734 
 2735 pipe_desc(A, P, F, B, I, J, S, R, E, C, M, W, X, T, D);
 2736 
 2737 //----------PIPELINE CLASSES---------------------------------------------------
 2738 // Pipeline Classes describe the stages in which input and output are
 2739 // referenced by the hardware pipeline.
 2740 
 2741 // Integer ALU reg-reg operation
 2742 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 2743     single_instruction;
 2744     dst   : E(write);
 2745     src1  : R(read);
 2746     src2  : R(read);
 2747     IALU  : R;
 2748 %}
 2749 
 2750 // Integer ALU reg-reg long operation
 2751 pipe_class ialu_reg_reg_2(iRegL dst, iRegL src1, iRegL src2) %{
 2752     instruction_count(2);
 2753     dst   : E(write);
 2754     src1  : R(read);
 2755     src2  : R(read);
 2756     IALU  : R;
 2757     IALU  : R;
 2758 %}
 2759 
 2760 // Integer ALU reg-reg long dependent operation
 2761 pipe_class ialu_reg_reg_2_dep(iRegL dst, iRegL src1, iRegL src2, flagsReg cr) %{
 2762     instruction_count(1); multiple_bundles;
 2763     dst   : E(write);
 2764     src1  : R(read);
 2765     src2  : R(read);
 2766     cr    : E(write);
 2767     IALU  : R(2);
 2768 %}
 2769 
 2770 // Integer ALU reg-imm operaion
 2771 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) %{
 2772     single_instruction;
 2773     dst   : E(write);
 2774     src1  : R(read);
 2775     IALU  : R;
 2776 %}
 2777 
 2778 // Integer ALU reg-reg operation with condition code
 2779 pipe_class ialu_cc_reg_reg(iRegI dst, iRegI src1, iRegI src2, flagsReg cr) %{
 2780     single_instruction;
 2781     dst   : E(write);
 2782     cr    : E(write);
 2783     src1  : R(read);
 2784     src2  : R(read);
 2785     IALU  : R;
 2786 %}
 2787 
 2788 // Integer ALU zero-reg operation
 2789 pipe_class ialu_zero_reg(iRegI dst, immI0 zero, iRegI src2) %{
 2790     single_instruction;
 2791     dst   : E(write);
 2792     src2  : R(read);
 2793     IALU  : R;
 2794 %}
 2795 
 2796 // Integer ALU zero-reg operation with condition code only
 2797 pipe_class ialu_cconly_zero_reg(flagsReg cr, iRegI src) %{
 2798     single_instruction;
 2799     cr    : E(write);
 2800     src   : R(read);
 2801     IALU  : R;
 2802 %}
 2803 
 2804 // Integer ALU reg-reg operation with condition code only
 2805 pipe_class ialu_cconly_reg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
 2806     single_instruction;
 2807     cr    : E(write);
 2808     src1  : R(read);
 2809     src2  : R(read);
 2810     IALU  : R;
 2811 %}
 2812 
 2813 // Integer ALU reg-imm operation with condition code only
 2814 pipe_class ialu_cconly_reg_imm(flagsReg cr, iRegI src1) %{
 2815     single_instruction;
 2816     cr    : E(write);
 2817     src1  : R(read);
 2818     IALU  : R;
 2819 %}
 2820 
 2821 // Integer ALU reg-reg-zero operation with condition code only
 2822 pipe_class ialu_cconly_reg_reg_zero(flagsReg cr, iRegI src1, iRegI src2, immI0 zero) %{
 2823     single_instruction;
 2824     cr    : E(write);
 2825     src1  : R(read);
 2826     src2  : R(read);
 2827     IALU  : R;
 2828 %}
 2829 
 2830 // Integer ALU reg-imm-zero operation with condition code only
 2831 pipe_class ialu_cconly_reg_imm_zero(flagsReg cr, iRegI src1, immI0 zero) %{
 2832     single_instruction;
 2833     cr    : E(write);
 2834     src1  : R(read);
 2835     IALU  : R;
 2836 %}
 2837 
 2838 // Integer ALU reg-reg operation with condition code, src1 modified
 2839 pipe_class ialu_cc_rwreg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
 2840     single_instruction;
 2841     cr    : E(write);
 2842     src1  : E(write);
 2843     src1  : R(read);
 2844     src2  : R(read);
 2845     IALU  : R;
 2846 %}
 2847 
 2848 pipe_class cmpL_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg cr ) %{
 2849     multiple_bundles;
 2850     dst   : E(write)+4;
 2851     cr    : E(write);
 2852     src1  : R(read);
 2853     src2  : R(read);
 2854     IALU  : R(3);
 2855     BR    : R(2);
 2856 %}
 2857 
 2858 // Integer ALU operation
 2859 pipe_class ialu_none(iRegI dst) %{
 2860     single_instruction;
 2861     dst   : E(write);
 2862     IALU  : R;
 2863 %}
 2864 
 2865 // Integer ALU reg operation
 2866 pipe_class ialu_reg(iRegI dst, iRegI src) %{
 2867     single_instruction; may_have_no_code;
 2868     dst   : E(write);
 2869     src   : R(read);
 2870     IALU  : R;
 2871 %}
 2872 
 2873 // Integer ALU reg conditional operation
 2874 // This instruction has a 1 cycle stall, and cannot execute
 2875 // in the same cycle as the instruction setting the condition
 2876 // code. We kludge this by pretending to read the condition code
 2877 // 1 cycle earlier, and by marking the functional units as busy
 2878 // for 2 cycles with the result available 1 cycle later than
 2879 // is really the case.
 2880 pipe_class ialu_reg_flags( iRegI op2_out, iRegI op2_in, iRegI op1, flagsReg cr ) %{
 2881     single_instruction;
 2882     op2_out : C(write);
 2883     op1     : R(read);
 2884     cr      : R(read);       // This is really E, with a 1 cycle stall
 2885     BR      : R(2);
 2886     MS      : R(2);
 2887 %}
 2888 
 2889 // Integer ALU reg operation
 2890 pipe_class ialu_move_reg_L_to_I(iRegI dst, iRegL src) %{
 2891     single_instruction; may_have_no_code;
 2892     dst   : E(write);
 2893     src   : R(read);
 2894     IALU  : R;
 2895 %}
 2896 pipe_class ialu_move_reg_I_to_L(iRegL dst, iRegI src) %{
 2897     single_instruction; may_have_no_code;
 2898     dst   : E(write);
 2899     src   : R(read);
 2900     IALU  : R;
 2901 %}
 2902 
 2903 // Two integer ALU reg operations
 2904 pipe_class ialu_reg_2(iRegL dst, iRegL src) %{
 2905     instruction_count(2);
 2906     dst   : E(write);
 2907     src   : R(read);
 2908     A0    : R;
 2909     A1    : R;
 2910 %}
 2911 
 2912 // Two integer ALU reg operations
 2913 pipe_class ialu_move_reg_L_to_L(iRegL dst, iRegL src) %{
 2914     instruction_count(2); may_have_no_code;
 2915     dst   : E(write);
 2916     src   : R(read);
 2917     A0    : R;
 2918     A1    : R;
 2919 %}
 2920 
 2921 // Integer ALU imm operation
 2922 pipe_class ialu_imm(iRegI dst) %{
 2923     single_instruction;
 2924     dst   : E(write);
 2925     IALU  : R;
 2926 %}
 2927 
 2928 pipe_class ialu_imm_n(iRegI dst) %{
 2929     single_instruction;
 2930     dst   : E(write);
 2931     IALU  : R;
 2932 %}
 2933 
 2934 // Integer ALU reg-reg with carry operation
 2935 pipe_class ialu_reg_reg_cy(iRegI dst, iRegI src1, iRegI src2, iRegI cy) %{
 2936     single_instruction;
 2937     dst   : E(write);
 2938     src1  : R(read);
 2939     src2  : R(read);
 2940     IALU  : R;
 2941 %}
 2942 
 2943 // Integer ALU cc operation
 2944 pipe_class ialu_cc(iRegI dst, flagsReg cc) %{
 2945     single_instruction;
 2946     dst   : E(write);
 2947     cc    : R(read);
 2948     IALU  : R;
 2949 %}
 2950 
 2951 // Integer ALU cc / second IALU operation
 2952 pipe_class ialu_reg_ialu( iRegI dst, iRegI src ) %{
 2953     instruction_count(1); multiple_bundles;
 2954     dst   : E(write)+1;
 2955     src   : R(read);
 2956     IALU  : R;
 2957 %}
 2958 
 2959 // Integer ALU cc / second IALU operation
 2960 pipe_class ialu_reg_reg_ialu( iRegI dst, iRegI p, iRegI q ) %{
 2961     instruction_count(1); multiple_bundles;
 2962     dst   : E(write)+1;
 2963     p     : R(read);
 2964     q     : R(read);
 2965     IALU  : R;
 2966 %}
 2967 
 2968 // Integer ALU hi-lo-reg operation
 2969 pipe_class ialu_hi_lo_reg(iRegI dst, immI src) %{
 2970     instruction_count(1); multiple_bundles;
 2971     dst   : E(write)+1;
 2972     IALU  : R(2);
 2973 %}
 2974 
 2975 // Long Constant
 2976 pipe_class loadConL( iRegL dst, immL src ) %{
 2977     instruction_count(2); multiple_bundles;
 2978     dst   : E(write)+1;
 2979     IALU  : R(2);
 2980     IALU  : R(2);
 2981 %}
 2982 
 2983 // Pointer Constant
 2984 pipe_class loadConP( iRegP dst, immP src ) %{
 2985     instruction_count(0); multiple_bundles;
 2986     fixed_latency(6);
 2987 %}
 2988 
 2989 // Long Constant small
 2990 pipe_class loadConLlo( iRegL dst, immL src ) %{
 2991     instruction_count(2);
 2992     dst   : E(write);
 2993     IALU  : R;
 2994     IALU  : R;
 2995 %}
 2996 
 2997 // [PHH] This is wrong for 64-bit.  See LdImmF/D.
 2998 pipe_class loadConFD(regF dst, immF src, iRegP tmp) %{
 2999     instruction_count(1); multiple_bundles;
 3000     src   : R(read);
 3001     dst   : M(write)+1;
 3002     IALU  : R;
 3003     MS    : E;
 3004 %}
 3005 
 3006 // Integer ALU nop operation
 3007 pipe_class ialu_nop() %{
 3008     single_instruction;
 3009     IALU  : R;
 3010 %}
 3011 
 3012 // Integer ALU nop operation
 3013 pipe_class ialu_nop_A0() %{
 3014     single_instruction;
 3015     A0    : R;
 3016 %}
 3017 
 3018 // Integer ALU nop operation
 3019 pipe_class ialu_nop_A1() %{
 3020     single_instruction;
 3021     A1    : R;
 3022 %}
 3023 
 3024 // Integer Multiply reg-reg operation
 3025 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 3026     single_instruction;
 3027     dst   : E(write);
 3028     src1  : R(read);
 3029     src2  : R(read);
 3030     MS    : R(5);
 3031 %}
 3032 
 3033 pipe_class mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 3034     single_instruction;
 3035     dst   : E(write)+4;
 3036     src1  : R(read);
 3037     src2  : R(read);
 3038     MS    : R(6);
 3039 %}
 3040 
 3041 // Integer Divide reg-reg
 3042 pipe_class sdiv_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI temp, flagsReg cr) %{
 3043     instruction_count(1); multiple_bundles;
 3044     dst   : E(write);
 3045     temp  : E(write);
 3046     src1  : R(read);
 3047     src2  : R(read);
 3048     temp  : R(read);
 3049     MS    : R(38);
 3050 %}
 3051 
 3052 // Long Divide
 3053 pipe_class divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 3054     dst  : E(write)+71;
 3055     src1 : R(read);
 3056     src2 : R(read)+1;
 3057     MS   : R(70);
 3058 %}
 3059 
 3060 // Floating Point Add Float
 3061 pipe_class faddF_reg_reg(regF dst, regF src1, regF src2) %{
 3062     single_instruction;
 3063     dst   : X(write);
 3064     src1  : E(read);
 3065     src2  : E(read);
 3066     FA    : R;
 3067 %}
 3068 
 3069 // Floating Point Add Double
 3070 pipe_class faddD_reg_reg(regD dst, regD src1, regD src2) %{
 3071     single_instruction;
 3072     dst   : X(write);
 3073     src1  : E(read);
 3074     src2  : E(read);
 3075     FA    : R;
 3076 %}
 3077 
 3078 // Floating Point Conditional Move based on integer flags
 3079 pipe_class int_conditional_float_move (cmpOp cmp, flagsReg cr, regF dst, regF src) %{
 3080     single_instruction;
 3081     dst   : X(write);
 3082     src   : E(read);
 3083     cr    : R(read);
 3084     FA    : R(2);
 3085     BR    : R(2);
 3086 %}
 3087 
 3088 // Floating Point Conditional Move based on integer flags
 3089 pipe_class int_conditional_double_move (cmpOp cmp, flagsReg cr, regD dst, regD src) %{
 3090     single_instruction;
 3091     dst   : X(write);
 3092     src   : E(read);
 3093     cr    : R(read);
 3094     FA    : R(2);
 3095     BR    : R(2);
 3096 %}
 3097 
 3098 // Floating Point Multiply Float
 3099 pipe_class fmulF_reg_reg(regF dst, regF src1, regF src2) %{
 3100     single_instruction;
 3101     dst   : X(write);
 3102     src1  : E(read);
 3103     src2  : E(read);
 3104     FM    : R;
 3105 %}
 3106 
 3107 // Floating Point Multiply Double
 3108 pipe_class fmulD_reg_reg(regD dst, regD src1, regD src2) %{
 3109     single_instruction;
 3110     dst   : X(write);
 3111     src1  : E(read);
 3112     src2  : E(read);
 3113     FM    : R;
 3114 %}
 3115 
 3116 // Floating Point Divide Float
 3117 pipe_class fdivF_reg_reg(regF dst, regF src1, regF src2) %{
 3118     single_instruction;
 3119     dst   : X(write);
 3120     src1  : E(read);
 3121     src2  : E(read);
 3122     FM    : R;
 3123     FDIV  : C(14);
 3124 %}
 3125 
 3126 // Floating Point Divide Double
 3127 pipe_class fdivD_reg_reg(regD dst, regD src1, regD src2) %{
 3128     single_instruction;
 3129     dst   : X(write);
 3130     src1  : E(read);
 3131     src2  : E(read);
 3132     FM    : R;
 3133     FDIV  : C(17);
 3134 %}
 3135 
 3136 // Floating Point Move/Negate/Abs Float
 3137 pipe_class faddF_reg(regF dst, regF src) %{
 3138     single_instruction;
 3139     dst   : W(write);
 3140     src   : E(read);
 3141     FA    : R(1);
 3142 %}
 3143 
 3144 // Floating Point Move/Negate/Abs Double
 3145 pipe_class faddD_reg(regD dst, regD src) %{
 3146     single_instruction;
 3147     dst   : W(write);
 3148     src   : E(read);
 3149     FA    : R;
 3150 %}
 3151 
 3152 // Floating Point Convert F->D
 3153 pipe_class fcvtF2D(regD dst, regF src) %{
 3154     single_instruction;
 3155     dst   : X(write);
 3156     src   : E(read);
 3157     FA    : R;
 3158 %}
 3159 
 3160 // Floating Point Convert I->D
 3161 pipe_class fcvtI2D(regD dst, regF src) %{
 3162     single_instruction;
 3163     dst   : X(write);
 3164     src   : E(read);
 3165     FA    : R;
 3166 %}
 3167 
 3168 // Floating Point Convert LHi->D
 3169 pipe_class fcvtLHi2D(regD dst, regD src) %{
 3170     single_instruction;
 3171     dst   : X(write);
 3172     src   : E(read);
 3173     FA    : R;
 3174 %}
 3175 
 3176 // Floating Point Convert L->D
 3177 pipe_class fcvtL2D(regD dst, iRegL src) %{
 3178     single_instruction;
 3179     dst   : X(write);
 3180     src   : E(read);
 3181     FA    : R;
 3182 %}
 3183 
 3184 // Floating Point Convert L->F
 3185 pipe_class fcvtL2F(regF dst, iRegL src) %{
 3186     single_instruction;
 3187     dst   : X(write);
 3188     src   : E(read);
 3189     FA    : R;
 3190 %}
 3191 
 3192 // Floating Point Convert D->F
 3193 pipe_class fcvtD2F(regD dst, regF src) %{
 3194     single_instruction;
 3195     dst   : X(write);
 3196     src   : E(read);
 3197     FA    : R;
 3198 %}
 3199 
 3200 // Floating Point Convert I->L
 3201 pipe_class fcvtI2L(regD dst, regF src) %{
 3202     single_instruction;
 3203     dst   : X(write);
 3204     src   : E(read);
 3205     FA    : R;
 3206 %}
 3207 
 3208 // Floating Point Convert D->F
 3209 pipe_class fcvtD2I(iRegI dst, regD src, flagsReg cr) %{
 3210     instruction_count(1); multiple_bundles;
 3211     dst   : X(write)+6;
 3212     src   : E(read);
 3213     FA    : R;
 3214 %}
 3215 
 3216 // Floating Point Convert D->L
 3217 pipe_class fcvtD2L(regD dst, regD src, flagsReg cr) %{
 3218     instruction_count(1); multiple_bundles;
 3219     dst   : X(write)+6;
 3220     src   : E(read);
 3221     FA    : R;
 3222 %}
 3223 
 3224 // Floating Point Convert F->I
 3225 pipe_class fcvtF2I(regF dst, regF src, flagsReg cr) %{
 3226     instruction_count(1); multiple_bundles;
 3227     dst   : X(write)+6;
 3228     src   : E(read);
 3229     FA    : R;
 3230 %}
 3231 
 3232 // Floating Point Convert F->L
 3233 pipe_class fcvtF2L(regD dst, regF src, flagsReg cr) %{
 3234     instruction_count(1); multiple_bundles;
 3235     dst   : X(write)+6;
 3236     src   : E(read);
 3237     FA    : R;
 3238 %}
 3239 
 3240 // Floating Point Convert I->F
 3241 pipe_class fcvtI2F(regF dst, regF src) %{
 3242     single_instruction;
 3243     dst   : X(write);
 3244     src   : E(read);
 3245     FA    : R;
 3246 %}
 3247 
 3248 // Floating Point Compare
 3249 pipe_class faddF_fcc_reg_reg_zero(flagsRegF cr, regF src1, regF src2, immI0 zero) %{
 3250     single_instruction;
 3251     cr    : X(write);
 3252     src1  : E(read);
 3253     src2  : E(read);
 3254     FA    : R;
 3255 %}
 3256 
 3257 // Floating Point Compare
 3258 pipe_class faddD_fcc_reg_reg_zero(flagsRegF cr, regD src1, regD src2, immI0 zero) %{
 3259     single_instruction;
 3260     cr    : X(write);
 3261     src1  : E(read);
 3262     src2  : E(read);
 3263     FA    : R;
 3264 %}
 3265 
 3266 // Floating Add Nop
 3267 pipe_class fadd_nop() %{
 3268     single_instruction;
 3269     FA  : R;
 3270 %}
 3271 
 3272 // Integer Store to Memory
 3273 pipe_class istore_mem_reg(memoryI mem, iRegI src) %{
 3274     single_instruction;
 3275     mem   : R(read);
 3276     src   : C(read);
 3277     MS    : R;
 3278 %}
 3279 
 3280 // Integer Store to Memory
 3281 pipe_class istore_mem_spORreg(memoryI mem, sp_ptr_RegP src) %{
 3282     single_instruction;
 3283     mem   : R(read);
 3284     src   : C(read);
 3285     MS    : R;
 3286 %}
 3287 
 3288 // Float Store
 3289 pipe_class fstoreF_mem_reg(memoryF mem, RegF src) %{
 3290     single_instruction;
 3291     mem : R(read);
 3292     src : C(read);
 3293     MS  : R;
 3294 %}
 3295 
 3296 // Float Store
 3297 pipe_class fstoreF_mem_zero(memoryF mem, immF0 src) %{
 3298     single_instruction;
 3299     mem : R(read);
 3300     MS  : R;
 3301 %}
 3302 
 3303 // Double Store
 3304 pipe_class fstoreD_mem_reg(memoryD mem, RegD src) %{
 3305     instruction_count(1);
 3306     mem : R(read);
 3307     src : C(read);
 3308     MS  : R;
 3309 %}
 3310 
 3311 // Double Store
 3312 pipe_class fstoreD_mem_zero(memoryD mem, immD0 src) %{
 3313     single_instruction;
 3314     mem : R(read);
 3315     MS  : R;
 3316 %}
 3317 
 3318 // Integer Load (when sign bit propagation not needed)
 3319 pipe_class iload_mem(iRegI dst, memoryI mem) %{
 3320     single_instruction;
 3321     mem : R(read);
 3322     dst : C(write);
 3323     MS  : R;
 3324 %}
 3325 
 3326 // Integer Load (when sign bit propagation or masking is needed)
 3327 pipe_class iload_mask_mem(iRegI dst, memoryI mem) %{
 3328     single_instruction;
 3329     mem : R(read);
 3330     dst : M(write);
 3331     MS  : R;
 3332 %}
 3333 
 3334 // Float Load
 3335 pipe_class floadF_mem(regF dst, memoryF mem) %{
 3336     single_instruction;
 3337     mem : R(read);
 3338     dst : M(write);
 3339     MS  : R;
 3340 %}
 3341 
 3342 // Float Load
 3343 pipe_class floadD_mem(regD dst, memoryD mem) %{
 3344     instruction_count(1); multiple_bundles; // Again, unaligned argument is only multiple case
 3345     mem : R(read);
 3346     dst : M(write);
 3347     MS  : R;
 3348 %}
 3349 
 3350 // Memory Nop
 3351 pipe_class mem_nop() %{
 3352     single_instruction;
 3353     MS  : R;
 3354 %}
 3355 
 3356 pipe_class sethi(iRegP dst, immI src) %{
 3357     single_instruction;
 3358     dst  : E(write);
 3359     IALU : R;
 3360 %}
 3361 
 3362 pipe_class loadPollP(iRegP poll) %{
 3363     single_instruction;
 3364     poll : R(read);
 3365     MS   : R;
 3366 %}
 3367 
 3368 pipe_class br(Universe br, label labl) %{
 3369     single_instruction_with_delay_slot;
 3370     BR  : R;
 3371 %}
 3372 
 3373 pipe_class br_cc(Universe br, cmpOp cmp, flagsReg cr, label labl) %{
 3374     single_instruction_with_delay_slot;
 3375     cr    : E(read);
 3376     BR    : R;
 3377 %}
 3378 
 3379 pipe_class br_reg(Universe br, cmpOp cmp, iRegI op1, label labl) %{
 3380     single_instruction_with_delay_slot;
 3381     op1 : E(read);
 3382     BR  : R;
 3383     MS  : R;
 3384 %}
 3385 
 3386 pipe_class br_nop() %{
 3387     single_instruction;
 3388     BR  : R;
 3389 %}
 3390 
 3391 pipe_class simple_call(method meth) %{
 3392     instruction_count(2); multiple_bundles; force_serialization;
 3393     fixed_latency(100);
 3394     BR  : R(1);
 3395     MS  : R(1);
 3396     A0  : R(1);
 3397 %}
 3398 
 3399 pipe_class compiled_call(method meth) %{
 3400     instruction_count(1); multiple_bundles; force_serialization;
 3401     fixed_latency(100);
 3402     MS  : R(1);
 3403 %}
 3404 
 3405 pipe_class call(method meth) %{
 3406     instruction_count(0); multiple_bundles; force_serialization;
 3407     fixed_latency(100);
 3408 %}
 3409 
 3410 pipe_class tail_call(Universe ignore, label labl) %{
 3411     single_instruction; has_delay_slot;
 3412     fixed_latency(100);
 3413     BR  : R(1);
 3414     MS  : R(1);
 3415 %}
 3416 
 3417 pipe_class ret(Universe ignore) %{
 3418     single_instruction; has_delay_slot;
 3419     BR  : R(1);
 3420     MS  : R(1);
 3421 %}
 3422 
 3423 // The real do-nothing guy
 3424 pipe_class empty( ) %{
 3425     instruction_count(0);
 3426 %}
 3427 
 3428 pipe_class long_memory_op() %{
 3429     instruction_count(0); multiple_bundles; force_serialization;
 3430     fixed_latency(25);
 3431     MS  : R(1);
 3432 %}
 3433 
 3434 // Check-cast
 3435 pipe_class partial_subtype_check_pipe(Universe ignore, iRegP array, iRegP match ) %{
 3436     array : R(read);
 3437     match  : R(read);
 3438     IALU   : R(2);
 3439     BR     : R(2);
 3440     MS     : R;
 3441 %}
 3442 
 3443 // Convert FPU flags into +1,0,-1
 3444 pipe_class floating_cmp( iRegI dst, regF src1, regF src2 ) %{
 3445     src1  : E(read);
 3446     src2  : E(read);
 3447     dst   : E(write);
 3448     FA    : R;
 3449     MS    : R(2);
 3450     BR    : R(2);
 3451 %}
 3452 
 3453 // Compare for p < q, and conditionally add y
 3454 pipe_class cadd_cmpltmask( iRegI p, iRegI q, iRegI y ) %{
 3455     p     : E(read);
 3456     q     : E(read);
 3457     y     : E(read);
 3458     IALU  : R(3)
 3459 %}
 3460 
 3461 // Perform a compare, then move conditionally in a branch delay slot.
 3462 pipe_class min_max( iRegI src2, iRegI srcdst ) %{
 3463     src2   : E(read);
 3464     srcdst : E(read);
 3465     IALU   : R;
 3466     BR     : R;
 3467 %}
 3468 
 3469 // Define the class for the Nop node
 3470 define %{
 3471    MachNop = ialu_nop;
 3472 %}
 3473 
 3474 %}
 3475 
 3476 //----------INSTRUCTIONS-------------------------------------------------------
 3477 
 3478 //------------Special Nop instructions for bundling - no match rules-----------
 3479 // Nop using the A0 functional unit
 3480 instruct Nop_A0() %{
 3481   ins_pipe(ialu_nop_A0);
 3482 %}
 3483 
 3484 // Nop using the A1 functional unit
 3485 instruct Nop_A1( ) %{
 3486   ins_pipe(ialu_nop_A1);
 3487 %}
 3488 
 3489 // Nop using the memory functional unit
 3490 instruct Nop_MS( ) %{
 3491   ins_pipe(mem_nop);
 3492 %}
 3493 
 3494 // Nop using the floating add functional unit
 3495 instruct Nop_FA( ) %{
 3496   ins_pipe(fadd_nop);
 3497 %}
 3498 
 3499 // Nop using the branch functional unit
 3500 instruct Nop_BR( ) %{
 3501   ins_pipe(br_nop);
 3502 %}
 3503 
 3504 //----------Load/Store/Move Instructions---------------------------------------
 3505 //----------Load Instructions--------------------------------------------------
 3506 // Load Byte (8bit signed)
 3507 instruct loadB(iRegI dst, memoryB mem) %{
 3508   match(Set dst (LoadB mem));
 3509   ins_cost(MEMORY_REF_COST);
 3510 
 3511   size(4);
 3512   format %{ "LDRSB   $dst,$mem\t! byte -> int" %}
 3513   ins_encode %{
 3514     __ ldrsb($dst$$Register, $mem$$Address);
 3515   %}
 3516   ins_pipe(iload_mask_mem);
 3517 %}
 3518 
 3519 // Load Byte (8bit signed) into a Long Register
 3520 instruct loadB2L(iRegL dst, memoryB mem) %{
 3521   match(Set dst (ConvI2L (LoadB mem)));
 3522   ins_cost(MEMORY_REF_COST);
 3523 
 3524   size(8);
 3525   format %{ "LDRSB $dst.lo,$mem\t! byte -> long\n\t"
 3526             "ASR   $dst.hi,$dst.lo,31" %}
 3527   ins_encode %{
 3528     __ ldrsb($dst$$Register, $mem$$Address);
 3529     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
 3530   %}
 3531   ins_pipe(iload_mask_mem);
 3532 %}
 3533 
 3534 // Load Unsigned Byte (8bit UNsigned) into an int reg
 3535 instruct loadUB(iRegI dst, memoryB mem) %{
 3536   match(Set dst (LoadUB mem));
 3537   ins_cost(MEMORY_REF_COST);
 3538 
 3539   size(4);
 3540   format %{ "LDRB   $dst,$mem\t! ubyte -> int" %}
 3541   ins_encode %{
 3542     __ ldrb($dst$$Register, $mem$$Address);
 3543   %}
 3544   ins_pipe(iload_mem);
 3545 %}
 3546 
 3547 // Load Unsigned Byte (8bit UNsigned) into a Long Register
 3548 instruct loadUB2L(iRegL dst, memoryB mem) %{
 3549   match(Set dst (ConvI2L (LoadUB mem)));
 3550   ins_cost(MEMORY_REF_COST);
 3551 
 3552   size(8);
 3553   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
 3554             "MOV   $dst.hi,0" %}
 3555   ins_encode %{
 3556     __ ldrb($dst$$Register, $mem$$Address);
 3557     __ mov($dst$$Register->successor(), 0);
 3558   %}
 3559   ins_pipe(iload_mem);
 3560 %}
 3561 
 3562 // Load Unsigned Byte (8 bit UNsigned) with immediate mask into Long Register
 3563 instruct loadUB2L_limmI(iRegL dst, memoryB mem, limmIlow8 mask) %{
 3564   match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
 3565 
 3566   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 3567   size(12);
 3568   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
 3569             "MOV   $dst.hi,0\n\t"
 3570             "AND  $dst.lo,$dst.lo,$mask" %}
 3571   ins_encode %{
 3572     __ ldrb($dst$$Register, $mem$$Address);
 3573     __ mov($dst$$Register->successor(), 0);
 3574     __ andr($dst$$Register, $dst$$Register, limmI_low($mask$$constant, 8));
 3575   %}
 3576   ins_pipe(iload_mem);
 3577 %}
 3578 
 3579 // Load Short (16bit signed)
 3580 
 3581 instruct loadS(iRegI dst, memoryS mem) %{
 3582   match(Set dst (LoadS mem));
 3583   ins_cost(MEMORY_REF_COST);
 3584 
 3585   size(4);
 3586   format %{ "LDRSH   $dst,$mem\t! short" %}
 3587   ins_encode %{
 3588     __ ldrsh($dst$$Register, $mem$$Address);
 3589   %}
 3590   ins_pipe(iload_mask_mem);
 3591 %}
 3592 
 3593 // Load Short (16 bit signed) to Byte (8 bit signed)
 3594 instruct loadS2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
 3595   match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
 3596   ins_cost(MEMORY_REF_COST);
 3597 
 3598   size(4);
 3599 
 3600   format %{ "LDRSB   $dst,$mem\t! short -> byte" %}
 3601   ins_encode %{
 3602     __ ldrsb($dst$$Register, $mem$$Address);
 3603   %}
 3604   ins_pipe(iload_mask_mem);
 3605 %}
 3606 
 3607 // Load Short (16bit signed) into a Long Register
 3608 instruct loadS2L(iRegL dst, memoryS mem) %{
 3609   match(Set dst (ConvI2L (LoadS mem)));
 3610   ins_cost(MEMORY_REF_COST);
 3611 
 3612   size(8);
 3613   format %{ "LDRSH $dst.lo,$mem\t! short -> long\n\t"
 3614             "ASR   $dst.hi,$dst.lo,31" %}
 3615   ins_encode %{
 3616     __ ldrsh($dst$$Register, $mem$$Address);
 3617     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
 3618   %}
 3619   ins_pipe(iload_mask_mem);
 3620 %}
 3621 
 3622 // Load Unsigned Short/Char (16bit UNsigned)
 3623 
 3624 
 3625 instruct loadUS(iRegI dst, memoryS mem) %{
 3626   match(Set dst (LoadUS mem));
 3627   ins_cost(MEMORY_REF_COST);
 3628 
 3629   size(4);
 3630   format %{ "LDRH   $dst,$mem\t! ushort/char" %}
 3631   ins_encode %{
 3632     __ ldrh($dst$$Register, $mem$$Address);
 3633   %}
 3634   ins_pipe(iload_mem);
 3635 %}
 3636 
 3637 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
 3638 instruct loadUS2B(iRegI dst, memoryB mem, immI_24 twentyfour) %{
 3639   match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
 3640   ins_cost(MEMORY_REF_COST);
 3641 
 3642   size(4);
 3643   format %{ "LDRSB   $dst,$mem\t! ushort -> byte" %}
 3644   ins_encode %{
 3645     __ ldrsb($dst$$Register, $mem$$Address);
 3646   %}
 3647   ins_pipe(iload_mask_mem);
 3648 %}
 3649 
 3650 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register
 3651 instruct loadUS2L(iRegL dst, memoryS mem) %{
 3652   match(Set dst (ConvI2L (LoadUS mem)));
 3653   ins_cost(MEMORY_REF_COST);
 3654 
 3655   size(8);
 3656   format %{ "LDRH  $dst.lo,$mem\t! short -> long\n\t"
 3657             "MOV   $dst.hi, 0" %}
 3658   ins_encode %{
 3659     __ ldrh($dst$$Register, $mem$$Address);
 3660     __ mov($dst$$Register->successor(), 0);
 3661   %}
 3662   ins_pipe(iload_mem);
 3663 %}
 3664 
 3665 // Load Unsigned Short/Char (16bit UNsigned) with mask 0xFF into a Long Register
 3666 instruct loadUS2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
 3667   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
 3668   ins_cost(MEMORY_REF_COST);
 3669 
 3670   size(8);
 3671   format %{ "LDRB  $dst.lo,$mem\t! \n\t"
 3672             "MOV   $dst.hi, 0" %}
 3673   ins_encode %{
 3674     __ ldrb($dst$$Register, $mem$$Address);
 3675     __ mov($dst$$Register->successor(), 0);
 3676   %}
 3677   ins_pipe(iload_mem);
 3678 %}
 3679 
 3680 // Load Unsigned Short/Char (16bit UNsigned) with a immediate mask into a Long Register
 3681 instruct loadUS2L_limmI(iRegL dst, memoryS mem, limmI mask) %{
 3682   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
 3683   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 3684 
 3685   size(12);
 3686   format %{ "LDRH   $dst,$mem\t! ushort/char & mask -> long\n\t"
 3687             "MOV    $dst.hi, 0\n\t"
 3688             "AND    $dst,$dst,$mask" %}
 3689   ins_encode %{
 3690     __ ldrh($dst$$Register, $mem$$Address);
 3691     __ mov($dst$$Register->successor(), 0);
 3692     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
 3693   %}
 3694   ins_pipe(iload_mem);
 3695 %}
 3696 
 3697 // Load Integer
 3698 
 3699 
 3700 instruct loadI(iRegI dst, memoryI mem) %{
 3701   match(Set dst (LoadI mem));
 3702   ins_cost(MEMORY_REF_COST);
 3703 
 3704   size(4);
 3705   format %{ "ldr_s32 $dst,$mem\t! int" %}
 3706   ins_encode %{
 3707     __ ldr_s32($dst$$Register, $mem$$Address);
 3708   %}
 3709   ins_pipe(iload_mem);
 3710 %}
 3711 
 3712 // Load Integer to Byte (8 bit signed)
 3713 instruct loadI2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
 3714   match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
 3715   ins_cost(MEMORY_REF_COST);
 3716 
 3717   size(4);
 3718 
 3719   format %{ "LDRSB   $dst,$mem\t! int -> byte" %}
 3720   ins_encode %{
 3721     __ ldrsb($dst$$Register, $mem$$Address);
 3722   %}
 3723   ins_pipe(iload_mask_mem);
 3724 %}
 3725 
 3726 // Load Integer to Unsigned Byte (8 bit UNsigned)
 3727 instruct loadI2UB(iRegI dst, memoryB mem, immI_255 mask) %{
 3728   match(Set dst (AndI (LoadI mem) mask));
 3729   ins_cost(MEMORY_REF_COST);
 3730 
 3731   size(4);
 3732 
 3733   format %{ "LDRB   $dst,$mem\t! int -> ubyte" %}
 3734   ins_encode %{
 3735     __ ldrb($dst$$Register, $mem$$Address);
 3736   %}
 3737   ins_pipe(iload_mask_mem);
 3738 %}
 3739 
 3740 // Load Integer to Short (16 bit signed)
 3741 instruct loadI2S(iRegI dst, memoryS mem, immI_16 sixteen) %{
 3742   match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
 3743   ins_cost(MEMORY_REF_COST);
 3744 
 3745   size(4);
 3746   format %{ "LDRSH   $dst,$mem\t! int -> short" %}
 3747   ins_encode %{
 3748     __ ldrsh($dst$$Register, $mem$$Address);
 3749   %}
 3750   ins_pipe(iload_mask_mem);
 3751 %}
 3752 
 3753 // Load Integer to Unsigned Short (16 bit UNsigned)
 3754 instruct loadI2US(iRegI dst, memoryS mem, immI_65535 mask) %{
 3755   match(Set dst (AndI (LoadI mem) mask));
 3756   ins_cost(MEMORY_REF_COST);
 3757 
 3758   size(4);
 3759   format %{ "LDRH   $dst,$mem\t! int -> ushort/char" %}
 3760   ins_encode %{
 3761     __ ldrh($dst$$Register, $mem$$Address);
 3762   %}
 3763   ins_pipe(iload_mask_mem);
 3764 %}
 3765 
 3766 // Load Integer into a Long Register
 3767 instruct loadI2L(iRegL dst, memoryI mem) %{
 3768   match(Set dst (ConvI2L (LoadI mem)));
 3769   ins_cost(MEMORY_REF_COST);
 3770 
 3771   size(8);
 3772   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
 3773             "ASR   $dst.hi,$dst.lo,31\t! int->long" %}
 3774   ins_encode %{
 3775     __ ldr($dst$$Register, $mem$$Address);
 3776     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
 3777   %}
 3778   ins_pipe(iload_mask_mem);
 3779 %}
 3780 
 3781 // Load Integer with mask 0xFF into a Long Register
 3782 instruct loadI2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
 3783   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3784   ins_cost(MEMORY_REF_COST);
 3785 
 3786   size(8);
 3787   format %{ "LDRB   $dst.lo,$mem\t! int & 0xFF -> long\n\t"
 3788             "MOV    $dst.hi, 0" %}
 3789   ins_encode %{
 3790     __ ldrb($dst$$Register, $mem$$Address);
 3791     __ mov($dst$$Register->successor(), 0);
 3792   %}
 3793   ins_pipe(iload_mem);
 3794 %}
 3795 
 3796 // Load Integer with mask 0xFFFF into a Long Register
 3797 instruct loadI2L_immI_65535(iRegL dst, memoryS mem, immI_65535 mask) %{
 3798   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3799   ins_cost(MEMORY_REF_COST);
 3800 
 3801   size(8);
 3802   format %{ "LDRH   $dst,$mem\t! int & 0xFFFF -> long\n\t"
 3803             "MOV    $dst.hi, 0" %}
 3804   ins_encode %{
 3805     __ ldrh($dst$$Register, $mem$$Address);
 3806     __ mov($dst$$Register->successor(), 0);
 3807   %}
 3808   ins_pipe(iload_mask_mem);
 3809 %}
 3810 
 3811 // Load Integer with a 31-bit immediate mask into a Long Register
 3812 instruct loadI2L_limmU31(iRegL dst, memoryI mem, limmU31 mask) %{
 3813   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3814   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 3815 
 3816   size(12);
 3817   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
 3818             "MOV    $dst.hi, 0\n\t"
 3819             "AND   $dst,$dst,$mask" %}
 3820 
 3821   ins_encode %{
 3822     __ ldr($dst$$Register, $mem$$Address);
 3823     __ mov($dst$$Register->successor(), 0);
 3824     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
 3825   %}
 3826   ins_pipe(iload_mem);
 3827 %}
 3828 
 3829 // Load Integer with a 31-bit mask into a Long Register
 3830 // FIXME: use iRegI mask, remove tmp?
 3831 instruct loadI2L_immU31(iRegL dst, memoryI mem, immU31 mask, iRegI tmp) %{
 3832   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3833   effect(TEMP dst, TEMP tmp);
 3834 
 3835   ins_cost(MEMORY_REF_COST + 4*DEFAULT_COST);
 3836   size(20);
 3837   format %{ "LDR      $mem,$dst\t! int & 31-bit mask -> long\n\t"
 3838             "MOV      $dst.hi, 0\n\t"
 3839             "MOV_SLOW $tmp,$mask\n\t"
 3840             "AND      $dst,$tmp,$dst" %}
 3841   ins_encode %{
 3842     __ ldr($dst$$Register, $mem$$Address);
 3843     __ mov($dst$$Register->successor(), 0);
 3844     __ mov_slow($tmp$$Register, $mask$$constant);
 3845     __ andr($dst$$Register, $dst$$Register, $tmp$$Register);
 3846   %}
 3847   ins_pipe(iload_mem);
 3848 %}
 3849 
 3850 // Load Unsigned Integer into a Long Register
 3851 instruct loadUI2L(iRegL dst, memoryI mem, immL_32bits mask) %{
 3852   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
 3853   ins_cost(MEMORY_REF_COST);
 3854 
 3855   size(8);
 3856   format %{ "LDR   $dst.lo,$mem\t! uint -> long\n\t"
 3857             "MOV   $dst.hi,0" %}
 3858   ins_encode %{
 3859     __ ldr($dst$$Register, $mem$$Address);
 3860     __ mov($dst$$Register->successor(), 0);
 3861   %}
 3862   ins_pipe(iload_mem);
 3863 %}
 3864 
 3865 // Load Long
 3866 
 3867 
 3868 instruct loadL(iRegLd dst, memoryL mem ) %{
 3869   predicate(!((LoadLNode*)n)->require_atomic_access());
 3870   match(Set dst (LoadL mem));
 3871   effect(TEMP dst);
 3872   ins_cost(MEMORY_REF_COST);
 3873 
 3874   size(4);
 3875   format %{ "ldr_64  $dst,$mem\t! long" %}
 3876   ins_encode %{
 3877     __ ldr_64($dst$$Register, $mem$$Address);
 3878   %}
 3879   ins_pipe(iload_mem);
 3880 %}
 3881 
 3882 instruct loadL_2instr(iRegL dst, memorylong mem ) %{
 3883   predicate(!((LoadLNode*)n)->require_atomic_access());
 3884   match(Set dst (LoadL mem));
 3885   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
 3886 
 3887   size(8);
 3888   format %{ "LDR    $dst.lo,$mem \t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
 3889             "LDR    $dst.hi,$mem+4 or $mem" %}
 3890   ins_encode %{
 3891     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 3892     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 3893 
 3894     if ($dst$$Register == reg_to_register_object($mem$$base)) {
 3895       __ ldr($dst$$Register->successor(), Amemhi);
 3896       __ ldr($dst$$Register, Amemlo);
 3897     } else {
 3898       __ ldr($dst$$Register, Amemlo);
 3899       __ ldr($dst$$Register->successor(), Amemhi);
 3900     }
 3901   %}
 3902   ins_pipe(iload_mem);
 3903 %}
 3904 
 3905 instruct loadL_volatile(iRegL dst, indirect mem ) %{
 3906   predicate(((LoadLNode*)n)->require_atomic_access());
 3907   match(Set dst (LoadL mem));
 3908   ins_cost(MEMORY_REF_COST);
 3909 
 3910   size(4);
 3911   format %{ "LDMIA    $dst,$mem\t! long" %}
 3912   ins_encode %{
 3913     // FIXME: why is ldmia considered atomic?  Should be ldrexd
 3914     RegisterSet set($dst$$Register);
 3915     set = set | reg_to_register_object($dst$$reg + 1);
 3916     __ ldmia(reg_to_register_object($mem$$base), set);
 3917   %}
 3918   ins_pipe(iload_mem);
 3919 %}
 3920 
 3921 instruct loadL_volatile_fp(iRegL dst, memoryD mem ) %{
 3922   predicate(((LoadLNode*)n)->require_atomic_access());
 3923   match(Set dst (LoadL mem));
 3924   ins_cost(MEMORY_REF_COST);
 3925 
 3926   size(8);
 3927   format %{ "FLDD      S14, $mem"
 3928             "FMRRD    $dst, S14\t! long \n't" %}
 3929   ins_encode %{
 3930     __ fldd(S14, $mem$$Address);
 3931     __ fmrrd($dst$$Register, $dst$$Register->successor(), S14);
 3932   %}
 3933   ins_pipe(iload_mem);
 3934 %}
 3935 
 3936 instruct loadL_unaligned(iRegL dst, memorylong mem ) %{
 3937   match(Set dst (LoadL_unaligned mem));
 3938   ins_cost(MEMORY_REF_COST);
 3939 
 3940   size(8);
 3941   format %{ "LDR    $dst.lo,$mem\t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
 3942             "LDR    $dst.hi,$mem+4" %}
 3943   ins_encode %{
 3944     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 3945     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 3946 
 3947     if ($dst$$Register == reg_to_register_object($mem$$base)) {
 3948       __ ldr($dst$$Register->successor(), Amemhi);
 3949       __ ldr($dst$$Register, Amemlo);
 3950     } else {
 3951       __ ldr($dst$$Register, Amemlo);
 3952       __ ldr($dst$$Register->successor(), Amemhi);
 3953     }
 3954   %}
 3955   ins_pipe(iload_mem);
 3956 %}
 3957 
 3958 // Load Range
 3959 instruct loadRange(iRegI dst, memoryI mem) %{
 3960   match(Set dst (LoadRange mem));
 3961   ins_cost(MEMORY_REF_COST);
 3962 
 3963   size(4);
 3964   format %{ "LDR_u32 $dst,$mem\t! range" %}
 3965   ins_encode %{
 3966     __ ldr_u32($dst$$Register, $mem$$Address);
 3967   %}
 3968   ins_pipe(iload_mem);
 3969 %}
 3970 
 3971 // Load Pointer
 3972 
 3973 
 3974 instruct loadP(iRegP dst, memoryP mem) %{
 3975   match(Set dst (LoadP mem));
 3976   ins_cost(MEMORY_REF_COST);
 3977   size(4);
 3978 
 3979   format %{ "LDR   $dst,$mem\t! ptr" %}
 3980   ins_encode %{
 3981     __ ldr($dst$$Register, $mem$$Address);
 3982   %}
 3983   ins_pipe(iload_mem);
 3984 %}
 3985 
 3986 #ifdef XXX
 3987 // FIXME XXXX
 3988 //instruct loadSP(iRegP dst, memoryP mem) %{
 3989 instruct loadSP(SPRegP dst, memoryP mem, iRegP tmp) %{
 3990   match(Set dst (LoadP mem));
 3991   effect(TEMP tmp);
 3992   ins_cost(MEMORY_REF_COST+1);
 3993   size(8);
 3994 
 3995   format %{ "LDR   $tmp,$mem\t! ptr\n\t"
 3996             "MOV   $dst,$tmp\t! ptr" %}
 3997   ins_encode %{
 3998     __ ldr($tmp$$Register, $mem$$Address);
 3999     __ mov($dst$$Register, $tmp$$Register);
 4000   %}
 4001   ins_pipe(iload_mem);
 4002 %}
 4003 #endif
 4004 
 4005 #ifdef _LP64
 4006 // Load Compressed Pointer
 4007 
 4008 // XXX This variant shouldn't be necessary if 6217251 is implemented
 4009 instruct loadNoff(iRegN dst, memoryScaledI mem, aimmX off, iRegP tmp) %{
 4010   match(Set dst (LoadN (AddP mem off)));
 4011   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
 4012   effect(TEMP tmp);
 4013   size(4 * 2);
 4014 
 4015   format %{ "ldr_u32 $dst,$mem+$off\t! compressed ptr temp=$tmp" %}
 4016   ins_encode %{
 4017     Register base = reg_to_register_object($mem$$base);
 4018     __ add($tmp$$Register, base, $off$$constant);
 4019     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 4020     __ ldr_u32($dst$$Register, nmem);
 4021   %}
 4022   ins_pipe(iload_mem);
 4023 %}
 4024 
 4025 instruct loadN(iRegN dst, memoryI mem) %{
 4026   match(Set dst (LoadN mem));
 4027   ins_cost(MEMORY_REF_COST);
 4028   size(4);
 4029 
 4030   format %{ "ldr_u32 $dst,$mem\t! compressed ptr" %}
 4031   ins_encode %{
 4032     __ ldr_u32($dst$$Register, $mem$$Address);
 4033   %}
 4034   ins_pipe(iload_mem);
 4035 %}
 4036 #endif
 4037 
 4038 // Load Klass Pointer
 4039 instruct loadKlass(iRegP dst, memoryI mem) %{
 4040   match(Set dst (LoadKlass mem));
 4041   ins_cost(MEMORY_REF_COST);
 4042   size(4);
 4043 
 4044   format %{ "LDR   $dst,$mem\t! klass ptr" %}
 4045   ins_encode %{
 4046     __ ldr($dst$$Register, $mem$$Address);
 4047   %}
 4048   ins_pipe(iload_mem);
 4049 %}
 4050 
 4051 #ifdef _LP64
 4052 // Load narrow Klass Pointer
 4053 instruct loadNKlass(iRegN dst, memoryI mem) %{
 4054   match(Set dst (LoadNKlass mem));
 4055   ins_cost(MEMORY_REF_COST);
 4056   size(4);
 4057 
 4058   format %{ "ldr_u32 $dst,$mem\t! compressed klass ptr" %}
 4059   ins_encode %{
 4060     __ ldr_u32($dst$$Register, $mem$$Address);
 4061   %}
 4062   ins_pipe(iload_mem);
 4063 %}
 4064 #endif
 4065 
 4066 
 4067 instruct loadD(regD dst, memoryD mem) %{
 4068   match(Set dst (LoadD mem));
 4069   ins_cost(MEMORY_REF_COST);
 4070 
 4071   size(4);
 4072   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
 4073   // only LDREXD and STREXD are 64-bit single-copy atomic
 4074   format %{ "FLDD   $dst,$mem" %}
 4075   ins_encode %{
 4076     __ ldr_double($dst$$FloatRegister, $mem$$Address);
 4077   %}
 4078   ins_pipe(floadD_mem);
 4079 %}
 4080 
 4081 // Load Double - UNaligned
 4082 instruct loadD_unaligned(regD_low dst, memoryF2 mem ) %{
 4083   match(Set dst (LoadD_unaligned mem));
 4084   ins_cost(MEMORY_REF_COST*2+DEFAULT_COST);
 4085   size(8);
 4086   format %{ "FLDS    $dst.lo,$mem\t! misaligned double\n"
 4087           "\tFLDS    $dst.hi,$mem+4\t!" %}
 4088   ins_encode %{
 4089     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 4090     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 4091       __ flds($dst$$FloatRegister, Amemlo);
 4092       __ flds($dst$$FloatRegister->successor(), Amemhi);
 4093   %}
 4094   ins_pipe(iload_mem);
 4095 %}
 4096 
 4097 
 4098 instruct loadF(regF dst, memoryF mem) %{
 4099   match(Set dst (LoadF mem));
 4100 
 4101   ins_cost(MEMORY_REF_COST);
 4102   size(4);
 4103   format %{ "FLDS    $dst,$mem" %}
 4104   ins_encode %{
 4105     __ ldr_float($dst$$FloatRegister, $mem$$Address);
 4106   %}
 4107   ins_pipe(floadF_mem);
 4108 %}
 4109 
 4110 
 4111 // // Load Constant
 4112 instruct loadConI( iRegI dst, immI src ) %{
 4113   match(Set dst src);
 4114   ins_cost(DEFAULT_COST * 3/2);
 4115   format %{ "MOV_SLOW    $dst, $src" %}
 4116   ins_encode %{
 4117     __ mov_slow($dst$$Register, $src$$constant);
 4118   %}
 4119   ins_pipe(ialu_hi_lo_reg);
 4120 %}
 4121 
 4122 instruct loadConIMov( iRegI dst, immIMov src ) %{
 4123   match(Set dst src);
 4124   size(4);
 4125   format %{ "MOV    $dst, $src" %}
 4126   ins_encode %{
 4127     __ mov($dst$$Register, $src$$constant);
 4128   %}
 4129   ins_pipe(ialu_imm);
 4130 %}
 4131 
 4132 instruct loadConIMovn( iRegI dst, immIRotn src ) %{
 4133   match(Set dst src);
 4134   size(4);
 4135   format %{ "MVN    $dst, ~$src" %}
 4136   ins_encode %{
 4137     __ mvn($dst$$Register, ~$src$$constant);
 4138   %}
 4139   ins_pipe(ialu_imm_n);
 4140 %}
 4141 
 4142 instruct loadConI16( iRegI dst, immI16 src ) %{
 4143   match(Set dst src);
 4144   size(4);
 4145   format %{ "MOVW    $dst, $src" %}
 4146   ins_encode %{
 4147     __ movw($dst$$Register, $src$$constant);
 4148   %}
 4149   ins_pipe(ialu_imm_n);
 4150 %}
 4151 
 4152 instruct loadConP(iRegP dst, immP src) %{
 4153   match(Set dst src);
 4154   ins_cost(DEFAULT_COST * 3/2);
 4155   format %{ "MOV_SLOW    $dst,$src\t!ptr" %}
 4156   ins_encode %{
 4157     relocInfo::relocType constant_reloc = _opnds[1]->constant_reloc();
 4158     intptr_t val = $src$$constant;
 4159     if (constant_reloc == relocInfo::oop_type) {
 4160       __ mov_oop($dst$$Register, (jobject)val);
 4161     } else if (constant_reloc == relocInfo::metadata_type) {
 4162       __ mov_metadata($dst$$Register, (Metadata*)val);
 4163     } else {
 4164       __ mov_slow($dst$$Register, val);
 4165     }
 4166   %}
 4167   ins_pipe(loadConP);
 4168 %}
 4169 
 4170 
 4171 instruct loadConL(iRegL dst, immL src) %{
 4172   match(Set dst src);
 4173   ins_cost(DEFAULT_COST * 4);
 4174   format %{ "MOV_SLOW   $dst.lo, $src & 0x0FFFFFFFFL \t! long\n\t"
 4175             "MOV_SLOW   $dst.hi, $src >> 32" %}
 4176   ins_encode %{
 4177     __ mov_slow(reg_to_register_object($dst$$reg), $src$$constant & 0x0FFFFFFFFL);
 4178     __ mov_slow(reg_to_register_object($dst$$reg + 1), ((julong)($src$$constant)) >> 32);
 4179   %}
 4180   ins_pipe(loadConL);
 4181 %}
 4182 
 4183 instruct loadConL16( iRegL dst, immL16 src ) %{
 4184   match(Set dst src);
 4185   ins_cost(DEFAULT_COST * 2);
 4186 
 4187   size(8);
 4188   format %{ "MOVW    $dst.lo, $src \n\t"
 4189             "MOVW    $dst.hi, 0 \n\t" %}
 4190   ins_encode %{
 4191     __ movw($dst$$Register, $src$$constant);
 4192     __ movw($dst$$Register->successor(), 0);
 4193   %}
 4194   ins_pipe(ialu_imm);
 4195 %}
 4196 
 4197 instruct loadConF_imm8(regF dst, imm8F src) %{
 4198   match(Set dst src);
 4199   ins_cost(DEFAULT_COST);
 4200   size(4);
 4201 
 4202   format %{ "FCONSTS      $dst, $src"%}
 4203 
 4204   ins_encode %{
 4205     __ fconsts($dst$$FloatRegister, Assembler::float_num($src$$constant).imm8());
 4206   %}
 4207   ins_pipe(loadConFD); // FIXME
 4208 %}
 4209 
 4210 
 4211 instruct loadConF(regF dst, immF src, iRegI tmp) %{
 4212   match(Set dst src);
 4213   ins_cost(DEFAULT_COST * 2);
 4214   effect(TEMP tmp);
 4215   size(3*4);
 4216 
 4217   format %{ "MOV_SLOW  $tmp, $src\n\t"
 4218             "FMSR      $dst, $tmp"%}
 4219 
 4220   ins_encode %{
 4221     // FIXME revisit once 6961697 is in
 4222     union {
 4223       jfloat f;
 4224       int i;
 4225     } v;
 4226     v.f = $src$$constant;
 4227     __ mov_slow($tmp$$Register, v.i);
 4228     __ fmsr($dst$$FloatRegister, $tmp$$Register);
 4229   %}
 4230   ins_pipe(loadConFD); // FIXME
 4231 %}
 4232 
 4233 instruct loadConD_imm8(regD dst, imm8D src) %{
 4234   match(Set dst src);
 4235   ins_cost(DEFAULT_COST);
 4236   size(4);
 4237 
 4238   format %{ "FCONSTD      $dst, $src"%}
 4239 
 4240   ins_encode %{
 4241     __ fconstd($dst$$FloatRegister, Assembler::double_num($src$$constant).imm8());
 4242   %}
 4243   ins_pipe(loadConFD); // FIXME
 4244 %}
 4245 
 4246 instruct loadConD(regD dst, immD src, iRegP tmp) %{
 4247   match(Set dst src);
 4248   effect(TEMP tmp);
 4249   ins_cost(MEMORY_REF_COST);
 4250   format %{ "FLDD  $dst, [$constanttablebase + $constantoffset]\t! load from constant table: double=$src" %}
 4251 
 4252   ins_encode %{
 4253     Register r = $constanttablebase;
 4254     int offset  = $constantoffset($src);
 4255     if (!is_memoryD(offset)) {                // can't use a predicate
 4256                                               // in load constant instructs
 4257       __ add_slow($tmp$$Register, r, offset);
 4258       r = $tmp$$Register;
 4259       offset = 0;
 4260     }
 4261     __ ldr_double($dst$$FloatRegister, Address(r, offset));
 4262   %}
 4263   ins_pipe(loadConFD);
 4264 %}
 4265 
 4266 // Prefetch instructions.
 4267 // Must be safe to execute with invalid address (cannot fault).
 4268 
 4269 instruct prefetchAlloc_mp( memoryP mem ) %{
 4270   predicate(VM_Version::has_multiprocessing_extensions());
 4271   match( PrefetchAllocation mem );
 4272   ins_cost(MEMORY_REF_COST);
 4273   size(4);
 4274 
 4275   format %{ "PLDW $mem\t! Prefetch allocation" %}
 4276   ins_encode %{
 4277     __ pldw($mem$$Address);
 4278   %}
 4279   ins_pipe(iload_mem);
 4280 %}
 4281 
 4282 instruct prefetchAlloc_sp( memoryP mem ) %{
 4283   predicate(!VM_Version::has_multiprocessing_extensions());
 4284   match( PrefetchAllocation mem );
 4285   ins_cost(MEMORY_REF_COST);
 4286   size(4);
 4287 
 4288   format %{ "PLD $mem\t! Prefetch allocation" %}
 4289   ins_encode %{
 4290     __ pld($mem$$Address);
 4291   %}
 4292   ins_pipe(iload_mem);
 4293 %}
 4294 
 4295 
 4296 //----------Store Instructions-------------------------------------------------
 4297 // Store Byte
 4298 instruct storeB(memoryB mem, store_RegI src) %{
 4299   match(Set mem (StoreB mem src));
 4300   ins_cost(MEMORY_REF_COST);
 4301 
 4302   size(4);
 4303   format %{ "STRB    $src,$mem\t! byte" %}
 4304   ins_encode %{
 4305     __ strb($src$$Register, $mem$$Address);
 4306   %}
 4307   ins_pipe(istore_mem_reg);
 4308 %}
 4309 
 4310 instruct storeCM(memoryB mem, store_RegI src) %{
 4311   match(Set mem (StoreCM mem src));
 4312   ins_cost(MEMORY_REF_COST);
 4313 
 4314   size(4);
 4315   format %{ "STRB    $src,$mem\t! CMS card-mark byte" %}
 4316   ins_encode %{
 4317     __ strb($src$$Register, $mem$$Address);
 4318   %}
 4319   ins_pipe(istore_mem_reg);
 4320 %}
 4321 
 4322 // Store Char/Short
 4323 
 4324 
 4325 instruct storeC(memoryS mem, store_RegI src) %{
 4326   match(Set mem (StoreC mem src));
 4327   ins_cost(MEMORY_REF_COST);
 4328 
 4329   size(4);
 4330   format %{ "STRH    $src,$mem\t! short" %}
 4331   ins_encode %{
 4332     __ strh($src$$Register, $mem$$Address);
 4333   %}
 4334   ins_pipe(istore_mem_reg);
 4335 %}
 4336 
 4337 // Store Integer
 4338 
 4339 
 4340 instruct storeI(memoryI mem, store_RegI src) %{
 4341   match(Set mem (StoreI mem src));
 4342   ins_cost(MEMORY_REF_COST);
 4343 
 4344   size(4);
 4345   format %{ "str_32 $src,$mem" %}
 4346   ins_encode %{
 4347     __ str_32($src$$Register, $mem$$Address);
 4348   %}
 4349   ins_pipe(istore_mem_reg);
 4350 %}
 4351 
 4352 // Store Long
 4353 
 4354 
 4355 instruct storeL(memoryL mem, store_RegLd src) %{
 4356   predicate(!((StoreLNode*)n)->require_atomic_access());
 4357   match(Set mem (StoreL mem src));
 4358   ins_cost(MEMORY_REF_COST);
 4359 
 4360   size(4);
 4361   format %{ "str_64  $src,$mem\t! long\n\t" %}
 4362 
 4363   ins_encode %{
 4364     __ str_64($src$$Register, $mem$$Address);
 4365   %}
 4366   ins_pipe(istore_mem_reg);
 4367 %}
 4368 
 4369 instruct storeL_2instr(memorylong mem, iRegL src) %{
 4370   predicate(!((StoreLNode*)n)->require_atomic_access());
 4371   match(Set mem (StoreL mem src));
 4372   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
 4373 
 4374   size(8);
 4375   format %{ "STR    $src.lo,$mem\t! long\n\t"
 4376             "STR    $src.hi,$mem+4" %}
 4377 
 4378   ins_encode %{
 4379     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 4380     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 4381     __ str($src$$Register, Amemlo);
 4382     __ str($src$$Register->successor(), Amemhi);
 4383   %}
 4384   ins_pipe(istore_mem_reg);
 4385 %}
 4386 
 4387 instruct storeL_volatile(indirect mem, iRegL src) %{
 4388   predicate(((StoreLNode*)n)->require_atomic_access());
 4389   match(Set mem (StoreL mem src));
 4390   ins_cost(MEMORY_REF_COST);
 4391   size(4);
 4392   format %{ "STMIA    $src,$mem\t! long" %}
 4393   ins_encode %{
 4394     // FIXME: why is stmia considered atomic?  Should be strexd
 4395     RegisterSet set($src$$Register);
 4396     set = set | reg_to_register_object($src$$reg + 1);
 4397     __ stmia(reg_to_register_object($mem$$base), set);
 4398   %}
 4399   ins_pipe(istore_mem_reg);
 4400 %}
 4401 
 4402 instruct storeL_volatile_fp(memoryD mem, iRegL src) %{
 4403   predicate(((StoreLNode*)n)->require_atomic_access());
 4404   match(Set mem (StoreL mem src));
 4405   ins_cost(MEMORY_REF_COST);
 4406   size(8);
 4407   format %{ "FMDRR    S14, $src\t! long \n\t"
 4408             "FSTD     S14, $mem" %}
 4409   ins_encode %{
 4410     __ fmdrr(S14, $src$$Register, $src$$Register->successor());
 4411     __ fstd(S14, $mem$$Address);
 4412   %}
 4413   ins_pipe(istore_mem_reg);
 4414 %}
 4415 
 4416 #ifdef XXX
 4417 // Move SP Pointer
 4418 //instruct movSP(sp_ptr_RegP dst, SPRegP src) %{
 4419 //instruct movSP(iRegP dst, SPRegP src) %{
 4420 instruct movSP(store_ptr_RegP dst, SPRegP src) %{
 4421   match(Set dst src);
 4422 //predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con == TypeFunc::FramePtr);
 4423   ins_cost(MEMORY_REF_COST);
 4424   size(4);
 4425 
 4426   format %{ "MOV    $dst,$src\t! SP ptr\n\t" %}
 4427   ins_encode %{
 4428     assert(false, "XXX1 got here");
 4429     __ mov($dst$$Register, SP);
 4430     __ mov($dst$$Register, $src$$Register);
 4431   %}
 4432   ins_pipe(ialu_reg);
 4433 %}
 4434 #endif
 4435 
 4436 
 4437 // Store Pointer
 4438 
 4439 
 4440 instruct storeP(memoryP mem, store_ptr_RegP src) %{
 4441   match(Set mem (StoreP mem src));
 4442   ins_cost(MEMORY_REF_COST);
 4443   size(4);
 4444 
 4445   format %{ "STR    $src,$mem\t! ptr" %}
 4446   ins_encode %{
 4447     __ str($src$$Register, $mem$$Address);
 4448   %}
 4449   ins_pipe(istore_mem_spORreg);
 4450 %}
 4451 
 4452 
 4453 #ifdef _LP64
 4454 // Store Compressed Pointer
 4455 
 4456 
 4457 instruct storeN(memoryI mem, store_RegN src) %{
 4458   match(Set mem (StoreN mem src));
 4459   ins_cost(MEMORY_REF_COST);
 4460   size(4);
 4461 
 4462   format %{ "str_32 $src,$mem\t! compressed ptr" %}
 4463   ins_encode %{
 4464     __ str_32($src$$Register, $mem$$Address);
 4465   %}
 4466   ins_pipe(istore_mem_reg);
 4467 %}
 4468 
 4469 
 4470 // Store Compressed Klass Pointer
 4471 instruct storeNKlass(memoryI mem, store_RegN src) %{
 4472   match(Set mem (StoreNKlass mem src));
 4473   ins_cost(MEMORY_REF_COST);
 4474   size(4);
 4475 
 4476   format %{ "str_32 $src,$mem\t! compressed klass ptr" %}
 4477   ins_encode %{
 4478     __ str_32($src$$Register, $mem$$Address);
 4479   %}
 4480   ins_pipe(istore_mem_reg);
 4481 %}
 4482 #endif
 4483 
 4484 // Store Double
 4485 
 4486 
 4487 instruct storeD(memoryD mem, regD src) %{
 4488   match(Set mem (StoreD mem src));
 4489   ins_cost(MEMORY_REF_COST);
 4490 
 4491   size(4);
 4492   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
 4493   // only LDREXD and STREXD are 64-bit single-copy atomic
 4494   format %{ "FSTD   $src,$mem" %}
 4495   ins_encode %{
 4496     __ str_double($src$$FloatRegister, $mem$$Address);
 4497   %}
 4498   ins_pipe(fstoreD_mem_reg);
 4499 %}
 4500 
 4501 
 4502 // Store Float
 4503 
 4504 
 4505 instruct storeF( memoryF mem, regF src) %{
 4506   match(Set mem (StoreF mem src));
 4507   ins_cost(MEMORY_REF_COST);
 4508 
 4509   size(4);
 4510   format %{ "FSTS    $src,$mem" %}
 4511   ins_encode %{
 4512     __ str_float($src$$FloatRegister, $mem$$Address);
 4513   %}
 4514   ins_pipe(fstoreF_mem_reg);
 4515 %}
 4516 
 4517 
 4518 //----------MemBar Instructions-----------------------------------------------
 4519 // Memory barrier flavors
 4520 
 4521 // pattern-match out unnecessary membars
 4522 instruct membar_storestore() %{
 4523   match(MemBarStoreStore);
 4524   ins_cost(4*MEMORY_REF_COST);
 4525 
 4526   size(4);
 4527   format %{ "MEMBAR-storestore" %}
 4528   ins_encode %{
 4529     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore), noreg);
 4530   %}
 4531   ins_pipe(long_memory_op);
 4532 %}
 4533 
 4534 instruct membar_acquire() %{
 4535   match(MemBarAcquire);
 4536   match(LoadFence);
 4537   ins_cost(4*MEMORY_REF_COST);
 4538 
 4539   size(4);
 4540   format %{ "MEMBAR-acquire" %}
 4541   ins_encode %{
 4542     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), noreg);
 4543   %}
 4544   ins_pipe(long_memory_op);
 4545 %}
 4546 
 4547 instruct membar_acquire_lock() %{
 4548   match(MemBarAcquireLock);
 4549   ins_cost(0);
 4550 
 4551   size(0);
 4552   format %{ "!MEMBAR-acquire (CAS in prior FastLock so empty encoding)" %}
 4553   ins_encode( );
 4554   ins_pipe(empty);
 4555 %}
 4556 
 4557 instruct membar_release() %{
 4558   match(MemBarRelease);
 4559   match(StoreFence);
 4560   ins_cost(4*MEMORY_REF_COST);
 4561 
 4562   size(4);
 4563   format %{ "MEMBAR-release" %}
 4564   ins_encode %{
 4565     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), noreg);
 4566   %}
 4567   ins_pipe(long_memory_op);
 4568 %}
 4569 
 4570 instruct membar_release_lock() %{
 4571   match(MemBarReleaseLock);
 4572   ins_cost(0);
 4573 
 4574   size(0);
 4575   format %{ "!MEMBAR-release (CAS in succeeding FastUnlock so empty encoding)" %}
 4576   ins_encode( );
 4577   ins_pipe(empty);
 4578 %}
 4579 
 4580 instruct membar_volatile() %{
 4581   match(MemBarVolatile);
 4582   ins_cost(4*MEMORY_REF_COST);
 4583 
 4584   size(4);
 4585   format %{ "MEMBAR-volatile" %}
 4586   ins_encode %{
 4587     __ membar(MacroAssembler::StoreLoad, noreg);
 4588   %}
 4589   ins_pipe(long_memory_op);
 4590 %}
 4591 
 4592 instruct unnecessary_membar_volatile() %{
 4593   match(MemBarVolatile);
 4594   predicate(Matcher::post_store_load_barrier(n));
 4595   ins_cost(0);
 4596 
 4597   size(0);
 4598   format %{ "!MEMBAR-volatile (unnecessary so empty encoding)" %}
 4599   ins_encode( );
 4600   ins_pipe(empty);
 4601 %}
 4602 
 4603 //----------Register Move Instructions-----------------------------------------
 4604 // instruct roundDouble_nop(regD dst) %{
 4605 //   match(Set dst (RoundDouble dst));
 4606 //   ins_pipe(empty);
 4607 // %}
 4608 
 4609 
 4610 // instruct roundFloat_nop(regF dst) %{
 4611 //   match(Set dst (RoundFloat dst));
 4612 //   ins_pipe(empty);
 4613 // %}
 4614 
 4615 
 4616 
 4617 // Cast Index to Pointer for unsafe natives
 4618 instruct castX2P(iRegX src, iRegP dst) %{
 4619   match(Set dst (CastX2P src));
 4620 
 4621   format %{ "MOV    $dst,$src\t! IntX->Ptr if $dst != $src" %}
 4622   ins_encode %{
 4623     if ($dst$$Register !=  $src$$Register) {
 4624       __ mov($dst$$Register, $src$$Register);
 4625     }
 4626   %}
 4627   ins_pipe(ialu_reg);
 4628 %}
 4629 
 4630 // Cast Pointer to Index for unsafe natives
 4631 instruct castP2X(iRegP src, iRegX dst) %{
 4632   match(Set dst (CastP2X src));
 4633 
 4634   format %{ "MOV    $dst,$src\t! Ptr->IntX if $dst != $src" %}
 4635   ins_encode %{
 4636     if ($dst$$Register !=  $src$$Register) {
 4637       __ mov($dst$$Register, $src$$Register);
 4638     }
 4639   %}
 4640   ins_pipe(ialu_reg);
 4641 %}
 4642 
 4643 //----------Conditional Move---------------------------------------------------
 4644 // Conditional move
 4645 instruct cmovIP_reg(cmpOpP cmp, flagsRegP pcc, iRegI dst, iRegI src) %{
 4646   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
 4647   ins_cost(150);
 4648   size(4);
 4649   format %{ "MOV$cmp  $dst,$src\t! int" %}
 4650   ins_encode %{
 4651     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4652   %}
 4653   ins_pipe(ialu_reg);
 4654 %}
 4655 
 4656 
 4657 instruct cmovIP_immMov(cmpOpP cmp, flagsRegP pcc, iRegI dst, immIMov src) %{
 4658   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
 4659   ins_cost(140);
 4660   size(4);
 4661   format %{ "MOV$cmp  $dst,$src" %}
 4662   ins_encode %{
 4663     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4664   %}
 4665   ins_pipe(ialu_imm);
 4666 %}
 4667 
 4668 instruct cmovIP_imm16(cmpOpP cmp, flagsRegP pcc, iRegI dst, immI16 src) %{
 4669   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
 4670   ins_cost(140);
 4671   size(4);
 4672   format %{ "MOVw$cmp  $dst,$src" %}
 4673   ins_encode %{
 4674     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4675   %}
 4676   ins_pipe(ialu_imm);
 4677 %}
 4678 
 4679 instruct cmovI_reg(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src) %{
 4680   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4681   ins_cost(150);
 4682   size(4);
 4683   format %{ "MOV$cmp  $dst,$src" %}
 4684   ins_encode %{
 4685     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4686   %}
 4687   ins_pipe(ialu_reg);
 4688 %}
 4689 
 4690 
 4691 instruct cmovI_immMov(cmpOp cmp, flagsReg icc, iRegI dst, immIMov src) %{
 4692   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4693   ins_cost(140);
 4694   size(4);
 4695   format %{ "MOV$cmp  $dst,$src" %}
 4696   ins_encode %{
 4697     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4698   %}
 4699   ins_pipe(ialu_imm);
 4700 %}
 4701 
 4702 instruct cmovII_imm16(cmpOp cmp, flagsReg icc, iRegI dst, immI16 src) %{
 4703   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4704   ins_cost(140);
 4705   size(4);
 4706   format %{ "MOVw$cmp  $dst,$src" %}
 4707   ins_encode %{
 4708     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4709   %}
 4710   ins_pipe(ialu_imm);
 4711 %}
 4712 
 4713 instruct cmovII_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, iRegI src) %{
 4714   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4715   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4716             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4717             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4718             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4719   ins_cost(150);
 4720   size(4);
 4721   format %{ "MOV$cmp  $dst,$src" %}
 4722   ins_encode %{
 4723     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4724   %}
 4725   ins_pipe(ialu_reg);
 4726 %}
 4727 
 4728 instruct cmovII_immMov_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immIMov src) %{
 4729   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4730   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4731             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4732             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4733             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4734   ins_cost(140);
 4735   size(4);
 4736   format %{ "MOV$cmp  $dst,$src" %}
 4737   ins_encode %{
 4738     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4739   %}
 4740   ins_pipe(ialu_imm);
 4741 %}
 4742 
 4743 instruct cmovII_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immI16 src) %{
 4744   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4745   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4746             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4747             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4748             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4749   ins_cost(140);
 4750   size(4);
 4751   format %{ "MOVW$cmp  $dst,$src" %}
 4752   ins_encode %{
 4753     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4754   %}
 4755   ins_pipe(ialu_imm);
 4756 %}
 4757 
 4758 instruct cmovIIu_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
 4759   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4760   ins_cost(150);
 4761   size(4);
 4762   format %{ "MOV$cmp  $dst,$src" %}
 4763   ins_encode %{
 4764     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4765   %}
 4766   ins_pipe(ialu_reg);
 4767 %}
 4768 
 4769 instruct cmovIIu_immMov(cmpOpU cmp, flagsRegU icc, iRegI dst, immIMov src) %{
 4770   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4771   ins_cost(140);
 4772   size(4);
 4773   format %{ "MOV$cmp  $dst,$src" %}
 4774   ins_encode %{
 4775     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4776   %}
 4777   ins_pipe(ialu_imm);
 4778 %}
 4779 
 4780 instruct cmovIIu_imm16(cmpOpU cmp, flagsRegU icc, iRegI dst, immI16 src) %{
 4781   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4782   ins_cost(140);
 4783   size(4);
 4784   format %{ "MOVW$cmp  $dst,$src" %}
 4785   ins_encode %{
 4786     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4787   %}
 4788   ins_pipe(ialu_imm);
 4789 %}
 4790 
 4791 // Conditional move
 4792 instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{
 4793   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
 4794   ins_cost(150);
 4795   size(4);
 4796   format %{ "MOV$cmp  $dst,$src" %}
 4797   ins_encode %{
 4798     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4799   %}
 4800   ins_pipe(ialu_reg);
 4801 %}
 4802 
 4803 instruct cmovPP_imm(cmpOpP cmp, flagsRegP pcc, iRegP dst, immP0 src) %{
 4804   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
 4805   ins_cost(140);
 4806   size(4);
 4807   format %{ "MOV$cmp  $dst,$src" %}
 4808   ins_encode %{
 4809     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4810   %}
 4811   ins_pipe(ialu_imm);
 4812 %}
 4813 
 4814 // This instruction also works with CmpN so we don't need cmovPN_reg.
 4815 instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{
 4816   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4817   ins_cost(150);
 4818 
 4819   size(4);
 4820   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4821   ins_encode %{
 4822     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4823   %}
 4824   ins_pipe(ialu_reg);
 4825 %}
 4826 
 4827 instruct cmovPI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, iRegP src) %{
 4828   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4829   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4830             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4831             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4832             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4833   ins_cost(150);
 4834 
 4835   size(4);
 4836   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4837   ins_encode %{
 4838     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4839   %}
 4840   ins_pipe(ialu_reg);
 4841 %}
 4842 
 4843 instruct cmovPIu_reg(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src) %{
 4844   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4845   ins_cost(150);
 4846 
 4847   size(4);
 4848   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4849   ins_encode %{
 4850     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4851   %}
 4852   ins_pipe(ialu_reg);
 4853 %}
 4854 
 4855 instruct cmovPI_imm(cmpOp cmp, flagsReg icc, iRegP dst, immP0 src) %{
 4856   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4857   ins_cost(140);
 4858 
 4859   size(4);
 4860   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4861   ins_encode %{
 4862     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4863   %}
 4864   ins_pipe(ialu_imm);
 4865 %}
 4866 
 4867 instruct cmovPI_imm_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, immP0 src) %{
 4868   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4869   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4870             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4871             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4872             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4873   ins_cost(140);
 4874 
 4875   size(4);
 4876   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4877   ins_encode %{
 4878     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4879   %}
 4880   ins_pipe(ialu_imm);
 4881 %}
 4882 
 4883 instruct cmovPIu_imm(cmpOpU cmp, flagsRegU icc, iRegP dst, immP0 src) %{
 4884   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4885   ins_cost(140);
 4886 
 4887   size(4);
 4888   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4889   ins_encode %{
 4890     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4891   %}
 4892   ins_pipe(ialu_imm);
 4893 %}
 4894 
 4895 
 4896 // Conditional move
 4897 instruct cmovFP_reg(cmpOpP cmp, flagsRegP pcc, regF dst, regF src) %{
 4898   match(Set dst (CMoveF (Binary cmp pcc) (Binary dst src)));
 4899   ins_cost(150);
 4900   size(4);
 4901   format %{ "FCPYS$cmp $dst,$src" %}
 4902   ins_encode %{
 4903     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4904   %}
 4905   ins_pipe(int_conditional_float_move);
 4906 %}
 4907 
 4908 instruct cmovFI_reg(cmpOp cmp, flagsReg icc, regF dst, regF src) %{
 4909   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
 4910   ins_cost(150);
 4911 
 4912   size(4);
 4913   format %{ "FCPYS$cmp $dst,$src" %}
 4914   ins_encode %{
 4915     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4916   %}
 4917   ins_pipe(int_conditional_float_move);
 4918 %}
 4919 
 4920 instruct cmovFI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regF dst, regF src) %{
 4921   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
 4922   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4923             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4924             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4925             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4926   ins_cost(150);
 4927 
 4928   size(4);
 4929   format %{ "FCPYS$cmp $dst,$src" %}
 4930   ins_encode %{
 4931     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4932   %}
 4933   ins_pipe(int_conditional_float_move);
 4934 %}
 4935 
 4936 instruct cmovFIu_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src) %{
 4937   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
 4938   ins_cost(150);
 4939 
 4940   size(4);
 4941   format %{ "FCPYS$cmp $dst,$src" %}
 4942   ins_encode %{
 4943     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4944   %}
 4945   ins_pipe(int_conditional_float_move);
 4946 %}
 4947 
 4948 // Conditional move
 4949 instruct cmovDP_reg(cmpOpP cmp, flagsRegP pcc, regD dst, regD src) %{
 4950   match(Set dst (CMoveD (Binary cmp pcc) (Binary dst src)));
 4951   ins_cost(150);
 4952   size(4);
 4953   format %{ "FCPYD$cmp $dst,$src" %}
 4954   ins_encode %{
 4955     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4956   %}
 4957   ins_pipe(int_conditional_double_move);
 4958 %}
 4959 
 4960 instruct cmovDI_reg(cmpOp cmp, flagsReg icc, regD dst, regD src) %{
 4961   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
 4962   ins_cost(150);
 4963 
 4964   size(4);
 4965   format %{ "FCPYD$cmp $dst,$src" %}
 4966   ins_encode %{
 4967     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4968   %}
 4969   ins_pipe(int_conditional_double_move);
 4970 %}
 4971 
 4972 instruct cmovDI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regD dst, regD src) %{
 4973   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
 4974   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);
 4975   ins_cost(150);
 4976 
 4977   size(4);
 4978   format %{ "FCPYD$cmp $dst,$src" %}
 4979   ins_encode %{
 4980     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4981   %}
 4982   ins_pipe(int_conditional_double_move);
 4983 %}
 4984 
 4985 instruct cmovDIu_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src) %{
 4986   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
 4987   ins_cost(150);
 4988 
 4989   size(4);
 4990   format %{ "FCPYD$cmp $dst,$src" %}
 4991   ins_encode %{
 4992     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4993   %}
 4994   ins_pipe(int_conditional_double_move);
 4995 %}
 4996 
 4997 // Conditional move
 4998 instruct cmovLP_reg(cmpOpP cmp, flagsRegP pcc, iRegL dst, iRegL src) %{
 4999   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
 5000   ins_cost(150);
 5001 
 5002   size(8);
 5003   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 5004             "MOV$cmp  $dst.hi,$src.hi" %}
 5005   ins_encode %{
 5006     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 5007     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 5008   %}
 5009   ins_pipe(ialu_reg);
 5010 %}
 5011 
 5012 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5013 // (hi($con$$constant), lo($con$$constant)) becomes
 5014 instruct cmovLP_immRot(cmpOpP cmp, flagsRegP pcc, iRegL dst, immLlowRot src) %{
 5015   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
 5016   ins_cost(140);
 5017 
 5018   size(8);
 5019   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5020             "MOV$cmp  $dst.hi,0" %}
 5021   ins_encode %{
 5022     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5023     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5024   %}
 5025   ins_pipe(ialu_imm);
 5026 %}
 5027 
 5028 instruct cmovLP_imm16(cmpOpP cmp, flagsRegP pcc, iRegL dst, immL16 src) %{
 5029   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
 5030   ins_cost(140);
 5031 
 5032   size(8);
 5033   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5034             "MOV$cmp  $dst.hi,0" %}
 5035   ins_encode %{
 5036     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5037     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5038   %}
 5039   ins_pipe(ialu_imm);
 5040 %}
 5041 
 5042 instruct cmovLI_reg(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src) %{
 5043   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5044   ins_cost(150);
 5045 
 5046   size(8);
 5047   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 5048             "MOV$cmp  $dst.hi,$src.hi" %}
 5049   ins_encode %{
 5050     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 5051     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 5052   %}
 5053   ins_pipe(ialu_reg);
 5054 %}
 5055 
 5056 instruct cmovLI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, iRegL src) %{
 5057   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5058   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 5059             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 5060             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 5061             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 5062   ins_cost(150);
 5063 
 5064   size(8);
 5065   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 5066             "MOV$cmp  $dst.hi,$src.hi" %}
 5067   ins_encode %{
 5068     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 5069     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 5070   %}
 5071   ins_pipe(ialu_reg);
 5072 %}
 5073 
 5074 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5075 // (hi($con$$constant), lo($con$$constant)) becomes
 5076 instruct cmovLI_immRot(cmpOp cmp, flagsReg icc, iRegL dst, immLlowRot src) %{
 5077   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5078   ins_cost(140);
 5079 
 5080   size(8);
 5081   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5082             "MOV$cmp  $dst.hi,0" %}
 5083   ins_encode %{
 5084     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5085     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5086   %}
 5087   ins_pipe(ialu_imm);
 5088 %}
 5089 
 5090 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5091 // (hi($con$$constant), lo($con$$constant)) becomes
 5092 instruct cmovLI_immRot_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immLlowRot src) %{
 5093   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5094   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 5095             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 5096             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 5097             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 5098   ins_cost(140);
 5099 
 5100   size(8);
 5101   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5102             "MOV$cmp  $dst.hi,0" %}
 5103   ins_encode %{
 5104     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5105     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5106   %}
 5107   ins_pipe(ialu_imm);
 5108 %}
 5109 
 5110 instruct cmovLI_imm16(cmpOp cmp, flagsReg icc, iRegL dst, immL16 src) %{
 5111   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5112   ins_cost(140);
 5113 
 5114   size(8);
 5115   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5116             "MOV$cmp  $dst.hi,0" %}
 5117   ins_encode %{
 5118     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5119     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5120   %}
 5121   ins_pipe(ialu_imm);
 5122 %}
 5123 
 5124 instruct cmovLI_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immL16 src) %{
 5125   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5126   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 5127             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 5128             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 5129             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 5130   ins_cost(140);
 5131 
 5132   size(8);
 5133   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5134             "MOV$cmp  $dst.hi,0" %}
 5135   ins_encode %{
 5136     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5137     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5138   %}
 5139   ins_pipe(ialu_imm);
 5140 %}
 5141 
 5142 instruct cmovLIu_reg(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src) %{
 5143   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5144   ins_cost(150);
 5145 
 5146   size(8);
 5147   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 5148             "MOV$cmp  $dst.hi,$src.hi" %}
 5149   ins_encode %{
 5150     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 5151     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 5152   %}
 5153   ins_pipe(ialu_reg);
 5154 %}
 5155 
 5156 
 5157 //----------OS and Locking Instructions----------------------------------------
 5158 
 5159 // This name is KNOWN by the ADLC and cannot be changed.
 5160 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
 5161 // for this guy.
 5162 instruct tlsLoadP(RthreadRegP dst) %{
 5163   match(Set dst (ThreadLocal));
 5164 
 5165   size(0);
 5166   ins_cost(0);
 5167   format %{ "! TLS is in $dst" %}
 5168   ins_encode( /*empty encoding*/ );
 5169   ins_pipe(ialu_none);
 5170 %}
 5171 
 5172 instruct checkCastPP( iRegP dst ) %{
 5173   match(Set dst (CheckCastPP dst));
 5174 
 5175   size(0);
 5176   format %{ "! checkcastPP of $dst" %}
 5177   ins_encode( /*empty encoding*/ );
 5178   ins_pipe(empty);
 5179 %}
 5180 
 5181 
 5182 instruct castPP( iRegP dst ) %{
 5183   match(Set dst (CastPP dst));
 5184   format %{ "! castPP of $dst" %}
 5185   ins_encode( /*empty encoding*/ );
 5186   ins_pipe(empty);
 5187 %}
 5188 
 5189 instruct castII( iRegI dst ) %{
 5190   match(Set dst (CastII dst));
 5191   format %{ "! castII of $dst" %}
 5192   ins_encode( /*empty encoding*/ );
 5193   ins_cost(0);
 5194   ins_pipe(empty);
 5195 %}
 5196 
 5197 instruct castLL( iRegL dst ) %{
 5198   match(Set dst (CastLL dst));
 5199   format %{ "! castLL of $dst" %}
 5200   ins_encode( /*empty encoding*/ );
 5201   ins_cost(0);
 5202   ins_pipe(empty);
 5203 %}
 5204 
 5205 instruct castFF( regF dst ) %{
 5206   match(Set dst (CastFF dst));
 5207   format %{ "! castFF of $dst" %}
 5208   ins_encode( /*empty encoding*/ );
 5209   ins_cost(0);
 5210   ins_pipe(empty);
 5211 %}
 5212 
 5213 instruct castDD( regD dst ) %{
 5214   match(Set dst (CastDD dst));
 5215   format %{ "! castDD of $dst" %}
 5216   ins_encode( /*empty encoding*/ );
 5217   ins_cost(0);
 5218   ins_pipe(empty);
 5219 %}
 5220 
 5221 instruct castVVD( vecD dst ) %{
 5222   match(Set dst (CastVV dst));
 5223   format %{ "! castVV of $dst" %}
 5224   ins_encode( /*empty encoding*/ );
 5225   ins_cost(0);
 5226   ins_pipe(empty);
 5227 %}
 5228 
 5229 instruct castVVX( vecX dst ) %{
 5230   match(Set dst (CastVV dst));
 5231   format %{ "! castVV of $dst" %}
 5232   ins_encode( /*empty encoding*/ );
 5233   ins_cost(0);
 5234   ins_pipe(empty);
 5235 %}
 5236 
 5237 
 5238 //----------Arithmetic Instructions--------------------------------------------
 5239 // Addition Instructions
 5240 // Register Addition
 5241 instruct addI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 5242   match(Set dst (AddI src1 src2));
 5243 
 5244   size(4);
 5245   format %{ "add_32 $dst,$src1,$src2\t! int" %}
 5246   ins_encode %{
 5247     __ add_32($dst$$Register, $src1$$Register, $src2$$Register);
 5248   %}
 5249   ins_pipe(ialu_reg_reg);
 5250 %}
 5251 
 5252 instruct addshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5253   match(Set dst (AddI (LShiftI src1 src2) src3));
 5254 
 5255   size(4);
 5256   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
 5257   ins_encode %{
 5258     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 5259   %}
 5260   ins_pipe(ialu_reg_reg);
 5261 %}
 5262 
 5263 
 5264 instruct addshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5265   match(Set dst (AddI (LShiftI src1 src2) src3));
 5266 
 5267   size(4);
 5268   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
 5269   ins_encode %{
 5270     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
 5271   %}
 5272   ins_pipe(ialu_reg_reg);
 5273 %}
 5274 
 5275 instruct addsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5276   match(Set dst (AddI (RShiftI src1 src2) src3));
 5277 
 5278   size(4);
 5279   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
 5280   ins_encode %{
 5281     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
 5282   %}
 5283   ins_pipe(ialu_reg_reg);
 5284 %}
 5285 
 5286 instruct addsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5287   match(Set dst (AddI (RShiftI src1 src2) src3));
 5288 
 5289   size(4);
 5290   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
 5291   ins_encode %{
 5292     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
 5293   %}
 5294   ins_pipe(ialu_reg_reg);
 5295 %}
 5296 
 5297 instruct addshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5298   match(Set dst (AddI (URShiftI src1 src2) src3));
 5299 
 5300   size(4);
 5301   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
 5302   ins_encode %{
 5303     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 5304   %}
 5305   ins_pipe(ialu_reg_reg);
 5306 %}
 5307 
 5308 instruct addshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5309   match(Set dst (AddI (URShiftI src1 src2) src3));
 5310 
 5311   size(4);
 5312   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
 5313   ins_encode %{
 5314     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 5315   %}
 5316   ins_pipe(ialu_reg_reg);
 5317 %}
 5318 
 5319 // Immediate Addition
 5320 instruct addI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
 5321   match(Set dst (AddI src1 src2));
 5322 
 5323   size(4);
 5324   format %{ "add_32 $dst,$src1,$src2\t! int" %}
 5325   ins_encode %{
 5326     __ add_32($dst$$Register, $src1$$Register, $src2$$constant);
 5327   %}
 5328   ins_pipe(ialu_reg_imm);
 5329 %}
 5330 
 5331 // Pointer Register Addition
 5332 instruct addP_reg_reg(iRegP dst, iRegP src1, iRegX src2) %{
 5333   match(Set dst (AddP src1 src2));
 5334 
 5335   size(4);
 5336   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
 5337   ins_encode %{
 5338     __ add($dst$$Register, $src1$$Register, $src2$$Register);
 5339   %}
 5340   ins_pipe(ialu_reg_reg);
 5341 %}
 5342 
 5343 
 5344 // shifted iRegX operand
 5345 operand shiftedX(iRegX src2, shimmX src3) %{
 5346 //constraint(ALLOC_IN_RC(sp_ptr_reg));
 5347   match(LShiftX src2 src3);
 5348 
 5349   op_cost(1);
 5350   format %{ "$src2 << $src3" %}
 5351   interface(MEMORY_INTER) %{
 5352     base($src2);
 5353     index(0xff);
 5354     scale($src3);
 5355     disp(0x0);
 5356   %}
 5357 %}
 5358 
 5359 instruct addshlP_reg_reg_imm(iRegP dst, iRegP src1, shiftedX src2) %{
 5360   match(Set dst (AddP src1 src2));
 5361 
 5362   ins_cost(DEFAULT_COST * 3/2);
 5363   size(4);
 5364   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
 5365   ins_encode %{
 5366     Register base = reg_to_register_object($src2$$base);
 5367     __ add($dst$$Register, $src1$$Register, AsmOperand(base, lsl, $src2$$scale));
 5368   %}
 5369   ins_pipe(ialu_reg_reg);
 5370 %}
 5371 
 5372 // Pointer Immediate Addition
 5373 instruct addP_reg_aimmX(iRegP dst, iRegP src1, aimmX src2) %{
 5374   match(Set dst (AddP src1 src2));
 5375 
 5376   size(4);
 5377   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
 5378   ins_encode %{
 5379     __ add($dst$$Register, $src1$$Register, $src2$$constant);
 5380   %}
 5381   ins_pipe(ialu_reg_imm);
 5382 %}
 5383 
 5384 // Long Addition
 5385 instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg ccr) %{
 5386   match(Set dst (AddL src1 src2));
 5387   effect(KILL ccr);
 5388   size(8);
 5389   format %{ "ADDS    $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
 5390             "ADC     $dst.hi,$src1.hi,$src2.hi" %}
 5391   ins_encode %{
 5392     __ adds($dst$$Register, $src1$$Register, $src2$$Register);
 5393     __ adc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 5394   %}
 5395   ins_pipe(ialu_reg_reg);
 5396 %}
 5397 
 5398 // TODO
 5399 
 5400 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5401 // (hi($con$$constant), lo($con$$constant)) becomes
 5402 instruct addL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg ccr) %{
 5403   match(Set dst (AddL src1 con));
 5404   effect(KILL ccr);
 5405   size(8);
 5406   format %{ "ADDS    $dst.lo,$src1.lo,$con\t! long\n\t"
 5407             "ADC     $dst.hi,$src1.hi,0" %}
 5408   ins_encode %{
 5409     __ adds($dst$$Register, $src1$$Register, $con$$constant);
 5410     __ adc($dst$$Register->successor(), $src1$$Register->successor(), 0);
 5411   %}
 5412   ins_pipe(ialu_reg_imm);
 5413 %}
 5414 
 5415 //----------Conditional_store--------------------------------------------------
 5416 // Conditional-store of the updated heap-top.
 5417 // Used during allocation of the shared heap.
 5418 // Sets flags (EQ) on success.
 5419 
 5420 // LoadP-locked.
 5421 instruct loadPLocked(iRegP dst, memoryex mem) %{
 5422   match(Set dst (LoadPLocked mem));
 5423   size(4);
 5424   format %{ "LDREX  $dst,$mem" %}
 5425   ins_encode %{
 5426     __ ldrex($dst$$Register,$mem$$Address);
 5427   %}
 5428   ins_pipe(iload_mem);
 5429 %}
 5430 
 5431 instruct storePConditional( memoryex heap_top_ptr, iRegP oldval, iRegP newval, iRegI tmp, flagsRegP pcc ) %{
 5432   predicate(_kids[1]->_kids[0]->_leaf->Opcode() == Op_LoadPLocked); // only works in conjunction with a LoadPLocked node
 5433   match(Set pcc (StorePConditional heap_top_ptr (Binary oldval newval)));
 5434   effect( TEMP tmp );
 5435   size(8);
 5436   format %{ "STREX  $tmp,$newval,$heap_top_ptr\n\t"
 5437             "CMP    $tmp, 0" %}
 5438   ins_encode %{
 5439     __ strex($tmp$$Register, $newval$$Register, $heap_top_ptr$$Address);
 5440     __ cmp($tmp$$Register, 0);
 5441   %}
 5442   ins_pipe( long_memory_op );
 5443 %}
 5444 
 5445 // Conditional-store of an intx value.
 5446 instruct storeXConditional( memoryex mem, iRegX oldval, iRegX newval, iRegX tmp, flagsReg icc ) %{
 5447   match(Set icc (StoreIConditional mem (Binary oldval newval)));
 5448   effect( TEMP tmp );
 5449   size(28);
 5450   format %{ "loop: \n\t"
 5451             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem], DOESN'T set $newval=[$mem] in any case\n\t"
 5452             "XORS     $tmp,$tmp, $oldval\n\t"
 5453             "STREX.eq $tmp, $newval, $mem\n\t"
 5454             "CMP.eq   $tmp, 1 \n\t"
 5455             "B.eq     loop \n\t"
 5456             "TEQ      $tmp, 0\n\t"
 5457             "membar   LoadStore|LoadLoad" %}
 5458   ins_encode %{
 5459     Label loop;
 5460     __ bind(loop);
 5461     __ ldrex($tmp$$Register, $mem$$Address);
 5462     __ eors($tmp$$Register, $tmp$$Register, $oldval$$Register);
 5463     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5464     __ cmp($tmp$$Register, 1, eq);
 5465     __ b(loop, eq);
 5466     __ teq($tmp$$Register, 0);
 5467     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadStore | MacroAssembler::LoadLoad), noreg);
 5468   %}
 5469   ins_pipe( long_memory_op );
 5470 %}
 5471 
 5472 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
 5473 
 5474 instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegLd newval, iRegI res, iRegLd tmp, flagsReg ccr ) %{
 5475   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
 5476   effect( KILL ccr, TEMP tmp);
 5477   size(32);
 5478   format %{ "loop: \n\t"
 5479             "LDREXD   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
 5480             "CMP      $tmp.lo, $oldval.lo\n\t"
 5481             "CMP.eq   $tmp.hi, $oldval.hi\n\t"
 5482             "STREXD.eq $tmp, $newval, $mem\n\t"
 5483             "MOV.ne   $tmp, 0 \n\t"
 5484             "XORS.eq  $tmp,$tmp, 1 \n\t"
 5485             "B.eq     loop \n\t"
 5486             "MOV      $res, $tmp" %}
 5487   ins_encode %{
 5488     Label loop;
 5489     __ bind(loop);
 5490     __ ldrexd($tmp$$Register, $mem$$Address);
 5491     __ cmp($tmp$$Register, $oldval$$Register);
 5492     __ cmp($tmp$$Register->successor(), $oldval$$Register->successor(), eq);
 5493     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5494     __ mov($tmp$$Register, 0, ne);
 5495     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
 5496     __ b(loop, eq);
 5497     __ mov($res$$Register, $tmp$$Register);
 5498   %}
 5499   ins_pipe( long_memory_op );
 5500 %}
 5501 
 5502 
 5503 instruct compareAndSwapI_bool(memoryex mem, iRegI oldval, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
 5504   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
 5505   effect( KILL ccr, TEMP tmp);
 5506   size(28);
 5507   format %{ "loop: \n\t"
 5508             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
 5509             "CMP      $tmp, $oldval\n\t"
 5510             "STREX.eq $tmp, $newval, $mem\n\t"
 5511             "MOV.ne   $tmp, 0 \n\t"
 5512             "XORS.eq  $tmp,$tmp, 1 \n\t"
 5513             "B.eq     loop \n\t"
 5514             "MOV      $res, $tmp" %}
 5515 
 5516   ins_encode %{
 5517     Label loop;
 5518     __ bind(loop);
 5519     __ ldrex($tmp$$Register,$mem$$Address);
 5520     __ cmp($tmp$$Register, $oldval$$Register);
 5521     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5522     __ mov($tmp$$Register, 0, ne);
 5523     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
 5524     __ b(loop, eq);
 5525     __ mov($res$$Register, $tmp$$Register);
 5526   %}
 5527   ins_pipe( long_memory_op );
 5528 %}
 5529 
 5530 instruct compareAndSwapP_bool(memoryex mem, iRegP oldval, iRegP newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
 5531   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
 5532   effect( KILL ccr, TEMP tmp);
 5533   size(28);
 5534   format %{ "loop: \n\t"
 5535             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
 5536             "CMP      $tmp, $oldval\n\t"
 5537             "STREX.eq $tmp, $newval, $mem\n\t"
 5538             "MOV.ne   $tmp, 0 \n\t"
 5539             "EORS.eq  $tmp,$tmp, 1 \n\t"
 5540             "B.eq     loop \n\t"
 5541             "MOV      $res, $tmp" %}
 5542 
 5543   ins_encode %{
 5544     Label loop;
 5545     __ bind(loop);
 5546     __ ldrex($tmp$$Register,$mem$$Address);
 5547     __ cmp($tmp$$Register, $oldval$$Register);
 5548     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5549     __ mov($tmp$$Register, 0, ne);
 5550     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
 5551     __ b(loop, eq);
 5552     __ mov($res$$Register, $tmp$$Register);
 5553   %}
 5554   ins_pipe( long_memory_op );
 5555 %}
 5556 
 5557 instruct xaddI_aimmI_no_res(memoryex mem, aimmI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5558   predicate(n->as_LoadStore()->result_not_used());
 5559   match(Set dummy (GetAndAddI mem add));
 5560   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
 5561   size(20);
 5562   format %{ "loop: \n\t"
 5563             "LDREX    $tmp1, $mem\n\t"
 5564             "ADD      $tmp1, $tmp1, $add\n\t"
 5565             "STREX    $tmp2, $tmp1, $mem\n\t"
 5566             "CMP      $tmp2, 0 \n\t"
 5567             "B.ne     loop \n\t" %}
 5568 
 5569   ins_encode %{
 5570     Label loop;
 5571     __ bind(loop);
 5572     __ ldrex($tmp1$$Register,$mem$$Address);
 5573     __ add($tmp1$$Register, $tmp1$$Register, $add$$constant);
 5574     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5575     __ cmp($tmp2$$Register, 0);
 5576     __ b(loop, ne);
 5577   %}
 5578   ins_pipe( long_memory_op );
 5579 %}
 5580 
 5581 instruct xaddI_reg_no_res(memoryex mem, iRegI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5582   predicate(n->as_LoadStore()->result_not_used());
 5583   match(Set dummy (GetAndAddI mem add));
 5584   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
 5585   size(20);
 5586   format %{ "loop: \n\t"
 5587             "LDREX    $tmp1, $mem\n\t"
 5588             "ADD      $tmp1, $tmp1, $add\n\t"
 5589             "STREX    $tmp2, $tmp1, $mem\n\t"
 5590             "CMP      $tmp2, 0 \n\t"
 5591             "B.ne     loop \n\t" %}
 5592 
 5593   ins_encode %{
 5594     Label loop;
 5595     __ bind(loop);
 5596     __ ldrex($tmp1$$Register,$mem$$Address);
 5597     __ add($tmp1$$Register, $tmp1$$Register, $add$$Register);
 5598     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5599     __ cmp($tmp2$$Register, 0);
 5600     __ b(loop, ne);
 5601   %}
 5602   ins_pipe( long_memory_op );
 5603 %}
 5604 
 5605 instruct xaddI_aimmI(memoryex mem, aimmI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5606   match(Set res (GetAndAddI mem add));
 5607   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5608   size(20);
 5609   format %{ "loop: \n\t"
 5610             "LDREX    $res, $mem\n\t"
 5611             "ADD      $tmp1, $res, $add\n\t"
 5612             "STREX    $tmp2, $tmp1, $mem\n\t"
 5613             "CMP      $tmp2, 0 \n\t"
 5614             "B.ne     loop \n\t" %}
 5615 
 5616   ins_encode %{
 5617     Label loop;
 5618     __ bind(loop);
 5619     __ ldrex($res$$Register,$mem$$Address);
 5620     __ add($tmp1$$Register, $res$$Register, $add$$constant);
 5621     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5622     __ cmp($tmp2$$Register, 0);
 5623     __ b(loop, ne);
 5624   %}
 5625   ins_pipe( long_memory_op );
 5626 %}
 5627 
 5628 instruct xaddI_reg(memoryex mem, iRegI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5629   match(Set res (GetAndAddI mem add));
 5630   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5631   size(20);
 5632   format %{ "loop: \n\t"
 5633             "LDREX    $res, $mem\n\t"
 5634             "ADD      $tmp1, $res, $add\n\t"
 5635             "STREX    $tmp2, $tmp1, $mem\n\t"
 5636             "CMP      $tmp2, 0 \n\t"
 5637             "B.ne     loop \n\t" %}
 5638 
 5639   ins_encode %{
 5640     Label loop;
 5641     __ bind(loop);
 5642     __ ldrex($res$$Register,$mem$$Address);
 5643     __ add($tmp1$$Register, $res$$Register, $add$$Register);
 5644     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5645     __ cmp($tmp2$$Register, 0);
 5646     __ b(loop, ne);
 5647   %}
 5648   ins_pipe( long_memory_op );
 5649 %}
 5650 
 5651 instruct xaddL_reg_no_res(memoryex mem, iRegL add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5652   predicate(n->as_LoadStore()->result_not_used());
 5653   match(Set dummy (GetAndAddL mem add));
 5654   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
 5655   size(24);
 5656   format %{ "loop: \n\t"
 5657             "LDREXD   $tmp1, $mem\n\t"
 5658             "ADDS     $tmp1.lo, $tmp1.lo, $add.lo\n\t"
 5659             "ADC      $tmp1.hi, $tmp1.hi, $add.hi\n\t"
 5660             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5661             "CMP      $tmp2, 0 \n\t"
 5662             "B.ne     loop \n\t" %}
 5663 
 5664   ins_encode %{
 5665     Label loop;
 5666     __ bind(loop);
 5667     __ ldrexd($tmp1$$Register, $mem$$Address);
 5668     __ adds($tmp1$$Register, $tmp1$$Register, $add$$Register);
 5669     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), $add$$Register->successor());
 5670     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5671     __ cmp($tmp2$$Register, 0);
 5672     __ b(loop, ne);
 5673   %}
 5674   ins_pipe( long_memory_op );
 5675 %}
 5676 
 5677 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5678 // (hi($con$$constant), lo($con$$constant)) becomes
 5679 instruct xaddL_immRot_no_res(memoryex mem, immLlowRot add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5680   predicate(n->as_LoadStore()->result_not_used());
 5681   match(Set dummy (GetAndAddL mem add));
 5682   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
 5683   size(24);
 5684   format %{ "loop: \n\t"
 5685             "LDREXD   $tmp1, $mem\n\t"
 5686             "ADDS     $tmp1.lo, $tmp1.lo, $add\n\t"
 5687             "ADC      $tmp1.hi, $tmp1.hi, 0\n\t"
 5688             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5689             "CMP      $tmp2, 0 \n\t"
 5690             "B.ne     loop \n\t" %}
 5691 
 5692   ins_encode %{
 5693     Label loop;
 5694     __ bind(loop);
 5695     __ ldrexd($tmp1$$Register, $mem$$Address);
 5696     __ adds($tmp1$$Register, $tmp1$$Register, $add$$constant);
 5697     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), 0);
 5698     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5699     __ cmp($tmp2$$Register, 0);
 5700     __ b(loop, ne);
 5701   %}
 5702   ins_pipe( long_memory_op );
 5703 %}
 5704 
 5705 instruct xaddL_reg(memoryex mem, iRegL add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5706   match(Set res (GetAndAddL mem add));
 5707   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5708   size(24);
 5709   format %{ "loop: \n\t"
 5710             "LDREXD   $res, $mem\n\t"
 5711             "ADDS     $tmp1.lo, $res.lo, $add.lo\n\t"
 5712             "ADC      $tmp1.hi, $res.hi, $add.hi\n\t"
 5713             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5714             "CMP      $tmp2, 0 \n\t"
 5715             "B.ne     loop \n\t" %}
 5716 
 5717   ins_encode %{
 5718     Label loop;
 5719     __ bind(loop);
 5720     __ ldrexd($res$$Register, $mem$$Address);
 5721     __ adds($tmp1$$Register, $res$$Register, $add$$Register);
 5722     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), $add$$Register->successor());
 5723     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5724     __ cmp($tmp2$$Register, 0);
 5725     __ b(loop, ne);
 5726   %}
 5727   ins_pipe( long_memory_op );
 5728 %}
 5729 
 5730 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5731 // (hi($con$$constant), lo($con$$constant)) becomes
 5732 instruct xaddL_immRot(memoryex mem, immLlowRot add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5733   match(Set res (GetAndAddL mem add));
 5734   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5735   size(24);
 5736   format %{ "loop: \n\t"
 5737             "LDREXD   $res, $mem\n\t"
 5738             "ADDS     $tmp1.lo, $res.lo, $add\n\t"
 5739             "ADC      $tmp1.hi, $res.hi, 0\n\t"
 5740             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5741             "CMP      $tmp2, 0 \n\t"
 5742             "B.ne     loop \n\t" %}
 5743 
 5744   ins_encode %{
 5745     Label loop;
 5746     __ bind(loop);
 5747     __ ldrexd($res$$Register, $mem$$Address);
 5748     __ adds($tmp1$$Register, $res$$Register, $add$$constant);
 5749     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), 0);
 5750     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5751     __ cmp($tmp2$$Register, 0);
 5752     __ b(loop, ne);
 5753   %}
 5754   ins_pipe( long_memory_op );
 5755 %}
 5756 
 5757 instruct xchgI(memoryex mem, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr) %{
 5758   match(Set res (GetAndSetI mem newval));
 5759   effect(KILL ccr, TEMP tmp, TEMP res);
 5760   size(16);
 5761   format %{ "loop: \n\t"
 5762             "LDREX    $res, $mem\n\t"
 5763             "STREX    $tmp, $newval, $mem\n\t"
 5764             "CMP      $tmp, 0 \n\t"
 5765             "B.ne     loop \n\t" %}
 5766 
 5767   ins_encode %{
 5768     Label loop;
 5769     __ bind(loop);
 5770     __ ldrex($res$$Register,$mem$$Address);
 5771     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
 5772     __ cmp($tmp$$Register, 0);
 5773     __ b(loop, ne);
 5774   %}
 5775   ins_pipe( long_memory_op );
 5776 %}
 5777 
 5778 instruct xchgL(memoryex mem, iRegLd newval, iRegLd res, iRegI tmp, flagsReg ccr) %{
 5779   match(Set res (GetAndSetL mem newval));
 5780   effect( KILL ccr, TEMP tmp, TEMP res);
 5781   size(16);
 5782   format %{ "loop: \n\t"
 5783             "LDREXD   $res, $mem\n\t"
 5784             "STREXD   $tmp, $newval, $mem\n\t"
 5785             "CMP      $tmp, 0 \n\t"
 5786             "B.ne     loop \n\t" %}
 5787 
 5788   ins_encode %{
 5789     Label loop;
 5790     __ bind(loop);
 5791     __ ldrexd($res$$Register, $mem$$Address);
 5792     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address);
 5793     __ cmp($tmp$$Register, 0);
 5794     __ b(loop, ne);
 5795   %}
 5796   ins_pipe( long_memory_op );
 5797 %}
 5798 
 5799 instruct xchgP(memoryex mem, iRegP newval, iRegP res, iRegI tmp, flagsReg ccr) %{
 5800   match(Set res (GetAndSetP mem newval));
 5801   effect(KILL ccr, TEMP tmp, TEMP res);
 5802   size(16);
 5803   format %{ "loop: \n\t"
 5804             "LDREX    $res, $mem\n\t"
 5805             "STREX    $tmp, $newval, $mem\n\t"
 5806             "CMP      $tmp, 0 \n\t"
 5807             "B.ne     loop \n\t" %}
 5808 
 5809   ins_encode %{
 5810     Label loop;
 5811     __ bind(loop);
 5812     __ ldrex($res$$Register,$mem$$Address);
 5813     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
 5814     __ cmp($tmp$$Register, 0);
 5815     __ b(loop, ne);
 5816   %}
 5817   ins_pipe( long_memory_op );
 5818 %}
 5819 
 5820 //---------------------
 5821 // Subtraction Instructions
 5822 // Register Subtraction
 5823 instruct subI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 5824   match(Set dst (SubI src1 src2));
 5825 
 5826   size(4);
 5827   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
 5828   ins_encode %{
 5829     __ sub_32($dst$$Register, $src1$$Register, $src2$$Register);
 5830   %}
 5831   ins_pipe(ialu_reg_reg);
 5832 %}
 5833 
 5834 instruct subshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5835   match(Set dst (SubI src1 (LShiftI src2 src3)));
 5836 
 5837   size(4);
 5838   format %{ "SUB    $dst,$src1,$src2<<$src3" %}
 5839   ins_encode %{
 5840     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 5841   %}
 5842   ins_pipe(ialu_reg_reg);
 5843 %}
 5844 
 5845 instruct subshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 5846   match(Set dst (SubI src1 (LShiftI src2 src3)));
 5847 
 5848   size(4);
 5849   format %{ "sub_32 $dst,$src1,$src2<<$src3\t! int" %}
 5850   ins_encode %{
 5851     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 5852   %}
 5853   ins_pipe(ialu_reg_reg);
 5854 %}
 5855 
 5856 instruct subsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5857   match(Set dst (SubI src1 (RShiftI src2 src3)));
 5858 
 5859   size(4);
 5860   format %{ "SUB    $dst,$src1,$src2>>$src3" %}
 5861   ins_encode %{
 5862     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 5863   %}
 5864   ins_pipe(ialu_reg_reg);
 5865 %}
 5866 
 5867 instruct subsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 5868   match(Set dst (SubI src1 (RShiftI src2 src3)));
 5869 
 5870   size(4);
 5871   format %{ "sub_32 $dst,$src1,$src2>>$src3\t! int" %}
 5872   ins_encode %{
 5873     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 5874   %}
 5875   ins_pipe(ialu_reg_reg);
 5876 %}
 5877 
 5878 instruct subshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5879   match(Set dst (SubI src1 (URShiftI src2 src3)));
 5880 
 5881   size(4);
 5882   format %{ "SUB    $dst,$src1,$src2>>>$src3" %}
 5883   ins_encode %{
 5884     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 5885   %}
 5886   ins_pipe(ialu_reg_reg);
 5887 %}
 5888 
 5889 instruct subshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 5890   match(Set dst (SubI src1 (URShiftI src2 src3)));
 5891 
 5892   size(4);
 5893   format %{ "sub_32 $dst,$src1,$src2>>>$src3\t! int" %}
 5894   ins_encode %{
 5895     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 5896   %}
 5897   ins_pipe(ialu_reg_reg);
 5898 %}
 5899 
 5900 instruct rsbshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5901   match(Set dst (SubI (LShiftI src1 src2) src3));
 5902 
 5903   size(4);
 5904   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
 5905   ins_encode %{
 5906     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 5907   %}
 5908   ins_pipe(ialu_reg_reg);
 5909 %}
 5910 
 5911 instruct rsbshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5912   match(Set dst (SubI (LShiftI src1 src2) src3));
 5913 
 5914   size(4);
 5915   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
 5916   ins_encode %{
 5917     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
 5918   %}
 5919   ins_pipe(ialu_reg_reg);
 5920 %}
 5921 
 5922 instruct rsbsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5923   match(Set dst (SubI (RShiftI src1 src2) src3));
 5924 
 5925   size(4);
 5926   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
 5927   ins_encode %{
 5928     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
 5929   %}
 5930   ins_pipe(ialu_reg_reg);
 5931 %}
 5932 
 5933 instruct rsbsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5934   match(Set dst (SubI (RShiftI src1 src2) src3));
 5935 
 5936   size(4);
 5937   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
 5938   ins_encode %{
 5939     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
 5940   %}
 5941   ins_pipe(ialu_reg_reg);
 5942 %}
 5943 
 5944 instruct rsbshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5945   match(Set dst (SubI (URShiftI src1 src2) src3));
 5946 
 5947   size(4);
 5948   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
 5949   ins_encode %{
 5950     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 5951   %}
 5952   ins_pipe(ialu_reg_reg);
 5953 %}
 5954 
 5955 instruct rsbshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5956   match(Set dst (SubI (URShiftI src1 src2) src3));
 5957 
 5958   size(4);
 5959   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
 5960   ins_encode %{
 5961     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 5962   %}
 5963   ins_pipe(ialu_reg_reg);
 5964 %}
 5965 
 5966 // Immediate Subtraction
 5967 instruct subI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
 5968   match(Set dst (SubI src1 src2));
 5969 
 5970   size(4);
 5971   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
 5972   ins_encode %{
 5973     __ sub_32($dst$$Register, $src1$$Register, $src2$$constant);
 5974   %}
 5975   ins_pipe(ialu_reg_imm);
 5976 %}
 5977 
 5978 instruct subI_reg_immRotneg(iRegI dst, iRegI src1, aimmIneg src2) %{
 5979   match(Set dst (AddI src1 src2));
 5980 
 5981   size(4);
 5982   format %{ "sub_32 $dst,$src1,-($src2)\t! int" %}
 5983   ins_encode %{
 5984     __ sub_32($dst$$Register, $src1$$Register, -$src2$$constant);
 5985   %}
 5986   ins_pipe(ialu_reg_imm);
 5987 %}
 5988 
 5989 instruct subI_immRot_reg(iRegI dst, immIRot src1, iRegI src2) %{
 5990   match(Set dst (SubI src1 src2));
 5991 
 5992   size(4);
 5993   format %{ "RSB    $dst,$src2,src1" %}
 5994   ins_encode %{
 5995     __ rsb($dst$$Register, $src2$$Register, $src1$$constant);
 5996   %}
 5997   ins_pipe(ialu_zero_reg);
 5998 %}
 5999 
 6000 // Register Subtraction
 6001 instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg icc ) %{
 6002   match(Set dst (SubL src1 src2));
 6003   effect (KILL icc);
 6004 
 6005   size(8);
 6006   format %{ "SUBS   $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
 6007             "SBC    $dst.hi,$src1.hi,$src2.hi" %}
 6008   ins_encode %{
 6009     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
 6010     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 6011   %}
 6012   ins_pipe(ialu_reg_reg);
 6013 %}
 6014 
 6015 // TODO
 6016 
 6017 // Immediate Subtraction
 6018 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 6019 // (hi($con$$constant), lo($con$$constant)) becomes
 6020 instruct subL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg icc) %{
 6021   match(Set dst (SubL src1 con));
 6022   effect (KILL icc);
 6023 
 6024   size(8);
 6025   format %{ "SUB    $dst.lo,$src1.lo,$con\t! long\n\t"
 6026             "SBC    $dst.hi,$src1.hi,0" %}
 6027   ins_encode %{
 6028     __ subs($dst$$Register, $src1$$Register, $con$$constant);
 6029     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), 0);
 6030   %}
 6031   ins_pipe(ialu_reg_imm);
 6032 %}
 6033 
 6034 // Long negation
 6035 instruct negL_reg_reg(iRegL dst, immL0 zero, iRegL src2, flagsReg icc) %{
 6036   match(Set dst (SubL zero src2));
 6037   effect (KILL icc);
 6038 
 6039   size(8);
 6040   format %{ "RSBS   $dst.lo,$src2.lo,0\t! long\n\t"
 6041             "RSC    $dst.hi,$src2.hi,0" %}
 6042   ins_encode %{
 6043     __ rsbs($dst$$Register, $src2$$Register, 0);
 6044     __ rsc($dst$$Register->successor(), $src2$$Register->successor(), 0);
 6045   %}
 6046   ins_pipe(ialu_zero_reg);
 6047 %}
 6048 
 6049 // Multiplication Instructions
 6050 // Integer Multiplication
 6051 // Register Multiplication
 6052 instruct mulI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6053   match(Set dst (MulI src1 src2));
 6054 
 6055   size(4);
 6056   format %{ "mul_32 $dst,$src1,$src2" %}
 6057   ins_encode %{
 6058     __ mul_32($dst$$Register, $src1$$Register, $src2$$Register);
 6059   %}
 6060   ins_pipe(imul_reg_reg);
 6061 %}
 6062 
 6063 instruct mulL_lo1_hi2(iRegL dst, iRegL src1, iRegL src2) %{
 6064   effect(DEF dst, USE src1, USE src2);
 6065   size(4);
 6066   format %{ "MUL  $dst.hi,$src1.lo,$src2.hi\t! long" %}
 6067   ins_encode %{
 6068     __ mul($dst$$Register->successor(), $src1$$Register, $src2$$Register->successor());
 6069   %}
 6070   ins_pipe(imul_reg_reg);
 6071 %}
 6072 
 6073 instruct mulL_hi1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
 6074   effect(USE_DEF dst, USE src1, USE src2);
 6075   size(8);
 6076   format %{ "MLA  $dst.hi,$src1.hi,$src2.lo,$dst.hi\t! long\n\t"
 6077             "MOV  $dst.lo, 0"%}
 6078   ins_encode %{
 6079     __ mla($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register, $dst$$Register->successor());
 6080     __ mov($dst$$Register, 0);
 6081   %}
 6082   ins_pipe(imul_reg_reg);
 6083 %}
 6084 
 6085 instruct mulL_lo1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
 6086   effect(USE_DEF dst, USE src1, USE src2);
 6087   size(4);
 6088   format %{ "UMLAL  $dst.lo,$dst.hi,$src1,$src2\t! long" %}
 6089   ins_encode %{
 6090     __ umlal($dst$$Register, $dst$$Register->successor(), $src1$$Register, $src2$$Register);
 6091   %}
 6092   ins_pipe(imul_reg_reg);
 6093 %}
 6094 
 6095 instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 6096   match(Set dst (MulL src1 src2));
 6097 
 6098   expand %{
 6099     mulL_lo1_hi2(dst, src1, src2);
 6100     mulL_hi1_lo2(dst, src1, src2);
 6101     mulL_lo1_lo2(dst, src1, src2);
 6102   %}
 6103 %}
 6104 
 6105 // Integer Division
 6106 // Register Division
 6107 instruct divI_reg_reg(R1RegI dst, R0RegI src1, R2RegI src2, LRRegP lr, flagsReg ccr) %{
 6108   match(Set dst (DivI src1 src2));
 6109   effect( KILL ccr, KILL src1, KILL src2, KILL lr);
 6110   ins_cost((2+71)*DEFAULT_COST);
 6111 
 6112   format %{ "DIV   $dst,$src1,$src2 ! call to StubRoutines::Arm::idiv_irem_entry()" %}
 6113   ins_encode %{
 6114     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
 6115   %}
 6116   ins_pipe(sdiv_reg_reg);
 6117 %}
 6118 
 6119 // Register Long Division
 6120 instruct divL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
 6121   match(Set dst (DivL src1 src2));
 6122   effect(CALL);
 6123   ins_cost(DEFAULT_COST*71);
 6124   format %{ "DIVL  $src1,$src2,$dst\t! long ! call to SharedRuntime::ldiv" %}
 6125   ins_encode %{
 6126     address target = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);
 6127     __ call(target, relocInfo::runtime_call_type);
 6128   %}
 6129   ins_pipe(divL_reg_reg);
 6130 %}
 6131 
 6132 // Integer Remainder
 6133 // Register Remainder
 6134 instruct modI_reg_reg(R0RegI dst, R0RegI src1, R2RegI src2, R1RegI temp, LRRegP lr, flagsReg ccr ) %{
 6135   match(Set dst (ModI src1 src2));
 6136   effect( KILL ccr, KILL temp, KILL src2, KILL lr);
 6137 
 6138   format %{ "MODI   $dst,$src1,$src2\t ! call to StubRoutines::Arm::idiv_irem_entry" %}
 6139   ins_encode %{
 6140     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
 6141   %}
 6142   ins_pipe(sdiv_reg_reg);
 6143 %}
 6144 
 6145 // Register Long Remainder
 6146 instruct modL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
 6147   match(Set dst (ModL src1 src2));
 6148   effect(CALL);
 6149   ins_cost(MEMORY_REF_COST); // FIXME
 6150   format %{ "modL    $dst,$src1,$src2\t ! call to SharedRuntime::lrem" %}
 6151   ins_encode %{
 6152     address target = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
 6153     __ call(target, relocInfo::runtime_call_type);
 6154   %}
 6155   ins_pipe(divL_reg_reg);
 6156 %}
 6157 
 6158 // Integer Shift Instructions
 6159 
 6160 // Register Shift Left
 6161 instruct shlI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6162   match(Set dst (LShiftI src1 src2));
 6163 
 6164   size(4);
 6165   format %{ "LSL  $dst,$src1,$src2 \n\t" %}
 6166   ins_encode %{
 6167     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 6168   %}
 6169   ins_pipe(ialu_reg_reg);
 6170 %}
 6171 
 6172 // Register Shift Left Immediate
 6173 instruct shlI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
 6174   match(Set dst (LShiftI src1 src2));
 6175 
 6176   size(4);
 6177   format %{ "LSL    $dst,$src1,$src2\t! int" %}
 6178   ins_encode %{
 6179     __ logical_shift_left($dst$$Register, $src1$$Register, $src2$$constant);
 6180   %}
 6181   ins_pipe(ialu_reg_imm);
 6182 %}
 6183 
 6184 instruct shlL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
 6185   effect(USE_DEF dst, USE src1, USE src2);
 6186   size(4);
 6187   format %{"OR  $dst.hi,$dst.hi,($src1.hi << $src2)"  %}
 6188   ins_encode %{
 6189     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$Register));
 6190   %}
 6191   ins_pipe(ialu_reg_reg);
 6192 %}
 6193 
 6194 instruct shlL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
 6195   effect(USE_DEF dst, USE src1, USE src2);
 6196   size(4);
 6197   format %{ "LSL  $dst.lo,$src1.lo,$src2 \n\t" %}
 6198   ins_encode %{
 6199     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 6200   %}
 6201   ins_pipe(ialu_reg_reg);
 6202 %}
 6203 
 6204 instruct shlL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
 6205   effect(DEF dst, USE src1, USE src2, KILL ccr);
 6206   size(16);
 6207   format %{ "SUBS  $dst.hi,$src2,32 \n\t"
 6208             "LSLpl $dst.hi,$src1.lo,$dst.hi \n\t"
 6209             "RSBmi $dst.hi,$dst.hi,0 \n\t"
 6210             "LSRmi $dst.hi,$src1.lo,$dst.hi" %}
 6211 
 6212   ins_encode %{
 6213     // $src1$$Register and $dst$$Register->successor() can't be the same
 6214     __ subs($dst$$Register->successor(), $src2$$Register, 32);
 6215     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $dst$$Register->successor()), pl);
 6216     __ rsb($dst$$Register->successor(), $dst$$Register->successor(), 0, mi);
 6217     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsr, $dst$$Register->successor()), mi);
 6218   %}
 6219   ins_pipe(ialu_reg_reg);
 6220 %}
 6221 
 6222 instruct shlL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
 6223   match(Set dst (LShiftL src1 src2));
 6224 
 6225   expand %{
 6226     flagsReg ccr;
 6227     shlL_reg_reg_overlap(dst, src1, src2, ccr);
 6228     shlL_reg_reg_merge_hi(dst, src1, src2);
 6229     shlL_reg_reg_merge_lo(dst, src1, src2);
 6230   %}
 6231 %}
 6232 
 6233 // Register Shift Left Immediate
 6234 instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
 6235   match(Set dst (LShiftL src1 src2));
 6236 
 6237   size(8);
 6238   format %{ "LSL   $dst.hi,$src1.lo,$src2-32\t! or mov if $src2==32\n\t"
 6239             "MOV   $dst.lo, 0" %}
 6240   ins_encode %{
 6241     if ($src2$$constant == 32) {
 6242       __ mov($dst$$Register->successor(), $src1$$Register);
 6243     } else {
 6244       __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $src2$$constant-32));
 6245     }
 6246     __ mov($dst$$Register, 0);
 6247   %}
 6248   ins_pipe(ialu_reg_imm);
 6249 %}
 6250 
 6251 instruct shlL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
 6252   match(Set dst (LShiftL src1 src2));
 6253 
 6254   size(12);
 6255   format %{ "LSL   $dst.hi,$src1.lo,$src2\n\t"
 6256             "OR    $dst.hi, $dst.hi, $src1.lo >> 32-$src2\n\t"
 6257             "LSL   $dst.lo,$src1.lo,$src2" %}
 6258   ins_encode %{
 6259     // The order of the following 3 instructions matters: src1.lo and
 6260     // dst.hi can't overlap but src.hi and dst.hi can.
 6261     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$constant));
 6262     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register, lsr, 32-$src2$$constant));
 6263     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
 6264   %}
 6265   ins_pipe(ialu_reg_imm);
 6266 %}
 6267 
 6268 // Register Arithmetic Shift Right
 6269 instruct sarI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6270   match(Set dst (RShiftI src1 src2));
 6271   size(4);
 6272   format %{ "ASR    $dst,$src1,$src2\t! int" %}
 6273   ins_encode %{
 6274     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
 6275   %}
 6276   ins_pipe(ialu_reg_reg);
 6277 %}
 6278 
 6279 // Register Arithmetic Shift Right Immediate
 6280 instruct sarI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
 6281   match(Set dst (RShiftI src1 src2));
 6282 
 6283   size(4);
 6284   format %{ "ASR    $dst,$src1,$src2" %}
 6285   ins_encode %{
 6286     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
 6287   %}
 6288   ins_pipe(ialu_reg_imm);
 6289 %}
 6290 
 6291 // Register Shift Right Arithmetic Long
 6292 instruct sarL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
 6293   effect(USE_DEF dst, USE src1, USE src2);
 6294   size(4);
 6295   format %{ "OR  $dst.lo,$dst.lo,($src1.lo >> $src2)"  %}
 6296   ins_encode %{
 6297     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6298   %}
 6299   ins_pipe(ialu_reg_reg);
 6300 %}
 6301 
 6302 instruct sarL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
 6303   effect(USE_DEF dst, USE src1, USE src2);
 6304   size(4);
 6305   format %{ "ASR  $dst.hi,$src1.hi,$src2 \n\t" %}
 6306   ins_encode %{
 6307     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$Register));
 6308   %}
 6309   ins_pipe(ialu_reg_reg);
 6310 %}
 6311 
 6312 instruct sarL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
 6313   effect(DEF dst, USE src1, USE src2, KILL ccr);
 6314   size(16);
 6315   format %{ "SUBS  $dst.lo,$src2,32 \n\t"
 6316             "ASRpl $dst.lo,$src1.hi,$dst.lo \n\t"
 6317             "RSBmi $dst.lo,$dst.lo,0 \n\t"
 6318             "LSLmi $dst.lo,$src1.hi,$dst.lo" %}
 6319 
 6320   ins_encode %{
 6321     // $src1$$Register->successor() and $dst$$Register can't be the same
 6322     __ subs($dst$$Register, $src2$$Register, 32);
 6323     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $dst$$Register), pl);
 6324     __ rsb($dst$$Register, $dst$$Register, 0, mi);
 6325     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
 6326   %}
 6327   ins_pipe(ialu_reg_reg);
 6328 %}
 6329 
 6330 instruct sarL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
 6331   match(Set dst (RShiftL src1 src2));
 6332 
 6333   expand %{
 6334     flagsReg ccr;
 6335     sarL_reg_reg_overlap(dst, src1, src2, ccr);
 6336     sarL_reg_reg_merge_lo(dst, src1, src2);
 6337     sarL_reg_reg_merge_hi(dst, src1, src2);
 6338   %}
 6339 %}
 6340 
 6341 // Register Shift Left Immediate
 6342 instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
 6343   match(Set dst (RShiftL src1 src2));
 6344 
 6345   size(8);
 6346   format %{ "ASR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
 6347             "ASR   $dst.hi,$src1.hi, $src2" %}
 6348   ins_encode %{
 6349     if ($src2$$constant == 32) {
 6350       __ mov($dst$$Register, $src1$$Register->successor());
 6351     } else{
 6352       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $src2$$constant-32));
 6353     }
 6354     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, 0));
 6355   %}
 6356 
 6357   ins_pipe(ialu_reg_imm);
 6358 %}
 6359 
 6360 instruct sarL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
 6361   match(Set dst (RShiftL src1 src2));
 6362   size(12);
 6363   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
 6364             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
 6365             "ASR   $dst.hi,$src1.hi,$src2" %}
 6366   ins_encode %{
 6367     // The order of the following 3 instructions matters: src1.lo and
 6368     // dst.hi can't overlap but src.hi and dst.hi can.
 6369     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6370     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
 6371     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$constant));
 6372   %}
 6373   ins_pipe(ialu_reg_imm);
 6374 %}
 6375 
 6376 // Register Shift Right
 6377 instruct shrI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6378   match(Set dst (URShiftI src1 src2));
 6379   size(4);
 6380   format %{ "LSR    $dst,$src1,$src2\t! int" %}
 6381   ins_encode %{
 6382     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6383   %}
 6384   ins_pipe(ialu_reg_reg);
 6385 %}
 6386 
 6387 // Register Shift Right Immediate
 6388 instruct shrI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
 6389   match(Set dst (URShiftI src1 src2));
 6390 
 6391   size(4);
 6392   format %{ "LSR    $dst,$src1,$src2" %}
 6393   ins_encode %{
 6394     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6395   %}
 6396   ins_pipe(ialu_reg_imm);
 6397 %}
 6398 
 6399 // Register Shift Right
 6400 instruct shrL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
 6401   effect(USE_DEF dst, USE src1, USE src2);
 6402   size(4);
 6403   format %{ "OR   $dst.lo,$dst,($src1.lo >>> $src2)"  %}
 6404   ins_encode %{
 6405     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6406   %}
 6407   ins_pipe(ialu_reg_reg);
 6408 %}
 6409 
 6410 instruct shrL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
 6411   effect(USE_DEF dst, USE src1, USE src2);
 6412   size(4);
 6413   format %{ "LSR  $dst.hi,$src1.hi,$src2 \n\t" %}
 6414   ins_encode %{
 6415     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$Register));
 6416   %}
 6417   ins_pipe(ialu_reg_reg);
 6418 %}
 6419 
 6420 instruct shrL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
 6421   effect(DEF dst, USE src1, USE src2, KILL ccr);
 6422   size(16);
 6423   format %{ "SUBS  $dst,$src2,32 \n\t"
 6424             "LSRpl $dst,$src1.hi,$dst \n\t"
 6425             "RSBmi $dst,$dst,0 \n\t"
 6426             "LSLmi $dst,$src1.hi,$dst" %}
 6427 
 6428   ins_encode %{
 6429     // $src1$$Register->successor() and $dst$$Register can't be the same
 6430     __ subs($dst$$Register, $src2$$Register, 32);
 6431     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $dst$$Register), pl);
 6432     __ rsb($dst$$Register, $dst$$Register, 0, mi);
 6433     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
 6434   %}
 6435   ins_pipe(ialu_reg_reg);
 6436 %}
 6437 
 6438 instruct shrL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
 6439   match(Set dst (URShiftL src1 src2));
 6440 
 6441   expand %{
 6442     flagsReg ccr;
 6443     shrL_reg_reg_overlap(dst, src1, src2, ccr);
 6444     shrL_reg_reg_merge_lo(dst, src1, src2);
 6445     shrL_reg_reg_merge_hi(dst, src1, src2);
 6446   %}
 6447 %}
 6448 
 6449 // Register Shift Right Immediate
 6450 instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
 6451   match(Set dst (URShiftL src1 src2));
 6452 
 6453   size(8);
 6454   format %{ "LSR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
 6455             "MOV   $dst.hi, 0" %}
 6456   ins_encode %{
 6457     if ($src2$$constant == 32) {
 6458       __ mov($dst$$Register, $src1$$Register->successor());
 6459     } else {
 6460       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $src2$$constant-32));
 6461     }
 6462     __ mov($dst$$Register->successor(), 0);
 6463   %}
 6464 
 6465   ins_pipe(ialu_reg_imm);
 6466 %}
 6467 
 6468 instruct shrL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
 6469   match(Set dst (URShiftL src1 src2));
 6470 
 6471   size(12);
 6472   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
 6473             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
 6474             "LSR   $dst.hi,$src1.hi,$src2" %}
 6475   ins_encode %{
 6476     // The order of the following 3 instructions matters: src1.lo and
 6477     // dst.hi can't overlap but src.hi and dst.hi can.
 6478     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6479     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
 6480     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$constant));
 6481   %}
 6482   ins_pipe(ialu_reg_imm);
 6483 %}
 6484 
 6485 
 6486 instruct shrP_reg_imm5(iRegX dst, iRegP src1, immU5 src2) %{
 6487   match(Set dst (URShiftI (CastP2X src1) src2));
 6488   size(4);
 6489   format %{ "LSR    $dst,$src1,$src2\t! Cast ptr $src1 to int and shift" %}
 6490   ins_encode %{
 6491     __ logical_shift_right($dst$$Register, $src1$$Register, $src2$$constant);
 6492   %}
 6493   ins_pipe(ialu_reg_imm);
 6494 %}
 6495 
 6496 //----------Floating Point Arithmetic Instructions-----------------------------
 6497 
 6498 //  Add float single precision
 6499 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
 6500   match(Set dst (AddF src1 src2));
 6501 
 6502   size(4);
 6503   format %{ "FADDS  $dst,$src1,$src2" %}
 6504   ins_encode %{
 6505     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6506   %}
 6507 
 6508   ins_pipe(faddF_reg_reg);
 6509 %}
 6510 
 6511 //  Add float double precision
 6512 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
 6513   match(Set dst (AddD src1 src2));
 6514 
 6515   size(4);
 6516   format %{ "FADDD  $dst,$src1,$src2" %}
 6517   ins_encode %{
 6518     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6519   %}
 6520 
 6521   ins_pipe(faddD_reg_reg);
 6522 %}
 6523 
 6524 //  Sub float single precision
 6525 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
 6526   match(Set dst (SubF src1 src2));
 6527 
 6528   size(4);
 6529   format %{ "FSUBS  $dst,$src1,$src2" %}
 6530   ins_encode %{
 6531     __ sub_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6532   %}
 6533   ins_pipe(faddF_reg_reg);
 6534 %}
 6535 
 6536 //  Sub float double precision
 6537 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
 6538   match(Set dst (SubD src1 src2));
 6539 
 6540   size(4);
 6541   format %{ "FSUBD  $dst,$src1,$src2" %}
 6542   ins_encode %{
 6543     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6544   %}
 6545   ins_pipe(faddD_reg_reg);
 6546 %}
 6547 
 6548 //  Mul float single precision
 6549 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
 6550   match(Set dst (MulF src1 src2));
 6551 
 6552   size(4);
 6553   format %{ "FMULS  $dst,$src1,$src2" %}
 6554   ins_encode %{
 6555     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6556   %}
 6557 
 6558   ins_pipe(fmulF_reg_reg);
 6559 %}
 6560 
 6561 //  Mul float double precision
 6562 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
 6563   match(Set dst (MulD src1 src2));
 6564 
 6565   size(4);
 6566   format %{ "FMULD  $dst,$src1,$src2" %}
 6567   ins_encode %{
 6568     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6569   %}
 6570 
 6571   ins_pipe(fmulD_reg_reg);
 6572 %}
 6573 
 6574 //  Div float single precision
 6575 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
 6576   match(Set dst (DivF src1 src2));
 6577 
 6578   size(4);
 6579   format %{ "FDIVS  $dst,$src1,$src2" %}
 6580   ins_encode %{
 6581     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6582   %}
 6583 
 6584   ins_pipe(fdivF_reg_reg);
 6585 %}
 6586 
 6587 //  Div float double precision
 6588 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
 6589   match(Set dst (DivD src1 src2));
 6590 
 6591   size(4);
 6592   format %{ "FDIVD  $dst,$src1,$src2" %}
 6593   ins_encode %{
 6594     __ div_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6595   %}
 6596 
 6597   ins_pipe(fdivD_reg_reg);
 6598 %}
 6599 
 6600 //  Absolute float double precision
 6601 instruct absD_reg(regD dst, regD src) %{
 6602   match(Set dst (AbsD src));
 6603 
 6604   size(4);
 6605   format %{ "FABSd  $dst,$src" %}
 6606   ins_encode %{
 6607     __ abs_double($dst$$FloatRegister, $src$$FloatRegister);
 6608   %}
 6609   ins_pipe(faddD_reg);
 6610 %}
 6611 
 6612 //  Absolute float single precision
 6613 instruct absF_reg(regF dst, regF src) %{
 6614   match(Set dst (AbsF src));
 6615   format %{ "FABSs  $dst,$src" %}
 6616   ins_encode %{
 6617     __ abs_float($dst$$FloatRegister, $src$$FloatRegister);
 6618   %}
 6619   ins_pipe(faddF_reg);
 6620 %}
 6621 
 6622 instruct negF_reg(regF dst, regF src) %{
 6623   match(Set dst (NegF src));
 6624 
 6625   size(4);
 6626   format %{ "FNEGs  $dst,$src" %}
 6627   ins_encode %{
 6628     __ neg_float($dst$$FloatRegister, $src$$FloatRegister);
 6629   %}
 6630   ins_pipe(faddF_reg);
 6631 %}
 6632 
 6633 instruct negD_reg(regD dst, regD src) %{
 6634   match(Set dst (NegD src));
 6635 
 6636   format %{ "FNEGd  $dst,$src" %}
 6637   ins_encode %{
 6638     __ neg_double($dst$$FloatRegister, $src$$FloatRegister);
 6639   %}
 6640   ins_pipe(faddD_reg);
 6641 %}
 6642 
 6643 //  Sqrt float double precision
 6644 instruct sqrtF_reg_reg(regF dst, regF src) %{
 6645   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
 6646 
 6647   size(4);
 6648   format %{ "FSQRTS $dst,$src" %}
 6649   ins_encode %{
 6650     __ sqrt_float($dst$$FloatRegister, $src$$FloatRegister);
 6651   %}
 6652   ins_pipe(fdivF_reg_reg);
 6653 %}
 6654 
 6655 //  Sqrt float double precision
 6656 instruct sqrtD_reg_reg(regD dst, regD src) %{
 6657   match(Set dst (SqrtD src));
 6658 
 6659   size(4);
 6660   format %{ "FSQRTD $dst,$src" %}
 6661   ins_encode %{
 6662     __ sqrt_double($dst$$FloatRegister, $src$$FloatRegister);
 6663   %}
 6664   ins_pipe(fdivD_reg_reg);
 6665 %}
 6666 
 6667 //----------Logical Instructions-----------------------------------------------
 6668 // And Instructions
 6669 // Register And
 6670 instruct andI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6671   match(Set dst (AndI src1 src2));
 6672 
 6673   size(4);
 6674   format %{ "and_32 $dst,$src1,$src2" %}
 6675   ins_encode %{
 6676     __ and_32($dst$$Register, $src1$$Register, $src2$$Register);
 6677   %}
 6678   ins_pipe(ialu_reg_reg);
 6679 %}
 6680 
 6681 instruct andshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6682   match(Set dst (AndI src1 (LShiftI src2 src3)));
 6683 
 6684   size(4);
 6685   format %{ "AND    $dst,$src1,$src2<<$src3" %}
 6686   ins_encode %{
 6687     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 6688   %}
 6689   ins_pipe(ialu_reg_reg);
 6690 %}
 6691 
 6692 instruct andshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6693   match(Set dst (AndI src1 (LShiftI src2 src3)));
 6694 
 6695   size(4);
 6696   format %{ "and_32 $dst,$src1,$src2<<$src3" %}
 6697   ins_encode %{
 6698     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 6699   %}
 6700   ins_pipe(ialu_reg_reg);
 6701 %}
 6702 
 6703 instruct andsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6704   match(Set dst (AndI src1 (RShiftI src2 src3)));
 6705 
 6706   size(4);
 6707   format %{ "AND    $dst,$src1,$src2>>$src3" %}
 6708   ins_encode %{
 6709     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 6710   %}
 6711   ins_pipe(ialu_reg_reg);
 6712 %}
 6713 
 6714 instruct andsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6715   match(Set dst (AndI src1 (RShiftI src2 src3)));
 6716 
 6717   size(4);
 6718   format %{ "and_32 $dst,$src1,$src2>>$src3" %}
 6719   ins_encode %{
 6720     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 6721   %}
 6722   ins_pipe(ialu_reg_reg);
 6723 %}
 6724 
 6725 instruct andshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6726   match(Set dst (AndI src1 (URShiftI src2 src3)));
 6727 
 6728   size(4);
 6729   format %{ "AND    $dst,$src1,$src2>>>$src3" %}
 6730   ins_encode %{
 6731     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 6732   %}
 6733   ins_pipe(ialu_reg_reg);
 6734 %}
 6735 
 6736 instruct andshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6737   match(Set dst (AndI src1 (URShiftI src2 src3)));
 6738 
 6739   size(4);
 6740   format %{ "and_32 $dst,$src1,$src2>>>$src3" %}
 6741   ins_encode %{
 6742     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 6743   %}
 6744   ins_pipe(ialu_reg_reg);
 6745 %}
 6746 
 6747 // Immediate And
 6748 instruct andI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
 6749   match(Set dst (AndI src1 src2));
 6750 
 6751   size(4);
 6752   format %{ "and_32 $dst,$src1,$src2\t! int" %}
 6753   ins_encode %{
 6754     __ and_32($dst$$Register, $src1$$Register, $src2$$constant);
 6755   %}
 6756   ins_pipe(ialu_reg_imm);
 6757 %}
 6758 
 6759 instruct andI_reg_limmn(iRegI dst, iRegI src1, limmIn src2) %{
 6760   match(Set dst (AndI src1 src2));
 6761 
 6762   size(4);
 6763   format %{ "bic    $dst,$src1,~$src2\t! int" %}
 6764   ins_encode %{
 6765     __ bic($dst$$Register, $src1$$Register, ~$src2$$constant);
 6766   %}
 6767   ins_pipe(ialu_reg_imm);
 6768 %}
 6769 
 6770 // Register And Long
 6771 instruct andL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 6772   match(Set dst (AndL src1 src2));
 6773 
 6774   ins_cost(DEFAULT_COST);
 6775   size(8);
 6776   format %{ "AND    $dst,$src1,$src2\t! long" %}
 6777   ins_encode %{
 6778     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
 6779     __ andr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 6780   %}
 6781   ins_pipe(ialu_reg_reg);
 6782 %}
 6783 
 6784 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 6785 // (hi($con$$constant), lo($con$$constant)) becomes
 6786 instruct andL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
 6787   match(Set dst (AndL src1 con));
 6788   ins_cost(DEFAULT_COST);
 6789   size(8);
 6790   format %{ "AND    $dst,$src1,$con\t! long" %}
 6791   ins_encode %{
 6792     __ andr($dst$$Register, $src1$$Register, $con$$constant);
 6793     __ andr($dst$$Register->successor(), $src1$$Register->successor(), 0);
 6794   %}
 6795   ins_pipe(ialu_reg_imm);
 6796 %}
 6797 
 6798 // Or Instructions
 6799 // Register Or
 6800 instruct orI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6801   match(Set dst (OrI src1 src2));
 6802 
 6803   size(4);
 6804   format %{ "orr_32 $dst,$src1,$src2\t! int" %}
 6805   ins_encode %{
 6806     __ orr_32($dst$$Register, $src1$$Register, $src2$$Register);
 6807   %}
 6808   ins_pipe(ialu_reg_reg);
 6809 %}
 6810 
 6811 instruct orshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6812   match(Set dst (OrI src1 (LShiftI src2 src3)));
 6813 
 6814   size(4);
 6815   format %{ "OR    $dst,$src1,$src2<<$src3" %}
 6816   ins_encode %{
 6817     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 6818   %}
 6819   ins_pipe(ialu_reg_reg);
 6820 %}
 6821 
 6822 instruct orshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6823   match(Set dst (OrI src1 (LShiftI src2 src3)));
 6824 
 6825   size(4);
 6826   format %{ "orr_32 $dst,$src1,$src2<<$src3" %}
 6827   ins_encode %{
 6828     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 6829   %}
 6830   ins_pipe(ialu_reg_reg);
 6831 %}
 6832 
 6833 instruct orsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6834   match(Set dst (OrI src1 (RShiftI src2 src3)));
 6835 
 6836   size(4);
 6837   format %{ "OR    $dst,$src1,$src2>>$src3" %}
 6838   ins_encode %{
 6839     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 6840   %}
 6841   ins_pipe(ialu_reg_reg);
 6842 %}
 6843 
 6844 instruct orsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6845   match(Set dst (OrI src1 (RShiftI src2 src3)));
 6846 
 6847   size(4);
 6848   format %{ "orr_32 $dst,$src1,$src2>>$src3" %}
 6849   ins_encode %{
 6850     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 6851   %}
 6852   ins_pipe(ialu_reg_reg);
 6853 %}
 6854 
 6855 instruct orshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6856   match(Set dst (OrI src1 (URShiftI src2 src3)));
 6857 
 6858   size(4);
 6859   format %{ "OR    $dst,$src1,$src2>>>$src3" %}
 6860   ins_encode %{
 6861     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 6862   %}
 6863   ins_pipe(ialu_reg_reg);
 6864 %}
 6865 
 6866 instruct orshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6867   match(Set dst (OrI src1 (URShiftI src2 src3)));
 6868 
 6869   size(4);
 6870   format %{ "orr_32 $dst,$src1,$src2>>>$src3" %}
 6871   ins_encode %{
 6872     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 6873   %}
 6874   ins_pipe(ialu_reg_reg);
 6875 %}
 6876 
 6877 // Immediate Or
 6878 instruct orI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
 6879   match(Set dst (OrI src1 src2));
 6880 
 6881   size(4);
 6882   format %{ "orr_32  $dst,$src1,$src2" %}
 6883   ins_encode %{
 6884     __ orr_32($dst$$Register, $src1$$Register, $src2$$constant);
 6885   %}
 6886   ins_pipe(ialu_reg_imm);
 6887 %}
 6888 // TODO: orn_32 with limmIn
 6889 
 6890 // Register Or Long
 6891 instruct orL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 6892   match(Set dst (OrL src1 src2));
 6893 
 6894   ins_cost(DEFAULT_COST);
 6895   size(8);
 6896   format %{ "OR     $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
 6897             "OR     $dst.hi,$src1.hi,$src2.hi" %}
 6898   ins_encode %{
 6899     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
 6900     __ orr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 6901   %}
 6902   ins_pipe(ialu_reg_reg);
 6903 %}
 6904 
 6905 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 6906 // (hi($con$$constant), lo($con$$constant)) becomes
 6907 instruct orL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
 6908   match(Set dst (OrL src1 con));
 6909   ins_cost(DEFAULT_COST);
 6910   size(8);
 6911   format %{ "OR     $dst.lo,$src1.lo,$con\t! long\n\t"
 6912             "OR     $dst.hi,$src1.hi,$con" %}
 6913   ins_encode %{
 6914     __ orr($dst$$Register, $src1$$Register, $con$$constant);
 6915     __ orr($dst$$Register->successor(), $src1$$Register->successor(), 0);
 6916   %}
 6917   ins_pipe(ialu_reg_imm);
 6918 %}
 6919 
 6920 #ifdef TODO
 6921 // Use SPRegP to match Rthread (TLS register) without spilling.
 6922 // Use store_ptr_RegP to match Rthread (TLS register) without spilling.
 6923 // Use sp_ptr_RegP to match Rthread (TLS register) without spilling.
 6924 instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
 6925   match(Set dst (OrI src1 (CastP2X src2)));
 6926   size(4);
 6927   format %{ "OR     $dst,$src1,$src2" %}
 6928   ins_encode %{
 6929     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
 6930   %}
 6931   ins_pipe(ialu_reg_reg);
 6932 %}
 6933 #endif
 6934 
 6935 // Xor Instructions
 6936 // Register Xor
 6937 instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6938   match(Set dst (XorI src1 src2));
 6939 
 6940   size(4);
 6941   format %{ "eor_32 $dst,$src1,$src2" %}
 6942   ins_encode %{
 6943     __ eor_32($dst$$Register, $src1$$Register, $src2$$Register);
 6944   %}
 6945   ins_pipe(ialu_reg_reg);
 6946 %}
 6947 
 6948 instruct xorshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6949   match(Set dst (XorI src1 (LShiftI src2 src3)));
 6950 
 6951   size(4);
 6952   format %{ "XOR    $dst,$src1,$src2<<$src3" %}
 6953   ins_encode %{
 6954     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 6955   %}
 6956   ins_pipe(ialu_reg_reg);
 6957 %}
 6958 
 6959 instruct xorshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6960   match(Set dst (XorI src1 (LShiftI src2 src3)));
 6961 
 6962   size(4);
 6963   format %{ "eor_32 $dst,$src1,$src2<<$src3" %}
 6964   ins_encode %{
 6965     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 6966   %}
 6967   ins_pipe(ialu_reg_reg);
 6968 %}
 6969 
 6970 instruct xorsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6971   match(Set dst (XorI src1 (RShiftI src2 src3)));
 6972 
 6973   size(4);
 6974   format %{ "XOR    $dst,$src1,$src2>>$src3" %}
 6975   ins_encode %{
 6976     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 6977   %}
 6978   ins_pipe(ialu_reg_reg);
 6979 %}
 6980 
 6981 instruct xorsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6982   match(Set dst (XorI src1 (RShiftI src2 src3)));
 6983 
 6984   size(4);
 6985   format %{ "eor_32 $dst,$src1,$src2>>$src3" %}
 6986   ins_encode %{
 6987     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 6988   %}
 6989   ins_pipe(ialu_reg_reg);
 6990 %}
 6991 
 6992 instruct xorshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6993   match(Set dst (XorI src1 (URShiftI src2 src3)));
 6994 
 6995   size(4);
 6996   format %{ "XOR    $dst,$src1,$src2>>>$src3" %}
 6997   ins_encode %{
 6998     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 6999   %}
 7000   ins_pipe(ialu_reg_reg);
 7001 %}
 7002 
 7003 instruct xorshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 7004   match(Set dst (XorI src1 (URShiftI src2 src3)));
 7005 
 7006   size(4);
 7007   format %{ "eor_32 $dst,$src1,$src2>>>$src3" %}
 7008   ins_encode %{
 7009     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 7010   %}
 7011   ins_pipe(ialu_reg_reg);
 7012 %}
 7013 
 7014 // Immediate Xor
 7015 instruct xorI_reg_imm(iRegI dst, iRegI src1, limmI src2) %{
 7016   match(Set dst (XorI src1 src2));
 7017 
 7018   size(4);
 7019   format %{ "eor_32 $dst,$src1,$src2" %}
 7020   ins_encode %{
 7021     __ eor_32($dst$$Register, $src1$$Register, $src2$$constant);
 7022   %}
 7023   ins_pipe(ialu_reg_imm);
 7024 %}
 7025 
 7026 // Register Xor Long
 7027 instruct xorL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 7028   match(Set dst (XorL src1 src2));
 7029   ins_cost(DEFAULT_COST);
 7030   size(8);
 7031   format %{ "XOR     $dst.hi,$src1.hi,$src2.hi\t! long\n\t"
 7032             "XOR     $dst.lo,$src1.lo,$src2.lo\t! long" %}
 7033   ins_encode %{
 7034     __ eor($dst$$Register, $src1$$Register, $src2$$Register);
 7035     __ eor($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 7036   %}
 7037   ins_pipe(ialu_reg_reg);
 7038 %}
 7039 
 7040 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7041 // (hi($con$$constant), lo($con$$constant)) becomes
 7042 instruct xorL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
 7043   match(Set dst (XorL src1 con));
 7044   ins_cost(DEFAULT_COST);
 7045   size(8);
 7046   format %{ "XOR     $dst.hi,$src1.hi,$con\t! long\n\t"
 7047             "XOR     $dst.lo,$src1.lo,0\t! long" %}
 7048   ins_encode %{
 7049     __ eor($dst$$Register, $src1$$Register, $con$$constant);
 7050     __ eor($dst$$Register->successor(), $src1$$Register->successor(), 0);
 7051   %}
 7052   ins_pipe(ialu_reg_imm);
 7053 %}
 7054 
 7055 //----------Convert to Boolean-------------------------------------------------
 7056 instruct convI2B( iRegI dst, iRegI src, flagsReg ccr ) %{
 7057   match(Set dst (Conv2B src));
 7058   effect(KILL ccr);
 7059   size(12);
 7060   ins_cost(DEFAULT_COST*2);
 7061   format %{ "TST    $src,$src \n\t"
 7062             "MOV    $dst, 0   \n\t"
 7063             "MOV.ne $dst, 1" %}
 7064   ins_encode %{ // FIXME: can do better?
 7065     __ tst($src$$Register, $src$$Register);
 7066     __ mov($dst$$Register, 0);
 7067     __ mov($dst$$Register, 1, ne);
 7068   %}
 7069   ins_pipe(ialu_reg_ialu);
 7070 %}
 7071 
 7072 instruct convP2B( iRegI dst, iRegP src, flagsReg ccr ) %{
 7073   match(Set dst (Conv2B src));
 7074   effect(KILL ccr);
 7075   size(12);
 7076   ins_cost(DEFAULT_COST*2);
 7077   format %{ "TST    $src,$src \n\t"
 7078             "MOV    $dst, 0   \n\t"
 7079             "MOV.ne $dst, 1" %}
 7080   ins_encode %{
 7081     __ tst($src$$Register, $src$$Register);
 7082     __ mov($dst$$Register, 0);
 7083     __ mov($dst$$Register, 1, ne);
 7084   %}
 7085   ins_pipe(ialu_reg_ialu);
 7086 %}
 7087 
 7088 instruct cmpLTMask_reg_reg( iRegI dst, iRegI p, iRegI q, flagsReg ccr ) %{
 7089   match(Set dst (CmpLTMask p q));
 7090   effect( KILL ccr );
 7091   ins_cost(DEFAULT_COST*3);
 7092   format %{ "CMP    $p,$q\n\t"
 7093             "MOV    $dst, #0\n\t"
 7094             "MOV.lt $dst, #-1" %}
 7095   ins_encode %{
 7096     __ cmp($p$$Register, $q$$Register);
 7097     __ mov($dst$$Register, 0);
 7098     __ mvn($dst$$Register, 0, lt);
 7099   %}
 7100   ins_pipe(ialu_reg_reg_ialu);
 7101 %}
 7102 
 7103 instruct cmpLTMask_reg_imm( iRegI dst, iRegI p, aimmI q, flagsReg ccr ) %{
 7104   match(Set dst (CmpLTMask p q));
 7105   effect( KILL ccr );
 7106   ins_cost(DEFAULT_COST*3);
 7107   format %{ "CMP    $p,$q\n\t"
 7108             "MOV    $dst, #0\n\t"
 7109             "MOV.lt $dst, #-1" %}
 7110   ins_encode %{
 7111     __ cmp($p$$Register, $q$$constant);
 7112     __ mov($dst$$Register, 0);
 7113     __ mvn($dst$$Register, 0, lt);
 7114   %}
 7115   ins_pipe(ialu_reg_reg_ialu);
 7116 %}
 7117 
 7118 instruct cadd_cmpLTMask3( iRegI p, iRegI q, iRegI y, iRegI z, flagsReg ccr ) %{
 7119   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
 7120   effect( KILL ccr );
 7121   ins_cost(DEFAULT_COST*2);
 7122   format %{ "CMP    $p,$q\n\t"
 7123             "ADD.lt $z,$y,$z" %}
 7124   ins_encode %{
 7125     __ cmp($p$$Register, $q$$Register);
 7126     __ add($z$$Register, $y$$Register, $z$$Register, lt);
 7127   %}
 7128   ins_pipe( cadd_cmpltmask );
 7129 %}
 7130 
 7131 // FIXME: remove unused "dst"
 7132 instruct cadd_cmpLTMask4( iRegI dst, iRegI p, aimmI q, iRegI y, iRegI z, flagsReg ccr ) %{
 7133   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
 7134   effect( KILL ccr );
 7135   ins_cost(DEFAULT_COST*2);
 7136   format %{ "CMP    $p,$q\n\t"
 7137             "ADD.lt $z,$y,$z" %}
 7138   ins_encode %{
 7139     __ cmp($p$$Register, $q$$constant);
 7140     __ add($z$$Register, $y$$Register, $z$$Register, lt);
 7141   %}
 7142   ins_pipe( cadd_cmpltmask );
 7143 %}
 7144 
 7145 instruct cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, flagsReg ccr ) %{
 7146   match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
 7147   effect( KILL ccr );
 7148   ins_cost(DEFAULT_COST*2);
 7149   format %{ "SUBS   $p,$p,$q\n\t"
 7150             "ADD.lt $p,$y,$p" %}
 7151   ins_encode %{
 7152     __ subs($p$$Register, $p$$Register, $q$$Register);
 7153     __ add($p$$Register, $y$$Register, $p$$Register, lt);
 7154   %}
 7155   ins_pipe( cadd_cmpltmask );
 7156 %}
 7157 
 7158 //----------Arithmetic Conversion Instructions---------------------------------
 7159 // The conversions operations are all Alpha sorted.  Please keep it that way!
 7160 
 7161 instruct convD2F_reg(regF dst, regD src) %{
 7162   match(Set dst (ConvD2F src));
 7163   size(4);
 7164   format %{ "FCVTSD  $dst,$src" %}
 7165   ins_encode %{
 7166     __ convert_d2f($dst$$FloatRegister, $src$$FloatRegister);
 7167   %}
 7168   ins_pipe(fcvtD2F);
 7169 %}
 7170 
 7171 // Convert a double to an int in a float register.
 7172 // If the double is a NAN, stuff a zero in instead.
 7173 
 7174 instruct convD2I_reg_reg(iRegI dst, regD src, regF tmp) %{
 7175   match(Set dst (ConvD2I src));
 7176   effect( TEMP tmp );
 7177   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
 7178   format %{ "FTOSIZD  $tmp,$src\n\t"
 7179             "FMRS     $dst, $tmp" %}
 7180   ins_encode %{
 7181     __ ftosizd($tmp$$FloatRegister, $src$$FloatRegister);
 7182     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 7183   %}
 7184   ins_pipe(fcvtD2I);
 7185 %}
 7186 
 7187 // Convert a double to a long in a double register.
 7188 // If the double is a NAN, stuff a zero in instead.
 7189 
 7190 // Double to Long conversion
 7191 instruct convD2L_reg(R0R1RegL dst, regD src) %{
 7192   match(Set dst (ConvD2L src));
 7193   effect(CALL);
 7194   ins_cost(MEMORY_REF_COST); // FIXME
 7195   format %{ "convD2L    $dst,$src\t ! call to SharedRuntime::d2l" %}
 7196   ins_encode %{
 7197 #ifndef __ABI_HARD__
 7198     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
 7199 #else
 7200     if ($src$$FloatRegister != D0) {
 7201       __ mov_double(D0, $src$$FloatRegister);
 7202     }
 7203 #endif
 7204     address target = CAST_FROM_FN_PTR(address, SharedRuntime::d2l);
 7205     __ call(target, relocInfo::runtime_call_type);
 7206   %}
 7207   ins_pipe(fcvtD2L);
 7208 %}
 7209 
 7210 instruct convF2D_reg(regD dst, regF src) %{
 7211   match(Set dst (ConvF2D src));
 7212   size(4);
 7213   format %{ "FCVTDS  $dst,$src" %}
 7214   ins_encode %{
 7215     __ convert_f2d($dst$$FloatRegister, $src$$FloatRegister);
 7216   %}
 7217   ins_pipe(fcvtF2D);
 7218 %}
 7219 
 7220 instruct convF2I_reg_reg(iRegI dst, regF src, regF tmp) %{
 7221   match(Set dst (ConvF2I src));
 7222   effect( TEMP tmp );
 7223   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
 7224   size(8);
 7225   format %{ "FTOSIZS  $tmp,$src\n\t"
 7226             "FMRS     $dst, $tmp" %}
 7227   ins_encode %{
 7228     __ ftosizs($tmp$$FloatRegister, $src$$FloatRegister);
 7229     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 7230   %}
 7231   ins_pipe(fcvtF2I);
 7232 %}
 7233 
 7234 // Float to Long conversion
 7235 instruct convF2L_reg(R0R1RegL dst, regF src, R0RegI arg1) %{
 7236   match(Set dst (ConvF2L src));
 7237   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
 7238   effect(CALL);
 7239   format %{ "convF2L  $dst,$src\t! call to SharedRuntime::f2l" %}
 7240   ins_encode %{
 7241 #ifndef __ABI_HARD__
 7242     __ fmrs($arg1$$Register, $src$$FloatRegister);
 7243 #else
 7244     if($src$$FloatRegister != S0) {
 7245       __ mov_float(S0, $src$$FloatRegister);
 7246     }
 7247 #endif
 7248     address target = CAST_FROM_FN_PTR(address, SharedRuntime::f2l);
 7249     __ call(target, relocInfo::runtime_call_type);
 7250   %}
 7251   ins_pipe(fcvtF2L);
 7252 %}
 7253 
 7254 instruct convI2D_reg_reg(iRegI src, regD_low dst) %{
 7255   match(Set dst (ConvI2D src));
 7256   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
 7257   size(8);
 7258   format %{ "FMSR     $dst,$src \n\t"
 7259             "FSITOD   $dst $dst"%}
 7260   ins_encode %{
 7261       __ fmsr($dst$$FloatRegister, $src$$Register);
 7262       __ fsitod($dst$$FloatRegister, $dst$$FloatRegister);
 7263   %}
 7264   ins_pipe(fcvtI2D);
 7265 %}
 7266 
 7267 instruct convI2F_reg_reg( regF dst, iRegI src ) %{
 7268   match(Set dst (ConvI2F src));
 7269   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
 7270   size(8);
 7271   format %{ "FMSR     $dst,$src \n\t"
 7272             "FSITOS   $dst, $dst"%}
 7273   ins_encode %{
 7274       __ fmsr($dst$$FloatRegister, $src$$Register);
 7275       __ fsitos($dst$$FloatRegister, $dst$$FloatRegister);
 7276   %}
 7277   ins_pipe(fcvtI2F);
 7278 %}
 7279 
 7280 instruct convI2L_reg(iRegL dst, iRegI src) %{
 7281   match(Set dst (ConvI2L src));
 7282   size(8);
 7283   format %{ "MOV    $dst.lo, $src \n\t"
 7284             "ASR    $dst.hi,$src,31\t! int->long" %}
 7285   ins_encode %{
 7286     __ mov($dst$$Register, $src$$Register);
 7287     __ mov($dst$$Register->successor(), AsmOperand($src$$Register, asr, 31));
 7288   %}
 7289   ins_pipe(ialu_reg_reg);
 7290 %}
 7291 
 7292 // Zero-extend convert int to long
 7293 instruct convI2L_reg_zex(iRegL dst, iRegI src, immL_32bits mask ) %{
 7294   match(Set dst (AndL (ConvI2L src) mask) );
 7295   size(8);
 7296   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend int to long\n\t"
 7297             "MOV    $dst.hi, 0"%}
 7298   ins_encode %{
 7299     __ mov($dst$$Register, $src$$Register);
 7300     __ mov($dst$$Register->successor(), 0);
 7301   %}
 7302   ins_pipe(ialu_reg_reg);
 7303 %}
 7304 
 7305 // Zero-extend long
 7306 instruct zerox_long(iRegL dst, iRegL src, immL_32bits mask ) %{
 7307   match(Set dst (AndL src mask) );
 7308   size(8);
 7309   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend long\n\t"
 7310             "MOV    $dst.hi, 0"%}
 7311   ins_encode %{
 7312     __ mov($dst$$Register, $src$$Register);
 7313     __ mov($dst$$Register->successor(), 0);
 7314   %}
 7315   ins_pipe(ialu_reg_reg);
 7316 %}
 7317 
 7318 instruct MoveF2I_reg_reg(iRegI dst, regF src) %{
 7319   match(Set dst (MoveF2I src));
 7320   effect(DEF dst, USE src);
 7321   ins_cost(MEMORY_REF_COST); // FIXME
 7322 
 7323   size(4);
 7324   format %{ "FMRS   $dst,$src\t! MoveF2I" %}
 7325   ins_encode %{
 7326     __ fmrs($dst$$Register, $src$$FloatRegister);
 7327   %}
 7328   ins_pipe(iload_mem); // FIXME
 7329 %}
 7330 
 7331 instruct MoveI2F_reg_reg(regF dst, iRegI src) %{
 7332   match(Set dst (MoveI2F src));
 7333   ins_cost(MEMORY_REF_COST); // FIXME
 7334 
 7335   size(4);
 7336   format %{ "FMSR   $dst,$src\t! MoveI2F" %}
 7337   ins_encode %{
 7338     __ fmsr($dst$$FloatRegister, $src$$Register);
 7339   %}
 7340   ins_pipe(iload_mem); // FIXME
 7341 %}
 7342 
 7343 instruct MoveD2L_reg_reg(iRegL dst, regD src) %{
 7344   match(Set dst (MoveD2L src));
 7345   effect(DEF dst, USE src);
 7346   ins_cost(MEMORY_REF_COST); // FIXME
 7347 
 7348   size(4);
 7349   format %{ "FMRRD    $dst,$src\t! MoveD2L" %}
 7350   ins_encode %{
 7351     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
 7352   %}
 7353   ins_pipe(iload_mem); // FIXME
 7354 %}
 7355 
 7356 instruct MoveL2D_reg_reg(regD dst, iRegL src) %{
 7357   match(Set dst (MoveL2D src));
 7358   effect(DEF dst, USE src);
 7359   ins_cost(MEMORY_REF_COST); // FIXME
 7360 
 7361   size(4);
 7362   format %{ "FMDRR   $dst,$src\t! MoveL2D" %}
 7363   ins_encode %{
 7364     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
 7365   %}
 7366   ins_pipe(ialu_reg_reg); // FIXME
 7367 %}
 7368 
 7369 //-----------
 7370 // Long to Double conversion
 7371 
 7372 // Magic constant, 0x43300000
 7373 instruct loadConI_x43300000(iRegI dst) %{
 7374   effect(DEF dst);
 7375   size(8);
 7376   format %{ "MOV_SLOW  $dst,0x43300000\t! 2^52" %}
 7377   ins_encode %{
 7378     __ mov_slow($dst$$Register, 0x43300000);
 7379   %}
 7380   ins_pipe(ialu_none);
 7381 %}
 7382 
 7383 // Magic constant, 0x41f00000
 7384 instruct loadConI_x41f00000(iRegI dst) %{
 7385   effect(DEF dst);
 7386   size(8);
 7387   format %{ "MOV_SLOW  $dst, 0x41f00000\t! 2^32" %}
 7388   ins_encode %{
 7389     __ mov_slow($dst$$Register, 0x41f00000);
 7390   %}
 7391   ins_pipe(ialu_none);
 7392 %}
 7393 
 7394 instruct loadConI_x0(iRegI dst) %{
 7395   effect(DEF dst);
 7396   size(4);
 7397   format %{ "MOV  $dst, 0x0\t! 0" %}
 7398   ins_encode %{
 7399     __ mov($dst$$Register, 0);
 7400   %}
 7401   ins_pipe(ialu_none);
 7402 %}
 7403 
 7404 // Construct a double from two float halves
 7405 instruct regDHi_regDLo_to_regD(regD_low dst, regD_low src1, regD_low src2) %{
 7406   effect(DEF dst, USE src1, USE src2);
 7407   size(8);
 7408   format %{ "FCPYS  $dst.hi,$src1.hi\n\t"
 7409             "FCPYS  $dst.lo,$src2.lo" %}
 7410   ins_encode %{
 7411     __ fcpys($dst$$FloatRegister->successor(), $src1$$FloatRegister->successor());
 7412     __ fcpys($dst$$FloatRegister, $src2$$FloatRegister);
 7413   %}
 7414   ins_pipe(faddD_reg_reg);
 7415 %}
 7416 
 7417 // Convert integer in high half of a double register (in the lower half of
 7418 // the double register file) to double
 7419 instruct convI2D_regDHi_regD(regD dst, regD_low src) %{
 7420   effect(DEF dst, USE src);
 7421   size(4);
 7422   format %{ "FSITOD  $dst,$src" %}
 7423   ins_encode %{
 7424     __ fsitod($dst$$FloatRegister, $src$$FloatRegister->successor());
 7425   %}
 7426   ins_pipe(fcvtLHi2D);
 7427 %}
 7428 
 7429 // Add float double precision
 7430 instruct addD_regD_regD(regD dst, regD src1, regD src2) %{
 7431   effect(DEF dst, USE src1, USE src2);
 7432   size(4);
 7433   format %{ "FADDD  $dst,$src1,$src2" %}
 7434   ins_encode %{
 7435     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 7436   %}
 7437   ins_pipe(faddD_reg_reg);
 7438 %}
 7439 
 7440 // Sub float double precision
 7441 instruct subD_regD_regD(regD dst, regD src1, regD src2) %{
 7442   effect(DEF dst, USE src1, USE src2);
 7443   size(4);
 7444   format %{ "FSUBD  $dst,$src1,$src2" %}
 7445   ins_encode %{
 7446     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 7447   %}
 7448   ins_pipe(faddD_reg_reg);
 7449 %}
 7450 
 7451 // Mul float double precision
 7452 instruct mulD_regD_regD(regD dst, regD src1, regD src2) %{
 7453   effect(DEF dst, USE src1, USE src2);
 7454   size(4);
 7455   format %{ "FMULD  $dst,$src1,$src2" %}
 7456   ins_encode %{
 7457     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 7458   %}
 7459   ins_pipe(fmulD_reg_reg);
 7460 %}
 7461 
 7462 instruct regL_to_regD(regD dst, iRegL src) %{
 7463   // No match rule to avoid chain rule match.
 7464   effect(DEF dst, USE src);
 7465   ins_cost(MEMORY_REF_COST);
 7466   size(4);
 7467   format %{ "FMDRR   $dst,$src\t! regL to regD" %}
 7468   ins_encode %{
 7469     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
 7470   %}
 7471   ins_pipe(ialu_reg_reg); // FIXME
 7472 %}
 7473 
 7474 instruct regI_regI_to_regD(regD dst, iRegI src1, iRegI src2) %{
 7475   // No match rule to avoid chain rule match.
 7476   effect(DEF dst, USE src1, USE src2);
 7477   ins_cost(MEMORY_REF_COST);
 7478   size(4);
 7479   format %{ "FMDRR   $dst,$src1,$src2\t! regI,regI to regD" %}
 7480   ins_encode %{
 7481     __ fmdrr($dst$$FloatRegister, $src1$$Register, $src2$$Register);
 7482   %}
 7483   ins_pipe(ialu_reg_reg); // FIXME
 7484 %}
 7485 
 7486 instruct convL2D_reg_slow_fxtof(regD dst, iRegL src) %{
 7487   match(Set dst (ConvL2D src));
 7488   ins_cost(DEFAULT_COST*8 + MEMORY_REF_COST*6); // FIXME
 7489 
 7490   expand %{
 7491     regD_low   tmpsrc;
 7492     iRegI      ix43300000;
 7493     iRegI      ix41f00000;
 7494     iRegI      ix0;
 7495     regD_low   dx43300000;
 7496     regD       dx41f00000;
 7497     regD       tmp1;
 7498     regD_low   tmp2;
 7499     regD       tmp3;
 7500     regD       tmp4;
 7501 
 7502     regL_to_regD(tmpsrc, src);
 7503 
 7504     loadConI_x43300000(ix43300000);
 7505     loadConI_x41f00000(ix41f00000);
 7506     loadConI_x0(ix0);
 7507 
 7508     regI_regI_to_regD(dx43300000, ix0, ix43300000);
 7509     regI_regI_to_regD(dx41f00000, ix0, ix41f00000);
 7510 
 7511     convI2D_regDHi_regD(tmp1, tmpsrc);
 7512     regDHi_regDLo_to_regD(tmp2, dx43300000, tmpsrc);
 7513     subD_regD_regD(tmp3, tmp2, dx43300000);
 7514     mulD_regD_regD(tmp4, tmp1, dx41f00000);
 7515     addD_regD_regD(dst, tmp3, tmp4);
 7516   %}
 7517 %}
 7518 
 7519 instruct convL2I_reg(iRegI dst, iRegL src) %{
 7520   match(Set dst (ConvL2I src));
 7521   size(4);
 7522   format %{ "MOV    $dst,$src.lo\t! long->int" %}
 7523   ins_encode %{
 7524     __ mov($dst$$Register, $src$$Register);
 7525   %}
 7526   ins_pipe(ialu_move_reg_I_to_L);
 7527 %}
 7528 
 7529 // Register Shift Right Immediate
 7530 instruct shrL_reg_imm6_L2I(iRegI dst, iRegL src, immI_32_63 cnt) %{
 7531   match(Set dst (ConvL2I (RShiftL src cnt)));
 7532   size(4);
 7533   format %{ "ASR    $dst,$src.hi,($cnt - 32)\t! long->int or mov if $cnt==32" %}
 7534   ins_encode %{
 7535     if ($cnt$$constant == 32) {
 7536       __ mov($dst$$Register, $src$$Register->successor());
 7537     } else {
 7538       __ mov($dst$$Register, AsmOperand($src$$Register->successor(), asr, $cnt$$constant - 32));
 7539     }
 7540   %}
 7541   ins_pipe(ialu_reg_imm);
 7542 %}
 7543 
 7544 
 7545 //----------Control Flow Instructions------------------------------------------
 7546 // Compare Instructions
 7547 // Compare Integers
 7548 instruct compI_iReg(flagsReg icc, iRegI op1, iRegI op2) %{
 7549   match(Set icc (CmpI op1 op2));
 7550   effect( DEF icc, USE op1, USE op2 );
 7551 
 7552   size(4);
 7553   format %{ "cmp_32 $op1,$op2\t! int" %}
 7554   ins_encode %{
 7555     __ cmp_32($op1$$Register, $op2$$Register);
 7556   %}
 7557   ins_pipe(ialu_cconly_reg_reg);
 7558 %}
 7559 
 7560 #ifdef _LP64
 7561 // Compare compressed pointers
 7562 instruct compN_reg2(flagsRegU icc, iRegN op1, iRegN op2) %{
 7563   match(Set icc (CmpN op1 op2));
 7564   effect( DEF icc, USE op1, USE op2 );
 7565 
 7566   size(4);
 7567   format %{ "cmp_32 $op1,$op2\t! int" %}
 7568   ins_encode %{
 7569     __ cmp_32($op1$$Register, $op2$$Register);
 7570   %}
 7571   ins_pipe(ialu_cconly_reg_reg);
 7572 %}
 7573 #endif
 7574 
 7575 instruct compU_iReg(flagsRegU icc, iRegI op1, iRegI op2) %{
 7576   match(Set icc (CmpU op1 op2));
 7577 
 7578   size(4);
 7579   format %{ "cmp_32 $op1,$op2\t! unsigned int" %}
 7580   ins_encode %{
 7581     __ cmp_32($op1$$Register, $op2$$Register);
 7582   %}
 7583   ins_pipe(ialu_cconly_reg_reg);
 7584 %}
 7585 
 7586 instruct compI_iReg_immneg(flagsReg icc, iRegI op1, aimmIneg op2) %{
 7587   match(Set icc (CmpI op1 op2));
 7588   effect( DEF icc, USE op1 );
 7589 
 7590   size(4);
 7591   format %{ "cmn_32 $op1,-$op2\t! int" %}
 7592   ins_encode %{
 7593     __ cmn_32($op1$$Register, -$op2$$constant);
 7594   %}
 7595   ins_pipe(ialu_cconly_reg_imm);
 7596 %}
 7597 
 7598 instruct compI_iReg_imm(flagsReg icc, iRegI op1, aimmI op2) %{
 7599   match(Set icc (CmpI op1 op2));
 7600   effect( DEF icc, USE op1 );
 7601 
 7602   size(4);
 7603   format %{ "cmp_32 $op1,$op2\t! int" %}
 7604   ins_encode %{
 7605     __ cmp_32($op1$$Register, $op2$$constant);
 7606   %}
 7607   ins_pipe(ialu_cconly_reg_imm);
 7608 %}
 7609 
 7610 instruct testI_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immI0 zero ) %{
 7611   match(Set icc (CmpI (AndI op1 op2) zero));
 7612   size(4);
 7613   format %{ "tst_32 $op2,$op1" %}
 7614 
 7615   ins_encode %{
 7616     __ tst_32($op1$$Register, $op2$$Register);
 7617   %}
 7618   ins_pipe(ialu_cconly_reg_reg_zero);
 7619 %}
 7620 
 7621 instruct testshlI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
 7622   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
 7623   size(4);
 7624   format %{ "TST   $op2,$op1<<$op3" %}
 7625 
 7626   ins_encode %{
 7627     __ tst($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$Register));
 7628   %}
 7629   ins_pipe(ialu_cconly_reg_reg_zero);
 7630 %}
 7631 
 7632 instruct testshlI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
 7633   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
 7634   size(4);
 7635   format %{ "tst_32 $op2,$op1<<$op3" %}
 7636 
 7637   ins_encode %{
 7638     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$constant));
 7639   %}
 7640   ins_pipe(ialu_cconly_reg_reg_zero);
 7641 %}
 7642 
 7643 instruct testsarI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
 7644   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
 7645   size(4);
 7646   format %{ "TST   $op2,$op1<<$op3" %}
 7647 
 7648   ins_encode %{
 7649     __ tst($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$Register));
 7650   %}
 7651   ins_pipe(ialu_cconly_reg_reg_zero);
 7652 %}
 7653 
 7654 instruct testsarI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
 7655   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
 7656   size(4);
 7657   format %{ "tst_32 $op2,$op1<<$op3" %}
 7658 
 7659   ins_encode %{
 7660     __ tst_32($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$constant));
 7661   %}
 7662   ins_pipe(ialu_cconly_reg_reg_zero);
 7663 %}
 7664 
 7665 instruct testshrI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
 7666   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
 7667   size(4);
 7668   format %{ "TST   $op2,$op1<<$op3" %}
 7669 
 7670   ins_encode %{
 7671     __ tst($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$Register));
 7672   %}
 7673   ins_pipe(ialu_cconly_reg_reg_zero);
 7674 %}
 7675 
 7676 instruct testshrI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
 7677   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
 7678   size(4);
 7679   format %{ "tst_32 $op2,$op1<<$op3" %}
 7680 
 7681   ins_encode %{
 7682     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$constant));
 7683   %}
 7684   ins_pipe(ialu_cconly_reg_reg_zero);
 7685 %}
 7686 
 7687 instruct testI_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, limmI op2, immI0 zero ) %{
 7688   match(Set icc (CmpI (AndI op1 op2) zero));
 7689   size(4);
 7690   format %{ "tst_32 $op2,$op1" %}
 7691 
 7692   ins_encode %{
 7693     __ tst_32($op1$$Register, $op2$$constant);
 7694   %}
 7695   ins_pipe(ialu_cconly_reg_imm_zero);
 7696 %}
 7697 
 7698 instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7699   match(Set xcc (CmpL op1 op2));
 7700   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
 7701 
 7702   size(8);
 7703   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! long\n\t"
 7704             "SBCS    $tmp,$op1.hi,$op2.hi" %}
 7705   ins_encode %{
 7706     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
 7707     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
 7708   %}
 7709   ins_pipe(ialu_cconly_reg_reg);
 7710 %}
 7711 
 7712 instruct compUL_reg_reg_LTGE(flagsRegUL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7713   match(Set xcc (CmpUL op1 op2));
 7714   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
 7715 
 7716   size(8);
 7717   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! unsigned long\n\t"
 7718             "SBCS    $tmp,$op1.hi,$op2.hi" %}
 7719   ins_encode %{
 7720     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
 7721     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
 7722   %}
 7723   ins_pipe(ialu_cconly_reg_reg);
 7724 %}
 7725 
 7726 instruct compL_reg_reg_EQNE(flagsRegL_EQNE xcc, iRegL op1, iRegL op2) %{
 7727   match(Set xcc (CmpL op1 op2));
 7728   effect( DEF xcc, USE op1, USE op2 );
 7729 
 7730   size(8);
 7731   format %{ "TEQ    $op1.hi,$op2.hi\t\t! long\n\t"
 7732             "TEQ.eq $op1.lo,$op2.lo" %}
 7733   ins_encode %{
 7734     __ teq($op1$$Register->successor(), $op2$$Register->successor());
 7735     __ teq($op1$$Register, $op2$$Register, eq);
 7736   %}
 7737   ins_pipe(ialu_cconly_reg_reg);
 7738 %}
 7739 
 7740 instruct compL_reg_reg_LEGT(flagsRegL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7741   match(Set xcc (CmpL op1 op2));
 7742   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
 7743 
 7744   size(8);
 7745   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! long\n\t"
 7746             "SBCS    $tmp,$op2.hi,$op1.hi" %}
 7747   ins_encode %{
 7748     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
 7749     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
 7750   %}
 7751   ins_pipe(ialu_cconly_reg_reg);
 7752 %}
 7753 
 7754 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7755 // (hi($con$$constant), lo($con$$constant)) becomes
 7756 instruct compL_reg_con_LTGE(flagsRegL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7757   match(Set xcc (CmpL op1 con));
 7758   effect( DEF xcc, USE op1, USE con, TEMP tmp );
 7759 
 7760   size(8);
 7761   format %{ "SUBS    $tmp,$op1.low,$con\t\t! long\n\t"
 7762             "SBCS    $tmp,$op1.hi,0" %}
 7763   ins_encode %{
 7764     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
 7765     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7766   %}
 7767 
 7768   ins_pipe(ialu_cconly_reg_reg);
 7769 %}
 7770 
 7771 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7772 // (hi($con$$constant), lo($con$$constant)) becomes
 7773 instruct compL_reg_con_EQNE(flagsRegL_EQNE xcc, iRegL op1, immLlowRot con) %{
 7774   match(Set xcc (CmpL op1 con));
 7775   effect( DEF xcc, USE op1, USE con );
 7776 
 7777   size(8);
 7778   format %{ "TEQ    $op1.hi,0\t\t! long\n\t"
 7779             "TEQ.eq $op1.lo,$con" %}
 7780   ins_encode %{
 7781     __ teq($op1$$Register->successor(), 0);
 7782     __ teq($op1$$Register, $con$$constant, eq);
 7783   %}
 7784 
 7785   ins_pipe(ialu_cconly_reg_reg);
 7786 %}
 7787 
 7788 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7789 // (hi($con$$constant), lo($con$$constant)) becomes
 7790 instruct compL_reg_con_LEGT(flagsRegL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7791   match(Set xcc (CmpL op1 con));
 7792   effect( DEF xcc, USE op1, USE con, TEMP tmp );
 7793 
 7794   size(8);
 7795   format %{ "RSBS    $tmp,$op1.low,$con\t\t! long\n\t"
 7796             "RSCS    $tmp,$op1.hi,0" %}
 7797   ins_encode %{
 7798     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
 7799     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7800   %}
 7801 
 7802   ins_pipe(ialu_cconly_reg_reg);
 7803 %}
 7804 
 7805 instruct compUL_reg_reg_EQNE(flagsRegUL_EQNE xcc, iRegL op1, iRegL op2) %{
 7806   match(Set xcc (CmpUL op1 op2));
 7807   effect(DEF xcc, USE op1, USE op2);
 7808 
 7809   size(8);
 7810   format %{ "TEQ    $op1.hi,$op2.hi\t\t! unsigned long\n\t"
 7811             "TEQ.eq $op1.lo,$op2.lo" %}
 7812   ins_encode %{
 7813     __ teq($op1$$Register->successor(), $op2$$Register->successor());
 7814     __ teq($op1$$Register, $op2$$Register, eq);
 7815   %}
 7816   ins_pipe(ialu_cconly_reg_reg);
 7817 %}
 7818 
 7819 instruct compUL_reg_reg_LEGT(flagsRegUL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7820   match(Set xcc (CmpUL op1 op2));
 7821   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
 7822 
 7823   size(8);
 7824   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! unsigned long\n\t"
 7825             "SBCS    $tmp,$op2.hi,$op1.hi" %}
 7826   ins_encode %{
 7827     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
 7828     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
 7829   %}
 7830   ins_pipe(ialu_cconly_reg_reg);
 7831 %}
 7832 
 7833 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7834 // (hi($con$$constant), lo($con$$constant)) becomes
 7835 instruct compUL_reg_con_LTGE(flagsRegUL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7836   match(Set xcc (CmpUL op1 con));
 7837   effect(DEF xcc, USE op1, USE con, TEMP tmp);
 7838 
 7839   size(8);
 7840   format %{ "SUBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
 7841             "SBCS    $tmp,$op1.hi,0" %}
 7842   ins_encode %{
 7843     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
 7844     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7845   %}
 7846 
 7847   ins_pipe(ialu_cconly_reg_reg);
 7848 %}
 7849 
 7850 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7851 // (hi($con$$constant), lo($con$$constant)) becomes
 7852 instruct compUL_reg_con_EQNE(flagsRegUL_EQNE xcc, iRegL op1, immLlowRot con) %{
 7853   match(Set xcc (CmpUL op1 con));
 7854   effect(DEF xcc, USE op1, USE con);
 7855 
 7856   size(8);
 7857   format %{ "TEQ    $op1.hi,0\t\t! unsigned long\n\t"
 7858             "TEQ.eq $op1.lo,$con" %}
 7859   ins_encode %{
 7860     __ teq($op1$$Register->successor(), 0);
 7861     __ teq($op1$$Register, $con$$constant, eq);
 7862   %}
 7863 
 7864   ins_pipe(ialu_cconly_reg_reg);
 7865 %}
 7866 
 7867 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7868 // (hi($con$$constant), lo($con$$constant)) becomes
 7869 instruct compUL_reg_con_LEGT(flagsRegUL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7870   match(Set xcc (CmpUL op1 con));
 7871   effect(DEF xcc, USE op1, USE con, TEMP tmp);
 7872 
 7873   size(8);
 7874   format %{ "RSBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
 7875             "RSCS    $tmp,$op1.hi,0" %}
 7876   ins_encode %{
 7877     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
 7878     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7879   %}
 7880 
 7881   ins_pipe(ialu_cconly_reg_reg);
 7882 %}
 7883 
 7884 /* instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ */
 7885 /*   match(Set xcc (CmpL (AndL op1 op2) zero)); */
 7886 /*   ins_encode %{ */
 7887 /*     __ stop("testL_reg_reg unimplemented"); */
 7888 /*   %} */
 7889 /*   ins_pipe(ialu_cconly_reg_reg); */
 7890 /* %} */
 7891 
 7892 /* // useful for checking the alignment of a pointer: */
 7893 /* instruct testL_reg_con(flagsRegL xcc, iRegL op1, immLlowRot con, immL0 zero) %{ */
 7894 /*   match(Set xcc (CmpL (AndL op1 con) zero)); */
 7895 /*   ins_encode %{ */
 7896 /*     __ stop("testL_reg_con unimplemented"); */
 7897 /*   %} */
 7898 /*   ins_pipe(ialu_cconly_reg_reg); */
 7899 /* %} */
 7900 
 7901 instruct compU_iReg_imm(flagsRegU icc, iRegI op1, aimmU31 op2 ) %{
 7902   match(Set icc (CmpU op1 op2));
 7903 
 7904   size(4);
 7905   format %{ "cmp_32 $op1,$op2\t! unsigned" %}
 7906   ins_encode %{
 7907     __ cmp_32($op1$$Register, $op2$$constant);
 7908   %}
 7909   ins_pipe(ialu_cconly_reg_imm);
 7910 %}
 7911 
 7912 // Compare Pointers
 7913 instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{
 7914   match(Set pcc (CmpP op1 op2));
 7915 
 7916   size(4);
 7917   format %{ "CMP    $op1,$op2\t! ptr" %}
 7918   ins_encode %{
 7919     __ cmp($op1$$Register, $op2$$Register);
 7920   %}
 7921   ins_pipe(ialu_cconly_reg_reg);
 7922 %}
 7923 
 7924 instruct compP_iRegP_imm(flagsRegP pcc, iRegP op1, aimmP op2 ) %{
 7925   match(Set pcc (CmpP op1 op2));
 7926 
 7927   size(4);
 7928   format %{ "CMP    $op1,$op2\t! ptr" %}
 7929   ins_encode %{
 7930     assert($op2$$constant == 0 || _opnds[2]->constant_reloc() == relocInfo::none, "reloc in cmp?");
 7931     __ cmp($op1$$Register, $op2$$constant);
 7932   %}
 7933   ins_pipe(ialu_cconly_reg_imm);
 7934 %}
 7935 
 7936 //----------Max and Min--------------------------------------------------------
 7937 // Min Instructions
 7938 // Conditional move for min
 7939 instruct cmovI_reg_lt( iRegI op2, iRegI op1, flagsReg icc ) %{
 7940   effect( USE_DEF op2, USE op1, USE icc );
 7941 
 7942   size(4);
 7943   format %{ "MOV.lt  $op2,$op1\t! min" %}
 7944   ins_encode %{
 7945     __ mov($op2$$Register, $op1$$Register, lt);
 7946   %}
 7947   ins_pipe(ialu_reg_flags);
 7948 %}
 7949 
 7950 // Min Register with Register.
 7951 instruct minI_eReg(iRegI op1, iRegI op2) %{
 7952   match(Set op2 (MinI op1 op2));
 7953   ins_cost(DEFAULT_COST*2);
 7954   expand %{
 7955     flagsReg icc;
 7956     compI_iReg(icc,op1,op2);
 7957     cmovI_reg_lt(op2,op1,icc);
 7958   %}
 7959 %}
 7960 
 7961 // Max Instructions
 7962 // Conditional move for max
 7963 instruct cmovI_reg_gt( iRegI op2, iRegI op1, flagsReg icc ) %{
 7964   effect( USE_DEF op2, USE op1, USE icc );
 7965   format %{ "MOV.gt  $op2,$op1\t! max" %}
 7966   ins_encode %{
 7967     __ mov($op2$$Register, $op1$$Register, gt);
 7968   %}
 7969   ins_pipe(ialu_reg_flags);
 7970 %}
 7971 
 7972 // Max Register with Register
 7973 instruct maxI_eReg(iRegI op1, iRegI op2) %{
 7974   match(Set op2 (MaxI op1 op2));
 7975   ins_cost(DEFAULT_COST*2);
 7976   expand %{
 7977     flagsReg icc;
 7978     compI_iReg(icc,op1,op2);
 7979     cmovI_reg_gt(op2,op1,icc);
 7980   %}
 7981 %}
 7982 
 7983 
 7984 //----------Float Compares----------------------------------------------------
 7985 // Compare floating, generate condition code
 7986 instruct cmpF_cc(flagsRegF fcc, flagsReg icc, regF src1, regF src2) %{
 7987   match(Set icc (CmpF src1 src2));
 7988   effect(KILL fcc);
 7989 
 7990   size(8);
 7991   format %{ "FCMPs  $src1,$src2\n\t"
 7992             "FMSTAT" %}
 7993   ins_encode %{
 7994     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
 7995     __ fmstat();
 7996   %}
 7997   ins_pipe(faddF_fcc_reg_reg_zero);
 7998 %}
 7999 
 8000 instruct cmpF0_cc(flagsRegF fcc, flagsReg icc, regF src1, immF0 src2) %{
 8001   match(Set icc (CmpF src1 src2));
 8002   effect(KILL fcc);
 8003 
 8004   size(8);
 8005   format %{ "FCMPs  $src1,$src2\n\t"
 8006             "FMSTAT" %}
 8007   ins_encode %{
 8008     __ fcmpzs($src1$$FloatRegister);
 8009     __ fmstat();
 8010   %}
 8011   ins_pipe(faddF_fcc_reg_reg_zero);
 8012 %}
 8013 
 8014 instruct cmpD_cc(flagsRegF fcc, flagsReg icc, regD src1, regD src2) %{
 8015   match(Set icc (CmpD src1 src2));
 8016   effect(KILL fcc);
 8017 
 8018   size(8);
 8019   format %{ "FCMPd  $src1,$src2 \n\t"
 8020             "FMSTAT" %}
 8021   ins_encode %{
 8022     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
 8023     __ fmstat();
 8024   %}
 8025   ins_pipe(faddD_fcc_reg_reg_zero);
 8026 %}
 8027 
 8028 instruct cmpD0_cc(flagsRegF fcc, flagsReg icc, regD src1, immD0 src2) %{
 8029   match(Set icc (CmpD src1 src2));
 8030   effect(KILL fcc);
 8031 
 8032   size(8);
 8033   format %{ "FCMPZd  $src1,$src2 \n\t"
 8034             "FMSTAT" %}
 8035   ins_encode %{
 8036     __ fcmpzd($src1$$FloatRegister);
 8037     __ fmstat();
 8038   %}
 8039   ins_pipe(faddD_fcc_reg_reg_zero);
 8040 %}
 8041 
 8042 // Compare floating, generate -1,0,1
 8043 instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsRegF fcc) %{
 8044   match(Set dst (CmpF3 src1 src2));
 8045   effect(KILL fcc);
 8046   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 8047   size(20);
 8048   // same number of instructions as code using conditional moves but
 8049   // doesn't kill integer condition register
 8050   format %{ "FCMPs  $dst,$src1,$src2 \n\t"
 8051             "VMRS   $dst, FPSCR \n\t"
 8052             "OR     $dst, $dst, 0x08000000 \n\t"
 8053             "EOR    $dst, $dst, $dst << 3 \n\t"
 8054             "MOV    $dst, $dst >> 30" %}
 8055   ins_encode %{
 8056     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
 8057     __ floating_cmp($dst$$Register);
 8058   %}
 8059   ins_pipe( floating_cmp );
 8060 %}
 8061 
 8062 instruct cmpF0_reg(iRegI dst, regF src1, immF0 src2, flagsRegF fcc) %{
 8063   match(Set dst (CmpF3 src1 src2));
 8064   effect(KILL fcc);
 8065   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 8066   size(20);
 8067   // same number of instructions as code using conditional moves but
 8068   // doesn't kill integer condition register
 8069   format %{ "FCMPZs $dst,$src1,$src2 \n\t"
 8070             "VMRS   $dst, FPSCR \n\t"
 8071             "OR     $dst, $dst, 0x08000000 \n\t"
 8072             "EOR    $dst, $dst, $dst << 3 \n\t"
 8073             "MOV    $dst, $dst >> 30" %}
 8074   ins_encode %{
 8075     __ fcmpzs($src1$$FloatRegister);
 8076     __ floating_cmp($dst$$Register);
 8077   %}
 8078   ins_pipe( floating_cmp );
 8079 %}
 8080 
 8081 instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsRegF fcc) %{
 8082   match(Set dst (CmpD3 src1 src2));
 8083   effect(KILL fcc);
 8084   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 8085   size(20);
 8086   // same number of instructions as code using conditional moves but
 8087   // doesn't kill integer condition register
 8088   format %{ "FCMPd  $dst,$src1,$src2 \n\t"
 8089             "VMRS   $dst, FPSCR \n\t"
 8090             "OR     $dst, $dst, 0x08000000 \n\t"
 8091             "EOR    $dst, $dst, $dst << 3 \n\t"
 8092             "MOV    $dst, $dst >> 30" %}
 8093   ins_encode %{
 8094     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
 8095     __ floating_cmp($dst$$Register);
 8096   %}
 8097   ins_pipe( floating_cmp );
 8098 %}
 8099 
 8100 instruct cmpD0_reg(iRegI dst, regD src1, immD0 src2, flagsRegF fcc) %{
 8101   match(Set dst (CmpD3 src1 src2));
 8102   effect(KILL fcc);
 8103   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 8104   size(20);
 8105   // same number of instructions as code using conditional moves but
 8106   // doesn't kill integer condition register
 8107   format %{ "FCMPZd $dst,$src1,$src2 \n\t"
 8108             "VMRS   $dst, FPSCR \n\t"
 8109             "OR     $dst, $dst, 0x08000000 \n\t"
 8110             "EOR    $dst, $dst, $dst << 3 \n\t"
 8111             "MOV    $dst, $dst >> 30" %}
 8112   ins_encode %{
 8113     __ fcmpzd($src1$$FloatRegister);
 8114     __ floating_cmp($dst$$Register);
 8115   %}
 8116   ins_pipe( floating_cmp );
 8117 %}
 8118 
 8119 //----------Branches---------------------------------------------------------
 8120 // Jump
 8121 // (compare 'operand indIndex' and 'instruct addP_reg_reg' above)
 8122 // FIXME
 8123 instruct jumpXtnd(iRegX switch_val, iRegP tmp) %{
 8124   match(Jump switch_val);
 8125   effect(TEMP tmp);
 8126   ins_cost(350);
 8127   format %{  "ADD    $tmp, $constanttablebase, $switch_val\n\t"
 8128              "LDR    $tmp,[$tmp + $constantoffset]\n\t"
 8129              "BX     $tmp" %}
 8130   size(20);
 8131   ins_encode %{
 8132     Register table_reg;
 8133     Register label_reg = $tmp$$Register;
 8134     if (constant_offset() == 0) {
 8135       table_reg = $constanttablebase;
 8136       __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
 8137     } else {
 8138       table_reg = $tmp$$Register;
 8139       int offset = $constantoffset;
 8140       if (is_memoryP(offset)) {
 8141         __ add(table_reg, $constanttablebase, $switch_val$$Register);
 8142         __ ldr(label_reg, Address(table_reg, offset));
 8143       } else {
 8144         __ mov_slow(table_reg, $constantoffset);
 8145         __ add(table_reg, $constanttablebase, table_reg);
 8146         __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
 8147       }
 8148     }
 8149     __ jump(label_reg); // ldr + b better than ldr to PC for branch predictor?
 8150     //    __ ldr(PC, Address($table$$Register, $switch_val$$Register));
 8151   %}
 8152   ins_pipe(ialu_reg_reg);
 8153 %}
 8154 
 8155 // // Direct Branch.
 8156 instruct branch(label labl) %{
 8157   match(Goto);
 8158   effect(USE labl);
 8159 
 8160   size(4);
 8161   ins_cost(BRANCH_COST);
 8162   format %{ "B     $labl" %}
 8163   ins_encode %{
 8164     __ b(*($labl$$label));
 8165   %}
 8166   ins_pipe(br);
 8167 %}
 8168 
 8169 // Conditional Direct Branch
 8170 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{
 8171   match(If cmp icc);
 8172   effect(USE labl);
 8173 
 8174   size(4);
 8175   ins_cost(BRANCH_COST);
 8176   format %{ "B$cmp   $icc,$labl" %}
 8177   ins_encode %{
 8178     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8179   %}
 8180   ins_pipe(br_cc);
 8181 %}
 8182 
 8183 #ifdef ARM
 8184 instruct branchCon_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, label labl) %{
 8185   match(If cmp icc);
 8186   effect(USE labl);
 8187   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);
 8188 
 8189   size(4);
 8190   ins_cost(BRANCH_COST);
 8191   format %{ "B$cmp   $icc,$labl" %}
 8192   ins_encode %{
 8193     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8194   %}
 8195   ins_pipe(br_cc);
 8196 %}
 8197 #endif
 8198 
 8199 
 8200 instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{
 8201   match(If cmp icc);
 8202   effect(USE labl);
 8203 
 8204   size(4);
 8205   ins_cost(BRANCH_COST);
 8206   format %{ "B$cmp  $icc,$labl" %}
 8207   ins_encode %{
 8208     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8209   %}
 8210   ins_pipe(br_cc);
 8211 %}
 8212 
 8213 instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{
 8214   match(If cmp pcc);
 8215   effect(USE labl);
 8216 
 8217   size(4);
 8218   ins_cost(BRANCH_COST);
 8219   format %{ "B$cmp  $pcc,$labl" %}
 8220   ins_encode %{
 8221     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8222   %}
 8223   ins_pipe(br_cc);
 8224 %}
 8225 
 8226 instruct branchConL_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, label labl) %{
 8227   match(If cmp xcc);
 8228   effect(USE labl);
 8229   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8230 
 8231   size(4);
 8232   ins_cost(BRANCH_COST);
 8233   format %{ "B$cmp  $xcc,$labl" %}
 8234   ins_encode %{
 8235     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8236   %}
 8237   ins_pipe(br_cc);
 8238 %}
 8239 
 8240 instruct branchConL_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, label labl) %{
 8241   match(If cmp xcc);
 8242   effect(USE labl);
 8243   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8244 
 8245   size(4);
 8246   ins_cost(BRANCH_COST);
 8247   format %{ "B$cmp  $xcc,$labl" %}
 8248   ins_encode %{
 8249     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8250   %}
 8251   ins_pipe(br_cc);
 8252 %}
 8253 
 8254 instruct branchConL_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, label labl) %{
 8255   match(If cmp xcc);
 8256   effect(USE labl);
 8257   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le );
 8258 
 8259   size(4);
 8260   ins_cost(BRANCH_COST);
 8261   format %{ "B$cmp  $xcc,$labl" %}
 8262   ins_encode %{
 8263     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8264   %}
 8265   ins_pipe(br_cc);
 8266 %}
 8267 
 8268 instruct branchConUL_LTGE(cmpOpUL cmp, flagsRegUL_LTGE xcc, label labl) %{
 8269   match(If cmp xcc);
 8270   effect(USE labl);
 8271   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8272 
 8273   size(4);
 8274   ins_cost(BRANCH_COST);
 8275   format %{ "B$cmp  $xcc,$labl" %}
 8276   ins_encode %{
 8277     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8278   %}
 8279   ins_pipe(br_cc);
 8280 %}
 8281 
 8282 instruct branchConUL_EQNE(cmpOpUL cmp, flagsRegUL_EQNE xcc, label labl) %{
 8283   match(If cmp xcc);
 8284   effect(USE labl);
 8285   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8286 
 8287   size(4);
 8288   ins_cost(BRANCH_COST);
 8289   format %{ "B$cmp  $xcc,$labl" %}
 8290   ins_encode %{
 8291     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8292   %}
 8293   ins_pipe(br_cc);
 8294 %}
 8295 
 8296 instruct branchConUL_LEGT(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, label labl) %{
 8297   match(If cmp xcc);
 8298   effect(USE labl);
 8299   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le);
 8300 
 8301   size(4);
 8302   ins_cost(BRANCH_COST);
 8303   format %{ "B$cmp  $xcc,$labl" %}
 8304   ins_encode %{
 8305     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8306   %}
 8307   ins_pipe(br_cc);
 8308 %}
 8309 
 8310 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
 8311   match(CountedLoopEnd cmp icc);
 8312   effect(USE labl);
 8313 
 8314   size(4);
 8315   ins_cost(BRANCH_COST);
 8316   format %{ "B$cmp   $icc,$labl\t! Loop end" %}
 8317   ins_encode %{
 8318     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8319   %}
 8320   ins_pipe(br_cc);
 8321 %}
 8322 
 8323 // instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{
 8324 //   match(CountedLoopEnd cmp icc);
 8325 //   ins_pipe(br_cc);
 8326 // %}
 8327 
 8328 // ============================================================================
 8329 // Long Compare
 8330 //
 8331 // Currently we hold longs in 2 registers.  Comparing such values efficiently
 8332 // is tricky.  The flavor of compare used depends on whether we are testing
 8333 // for LT, LE, or EQ.  For a simple LT test we can check just the sign bit.
 8334 // The GE test is the negated LT test.  The LE test can be had by commuting
 8335 // the operands (yielding a GE test) and then negating; negate again for the
 8336 // GT test.  The EQ test is done by ORcc'ing the high and low halves, and the
 8337 // NE test is negated from that.
 8338 
 8339 // Due to a shortcoming in the ADLC, it mixes up expressions like:
 8340 // (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)).  Note the
 8341 // difference between 'Y' and '0L'.  The tree-matches for the CmpI sections
 8342 // are collapsed internally in the ADLC's dfa-gen code.  The match for
 8343 // (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the
 8344 // foo match ends up with the wrong leaf.  One fix is to not match both
 8345 // reg-reg and reg-zero forms of long-compare.  This is unfortunate because
 8346 // both forms beat the trinary form of long-compare and both are very useful
 8347 // on Intel which has so few registers.
 8348 
 8349 // instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{
 8350 //   match(If cmp xcc);
 8351 //   ins_pipe(br_cc);
 8352 // %}
 8353 
 8354 // Manifest a CmpL3 result in an integer register.  Very painful.
 8355 // This is the test to avoid.
 8356 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
 8357   match(Set dst (CmpL3 src1 src2) );
 8358   effect( KILL ccr );
 8359   ins_cost(6*DEFAULT_COST); // FIXME
 8360   size(32);
 8361   format %{
 8362       "CMP    $src1.hi, $src2.hi\t\t! long\n"
 8363     "\tMOV.gt $dst, 1\n"
 8364     "\tmvn.lt $dst, 0\n"
 8365     "\tB.ne   done\n"
 8366     "\tSUBS   $dst, $src1.lo, $src2.lo\n"
 8367     "\tMOV.hi $dst, 1\n"
 8368     "\tmvn.lo $dst, 0\n"
 8369     "done:"     %}
 8370   ins_encode %{
 8371     Label done;
 8372     __ cmp($src1$$Register->successor(), $src2$$Register->successor());
 8373     __ mov($dst$$Register, 1, gt);
 8374     __ mvn($dst$$Register, 0, lt);
 8375     __ b(done, ne);
 8376     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
 8377     __ mov($dst$$Register, 1, hi);
 8378     __ mvn($dst$$Register, 0, lo);
 8379     __ bind(done);
 8380   %}
 8381   ins_pipe(cmpL_reg);
 8382 %}
 8383 
 8384 // Conditional move
 8385 instruct cmovLL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, iRegL src) %{
 8386   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8387   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8388 
 8389   ins_cost(150);
 8390   size(8);
 8391   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8392             "MOV$cmp  $dst,$src.hi" %}
 8393   ins_encode %{
 8394     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8395     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8396   %}
 8397   ins_pipe(ialu_reg);
 8398 %}
 8399 
 8400 instruct cmovLL_reg_LTGE_U(cmpOpL cmp, flagsRegUL_LTGE xcc, iRegL dst, iRegL src) %{
 8401   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8402   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8403 
 8404   ins_cost(150);
 8405   size(8);
 8406   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8407             "MOV$cmp  $dst,$src.hi" %}
 8408   ins_encode %{
 8409     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8410     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8411   %}
 8412   ins_pipe(ialu_reg);
 8413 %}
 8414 
 8415 instruct cmovLL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, iRegL src) %{
 8416   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8417   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8418 
 8419   ins_cost(150);
 8420   size(8);
 8421   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8422             "MOV$cmp  $dst,$src.hi" %}
 8423   ins_encode %{
 8424     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8425     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8426   %}
 8427   ins_pipe(ialu_reg);
 8428 %}
 8429 
 8430 instruct cmovLL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, iRegL src) %{
 8431   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8432   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8433 
 8434   ins_cost(150);
 8435   size(8);
 8436   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8437             "MOV$cmp  $dst,$src.hi" %}
 8438   ins_encode %{
 8439     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8440     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8441   %}
 8442   ins_pipe(ialu_reg);
 8443 %}
 8444 
 8445 instruct cmovLL_reg_LEGT_U(cmpOpL_commute cmp, flagsRegUL_LEGT xcc, iRegL dst, iRegL src) %{
 8446   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8447   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8448 
 8449   ins_cost(150);
 8450   size(8);
 8451   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8452             "MOV$cmp  $dst,$src.hi" %}
 8453   ins_encode %{
 8454     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8455     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8456   %}
 8457   ins_pipe(ialu_reg);
 8458 %}
 8459 
 8460 instruct cmovLL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, immL0 src) %{
 8461   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8462   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8463   ins_cost(140);
 8464   size(8);
 8465   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8466             "MOV$cmp  $dst,0" %}
 8467   ins_encode %{
 8468     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8469     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8470   %}
 8471   ins_pipe(ialu_imm);
 8472 %}
 8473 
 8474 instruct cmovLL_imm_LTGE_U(cmpOpL cmp, flagsRegUL_LTGE xcc, iRegL dst, immL0 src) %{
 8475   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8476   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8477   ins_cost(140);
 8478   size(8);
 8479   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8480             "MOV$cmp  $dst,0" %}
 8481   ins_encode %{
 8482     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8483     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8484   %}
 8485   ins_pipe(ialu_imm);
 8486 %}
 8487 
 8488 instruct cmovLL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, immL0 src) %{
 8489   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8490   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8491   ins_cost(140);
 8492   size(8);
 8493   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8494             "MOV$cmp  $dst,0" %}
 8495   ins_encode %{
 8496     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8497     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8498   %}
 8499   ins_pipe(ialu_imm);
 8500 %}
 8501 
 8502 instruct cmovLL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, immL0 src) %{
 8503   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8504   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8505   ins_cost(140);
 8506   size(8);
 8507   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8508             "MOV$cmp  $dst,0" %}
 8509   ins_encode %{
 8510     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8511     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8512   %}
 8513   ins_pipe(ialu_imm);
 8514 %}
 8515 
 8516 instruct cmovIL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, iRegI src) %{
 8517   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8518   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8519 
 8520   ins_cost(150);
 8521   size(4);
 8522   format %{ "MOV$cmp  $dst,$src" %}
 8523   ins_encode %{
 8524     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8525   %}
 8526   ins_pipe(ialu_reg);
 8527 %}
 8528 
 8529 instruct cmovIL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, iRegI src) %{
 8530   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8531   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8532 
 8533   ins_cost(150);
 8534   size(4);
 8535   format %{ "MOV$cmp  $dst,$src" %}
 8536   ins_encode %{
 8537     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8538   %}
 8539   ins_pipe(ialu_reg);
 8540 %}
 8541 
 8542 instruct cmovIL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, iRegI src) %{
 8543   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8544   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8545 
 8546   ins_cost(150);
 8547   size(4);
 8548   format %{ "MOV$cmp  $dst,$src" %}
 8549   ins_encode %{
 8550     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8551   %}
 8552   ins_pipe(ialu_reg);
 8553 %}
 8554 
 8555 instruct cmovIL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immI16 src) %{
 8556   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8557   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8558 
 8559   ins_cost(140);
 8560   format %{ "MOVW$cmp  $dst,$src" %}
 8561   ins_encode %{
 8562     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8563   %}
 8564   ins_pipe(ialu_imm);
 8565 %}
 8566 
 8567 instruct cmovIL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, immI16 src) %{
 8568   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8569   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8570 
 8571   ins_cost(140);
 8572   format %{ "MOVW$cmp  $dst,$src" %}
 8573   ins_encode %{
 8574     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8575   %}
 8576   ins_pipe(ialu_imm);
 8577 %}
 8578 
 8579 instruct cmovIL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immI16 src) %{
 8580   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8581   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8582 
 8583   ins_cost(140);
 8584   format %{ "MOVW$cmp  $dst,$src" %}
 8585   ins_encode %{
 8586     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8587   %}
 8588   ins_pipe(ialu_imm);
 8589 %}
 8590 
 8591 instruct cmovPL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, iRegP src) %{
 8592   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8593   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8594 
 8595   ins_cost(150);
 8596   size(4);
 8597   format %{ "MOV$cmp  $dst,$src" %}
 8598   ins_encode %{
 8599     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8600   %}
 8601   ins_pipe(ialu_reg);
 8602 %}
 8603 
 8604 instruct cmovPL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, iRegP src) %{
 8605   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8606   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8607 
 8608   ins_cost(150);
 8609   size(4);
 8610   format %{ "MOV$cmp  $dst,$src" %}
 8611   ins_encode %{
 8612     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8613   %}
 8614   ins_pipe(ialu_reg);
 8615 %}
 8616 
 8617 instruct cmovPL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, iRegP src) %{
 8618   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8619   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8620 
 8621   ins_cost(150);
 8622   size(4);
 8623   format %{ "MOV$cmp  $dst,$src" %}
 8624   ins_encode %{
 8625     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8626   %}
 8627   ins_pipe(ialu_reg);
 8628 %}
 8629 
 8630 instruct cmovPL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, immP0 src) %{
 8631   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8632   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8633 
 8634   ins_cost(140);
 8635   format %{ "MOVW$cmp  $dst,$src" %}
 8636   ins_encode %{
 8637     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8638   %}
 8639   ins_pipe(ialu_imm);
 8640 %}
 8641 
 8642 instruct cmovPL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, immP0 src) %{
 8643   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8644   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8645 
 8646   ins_cost(140);
 8647   format %{ "MOVW$cmp  $dst,$src" %}
 8648   ins_encode %{
 8649     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8650   %}
 8651   ins_pipe(ialu_imm);
 8652 %}
 8653 
 8654 instruct cmovPL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, immP0 src) %{
 8655   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8656   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8657 
 8658   ins_cost(140);
 8659   format %{ "MOVW$cmp  $dst,$src" %}
 8660   ins_encode %{
 8661     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8662   %}
 8663   ins_pipe(ialu_imm);
 8664 %}
 8665 
 8666 instruct cmovFL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regF dst, regF src) %{
 8667   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
 8668   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8669   ins_cost(150);
 8670   size(4);
 8671   format %{ "FCPYS$cmp $dst,$src" %}
 8672   ins_encode %{
 8673     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8674   %}
 8675   ins_pipe(int_conditional_float_move);
 8676 %}
 8677 
 8678 instruct cmovFL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regF dst, regF src) %{
 8679   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
 8680   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8681   ins_cost(150);
 8682   size(4);
 8683   format %{ "FCPYS$cmp $dst,$src" %}
 8684   ins_encode %{
 8685     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8686   %}
 8687   ins_pipe(int_conditional_float_move);
 8688 %}
 8689 
 8690 instruct cmovFL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regF dst, regF src) %{
 8691   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
 8692   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8693   ins_cost(150);
 8694   size(4);
 8695   format %{ "FCPYS$cmp $dst,$src" %}
 8696   ins_encode %{
 8697     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8698   %}
 8699   ins_pipe(int_conditional_float_move);
 8700 %}
 8701 
 8702 instruct cmovDL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regD dst, regD src) %{
 8703   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
 8704   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8705 
 8706   ins_cost(150);
 8707   size(4);
 8708   format %{ "FCPYD$cmp $dst,$src" %}
 8709   ins_encode %{
 8710     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8711   %}
 8712   ins_pipe(int_conditional_float_move);
 8713 %}
 8714 
 8715 instruct cmovDL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regD dst, regD src) %{
 8716   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
 8717   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8718 
 8719   ins_cost(150);
 8720   size(4);
 8721   format %{ "FCPYD$cmp $dst,$src" %}
 8722   ins_encode %{
 8723     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8724   %}
 8725   ins_pipe(int_conditional_float_move);
 8726 %}
 8727 
 8728 instruct cmovDL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regD dst, regD src) %{
 8729   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
 8730   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8731 
 8732   ins_cost(150);
 8733   size(4);
 8734   format %{ "FCPYD$cmp $dst,$src" %}
 8735   ins_encode %{
 8736     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8737   %}
 8738   ins_pipe(int_conditional_float_move);
 8739 %}
 8740 
 8741 // ============================================================================
 8742 // Safepoint Instruction
 8743 // rather than KILL R12, it would be better to use any reg as
 8744 // TEMP. Can't do that at this point because it crashes the compiler
 8745 instruct safePoint_poll(iRegP poll, R12RegI tmp, flagsReg icc) %{
 8746   match(SafePoint poll);
 8747   effect(USE poll, KILL tmp, KILL icc);
 8748 
 8749   size(4);
 8750   format %{ "LDR   $tmp,[$poll]\t! Safepoint: poll for GC" %}
 8751   ins_encode %{
 8752     __ relocate(relocInfo::poll_type);
 8753     __ ldr($tmp$$Register, Address($poll$$Register));
 8754   %}
 8755   ins_pipe(loadPollP);
 8756 %}
 8757 
 8758 
 8759 // ============================================================================
 8760 // Call Instructions
 8761 // Call Java Static Instruction
 8762 instruct CallStaticJavaDirect( method meth ) %{
 8763   match(CallStaticJava);
 8764   predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke());
 8765   effect(USE meth);
 8766 
 8767   ins_cost(CALL_COST);
 8768   format %{ "CALL,static ==> " %}
 8769   ins_encode( Java_Static_Call( meth ), call_epilog );
 8770   ins_pipe(simple_call);
 8771 %}
 8772 
 8773 // Call Java Static Instruction (method handle version)
 8774 instruct CallStaticJavaHandle( method meth ) %{
 8775   match(CallStaticJava);
 8776   predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke());
 8777   effect(USE meth);
 8778   // FP is saved by all callees (for interpreter stack correction).
 8779   // We use it here for a similar purpose, in {preserve,restore}_FP.
 8780 
 8781   ins_cost(CALL_COST);
 8782   format %{ "CALL,static/MethodHandle ==> " %}
 8783   ins_encode( preserve_SP, Java_Static_Call( meth ), restore_SP, call_epilog );
 8784   ins_pipe(simple_call);
 8785 %}
 8786 
 8787 // Call Java Dynamic Instruction
 8788 instruct CallDynamicJavaDirect( method meth ) %{
 8789   match(CallDynamicJava);
 8790   effect(USE meth);
 8791 
 8792   ins_cost(CALL_COST);
 8793   format %{ "MOV_OOP    (empty),R_R8\n\t"
 8794             "CALL,dynamic  ; NOP ==> " %}
 8795   ins_encode( Java_Dynamic_Call( meth ), call_epilog );
 8796   ins_pipe(call);
 8797 %}
 8798 
 8799 // Call Runtime Instruction
 8800 instruct CallRuntimeDirect(method meth) %{
 8801   match(CallRuntime);
 8802   effect(USE meth);
 8803   ins_cost(CALL_COST);
 8804   format %{ "CALL,runtime" %}
 8805   ins_encode( Java_To_Runtime( meth ),
 8806               call_epilog );
 8807   ins_pipe(simple_call);
 8808 %}
 8809 
 8810 // Call runtime without safepoint - same as CallRuntime
 8811 instruct CallLeafDirect(method meth) %{
 8812   match(CallLeaf);
 8813   effect(USE meth);
 8814   ins_cost(CALL_COST);
 8815   format %{ "CALL,runtime leaf" %}
 8816   // TODO: ned save_last_PC here?
 8817   ins_encode( Java_To_Runtime( meth ),
 8818               call_epilog );
 8819   ins_pipe(simple_call);
 8820 %}
 8821 
 8822 // Call runtime without safepoint - same as CallLeaf
 8823 instruct CallLeafNoFPDirect(method meth) %{
 8824   match(CallLeafNoFP);
 8825   effect(USE meth);
 8826   ins_cost(CALL_COST);
 8827   format %{ "CALL,runtime leaf nofp" %}
 8828   // TODO: ned save_last_PC here?
 8829   ins_encode( Java_To_Runtime( meth ),
 8830               call_epilog );
 8831   ins_pipe(simple_call);
 8832 %}
 8833 
 8834 // Tail Call; Jump from runtime stub to Java code.
 8835 // Also known as an 'interprocedural jump'.
 8836 // Target of jump will eventually return to caller.
 8837 // TailJump below removes the return address.
 8838 instruct TailCalljmpInd(IPRegP jump_target, inline_cache_regP method_ptr) %{
 8839   match(TailCall jump_target method_ptr);
 8840 
 8841   ins_cost(CALL_COST);
 8842   format %{ "MOV    Rexception_pc, LR\n\t"
 8843             "jump   $jump_target  \t! $method_ptr holds method" %}
 8844   ins_encode %{
 8845     __ mov(Rexception_pc, LR);   // this is used only to call
 8846                                  // StubRoutines::forward_exception_entry()
 8847                                  // which expects PC of exception in
 8848                                  // R5. FIXME?
 8849     __ jump($jump_target$$Register);
 8850   %}
 8851   ins_pipe(tail_call);
 8852 %}
 8853 
 8854 
 8855 // Return Instruction
 8856 instruct Ret() %{
 8857   match(Return);
 8858 
 8859   format %{ "ret LR" %}
 8860 
 8861   ins_encode %{
 8862     __ ret(LR);
 8863   %}
 8864 
 8865   ins_pipe(br);
 8866 %}
 8867 
 8868 
 8869 // Tail Jump; remove the return address; jump to target.
 8870 // TailCall above leaves the return address around.
 8871 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
 8872 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
 8873 // "restore" before this instruction (in Epilogue), we need to materialize it
 8874 // in %i0.
 8875 instruct tailjmpInd(IPRegP jump_target, RExceptionRegP ex_oop) %{
 8876   match( TailJump jump_target ex_oop );
 8877   ins_cost(CALL_COST);
 8878   format %{ "MOV    Rexception_pc, LR\n\t"
 8879             "jump   $jump_target \t! $ex_oop holds exc. oop" %}
 8880   ins_encode %{
 8881     __ mov(Rexception_pc, LR);
 8882     __ jump($jump_target$$Register);
 8883   %}
 8884   ins_pipe(tail_call);
 8885 %}
 8886 
 8887 // Create exception oop: created by stack-crawling runtime code.
 8888 // Created exception is now available to this handler, and is setup
 8889 // just prior to jumping to this handler.  No code emitted.
 8890 instruct CreateException( RExceptionRegP ex_oop )
 8891 %{
 8892   match(Set ex_oop (CreateEx));
 8893   ins_cost(0);
 8894 
 8895   size(0);
 8896   // use the following format syntax
 8897   format %{ "! exception oop is in Rexception_obj; no code emitted" %}
 8898   ins_encode();
 8899   ins_pipe(empty);
 8900 %}
 8901 
 8902 
 8903 // Rethrow exception:
 8904 // The exception oop will come in the first argument position.
 8905 // Then JUMP (not call) to the rethrow stub code.
 8906 instruct RethrowException()
 8907 %{
 8908   match(Rethrow);
 8909   ins_cost(CALL_COST);
 8910 
 8911   // use the following format syntax
 8912   format %{ "b    rethrow_stub" %}
 8913   ins_encode %{
 8914     Register scratch = R1_tmp;
 8915     assert_different_registers(scratch, c_rarg0, LR);
 8916     __ jump(OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type, scratch);
 8917   %}
 8918   ins_pipe(tail_call);
 8919 %}
 8920 
 8921 
 8922 // Die now
 8923 instruct ShouldNotReachHere( )
 8924 %{
 8925   match(Halt);
 8926   ins_cost(CALL_COST);
 8927 
 8928   // Use the following format syntax
 8929   format %{ "ShouldNotReachHere" %}
 8930   ins_encode %{
 8931     if (is_reachable()) {
 8932       __ stop(_halt_reason);
 8933     }
 8934   %}
 8935   ins_pipe(tail_call);
 8936 %}
 8937 
 8938 // ============================================================================
 8939 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
 8940 // array for an instance of the superklass.  Set a hidden internal cache on a
 8941 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
 8942 // not zero for a miss or zero for a hit.  The encoding ALSO sets flags.
 8943 instruct partialSubtypeCheck( R0RegP index, R1RegP sub, R2RegP super, flagsRegP pcc, LRRegP lr ) %{
 8944   match(Set index (PartialSubtypeCheck sub super));
 8945   effect( KILL pcc, KILL lr );
 8946   ins_cost(DEFAULT_COST*10);
 8947   format %{ "CALL   PartialSubtypeCheck" %}
 8948   ins_encode %{
 8949     __ call(StubRoutines::Arm::partial_subtype_check(), relocInfo::runtime_call_type);
 8950   %}
 8951   ins_pipe(partial_subtype_check_pipe);
 8952 %}
 8953 
 8954 /* instruct partialSubtypeCheck_vs_zero( flagsRegP pcc, o1RegP sub, o2RegP super, immP0 zero, o0RegP idx, o7RegP o7 ) %{ */
 8955 /*   match(Set pcc (CmpP (PartialSubtypeCheck sub super) zero)); */
 8956 /*   ins_pipe(partial_subtype_check_pipe); */
 8957 /* %} */
 8958 
 8959 
 8960 // ============================================================================
 8961 // inlined locking and unlocking
 8962 
 8963 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch )
 8964 %{
 8965   match(Set pcc (FastLock object box));
 8966 
 8967   effect(TEMP scratch, TEMP scratch2);
 8968   ins_cost(DEFAULT_COST*3);
 8969 
 8970   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2" %}
 8971   ins_encode %{
 8972     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
 8973   %}
 8974   ins_pipe(long_memory_op);
 8975 %}
 8976 
 8977 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch ) %{
 8978   match(Set pcc (FastUnlock object box));
 8979   effect(TEMP scratch, TEMP scratch2);
 8980   ins_cost(100);
 8981 
 8982   format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2" %}
 8983   ins_encode %{
 8984     __ fast_unlock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
 8985   %}
 8986   ins_pipe(long_memory_op);
 8987 %}
 8988 
 8989 // Count and Base registers are fixed because the allocator cannot
 8990 // kill unknown registers.  The encodings are generic.
 8991 instruct clear_array(iRegX cnt, iRegP base, iRegI temp, iRegX zero, Universe dummy, flagsReg cpsr) %{
 8992   match(Set dummy (ClearArray cnt base));
 8993   effect(TEMP temp, TEMP zero, KILL cpsr);
 8994   ins_cost(300);
 8995   format %{ "MOV    $zero,0\n"
 8996       "        MOV    $temp,$cnt\n"
 8997       "loop:   SUBS   $temp,$temp,4\t! Count down a dword of bytes\n"
 8998       "        STR.ge $zero,[$base+$temp]\t! delay slot"
 8999       "        B.gt   loop\t\t! Clearing loop\n" %}
 9000   ins_encode %{
 9001     __ mov($zero$$Register, 0);
 9002     __ mov($temp$$Register, $cnt$$Register);
 9003     Label(loop);
 9004     __ bind(loop);
 9005     __ subs($temp$$Register, $temp$$Register, 4);
 9006     __ str($zero$$Register, Address($base$$Register, $temp$$Register), ge);
 9007     __ b(loop, gt);
 9008   %}
 9009   ins_pipe(long_memory_op);
 9010 %}
 9011 
 9012 #ifdef XXX
 9013 // FIXME: Why R0/R1/R2/R3?
 9014 instruct string_compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result,
 9015                         iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 9016   predicate(!CompactStrings);
 9017   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
 9018   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, TEMP tmp1, TEMP tmp2);
 9019   ins_cost(300);
 9020   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // TEMP $tmp1, $tmp2" %}
 9021   ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result, tmp1, tmp2) );
 9022 
 9023   ins_pipe(long_memory_op);
 9024 %}
 9025 
 9026 // FIXME: Why R0/R1/R2?
 9027 instruct string_equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2,
 9028                        flagsReg ccr) %{
 9029   predicate(!CompactStrings);
 9030   match(Set result (StrEquals (Binary str1 str2) cnt));
 9031   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp1, TEMP tmp2, TEMP result, KILL ccr);
 9032 
 9033   ins_cost(300);
 9034   format %{ "String Equals $str1,$str2,$cnt -> $result   // TEMP $tmp1, $tmp2" %}
 9035   ins_encode( enc_String_Equals(str1, str2, cnt, result, tmp1, tmp2) );
 9036   ins_pipe(long_memory_op);
 9037 %}
 9038 
 9039 // FIXME: Why R0/R1?
 9040 instruct array_equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result,
 9041                       flagsReg ccr) %{
 9042   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
 9043   match(Set result (AryEq ary1 ary2));
 9044   effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP result, KILL ccr);
 9045 
 9046   ins_cost(300);
 9047   format %{ "Array Equals $ary1,$ary2 -> $result   // TEMP $tmp1,$tmp2,$tmp3" %}
 9048   ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, result));
 9049   ins_pipe(long_memory_op);
 9050 %}
 9051 #endif
 9052 
 9053 //---------- Zeros Count Instructions ------------------------------------------
 9054 
 9055 instruct countLeadingZerosI(iRegI dst, iRegI src) %{
 9056   match(Set dst (CountLeadingZerosI src));
 9057   size(4);
 9058   format %{ "CLZ_32 $dst,$src" %}
 9059   ins_encode %{
 9060     __ clz_32($dst$$Register, $src$$Register);
 9061   %}
 9062   ins_pipe(ialu_reg);
 9063 %}
 9064 
 9065 instruct countLeadingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
 9066   match(Set dst (CountLeadingZerosL src));
 9067   effect(TEMP tmp, TEMP dst, KILL ccr);
 9068   size(16);
 9069   format %{ "CLZ    $dst,$src.hi\n\t"
 9070             "TEQ    $dst,32\n\t"
 9071             "CLZ.eq $tmp,$src.lo\n\t"
 9072             "ADD.eq $dst, $dst, $tmp\n\t" %}
 9073   ins_encode %{
 9074     __ clz($dst$$Register, $src$$Register->successor());
 9075     __ teq($dst$$Register, 32);
 9076     __ clz($tmp$$Register, $src$$Register, eq);
 9077     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
 9078   %}
 9079   ins_pipe(ialu_reg);
 9080 %}
 9081 
 9082 instruct countTrailingZerosI(iRegI dst, iRegI src, iRegI tmp) %{
 9083   match(Set dst (CountTrailingZerosI src));
 9084   effect(TEMP tmp);
 9085   size(8);
 9086   format %{ "RBIT_32 $tmp, $src\n\t"
 9087             "CLZ_32  $dst,$tmp" %}
 9088   ins_encode %{
 9089     __ rbit_32($tmp$$Register, $src$$Register);
 9090     __ clz_32($dst$$Register, $tmp$$Register);
 9091   %}
 9092   ins_pipe(ialu_reg);
 9093 %}
 9094 
 9095 instruct countTrailingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
 9096   match(Set dst (CountTrailingZerosL src));
 9097   effect(TEMP tmp, TEMP dst, KILL ccr);
 9098   size(24);
 9099   format %{ "RBIT   $tmp,$src.lo\n\t"
 9100             "CLZ    $dst,$tmp\n\t"
 9101             "TEQ    $dst,32\n\t"
 9102             "RBIT   $tmp,$src.hi\n\t"
 9103             "CLZ.eq $tmp,$tmp\n\t"
 9104             "ADD.eq $dst,$dst,$tmp\n\t" %}
 9105   ins_encode %{
 9106     __ rbit($tmp$$Register, $src$$Register);
 9107     __ clz($dst$$Register, $tmp$$Register);
 9108     __ teq($dst$$Register, 32);
 9109     __ rbit($tmp$$Register, $src$$Register->successor());
 9110     __ clz($tmp$$Register, $tmp$$Register, eq);
 9111     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
 9112   %}
 9113   ins_pipe(ialu_reg);
 9114 %}
 9115 
 9116 
 9117 //---------- Population Count Instructions -------------------------------------
 9118 
 9119 instruct popCountI(iRegI dst, iRegI src, regD_low tmp) %{
 9120   predicate(UsePopCountInstruction);
 9121   match(Set dst (PopCountI src));
 9122   effect(TEMP tmp);
 9123 
 9124   format %{ "FMSR       $tmp,$src\n\t"
 9125             "VCNT.8     $tmp,$tmp\n\t"
 9126             "VPADDL.U8  $tmp,$tmp\n\t"
 9127             "VPADDL.U16 $tmp,$tmp\n\t"
 9128             "FMRS       $dst,$tmp" %}
 9129   size(20);
 9130 
 9131   ins_encode %{
 9132     __ fmsr($tmp$$FloatRegister, $src$$Register);
 9133     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
 9134     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
 9135     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
 9136     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 9137   %}
 9138   ins_pipe(ialu_reg); // FIXME
 9139 %}
 9140 
 9141 // Note: Long.bitCount(long) returns an int.
 9142 instruct popCountL(iRegI dst, iRegL src, regD_low tmp) %{
 9143   predicate(UsePopCountInstruction);
 9144   match(Set dst (PopCountL src));
 9145   effect(TEMP tmp);
 9146 
 9147   format %{ "FMDRR       $tmp,$src.lo,$src.hi\n\t"
 9148             "VCNT.8      $tmp,$tmp\n\t"
 9149             "VPADDL.U8   $tmp,$tmp\n\t"
 9150             "VPADDL.U16  $tmp,$tmp\n\t"
 9151             "VPADDL.U32  $tmp,$tmp\n\t"
 9152             "FMRS        $dst,$tmp" %}
 9153 
 9154   size(32);
 9155 
 9156   ins_encode %{
 9157     __ fmdrr($tmp$$FloatRegister, $src$$Register, $src$$Register->successor());
 9158     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
 9159     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
 9160     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
 9161     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 32, 0);
 9162     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 9163   %}
 9164   ins_pipe(ialu_reg);
 9165 %}
 9166 
 9167 
 9168 // ============================================================================
 9169 //------------Bytes reverse--------------------------------------------------
 9170 
 9171 instruct bytes_reverse_int(iRegI dst, iRegI src) %{
 9172   match(Set dst (ReverseBytesI src));
 9173 
 9174   size(4);
 9175   format %{ "REV32 $dst,$src" %}
 9176   ins_encode %{
 9177     __ rev($dst$$Register, $src$$Register);
 9178   %}
 9179   ins_pipe( iload_mem ); // FIXME
 9180 %}
 9181 
 9182 instruct bytes_reverse_long(iRegL dst, iRegL src) %{
 9183   match(Set dst (ReverseBytesL src));
 9184   effect(TEMP dst);
 9185   size(8);
 9186   format %{ "REV $dst.lo,$src.lo\n\t"
 9187             "REV $dst.hi,$src.hi" %}
 9188   ins_encode %{
 9189     __ rev($dst$$Register, $src$$Register->successor());
 9190     __ rev($dst$$Register->successor(), $src$$Register);
 9191   %}
 9192   ins_pipe( iload_mem ); // FIXME
 9193 %}
 9194 
 9195 instruct bytes_reverse_unsigned_short(iRegI dst, iRegI src) %{
 9196   match(Set dst (ReverseBytesUS src));
 9197   size(4);
 9198   format %{ "REV16 $dst,$src" %}
 9199   ins_encode %{
 9200     __ rev16($dst$$Register, $src$$Register);
 9201   %}
 9202   ins_pipe( iload_mem ); // FIXME
 9203 %}
 9204 
 9205 instruct bytes_reverse_short(iRegI dst, iRegI src) %{
 9206   match(Set dst (ReverseBytesS src));
 9207   size(4);
 9208   format %{ "REVSH $dst,$src" %}
 9209   ins_encode %{
 9210     __ revsh($dst$$Register, $src$$Register);
 9211   %}
 9212   ins_pipe( iload_mem ); // FIXME
 9213 %}
 9214 
 9215 
 9216 // ====================VECTOR INSTRUCTIONS=====================================
 9217 
 9218 // Load Aligned Packed values into a Double Register
 9219 instruct loadV8(vecD dst, memoryD mem) %{
 9220   predicate(n->as_LoadVector()->memory_size() == 8);
 9221   match(Set dst (LoadVector mem));
 9222   ins_cost(MEMORY_REF_COST);
 9223   size(4);
 9224   format %{ "FLDD   $mem,$dst\t! load vector (8 bytes)" %}
 9225   ins_encode %{
 9226     __ ldr_double($dst$$FloatRegister, $mem$$Address);
 9227   %}
 9228   ins_pipe(floadD_mem);
 9229 %}
 9230 
 9231 // Load Aligned Packed values into a Double Register Pair
 9232 instruct loadV16(vecX dst, memoryvld mem) %{
 9233   predicate(n->as_LoadVector()->memory_size() == 16);
 9234   match(Set dst (LoadVector mem));
 9235   ins_cost(MEMORY_REF_COST);
 9236   size(4);
 9237   format %{ "VLD1   $mem,$dst.Q\t! load vector (16 bytes)" %}
 9238   ins_encode %{
 9239     __ vld1($dst$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
 9240   %}
 9241   ins_pipe(floadD_mem); // FIXME
 9242 %}
 9243 
 9244 // Store Vector in Double register to memory
 9245 instruct storeV8(memoryD mem, vecD src) %{
 9246   predicate(n->as_StoreVector()->memory_size() == 8);
 9247   match(Set mem (StoreVector mem src));
 9248   ins_cost(MEMORY_REF_COST);
 9249   size(4);
 9250   format %{ "FSTD   $src,$mem\t! store vector (8 bytes)" %}
 9251   ins_encode %{
 9252     __ str_double($src$$FloatRegister, $mem$$Address);
 9253   %}
 9254   ins_pipe(fstoreD_mem_reg);
 9255 %}
 9256 
 9257 // Store Vector in Double Register Pair to memory
 9258 instruct storeV16(memoryvld mem, vecX src) %{
 9259   predicate(n->as_StoreVector()->memory_size() == 16);
 9260   match(Set mem (StoreVector mem src));
 9261   ins_cost(MEMORY_REF_COST);
 9262   size(4);
 9263   format %{ "VST1   $src,$mem\t! store vector (16 bytes)" %}
 9264   ins_encode %{
 9265     __ vst1($src$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
 9266   %}
 9267   ins_pipe(fstoreD_mem_reg); // FIXME
 9268 %}
 9269 
 9270 // Replicate scalar to packed byte values in Double register
 9271 instruct Repl8B_reg(vecD dst, iRegI src, iRegI tmp) %{
 9272   predicate(n->as_Vector()->length() == 8);
 9273   match(Set dst (ReplicateB src));
 9274   ins_cost(DEFAULT_COST*4);
 9275   effect(TEMP tmp);
 9276   size(16);
 9277 
 9278   // FIXME: could use PKH instruction instead?
 9279   format %{ "LSL      $tmp, $src, 24 \n\t"
 9280             "OR       $tmp, $tmp, ($tmp >> 8) \n\t"
 9281             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
 9282             "FMDRR    $dst,$tmp,$tmp\t" %}
 9283   ins_encode %{
 9284     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 24));
 9285     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 8));
 9286     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
 9287     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 9288   %}
 9289   ins_pipe(ialu_reg); // FIXME
 9290 %}
 9291 
 9292 // Replicate scalar to packed byte values in Double register
 9293 instruct Repl8B_reg_simd(vecD dst, iRegI src) %{
 9294   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9295   match(Set dst (ReplicateB src));
 9296   size(4);
 9297 
 9298   format %{ "VDUP.8 $dst,$src\t" %}
 9299   ins_encode %{
 9300     bool quad = false;
 9301     __ vdupI($dst$$FloatRegister, $src$$Register,
 9302              MacroAssembler::VELEM_SIZE_8, quad);
 9303   %}
 9304   ins_pipe(ialu_reg); // FIXME
 9305 %}
 9306 
 9307 // Replicate scalar to packed byte values in Double register pair
 9308 instruct Repl16B_reg(vecX dst, iRegI src) %{
 9309   predicate(n->as_Vector()->length_in_bytes() == 16);
 9310   match(Set dst (ReplicateB src));
 9311   size(4);
 9312 
 9313   format %{ "VDUP.8 $dst.Q,$src\t" %}
 9314   ins_encode %{
 9315     bool quad = true;
 9316     __ vdupI($dst$$FloatRegister, $src$$Register,
 9317              MacroAssembler::VELEM_SIZE_8, quad);
 9318   %}
 9319   ins_pipe(ialu_reg); // FIXME
 9320 %}
 9321 
 9322 // Replicate scalar constant to packed byte values in Double register
 9323 instruct Repl8B_immI(vecD dst, immI src, iRegI tmp) %{
 9324   predicate(n->as_Vector()->length() == 8);
 9325   match(Set dst (ReplicateB src));
 9326   ins_cost(DEFAULT_COST*2);
 9327   effect(TEMP tmp);
 9328   size(12);
 9329 
 9330   format %{ "MOV      $tmp, Repl4($src))\n\t"
 9331             "FMDRR    $dst,$tmp,$tmp\t" %}
 9332   ins_encode( LdReplImmI(src, dst, tmp, (4), (1)) );
 9333   ins_pipe(loadConFD); // FIXME
 9334 %}
 9335 
 9336 // Replicate scalar constant to packed byte values in Double register
 9337 // TODO: support negative constants with MVNI?
 9338 instruct Repl8B_immU8(vecD dst, immU8 src) %{
 9339   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9340   match(Set dst (ReplicateB src));
 9341   size(4);
 9342 
 9343   format %{ "VMOV.U8  $dst,$src" %}
 9344   ins_encode %{
 9345     bool quad = false;
 9346     __ vmovI($dst$$FloatRegister, $src$$constant,
 9347              MacroAssembler::VELEM_SIZE_8, quad);
 9348   %}
 9349   ins_pipe(loadConFD); // FIXME
 9350 %}
 9351 
 9352 // Replicate scalar constant to packed byte values in Double register pair
 9353 instruct Repl16B_immU8(vecX dst, immU8 src) %{
 9354   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
 9355   match(Set dst (ReplicateB src));
 9356   size(4);
 9357 
 9358   format %{ "VMOV.U8  $dst.Q,$src" %}
 9359   ins_encode %{
 9360     bool quad = true;
 9361     __ vmovI($dst$$FloatRegister, $src$$constant,
 9362              MacroAssembler::VELEM_SIZE_8, quad);
 9363   %}
 9364   ins_pipe(loadConFD); // FIXME
 9365 %}
 9366 
 9367 // Replicate scalar to packed short/char values into Double register
 9368 instruct Repl4S_reg(vecD dst, iRegI src, iRegI tmp) %{
 9369   predicate(n->as_Vector()->length() == 4);
 9370   match(Set dst (ReplicateS src));
 9371   ins_cost(DEFAULT_COST*3);
 9372   effect(TEMP tmp);
 9373   size(12);
 9374 
 9375   // FIXME: could use PKH instruction instead?
 9376   format %{ "LSL      $tmp, $src, 16 \n\t"
 9377             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
 9378             "FMDRR    $dst,$tmp,$tmp\t" %}
 9379   ins_encode %{
 9380     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 16));
 9381     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
 9382     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 9383   %}
 9384   ins_pipe(ialu_reg); // FIXME
 9385 %}
 9386 
 9387 // Replicate scalar to packed byte values in Double register
 9388 instruct Repl4S_reg_simd(vecD dst, iRegI src) %{
 9389   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9390   match(Set dst (ReplicateS src));
 9391   size(4);
 9392 
 9393   format %{ "VDUP.16 $dst,$src\t" %}
 9394   ins_encode %{
 9395     bool quad = false;
 9396     __ vdupI($dst$$FloatRegister, $src$$Register,
 9397              MacroAssembler::VELEM_SIZE_16, quad);
 9398   %}
 9399   ins_pipe(ialu_reg); // FIXME
 9400 %}
 9401 
 9402 // Replicate scalar to packed byte values in Double register pair
 9403 instruct Repl8S_reg(vecX dst, iRegI src) %{
 9404   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
 9405   match(Set dst (ReplicateS src));
 9406   size(4);
 9407 
 9408   format %{ "VDUP.16 $dst.Q,$src\t" %}
 9409   ins_encode %{
 9410     bool quad = true;
 9411     __ vdupI($dst$$FloatRegister, $src$$Register,
 9412              MacroAssembler::VELEM_SIZE_16, quad);
 9413   %}
 9414   ins_pipe(ialu_reg); // FIXME
 9415 %}
 9416 
 9417 
 9418 // Replicate scalar constant to packed short/char values in Double register
 9419 instruct Repl4S_immI(vecD dst, immI src, iRegP tmp) %{
 9420   predicate(n->as_Vector()->length() == 4);
 9421   match(Set dst (ReplicateS src));
 9422   effect(TEMP tmp);
 9423   size(12);
 9424   ins_cost(DEFAULT_COST*4); // FIXME
 9425 
 9426   format %{ "MOV      $tmp, Repl2($src))\n\t"
 9427             "FMDRR    $dst,$tmp,$tmp\t" %}
 9428   ins_encode( LdReplImmI(src, dst, tmp, (2), (2)) );
 9429   ins_pipe(loadConFD); // FIXME
 9430 %}
 9431 
 9432 // Replicate scalar constant to packed byte values in Double register
 9433 instruct Repl4S_immU8(vecD dst, immU8 src) %{
 9434   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9435   match(Set dst (ReplicateS src));
 9436   size(4);
 9437 
 9438   format %{ "VMOV.U16  $dst,$src" %}
 9439   ins_encode %{
 9440     bool quad = false;
 9441     __ vmovI($dst$$FloatRegister, $src$$constant,
 9442              MacroAssembler::VELEM_SIZE_16, quad);
 9443   %}
 9444   ins_pipe(loadConFD); // FIXME
 9445 %}
 9446 
 9447 // Replicate scalar constant to packed byte values in Double register pair
 9448 instruct Repl8S_immU8(vecX dst, immU8 src) %{
 9449   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
 9450   match(Set dst (ReplicateS src));
 9451   size(4);
 9452 
 9453   format %{ "VMOV.U16  $dst.Q,$src" %}
 9454   ins_encode %{
 9455     bool quad = true;
 9456     __ vmovI($dst$$FloatRegister, $src$$constant,
 9457              MacroAssembler::VELEM_SIZE_16, quad);
 9458   %}
 9459   ins_pipe(loadConFD); // FIXME
 9460 %}
 9461 
 9462 // Replicate scalar to packed int values in Double register
 9463 instruct Repl2I_reg(vecD dst, iRegI src) %{
 9464   predicate(n->as_Vector()->length() == 2);
 9465   match(Set dst (ReplicateI src));
 9466   size(4);
 9467 
 9468   format %{ "FMDRR    $dst,$src,$src\t" %}
 9469   ins_encode %{
 9470     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
 9471   %}
 9472   ins_pipe(ialu_reg); // FIXME
 9473 %}
 9474 
 9475 // Replicate scalar to packed int values in Double register pair
 9476 instruct Repl4I_reg(vecX dst, iRegI src) %{
 9477   predicate(n->as_Vector()->length() == 4);
 9478   match(Set dst (ReplicateI src));
 9479   ins_cost(DEFAULT_COST*2);
 9480   size(8);
 9481 
 9482   format %{ "FMDRR    $dst.lo,$src,$src\n\t"
 9483             "FMDRR    $dst.hi,$src,$src" %}
 9484 
 9485   ins_encode %{
 9486     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
 9487     __ fmdrr($dst$$FloatRegister->successor()->successor(),
 9488              $src$$Register, $src$$Register);
 9489   %}
 9490   ins_pipe(ialu_reg); // FIXME
 9491 %}
 9492 
 9493 // Replicate scalar to packed int values in Double register
 9494 instruct Repl2I_reg_simd(vecD dst, iRegI src) %{
 9495   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9496   match(Set dst (ReplicateI src));
 9497   size(4);
 9498 
 9499   format %{ "VDUP.32 $dst.D,$src\t" %}
 9500   ins_encode %{
 9501     bool quad = false;
 9502     __ vdupI($dst$$FloatRegister, $src$$Register,
 9503              MacroAssembler::VELEM_SIZE_32, quad);
 9504   %}
 9505   ins_pipe(ialu_reg); // FIXME
 9506 %}
 9507 
 9508 // Replicate scalar to packed int values in Double register pair
 9509 instruct Repl4I_reg_simd(vecX dst, iRegI src) %{
 9510   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
 9511   match(Set dst (ReplicateI src));
 9512   size(4);
 9513 
 9514   format %{ "VDUP.32 $dst.Q,$src\t" %}
 9515   ins_encode %{
 9516     bool quad = true;
 9517     __ vdupI($dst$$FloatRegister, $src$$Register,
 9518              MacroAssembler::VELEM_SIZE_32, quad);
 9519   %}
 9520   ins_pipe(ialu_reg); // FIXME
 9521 %}
 9522 
 9523 
 9524 // Replicate scalar zero constant to packed int values in Double register
 9525 instruct Repl2I_immI(vecD dst, immI src, iRegI tmp) %{
 9526   predicate(n->as_Vector()->length() == 2);
 9527   match(Set dst (ReplicateI src));
 9528   effect(TEMP tmp);
 9529   size(12);
 9530   ins_cost(DEFAULT_COST*4); // FIXME
 9531 
 9532   format %{ "MOV      $tmp, Repl1($src))\n\t"
 9533             "FMDRR    $dst,$tmp,$tmp\t" %}
 9534   ins_encode( LdReplImmI(src, dst, tmp, (1), (4)) );
 9535   ins_pipe(loadConFD); // FIXME
 9536 %}
 9537 
 9538 // Replicate scalar constant to packed byte values in Double register
 9539 instruct Repl2I_immU8(vecD dst, immU8 src) %{
 9540   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9541   match(Set dst (ReplicateI src));
 9542   size(4);
 9543 
 9544   format %{ "VMOV.I32  $dst.D,$src" %}
 9545   ins_encode %{
 9546     bool quad = false;
 9547     __ vmovI($dst$$FloatRegister, $src$$constant,
 9548              MacroAssembler::VELEM_SIZE_32, quad);
 9549   %}
 9550   ins_pipe(loadConFD); // FIXME
 9551 %}
 9552 
 9553 // Replicate scalar constant to packed byte values in Double register pair
 9554 instruct Repl4I_immU8(vecX dst, immU8 src) %{
 9555   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
 9556   match(Set dst (ReplicateI src));
 9557   size(4);
 9558 
 9559   format %{ "VMOV.I32  $dst.Q,$src" %}
 9560   ins_encode %{
 9561     bool quad = true;
 9562     __ vmovI($dst$$FloatRegister, $src$$constant,
 9563              MacroAssembler::VELEM_SIZE_32, quad);
 9564   %}
 9565   ins_pipe(loadConFD); // FIXME
 9566 %}
 9567 
 9568 // Replicate scalar to packed byte values in Double register pair
 9569 instruct Repl2L_reg(vecX dst, iRegL src) %{
 9570   predicate(n->as_Vector()->length() == 2);
 9571   match(Set dst (ReplicateL src));
 9572   size(8);
 9573   ins_cost(DEFAULT_COST*2); // FIXME
 9574 
 9575   format %{ "FMDRR $dst.D,$src.lo,$src.hi\t\n"
 9576             "FMDRR $dst.D.next,$src.lo,$src.hi" %}
 9577   ins_encode %{
 9578     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
 9579     __ fmdrr($dst$$FloatRegister->successor()->successor(),
 9580              $src$$Register, $src$$Register->successor());
 9581   %}
 9582   ins_pipe(ialu_reg); // FIXME
 9583 %}
 9584 
 9585 
 9586 // Replicate scalar to packed float values in Double register
 9587 instruct Repl2F_regI(vecD dst, iRegI src) %{
 9588   predicate(n->as_Vector()->length() == 2);
 9589   match(Set dst (ReplicateF src));
 9590   size(4);
 9591 
 9592   format %{ "FMDRR    $dst.D,$src,$src\t" %}
 9593   ins_encode %{
 9594     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
 9595   %}
 9596   ins_pipe(ialu_reg); // FIXME
 9597 %}
 9598 
 9599 // Replicate scalar to packed float values in Double register
 9600 instruct Repl2F_reg_vfp(vecD dst, regF src) %{
 9601   predicate(n->as_Vector()->length() == 2);
 9602   match(Set dst (ReplicateF src));
 9603   size(4*2);
 9604   ins_cost(DEFAULT_COST*2); // FIXME
 9605 
 9606   expand %{
 9607     iRegI tmp;
 9608     MoveF2I_reg_reg(tmp, src);
 9609     Repl2F_regI(dst,tmp);
 9610   %}
 9611 %}
 9612 
 9613 // Replicate scalar to packed float values in Double register
 9614 instruct Repl2F_reg_simd(vecD dst, regF src) %{
 9615   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9616   match(Set dst (ReplicateF src));
 9617   size(4);
 9618   ins_cost(DEFAULT_COST); // FIXME
 9619 
 9620   format %{ "VDUP.32  $dst.D,$src.D\t" %}
 9621   ins_encode %{
 9622     bool quad = false;
 9623     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
 9624   %}
 9625   ins_pipe(ialu_reg); // FIXME
 9626 %}
 9627 
 9628 // Replicate scalar to packed float values in Double register pair
 9629 instruct Repl4F_reg(vecX dst, regF src, iRegI tmp) %{
 9630   predicate(n->as_Vector()->length() == 4);
 9631   match(Set dst (ReplicateF src));
 9632   effect(TEMP tmp);
 9633   size(4*3);
 9634   ins_cost(DEFAULT_COST*3); // FIXME
 9635 
 9636   format %{ "FMRS     $tmp,$src\n\t"
 9637             "FMDRR    $dst.D,$tmp,$tmp\n\t"
 9638             "FMDRR    $dst.D.next,$tmp,$tmp\t" %}
 9639   ins_encode %{
 9640     __ fmrs($tmp$$Register, $src$$FloatRegister);
 9641     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 9642     __ fmdrr($dst$$FloatRegister->successor()->successor(),
 9643              $tmp$$Register, $tmp$$Register);
 9644   %}
 9645   ins_pipe(ialu_reg); // FIXME
 9646 %}
 9647 
 9648 // Replicate scalar to packed float values in Double register pair
 9649 instruct Repl4F_reg_simd(vecX dst, regF src) %{
 9650   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
 9651   match(Set dst (ReplicateF src));
 9652   size(4);
 9653   ins_cost(DEFAULT_COST); // FIXME
 9654 
 9655   format %{ "VDUP.32  $dst.Q,$src.D\t" %}
 9656   ins_encode %{
 9657     bool quad = true;
 9658     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
 9659   %}
 9660   ins_pipe(ialu_reg); // FIXME
 9661 %}
 9662 
 9663 // Replicate scalar zero constant to packed float values in Double register
 9664 instruct Repl2F_immI(vecD dst, immF src, iRegI tmp) %{
 9665   predicate(n->as_Vector()->length() == 2);
 9666   match(Set dst (ReplicateF src));
 9667   effect(TEMP tmp);
 9668   size(12);
 9669   ins_cost(DEFAULT_COST*4); // FIXME
 9670 
 9671   format %{ "MOV      $tmp, Repl1($src))\n\t"
 9672             "FMDRR    $dst,$tmp,$tmp\t" %}
 9673   ins_encode( LdReplImmF(src, dst, tmp) );
 9674   ins_pipe(loadConFD); // FIXME
 9675 %}
 9676 
 9677 // Replicate scalar to packed double float values in Double register pair
 9678 instruct Repl2D_reg(vecX dst, regD src) %{
 9679   predicate(n->as_Vector()->length() == 2);
 9680   match(Set dst (ReplicateD src));
 9681   size(4*2);
 9682   ins_cost(DEFAULT_COST*2); // FIXME
 9683 
 9684   format %{ "FCPYD    $dst.D.a,$src\n\t"
 9685             "FCPYD    $dst.D.b,$src\t" %}
 9686   ins_encode %{
 9687     FloatRegister dsta = $dst$$FloatRegister;
 9688     FloatRegister src = $src$$FloatRegister;
 9689     __ fcpyd(dsta, src);
 9690     FloatRegister dstb = dsta->successor()->successor();
 9691     __ fcpyd(dstb, src);
 9692   %}
 9693   ins_pipe(ialu_reg); // FIXME
 9694 %}
 9695 
 9696 // ====================VECTOR ARITHMETIC=======================================
 9697 
 9698 // --------------------------------- ADD --------------------------------------
 9699 
 9700 // Bytes vector add
 9701 instruct vadd8B_reg(vecD dst, vecD src1, vecD src2) %{
 9702   predicate(n->as_Vector()->length() == 8);
 9703   match(Set dst (AddVB src1 src2));
 9704   format %{ "VADD.I8 $dst,$src1,$src2\t! add packed8B" %}
 9705   size(4);
 9706   ins_encode %{
 9707     bool quad = false;
 9708     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9709              MacroAssembler::VELEM_SIZE_8, quad);
 9710   %}
 9711   ins_pipe( ialu_reg_reg ); // FIXME
 9712 %}
 9713 
 9714 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
 9715   predicate(n->as_Vector()->length() == 16);
 9716   match(Set dst (AddVB src1 src2));
 9717   size(4);
 9718   format %{ "VADD.I8 $dst.Q,$src1.Q,$src2.Q\t! add packed16B" %}
 9719   ins_encode %{
 9720     bool quad = true;
 9721     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9722              MacroAssembler::VELEM_SIZE_8, quad);
 9723   %}
 9724   ins_pipe( ialu_reg_reg ); // FIXME
 9725 %}
 9726 
 9727 // Shorts/Chars vector add
 9728 instruct vadd4S_reg(vecD dst, vecD src1, vecD src2) %{
 9729   predicate(n->as_Vector()->length() == 4);
 9730   match(Set dst (AddVS src1 src2));
 9731   size(4);
 9732   format %{ "VADD.I16 $dst,$src1,$src2\t! add packed4S" %}
 9733   ins_encode %{
 9734     bool quad = false;
 9735     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9736              MacroAssembler::VELEM_SIZE_16, quad);
 9737   %}
 9738   ins_pipe( ialu_reg_reg ); // FIXME
 9739 %}
 9740 
 9741 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
 9742   predicate(n->as_Vector()->length() == 8);
 9743   match(Set dst (AddVS src1 src2));
 9744   size(4);
 9745   format %{ "VADD.I16 $dst.Q,$src1.Q,$src2.Q\t! add packed8S" %}
 9746   ins_encode %{
 9747     bool quad = true;
 9748     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9749              MacroAssembler::VELEM_SIZE_16, quad);
 9750   %}
 9751   ins_pipe( ialu_reg_reg ); // FIXME
 9752 %}
 9753 
 9754 // Integers vector add
 9755 instruct vadd2I_reg(vecD dst, vecD src1, vecD src2) %{
 9756   predicate(n->as_Vector()->length() == 2);
 9757   match(Set dst (AddVI src1 src2));
 9758   size(4);
 9759   format %{ "VADD.I32 $dst.D,$src1.D,$src2.D\t! add packed2I" %}
 9760   ins_encode %{
 9761     bool quad = false;
 9762     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9763              MacroAssembler::VELEM_SIZE_32, quad);
 9764   %}
 9765   ins_pipe( ialu_reg_reg ); // FIXME
 9766 %}
 9767 
 9768 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
 9769   predicate(n->as_Vector()->length() == 4);
 9770   match(Set dst (AddVI src1 src2));
 9771   size(4);
 9772   format %{ "VADD.I32 $dst.Q,$src1.Q,$src2.Q\t! add packed4I" %}
 9773   ins_encode %{
 9774     bool quad = true;
 9775     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9776              MacroAssembler::VELEM_SIZE_32, quad);
 9777   %}
 9778   ins_pipe( ialu_reg_reg ); // FIXME
 9779 %}
 9780 
 9781 // Longs vector add
 9782 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
 9783   predicate(n->as_Vector()->length() == 2);
 9784   match(Set dst (AddVL src1 src2));
 9785   size(4);
 9786   format %{ "VADD.I64 $dst.Q,$src1.Q,$src2.Q\t! add packed2L" %}
 9787   ins_encode %{
 9788     bool quad = true;
 9789     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9790              MacroAssembler::VELEM_SIZE_64, quad);
 9791   %}
 9792   ins_pipe( ialu_reg_reg ); // FIXME
 9793 %}
 9794 
 9795 // Floats vector add
 9796 instruct vadd2F_reg(vecD dst, vecD src1, vecD src2) %{
 9797   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
 9798   match(Set dst (AddVF src1 src2));
 9799   size(4);
 9800   format %{ "VADD.F32 $dst,$src1,$src2\t! add packed2F" %}
 9801   ins_encode %{
 9802     bool quad = false;
 9803     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9804              MacroAssembler::VFA_SIZE_F32, quad);
 9805   %}
 9806   ins_pipe( faddD_reg_reg ); // FIXME
 9807 %}
 9808 
 9809 instruct vadd2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
 9810   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
 9811   match(Set dst (AddVF src1 src2));
 9812   ins_cost(DEFAULT_COST*2); // FIXME
 9813 
 9814   size(4*2);
 9815   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
 9816             "FADDS  $dst.b,$src1.b,$src2.b" %}
 9817   ins_encode %{
 9818     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 9819     __ add_float($dst$$FloatRegister->successor(),
 9820              $src1$$FloatRegister->successor(),
 9821              $src2$$FloatRegister->successor());
 9822   %}
 9823 
 9824   ins_pipe(faddF_reg_reg); // FIXME
 9825 %}
 9826 
 9827 instruct vadd4F_reg_simd(vecX dst, vecX src1, vecX src2) %{
 9828   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
 9829   match(Set dst (AddVF src1 src2));
 9830   size(4);
 9831   format %{ "VADD.F32 $dst.Q,$src1.Q,$src2.Q\t! add packed4F" %}
 9832   ins_encode %{
 9833     bool quad = true;
 9834     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9835              MacroAssembler::VFA_SIZE_F32, quad);
 9836   %}
 9837   ins_pipe( faddD_reg_reg ); // FIXME
 9838 %}
 9839 
 9840 instruct vadd4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
 9841   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
 9842   match(Set dst (AddVF src1 src2));
 9843   size(4*4);
 9844   ins_cost(DEFAULT_COST*4); // FIXME
 9845 
 9846   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
 9847             "FADDS  $dst.b,$src1.b,$src2.b\n\t"
 9848             "FADDS  $dst.c,$src1.c,$src2.c\n\t"
 9849             "FADDS  $dst.d,$src1.d,$src2.d" %}
 9850 
 9851   ins_encode %{
 9852     FloatRegister dsta = $dst$$FloatRegister;
 9853     FloatRegister src1a = $src1$$FloatRegister;
 9854     FloatRegister src2a = $src2$$FloatRegister;
 9855     __ add_float(dsta, src1a, src2a);
 9856     FloatRegister dstb = dsta->successor();
 9857     FloatRegister src1b = src1a->successor();
 9858     FloatRegister src2b = src2a->successor();
 9859     __ add_float(dstb, src1b, src2b);
 9860     FloatRegister dstc = dstb->successor();
 9861     FloatRegister src1c = src1b->successor();
 9862     FloatRegister src2c = src2b->successor();
 9863     __ add_float(dstc, src1c, src2c);
 9864     FloatRegister dstd = dstc->successor();
 9865     FloatRegister src1d = src1c->successor();
 9866     FloatRegister src2d = src2c->successor();
 9867     __ add_float(dstd, src1d, src2d);
 9868   %}
 9869 
 9870   ins_pipe(faddF_reg_reg); // FIXME
 9871 %}
 9872 
 9873 instruct vadd2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
 9874   predicate(n->as_Vector()->length() == 2);
 9875   match(Set dst (AddVD src1 src2));
 9876   size(4*2);
 9877   ins_cost(DEFAULT_COST*2); // FIXME
 9878 
 9879   format %{ "FADDD  $dst.a,$src1.a,$src2.a\n\t"
 9880             "FADDD  $dst.b,$src1.b,$src2.b" %}
 9881 
 9882   ins_encode %{
 9883     FloatRegister dsta = $dst$$FloatRegister;
 9884     FloatRegister src1a = $src1$$FloatRegister;
 9885     FloatRegister src2a = $src2$$FloatRegister;
 9886     __ add_double(dsta, src1a, src2a);
 9887     FloatRegister dstb = dsta->successor()->successor();
 9888     FloatRegister src1b = src1a->successor()->successor();
 9889     FloatRegister src2b = src2a->successor()->successor();
 9890     __ add_double(dstb, src1b, src2b);
 9891   %}
 9892 
 9893   ins_pipe(faddF_reg_reg); // FIXME
 9894 %}
 9895 
 9896 
 9897 // Bytes vector sub
 9898 instruct vsub8B_reg(vecD dst, vecD src1, vecD src2) %{
 9899   predicate(n->as_Vector()->length() == 8);
 9900   match(Set dst (SubVB src1 src2));
 9901   size(4);
 9902   format %{ "VSUB.I8 $dst,$src1,$src2\t! sub packed8B" %}
 9903   ins_encode %{
 9904     bool quad = false;
 9905     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9906              MacroAssembler::VELEM_SIZE_8, quad);
 9907   %}
 9908   ins_pipe( ialu_reg_reg ); // FIXME
 9909 %}
 9910 
 9911 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
 9912   predicate(n->as_Vector()->length() == 16);
 9913   match(Set dst (SubVB src1 src2));
 9914   size(4);
 9915   format %{ "VSUB.I8 $dst.Q,$src1.Q,$src2.Q\t! sub packed16B" %}
 9916   ins_encode %{
 9917     bool quad = true;
 9918     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9919              MacroAssembler::VELEM_SIZE_8, quad);
 9920   %}
 9921   ins_pipe( ialu_reg_reg ); // FIXME
 9922 %}
 9923 
 9924 // Shorts/Chars vector sub
 9925 instruct vsub4S_reg(vecD dst, vecD src1, vecD src2) %{
 9926   predicate(n->as_Vector()->length() == 4);
 9927   match(Set dst (SubVS src1 src2));
 9928   size(4);
 9929   format %{ "VSUB.I16 $dst,$src1,$src2\t! sub packed4S" %}
 9930   ins_encode %{
 9931     bool quad = false;
 9932     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9933              MacroAssembler::VELEM_SIZE_16, quad);
 9934   %}
 9935   ins_pipe( ialu_reg_reg ); // FIXME
 9936 %}
 9937 
 9938 instruct vsub16S_reg(vecX dst, vecX src1, vecX src2) %{
 9939   predicate(n->as_Vector()->length() == 8);
 9940   match(Set dst (SubVS src1 src2));
 9941   size(4);
 9942   format %{ "VSUB.I16 $dst.Q,$src1.Q,$src2.Q\t! sub packed8S" %}
 9943   ins_encode %{
 9944     bool quad = true;
 9945     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9946              MacroAssembler::VELEM_SIZE_16, quad);
 9947   %}
 9948   ins_pipe( ialu_reg_reg ); // FIXME
 9949 %}
 9950 
 9951 // Integers vector sub
 9952 instruct vsub2I_reg(vecD dst, vecD src1, vecD src2) %{
 9953   predicate(n->as_Vector()->length() == 2);
 9954   match(Set dst (SubVI src1 src2));
 9955   size(4);
 9956   format %{ "VSUB.I32 $dst,$src1,$src2\t! sub packed2I" %}
 9957   ins_encode %{
 9958     bool quad = false;
 9959     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9960              MacroAssembler::VELEM_SIZE_32, quad);
 9961   %}
 9962   ins_pipe( ialu_reg_reg ); // FIXME
 9963 %}
 9964 
 9965 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
 9966   predicate(n->as_Vector()->length() == 4);
 9967   match(Set dst (SubVI src1 src2));
 9968   size(4);
 9969   format %{ "VSUB.I32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4I" %}
 9970   ins_encode %{
 9971     bool quad = true;
 9972     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9973              MacroAssembler::VELEM_SIZE_32, quad);
 9974   %}
 9975   ins_pipe( ialu_reg_reg ); // FIXME
 9976 %}
 9977 
 9978 // Longs vector sub
 9979 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
 9980   predicate(n->as_Vector()->length() == 2);
 9981   match(Set dst (SubVL src1 src2));
 9982   size(4);
 9983   format %{ "VSUB.I64 $dst.Q,$src1.Q,$src2.Q\t! sub packed2L" %}
 9984   ins_encode %{
 9985     bool quad = true;
 9986     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9987              MacroAssembler::VELEM_SIZE_64, quad);
 9988   %}
 9989   ins_pipe( ialu_reg_reg ); // FIXME
 9990 %}
 9991 
 9992 // Floats vector sub
 9993 instruct vsub2F_reg(vecD dst, vecD src1, vecD src2) %{
 9994   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
 9995   match(Set dst (SubVF src1 src2));
 9996   size(4);
 9997   format %{ "VSUB.F32 $dst,$src1,$src2\t! sub packed2F" %}
 9998   ins_encode %{
 9999     bool quad = false;
10000     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10001              MacroAssembler::VFA_SIZE_F32, quad);
10002   %}
10003   ins_pipe( faddF_reg_reg ); // FIXME
10004 %}
10005 
10006 instruct vsub2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10007   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
10008   match(Set dst (SubVF src1 src2));
10009   size(4*2);
10010   ins_cost(DEFAULT_COST*2); // FIXME
10011 
10012   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10013             "FSUBS  $dst.b,$src1.b,$src2.b" %}
10014 
10015   ins_encode %{
10016     FloatRegister dsta = $dst$$FloatRegister;
10017     FloatRegister src1a = $src1$$FloatRegister;
10018     FloatRegister src2a = $src2$$FloatRegister;
10019     __ sub_float(dsta, src1a, src2a);
10020     FloatRegister dstb = dsta->successor();
10021     FloatRegister src1b = src1a->successor();
10022     FloatRegister src2b = src2a->successor();
10023     __ sub_float(dstb, src1b, src2b);
10024   %}
10025 
10026   ins_pipe(faddF_reg_reg); // FIXME
10027 %}
10028 
10029 
10030 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
10031   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
10032   match(Set dst (SubVF src1 src2));
10033   size(4);
10034   format %{ "VSUB.F32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4F" %}
10035   ins_encode %{
10036     bool quad = true;
10037     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10038              MacroAssembler::VFA_SIZE_F32, quad);
10039   %}
10040   ins_pipe( faddF_reg_reg ); // FIXME
10041 %}
10042 
10043 instruct vsub4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10044   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
10045   match(Set dst (SubVF src1 src2));
10046   size(4*4);
10047   ins_cost(DEFAULT_COST*4); // FIXME
10048 
10049   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10050             "FSUBS  $dst.b,$src1.b,$src2.b\n\t"
10051             "FSUBS  $dst.c,$src1.c,$src2.c\n\t"
10052             "FSUBS  $dst.d,$src1.d,$src2.d" %}
10053 
10054   ins_encode %{
10055     FloatRegister dsta = $dst$$FloatRegister;
10056     FloatRegister src1a = $src1$$FloatRegister;
10057     FloatRegister src2a = $src2$$FloatRegister;
10058     __ sub_float(dsta, src1a, src2a);
10059     FloatRegister dstb = dsta->successor();
10060     FloatRegister src1b = src1a->successor();
10061     FloatRegister src2b = src2a->successor();
10062     __ sub_float(dstb, src1b, src2b);
10063     FloatRegister dstc = dstb->successor();
10064     FloatRegister src1c = src1b->successor();
10065     FloatRegister src2c = src2b->successor();
10066     __ sub_float(dstc, src1c, src2c);
10067     FloatRegister dstd = dstc->successor();
10068     FloatRegister src1d = src1c->successor();
10069     FloatRegister src2d = src2c->successor();
10070     __ sub_float(dstd, src1d, src2d);
10071   %}
10072 
10073   ins_pipe(faddF_reg_reg); // FIXME
10074 %}
10075 
10076 instruct vsub2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10077   predicate(n->as_Vector()->length() == 2);
10078   match(Set dst (SubVD src1 src2));
10079   size(4*2);
10080   ins_cost(DEFAULT_COST*2); // FIXME
10081 
10082   format %{ "FSUBD  $dst.a,$src1.a,$src2.a\n\t"
10083             "FSUBD  $dst.b,$src1.b,$src2.b" %}
10084 
10085   ins_encode %{
10086     FloatRegister dsta = $dst$$FloatRegister;
10087     FloatRegister src1a = $src1$$FloatRegister;
10088     FloatRegister src2a = $src2$$FloatRegister;
10089     __ sub_double(dsta, src1a, src2a);
10090     FloatRegister dstb = dsta->successor()->successor();
10091     FloatRegister src1b = src1a->successor()->successor();
10092     FloatRegister src2b = src2a->successor()->successor();
10093     __ sub_double(dstb, src1b, src2b);
10094   %}
10095 
10096   ins_pipe(faddF_reg_reg); // FIXME
10097 %}
10098 
10099 // Shorts/Chars vector mul
10100 instruct vmul4S_reg(vecD dst, vecD src1, vecD src2) %{
10101   predicate(n->as_Vector()->length() == 4);
10102   match(Set dst (MulVS src1 src2));
10103   size(4);
10104   format %{ "VMUL.I16 $dst,$src1,$src2\t! mul packed4S" %}
10105   ins_encode %{
10106     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10107              MacroAssembler::VELEM_SIZE_16, 0);
10108   %}
10109   ins_pipe( ialu_reg_reg ); // FIXME
10110 %}
10111 
10112 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2) %{
10113   predicate(n->as_Vector()->length() == 8);
10114   match(Set dst (MulVS src1 src2));
10115   size(4);
10116   format %{ "VMUL.I16 $dst.Q,$src1.Q,$src2.Q\t! mul packed8S" %}
10117   ins_encode %{
10118     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10119              MacroAssembler::VELEM_SIZE_16, 1);
10120   %}
10121   ins_pipe( ialu_reg_reg ); // FIXME
10122 %}
10123 
10124 // Integers vector mul
10125 instruct vmul2I_reg(vecD dst, vecD src1, vecD src2) %{
10126   predicate(n->as_Vector()->length() == 2);
10127   match(Set dst (MulVI src1 src2));
10128   size(4);
10129   format %{ "VMUL.I32 $dst,$src1,$src2\t! mul packed2I" %}
10130   ins_encode %{
10131     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10132              MacroAssembler::VELEM_SIZE_32, 0);
10133   %}
10134   ins_pipe( ialu_reg_reg ); // FIXME
10135 %}
10136 
10137 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
10138   predicate(n->as_Vector()->length() == 4);
10139   match(Set dst (MulVI src1 src2));
10140   size(4);
10141   format %{ "VMUL.I32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4I" %}
10142   ins_encode %{
10143     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10144              MacroAssembler::VELEM_SIZE_32, 1);
10145   %}
10146   ins_pipe( ialu_reg_reg ); // FIXME
10147 %}
10148 
10149 // Floats vector mul
10150 instruct vmul2F_reg(vecD dst, vecD src1, vecD src2) %{
10151   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
10152   match(Set dst (MulVF src1 src2));
10153   size(4);
10154   format %{ "VMUL.F32 $dst,$src1,$src2\t! mul packed2F" %}
10155   ins_encode %{
10156     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10157              MacroAssembler::VFA_SIZE_F32, 0);
10158   %}
10159   ins_pipe( fmulF_reg_reg ); // FIXME
10160 %}
10161 
10162 instruct vmul2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10163   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
10164   match(Set dst (MulVF src1 src2));
10165   size(4*2);
10166   ins_cost(DEFAULT_COST*2); // FIXME
10167 
10168   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10169             "FMULS  $dst.b,$src1.b,$src2.b" %}
10170   ins_encode %{
10171     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10172     __ mul_float($dst$$FloatRegister->successor(),
10173              $src1$$FloatRegister->successor(),
10174              $src2$$FloatRegister->successor());
10175   %}
10176 
10177   ins_pipe(fmulF_reg_reg); // FIXME
10178 %}
10179 
10180 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
10181   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
10182   match(Set dst (MulVF src1 src2));
10183   size(4);
10184   format %{ "VMUL.F32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4F" %}
10185   ins_encode %{
10186     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10187              MacroAssembler::VFA_SIZE_F32, 1);
10188   %}
10189   ins_pipe( fmulF_reg_reg ); // FIXME
10190 %}
10191 
10192 instruct vmul4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10193   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
10194   match(Set dst (MulVF src1 src2));
10195   size(4*4);
10196   ins_cost(DEFAULT_COST*4); // FIXME
10197 
10198   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10199             "FMULS  $dst.b,$src1.b,$src2.b\n\t"
10200             "FMULS  $dst.c,$src1.c,$src2.c\n\t"
10201             "FMULS  $dst.d,$src1.d,$src2.d" %}
10202 
10203   ins_encode %{
10204     FloatRegister dsta = $dst$$FloatRegister;
10205     FloatRegister src1a = $src1$$FloatRegister;
10206     FloatRegister src2a = $src2$$FloatRegister;
10207     __ mul_float(dsta, src1a, src2a);
10208     FloatRegister dstb = dsta->successor();
10209     FloatRegister src1b = src1a->successor();
10210     FloatRegister src2b = src2a->successor();
10211     __ mul_float(dstb, src1b, src2b);
10212     FloatRegister dstc = dstb->successor();
10213     FloatRegister src1c = src1b->successor();
10214     FloatRegister src2c = src2b->successor();
10215     __ mul_float(dstc, src1c, src2c);
10216     FloatRegister dstd = dstc->successor();
10217     FloatRegister src1d = src1c->successor();
10218     FloatRegister src2d = src2c->successor();
10219     __ mul_float(dstd, src1d, src2d);
10220   %}
10221 
10222   ins_pipe(fmulF_reg_reg); // FIXME
10223 %}
10224 
10225 instruct vmul2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10226   predicate(n->as_Vector()->length() == 2);
10227   match(Set dst (MulVD src1 src2));
10228   size(4*2);
10229   ins_cost(DEFAULT_COST*2); // FIXME
10230 
10231   format %{ "FMULD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10232             "FMULD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10233   ins_encode %{
10234     FloatRegister dsta = $dst$$FloatRegister;
10235     FloatRegister src1a = $src1$$FloatRegister;
10236     FloatRegister src2a = $src2$$FloatRegister;
10237     __ mul_double(dsta, src1a, src2a);
10238     FloatRegister dstb = dsta->successor()->successor();
10239     FloatRegister src1b = src1a->successor()->successor();
10240     FloatRegister src2b = src2a->successor()->successor();
10241     __ mul_double(dstb, src1b, src2b);
10242   %}
10243 
10244   ins_pipe(fmulD_reg_reg); // FIXME
10245 %}
10246 
10247 
10248 // Floats vector div
10249 instruct vdiv2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10250   predicate(n->as_Vector()->length() == 2);
10251   match(Set dst (DivVF src1 src2));
10252   size(4*2);
10253   ins_cost(DEFAULT_COST*2); // FIXME
10254 
10255   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10256             "FDIVS  $dst.b,$src1.b,$src2.b" %}
10257   ins_encode %{
10258     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10259     __ div_float($dst$$FloatRegister->successor(),
10260              $src1$$FloatRegister->successor(),
10261              $src2$$FloatRegister->successor());
10262   %}
10263 
10264   ins_pipe(fdivF_reg_reg); // FIXME
10265 %}
10266 
10267 instruct vdiv4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10268   predicate(n->as_Vector()->length() == 4);
10269   match(Set dst (DivVF src1 src2));
10270   size(4*4);
10271   ins_cost(DEFAULT_COST*4); // FIXME
10272 
10273   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10274             "FDIVS  $dst.b,$src1.b,$src2.b\n\t"
10275             "FDIVS  $dst.c,$src1.c,$src2.c\n\t"
10276             "FDIVS  $dst.d,$src1.d,$src2.d" %}
10277 
10278   ins_encode %{
10279     FloatRegister dsta = $dst$$FloatRegister;
10280     FloatRegister src1a = $src1$$FloatRegister;
10281     FloatRegister src2a = $src2$$FloatRegister;
10282     __ div_float(dsta, src1a, src2a);
10283     FloatRegister dstb = dsta->successor();
10284     FloatRegister src1b = src1a->successor();
10285     FloatRegister src2b = src2a->successor();
10286     __ div_float(dstb, src1b, src2b);
10287     FloatRegister dstc = dstb->successor();
10288     FloatRegister src1c = src1b->successor();
10289     FloatRegister src2c = src2b->successor();
10290     __ div_float(dstc, src1c, src2c);
10291     FloatRegister dstd = dstc->successor();
10292     FloatRegister src1d = src1c->successor();
10293     FloatRegister src2d = src2c->successor();
10294     __ div_float(dstd, src1d, src2d);
10295   %}
10296 
10297   ins_pipe(fdivF_reg_reg); // FIXME
10298 %}
10299 
10300 instruct vdiv2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10301   predicate(n->as_Vector()->length() == 2);
10302   match(Set dst (DivVD src1 src2));
10303   size(4*2);
10304   ins_cost(DEFAULT_COST*2); // FIXME
10305 
10306   format %{ "FDIVD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10307             "FDIVD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10308   ins_encode %{
10309     FloatRegister dsta = $dst$$FloatRegister;
10310     FloatRegister src1a = $src1$$FloatRegister;
10311     FloatRegister src2a = $src2$$FloatRegister;
10312     __ div_double(dsta, src1a, src2a);
10313     FloatRegister dstb = dsta->successor()->successor();
10314     FloatRegister src1b = src1a->successor()->successor();
10315     FloatRegister src2b = src2a->successor()->successor();
10316     __ div_double(dstb, src1b, src2b);
10317   %}
10318 
10319   ins_pipe(fdivD_reg_reg); // FIXME
10320 %}
10321 
10322 // --------------------------------- NEG --------------------------------------
10323 
10324 instruct vneg8B_reg(vecD dst, vecD src) %{
10325   predicate(n->as_Vector()->length_in_bytes() == 8);
10326   effect(DEF dst, USE src);
10327   size(4);
10328   ins_cost(DEFAULT_COST); // FIXME
10329   format %{ "VNEG.S8 $dst.D,$src.D\t! neg packed8B" %}
10330   ins_encode %{
10331     bool quad = false;
10332     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
10333               MacroAssembler::VELEM_SIZE_8, quad);
10334   %}
10335   ins_pipe( ialu_reg_reg ); // FIXME
10336 %}
10337 
10338 instruct vneg16B_reg(vecX dst, vecX src) %{
10339   predicate(n->as_Vector()->length_in_bytes() == 16);
10340   effect(DEF dst, USE src);
10341   size(4);
10342   ins_cost(DEFAULT_COST); // FIXME
10343   format %{ "VNEG.S8 $dst.Q,$src.Q\t! neg0 packed16B" %}
10344   ins_encode %{
10345     bool _float = false;
10346     bool quad = true;
10347     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
10348               MacroAssembler::VELEM_SIZE_8, quad);
10349   %}
10350   ins_pipe( ialu_reg_reg ); // FIXME
10351 %}
10352 
10353 // ------------------------------ Shift ---------------------------------------
10354 
10355 instruct vslcntD(vecD dst, iRegI cnt) %{
10356   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
10357   match(Set dst (LShiftCntV cnt));
10358   size(4);
10359   ins_cost(DEFAULT_COST); // FIXME
10360   expand %{
10361     Repl8B_reg_simd(dst, cnt);
10362   %}
10363 %}
10364 
10365 instruct vslcntX(vecX dst, iRegI cnt) %{
10366   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
10367   match(Set dst (LShiftCntV cnt));
10368   size(4);
10369   ins_cost(DEFAULT_COST); // FIXME
10370   expand %{
10371     Repl16B_reg(dst, cnt);
10372   %}
10373 %}
10374 
10375 // Low bits of vector "shift" elements are used, so it
10376 // doesn't matter if we treat it as ints or bytes here.
10377 instruct vsrcntD(vecD dst, iRegI cnt) %{
10378   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
10379   match(Set dst (RShiftCntV cnt));
10380   size(4*2);
10381   ins_cost(DEFAULT_COST*2); // FIXME
10382 
10383   format %{ "VDUP.8 $dst.D,$cnt\n\t"
10384             "VNEG.S8 $dst.D,$dst.D\t! neg packed8B" %}
10385   ins_encode %{
10386     bool quad = false;
10387     __ vdupI($dst$$FloatRegister, $cnt$$Register,
10388              MacroAssembler::VELEM_SIZE_8, quad);
10389     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
10390               MacroAssembler::VELEM_SIZE_8, quad);
10391   %}
10392   ins_pipe( ialu_reg_reg ); // FIXME
10393 %}
10394 
10395 instruct vsrcntX(vecX dst, iRegI cnt) %{
10396   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
10397   match(Set dst (RShiftCntV cnt));
10398   size(4*2);
10399   ins_cost(DEFAULT_COST*2); // FIXME
10400   format %{ "VDUP.8 $dst.Q,$cnt\n\t"
10401             "VNEG.S8 $dst.Q,$dst.Q\t! neg packed16B" %}
10402   ins_encode %{
10403     bool quad = true;
10404     __ vdupI($dst$$FloatRegister, $cnt$$Register,
10405              MacroAssembler::VELEM_SIZE_8, quad);
10406     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
10407               MacroAssembler::VELEM_SIZE_8, quad);
10408   %}
10409   ins_pipe( ialu_reg_reg ); // FIXME
10410 %}
10411 
10412 // Byte vector logical left/right shift based on sign
10413 instruct vsh8B_reg(vecD dst, vecD src, vecD shift) %{
10414   predicate(n->as_Vector()->length() == 8);
10415   effect(DEF dst, USE src, USE shift);
10416   size(4);
10417   ins_cost(DEFAULT_COST); // FIXME
10418   format %{
10419     "VSHL.U8 $dst.D,$src.D,$shift.D\t! logical left/right shift packed8B"
10420   %}
10421   ins_encode %{
10422     bool quad = false;
10423     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10424               MacroAssembler::VELEM_SIZE_8, quad);
10425   %}
10426   ins_pipe( ialu_reg_reg ); // FIXME
10427 %}
10428 
10429 instruct vsh16B_reg(vecX dst, vecX src, vecX shift) %{
10430   predicate(n->as_Vector()->length() == 16);
10431   effect(DEF dst, USE src, USE shift);
10432   size(4);
10433   ins_cost(DEFAULT_COST); // FIXME
10434   format %{
10435     "VSHL.U8 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed16B"
10436   %}
10437   ins_encode %{
10438     bool quad = true;
10439     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10440               MacroAssembler::VELEM_SIZE_8, quad);
10441   %}
10442   ins_pipe( ialu_reg_reg ); // FIXME
10443 %}
10444 
10445 // Shorts/Char vector logical left/right shift based on sign
10446 instruct vsh4S_reg(vecD dst, vecD src, vecD shift) %{
10447   predicate(n->as_Vector()->length() == 4);
10448   effect(DEF dst, USE src, USE shift);
10449   size(4);
10450   ins_cost(DEFAULT_COST); // FIXME
10451   format %{
10452     "VSHL.U16 $dst.D,$src.D,$shift.D\t! logical left/right shift packed4S"
10453   %}
10454   ins_encode %{
10455     bool quad = false;
10456     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10457               MacroAssembler::VELEM_SIZE_16, quad);
10458   %}
10459   ins_pipe( ialu_reg_reg ); // FIXME
10460 %}
10461 
10462 instruct vsh8S_reg(vecX dst, vecX src, vecX shift) %{
10463   predicate(n->as_Vector()->length() == 8);
10464   effect(DEF dst, USE src, USE shift);
10465   size(4);
10466   ins_cost(DEFAULT_COST); // FIXME
10467   format %{
10468     "VSHL.U16 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed8S"
10469   %}
10470   ins_encode %{
10471     bool quad = true;
10472     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10473               MacroAssembler::VELEM_SIZE_16, quad);
10474   %}
10475   ins_pipe( ialu_reg_reg ); // FIXME
10476 %}
10477 
10478 // Integers vector logical left/right shift based on sign
10479 instruct vsh2I_reg(vecD dst, vecD src, vecD shift) %{
10480   predicate(n->as_Vector()->length() == 2);
10481   effect(DEF dst, USE src, USE shift);
10482   size(4);
10483   ins_cost(DEFAULT_COST); // FIXME
10484   format %{
10485     "VSHL.U32 $dst.D,$src.D,$shift.D\t! logical left/right shift packed2I"
10486   %}
10487   ins_encode %{
10488     bool quad = false;
10489     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10490               MacroAssembler::VELEM_SIZE_32, quad);
10491   %}
10492   ins_pipe( ialu_reg_reg ); // FIXME
10493 %}
10494 
10495 instruct vsh4I_reg(vecX dst, vecX src, vecX shift) %{
10496   predicate(n->as_Vector()->length() == 4);
10497   effect(DEF dst, USE src, USE shift);
10498   size(4);
10499   ins_cost(DEFAULT_COST); // FIXME
10500   format %{
10501     "VSHL.U32 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed4I"
10502   %}
10503   ins_encode %{
10504     bool quad = true;
10505     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10506               MacroAssembler::VELEM_SIZE_32, quad);
10507   %}
10508   ins_pipe( ialu_reg_reg ); // FIXME
10509 %}
10510 
10511 // Longs vector logical left/right shift based on sign
10512 instruct vsh2L_reg(vecX dst, vecX src, vecX shift) %{
10513   predicate(n->as_Vector()->length() == 2);
10514   effect(DEF dst, USE src, USE shift);
10515   size(4);
10516   ins_cost(DEFAULT_COST); // FIXME
10517   format %{
10518     "VSHL.U64 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed2L"
10519   %}
10520   ins_encode %{
10521     bool quad = true;
10522     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10523               MacroAssembler::VELEM_SIZE_64, quad);
10524   %}
10525   ins_pipe( ialu_reg_reg ); // FIXME
10526 %}
10527 
10528 // ------------------------------ LeftShift -----------------------------------
10529 
10530 // Byte vector left shift
10531 instruct vsl8B_reg(vecD dst, vecD src, vecD shift) %{
10532   predicate(n->as_Vector()->length() == 8);
10533   match(Set dst (LShiftVB src shift));
10534   size(4*1);
10535   ins_cost(DEFAULT_COST*1); // FIXME
10536   expand %{
10537     vsh8B_reg(dst, src, shift);
10538   %}
10539 %}
10540 
10541 instruct vsl16B_reg(vecX dst, vecX src, vecX shift) %{
10542   predicate(n->as_Vector()->length() == 16);
10543   match(Set dst (LShiftVB src shift));
10544   size(4*1);
10545   ins_cost(DEFAULT_COST*1); // FIXME
10546   expand %{
10547     vsh16B_reg(dst, src, shift);
10548   %}
10549 %}
10550 
10551 instruct vsl8B_immI(vecD dst, vecD src, immI shift) %{
10552   predicate(n->as_Vector()->length() == 8);
10553   match(Set dst (LShiftVB src (LShiftCntV shift)));
10554   size(4);
10555   ins_cost(DEFAULT_COST); // FIXME
10556   format %{
10557     "VSHL.I8 $dst.D,$src.D,$shift\t! logical left shift packed8B"
10558   %}
10559   ins_encode %{
10560     bool quad = false;
10561     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10562              quad);
10563   %}
10564   ins_pipe( ialu_reg_reg ); // FIXME
10565 %}
10566 
10567 instruct vsl16B_immI(vecX dst, vecX src, immI shift) %{
10568   predicate(n->as_Vector()->length() == 16);
10569   match(Set dst (LShiftVB src (LShiftCntV shift)));
10570   size(4);
10571   ins_cost(DEFAULT_COST); // FIXME
10572   format %{
10573     "VSHL.I8 $dst.Q,$src.Q,$shift\t! logical left shift packed16B"
10574   %}
10575   ins_encode %{
10576     bool quad = true;
10577     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10578              quad);
10579   %}
10580   ins_pipe( ialu_reg_reg ); // FIXME
10581 %}
10582 
10583 // Shorts/Chars vector logical left/right shift
10584 instruct vsl4S_reg(vecD dst, vecD src, vecD shift) %{
10585   predicate(n->as_Vector()->length() == 4);
10586   match(Set dst (LShiftVS src shift));
10587   match(Set dst (URShiftVS src shift));
10588   size(4*1);
10589   ins_cost(DEFAULT_COST*1); // FIXME
10590   expand %{
10591     vsh4S_reg(dst, src, shift);
10592   %}
10593 %}
10594 
10595 instruct vsl8S_reg(vecX dst, vecX src, vecX shift) %{
10596   predicate(n->as_Vector()->length() == 8);
10597   match(Set dst (LShiftVS src shift));
10598   match(Set dst (URShiftVS src shift));
10599   size(4*1);
10600   ins_cost(DEFAULT_COST*1); // FIXME
10601   expand %{
10602     vsh8S_reg(dst, src, shift);
10603   %}
10604 %}
10605 
10606 instruct vsl4S_immI(vecD dst, vecD src, immI shift) %{
10607   predicate(n->as_Vector()->length() == 4);
10608   match(Set dst (LShiftVS src (LShiftCntV shift)));
10609   size(4);
10610   ins_cost(DEFAULT_COST); // FIXME
10611   format %{
10612     "VSHL.I16 $dst.D,$src.D,$shift\t! logical left shift packed4S"
10613   %}
10614   ins_encode %{
10615     bool quad = false;
10616     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10617              quad);
10618   %}
10619   ins_pipe( ialu_reg_reg ); // FIXME
10620 %}
10621 
10622 instruct vsl8S_immI(vecX dst, vecX src, immI shift) %{
10623   predicate(n->as_Vector()->length() == 8);
10624   match(Set dst (LShiftVS src shift));
10625   size(4);
10626   ins_cost(DEFAULT_COST); // FIXME
10627   format %{
10628     "VSHL.I16 $dst.Q,$src.Q,$shift\t! logical left shift packed8S"
10629   %}
10630   ins_encode %{
10631     bool quad = true;
10632     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10633              quad);
10634   %}
10635   ins_pipe( ialu_reg_reg ); // FIXME
10636 %}
10637 
10638 // Integers vector logical left/right shift
10639 instruct vsl2I_reg(vecD dst, vecD src, vecD shift) %{
10640   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10641   match(Set dst (LShiftVI src shift));
10642   match(Set dst (URShiftVI src shift));
10643   size(4*1);
10644   ins_cost(DEFAULT_COST*1); // FIXME
10645   expand %{
10646     vsh2I_reg(dst, src, shift);
10647   %}
10648 %}
10649 
10650 instruct vsl4I_reg(vecX dst, vecX src, vecX shift) %{
10651   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10652   match(Set dst (LShiftVI src shift));
10653   match(Set dst (URShiftVI src shift));
10654   size(4*1);
10655   ins_cost(DEFAULT_COST*1); // FIXME
10656   expand %{
10657     vsh4I_reg(dst, src, shift);
10658   %}
10659 %}
10660 
10661 instruct vsl2I_immI(vecD dst, vecD src, immI shift) %{
10662   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10663   match(Set dst (LShiftVI src (LShiftCntV shift)));
10664   size(4);
10665   ins_cost(DEFAULT_COST); // FIXME
10666   format %{
10667     "VSHL.I32 $dst.D,$src.D,$shift\t! logical left shift packed2I"
10668   %}
10669   ins_encode %{
10670     bool quad = false;
10671     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10672              quad);
10673   %}
10674   ins_pipe( ialu_reg_reg ); // FIXME
10675 %}
10676 
10677 instruct vsl4I_immI(vecX dst, vecX src, immI shift) %{
10678   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10679   match(Set dst (LShiftVI src (LShiftCntV shift)));
10680   size(4);
10681   ins_cost(DEFAULT_COST); // FIXME
10682   format %{
10683     "VSHL.I32 $dst.Q,$src.Q,$shift\t! logical left shift packed4I"
10684   %}
10685   ins_encode %{
10686     bool quad = true;
10687     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10688              quad);
10689   %}
10690   ins_pipe( ialu_reg_reg ); // FIXME
10691 %}
10692 
10693 // Longs vector logical left/right shift
10694 instruct vsl2L_reg(vecX dst, vecX src, vecX shift) %{
10695   predicate(n->as_Vector()->length() == 2);
10696   match(Set dst (LShiftVL src shift));
10697   match(Set dst (URShiftVL src shift));
10698   size(4*1);
10699   ins_cost(DEFAULT_COST*1); // FIXME
10700   expand %{
10701     vsh2L_reg(dst, src, shift);
10702   %}
10703 %}
10704 
10705 instruct vsl2L_immI(vecX dst, vecX src, immI shift) %{
10706   predicate(n->as_Vector()->length() == 2);
10707   match(Set dst (LShiftVL src (LShiftCntV shift)));
10708   size(4);
10709   ins_cost(DEFAULT_COST); // FIXME
10710   format %{
10711     "VSHL.I64 $dst.Q,$src.Q,$shift\t! logical left shift packed2L"
10712   %}
10713   ins_encode %{
10714     bool quad = true;
10715     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
10716              quad);
10717   %}
10718   ins_pipe( ialu_reg_reg ); // FIXME
10719 %}
10720 
10721 // ----------------------- LogicalRightShift -----------------------------------
10722 
10723 // Bytes/Shorts vector logical right shift produces incorrect Java result
10724 // for negative data because java code convert short value into int with
10725 // sign extension before a shift.
10726 
10727 // Chars vector logical right shift
10728 instruct vsrl4S_immI(vecD dst, vecD src, immI shift) %{
10729   predicate(n->as_Vector()->length() == 4);
10730   match(Set dst (URShiftVS src (RShiftCntV shift)));
10731   size(4);
10732   ins_cost(DEFAULT_COST); // FIXME
10733   format %{
10734     "VSHR.U16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
10735   %}
10736   ins_encode %{
10737     bool quad = false;
10738     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10739              quad);
10740   %}
10741   ins_pipe( ialu_reg_reg ); // FIXME
10742 %}
10743 
10744 instruct vsrl8S_immI(vecX dst, vecX src, immI shift) %{
10745   predicate(n->as_Vector()->length() == 8);
10746   match(Set dst (URShiftVS src (RShiftCntV shift)));
10747   size(4);
10748   ins_cost(DEFAULT_COST); // FIXME
10749   format %{
10750     "VSHR.U16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
10751   %}
10752   ins_encode %{
10753     bool quad = true;
10754     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10755              quad);
10756   %}
10757   ins_pipe( ialu_reg_reg ); // FIXME
10758 %}
10759 
10760 // Integers vector logical right shift
10761 instruct vsrl2I_immI(vecD dst, vecD src, immI shift) %{
10762   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10763   match(Set dst (URShiftVI src (RShiftCntV shift)));
10764   size(4);
10765   ins_cost(DEFAULT_COST); // FIXME
10766   format %{
10767     "VSHR.U32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
10768   %}
10769   ins_encode %{
10770     bool quad = false;
10771     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10772              quad);
10773   %}
10774   ins_pipe( ialu_reg_reg ); // FIXME
10775 %}
10776 
10777 instruct vsrl4I_immI(vecX dst, vecX src, immI shift) %{
10778   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10779   match(Set dst (URShiftVI src (RShiftCntV shift)));
10780   size(4);
10781   ins_cost(DEFAULT_COST); // FIXME
10782   format %{
10783     "VSHR.U32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
10784   %}
10785   ins_encode %{
10786     bool quad = true;
10787     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10788              quad);
10789   %}
10790   ins_pipe( ialu_reg_reg ); // FIXME
10791 %}
10792 
10793 // Longs vector logical right shift
10794 instruct vsrl2L_immI(vecX dst, vecX src, immI shift) %{
10795   predicate(n->as_Vector()->length() == 2);
10796   match(Set dst (URShiftVL src (RShiftCntV shift)));
10797   size(4);
10798   ins_cost(DEFAULT_COST); // FIXME
10799   format %{
10800     "VSHR.U64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
10801   %}
10802   ins_encode %{
10803     bool quad = true;
10804     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
10805              quad);
10806   %}
10807   ins_pipe( ialu_reg_reg ); // FIXME
10808 %}
10809 
10810 // ------------------- ArithmeticRightShift -----------------------------------
10811 
10812 // Bytes vector arithmetic left/right shift based on sign
10813 instruct vsha8B_reg(vecD dst, vecD src, vecD shift) %{
10814   predicate(n->as_Vector()->length() == 8);
10815   effect(DEF dst, USE src, USE shift);
10816   size(4);
10817   ins_cost(DEFAULT_COST); // FIXME
10818   format %{
10819     "VSHL.S8 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed8B"
10820   %}
10821   ins_encode %{
10822     bool quad = false;
10823     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10824               MacroAssembler::VELEM_SIZE_8, quad);
10825   %}
10826   ins_pipe( ialu_reg_reg ); // FIXME
10827 %}
10828 
10829 instruct vsha16B_reg(vecX dst, vecX src, vecX shift) %{
10830   predicate(n->as_Vector()->length() == 16);
10831   effect(DEF dst, USE src, USE shift);
10832   size(4);
10833   ins_cost(DEFAULT_COST); // FIXME
10834   format %{
10835     "VSHL.S8 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed16B"
10836   %}
10837   ins_encode %{
10838     bool quad = true;
10839     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10840               MacroAssembler::VELEM_SIZE_8, quad);
10841   %}
10842   ins_pipe( ialu_reg_reg ); // FIXME
10843 %}
10844 
10845 // Shorts vector arithmetic left/right shift based on sign
10846 instruct vsha4S_reg(vecD dst, vecD src, vecD shift) %{
10847   predicate(n->as_Vector()->length() == 4);
10848   effect(DEF dst, USE src, USE shift);
10849   size(4);
10850   ins_cost(DEFAULT_COST); // FIXME
10851   format %{
10852     "VSHL.S16 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed4S"
10853   %}
10854   ins_encode %{
10855     bool quad = false;
10856     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10857               MacroAssembler::VELEM_SIZE_16, quad);
10858   %}
10859   ins_pipe( ialu_reg_reg ); // FIXME
10860 %}
10861 
10862 instruct vsha8S_reg(vecX dst, vecX src, vecX shift) %{
10863   predicate(n->as_Vector()->length() == 8);
10864   effect(DEF dst, USE src, USE shift);
10865   size(4);
10866   ins_cost(DEFAULT_COST); // FIXME
10867   format %{
10868     "VSHL.S16 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed8S"
10869   %}
10870   ins_encode %{
10871     bool quad = true;
10872     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10873               MacroAssembler::VELEM_SIZE_16, quad);
10874   %}
10875   ins_pipe( ialu_reg_reg ); // FIXME
10876 %}
10877 
10878 // Integers vector arithmetic left/right shift based on sign
10879 instruct vsha2I_reg(vecD dst, vecD src, vecD shift) %{
10880   predicate(n->as_Vector()->length() == 2);
10881   effect(DEF dst, USE src, USE shift);
10882   size(4);
10883   ins_cost(DEFAULT_COST); // FIXME
10884   format %{
10885     "VSHL.S32 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed2I"
10886   %}
10887   ins_encode %{
10888     bool quad = false;
10889     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10890               MacroAssembler::VELEM_SIZE_32, quad);
10891   %}
10892   ins_pipe( ialu_reg_reg ); // FIXME
10893 %}
10894 
10895 instruct vsha4I_reg(vecX dst, vecX src, vecX shift) %{
10896   predicate(n->as_Vector()->length() == 4);
10897   effect(DEF dst, USE src, USE shift);
10898   size(4);
10899   ins_cost(DEFAULT_COST); // FIXME
10900   format %{
10901     "VSHL.S32 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed4I"
10902   %}
10903   ins_encode %{
10904     bool quad = true;
10905     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10906               MacroAssembler::VELEM_SIZE_32, quad);
10907   %}
10908   ins_pipe( ialu_reg_reg ); // FIXME
10909 %}
10910 
10911 // Longs vector arithmetic left/right shift based on sign
10912 instruct vsha2L_reg(vecX dst, vecX src, vecX shift) %{
10913   predicate(n->as_Vector()->length() == 2);
10914   effect(DEF dst, USE src, USE shift);
10915   size(4);
10916   ins_cost(DEFAULT_COST); // FIXME
10917   format %{
10918     "VSHL.S64 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed2L"
10919   %}
10920   ins_encode %{
10921     bool quad = true;
10922     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10923               MacroAssembler::VELEM_SIZE_64, quad);
10924   %}
10925   ins_pipe( ialu_reg_reg ); // FIXME
10926 %}
10927 
10928 // Byte vector arithmetic right shift
10929 
10930 instruct vsra8B_reg(vecD dst, vecD src, vecD shift) %{
10931   predicate(n->as_Vector()->length() == 8);
10932   match(Set dst (RShiftVB src shift));
10933   size(4);
10934   ins_cost(DEFAULT_COST); // FIXME
10935   expand %{
10936     vsha8B_reg(dst, src, shift);
10937   %}
10938 %}
10939 
10940 instruct vsrl16B_reg(vecX dst, vecX src, vecX shift) %{
10941   predicate(n->as_Vector()->length() == 16);
10942   match(Set dst (RShiftVB src shift));
10943   size(4);
10944   ins_cost(DEFAULT_COST); // FIXME
10945   expand %{
10946     vsha16B_reg(dst, src, shift);
10947   %}
10948 %}
10949 
10950 instruct vsrl8B_immI(vecD dst, vecD src, immI shift) %{
10951   predicate(n->as_Vector()->length() == 8);
10952   match(Set dst (RShiftVB src shift));
10953   size(4);
10954   ins_cost(DEFAULT_COST); // FIXME
10955   format %{
10956     "VSHR.S8 $dst.D,$src.D,$shift\t! logical right shift packed8B"
10957   %}
10958   ins_encode %{
10959     bool quad = false;
10960     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10961              quad);
10962   %}
10963   ins_pipe( ialu_reg_reg ); // FIXME
10964 %}
10965 
10966 instruct vsrl16B_immI(vecX dst, vecX src, immI shift) %{
10967   predicate(n->as_Vector()->length() == 16);
10968   match(Set dst (RShiftVB src shift));
10969   size(4);
10970   ins_cost(DEFAULT_COST); // FIXME
10971   format %{
10972     "VSHR.S8 $dst.Q,$src.Q,$shift\t! logical right shift packed16B"
10973   %}
10974   ins_encode %{
10975     bool quad = true;
10976     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10977              quad);
10978   %}
10979   ins_pipe( ialu_reg_reg ); // FIXME
10980 %}
10981 
10982 // Shorts vector arithmetic right shift
10983 instruct vsra4S_reg(vecD dst, vecD src, vecD shift) %{
10984   predicate(n->as_Vector()->length() == 4);
10985   match(Set dst (RShiftVS src shift));
10986   size(4);
10987   ins_cost(DEFAULT_COST); // FIXME
10988   expand %{
10989     vsha4S_reg(dst, src, shift);
10990   %}
10991 %}
10992 
10993 instruct vsra8S_reg(vecX dst, vecX src, vecX shift) %{
10994   predicate(n->as_Vector()->length() == 8);
10995   match(Set dst (RShiftVS src shift));
10996   size(4);
10997   ins_cost(DEFAULT_COST); // FIXME
10998   expand %{
10999     vsha8S_reg(dst, src, shift);
11000   %}
11001 %}
11002 
11003 instruct vsra4S_immI(vecD dst, vecD src, immI shift) %{
11004   predicate(n->as_Vector()->length() == 4);
11005   match(Set dst (RShiftVS src shift));
11006   size(4);
11007   ins_cost(DEFAULT_COST); // FIXME
11008   format %{
11009     "VSHR.S16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
11010   %}
11011   ins_encode %{
11012     bool quad = false;
11013     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
11014              quad);
11015   %}
11016   ins_pipe( ialu_reg_reg ); // FIXME
11017 %}
11018 
11019 instruct vsra8S_immI(vecX dst, vecX src, immI shift) %{
11020   predicate(n->as_Vector()->length() == 8);
11021   match(Set dst (RShiftVS src shift));
11022   size(4);
11023   ins_cost(DEFAULT_COST); // FIXME
11024   format %{
11025     "VSHR.S16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
11026   %}
11027   ins_encode %{
11028     bool quad = true;
11029     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
11030              quad);
11031   %}
11032   ins_pipe( ialu_reg_reg ); // FIXME
11033 %}
11034 
11035 // Integers vector arithmetic right shift
11036 instruct vsra2I_reg(vecD dst, vecD src, vecD shift) %{
11037   predicate(n->as_Vector()->length() == 2);
11038   match(Set dst (RShiftVI src shift));
11039   size(4);
11040   ins_cost(DEFAULT_COST); // FIXME
11041   expand %{
11042     vsha2I_reg(dst, src, shift);
11043   %}
11044 %}
11045 
11046 instruct vsra4I_reg(vecX dst, vecX src, vecX shift) %{
11047   predicate(n->as_Vector()->length() == 4);
11048   match(Set dst (RShiftVI src shift));
11049   size(4);
11050   ins_cost(DEFAULT_COST); // FIXME
11051   expand %{
11052     vsha4I_reg(dst, src, shift);
11053   %}
11054 %}
11055 
11056 instruct vsra2I_immI(vecD dst, vecD src, immI shift) %{
11057   predicate(n->as_Vector()->length() == 2);
11058   match(Set dst (RShiftVI src shift));
11059   size(4);
11060   ins_cost(DEFAULT_COST); // FIXME
11061   format %{
11062     "VSHR.S32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
11063   %}
11064   ins_encode %{
11065     bool quad = false;
11066     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11067              quad);
11068   %}
11069   ins_pipe( ialu_reg_reg ); // FIXME
11070 %}
11071 
11072 instruct vsra4I_immI(vecX dst, vecX src, immI shift) %{
11073   predicate(n->as_Vector()->length() == 4);
11074   match(Set dst (RShiftVI src shift));
11075   size(4);
11076   ins_cost(DEFAULT_COST); // FIXME
11077   format %{
11078     "VSHR.S32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
11079   %}
11080   ins_encode %{
11081     bool quad = true;
11082     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11083              quad);
11084   %}
11085   ins_pipe( ialu_reg_reg ); // FIXME
11086 %}
11087 
11088 // Longs vector arithmetic right shift
11089 instruct vsra2L_reg(vecX dst, vecX src, vecX shift) %{
11090   predicate(n->as_Vector()->length() == 2);
11091   match(Set dst (RShiftVL src shift));
11092   size(4);
11093   ins_cost(DEFAULT_COST); // FIXME
11094   expand %{
11095     vsha2L_reg(dst, src, shift);
11096   %}
11097 %}
11098 
11099 instruct vsra2L_immI(vecX dst, vecX src, immI shift) %{
11100   predicate(n->as_Vector()->length() == 2);
11101   match(Set dst (RShiftVL src shift));
11102   size(4);
11103   ins_cost(DEFAULT_COST); // FIXME
11104   format %{
11105     "VSHR.S64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
11106   %}
11107   ins_encode %{
11108     bool quad = true;
11109     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
11110              quad);
11111   %}
11112   ins_pipe( ialu_reg_reg ); // FIXME
11113 %}
11114 
11115 // --------------------------------- AND --------------------------------------
11116 
11117 instruct vandD(vecD dst, vecD src1, vecD src2) %{
11118   predicate(n->as_Vector()->length_in_bytes() == 8);
11119   match(Set dst (AndV src1 src2));
11120   format %{ "VAND    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11121   ins_encode %{
11122     bool quad = false;
11123     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11124              quad);
11125   %}
11126   ins_pipe( ialu_reg_reg ); // FIXME
11127 %}
11128 
11129 instruct vandX(vecX dst, vecX src1, vecX src2) %{
11130   predicate(n->as_Vector()->length_in_bytes() == 16);
11131   match(Set dst (AndV src1 src2));
11132   format %{ "VAND    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11133   ins_encode %{
11134     bool quad = true;
11135     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11136              quad);
11137   %}
11138   ins_pipe( ialu_reg_reg ); // FIXME
11139 %}
11140 
11141 // --------------------------------- OR ---------------------------------------
11142 
11143 instruct vorD(vecD dst, vecD src1, vecD src2) %{
11144   predicate(n->as_Vector()->length_in_bytes() == 8);
11145   match(Set dst (OrV src1 src2));
11146   format %{ "VOR     $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11147   ins_encode %{
11148     bool quad = false;
11149     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11150             quad);
11151   %}
11152   ins_pipe( ialu_reg_reg ); // FIXME
11153 %}
11154 
11155 instruct vorX(vecX dst, vecX src1, vecX src2) %{
11156   predicate(n->as_Vector()->length_in_bytes() == 16);
11157   match(Set dst (OrV src1 src2));
11158   format %{ "VOR     $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11159   ins_encode %{
11160     bool quad = true;
11161     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11162             quad);
11163   %}
11164   ins_pipe( ialu_reg_reg ); // FIXME
11165 %}
11166 
11167 // --------------------------------- XOR --------------------------------------
11168 
11169 instruct vxorD(vecD dst, vecD src1, vecD src2) %{
11170   predicate(n->as_Vector()->length_in_bytes() == 8);
11171   match(Set dst (XorV src1 src2));
11172   format %{ "VXOR    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11173   ins_encode %{
11174     bool quad = false;
11175     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11176              quad);
11177   %}
11178   ins_pipe( ialu_reg_reg ); // FIXME
11179 %}
11180 
11181 instruct vxorX(vecX dst, vecX src1, vecX src2) %{
11182   predicate(n->as_Vector()->length_in_bytes() == 16);
11183   match(Set dst (XorV src1 src2));
11184   format %{ "VXOR    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11185   ins_encode %{
11186     bool quad = true;
11187     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11188              quad);
11189   %}
11190   ins_pipe( ialu_reg_reg ); // FIXME
11191 %}
11192 
11193 
11194 //----------PEEPHOLE RULES-----------------------------------------------------
11195 // These must follow all instruction definitions as they use the names
11196 // defined in the instructions definitions.
11197 //
11198 // peepmatch ( root_instr_name [preceding_instruction]* );
11199 //
11200 // peepconstraint %{
11201 // (instruction_number.operand_name relational_op instruction_number.operand_name
11202 //  [, ...] );
11203 // // instruction numbers are zero-based using left to right order in peepmatch
11204 //
11205 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
11206 // // provide an instruction_number.operand_name for each operand that appears
11207 // // in the replacement instruction's match rule
11208 //
11209 // ---------VM FLAGS---------------------------------------------------------
11210 //
11211 // All peephole optimizations can be turned off using -XX:-OptoPeephole
11212 //
11213 // Each peephole rule is given an identifying number starting with zero and
11214 // increasing by one in the order seen by the parser.  An individual peephole
11215 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
11216 // on the command-line.
11217 //
11218 // ---------CURRENT LIMITATIONS----------------------------------------------
11219 //
11220 // Only match adjacent instructions in same basic block
11221 // Only equality constraints
11222 // Only constraints between operands, not (0.dest_reg == EAX_enc)
11223 // Only one replacement instruction
11224 //
11225 // ---------EXAMPLE----------------------------------------------------------
11226 //
11227 // // pertinent parts of existing instructions in architecture description
11228 // instruct movI(eRegI dst, eRegI src) %{
11229 //   match(Set dst (CopyI src));
11230 // %}
11231 //
11232 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
11233 //   match(Set dst (AddI dst src));
11234 //   effect(KILL cr);
11235 // %}
11236 //
11237 // // Change (inc mov) to lea
11238 // peephole %{
11239 //   // increment preceeded by register-register move
11240 //   peepmatch ( incI_eReg movI );
11241 //   // require that the destination register of the increment
11242 //   // match the destination register of the move
11243 //   peepconstraint ( 0.dst == 1.dst );
11244 //   // construct a replacement instruction that sets
11245 //   // the destination to ( move's source register + one )
11246 //   peepreplace ( incI_eReg_immI1( 0.dst 1.src 0.src ) );
11247 // %}
11248 //
11249 
11250 // // Change load of spilled value to only a spill
11251 // instruct storeI(memory mem, eRegI src) %{
11252 //   match(Set mem (StoreI mem src));
11253 // %}
11254 //
11255 // instruct loadI(eRegI dst, memory mem) %{
11256 //   match(Set dst (LoadI mem));
11257 // %}
11258 //
11259 // peephole %{
11260 //   peepmatch ( loadI storeI );
11261 //   peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
11262 //   peepreplace ( storeI( 1.mem 1.mem 1.src ) );
11263 // %}
11264 
11265 //----------SMARTSPILL RULES---------------------------------------------------
11266 // These must follow all instruction definitions as they use the names
11267 // defined in the instructions definitions.
11268 //
11269 // ARM will probably not have any of these rules due to RISC instruction set.
11270 
11271 //----------PIPELINE-----------------------------------------------------------
11272 // Rules which define the behavior of the target architectures pipeline.