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 RegMask* Matcher::predicate_reg_mask(void) {
  987   return NULL;
  988 }
  989 
  990 const TypeVect* Matcher::predicate_reg_type(const Type* elemTy, int length) {
  991   return NULL;
  992 }
  993 
  994 // Vector calling convention not yet implemented.
  995 const bool Matcher::supports_vector_calling_convention(void) {
  996   return false;
  997 }
  998 
  999 OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
 1000   Unimplemented();
 1001   return OptoRegPair(0, 0);
 1002 }
 1003 
 1004 // Vector width in bytes
 1005 const int Matcher::vector_width_in_bytes(BasicType bt) {
 1006   return MaxVectorSize;
 1007 }
 1008 
 1009 const int Matcher::scalable_vector_reg_size(const BasicType bt) {
 1010   return -1;
 1011 }
 1012 
 1013 // Vector ideal reg corresponding to specified size in bytes
 1014 const uint Matcher::vector_ideal_reg(int size) {
 1015   assert(MaxVectorSize >= size, "");
 1016   switch(size) {
 1017     case  8: return Op_VecD;
 1018     case 16: return Op_VecX;
 1019   }
 1020   ShouldNotReachHere();
 1021   return 0;
 1022 }
 1023 
 1024 // Limits on vector size (number of elements) loaded into vector.
 1025 const int Matcher::max_vector_size(const BasicType bt) {
 1026   assert(is_java_primitive(bt), "only primitive type vectors");
 1027   return vector_width_in_bytes(bt)/type2aelembytes(bt);
 1028 }
 1029 
 1030 const int Matcher::min_vector_size(const BasicType bt) {
 1031   assert(is_java_primitive(bt), "only primitive type vectors");
 1032   return 8/type2aelembytes(bt);
 1033 }
 1034 
 1035 // Is this branch offset short enough that a short branch can be used?
 1036 //
 1037 // NOTE: If the platform does not provide any short branch variants, then
 1038 //       this method should return false for offset 0.
 1039 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
 1040   // The passed offset is relative to address of the branch.
 1041   // On ARM a branch displacement is calculated relative to address
 1042   // of the branch + 8.
 1043   //
 1044   // offset -= 8;
 1045   // return (Assembler::is_simm24(offset));
 1046   return false;
 1047 }
 1048 
 1049 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) {
 1050   ShouldNotReachHere(); // generic vector operands not supported
 1051   return NULL;
 1052 }
 1053 
 1054 bool Matcher::is_reg2reg_move(MachNode* m) {
 1055   ShouldNotReachHere();  // generic vector operands not supported
 1056   return false;
 1057 }
 1058 
 1059 bool Matcher::is_generic_vector(MachOper* opnd)  {
 1060   ShouldNotReachHere();  // generic vector operands not supported
 1061   return false;
 1062 }
 1063 
 1064 // Should the matcher clone input 'm' of node 'n'?
 1065 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
 1066   if (is_vshift_con_pattern(n, m)) { // ShiftV src (ShiftCntV con)
 1067     mstack.push(m, Visit);           // m = ShiftCntV
 1068     return true;
 1069   }
 1070   return false;
 1071 }
 1072 
 1073 // Should the Matcher clone shifts on addressing modes, expecting them
 1074 // to be subsumed into complex addressing expressions or compute them
 1075 // into registers?
 1076 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
 1077   return clone_base_plus_offset_address(m, mstack, address_visited);
 1078 }
 1079 
 1080 // Return whether or not this register is ever used as an argument.  This
 1081 // function is used on startup to build the trampoline stubs in generateOptoStub.
 1082 // Registers not mentioned will be killed by the VM call in the trampoline, and
 1083 // arguments in those registers not be available to the callee.
 1084 bool Matcher::can_be_java_arg( int reg ) {
 1085   if (reg == R_R0_num ||
 1086       reg == R_R1_num ||
 1087       reg == R_R2_num ||
 1088       reg == R_R3_num) return true;
 1089 
 1090   if (reg >= R_S0_num &&
 1091       reg <= R_S13_num) return true;
 1092   return false;
 1093 }
 1094 
 1095 bool Matcher::is_spillable_arg( int reg ) {
 1096   return can_be_java_arg(reg);
 1097 }
 1098 
 1099 uint Matcher::int_pressure_limit()
 1100 {
 1101   return (INTPRESSURE == -1) ? 12 : INTPRESSURE;
 1102 }
 1103 
 1104 uint Matcher::float_pressure_limit()
 1105 {
 1106   return (FLOATPRESSURE == -1) ? 30 : FLOATPRESSURE;
 1107 }
 1108 
 1109 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
 1110   return false;
 1111 }
 1112 
 1113 // Register for DIVI projection of divmodI
 1114 RegMask Matcher::divI_proj_mask() {
 1115   ShouldNotReachHere();
 1116   return RegMask();
 1117 }
 1118 
 1119 // Register for MODI projection of divmodI
 1120 RegMask Matcher::modI_proj_mask() {
 1121   ShouldNotReachHere();
 1122   return RegMask();
 1123 }
 1124 
 1125 // Register for DIVL projection of divmodL
 1126 RegMask Matcher::divL_proj_mask() {
 1127   ShouldNotReachHere();
 1128   return RegMask();
 1129 }
 1130 
 1131 // Register for MODL projection of divmodL
 1132 RegMask Matcher::modL_proj_mask() {
 1133   ShouldNotReachHere();
 1134   return RegMask();
 1135 }
 1136 
 1137 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
 1138   return FP_REGP_mask();
 1139 }
 1140 
 1141 bool maybe_far_call(const CallNode *n) {
 1142   return !MacroAssembler::_reachable_from_cache(n->as_Call()->entry_point());
 1143 }
 1144 
 1145 bool maybe_far_call(const MachCallNode *n) {
 1146   return !MacroAssembler::_reachable_from_cache(n->as_MachCall()->entry_point());
 1147 }
 1148 
 1149 %}
 1150 
 1151 //----------ENCODING BLOCK-----------------------------------------------------
 1152 // This block specifies the encoding classes used by the compiler to output
 1153 // byte streams.  Encoding classes are parameterized macros used by
 1154 // Machine Instruction Nodes in order to generate the bit encoding of the
 1155 // instruction.  Operands specify their base encoding interface with the
 1156 // interface keyword.  There are currently supported four interfaces,
 1157 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
 1158 // operand to generate a function which returns its register number when
 1159 // queried.   CONST_INTER causes an operand to generate a function which
 1160 // returns the value of the constant when queried.  MEMORY_INTER causes an
 1161 // operand to generate four functions which return the Base Register, the
 1162 // Index Register, the Scale Value, and the Offset Value of the operand when
 1163 // queried.  COND_INTER causes an operand to generate six functions which
 1164 // return the encoding code (ie - encoding bits for the instruction)
 1165 // associated with each basic boolean condition for a conditional instruction.
 1166 //
 1167 // Instructions specify two basic values for encoding.  Again, a function
 1168 // is available to check if the constant displacement is an oop. They use the
 1169 // ins_encode keyword to specify their encoding classes (which must be
 1170 // a sequence of enc_class names, and their parameters, specified in
 1171 // the encoding block), and they use the
 1172 // opcode keyword to specify, in order, their primary, secondary, and
 1173 // tertiary opcode.  Only the opcode sections which a particular instruction
 1174 // needs for encoding need to be specified.
 1175 encode %{
 1176   enc_class call_epilog %{
 1177     // nothing
 1178   %}
 1179 
 1180   enc_class Java_To_Runtime (method meth) %{
 1181     // CALL directly to the runtime
 1182     emit_call_reloc(cbuf, as_MachCall(), $meth, runtime_call_Relocation::spec());
 1183   %}
 1184 
 1185   enc_class Java_Static_Call (method meth) %{
 1186     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
 1187     // who we intended to call.
 1188 
 1189     if ( !_method) {
 1190       emit_call_reloc(cbuf, as_MachCall(), $meth, runtime_call_Relocation::spec());
 1191     } else {
 1192       int method_index = resolved_method_index(cbuf);
 1193       RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
 1194                                                   : static_call_Relocation::spec(method_index);
 1195       emit_call_reloc(cbuf, as_MachCall(), $meth, rspec);
 1196 
 1197       // Emit stubs for static call.
 1198       address stub = CompiledStaticCall::emit_to_interp_stub(cbuf);
 1199       if (stub == NULL) {
 1200         ciEnv::current()->record_failure("CodeCache is full");
 1201         return;
 1202       }
 1203     }
 1204   %}
 1205 
 1206   enc_class save_last_PC %{
 1207     // preserve mark
 1208     address mark = cbuf.insts()->mark();
 1209     debug_only(int off0 = cbuf.insts_size());
 1210     C2_MacroAssembler _masm(&cbuf);
 1211     int ret_addr_offset = as_MachCall()->ret_addr_offset();
 1212     __ adr(LR, mark + ret_addr_offset);
 1213     __ str(LR, Address(Rthread, JavaThread::last_Java_pc_offset()));
 1214     debug_only(int off1 = cbuf.insts_size());
 1215     assert(off1 - off0 == 2 * Assembler::InstructionSize, "correct size prediction");
 1216     // restore mark
 1217     cbuf.insts()->set_mark(mark);
 1218   %}
 1219 
 1220   enc_class preserve_SP %{
 1221     // preserve mark
 1222     address mark = cbuf.insts()->mark();
 1223     debug_only(int off0 = cbuf.insts_size());
 1224     C2_MacroAssembler _masm(&cbuf);
 1225     // FP is preserved across all calls, even compiled calls.
 1226     // Use it to preserve SP in places where the callee might change the SP.
 1227     __ mov(Rmh_SP_save, SP);
 1228     debug_only(int off1 = cbuf.insts_size());
 1229     assert(off1 - off0 == 4, "correct size prediction");
 1230     // restore mark
 1231     cbuf.insts()->set_mark(mark);
 1232   %}
 1233 
 1234   enc_class restore_SP %{
 1235     C2_MacroAssembler _masm(&cbuf);
 1236     __ mov(SP, Rmh_SP_save);
 1237   %}
 1238 
 1239   enc_class Java_Dynamic_Call (method meth) %{
 1240     C2_MacroAssembler _masm(&cbuf);
 1241     Register R8_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode());
 1242     assert(R8_ic_reg == Ricklass, "should be");
 1243     __ set_inst_mark();
 1244     __ movw(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) & 0xffff);
 1245     __ movt(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) >> 16);
 1246     address  virtual_call_oop_addr = __ inst_mark();
 1247     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
 1248     // who we intended to call.
 1249     int method_index = resolved_method_index(cbuf);
 1250     __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index));
 1251     emit_call_reloc(cbuf, as_MachCall(), $meth, RelocationHolder::none);
 1252   %}
 1253 
 1254   enc_class LdReplImmI(immI src, regD dst, iRegI tmp, int cnt, int wth) %{
 1255     // FIXME: load from constant table?
 1256     // Load a constant replicated "count" times with width "width"
 1257     int count = $cnt$$constant;
 1258     int width = $wth$$constant;
 1259     assert(count*width == 4, "sanity");
 1260     int val = $src$$constant;
 1261     if (width < 4) {
 1262       int bit_width = width * 8;
 1263       val &= (((int)1) << bit_width) - 1; // mask off sign bits
 1264       for (int i = 0; i < count - 1; i++) {
 1265         val |= (val << bit_width);
 1266       }
 1267     }
 1268     C2_MacroAssembler _masm(&cbuf);
 1269 
 1270     if (val == -1) {
 1271       __ mvn($tmp$$Register, 0);
 1272     } else if (val == 0) {
 1273       __ mov($tmp$$Register, 0);
 1274     } else {
 1275       __ movw($tmp$$Register, val & 0xffff);
 1276       __ movt($tmp$$Register, (unsigned int)val >> 16);
 1277     }
 1278     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 1279   %}
 1280 
 1281   enc_class LdReplImmF(immF src, regD dst, iRegI tmp) %{
 1282     // Replicate float con 2 times and pack into vector (8 bytes) in regD.
 1283     float fval = $src$$constant;
 1284     int val = *((int*)&fval);
 1285     C2_MacroAssembler _masm(&cbuf);
 1286 
 1287     if (val == -1) {
 1288       __ mvn($tmp$$Register, 0);
 1289     } else if (val == 0) {
 1290       __ mov($tmp$$Register, 0);
 1291     } else {
 1292       __ movw($tmp$$Register, val & 0xffff);
 1293       __ movt($tmp$$Register, (unsigned int)val >> 16);
 1294     }
 1295     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 1296   %}
 1297 
 1298   enc_class enc_String_Compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result, iRegI tmp1, iRegI tmp2) %{
 1299     Label Ldone, Lloop;
 1300     C2_MacroAssembler _masm(&cbuf);
 1301 
 1302     Register   str1_reg = $str1$$Register;
 1303     Register   str2_reg = $str2$$Register;
 1304     Register   cnt1_reg = $cnt1$$Register; // int
 1305     Register   cnt2_reg = $cnt2$$Register; // int
 1306     Register   tmp1_reg = $tmp1$$Register;
 1307     Register   tmp2_reg = $tmp2$$Register;
 1308     Register result_reg = $result$$Register;
 1309 
 1310     assert_different_registers(str1_reg, str2_reg, cnt1_reg, cnt2_reg, tmp1_reg, tmp2_reg);
 1311 
 1312     // Compute the minimum of the string lengths(str1_reg) and the
 1313     // difference of the string lengths (stack)
 1314 
 1315     // See if the lengths are different, and calculate min in str1_reg.
 1316     // Stash diff in tmp2 in case we need it for a tie-breaker.
 1317     __ subs_32(tmp2_reg, cnt1_reg, cnt2_reg);
 1318     __ mov(cnt1_reg, AsmOperand(cnt1_reg, lsl, exact_log2(sizeof(jchar)))); // scale the limit
 1319     __ mov(cnt1_reg, AsmOperand(cnt2_reg, lsl, exact_log2(sizeof(jchar))), pl); // scale the limit
 1320 
 1321     // reallocate cnt1_reg, cnt2_reg, result_reg
 1322     // Note:  limit_reg holds the string length pre-scaled by 2
 1323     Register limit_reg = cnt1_reg;
 1324     Register  chr2_reg = cnt2_reg;
 1325     Register  chr1_reg = tmp1_reg;
 1326     // str{12} are the base pointers
 1327 
 1328     // Is the minimum length zero?
 1329     __ cmp_32(limit_reg, 0);
 1330     if (result_reg != tmp2_reg) {
 1331       __ mov(result_reg, tmp2_reg, eq);
 1332     }
 1333     __ b(Ldone, eq);
 1334 
 1335     // Load first characters
 1336     __ ldrh(chr1_reg, Address(str1_reg, 0));
 1337     __ ldrh(chr2_reg, Address(str2_reg, 0));
 1338 
 1339     // Compare first characters
 1340     __ subs(chr1_reg, chr1_reg, chr2_reg);
 1341     if (result_reg != chr1_reg) {
 1342       __ mov(result_reg, chr1_reg, ne);
 1343     }
 1344     __ b(Ldone, ne);
 1345 
 1346     {
 1347       // Check after comparing first character to see if strings are equivalent
 1348       // Check if the strings start at same location
 1349       __ cmp(str1_reg, str2_reg);
 1350       // Check if the length difference is zero
 1351       __ cond_cmp(tmp2_reg, 0, eq);
 1352       __ mov(result_reg, 0, eq); // result is zero
 1353       __ b(Ldone, eq);
 1354       // Strings might not be equal
 1355     }
 1356 
 1357     __ subs(chr1_reg, limit_reg, 1 * sizeof(jchar));
 1358     if (result_reg != tmp2_reg) {
 1359       __ mov(result_reg, tmp2_reg, eq);
 1360     }
 1361     __ b(Ldone, eq);
 1362 
 1363     // Shift str1_reg and str2_reg to the end of the arrays, negate limit
 1364     __ add(str1_reg, str1_reg, limit_reg);
 1365     __ add(str2_reg, str2_reg, limit_reg);
 1366     __ neg(limit_reg, chr1_reg);  // limit = -(limit-2)
 1367 
 1368     // Compare the rest of the characters
 1369     __ bind(Lloop);
 1370     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
 1371     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
 1372     __ subs(chr1_reg, chr1_reg, chr2_reg);
 1373     if (result_reg != chr1_reg) {
 1374       __ mov(result_reg, chr1_reg, ne);
 1375     }
 1376     __ b(Ldone, ne);
 1377 
 1378     __ adds(limit_reg, limit_reg, sizeof(jchar));
 1379     __ b(Lloop, ne);
 1380 
 1381     // If strings are equal up to min length, return the length difference.
 1382     if (result_reg != tmp2_reg) {
 1383       __ mov(result_reg, tmp2_reg);
 1384     }
 1385 
 1386     // Otherwise, return the difference between the first mismatched chars.
 1387     __ bind(Ldone);
 1388   %}
 1389 
 1390   enc_class enc_String_Equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2) %{
 1391     Label Lchar, Lchar_loop, Ldone, Lequal;
 1392     C2_MacroAssembler _masm(&cbuf);
 1393 
 1394     Register   str1_reg = $str1$$Register;
 1395     Register   str2_reg = $str2$$Register;
 1396     Register    cnt_reg = $cnt$$Register; // int
 1397     Register   tmp1_reg = $tmp1$$Register;
 1398     Register   tmp2_reg = $tmp2$$Register;
 1399     Register result_reg = $result$$Register;
 1400 
 1401     assert_different_registers(str1_reg, str2_reg, cnt_reg, tmp1_reg, tmp2_reg, result_reg);
 1402 
 1403     __ cmp(str1_reg, str2_reg); //same char[] ?
 1404     __ b(Lequal, eq);
 1405 
 1406     __ cbz_32(cnt_reg, Lequal); // count == 0
 1407 
 1408     //rename registers
 1409     Register limit_reg = cnt_reg;
 1410     Register  chr1_reg = tmp1_reg;
 1411     Register  chr2_reg = tmp2_reg;
 1412 
 1413     __ logical_shift_left(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
 1414 
 1415     //check for alignment and position the pointers to the ends
 1416     __ orr(chr1_reg, str1_reg, str2_reg);
 1417     __ tst(chr1_reg, 0x3);
 1418 
 1419     // notZero means at least one not 4-byte aligned.
 1420     // We could optimize the case when both arrays are not aligned
 1421     // but it is not frequent case and it requires additional checks.
 1422     __ b(Lchar, ne);
 1423 
 1424     // Compare char[] arrays aligned to 4 bytes.
 1425     __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg,
 1426                           chr1_reg, chr2_reg, Ldone);
 1427 
 1428     __ b(Lequal); // equal
 1429 
 1430     // char by char compare
 1431     __ bind(Lchar);
 1432     __ mov(result_reg, 0);
 1433     __ add(str1_reg, limit_reg, str1_reg);
 1434     __ add(str2_reg, limit_reg, str2_reg);
 1435     __ neg(limit_reg, limit_reg); //negate count
 1436 
 1437     // Lchar_loop
 1438     __ bind(Lchar_loop);
 1439     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
 1440     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
 1441     __ cmp(chr1_reg, chr2_reg);
 1442     __ b(Ldone, ne);
 1443     __ adds(limit_reg, limit_reg, sizeof(jchar));
 1444     __ b(Lchar_loop, ne);
 1445 
 1446     __ bind(Lequal);
 1447     __ mov(result_reg, 1);  //equal
 1448 
 1449     __ bind(Ldone);
 1450   %}
 1451 
 1452   enc_class enc_Array_Equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result) %{
 1453     Label Ldone, Lloop, Lequal;
 1454     C2_MacroAssembler _masm(&cbuf);
 1455 
 1456     Register   ary1_reg = $ary1$$Register;
 1457     Register   ary2_reg = $ary2$$Register;
 1458     Register   tmp1_reg = $tmp1$$Register;
 1459     Register   tmp2_reg = $tmp2$$Register;
 1460     Register   tmp3_reg = $tmp3$$Register;
 1461     Register result_reg = $result$$Register;
 1462 
 1463     assert_different_registers(ary1_reg, ary2_reg, tmp1_reg, tmp2_reg, tmp3_reg, result_reg);
 1464 
 1465     int length_offset  = arrayOopDesc::length_offset_in_bytes();
 1466     int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
 1467 
 1468     // return true if the same array
 1469     __ teq(ary1_reg, ary2_reg);
 1470     __ mov(result_reg, 1, eq);
 1471     __ b(Ldone, eq); // equal
 1472 
 1473     __ tst(ary1_reg, ary1_reg);
 1474     __ mov(result_reg, 0, eq);
 1475     __ b(Ldone, eq);    // not equal
 1476 
 1477     __ tst(ary2_reg, ary2_reg);
 1478     __ mov(result_reg, 0, eq);
 1479     __ b(Ldone, eq);    // not equal
 1480 
 1481     //load the lengths of arrays
 1482     __ ldr_s32(tmp1_reg, Address(ary1_reg, length_offset)); // int
 1483     __ ldr_s32(tmp2_reg, Address(ary2_reg, length_offset)); // int
 1484 
 1485     // return false if the two arrays are not equal length
 1486     __ teq_32(tmp1_reg, tmp2_reg);
 1487     __ mov(result_reg, 0, ne);
 1488     __ b(Ldone, ne);    // not equal
 1489 
 1490     __ tst(tmp1_reg, tmp1_reg);
 1491     __ mov(result_reg, 1, eq);
 1492     __ b(Ldone, eq);    // zero-length arrays are equal
 1493 
 1494     // load array addresses
 1495     __ add(ary1_reg, ary1_reg, base_offset);
 1496     __ add(ary2_reg, ary2_reg, base_offset);
 1497 
 1498     // renaming registers
 1499     Register chr1_reg  =  tmp3_reg;   // for characters in ary1
 1500     Register chr2_reg  =  tmp2_reg;   // for characters in ary2
 1501     Register limit_reg =  tmp1_reg;   // length
 1502 
 1503     // set byte count
 1504     __ logical_shift_left_32(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
 1505 
 1506     // Compare char[] arrays aligned to 4 bytes.
 1507     __ char_arrays_equals(ary1_reg, ary2_reg, limit_reg, result_reg,
 1508                           chr1_reg, chr2_reg, Ldone);
 1509     __ bind(Lequal);
 1510     __ mov(result_reg, 1);  //equal
 1511 
 1512     __ bind(Ldone);
 1513     %}
 1514 %}
 1515 
 1516 //----------FRAME--------------------------------------------------------------
 1517 // Definition of frame structure and management information.
 1518 //
 1519 //  S T A C K   L A Y O U T    Allocators stack-slot number
 1520 //                             |   (to get allocators register number
 1521 //  G  Owned by    |        |  v    add VMRegImpl::stack0)
 1522 //  r   CALLER     |        |
 1523 //  o     |        +--------+      pad to even-align allocators stack-slot
 1524 //  w     V        |  pad0  |        numbers; owned by CALLER
 1525 //  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
 1526 //  h     ^        |   in   |  5
 1527 //        |        |  args  |  4   Holes in incoming args owned by SELF
 1528 //  |     |        |        |  3
 1529 //  |     |        +--------+
 1530 //  V     |        | old out|      Empty on Intel, window on Sparc
 1531 //        |    old |preserve|      Must be even aligned.
 1532 //        |     SP-+--------+----> Matcher::_old_SP, 8 (or 16 in LP64)-byte aligned
 1533 //        |        |   in   |  3   area for Intel ret address
 1534 //     Owned by    |preserve|      Empty on Sparc.
 1535 //       SELF      +--------+
 1536 //        |        |  pad2  |  2   pad to align old SP
 1537 //        |        +--------+  1
 1538 //        |        | locks  |  0
 1539 //        |        +--------+----> VMRegImpl::stack0, 8 (or 16 in LP64)-byte aligned
 1540 //        |        |  pad1  | 11   pad to align new SP
 1541 //        |        +--------+
 1542 //        |        |        | 10
 1543 //        |        | spills |  9   spills
 1544 //        V        |        |  8   (pad0 slot for callee)
 1545 //      -----------+--------+----> Matcher::_out_arg_limit, unaligned
 1546 //        ^        |  out   |  7
 1547 //        |        |  args  |  6   Holes in outgoing args owned by CALLEE
 1548 //     Owned by    +--------+
 1549 //      CALLEE     | new out|  6   Empty on Intel, window on Sparc
 1550 //        |    new |preserve|      Must be even-aligned.
 1551 //        |     SP-+--------+----> Matcher::_new_SP, even aligned
 1552 //        |        |        |
 1553 //
 1554 // Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
 1555 //         known from SELF's arguments and the Java calling convention.
 1556 //         Region 6-7 is determined per call site.
 1557 // Note 2: If the calling convention leaves holes in the incoming argument
 1558 //         area, those holes are owned by SELF.  Holes in the outgoing area
 1559 //         are owned by the CALLEE.  Holes should not be nessecary in the
 1560 //         incoming area, as the Java calling convention is completely under
 1561 //         the control of the AD file.  Doubles can be sorted and packed to
 1562 //         avoid holes.  Holes in the outgoing arguments may be nessecary for
 1563 //         varargs C calling conventions.
 1564 // Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
 1565 //         even aligned with pad0 as needed.
 1566 //         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
 1567 //         region 6-11 is even aligned; it may be padded out more so that
 1568 //         the region from SP to FP meets the minimum stack alignment.
 1569 
 1570 frame %{
 1571   // These two registers define part of the calling convention
 1572   // between compiled code and the interpreter.
 1573   inline_cache_reg(R_Ricklass);          // Inline Cache Register or Method* for I2C
 1574 
 1575   // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
 1576   cisc_spilling_operand_name(indOffset);
 1577 
 1578   // Number of stack slots consumed by a Monitor enter
 1579   sync_stack_slots(1 * VMRegImpl::slots_per_word);
 1580 
 1581   // Compiled code's Frame Pointer
 1582   frame_pointer(R_R13);
 1583 
 1584   // Stack alignment requirement
 1585   stack_alignment(StackAlignmentInBytes);
 1586   //  LP64: Alignment size in bytes (128-bit -> 16 bytes)
 1587   // !LP64: Alignment size in bytes (64-bit  ->  8 bytes)
 1588 
 1589   // Number of outgoing stack slots killed above the out_preserve_stack_slots
 1590   // for calls to C.  Supports the var-args backing area for register parms.
 1591   // ADLC doesn't support parsing expressions, so I folded the math by hand.
 1592   varargs_C_out_slots_killed( 0);
 1593 
 1594   // The after-PROLOG location of the return address.  Location of
 1595   // return address specifies a type (REG or STACK) and a number
 1596   // representing the register number (i.e. - use a register name) or
 1597   // stack slot.
 1598   // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
 1599   // Otherwise, it is above the locks and verification slot and alignment word
 1600   return_addr(STACK - 1*VMRegImpl::slots_per_word +
 1601               align_up((Compile::current()->in_preserve_stack_slots() +
 1602                         Compile::current()->fixed_slots()),
 1603                        stack_alignment_in_slots()));
 1604 
 1605   // Location of compiled Java return values.  Same as C
 1606   return_value %{
 1607     return c2::return_value(ideal_reg);
 1608   %}
 1609 
 1610 %}
 1611 
 1612 //----------ATTRIBUTES---------------------------------------------------------
 1613 //----------Instruction Attributes---------------------------------------------
 1614 ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute
 1615 ins_attrib ins_size(32);           // Required size attribute (in bits)
 1616 ins_attrib ins_short_branch(0);    // Required flag: is this instruction a
 1617                                    // non-matching short branch variant of some
 1618                                                             // long branch?
 1619 
 1620 //----------OPERANDS-----------------------------------------------------------
 1621 // Operand definitions must precede instruction definitions for correct parsing
 1622 // in the ADLC because operands constitute user defined types which are used in
 1623 // instruction definitions.
 1624 
 1625 //----------Simple Operands----------------------------------------------------
 1626 // Immediate Operands
 1627 // Integer Immediate: 32-bit
 1628 operand immI() %{
 1629   match(ConI);
 1630 
 1631   op_cost(0);
 1632   // formats are generated automatically for constants and base registers
 1633   format %{ %}
 1634   interface(CONST_INTER);
 1635 %}
 1636 
 1637 // Integer Immediate: 8-bit unsigned - for VMOV
 1638 operand immU8() %{
 1639   predicate(0 <= n->get_int() && (n->get_int() <= 255));
 1640   match(ConI);
 1641   op_cost(0);
 1642 
 1643   format %{ %}
 1644   interface(CONST_INTER);
 1645 %}
 1646 
 1647 // Integer Immediate: 16-bit
 1648 operand immI16() %{
 1649   predicate((n->get_int() >> 16) == 0 && VM_Version::supports_movw());
 1650   match(ConI);
 1651   op_cost(0);
 1652 
 1653   format %{ %}
 1654   interface(CONST_INTER);
 1655 %}
 1656 
 1657 // Integer Immediate: offset for half and double word loads and stores
 1658 operand immIHD() %{
 1659   predicate(is_memoryHD(n->get_int()));
 1660   match(ConI);
 1661   op_cost(0);
 1662   format %{ %}
 1663   interface(CONST_INTER);
 1664 %}
 1665 
 1666 // Integer Immediate: offset for fp loads and stores
 1667 operand immIFP() %{
 1668   predicate(is_memoryfp(n->get_int()) && ((n->get_int() & 3) == 0));
 1669   match(ConI);
 1670   op_cost(0);
 1671 
 1672   format %{ %}
 1673   interface(CONST_INTER);
 1674 %}
 1675 
 1676 // Valid scale values for addressing modes and shifts
 1677 operand immU5() %{
 1678   predicate(0 <= n->get_int() && (n->get_int() <= 31));
 1679   match(ConI);
 1680   op_cost(0);
 1681 
 1682   format %{ %}
 1683   interface(CONST_INTER);
 1684 %}
 1685 
 1686 // Integer Immediate: 6-bit
 1687 operand immU6Big() %{
 1688   predicate(n->get_int() >= 32 && n->get_int() <= 63);
 1689   match(ConI);
 1690   op_cost(0);
 1691   format %{ %}
 1692   interface(CONST_INTER);
 1693 %}
 1694 
 1695 // Integer Immediate: 0-bit
 1696 operand immI0() %{
 1697   predicate(n->get_int() == 0);
 1698   match(ConI);
 1699   op_cost(0);
 1700 
 1701   format %{ %}
 1702   interface(CONST_INTER);
 1703 %}
 1704 
 1705 // Integer Immediate: the value 1
 1706 operand immI_1() %{
 1707   predicate(n->get_int() == 1);
 1708   match(ConI);
 1709   op_cost(0);
 1710 
 1711   format %{ %}
 1712   interface(CONST_INTER);
 1713 %}
 1714 
 1715 // Integer Immediate: the value 2
 1716 operand immI_2() %{
 1717   predicate(n->get_int() == 2);
 1718   match(ConI);
 1719   op_cost(0);
 1720 
 1721   format %{ %}
 1722   interface(CONST_INTER);
 1723 %}
 1724 
 1725 // Integer Immediate: the value 3
 1726 operand immI_3() %{
 1727   predicate(n->get_int() == 3);
 1728   match(ConI);
 1729   op_cost(0);
 1730 
 1731   format %{ %}
 1732   interface(CONST_INTER);
 1733 %}
 1734 
 1735 // Integer Immediate: the value 4
 1736 operand immI_4() %{
 1737   predicate(n->get_int() == 4);
 1738   match(ConI);
 1739   op_cost(0);
 1740 
 1741   format %{ %}
 1742   interface(CONST_INTER);
 1743 %}
 1744 
 1745 // Integer Immediate: the value 8
 1746 operand immI_8() %{
 1747   predicate(n->get_int() == 8);
 1748   match(ConI);
 1749   op_cost(0);
 1750 
 1751   format %{ %}
 1752   interface(CONST_INTER);
 1753 %}
 1754 
 1755 // Int Immediate non-negative
 1756 operand immU31()
 1757 %{
 1758   predicate(n->get_int() >= 0);
 1759   match(ConI);
 1760 
 1761   op_cost(0);
 1762   format %{ %}
 1763   interface(CONST_INTER);
 1764 %}
 1765 
 1766 // Integer Immediate: the values 32-63
 1767 operand immI_32_63() %{
 1768   predicate(n->get_int() >= 32 && n->get_int() <= 63);
 1769   match(ConI);
 1770   op_cost(0);
 1771 
 1772   format %{ %}
 1773   interface(CONST_INTER);
 1774 %}
 1775 
 1776 // Immediates for special shifts (sign extend)
 1777 
 1778 // Integer Immediate: the value 16
 1779 operand immI_16() %{
 1780   predicate(n->get_int() == 16);
 1781   match(ConI);
 1782   op_cost(0);
 1783 
 1784   format %{ %}
 1785   interface(CONST_INTER);
 1786 %}
 1787 
 1788 // Integer Immediate: the value 24
 1789 operand immI_24() %{
 1790   predicate(n->get_int() == 24);
 1791   match(ConI);
 1792   op_cost(0);
 1793 
 1794   format %{ %}
 1795   interface(CONST_INTER);
 1796 %}
 1797 
 1798 // Integer Immediate: the value 255
 1799 operand immI_255() %{
 1800   predicate( n->get_int() == 255 );
 1801   match(ConI);
 1802   op_cost(0);
 1803 
 1804   format %{ %}
 1805   interface(CONST_INTER);
 1806 %}
 1807 
 1808 // Integer Immediate: the value 65535
 1809 operand immI_65535() %{
 1810   predicate(n->get_int() == 65535);
 1811   match(ConI);
 1812   op_cost(0);
 1813 
 1814   format %{ %}
 1815   interface(CONST_INTER);
 1816 %}
 1817 
 1818 // Integer Immediates for arithmetic instructions
 1819 
 1820 operand aimmI() %{
 1821   predicate(is_aimm(n->get_int()));
 1822   match(ConI);
 1823   op_cost(0);
 1824 
 1825   format %{ %}
 1826   interface(CONST_INTER);
 1827 %}
 1828 
 1829 operand aimmIneg() %{
 1830   predicate(is_aimm(-n->get_int()));
 1831   match(ConI);
 1832   op_cost(0);
 1833 
 1834   format %{ %}
 1835   interface(CONST_INTER);
 1836 %}
 1837 
 1838 operand aimmU31() %{
 1839   predicate((0 <= n->get_int()) && is_aimm(n->get_int()));
 1840   match(ConI);
 1841   op_cost(0);
 1842 
 1843   format %{ %}
 1844   interface(CONST_INTER);
 1845 %}
 1846 
 1847 // Integer Immediates for logical instructions
 1848 
 1849 operand limmI() %{
 1850   predicate(is_limmI(n->get_int()));
 1851   match(ConI);
 1852   op_cost(0);
 1853 
 1854   format %{ %}
 1855   interface(CONST_INTER);
 1856 %}
 1857 
 1858 operand limmIlow8() %{
 1859   predicate(is_limmI_low(n->get_int(), 8));
 1860   match(ConI);
 1861   op_cost(0);
 1862 
 1863   format %{ %}
 1864   interface(CONST_INTER);
 1865 %}
 1866 
 1867 operand limmU31() %{
 1868   predicate(0 <= n->get_int() && is_limmI(n->get_int()));
 1869   match(ConI);
 1870   op_cost(0);
 1871 
 1872   format %{ %}
 1873   interface(CONST_INTER);
 1874 %}
 1875 
 1876 operand limmIn() %{
 1877   predicate(is_limmI(~n->get_int()));
 1878   match(ConI);
 1879   op_cost(0);
 1880 
 1881   format %{ %}
 1882   interface(CONST_INTER);
 1883 %}
 1884 
 1885 
 1886 // Long Immediate: the value FF
 1887 operand immL_FF() %{
 1888   predicate( n->get_long() == 0xFFL );
 1889   match(ConL);
 1890   op_cost(0);
 1891 
 1892   format %{ %}
 1893   interface(CONST_INTER);
 1894 %}
 1895 
 1896 // Long Immediate: the value FFFF
 1897 operand immL_FFFF() %{
 1898   predicate( n->get_long() == 0xFFFFL );
 1899   match(ConL);
 1900   op_cost(0);
 1901 
 1902   format %{ %}
 1903   interface(CONST_INTER);
 1904 %}
 1905 
 1906 // Pointer Immediate: 32 or 64-bit
 1907 operand immP() %{
 1908   match(ConP);
 1909 
 1910   op_cost(5);
 1911   // formats are generated automatically for constants and base registers
 1912   format %{ %}
 1913   interface(CONST_INTER);
 1914 %}
 1915 
 1916 operand immP0() %{
 1917   predicate(n->get_ptr() == 0);
 1918   match(ConP);
 1919   op_cost(0);
 1920 
 1921   format %{ %}
 1922   interface(CONST_INTER);
 1923 %}
 1924 
 1925 // Pointer Immediate
 1926 operand immN()
 1927 %{
 1928   match(ConN);
 1929 
 1930   op_cost(10);
 1931   format %{ %}
 1932   interface(CONST_INTER);
 1933 %}
 1934 
 1935 operand immNKlass()
 1936 %{
 1937   match(ConNKlass);
 1938 
 1939   op_cost(10);
 1940   format %{ %}
 1941   interface(CONST_INTER);
 1942 %}
 1943 
 1944 // NULL Pointer Immediate
 1945 operand immN0()
 1946 %{
 1947   predicate(n->get_narrowcon() == 0);
 1948   match(ConN);
 1949 
 1950   op_cost(0);
 1951   format %{ %}
 1952   interface(CONST_INTER);
 1953 %}
 1954 
 1955 operand immL() %{
 1956   match(ConL);
 1957   op_cost(40);
 1958   // formats are generated automatically for constants and base registers
 1959   format %{ %}
 1960   interface(CONST_INTER);
 1961 %}
 1962 
 1963 operand immL0() %{
 1964   predicate(n->get_long() == 0L);
 1965   match(ConL);
 1966   op_cost(0);
 1967   // formats are generated automatically for constants and base registers
 1968   format %{ %}
 1969   interface(CONST_INTER);
 1970 %}
 1971 
 1972 // Long Immediate: 16-bit
 1973 operand immL16() %{
 1974   predicate(n->get_long() >= 0 && n->get_long() < (1<<16)  && VM_Version::supports_movw());
 1975   match(ConL);
 1976   op_cost(0);
 1977 
 1978   format %{ %}
 1979   interface(CONST_INTER);
 1980 %}
 1981 
 1982 // Long Immediate: low 32-bit mask
 1983 operand immL_32bits() %{
 1984   predicate(n->get_long() == 0xFFFFFFFFL);
 1985   match(ConL);
 1986   op_cost(0);
 1987 
 1988   format %{ %}
 1989   interface(CONST_INTER);
 1990 %}
 1991 
 1992 // Double Immediate
 1993 operand immD() %{
 1994   match(ConD);
 1995 
 1996   op_cost(40);
 1997   format %{ %}
 1998   interface(CONST_INTER);
 1999 %}
 2000 
 2001 // Double Immediate: +0.0d.
 2002 operand immD0() %{
 2003   predicate(jlong_cast(n->getd()) == 0);
 2004 
 2005   match(ConD);
 2006   op_cost(0);
 2007   format %{ %}
 2008   interface(CONST_INTER);
 2009 %}
 2010 
 2011 operand imm8D() %{
 2012   predicate(Assembler::double_num(n->getd()).can_be_imm8());
 2013   match(ConD);
 2014 
 2015   op_cost(0);
 2016   format %{ %}
 2017   interface(CONST_INTER);
 2018 %}
 2019 
 2020 // Float Immediate
 2021 operand immF() %{
 2022   match(ConF);
 2023 
 2024   op_cost(20);
 2025   format %{ %}
 2026   interface(CONST_INTER);
 2027 %}
 2028 
 2029 // Float Immediate: +0.0f
 2030 operand immF0() %{
 2031   predicate(jint_cast(n->getf()) == 0);
 2032   match(ConF);
 2033 
 2034   op_cost(0);
 2035   format %{ %}
 2036   interface(CONST_INTER);
 2037 %}
 2038 
 2039 // Float Immediate: encoded as 8 bits
 2040 operand imm8F() %{
 2041   predicate(Assembler::float_num(n->getf()).can_be_imm8());
 2042   match(ConF);
 2043 
 2044   op_cost(0);
 2045   format %{ %}
 2046   interface(CONST_INTER);
 2047 %}
 2048 
 2049 // Integer Register Operands
 2050 // Integer Register
 2051 operand iRegI() %{
 2052   constraint(ALLOC_IN_RC(int_reg));
 2053   match(RegI);
 2054   match(R0RegI);
 2055   match(R1RegI);
 2056   match(R2RegI);
 2057   match(R3RegI);
 2058   match(R12RegI);
 2059 
 2060   format %{ %}
 2061   interface(REG_INTER);
 2062 %}
 2063 
 2064 // Pointer Register
 2065 operand iRegP() %{
 2066   constraint(ALLOC_IN_RC(ptr_reg));
 2067   match(RegP);
 2068   match(R0RegP);
 2069   match(R1RegP);
 2070   match(R2RegP);
 2071   match(RExceptionRegP);
 2072   match(R8RegP);
 2073   match(R9RegP);
 2074   match(RthreadRegP); // FIXME: move to sp_ptr_RegP?
 2075   match(R12RegP);
 2076   match(LRRegP);
 2077 
 2078   match(sp_ptr_RegP);
 2079   match(store_ptr_RegP);
 2080 
 2081   format %{ %}
 2082   interface(REG_INTER);
 2083 %}
 2084 
 2085 // GPRs + Rthread + SP
 2086 operand sp_ptr_RegP() %{
 2087   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2088   match(RegP);
 2089   match(iRegP);
 2090   match(SPRegP); // FIXME: check cost
 2091 
 2092   format %{ %}
 2093   interface(REG_INTER);
 2094 %}
 2095 
 2096 
 2097 operand R0RegP() %{
 2098   constraint(ALLOC_IN_RC(R0_regP));
 2099   match(iRegP);
 2100 
 2101   format %{ %}
 2102   interface(REG_INTER);
 2103 %}
 2104 
 2105 operand R1RegP() %{
 2106   constraint(ALLOC_IN_RC(R1_regP));
 2107   match(iRegP);
 2108 
 2109   format %{ %}
 2110   interface(REG_INTER);
 2111 %}
 2112 
 2113 operand R8RegP() %{
 2114   constraint(ALLOC_IN_RC(R8_regP));
 2115   match(iRegP);
 2116 
 2117   format %{ %}
 2118   interface(REG_INTER);
 2119 %}
 2120 
 2121 operand R9RegP() %{
 2122   constraint(ALLOC_IN_RC(R9_regP));
 2123   match(iRegP);
 2124 
 2125   format %{ %}
 2126   interface(REG_INTER);
 2127 %}
 2128 
 2129 operand R12RegP() %{
 2130   constraint(ALLOC_IN_RC(R12_regP));
 2131   match(iRegP);
 2132 
 2133   format %{ %}
 2134   interface(REG_INTER);
 2135 %}
 2136 
 2137 operand R2RegP() %{
 2138   constraint(ALLOC_IN_RC(R2_regP));
 2139   match(iRegP);
 2140 
 2141   format %{ %}
 2142   interface(REG_INTER);
 2143 %}
 2144 
 2145 operand RExceptionRegP() %{
 2146   constraint(ALLOC_IN_RC(Rexception_regP));
 2147   match(iRegP);
 2148 
 2149   format %{ %}
 2150   interface(REG_INTER);
 2151 %}
 2152 
 2153 operand RthreadRegP() %{
 2154   constraint(ALLOC_IN_RC(Rthread_regP));
 2155   match(iRegP);
 2156 
 2157   format %{ %}
 2158   interface(REG_INTER);
 2159 %}
 2160 
 2161 operand IPRegP() %{
 2162   constraint(ALLOC_IN_RC(IP_regP));
 2163   match(iRegP);
 2164 
 2165   format %{ %}
 2166   interface(REG_INTER);
 2167 %}
 2168 
 2169 operand SPRegP() %{
 2170   constraint(ALLOC_IN_RC(SP_regP));
 2171   match(iRegP);
 2172 
 2173   format %{ %}
 2174   interface(REG_INTER);
 2175 %}
 2176 
 2177 operand LRRegP() %{
 2178   constraint(ALLOC_IN_RC(LR_regP));
 2179   match(iRegP);
 2180 
 2181   format %{ %}
 2182   interface(REG_INTER);
 2183 %}
 2184 
 2185 operand R0RegI() %{
 2186   constraint(ALLOC_IN_RC(R0_regI));
 2187   match(iRegI);
 2188 
 2189   format %{ %}
 2190   interface(REG_INTER);
 2191 %}
 2192 
 2193 operand R1RegI() %{
 2194   constraint(ALLOC_IN_RC(R1_regI));
 2195   match(iRegI);
 2196 
 2197   format %{ %}
 2198   interface(REG_INTER);
 2199 %}
 2200 
 2201 operand R2RegI() %{
 2202   constraint(ALLOC_IN_RC(R2_regI));
 2203   match(iRegI);
 2204 
 2205   format %{ %}
 2206   interface(REG_INTER);
 2207 %}
 2208 
 2209 operand R3RegI() %{
 2210   constraint(ALLOC_IN_RC(R3_regI));
 2211   match(iRegI);
 2212 
 2213   format %{ %}
 2214   interface(REG_INTER);
 2215 %}
 2216 
 2217 operand R12RegI() %{
 2218   constraint(ALLOC_IN_RC(R12_regI));
 2219   match(iRegI);
 2220 
 2221   format %{ %}
 2222   interface(REG_INTER);
 2223 %}
 2224 
 2225 // Long Register
 2226 operand iRegL() %{
 2227   constraint(ALLOC_IN_RC(long_reg));
 2228   match(RegL);
 2229   match(R0R1RegL);
 2230   match(R2R3RegL);
 2231 //match(iRegLex);
 2232 
 2233   format %{ %}
 2234   interface(REG_INTER);
 2235 %}
 2236 
 2237 operand iRegLd() %{
 2238   constraint(ALLOC_IN_RC(long_reg_align));
 2239   match(iRegL); // FIXME: allows unaligned R11/R12?
 2240 
 2241   format %{ %}
 2242   interface(REG_INTER);
 2243 %}
 2244 
 2245 // first long arg, or return value
 2246 operand R0R1RegL() %{
 2247   constraint(ALLOC_IN_RC(R0R1_regL));
 2248   match(iRegL);
 2249 
 2250   format %{ %}
 2251   interface(REG_INTER);
 2252 %}
 2253 
 2254 operand R2R3RegL() %{
 2255   constraint(ALLOC_IN_RC(R2R3_regL));
 2256   match(iRegL);
 2257 
 2258   format %{ %}
 2259   interface(REG_INTER);
 2260 %}
 2261 
 2262 // Condition Code Flag Register
 2263 operand flagsReg() %{
 2264   constraint(ALLOC_IN_RC(int_flags));
 2265   match(RegFlags);
 2266 
 2267   format %{ "apsr" %}
 2268   interface(REG_INTER);
 2269 %}
 2270 
 2271 // Result of compare to 0 (TST)
 2272 operand flagsReg_EQNELTGE() %{
 2273   constraint(ALLOC_IN_RC(int_flags));
 2274   match(RegFlags);
 2275 
 2276   format %{ "apsr_EQNELTGE" %}
 2277   interface(REG_INTER);
 2278 %}
 2279 
 2280 // Condition Code Register, unsigned comparisons.
 2281 operand flagsRegU() %{
 2282   constraint(ALLOC_IN_RC(int_flags));
 2283   match(RegFlags);
 2284 #ifdef TODO
 2285   match(RegFlagsP);
 2286 #endif
 2287 
 2288   format %{ "apsr_U" %}
 2289   interface(REG_INTER);
 2290 %}
 2291 
 2292 // Condition Code Register, pointer comparisons.
 2293 operand flagsRegP() %{
 2294   constraint(ALLOC_IN_RC(int_flags));
 2295   match(RegFlags);
 2296 
 2297   format %{ "apsr_P" %}
 2298   interface(REG_INTER);
 2299 %}
 2300 
 2301 // Condition Code Register, long comparisons.
 2302 operand flagsRegL_LTGE() %{
 2303   constraint(ALLOC_IN_RC(int_flags));
 2304   match(RegFlags);
 2305 
 2306   format %{ "apsr_L_LTGE" %}
 2307   interface(REG_INTER);
 2308 %}
 2309 
 2310 operand flagsRegL_EQNE() %{
 2311   constraint(ALLOC_IN_RC(int_flags));
 2312   match(RegFlags);
 2313 
 2314   format %{ "apsr_L_EQNE" %}
 2315   interface(REG_INTER);
 2316 %}
 2317 
 2318 operand flagsRegL_LEGT() %{
 2319   constraint(ALLOC_IN_RC(int_flags));
 2320   match(RegFlags);
 2321 
 2322   format %{ "apsr_L_LEGT" %}
 2323   interface(REG_INTER);
 2324 %}
 2325 
 2326 operand flagsRegUL_LTGE() %{
 2327   constraint(ALLOC_IN_RC(int_flags));
 2328   match(RegFlags);
 2329 
 2330   format %{ "apsr_UL_LTGE" %}
 2331   interface(REG_INTER);
 2332 %}
 2333 
 2334 operand flagsRegUL_EQNE() %{
 2335   constraint(ALLOC_IN_RC(int_flags));
 2336   match(RegFlags);
 2337 
 2338   format %{ "apsr_UL_EQNE" %}
 2339   interface(REG_INTER);
 2340 %}
 2341 
 2342 operand flagsRegUL_LEGT() %{
 2343   constraint(ALLOC_IN_RC(int_flags));
 2344   match(RegFlags);
 2345 
 2346   format %{ "apsr_UL_LEGT" %}
 2347   interface(REG_INTER);
 2348 %}
 2349 
 2350 // Condition Code Register, floating comparisons, unordered same as "less".
 2351 operand flagsRegF() %{
 2352   constraint(ALLOC_IN_RC(float_flags));
 2353   match(RegFlags);
 2354 
 2355   format %{ "fpscr_F" %}
 2356   interface(REG_INTER);
 2357 %}
 2358 
 2359 // Vectors
 2360 operand vecD() %{
 2361   constraint(ALLOC_IN_RC(actual_dflt_reg));
 2362   match(VecD);
 2363 
 2364   format %{ %}
 2365   interface(REG_INTER);
 2366 %}
 2367 
 2368 operand vecX() %{
 2369   constraint(ALLOC_IN_RC(vectorx_reg));
 2370   match(VecX);
 2371 
 2372   format %{ %}
 2373   interface(REG_INTER);
 2374 %}
 2375 
 2376 operand regD() %{
 2377   constraint(ALLOC_IN_RC(actual_dflt_reg));
 2378   match(RegD);
 2379   match(regD_low);
 2380 
 2381   format %{ %}
 2382   interface(REG_INTER);
 2383 %}
 2384 
 2385 operand regF() %{
 2386   constraint(ALLOC_IN_RC(sflt_reg));
 2387   match(RegF);
 2388 
 2389   format %{ %}
 2390   interface(REG_INTER);
 2391 %}
 2392 
 2393 operand regD_low() %{
 2394   constraint(ALLOC_IN_RC(dflt_low_reg));
 2395   match(RegD);
 2396 
 2397   format %{ %}
 2398   interface(REG_INTER);
 2399 %}
 2400 
 2401 // Special Registers
 2402 
 2403 // Method Register
 2404 operand inline_cache_regP(iRegP reg) %{
 2405   constraint(ALLOC_IN_RC(Ricklass_regP));
 2406   match(reg);
 2407   format %{ %}
 2408   interface(REG_INTER);
 2409 %}
 2410 
 2411 //----------Complex Operands---------------------------------------------------
 2412 // Indirect Memory Reference
 2413 operand indirect(sp_ptr_RegP reg) %{
 2414   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2415   match(reg);
 2416 
 2417   op_cost(100);
 2418   format %{ "[$reg]" %}
 2419   interface(MEMORY_INTER) %{
 2420     base($reg);
 2421     index(0xf); // PC => no index
 2422     scale(0x0);
 2423     disp(0x0);
 2424   %}
 2425 %}
 2426 
 2427 
 2428 // Indirect with Offset in ]-4096, 4096[
 2429 operand indOffset12(sp_ptr_RegP reg, immI12 offset) %{
 2430   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2431   match(AddP reg offset);
 2432 
 2433   op_cost(100);
 2434   format %{ "[$reg + $offset]" %}
 2435   interface(MEMORY_INTER) %{
 2436     base($reg);
 2437     index(0xf); // PC => no index
 2438     scale(0x0);
 2439     disp($offset);
 2440   %}
 2441 %}
 2442 
 2443 // Indirect with offset for float load/store
 2444 operand indOffsetFP(sp_ptr_RegP reg, immIFP offset) %{
 2445   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2446   match(AddP reg offset);
 2447 
 2448   op_cost(100);
 2449   format %{ "[$reg + $offset]" %}
 2450   interface(MEMORY_INTER) %{
 2451     base($reg);
 2452     index(0xf); // PC => no index
 2453     scale(0x0);
 2454     disp($offset);
 2455   %}
 2456 %}
 2457 
 2458 // Indirect with Offset for half and double words
 2459 operand indOffsetHD(sp_ptr_RegP reg, immIHD offset) %{
 2460   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2461   match(AddP reg offset);
 2462 
 2463   op_cost(100);
 2464   format %{ "[$reg + $offset]" %}
 2465   interface(MEMORY_INTER) %{
 2466     base($reg);
 2467     index(0xf); // PC => no index
 2468     scale(0x0);
 2469     disp($offset);
 2470   %}
 2471 %}
 2472 
 2473 // Indirect with Offset and Offset+4 in ]-1024, 1024[
 2474 operand indOffsetFPx2(sp_ptr_RegP reg, immX10x2 offset) %{
 2475   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2476   match(AddP reg offset);
 2477 
 2478   op_cost(100);
 2479   format %{ "[$reg + $offset]" %}
 2480   interface(MEMORY_INTER) %{
 2481     base($reg);
 2482     index(0xf); // PC => no index
 2483     scale(0x0);
 2484     disp($offset);
 2485   %}
 2486 %}
 2487 
 2488 // Indirect with Offset and Offset+4 in ]-4096, 4096[
 2489 operand indOffset12x2(sp_ptr_RegP reg, immI12x2 offset) %{
 2490   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2491   match(AddP reg offset);
 2492 
 2493   op_cost(100);
 2494   format %{ "[$reg + $offset]" %}
 2495   interface(MEMORY_INTER) %{
 2496     base($reg);
 2497     index(0xf); // PC => no index
 2498     scale(0x0);
 2499     disp($offset);
 2500   %}
 2501 %}
 2502 
 2503 // Indirect with Register Index
 2504 operand indIndex(iRegP addr, iRegX index) %{
 2505   constraint(ALLOC_IN_RC(ptr_reg));
 2506   match(AddP addr index);
 2507 
 2508   op_cost(100);
 2509   format %{ "[$addr + $index]" %}
 2510   interface(MEMORY_INTER) %{
 2511     base($addr);
 2512     index($index);
 2513     scale(0x0);
 2514     disp(0x0);
 2515   %}
 2516 %}
 2517 
 2518 // Indirect Memory Times Scale Plus Index Register
 2519 operand indIndexScale(iRegP addr, iRegX index, immU5 scale) %{
 2520   constraint(ALLOC_IN_RC(ptr_reg));
 2521   match(AddP addr (LShiftX index scale));
 2522 
 2523   op_cost(100);
 2524   format %{"[$addr + $index << $scale]" %}
 2525   interface(MEMORY_INTER) %{
 2526     base($addr);
 2527     index($index);
 2528     scale($scale);
 2529     disp(0x0);
 2530   %}
 2531 %}
 2532 
 2533 // Operands for expressing Control Flow
 2534 // NOTE:  Label is a predefined operand which should not be redefined in
 2535 //        the AD file.  It is generically handled within the ADLC.
 2536 
 2537 //----------Conditional Branch Operands----------------------------------------
 2538 // Comparison Op  - This is the operation of the comparison, and is limited to
 2539 //                  the following set of codes:
 2540 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
 2541 //
 2542 // Other attributes of the comparison, such as unsignedness, are specified
 2543 // by the comparison instruction that sets a condition code flags register.
 2544 // That result is represented by a flags operand whose subtype is appropriate
 2545 // to the unsignedness (etc.) of the comparison.
 2546 //
 2547 // Later, the instruction which matches both the Comparison Op (a Bool) and
 2548 // the flags (produced by the Cmp) specifies the coding of the comparison op
 2549 // by matching a specific subtype of Bool operand below, such as cmpOpU.
 2550 
 2551 operand cmpOp() %{
 2552   match(Bool);
 2553 
 2554   format %{ "" %}
 2555   interface(COND_INTER) %{
 2556     equal(0x0);
 2557     not_equal(0x1);
 2558     less(0xb);
 2559     greater_equal(0xa);
 2560     less_equal(0xd);
 2561     greater(0xc);
 2562     overflow(0x0); // unsupported/unimplemented
 2563     no_overflow(0x0); // unsupported/unimplemented
 2564   %}
 2565 %}
 2566 
 2567 // integer comparison with 0, signed
 2568 operand cmpOp0() %{
 2569   match(Bool);
 2570 
 2571   format %{ "" %}
 2572   interface(COND_INTER) %{
 2573     equal(0x0);
 2574     not_equal(0x1);
 2575     less(0x4);
 2576     greater_equal(0x5);
 2577     less_equal(0xd); // unsupported
 2578     greater(0xc); // unsupported
 2579     overflow(0x0); // unsupported/unimplemented
 2580     no_overflow(0x0); // unsupported/unimplemented
 2581   %}
 2582 %}
 2583 
 2584 // Comparison Op, unsigned
 2585 operand cmpOpU() %{
 2586   match(Bool);
 2587 
 2588   format %{ "u" %}
 2589   interface(COND_INTER) %{
 2590     equal(0x0);
 2591     not_equal(0x1);
 2592     less(0x3);
 2593     greater_equal(0x2);
 2594     less_equal(0x9);
 2595     greater(0x8);
 2596     overflow(0x0); // unsupported/unimplemented
 2597     no_overflow(0x0); // unsupported/unimplemented
 2598   %}
 2599 %}
 2600 
 2601 // Comparison Op, pointer (same as unsigned)
 2602 operand cmpOpP() %{
 2603   match(Bool);
 2604 
 2605   format %{ "p" %}
 2606   interface(COND_INTER) %{
 2607     equal(0x0);
 2608     not_equal(0x1);
 2609     less(0x3);
 2610     greater_equal(0x2);
 2611     less_equal(0x9);
 2612     greater(0x8);
 2613     overflow(0x0); // unsupported/unimplemented
 2614     no_overflow(0x0); // unsupported/unimplemented
 2615   %}
 2616 %}
 2617 
 2618 operand cmpOpL() %{
 2619   match(Bool);
 2620 
 2621   format %{ "L" %}
 2622   interface(COND_INTER) %{
 2623     equal(0x0);
 2624     not_equal(0x1);
 2625     less(0xb);
 2626     greater_equal(0xa);
 2627     less_equal(0xd);
 2628     greater(0xc);
 2629     overflow(0x0); // unsupported/unimplemented
 2630     no_overflow(0x0); // unsupported/unimplemented
 2631   %}
 2632 %}
 2633 
 2634 operand cmpOpL_commute() %{
 2635   match(Bool);
 2636 
 2637   format %{ "L" %}
 2638   interface(COND_INTER) %{
 2639     equal(0x0);
 2640     not_equal(0x1);
 2641     less(0xc);
 2642     greater_equal(0xd);
 2643     less_equal(0xa);
 2644     greater(0xb);
 2645     overflow(0x0); // unsupported/unimplemented
 2646     no_overflow(0x0); // unsupported/unimplemented
 2647   %}
 2648 %}
 2649 
 2650 operand cmpOpUL() %{
 2651   match(Bool);
 2652 
 2653   format %{ "UL" %}
 2654   interface(COND_INTER) %{
 2655     equal(0x0);
 2656     not_equal(0x1);
 2657     less(0x3);
 2658     greater_equal(0x2);
 2659     less_equal(0x9);
 2660     greater(0x8);
 2661     overflow(0x0); // unsupported/unimplemented
 2662     no_overflow(0x0); // unsupported/unimplemented
 2663   %}
 2664 %}
 2665 
 2666 operand cmpOpUL_commute() %{
 2667   match(Bool);
 2668 
 2669   format %{ "UL" %}
 2670   interface(COND_INTER) %{
 2671     equal(0x0);
 2672     not_equal(0x1);
 2673     less(0x8);
 2674     greater_equal(0x9);
 2675     less_equal(0x2);
 2676     greater(0x3);
 2677     overflow(0x0); // unsupported/unimplemented
 2678     no_overflow(0x0); // unsupported/unimplemented
 2679   %}
 2680 %}
 2681 
 2682 
 2683 //----------OPERAND CLASSES----------------------------------------------------
 2684 // Operand Classes are groups of operands that are used to simplify
 2685 // instruction definitions by not requiring the AD writer to specify separate
 2686 // instructions for every form of operand when the instruction accepts
 2687 // multiple operand types with the same basic encoding and format.  The classic
 2688 // case of this is memory operands.
 2689 
 2690 opclass memoryI ( indirect, indOffset12, indIndex, indIndexScale );
 2691 opclass memoryP ( indirect, indOffset12, indIndex, indIndexScale );
 2692 opclass memoryF ( indirect, indOffsetFP );
 2693 opclass memoryF2 ( indirect, indOffsetFPx2 );
 2694 opclass memoryD ( indirect, indOffsetFP );
 2695 opclass memoryfp( indirect, indOffsetFP );
 2696 opclass memoryB ( indirect, indIndex, indOffsetHD );
 2697 opclass memoryS ( indirect, indIndex, indOffsetHD );
 2698 opclass memoryL ( indirect, indIndex, indOffsetHD );
 2699 
 2700 opclass memoryScaledI(indIndexScale);
 2701 opclass memoryScaledP(indIndexScale);
 2702 
 2703 // when ldrex/strex is used:
 2704 opclass memoryex ( indirect );
 2705 opclass indIndexMemory( indIndex );
 2706 opclass memorylong ( indirect, indOffset12x2 );
 2707 opclass memoryvld ( indirect /* , write back mode not implemented */ );
 2708 
 2709 //----------PIPELINE-----------------------------------------------------------
 2710 pipeline %{
 2711 
 2712 //----------ATTRIBUTES---------------------------------------------------------
 2713 attributes %{
 2714   fixed_size_instructions;           // Fixed size instructions
 2715   max_instructions_per_bundle = 4;   // Up to 4 instructions per bundle
 2716   instruction_unit_size = 4;         // An instruction is 4 bytes long
 2717   instruction_fetch_unit_size = 16;  // The processor fetches one line
 2718   instruction_fetch_units = 1;       // of 16 bytes
 2719 
 2720   // List of nop instructions
 2721   nops( Nop_A0, Nop_A1, Nop_MS, Nop_FA, Nop_BR );
 2722 %}
 2723 
 2724 //----------RESOURCES----------------------------------------------------------
 2725 // Resources are the functional units available to the machine
 2726 resources(A0, A1, MS, BR, FA, FM, IDIV, FDIV, IALU = A0 | A1);
 2727 
 2728 //----------PIPELINE DESCRIPTION-----------------------------------------------
 2729 // Pipeline Description specifies the stages in the machine's pipeline
 2730 
 2731 pipe_desc(A, P, F, B, I, J, S, R, E, C, M, W, X, T, D);
 2732 
 2733 //----------PIPELINE CLASSES---------------------------------------------------
 2734 // Pipeline Classes describe the stages in which input and output are
 2735 // referenced by the hardware pipeline.
 2736 
 2737 // Integer ALU reg-reg operation
 2738 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 2739     single_instruction;
 2740     dst   : E(write);
 2741     src1  : R(read);
 2742     src2  : R(read);
 2743     IALU  : R;
 2744 %}
 2745 
 2746 // Integer ALU reg-reg long operation
 2747 pipe_class ialu_reg_reg_2(iRegL dst, iRegL src1, iRegL src2) %{
 2748     instruction_count(2);
 2749     dst   : E(write);
 2750     src1  : R(read);
 2751     src2  : R(read);
 2752     IALU  : R;
 2753     IALU  : R;
 2754 %}
 2755 
 2756 // Integer ALU reg-reg long dependent operation
 2757 pipe_class ialu_reg_reg_2_dep(iRegL dst, iRegL src1, iRegL src2, flagsReg cr) %{
 2758     instruction_count(1); multiple_bundles;
 2759     dst   : E(write);
 2760     src1  : R(read);
 2761     src2  : R(read);
 2762     cr    : E(write);
 2763     IALU  : R(2);
 2764 %}
 2765 
 2766 // Integer ALU reg-imm operaion
 2767 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) %{
 2768     single_instruction;
 2769     dst   : E(write);
 2770     src1  : R(read);
 2771     IALU  : R;
 2772 %}
 2773 
 2774 // Integer ALU reg-reg operation with condition code
 2775 pipe_class ialu_cc_reg_reg(iRegI dst, iRegI src1, iRegI src2, flagsReg cr) %{
 2776     single_instruction;
 2777     dst   : E(write);
 2778     cr    : E(write);
 2779     src1  : R(read);
 2780     src2  : R(read);
 2781     IALU  : R;
 2782 %}
 2783 
 2784 // Integer ALU zero-reg operation
 2785 pipe_class ialu_zero_reg(iRegI dst, immI0 zero, iRegI src2) %{
 2786     single_instruction;
 2787     dst   : E(write);
 2788     src2  : R(read);
 2789     IALU  : R;
 2790 %}
 2791 
 2792 // Integer ALU zero-reg operation with condition code only
 2793 pipe_class ialu_cconly_zero_reg(flagsReg cr, iRegI src) %{
 2794     single_instruction;
 2795     cr    : E(write);
 2796     src   : R(read);
 2797     IALU  : R;
 2798 %}
 2799 
 2800 // Integer ALU reg-reg operation with condition code only
 2801 pipe_class ialu_cconly_reg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
 2802     single_instruction;
 2803     cr    : E(write);
 2804     src1  : R(read);
 2805     src2  : R(read);
 2806     IALU  : R;
 2807 %}
 2808 
 2809 // Integer ALU reg-imm operation with condition code only
 2810 pipe_class ialu_cconly_reg_imm(flagsReg cr, iRegI src1) %{
 2811     single_instruction;
 2812     cr    : E(write);
 2813     src1  : R(read);
 2814     IALU  : R;
 2815 %}
 2816 
 2817 // Integer ALU reg-reg-zero operation with condition code only
 2818 pipe_class ialu_cconly_reg_reg_zero(flagsReg cr, iRegI src1, iRegI src2, immI0 zero) %{
 2819     single_instruction;
 2820     cr    : E(write);
 2821     src1  : R(read);
 2822     src2  : R(read);
 2823     IALU  : R;
 2824 %}
 2825 
 2826 // Integer ALU reg-imm-zero operation with condition code only
 2827 pipe_class ialu_cconly_reg_imm_zero(flagsReg cr, iRegI src1, immI0 zero) %{
 2828     single_instruction;
 2829     cr    : E(write);
 2830     src1  : R(read);
 2831     IALU  : R;
 2832 %}
 2833 
 2834 // Integer ALU reg-reg operation with condition code, src1 modified
 2835 pipe_class ialu_cc_rwreg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
 2836     single_instruction;
 2837     cr    : E(write);
 2838     src1  : E(write);
 2839     src1  : R(read);
 2840     src2  : R(read);
 2841     IALU  : R;
 2842 %}
 2843 
 2844 pipe_class cmpL_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg cr ) %{
 2845     multiple_bundles;
 2846     dst   : E(write)+4;
 2847     cr    : E(write);
 2848     src1  : R(read);
 2849     src2  : R(read);
 2850     IALU  : R(3);
 2851     BR    : R(2);
 2852 %}
 2853 
 2854 // Integer ALU operation
 2855 pipe_class ialu_none(iRegI dst) %{
 2856     single_instruction;
 2857     dst   : E(write);
 2858     IALU  : R;
 2859 %}
 2860 
 2861 // Integer ALU reg operation
 2862 pipe_class ialu_reg(iRegI dst, iRegI src) %{
 2863     single_instruction; may_have_no_code;
 2864     dst   : E(write);
 2865     src   : R(read);
 2866     IALU  : R;
 2867 %}
 2868 
 2869 // Integer ALU reg conditional operation
 2870 // This instruction has a 1 cycle stall, and cannot execute
 2871 // in the same cycle as the instruction setting the condition
 2872 // code. We kludge this by pretending to read the condition code
 2873 // 1 cycle earlier, and by marking the functional units as busy
 2874 // for 2 cycles with the result available 1 cycle later than
 2875 // is really the case.
 2876 pipe_class ialu_reg_flags( iRegI op2_out, iRegI op2_in, iRegI op1, flagsReg cr ) %{
 2877     single_instruction;
 2878     op2_out : C(write);
 2879     op1     : R(read);
 2880     cr      : R(read);       // This is really E, with a 1 cycle stall
 2881     BR      : R(2);
 2882     MS      : R(2);
 2883 %}
 2884 
 2885 // Integer ALU reg operation
 2886 pipe_class ialu_move_reg_L_to_I(iRegI dst, iRegL src) %{
 2887     single_instruction; may_have_no_code;
 2888     dst   : E(write);
 2889     src   : R(read);
 2890     IALU  : R;
 2891 %}
 2892 pipe_class ialu_move_reg_I_to_L(iRegL dst, iRegI src) %{
 2893     single_instruction; may_have_no_code;
 2894     dst   : E(write);
 2895     src   : R(read);
 2896     IALU  : R;
 2897 %}
 2898 
 2899 // Two integer ALU reg operations
 2900 pipe_class ialu_reg_2(iRegL dst, iRegL src) %{
 2901     instruction_count(2);
 2902     dst   : E(write);
 2903     src   : R(read);
 2904     A0    : R;
 2905     A1    : R;
 2906 %}
 2907 
 2908 // Two integer ALU reg operations
 2909 pipe_class ialu_move_reg_L_to_L(iRegL dst, iRegL src) %{
 2910     instruction_count(2); may_have_no_code;
 2911     dst   : E(write);
 2912     src   : R(read);
 2913     A0    : R;
 2914     A1    : R;
 2915 %}
 2916 
 2917 // Integer ALU imm operation
 2918 pipe_class ialu_imm(iRegI dst) %{
 2919     single_instruction;
 2920     dst   : E(write);
 2921     IALU  : R;
 2922 %}
 2923 
 2924 pipe_class ialu_imm_n(iRegI dst) %{
 2925     single_instruction;
 2926     dst   : E(write);
 2927     IALU  : R;
 2928 %}
 2929 
 2930 // Integer ALU reg-reg with carry operation
 2931 pipe_class ialu_reg_reg_cy(iRegI dst, iRegI src1, iRegI src2, iRegI cy) %{
 2932     single_instruction;
 2933     dst   : E(write);
 2934     src1  : R(read);
 2935     src2  : R(read);
 2936     IALU  : R;
 2937 %}
 2938 
 2939 // Integer ALU cc operation
 2940 pipe_class ialu_cc(iRegI dst, flagsReg cc) %{
 2941     single_instruction;
 2942     dst   : E(write);
 2943     cc    : R(read);
 2944     IALU  : R;
 2945 %}
 2946 
 2947 // Integer ALU cc / second IALU operation
 2948 pipe_class ialu_reg_ialu( iRegI dst, iRegI src ) %{
 2949     instruction_count(1); multiple_bundles;
 2950     dst   : E(write)+1;
 2951     src   : R(read);
 2952     IALU  : R;
 2953 %}
 2954 
 2955 // Integer ALU cc / second IALU operation
 2956 pipe_class ialu_reg_reg_ialu( iRegI dst, iRegI p, iRegI q ) %{
 2957     instruction_count(1); multiple_bundles;
 2958     dst   : E(write)+1;
 2959     p     : R(read);
 2960     q     : R(read);
 2961     IALU  : R;
 2962 %}
 2963 
 2964 // Integer ALU hi-lo-reg operation
 2965 pipe_class ialu_hi_lo_reg(iRegI dst, immI src) %{
 2966     instruction_count(1); multiple_bundles;
 2967     dst   : E(write)+1;
 2968     IALU  : R(2);
 2969 %}
 2970 
 2971 // Long Constant
 2972 pipe_class loadConL( iRegL dst, immL src ) %{
 2973     instruction_count(2); multiple_bundles;
 2974     dst   : E(write)+1;
 2975     IALU  : R(2);
 2976     IALU  : R(2);
 2977 %}
 2978 
 2979 // Pointer Constant
 2980 pipe_class loadConP( iRegP dst, immP src ) %{
 2981     instruction_count(0); multiple_bundles;
 2982     fixed_latency(6);
 2983 %}
 2984 
 2985 // Long Constant small
 2986 pipe_class loadConLlo( iRegL dst, immL src ) %{
 2987     instruction_count(2);
 2988     dst   : E(write);
 2989     IALU  : R;
 2990     IALU  : R;
 2991 %}
 2992 
 2993 // [PHH] This is wrong for 64-bit.  See LdImmF/D.
 2994 pipe_class loadConFD(regF dst, immF src, iRegP tmp) %{
 2995     instruction_count(1); multiple_bundles;
 2996     src   : R(read);
 2997     dst   : M(write)+1;
 2998     IALU  : R;
 2999     MS    : E;
 3000 %}
 3001 
 3002 // Integer ALU nop operation
 3003 pipe_class ialu_nop() %{
 3004     single_instruction;
 3005     IALU  : R;
 3006 %}
 3007 
 3008 // Integer ALU nop operation
 3009 pipe_class ialu_nop_A0() %{
 3010     single_instruction;
 3011     A0    : R;
 3012 %}
 3013 
 3014 // Integer ALU nop operation
 3015 pipe_class ialu_nop_A1() %{
 3016     single_instruction;
 3017     A1    : R;
 3018 %}
 3019 
 3020 // Integer Multiply reg-reg operation
 3021 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 3022     single_instruction;
 3023     dst   : E(write);
 3024     src1  : R(read);
 3025     src2  : R(read);
 3026     MS    : R(5);
 3027 %}
 3028 
 3029 pipe_class mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 3030     single_instruction;
 3031     dst   : E(write)+4;
 3032     src1  : R(read);
 3033     src2  : R(read);
 3034     MS    : R(6);
 3035 %}
 3036 
 3037 // Integer Divide reg-reg
 3038 pipe_class sdiv_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI temp, flagsReg cr) %{
 3039     instruction_count(1); multiple_bundles;
 3040     dst   : E(write);
 3041     temp  : E(write);
 3042     src1  : R(read);
 3043     src2  : R(read);
 3044     temp  : R(read);
 3045     MS    : R(38);
 3046 %}
 3047 
 3048 // Long Divide
 3049 pipe_class divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 3050     dst  : E(write)+71;
 3051     src1 : R(read);
 3052     src2 : R(read)+1;
 3053     MS   : R(70);
 3054 %}
 3055 
 3056 // Floating Point Add Float
 3057 pipe_class faddF_reg_reg(regF dst, regF src1, regF src2) %{
 3058     single_instruction;
 3059     dst   : X(write);
 3060     src1  : E(read);
 3061     src2  : E(read);
 3062     FA    : R;
 3063 %}
 3064 
 3065 // Floating Point Add Double
 3066 pipe_class faddD_reg_reg(regD dst, regD src1, regD src2) %{
 3067     single_instruction;
 3068     dst   : X(write);
 3069     src1  : E(read);
 3070     src2  : E(read);
 3071     FA    : R;
 3072 %}
 3073 
 3074 // Floating Point Conditional Move based on integer flags
 3075 pipe_class int_conditional_float_move (cmpOp cmp, flagsReg cr, regF dst, regF src) %{
 3076     single_instruction;
 3077     dst   : X(write);
 3078     src   : E(read);
 3079     cr    : R(read);
 3080     FA    : R(2);
 3081     BR    : R(2);
 3082 %}
 3083 
 3084 // Floating Point Conditional Move based on integer flags
 3085 pipe_class int_conditional_double_move (cmpOp cmp, flagsReg cr, regD dst, regD src) %{
 3086     single_instruction;
 3087     dst   : X(write);
 3088     src   : E(read);
 3089     cr    : R(read);
 3090     FA    : R(2);
 3091     BR    : R(2);
 3092 %}
 3093 
 3094 // Floating Point Multiply Float
 3095 pipe_class fmulF_reg_reg(regF dst, regF src1, regF src2) %{
 3096     single_instruction;
 3097     dst   : X(write);
 3098     src1  : E(read);
 3099     src2  : E(read);
 3100     FM    : R;
 3101 %}
 3102 
 3103 // Floating Point Multiply Double
 3104 pipe_class fmulD_reg_reg(regD dst, regD src1, regD src2) %{
 3105     single_instruction;
 3106     dst   : X(write);
 3107     src1  : E(read);
 3108     src2  : E(read);
 3109     FM    : R;
 3110 %}
 3111 
 3112 // Floating Point Divide Float
 3113 pipe_class fdivF_reg_reg(regF dst, regF src1, regF src2) %{
 3114     single_instruction;
 3115     dst   : X(write);
 3116     src1  : E(read);
 3117     src2  : E(read);
 3118     FM    : R;
 3119     FDIV  : C(14);
 3120 %}
 3121 
 3122 // Floating Point Divide Double
 3123 pipe_class fdivD_reg_reg(regD dst, regD src1, regD src2) %{
 3124     single_instruction;
 3125     dst   : X(write);
 3126     src1  : E(read);
 3127     src2  : E(read);
 3128     FM    : R;
 3129     FDIV  : C(17);
 3130 %}
 3131 
 3132 // Floating Point Move/Negate/Abs Float
 3133 pipe_class faddF_reg(regF dst, regF src) %{
 3134     single_instruction;
 3135     dst   : W(write);
 3136     src   : E(read);
 3137     FA    : R(1);
 3138 %}
 3139 
 3140 // Floating Point Move/Negate/Abs Double
 3141 pipe_class faddD_reg(regD dst, regD src) %{
 3142     single_instruction;
 3143     dst   : W(write);
 3144     src   : E(read);
 3145     FA    : R;
 3146 %}
 3147 
 3148 // Floating Point Convert F->D
 3149 pipe_class fcvtF2D(regD dst, regF src) %{
 3150     single_instruction;
 3151     dst   : X(write);
 3152     src   : E(read);
 3153     FA    : R;
 3154 %}
 3155 
 3156 // Floating Point Convert I->D
 3157 pipe_class fcvtI2D(regD dst, regF src) %{
 3158     single_instruction;
 3159     dst   : X(write);
 3160     src   : E(read);
 3161     FA    : R;
 3162 %}
 3163 
 3164 // Floating Point Convert LHi->D
 3165 pipe_class fcvtLHi2D(regD dst, regD src) %{
 3166     single_instruction;
 3167     dst   : X(write);
 3168     src   : E(read);
 3169     FA    : R;
 3170 %}
 3171 
 3172 // Floating Point Convert L->D
 3173 pipe_class fcvtL2D(regD dst, iRegL src) %{
 3174     single_instruction;
 3175     dst   : X(write);
 3176     src   : E(read);
 3177     FA    : R;
 3178 %}
 3179 
 3180 // Floating Point Convert L->F
 3181 pipe_class fcvtL2F(regF dst, iRegL src) %{
 3182     single_instruction;
 3183     dst   : X(write);
 3184     src   : E(read);
 3185     FA    : R;
 3186 %}
 3187 
 3188 // Floating Point Convert D->F
 3189 pipe_class fcvtD2F(regD dst, regF src) %{
 3190     single_instruction;
 3191     dst   : X(write);
 3192     src   : E(read);
 3193     FA    : R;
 3194 %}
 3195 
 3196 // Floating Point Convert I->L
 3197 pipe_class fcvtI2L(regD dst, regF src) %{
 3198     single_instruction;
 3199     dst   : X(write);
 3200     src   : E(read);
 3201     FA    : R;
 3202 %}
 3203 
 3204 // Floating Point Convert D->F
 3205 pipe_class fcvtD2I(iRegI dst, regD src, flagsReg cr) %{
 3206     instruction_count(1); multiple_bundles;
 3207     dst   : X(write)+6;
 3208     src   : E(read);
 3209     FA    : R;
 3210 %}
 3211 
 3212 // Floating Point Convert D->L
 3213 pipe_class fcvtD2L(regD dst, regD src, flagsReg cr) %{
 3214     instruction_count(1); multiple_bundles;
 3215     dst   : X(write)+6;
 3216     src   : E(read);
 3217     FA    : R;
 3218 %}
 3219 
 3220 // Floating Point Convert F->I
 3221 pipe_class fcvtF2I(regF dst, regF src, flagsReg cr) %{
 3222     instruction_count(1); multiple_bundles;
 3223     dst   : X(write)+6;
 3224     src   : E(read);
 3225     FA    : R;
 3226 %}
 3227 
 3228 // Floating Point Convert F->L
 3229 pipe_class fcvtF2L(regD dst, regF src, flagsReg cr) %{
 3230     instruction_count(1); multiple_bundles;
 3231     dst   : X(write)+6;
 3232     src   : E(read);
 3233     FA    : R;
 3234 %}
 3235 
 3236 // Floating Point Convert I->F
 3237 pipe_class fcvtI2F(regF dst, regF src) %{
 3238     single_instruction;
 3239     dst   : X(write);
 3240     src   : E(read);
 3241     FA    : R;
 3242 %}
 3243 
 3244 // Floating Point Compare
 3245 pipe_class faddF_fcc_reg_reg_zero(flagsRegF cr, regF src1, regF src2, immI0 zero) %{
 3246     single_instruction;
 3247     cr    : X(write);
 3248     src1  : E(read);
 3249     src2  : E(read);
 3250     FA    : R;
 3251 %}
 3252 
 3253 // Floating Point Compare
 3254 pipe_class faddD_fcc_reg_reg_zero(flagsRegF cr, regD src1, regD src2, immI0 zero) %{
 3255     single_instruction;
 3256     cr    : X(write);
 3257     src1  : E(read);
 3258     src2  : E(read);
 3259     FA    : R;
 3260 %}
 3261 
 3262 // Floating Add Nop
 3263 pipe_class fadd_nop() %{
 3264     single_instruction;
 3265     FA  : R;
 3266 %}
 3267 
 3268 // Integer Store to Memory
 3269 pipe_class istore_mem_reg(memoryI mem, iRegI src) %{
 3270     single_instruction;
 3271     mem   : R(read);
 3272     src   : C(read);
 3273     MS    : R;
 3274 %}
 3275 
 3276 // Integer Store to Memory
 3277 pipe_class istore_mem_spORreg(memoryI mem, sp_ptr_RegP src) %{
 3278     single_instruction;
 3279     mem   : R(read);
 3280     src   : C(read);
 3281     MS    : R;
 3282 %}
 3283 
 3284 // Float Store
 3285 pipe_class fstoreF_mem_reg(memoryF mem, RegF src) %{
 3286     single_instruction;
 3287     mem : R(read);
 3288     src : C(read);
 3289     MS  : R;
 3290 %}
 3291 
 3292 // Float Store
 3293 pipe_class fstoreF_mem_zero(memoryF mem, immF0 src) %{
 3294     single_instruction;
 3295     mem : R(read);
 3296     MS  : R;
 3297 %}
 3298 
 3299 // Double Store
 3300 pipe_class fstoreD_mem_reg(memoryD mem, RegD src) %{
 3301     instruction_count(1);
 3302     mem : R(read);
 3303     src : C(read);
 3304     MS  : R;
 3305 %}
 3306 
 3307 // Double Store
 3308 pipe_class fstoreD_mem_zero(memoryD mem, immD0 src) %{
 3309     single_instruction;
 3310     mem : R(read);
 3311     MS  : R;
 3312 %}
 3313 
 3314 // Integer Load (when sign bit propagation not needed)
 3315 pipe_class iload_mem(iRegI dst, memoryI mem) %{
 3316     single_instruction;
 3317     mem : R(read);
 3318     dst : C(write);
 3319     MS  : R;
 3320 %}
 3321 
 3322 // Integer Load (when sign bit propagation or masking is needed)
 3323 pipe_class iload_mask_mem(iRegI dst, memoryI mem) %{
 3324     single_instruction;
 3325     mem : R(read);
 3326     dst : M(write);
 3327     MS  : R;
 3328 %}
 3329 
 3330 // Float Load
 3331 pipe_class floadF_mem(regF dst, memoryF mem) %{
 3332     single_instruction;
 3333     mem : R(read);
 3334     dst : M(write);
 3335     MS  : R;
 3336 %}
 3337 
 3338 // Float Load
 3339 pipe_class floadD_mem(regD dst, memoryD mem) %{
 3340     instruction_count(1); multiple_bundles; // Again, unaligned argument is only multiple case
 3341     mem : R(read);
 3342     dst : M(write);
 3343     MS  : R;
 3344 %}
 3345 
 3346 // Memory Nop
 3347 pipe_class mem_nop() %{
 3348     single_instruction;
 3349     MS  : R;
 3350 %}
 3351 
 3352 pipe_class sethi(iRegP dst, immI src) %{
 3353     single_instruction;
 3354     dst  : E(write);
 3355     IALU : R;
 3356 %}
 3357 
 3358 pipe_class loadPollP(iRegP poll) %{
 3359     single_instruction;
 3360     poll : R(read);
 3361     MS   : R;
 3362 %}
 3363 
 3364 pipe_class br(Universe br, label labl) %{
 3365     single_instruction_with_delay_slot;
 3366     BR  : R;
 3367 %}
 3368 
 3369 pipe_class br_cc(Universe br, cmpOp cmp, flagsReg cr, label labl) %{
 3370     single_instruction_with_delay_slot;
 3371     cr    : E(read);
 3372     BR    : R;
 3373 %}
 3374 
 3375 pipe_class br_reg(Universe br, cmpOp cmp, iRegI op1, label labl) %{
 3376     single_instruction_with_delay_slot;
 3377     op1 : E(read);
 3378     BR  : R;
 3379     MS  : R;
 3380 %}
 3381 
 3382 pipe_class br_nop() %{
 3383     single_instruction;
 3384     BR  : R;
 3385 %}
 3386 
 3387 pipe_class simple_call(method meth) %{
 3388     instruction_count(2); multiple_bundles; force_serialization;
 3389     fixed_latency(100);
 3390     BR  : R(1);
 3391     MS  : R(1);
 3392     A0  : R(1);
 3393 %}
 3394 
 3395 pipe_class compiled_call(method meth) %{
 3396     instruction_count(1); multiple_bundles; force_serialization;
 3397     fixed_latency(100);
 3398     MS  : R(1);
 3399 %}
 3400 
 3401 pipe_class call(method meth) %{
 3402     instruction_count(0); multiple_bundles; force_serialization;
 3403     fixed_latency(100);
 3404 %}
 3405 
 3406 pipe_class tail_call(Universe ignore, label labl) %{
 3407     single_instruction; has_delay_slot;
 3408     fixed_latency(100);
 3409     BR  : R(1);
 3410     MS  : R(1);
 3411 %}
 3412 
 3413 pipe_class ret(Universe ignore) %{
 3414     single_instruction; has_delay_slot;
 3415     BR  : R(1);
 3416     MS  : R(1);
 3417 %}
 3418 
 3419 // The real do-nothing guy
 3420 pipe_class empty( ) %{
 3421     instruction_count(0);
 3422 %}
 3423 
 3424 pipe_class long_memory_op() %{
 3425     instruction_count(0); multiple_bundles; force_serialization;
 3426     fixed_latency(25);
 3427     MS  : R(1);
 3428 %}
 3429 
 3430 // Check-cast
 3431 pipe_class partial_subtype_check_pipe(Universe ignore, iRegP array, iRegP match ) %{
 3432     array : R(read);
 3433     match  : R(read);
 3434     IALU   : R(2);
 3435     BR     : R(2);
 3436     MS     : R;
 3437 %}
 3438 
 3439 // Convert FPU flags into +1,0,-1
 3440 pipe_class floating_cmp( iRegI dst, regF src1, regF src2 ) %{
 3441     src1  : E(read);
 3442     src2  : E(read);
 3443     dst   : E(write);
 3444     FA    : R;
 3445     MS    : R(2);
 3446     BR    : R(2);
 3447 %}
 3448 
 3449 // Compare for p < q, and conditionally add y
 3450 pipe_class cadd_cmpltmask( iRegI p, iRegI q, iRegI y ) %{
 3451     p     : E(read);
 3452     q     : E(read);
 3453     y     : E(read);
 3454     IALU  : R(3)
 3455 %}
 3456 
 3457 // Perform a compare, then move conditionally in a branch delay slot.
 3458 pipe_class min_max( iRegI src2, iRegI srcdst ) %{
 3459     src2   : E(read);
 3460     srcdst : E(read);
 3461     IALU   : R;
 3462     BR     : R;
 3463 %}
 3464 
 3465 // Define the class for the Nop node
 3466 define %{
 3467    MachNop = ialu_nop;
 3468 %}
 3469 
 3470 %}
 3471 
 3472 //----------INSTRUCTIONS-------------------------------------------------------
 3473 
 3474 //------------Special Nop instructions for bundling - no match rules-----------
 3475 // Nop using the A0 functional unit
 3476 instruct Nop_A0() %{
 3477   ins_pipe(ialu_nop_A0);
 3478 %}
 3479 
 3480 // Nop using the A1 functional unit
 3481 instruct Nop_A1( ) %{
 3482   ins_pipe(ialu_nop_A1);
 3483 %}
 3484 
 3485 // Nop using the memory functional unit
 3486 instruct Nop_MS( ) %{
 3487   ins_pipe(mem_nop);
 3488 %}
 3489 
 3490 // Nop using the floating add functional unit
 3491 instruct Nop_FA( ) %{
 3492   ins_pipe(fadd_nop);
 3493 %}
 3494 
 3495 // Nop using the branch functional unit
 3496 instruct Nop_BR( ) %{
 3497   ins_pipe(br_nop);
 3498 %}
 3499 
 3500 //----------Load/Store/Move Instructions---------------------------------------
 3501 //----------Load Instructions--------------------------------------------------
 3502 // Load Byte (8bit signed)
 3503 instruct loadB(iRegI dst, memoryB mem) %{
 3504   match(Set dst (LoadB mem));
 3505   ins_cost(MEMORY_REF_COST);
 3506 
 3507   size(4);
 3508   format %{ "LDRSB   $dst,$mem\t! byte -> int" %}
 3509   ins_encode %{
 3510     __ ldrsb($dst$$Register, $mem$$Address);
 3511   %}
 3512   ins_pipe(iload_mask_mem);
 3513 %}
 3514 
 3515 // Load Byte (8bit signed) into a Long Register
 3516 instruct loadB2L(iRegL dst, memoryB mem) %{
 3517   match(Set dst (ConvI2L (LoadB mem)));
 3518   ins_cost(MEMORY_REF_COST);
 3519 
 3520   size(8);
 3521   format %{ "LDRSB $dst.lo,$mem\t! byte -> long\n\t"
 3522             "ASR   $dst.hi,$dst.lo,31" %}
 3523   ins_encode %{
 3524     __ ldrsb($dst$$Register, $mem$$Address);
 3525     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
 3526   %}
 3527   ins_pipe(iload_mask_mem);
 3528 %}
 3529 
 3530 // Load Unsigned Byte (8bit UNsigned) into an int reg
 3531 instruct loadUB(iRegI dst, memoryB mem) %{
 3532   match(Set dst (LoadUB mem));
 3533   ins_cost(MEMORY_REF_COST);
 3534 
 3535   size(4);
 3536   format %{ "LDRB   $dst,$mem\t! ubyte -> int" %}
 3537   ins_encode %{
 3538     __ ldrb($dst$$Register, $mem$$Address);
 3539   %}
 3540   ins_pipe(iload_mem);
 3541 %}
 3542 
 3543 // Load Unsigned Byte (8bit UNsigned) into a Long Register
 3544 instruct loadUB2L(iRegL dst, memoryB mem) %{
 3545   match(Set dst (ConvI2L (LoadUB mem)));
 3546   ins_cost(MEMORY_REF_COST);
 3547 
 3548   size(8);
 3549   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
 3550             "MOV   $dst.hi,0" %}
 3551   ins_encode %{
 3552     __ ldrb($dst$$Register, $mem$$Address);
 3553     __ mov($dst$$Register->successor(), 0);
 3554   %}
 3555   ins_pipe(iload_mem);
 3556 %}
 3557 
 3558 // Load Unsigned Byte (8 bit UNsigned) with immediate mask into Long Register
 3559 instruct loadUB2L_limmI(iRegL dst, memoryB mem, limmIlow8 mask) %{
 3560   match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
 3561 
 3562   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 3563   size(12);
 3564   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
 3565             "MOV   $dst.hi,0\n\t"
 3566             "AND  $dst.lo,$dst.lo,$mask" %}
 3567   ins_encode %{
 3568     __ ldrb($dst$$Register, $mem$$Address);
 3569     __ mov($dst$$Register->successor(), 0);
 3570     __ andr($dst$$Register, $dst$$Register, limmI_low($mask$$constant, 8));
 3571   %}
 3572   ins_pipe(iload_mem);
 3573 %}
 3574 
 3575 // Load Short (16bit signed)
 3576 
 3577 instruct loadS(iRegI dst, memoryS mem) %{
 3578   match(Set dst (LoadS mem));
 3579   ins_cost(MEMORY_REF_COST);
 3580 
 3581   size(4);
 3582   format %{ "LDRSH   $dst,$mem\t! short" %}
 3583   ins_encode %{
 3584     __ ldrsh($dst$$Register, $mem$$Address);
 3585   %}
 3586   ins_pipe(iload_mask_mem);
 3587 %}
 3588 
 3589 // Load Short (16 bit signed) to Byte (8 bit signed)
 3590 instruct loadS2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
 3591   match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
 3592   ins_cost(MEMORY_REF_COST);
 3593 
 3594   size(4);
 3595 
 3596   format %{ "LDRSB   $dst,$mem\t! short -> byte" %}
 3597   ins_encode %{
 3598     __ ldrsb($dst$$Register, $mem$$Address);
 3599   %}
 3600   ins_pipe(iload_mask_mem);
 3601 %}
 3602 
 3603 // Load Short (16bit signed) into a Long Register
 3604 instruct loadS2L(iRegL dst, memoryS mem) %{
 3605   match(Set dst (ConvI2L (LoadS mem)));
 3606   ins_cost(MEMORY_REF_COST);
 3607 
 3608   size(8);
 3609   format %{ "LDRSH $dst.lo,$mem\t! short -> long\n\t"
 3610             "ASR   $dst.hi,$dst.lo,31" %}
 3611   ins_encode %{
 3612     __ ldrsh($dst$$Register, $mem$$Address);
 3613     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
 3614   %}
 3615   ins_pipe(iload_mask_mem);
 3616 %}
 3617 
 3618 // Load Unsigned Short/Char (16bit UNsigned)
 3619 
 3620 
 3621 instruct loadUS(iRegI dst, memoryS mem) %{
 3622   match(Set dst (LoadUS mem));
 3623   ins_cost(MEMORY_REF_COST);
 3624 
 3625   size(4);
 3626   format %{ "LDRH   $dst,$mem\t! ushort/char" %}
 3627   ins_encode %{
 3628     __ ldrh($dst$$Register, $mem$$Address);
 3629   %}
 3630   ins_pipe(iload_mem);
 3631 %}
 3632 
 3633 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
 3634 instruct loadUS2B(iRegI dst, memoryB mem, immI_24 twentyfour) %{
 3635   match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
 3636   ins_cost(MEMORY_REF_COST);
 3637 
 3638   size(4);
 3639   format %{ "LDRSB   $dst,$mem\t! ushort -> byte" %}
 3640   ins_encode %{
 3641     __ ldrsb($dst$$Register, $mem$$Address);
 3642   %}
 3643   ins_pipe(iload_mask_mem);
 3644 %}
 3645 
 3646 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register
 3647 instruct loadUS2L(iRegL dst, memoryS mem) %{
 3648   match(Set dst (ConvI2L (LoadUS mem)));
 3649   ins_cost(MEMORY_REF_COST);
 3650 
 3651   size(8);
 3652   format %{ "LDRH  $dst.lo,$mem\t! short -> long\n\t"
 3653             "MOV   $dst.hi, 0" %}
 3654   ins_encode %{
 3655     __ ldrh($dst$$Register, $mem$$Address);
 3656     __ mov($dst$$Register->successor(), 0);
 3657   %}
 3658   ins_pipe(iload_mem);
 3659 %}
 3660 
 3661 // Load Unsigned Short/Char (16bit UNsigned) with mask 0xFF into a Long Register
 3662 instruct loadUS2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
 3663   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
 3664   ins_cost(MEMORY_REF_COST);
 3665 
 3666   size(8);
 3667   format %{ "LDRB  $dst.lo,$mem\t! \n\t"
 3668             "MOV   $dst.hi, 0" %}
 3669   ins_encode %{
 3670     __ ldrb($dst$$Register, $mem$$Address);
 3671     __ mov($dst$$Register->successor(), 0);
 3672   %}
 3673   ins_pipe(iload_mem);
 3674 %}
 3675 
 3676 // Load Unsigned Short/Char (16bit UNsigned) with a immediate mask into a Long Register
 3677 instruct loadUS2L_limmI(iRegL dst, memoryS mem, limmI mask) %{
 3678   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
 3679   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 3680 
 3681   size(12);
 3682   format %{ "LDRH   $dst,$mem\t! ushort/char & mask -> long\n\t"
 3683             "MOV    $dst.hi, 0\n\t"
 3684             "AND    $dst,$dst,$mask" %}
 3685   ins_encode %{
 3686     __ ldrh($dst$$Register, $mem$$Address);
 3687     __ mov($dst$$Register->successor(), 0);
 3688     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
 3689   %}
 3690   ins_pipe(iload_mem);
 3691 %}
 3692 
 3693 // Load Integer
 3694 
 3695 
 3696 instruct loadI(iRegI dst, memoryI mem) %{
 3697   match(Set dst (LoadI mem));
 3698   ins_cost(MEMORY_REF_COST);
 3699 
 3700   size(4);
 3701   format %{ "ldr_s32 $dst,$mem\t! int" %}
 3702   ins_encode %{
 3703     __ ldr_s32($dst$$Register, $mem$$Address);
 3704   %}
 3705   ins_pipe(iload_mem);
 3706 %}
 3707 
 3708 // Load Integer to Byte (8 bit signed)
 3709 instruct loadI2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
 3710   match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
 3711   ins_cost(MEMORY_REF_COST);
 3712 
 3713   size(4);
 3714 
 3715   format %{ "LDRSB   $dst,$mem\t! int -> byte" %}
 3716   ins_encode %{
 3717     __ ldrsb($dst$$Register, $mem$$Address);
 3718   %}
 3719   ins_pipe(iload_mask_mem);
 3720 %}
 3721 
 3722 // Load Integer to Unsigned Byte (8 bit UNsigned)
 3723 instruct loadI2UB(iRegI dst, memoryB mem, immI_255 mask) %{
 3724   match(Set dst (AndI (LoadI mem) mask));
 3725   ins_cost(MEMORY_REF_COST);
 3726 
 3727   size(4);
 3728 
 3729   format %{ "LDRB   $dst,$mem\t! int -> ubyte" %}
 3730   ins_encode %{
 3731     __ ldrb($dst$$Register, $mem$$Address);
 3732   %}
 3733   ins_pipe(iload_mask_mem);
 3734 %}
 3735 
 3736 // Load Integer to Short (16 bit signed)
 3737 instruct loadI2S(iRegI dst, memoryS mem, immI_16 sixteen) %{
 3738   match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
 3739   ins_cost(MEMORY_REF_COST);
 3740 
 3741   size(4);
 3742   format %{ "LDRSH   $dst,$mem\t! int -> short" %}
 3743   ins_encode %{
 3744     __ ldrsh($dst$$Register, $mem$$Address);
 3745   %}
 3746   ins_pipe(iload_mask_mem);
 3747 %}
 3748 
 3749 // Load Integer to Unsigned Short (16 bit UNsigned)
 3750 instruct loadI2US(iRegI dst, memoryS mem, immI_65535 mask) %{
 3751   match(Set dst (AndI (LoadI mem) mask));
 3752   ins_cost(MEMORY_REF_COST);
 3753 
 3754   size(4);
 3755   format %{ "LDRH   $dst,$mem\t! int -> ushort/char" %}
 3756   ins_encode %{
 3757     __ ldrh($dst$$Register, $mem$$Address);
 3758   %}
 3759   ins_pipe(iload_mask_mem);
 3760 %}
 3761 
 3762 // Load Integer into a Long Register
 3763 instruct loadI2L(iRegL dst, memoryI mem) %{
 3764   match(Set dst (ConvI2L (LoadI mem)));
 3765   ins_cost(MEMORY_REF_COST);
 3766 
 3767   size(8);
 3768   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
 3769             "ASR   $dst.hi,$dst.lo,31\t! int->long" %}
 3770   ins_encode %{
 3771     __ ldr($dst$$Register, $mem$$Address);
 3772     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
 3773   %}
 3774   ins_pipe(iload_mask_mem);
 3775 %}
 3776 
 3777 // Load Integer with mask 0xFF into a Long Register
 3778 instruct loadI2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
 3779   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3780   ins_cost(MEMORY_REF_COST);
 3781 
 3782   size(8);
 3783   format %{ "LDRB   $dst.lo,$mem\t! int & 0xFF -> long\n\t"
 3784             "MOV    $dst.hi, 0" %}
 3785   ins_encode %{
 3786     __ ldrb($dst$$Register, $mem$$Address);
 3787     __ mov($dst$$Register->successor(), 0);
 3788   %}
 3789   ins_pipe(iload_mem);
 3790 %}
 3791 
 3792 // Load Integer with mask 0xFFFF into a Long Register
 3793 instruct loadI2L_immI_65535(iRegL dst, memoryS mem, immI_65535 mask) %{
 3794   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3795   ins_cost(MEMORY_REF_COST);
 3796 
 3797   size(8);
 3798   format %{ "LDRH   $dst,$mem\t! int & 0xFFFF -> long\n\t"
 3799             "MOV    $dst.hi, 0" %}
 3800   ins_encode %{
 3801     __ ldrh($dst$$Register, $mem$$Address);
 3802     __ mov($dst$$Register->successor(), 0);
 3803   %}
 3804   ins_pipe(iload_mask_mem);
 3805 %}
 3806 
 3807 // Load Integer with a 31-bit immediate mask into a Long Register
 3808 instruct loadI2L_limmU31(iRegL dst, memoryI mem, limmU31 mask) %{
 3809   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3810   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 3811 
 3812   size(12);
 3813   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
 3814             "MOV    $dst.hi, 0\n\t"
 3815             "AND   $dst,$dst,$mask" %}
 3816 
 3817   ins_encode %{
 3818     __ ldr($dst$$Register, $mem$$Address);
 3819     __ mov($dst$$Register->successor(), 0);
 3820     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
 3821   %}
 3822   ins_pipe(iload_mem);
 3823 %}
 3824 
 3825 // Load Integer with a 31-bit mask into a Long Register
 3826 // FIXME: use iRegI mask, remove tmp?
 3827 instruct loadI2L_immU31(iRegL dst, memoryI mem, immU31 mask, iRegI tmp) %{
 3828   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3829   effect(TEMP dst, TEMP tmp);
 3830 
 3831   ins_cost(MEMORY_REF_COST + 4*DEFAULT_COST);
 3832   size(20);
 3833   format %{ "LDR      $mem,$dst\t! int & 31-bit mask -> long\n\t"
 3834             "MOV      $dst.hi, 0\n\t"
 3835             "MOV_SLOW $tmp,$mask\n\t"
 3836             "AND      $dst,$tmp,$dst" %}
 3837   ins_encode %{
 3838     __ ldr($dst$$Register, $mem$$Address);
 3839     __ mov($dst$$Register->successor(), 0);
 3840     __ mov_slow($tmp$$Register, $mask$$constant);
 3841     __ andr($dst$$Register, $dst$$Register, $tmp$$Register);
 3842   %}
 3843   ins_pipe(iload_mem);
 3844 %}
 3845 
 3846 // Load Unsigned Integer into a Long Register
 3847 instruct loadUI2L(iRegL dst, memoryI mem, immL_32bits mask) %{
 3848   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
 3849   ins_cost(MEMORY_REF_COST);
 3850 
 3851   size(8);
 3852   format %{ "LDR   $dst.lo,$mem\t! uint -> long\n\t"
 3853             "MOV   $dst.hi,0" %}
 3854   ins_encode %{
 3855     __ ldr($dst$$Register, $mem$$Address);
 3856     __ mov($dst$$Register->successor(), 0);
 3857   %}
 3858   ins_pipe(iload_mem);
 3859 %}
 3860 
 3861 // Load Long
 3862 
 3863 
 3864 instruct loadL(iRegLd dst, memoryL mem ) %{
 3865   predicate(!((LoadLNode*)n)->require_atomic_access());
 3866   match(Set dst (LoadL mem));
 3867   effect(TEMP dst);
 3868   ins_cost(MEMORY_REF_COST);
 3869 
 3870   size(4);
 3871   format %{ "ldr_64  $dst,$mem\t! long" %}
 3872   ins_encode %{
 3873     __ ldr_64($dst$$Register, $mem$$Address);
 3874   %}
 3875   ins_pipe(iload_mem);
 3876 %}
 3877 
 3878 instruct loadL_2instr(iRegL dst, memorylong mem ) %{
 3879   predicate(!((LoadLNode*)n)->require_atomic_access());
 3880   match(Set dst (LoadL mem));
 3881   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
 3882 
 3883   size(8);
 3884   format %{ "LDR    $dst.lo,$mem \t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
 3885             "LDR    $dst.hi,$mem+4 or $mem" %}
 3886   ins_encode %{
 3887     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 3888     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 3889 
 3890     if ($dst$$Register == reg_to_register_object($mem$$base)) {
 3891       __ ldr($dst$$Register->successor(), Amemhi);
 3892       __ ldr($dst$$Register, Amemlo);
 3893     } else {
 3894       __ ldr($dst$$Register, Amemlo);
 3895       __ ldr($dst$$Register->successor(), Amemhi);
 3896     }
 3897   %}
 3898   ins_pipe(iload_mem);
 3899 %}
 3900 
 3901 instruct loadL_volatile(iRegL dst, indirect mem ) %{
 3902   predicate(((LoadLNode*)n)->require_atomic_access());
 3903   match(Set dst (LoadL mem));
 3904   ins_cost(MEMORY_REF_COST);
 3905 
 3906   size(4);
 3907   format %{ "LDMIA    $dst,$mem\t! long" %}
 3908   ins_encode %{
 3909     // FIXME: why is ldmia considered atomic?  Should be ldrexd
 3910     RegisterSet set($dst$$Register);
 3911     set = set | reg_to_register_object($dst$$reg + 1);
 3912     __ ldmia(reg_to_register_object($mem$$base), set);
 3913   %}
 3914   ins_pipe(iload_mem);
 3915 %}
 3916 
 3917 instruct loadL_volatile_fp(iRegL dst, memoryD mem ) %{
 3918   predicate(((LoadLNode*)n)->require_atomic_access());
 3919   match(Set dst (LoadL mem));
 3920   ins_cost(MEMORY_REF_COST);
 3921 
 3922   size(8);
 3923   format %{ "FLDD      S14, $mem"
 3924             "FMRRD    $dst, S14\t! long \n't" %}
 3925   ins_encode %{
 3926     __ fldd(S14, $mem$$Address);
 3927     __ fmrrd($dst$$Register, $dst$$Register->successor(), S14);
 3928   %}
 3929   ins_pipe(iload_mem);
 3930 %}
 3931 
 3932 instruct loadL_unaligned(iRegL dst, memorylong mem ) %{
 3933   match(Set dst (LoadL_unaligned mem));
 3934   ins_cost(MEMORY_REF_COST);
 3935 
 3936   size(8);
 3937   format %{ "LDR    $dst.lo,$mem\t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
 3938             "LDR    $dst.hi,$mem+4" %}
 3939   ins_encode %{
 3940     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 3941     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 3942 
 3943     if ($dst$$Register == reg_to_register_object($mem$$base)) {
 3944       __ ldr($dst$$Register->successor(), Amemhi);
 3945       __ ldr($dst$$Register, Amemlo);
 3946     } else {
 3947       __ ldr($dst$$Register, Amemlo);
 3948       __ ldr($dst$$Register->successor(), Amemhi);
 3949     }
 3950   %}
 3951   ins_pipe(iload_mem);
 3952 %}
 3953 
 3954 // Load Range
 3955 instruct loadRange(iRegI dst, memoryI mem) %{
 3956   match(Set dst (LoadRange mem));
 3957   ins_cost(MEMORY_REF_COST);
 3958 
 3959   size(4);
 3960   format %{ "LDR_u32 $dst,$mem\t! range" %}
 3961   ins_encode %{
 3962     __ ldr_u32($dst$$Register, $mem$$Address);
 3963   %}
 3964   ins_pipe(iload_mem);
 3965 %}
 3966 
 3967 // Load Pointer
 3968 
 3969 
 3970 instruct loadP(iRegP dst, memoryP mem) %{
 3971   match(Set dst (LoadP mem));
 3972   ins_cost(MEMORY_REF_COST);
 3973   size(4);
 3974 
 3975   format %{ "LDR   $dst,$mem\t! ptr" %}
 3976   ins_encode %{
 3977     __ ldr($dst$$Register, $mem$$Address);
 3978   %}
 3979   ins_pipe(iload_mem);
 3980 %}
 3981 
 3982 #ifdef XXX
 3983 // FIXME XXXX
 3984 //instruct loadSP(iRegP dst, memoryP mem) %{
 3985 instruct loadSP(SPRegP dst, memoryP mem, iRegP tmp) %{
 3986   match(Set dst (LoadP mem));
 3987   effect(TEMP tmp);
 3988   ins_cost(MEMORY_REF_COST+1);
 3989   size(8);
 3990 
 3991   format %{ "LDR   $tmp,$mem\t! ptr\n\t"
 3992             "MOV   $dst,$tmp\t! ptr" %}
 3993   ins_encode %{
 3994     __ ldr($tmp$$Register, $mem$$Address);
 3995     __ mov($dst$$Register, $tmp$$Register);
 3996   %}
 3997   ins_pipe(iload_mem);
 3998 %}
 3999 #endif
 4000 
 4001 #ifdef _LP64
 4002 // Load Compressed Pointer
 4003 
 4004 // XXX This variant shouldn't be necessary if 6217251 is implemented
 4005 instruct loadNoff(iRegN dst, memoryScaledI mem, aimmX off, iRegP tmp) %{
 4006   match(Set dst (LoadN (AddP mem off)));
 4007   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
 4008   effect(TEMP tmp);
 4009   size(4 * 2);
 4010 
 4011   format %{ "ldr_u32 $dst,$mem+$off\t! compressed ptr temp=$tmp" %}
 4012   ins_encode %{
 4013     Register base = reg_to_register_object($mem$$base);
 4014     __ add($tmp$$Register, base, $off$$constant);
 4015     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 4016     __ ldr_u32($dst$$Register, nmem);
 4017   %}
 4018   ins_pipe(iload_mem);
 4019 %}
 4020 
 4021 instruct loadN(iRegN dst, memoryI mem) %{
 4022   match(Set dst (LoadN mem));
 4023   ins_cost(MEMORY_REF_COST);
 4024   size(4);
 4025 
 4026   format %{ "ldr_u32 $dst,$mem\t! compressed ptr" %}
 4027   ins_encode %{
 4028     __ ldr_u32($dst$$Register, $mem$$Address);
 4029   %}
 4030   ins_pipe(iload_mem);
 4031 %}
 4032 #endif
 4033 
 4034 // Load Klass Pointer
 4035 instruct loadKlass(iRegP dst, memoryI mem) %{
 4036   match(Set dst (LoadKlass mem));
 4037   ins_cost(MEMORY_REF_COST);
 4038   size(4);
 4039 
 4040   format %{ "LDR   $dst,$mem\t! klass ptr" %}
 4041   ins_encode %{
 4042     __ ldr($dst$$Register, $mem$$Address);
 4043   %}
 4044   ins_pipe(iload_mem);
 4045 %}
 4046 
 4047 #ifdef _LP64
 4048 // Load narrow Klass Pointer
 4049 instruct loadNKlass(iRegN dst, memoryI mem) %{
 4050   match(Set dst (LoadNKlass mem));
 4051   ins_cost(MEMORY_REF_COST);
 4052   size(4);
 4053 
 4054   format %{ "ldr_u32 $dst,$mem\t! compressed klass ptr" %}
 4055   ins_encode %{
 4056     __ ldr_u32($dst$$Register, $mem$$Address);
 4057   %}
 4058   ins_pipe(iload_mem);
 4059 %}
 4060 #endif
 4061 
 4062 
 4063 instruct loadD(regD dst, memoryD mem) %{
 4064   match(Set dst (LoadD mem));
 4065   ins_cost(MEMORY_REF_COST);
 4066 
 4067   size(4);
 4068   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
 4069   // only LDREXD and STREXD are 64-bit single-copy atomic
 4070   format %{ "FLDD   $dst,$mem" %}
 4071   ins_encode %{
 4072     __ ldr_double($dst$$FloatRegister, $mem$$Address);
 4073   %}
 4074   ins_pipe(floadD_mem);
 4075 %}
 4076 
 4077 // Load Double - UNaligned
 4078 instruct loadD_unaligned(regD_low dst, memoryF2 mem ) %{
 4079   match(Set dst (LoadD_unaligned mem));
 4080   ins_cost(MEMORY_REF_COST*2+DEFAULT_COST);
 4081   size(8);
 4082   format %{ "FLDS    $dst.lo,$mem\t! misaligned double\n"
 4083           "\tFLDS    $dst.hi,$mem+4\t!" %}
 4084   ins_encode %{
 4085     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 4086     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 4087       __ flds($dst$$FloatRegister, Amemlo);
 4088       __ flds($dst$$FloatRegister->successor(), Amemhi);
 4089   %}
 4090   ins_pipe(iload_mem);
 4091 %}
 4092 
 4093 
 4094 instruct loadF(regF dst, memoryF mem) %{
 4095   match(Set dst (LoadF mem));
 4096 
 4097   ins_cost(MEMORY_REF_COST);
 4098   size(4);
 4099   format %{ "FLDS    $dst,$mem" %}
 4100   ins_encode %{
 4101     __ ldr_float($dst$$FloatRegister, $mem$$Address);
 4102   %}
 4103   ins_pipe(floadF_mem);
 4104 %}
 4105 
 4106 
 4107 // // Load Constant
 4108 instruct loadConI( iRegI dst, immI src ) %{
 4109   match(Set dst src);
 4110   ins_cost(DEFAULT_COST * 3/2);
 4111   format %{ "MOV_SLOW    $dst, $src" %}
 4112   ins_encode %{
 4113     __ mov_slow($dst$$Register, $src$$constant);
 4114   %}
 4115   ins_pipe(ialu_hi_lo_reg);
 4116 %}
 4117 
 4118 instruct loadConIMov( iRegI dst, immIMov src ) %{
 4119   match(Set dst src);
 4120   size(4);
 4121   format %{ "MOV    $dst, $src" %}
 4122   ins_encode %{
 4123     __ mov($dst$$Register, $src$$constant);
 4124   %}
 4125   ins_pipe(ialu_imm);
 4126 %}
 4127 
 4128 instruct loadConIMovn( iRegI dst, immIRotn src ) %{
 4129   match(Set dst src);
 4130   size(4);
 4131   format %{ "MVN    $dst, ~$src" %}
 4132   ins_encode %{
 4133     __ mvn($dst$$Register, ~$src$$constant);
 4134   %}
 4135   ins_pipe(ialu_imm_n);
 4136 %}
 4137 
 4138 instruct loadConI16( iRegI dst, immI16 src ) %{
 4139   match(Set dst src);
 4140   size(4);
 4141   format %{ "MOVW    $dst, $src" %}
 4142   ins_encode %{
 4143     __ movw($dst$$Register, $src$$constant);
 4144   %}
 4145   ins_pipe(ialu_imm_n);
 4146 %}
 4147 
 4148 instruct loadConP(iRegP dst, immP src) %{
 4149   match(Set dst src);
 4150   ins_cost(DEFAULT_COST * 3/2);
 4151   format %{ "MOV_SLOW    $dst,$src\t!ptr" %}
 4152   ins_encode %{
 4153     relocInfo::relocType constant_reloc = _opnds[1]->constant_reloc();
 4154     intptr_t val = $src$$constant;
 4155     if (constant_reloc == relocInfo::oop_type) {
 4156       __ mov_oop($dst$$Register, (jobject)val);
 4157     } else if (constant_reloc == relocInfo::metadata_type) {
 4158       __ mov_metadata($dst$$Register, (Metadata*)val);
 4159     } else {
 4160       __ mov_slow($dst$$Register, val);
 4161     }
 4162   %}
 4163   ins_pipe(loadConP);
 4164 %}
 4165 
 4166 
 4167 instruct loadConL(iRegL dst, immL src) %{
 4168   match(Set dst src);
 4169   ins_cost(DEFAULT_COST * 4);
 4170   format %{ "MOV_SLOW   $dst.lo, $src & 0x0FFFFFFFFL \t! long\n\t"
 4171             "MOV_SLOW   $dst.hi, $src >> 32" %}
 4172   ins_encode %{
 4173     __ mov_slow(reg_to_register_object($dst$$reg), $src$$constant & 0x0FFFFFFFFL);
 4174     __ mov_slow(reg_to_register_object($dst$$reg + 1), ((julong)($src$$constant)) >> 32);
 4175   %}
 4176   ins_pipe(loadConL);
 4177 %}
 4178 
 4179 instruct loadConL16( iRegL dst, immL16 src ) %{
 4180   match(Set dst src);
 4181   ins_cost(DEFAULT_COST * 2);
 4182 
 4183   size(8);
 4184   format %{ "MOVW    $dst.lo, $src \n\t"
 4185             "MOVW    $dst.hi, 0 \n\t" %}
 4186   ins_encode %{
 4187     __ movw($dst$$Register, $src$$constant);
 4188     __ movw($dst$$Register->successor(), 0);
 4189   %}
 4190   ins_pipe(ialu_imm);
 4191 %}
 4192 
 4193 instruct loadConF_imm8(regF dst, imm8F src) %{
 4194   match(Set dst src);
 4195   ins_cost(DEFAULT_COST);
 4196   size(4);
 4197 
 4198   format %{ "FCONSTS      $dst, $src"%}
 4199 
 4200   ins_encode %{
 4201     __ fconsts($dst$$FloatRegister, Assembler::float_num($src$$constant).imm8());
 4202   %}
 4203   ins_pipe(loadConFD); // FIXME
 4204 %}
 4205 
 4206 
 4207 instruct loadConF(regF dst, immF src, iRegI tmp) %{
 4208   match(Set dst src);
 4209   ins_cost(DEFAULT_COST * 2);
 4210   effect(TEMP tmp);
 4211   size(3*4);
 4212 
 4213   format %{ "MOV_SLOW  $tmp, $src\n\t"
 4214             "FMSR      $dst, $tmp"%}
 4215 
 4216   ins_encode %{
 4217     // FIXME revisit once 6961697 is in
 4218     union {
 4219       jfloat f;
 4220       int i;
 4221     } v;
 4222     v.f = $src$$constant;
 4223     __ mov_slow($tmp$$Register, v.i);
 4224     __ fmsr($dst$$FloatRegister, $tmp$$Register);
 4225   %}
 4226   ins_pipe(loadConFD); // FIXME
 4227 %}
 4228 
 4229 instruct loadConD_imm8(regD dst, imm8D src) %{
 4230   match(Set dst src);
 4231   ins_cost(DEFAULT_COST);
 4232   size(4);
 4233 
 4234   format %{ "FCONSTD      $dst, $src"%}
 4235 
 4236   ins_encode %{
 4237     __ fconstd($dst$$FloatRegister, Assembler::double_num($src$$constant).imm8());
 4238   %}
 4239   ins_pipe(loadConFD); // FIXME
 4240 %}
 4241 
 4242 instruct loadConD(regD dst, immD src, iRegP tmp) %{
 4243   match(Set dst src);
 4244   effect(TEMP tmp);
 4245   ins_cost(MEMORY_REF_COST);
 4246   format %{ "FLDD  $dst, [$constanttablebase + $constantoffset]\t! load from constant table: double=$src" %}
 4247 
 4248   ins_encode %{
 4249     Register r = $constanttablebase;
 4250     int offset  = $constantoffset($src);
 4251     if (!is_memoryD(offset)) {                // can't use a predicate
 4252                                               // in load constant instructs
 4253       __ add_slow($tmp$$Register, r, offset);
 4254       r = $tmp$$Register;
 4255       offset = 0;
 4256     }
 4257     __ ldr_double($dst$$FloatRegister, Address(r, offset));
 4258   %}
 4259   ins_pipe(loadConFD);
 4260 %}
 4261 
 4262 // Prefetch instructions.
 4263 // Must be safe to execute with invalid address (cannot fault).
 4264 
 4265 instruct prefetchAlloc_mp( memoryP mem ) %{
 4266   predicate(VM_Version::has_multiprocessing_extensions());
 4267   match( PrefetchAllocation mem );
 4268   ins_cost(MEMORY_REF_COST);
 4269   size(4);
 4270 
 4271   format %{ "PLDW $mem\t! Prefetch allocation" %}
 4272   ins_encode %{
 4273     __ pldw($mem$$Address);
 4274   %}
 4275   ins_pipe(iload_mem);
 4276 %}
 4277 
 4278 instruct prefetchAlloc_sp( memoryP mem ) %{
 4279   predicate(!VM_Version::has_multiprocessing_extensions());
 4280   match( PrefetchAllocation mem );
 4281   ins_cost(MEMORY_REF_COST);
 4282   size(4);
 4283 
 4284   format %{ "PLD $mem\t! Prefetch allocation" %}
 4285   ins_encode %{
 4286     __ pld($mem$$Address);
 4287   %}
 4288   ins_pipe(iload_mem);
 4289 %}
 4290 
 4291 
 4292 //----------Store Instructions-------------------------------------------------
 4293 // Store Byte
 4294 instruct storeB(memoryB mem, store_RegI src) %{
 4295   match(Set mem (StoreB mem src));
 4296   ins_cost(MEMORY_REF_COST);
 4297 
 4298   size(4);
 4299   format %{ "STRB    $src,$mem\t! byte" %}
 4300   ins_encode %{
 4301     __ strb($src$$Register, $mem$$Address);
 4302   %}
 4303   ins_pipe(istore_mem_reg);
 4304 %}
 4305 
 4306 instruct storeCM(memoryB mem, store_RegI src) %{
 4307   match(Set mem (StoreCM mem src));
 4308   ins_cost(MEMORY_REF_COST);
 4309 
 4310   size(4);
 4311   format %{ "STRB    $src,$mem\t! CMS card-mark byte" %}
 4312   ins_encode %{
 4313     __ strb($src$$Register, $mem$$Address);
 4314   %}
 4315   ins_pipe(istore_mem_reg);
 4316 %}
 4317 
 4318 // Store Char/Short
 4319 
 4320 
 4321 instruct storeC(memoryS mem, store_RegI src) %{
 4322   match(Set mem (StoreC mem src));
 4323   ins_cost(MEMORY_REF_COST);
 4324 
 4325   size(4);
 4326   format %{ "STRH    $src,$mem\t! short" %}
 4327   ins_encode %{
 4328     __ strh($src$$Register, $mem$$Address);
 4329   %}
 4330   ins_pipe(istore_mem_reg);
 4331 %}
 4332 
 4333 // Store Integer
 4334 
 4335 
 4336 instruct storeI(memoryI mem, store_RegI src) %{
 4337   match(Set mem (StoreI mem src));
 4338   ins_cost(MEMORY_REF_COST);
 4339 
 4340   size(4);
 4341   format %{ "str_32 $src,$mem" %}
 4342   ins_encode %{
 4343     __ str_32($src$$Register, $mem$$Address);
 4344   %}
 4345   ins_pipe(istore_mem_reg);
 4346 %}
 4347 
 4348 // Store Long
 4349 
 4350 
 4351 instruct storeL(memoryL mem, store_RegLd src) %{
 4352   predicate(!((StoreLNode*)n)->require_atomic_access());
 4353   match(Set mem (StoreL mem src));
 4354   ins_cost(MEMORY_REF_COST);
 4355 
 4356   size(4);
 4357   format %{ "str_64  $src,$mem\t! long\n\t" %}
 4358 
 4359   ins_encode %{
 4360     __ str_64($src$$Register, $mem$$Address);
 4361   %}
 4362   ins_pipe(istore_mem_reg);
 4363 %}
 4364 
 4365 instruct storeL_2instr(memorylong mem, iRegL src) %{
 4366   predicate(!((StoreLNode*)n)->require_atomic_access());
 4367   match(Set mem (StoreL mem src));
 4368   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
 4369 
 4370   size(8);
 4371   format %{ "STR    $src.lo,$mem\t! long\n\t"
 4372             "STR    $src.hi,$mem+4" %}
 4373 
 4374   ins_encode %{
 4375     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 4376     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 4377     __ str($src$$Register, Amemlo);
 4378     __ str($src$$Register->successor(), Amemhi);
 4379   %}
 4380   ins_pipe(istore_mem_reg);
 4381 %}
 4382 
 4383 instruct storeL_volatile(indirect mem, iRegL src) %{
 4384   predicate(((StoreLNode*)n)->require_atomic_access());
 4385   match(Set mem (StoreL mem src));
 4386   ins_cost(MEMORY_REF_COST);
 4387   size(4);
 4388   format %{ "STMIA    $src,$mem\t! long" %}
 4389   ins_encode %{
 4390     // FIXME: why is stmia considered atomic?  Should be strexd
 4391     RegisterSet set($src$$Register);
 4392     set = set | reg_to_register_object($src$$reg + 1);
 4393     __ stmia(reg_to_register_object($mem$$base), set);
 4394   %}
 4395   ins_pipe(istore_mem_reg);
 4396 %}
 4397 
 4398 instruct storeL_volatile_fp(memoryD mem, iRegL src) %{
 4399   predicate(((StoreLNode*)n)->require_atomic_access());
 4400   match(Set mem (StoreL mem src));
 4401   ins_cost(MEMORY_REF_COST);
 4402   size(8);
 4403   format %{ "FMDRR    S14, $src\t! long \n\t"
 4404             "FSTD     S14, $mem" %}
 4405   ins_encode %{
 4406     __ fmdrr(S14, $src$$Register, $src$$Register->successor());
 4407     __ fstd(S14, $mem$$Address);
 4408   %}
 4409   ins_pipe(istore_mem_reg);
 4410 %}
 4411 
 4412 #ifdef XXX
 4413 // Move SP Pointer
 4414 //instruct movSP(sp_ptr_RegP dst, SPRegP src) %{
 4415 //instruct movSP(iRegP dst, SPRegP src) %{
 4416 instruct movSP(store_ptr_RegP dst, SPRegP src) %{
 4417   match(Set dst src);
 4418 //predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con == TypeFunc::FramePtr);
 4419   ins_cost(MEMORY_REF_COST);
 4420   size(4);
 4421 
 4422   format %{ "MOV    $dst,$src\t! SP ptr\n\t" %}
 4423   ins_encode %{
 4424     assert(false, "XXX1 got here");
 4425     __ mov($dst$$Register, SP);
 4426     __ mov($dst$$Register, $src$$Register);
 4427   %}
 4428   ins_pipe(ialu_reg);
 4429 %}
 4430 #endif
 4431 
 4432 
 4433 // Store Pointer
 4434 
 4435 
 4436 instruct storeP(memoryP mem, store_ptr_RegP src) %{
 4437   match(Set mem (StoreP mem src));
 4438   ins_cost(MEMORY_REF_COST);
 4439   size(4);
 4440 
 4441   format %{ "STR    $src,$mem\t! ptr" %}
 4442   ins_encode %{
 4443     __ str($src$$Register, $mem$$Address);
 4444   %}
 4445   ins_pipe(istore_mem_spORreg);
 4446 %}
 4447 
 4448 
 4449 #ifdef _LP64
 4450 // Store Compressed Pointer
 4451 
 4452 
 4453 instruct storeN(memoryI mem, store_RegN src) %{
 4454   match(Set mem (StoreN mem src));
 4455   ins_cost(MEMORY_REF_COST);
 4456   size(4);
 4457 
 4458   format %{ "str_32 $src,$mem\t! compressed ptr" %}
 4459   ins_encode %{
 4460     __ str_32($src$$Register, $mem$$Address);
 4461   %}
 4462   ins_pipe(istore_mem_reg);
 4463 %}
 4464 
 4465 
 4466 // Store Compressed Klass Pointer
 4467 instruct storeNKlass(memoryI mem, store_RegN src) %{
 4468   match(Set mem (StoreNKlass mem src));
 4469   ins_cost(MEMORY_REF_COST);
 4470   size(4);
 4471 
 4472   format %{ "str_32 $src,$mem\t! compressed klass ptr" %}
 4473   ins_encode %{
 4474     __ str_32($src$$Register, $mem$$Address);
 4475   %}
 4476   ins_pipe(istore_mem_reg);
 4477 %}
 4478 #endif
 4479 
 4480 // Store Double
 4481 
 4482 
 4483 instruct storeD(memoryD mem, regD src) %{
 4484   match(Set mem (StoreD mem src));
 4485   ins_cost(MEMORY_REF_COST);
 4486 
 4487   size(4);
 4488   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
 4489   // only LDREXD and STREXD are 64-bit single-copy atomic
 4490   format %{ "FSTD   $src,$mem" %}
 4491   ins_encode %{
 4492     __ str_double($src$$FloatRegister, $mem$$Address);
 4493   %}
 4494   ins_pipe(fstoreD_mem_reg);
 4495 %}
 4496 
 4497 
 4498 // Store Float
 4499 
 4500 
 4501 instruct storeF( memoryF mem, regF src) %{
 4502   match(Set mem (StoreF mem src));
 4503   ins_cost(MEMORY_REF_COST);
 4504 
 4505   size(4);
 4506   format %{ "FSTS    $src,$mem" %}
 4507   ins_encode %{
 4508     __ str_float($src$$FloatRegister, $mem$$Address);
 4509   %}
 4510   ins_pipe(fstoreF_mem_reg);
 4511 %}
 4512 
 4513 
 4514 //----------MemBar Instructions-----------------------------------------------
 4515 // Memory barrier flavors
 4516 
 4517 // pattern-match out unnecessary membars
 4518 instruct membar_storestore() %{
 4519   match(MemBarStoreStore);
 4520   ins_cost(4*MEMORY_REF_COST);
 4521 
 4522   size(4);
 4523   format %{ "MEMBAR-storestore" %}
 4524   ins_encode %{
 4525     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore), noreg);
 4526   %}
 4527   ins_pipe(long_memory_op);
 4528 %}
 4529 
 4530 instruct membar_acquire() %{
 4531   match(MemBarAcquire);
 4532   match(LoadFence);
 4533   ins_cost(4*MEMORY_REF_COST);
 4534 
 4535   size(4);
 4536   format %{ "MEMBAR-acquire" %}
 4537   ins_encode %{
 4538     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), noreg);
 4539   %}
 4540   ins_pipe(long_memory_op);
 4541 %}
 4542 
 4543 instruct membar_acquire_lock() %{
 4544   match(MemBarAcquireLock);
 4545   ins_cost(0);
 4546 
 4547   size(0);
 4548   format %{ "!MEMBAR-acquire (CAS in prior FastLock so empty encoding)" %}
 4549   ins_encode( );
 4550   ins_pipe(empty);
 4551 %}
 4552 
 4553 instruct membar_release() %{
 4554   match(MemBarRelease);
 4555   match(StoreFence);
 4556   ins_cost(4*MEMORY_REF_COST);
 4557 
 4558   size(4);
 4559   format %{ "MEMBAR-release" %}
 4560   ins_encode %{
 4561     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), noreg);
 4562   %}
 4563   ins_pipe(long_memory_op);
 4564 %}
 4565 
 4566 instruct membar_release_lock() %{
 4567   match(MemBarReleaseLock);
 4568   ins_cost(0);
 4569 
 4570   size(0);
 4571   format %{ "!MEMBAR-release (CAS in succeeding FastUnlock so empty encoding)" %}
 4572   ins_encode( );
 4573   ins_pipe(empty);
 4574 %}
 4575 
 4576 instruct membar_volatile() %{
 4577   match(MemBarVolatile);
 4578   ins_cost(4*MEMORY_REF_COST);
 4579 
 4580   size(4);
 4581   format %{ "MEMBAR-volatile" %}
 4582   ins_encode %{
 4583     __ membar(MacroAssembler::StoreLoad, noreg);
 4584   %}
 4585   ins_pipe(long_memory_op);
 4586 %}
 4587 
 4588 instruct unnecessary_membar_volatile() %{
 4589   match(MemBarVolatile);
 4590   predicate(Matcher::post_store_load_barrier(n));
 4591   ins_cost(0);
 4592 
 4593   size(0);
 4594   format %{ "!MEMBAR-volatile (unnecessary so empty encoding)" %}
 4595   ins_encode( );
 4596   ins_pipe(empty);
 4597 %}
 4598 
 4599 //----------Register Move Instructions-----------------------------------------
 4600 // instruct roundDouble_nop(regD dst) %{
 4601 //   match(Set dst (RoundDouble dst));
 4602 //   ins_pipe(empty);
 4603 // %}
 4604 
 4605 
 4606 // instruct roundFloat_nop(regF dst) %{
 4607 //   match(Set dst (RoundFloat dst));
 4608 //   ins_pipe(empty);
 4609 // %}
 4610 
 4611 
 4612 
 4613 // Cast Index to Pointer for unsafe natives
 4614 instruct castX2P(iRegX src, iRegP dst) %{
 4615   match(Set dst (CastX2P src));
 4616 
 4617   format %{ "MOV    $dst,$src\t! IntX->Ptr if $dst != $src" %}
 4618   ins_encode %{
 4619     if ($dst$$Register !=  $src$$Register) {
 4620       __ mov($dst$$Register, $src$$Register);
 4621     }
 4622   %}
 4623   ins_pipe(ialu_reg);
 4624 %}
 4625 
 4626 // Cast Pointer to Index for unsafe natives
 4627 instruct castP2X(iRegP src, iRegX dst) %{
 4628   match(Set dst (CastP2X src));
 4629 
 4630   format %{ "MOV    $dst,$src\t! Ptr->IntX if $dst != $src" %}
 4631   ins_encode %{
 4632     if ($dst$$Register !=  $src$$Register) {
 4633       __ mov($dst$$Register, $src$$Register);
 4634     }
 4635   %}
 4636   ins_pipe(ialu_reg);
 4637 %}
 4638 
 4639 //----------Conditional Move---------------------------------------------------
 4640 // Conditional move
 4641 instruct cmovIP_reg(cmpOpP cmp, flagsRegP pcc, iRegI dst, iRegI src) %{
 4642   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
 4643   ins_cost(150);
 4644   size(4);
 4645   format %{ "MOV$cmp  $dst,$src\t! int" %}
 4646   ins_encode %{
 4647     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4648   %}
 4649   ins_pipe(ialu_reg);
 4650 %}
 4651 
 4652 
 4653 instruct cmovIP_immMov(cmpOpP cmp, flagsRegP pcc, iRegI dst, immIMov src) %{
 4654   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
 4655   ins_cost(140);
 4656   size(4);
 4657   format %{ "MOV$cmp  $dst,$src" %}
 4658   ins_encode %{
 4659     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4660   %}
 4661   ins_pipe(ialu_imm);
 4662 %}
 4663 
 4664 instruct cmovIP_imm16(cmpOpP cmp, flagsRegP pcc, iRegI dst, immI16 src) %{
 4665   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
 4666   ins_cost(140);
 4667   size(4);
 4668   format %{ "MOVw$cmp  $dst,$src" %}
 4669   ins_encode %{
 4670     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4671   %}
 4672   ins_pipe(ialu_imm);
 4673 %}
 4674 
 4675 instruct cmovI_reg(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src) %{
 4676   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4677   ins_cost(150);
 4678   size(4);
 4679   format %{ "MOV$cmp  $dst,$src" %}
 4680   ins_encode %{
 4681     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4682   %}
 4683   ins_pipe(ialu_reg);
 4684 %}
 4685 
 4686 
 4687 instruct cmovI_immMov(cmpOp cmp, flagsReg icc, iRegI dst, immIMov src) %{
 4688   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4689   ins_cost(140);
 4690   size(4);
 4691   format %{ "MOV$cmp  $dst,$src" %}
 4692   ins_encode %{
 4693     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4694   %}
 4695   ins_pipe(ialu_imm);
 4696 %}
 4697 
 4698 instruct cmovII_imm16(cmpOp cmp, flagsReg icc, iRegI dst, immI16 src) %{
 4699   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4700   ins_cost(140);
 4701   size(4);
 4702   format %{ "MOVw$cmp  $dst,$src" %}
 4703   ins_encode %{
 4704     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4705   %}
 4706   ins_pipe(ialu_imm);
 4707 %}
 4708 
 4709 instruct cmovII_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, iRegI src) %{
 4710   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4711   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4712             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4713             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4714             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4715   ins_cost(150);
 4716   size(4);
 4717   format %{ "MOV$cmp  $dst,$src" %}
 4718   ins_encode %{
 4719     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4720   %}
 4721   ins_pipe(ialu_reg);
 4722 %}
 4723 
 4724 instruct cmovII_immMov_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immIMov src) %{
 4725   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4726   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4727             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4728             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4729             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4730   ins_cost(140);
 4731   size(4);
 4732   format %{ "MOV$cmp  $dst,$src" %}
 4733   ins_encode %{
 4734     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4735   %}
 4736   ins_pipe(ialu_imm);
 4737 %}
 4738 
 4739 instruct cmovII_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immI16 src) %{
 4740   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4741   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4742             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4743             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4744             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4745   ins_cost(140);
 4746   size(4);
 4747   format %{ "MOVW$cmp  $dst,$src" %}
 4748   ins_encode %{
 4749     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4750   %}
 4751   ins_pipe(ialu_imm);
 4752 %}
 4753 
 4754 instruct cmovIIu_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
 4755   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4756   ins_cost(150);
 4757   size(4);
 4758   format %{ "MOV$cmp  $dst,$src" %}
 4759   ins_encode %{
 4760     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4761   %}
 4762   ins_pipe(ialu_reg);
 4763 %}
 4764 
 4765 instruct cmovIIu_immMov(cmpOpU cmp, flagsRegU icc, iRegI dst, immIMov src) %{
 4766   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4767   ins_cost(140);
 4768   size(4);
 4769   format %{ "MOV$cmp  $dst,$src" %}
 4770   ins_encode %{
 4771     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4772   %}
 4773   ins_pipe(ialu_imm);
 4774 %}
 4775 
 4776 instruct cmovIIu_imm16(cmpOpU cmp, flagsRegU icc, iRegI dst, immI16 src) %{
 4777   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4778   ins_cost(140);
 4779   size(4);
 4780   format %{ "MOVW$cmp  $dst,$src" %}
 4781   ins_encode %{
 4782     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4783   %}
 4784   ins_pipe(ialu_imm);
 4785 %}
 4786 
 4787 // Conditional move
 4788 instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{
 4789   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
 4790   ins_cost(150);
 4791   size(4);
 4792   format %{ "MOV$cmp  $dst,$src" %}
 4793   ins_encode %{
 4794     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4795   %}
 4796   ins_pipe(ialu_reg);
 4797 %}
 4798 
 4799 instruct cmovPP_imm(cmpOpP cmp, flagsRegP pcc, iRegP dst, immP0 src) %{
 4800   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
 4801   ins_cost(140);
 4802   size(4);
 4803   format %{ "MOV$cmp  $dst,$src" %}
 4804   ins_encode %{
 4805     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4806   %}
 4807   ins_pipe(ialu_imm);
 4808 %}
 4809 
 4810 // This instruction also works with CmpN so we don't need cmovPN_reg.
 4811 instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{
 4812   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4813   ins_cost(150);
 4814 
 4815   size(4);
 4816   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4817   ins_encode %{
 4818     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4819   %}
 4820   ins_pipe(ialu_reg);
 4821 %}
 4822 
 4823 instruct cmovPI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, iRegP src) %{
 4824   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4825   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4826             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4827             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4828             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4829   ins_cost(150);
 4830 
 4831   size(4);
 4832   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4833   ins_encode %{
 4834     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4835   %}
 4836   ins_pipe(ialu_reg);
 4837 %}
 4838 
 4839 instruct cmovPIu_reg(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src) %{
 4840   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4841   ins_cost(150);
 4842 
 4843   size(4);
 4844   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4845   ins_encode %{
 4846     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4847   %}
 4848   ins_pipe(ialu_reg);
 4849 %}
 4850 
 4851 instruct cmovPI_imm(cmpOp cmp, flagsReg icc, iRegP dst, immP0 src) %{
 4852   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4853   ins_cost(140);
 4854 
 4855   size(4);
 4856   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4857   ins_encode %{
 4858     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4859   %}
 4860   ins_pipe(ialu_imm);
 4861 %}
 4862 
 4863 instruct cmovPI_imm_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, immP0 src) %{
 4864   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4865   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4866             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4867             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4868             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4869   ins_cost(140);
 4870 
 4871   size(4);
 4872   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4873   ins_encode %{
 4874     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4875   %}
 4876   ins_pipe(ialu_imm);
 4877 %}
 4878 
 4879 instruct cmovPIu_imm(cmpOpU cmp, flagsRegU icc, iRegP dst, immP0 src) %{
 4880   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4881   ins_cost(140);
 4882 
 4883   size(4);
 4884   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4885   ins_encode %{
 4886     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4887   %}
 4888   ins_pipe(ialu_imm);
 4889 %}
 4890 
 4891 
 4892 // Conditional move
 4893 instruct cmovFP_reg(cmpOpP cmp, flagsRegP pcc, regF dst, regF src) %{
 4894   match(Set dst (CMoveF (Binary cmp pcc) (Binary dst src)));
 4895   ins_cost(150);
 4896   size(4);
 4897   format %{ "FCPYS$cmp $dst,$src" %}
 4898   ins_encode %{
 4899     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4900   %}
 4901   ins_pipe(int_conditional_float_move);
 4902 %}
 4903 
 4904 instruct cmovFI_reg(cmpOp cmp, flagsReg icc, regF dst, regF src) %{
 4905   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
 4906   ins_cost(150);
 4907 
 4908   size(4);
 4909   format %{ "FCPYS$cmp $dst,$src" %}
 4910   ins_encode %{
 4911     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4912   %}
 4913   ins_pipe(int_conditional_float_move);
 4914 %}
 4915 
 4916 instruct cmovFI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regF dst, regF src) %{
 4917   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
 4918   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4919             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4920             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4921             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4922   ins_cost(150);
 4923 
 4924   size(4);
 4925   format %{ "FCPYS$cmp $dst,$src" %}
 4926   ins_encode %{
 4927     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4928   %}
 4929   ins_pipe(int_conditional_float_move);
 4930 %}
 4931 
 4932 instruct cmovFIu_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src) %{
 4933   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
 4934   ins_cost(150);
 4935 
 4936   size(4);
 4937   format %{ "FCPYS$cmp $dst,$src" %}
 4938   ins_encode %{
 4939     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4940   %}
 4941   ins_pipe(int_conditional_float_move);
 4942 %}
 4943 
 4944 // Conditional move
 4945 instruct cmovDP_reg(cmpOpP cmp, flagsRegP pcc, regD dst, regD src) %{
 4946   match(Set dst (CMoveD (Binary cmp pcc) (Binary dst src)));
 4947   ins_cost(150);
 4948   size(4);
 4949   format %{ "FCPYD$cmp $dst,$src" %}
 4950   ins_encode %{
 4951     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4952   %}
 4953   ins_pipe(int_conditional_double_move);
 4954 %}
 4955 
 4956 instruct cmovDI_reg(cmpOp cmp, flagsReg icc, regD dst, regD src) %{
 4957   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
 4958   ins_cost(150);
 4959 
 4960   size(4);
 4961   format %{ "FCPYD$cmp $dst,$src" %}
 4962   ins_encode %{
 4963     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4964   %}
 4965   ins_pipe(int_conditional_double_move);
 4966 %}
 4967 
 4968 instruct cmovDI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regD dst, regD src) %{
 4969   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
 4970   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);
 4971   ins_cost(150);
 4972 
 4973   size(4);
 4974   format %{ "FCPYD$cmp $dst,$src" %}
 4975   ins_encode %{
 4976     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4977   %}
 4978   ins_pipe(int_conditional_double_move);
 4979 %}
 4980 
 4981 instruct cmovDIu_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src) %{
 4982   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
 4983   ins_cost(150);
 4984 
 4985   size(4);
 4986   format %{ "FCPYD$cmp $dst,$src" %}
 4987   ins_encode %{
 4988     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 4989   %}
 4990   ins_pipe(int_conditional_double_move);
 4991 %}
 4992 
 4993 // Conditional move
 4994 instruct cmovLP_reg(cmpOpP cmp, flagsRegP pcc, iRegL dst, iRegL src) %{
 4995   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
 4996   ins_cost(150);
 4997 
 4998   size(8);
 4999   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 5000             "MOV$cmp  $dst.hi,$src.hi" %}
 5001   ins_encode %{
 5002     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 5003     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 5004   %}
 5005   ins_pipe(ialu_reg);
 5006 %}
 5007 
 5008 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5009 // (hi($con$$constant), lo($con$$constant)) becomes
 5010 instruct cmovLP_immRot(cmpOpP cmp, flagsRegP pcc, iRegL dst, immLlowRot src) %{
 5011   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
 5012   ins_cost(140);
 5013 
 5014   size(8);
 5015   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5016             "MOV$cmp  $dst.hi,0" %}
 5017   ins_encode %{
 5018     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5019     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5020   %}
 5021   ins_pipe(ialu_imm);
 5022 %}
 5023 
 5024 instruct cmovLP_imm16(cmpOpP cmp, flagsRegP pcc, iRegL dst, immL16 src) %{
 5025   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
 5026   ins_cost(140);
 5027 
 5028   size(8);
 5029   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5030             "MOV$cmp  $dst.hi,0" %}
 5031   ins_encode %{
 5032     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5033     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5034   %}
 5035   ins_pipe(ialu_imm);
 5036 %}
 5037 
 5038 instruct cmovLI_reg(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src) %{
 5039   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5040   ins_cost(150);
 5041 
 5042   size(8);
 5043   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 5044             "MOV$cmp  $dst.hi,$src.hi" %}
 5045   ins_encode %{
 5046     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 5047     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 5048   %}
 5049   ins_pipe(ialu_reg);
 5050 %}
 5051 
 5052 instruct cmovLI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, iRegL src) %{
 5053   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5054   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 5055             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 5056             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 5057             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 5058   ins_cost(150);
 5059 
 5060   size(8);
 5061   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 5062             "MOV$cmp  $dst.hi,$src.hi" %}
 5063   ins_encode %{
 5064     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 5065     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 5066   %}
 5067   ins_pipe(ialu_reg);
 5068 %}
 5069 
 5070 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5071 // (hi($con$$constant), lo($con$$constant)) becomes
 5072 instruct cmovLI_immRot(cmpOp cmp, flagsReg icc, iRegL dst, immLlowRot src) %{
 5073   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5074   ins_cost(140);
 5075 
 5076   size(8);
 5077   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5078             "MOV$cmp  $dst.hi,0" %}
 5079   ins_encode %{
 5080     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5081     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5082   %}
 5083   ins_pipe(ialu_imm);
 5084 %}
 5085 
 5086 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5087 // (hi($con$$constant), lo($con$$constant)) becomes
 5088 instruct cmovLI_immRot_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immLlowRot src) %{
 5089   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5090   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 5091             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 5092             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 5093             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 5094   ins_cost(140);
 5095 
 5096   size(8);
 5097   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5098             "MOV$cmp  $dst.hi,0" %}
 5099   ins_encode %{
 5100     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5101     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5102   %}
 5103   ins_pipe(ialu_imm);
 5104 %}
 5105 
 5106 instruct cmovLI_imm16(cmpOp cmp, flagsReg icc, iRegL dst, immL16 src) %{
 5107   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5108   ins_cost(140);
 5109 
 5110   size(8);
 5111   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5112             "MOV$cmp  $dst.hi,0" %}
 5113   ins_encode %{
 5114     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5115     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5116   %}
 5117   ins_pipe(ialu_imm);
 5118 %}
 5119 
 5120 instruct cmovLI_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immL16 src) %{
 5121   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5122   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 5123             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 5124             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 5125             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 5126   ins_cost(140);
 5127 
 5128   size(8);
 5129   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5130             "MOV$cmp  $dst.hi,0" %}
 5131   ins_encode %{
 5132     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5133     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5134   %}
 5135   ins_pipe(ialu_imm);
 5136 %}
 5137 
 5138 instruct cmovLIu_reg(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src) %{
 5139   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5140   ins_cost(150);
 5141 
 5142   size(8);
 5143   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 5144             "MOV$cmp  $dst.hi,$src.hi" %}
 5145   ins_encode %{
 5146     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 5147     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 5148   %}
 5149   ins_pipe(ialu_reg);
 5150 %}
 5151 
 5152 
 5153 //----------OS and Locking Instructions----------------------------------------
 5154 
 5155 // This name is KNOWN by the ADLC and cannot be changed.
 5156 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
 5157 // for this guy.
 5158 instruct tlsLoadP(RthreadRegP dst) %{
 5159   match(Set dst (ThreadLocal));
 5160 
 5161   size(0);
 5162   ins_cost(0);
 5163   format %{ "! TLS is in $dst" %}
 5164   ins_encode( /*empty encoding*/ );
 5165   ins_pipe(ialu_none);
 5166 %}
 5167 
 5168 instruct checkCastPP( iRegP dst ) %{
 5169   match(Set dst (CheckCastPP dst));
 5170 
 5171   size(0);
 5172   format %{ "! checkcastPP of $dst" %}
 5173   ins_encode( /*empty encoding*/ );
 5174   ins_pipe(empty);
 5175 %}
 5176 
 5177 
 5178 instruct castPP( iRegP dst ) %{
 5179   match(Set dst (CastPP dst));
 5180   format %{ "! castPP of $dst" %}
 5181   ins_encode( /*empty encoding*/ );
 5182   ins_pipe(empty);
 5183 %}
 5184 
 5185 instruct castII( iRegI dst ) %{
 5186   match(Set dst (CastII dst));
 5187   format %{ "! castII of $dst" %}
 5188   ins_encode( /*empty encoding*/ );
 5189   ins_cost(0);
 5190   ins_pipe(empty);
 5191 %}
 5192 
 5193 instruct castLL( iRegL dst ) %{
 5194   match(Set dst (CastLL dst));
 5195   format %{ "! castLL of $dst" %}
 5196   ins_encode( /*empty encoding*/ );
 5197   ins_cost(0);
 5198   ins_pipe(empty);
 5199 %}
 5200 
 5201 instruct castFF( regF dst ) %{
 5202   match(Set dst (CastFF dst));
 5203   format %{ "! castFF of $dst" %}
 5204   ins_encode( /*empty encoding*/ );
 5205   ins_cost(0);
 5206   ins_pipe(empty);
 5207 %}
 5208 
 5209 instruct castDD( regD dst ) %{
 5210   match(Set dst (CastDD dst));
 5211   format %{ "! castDD of $dst" %}
 5212   ins_encode( /*empty encoding*/ );
 5213   ins_cost(0);
 5214   ins_pipe(empty);
 5215 %}
 5216 
 5217 instruct castVVD( vecD dst ) %{
 5218   match(Set dst (CastVV dst));
 5219   format %{ "! castVV of $dst" %}
 5220   ins_encode( /*empty encoding*/ );
 5221   ins_cost(0);
 5222   ins_pipe(empty);
 5223 %}
 5224 
 5225 instruct castVVX( vecX dst ) %{
 5226   match(Set dst (CastVV dst));
 5227   format %{ "! castVV of $dst" %}
 5228   ins_encode( /*empty encoding*/ );
 5229   ins_cost(0);
 5230   ins_pipe(empty);
 5231 %}
 5232 
 5233 
 5234 //----------Arithmetic Instructions--------------------------------------------
 5235 // Addition Instructions
 5236 // Register Addition
 5237 instruct addI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 5238   match(Set dst (AddI src1 src2));
 5239 
 5240   size(4);
 5241   format %{ "add_32 $dst,$src1,$src2\t! int" %}
 5242   ins_encode %{
 5243     __ add_32($dst$$Register, $src1$$Register, $src2$$Register);
 5244   %}
 5245   ins_pipe(ialu_reg_reg);
 5246 %}
 5247 
 5248 instruct addshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5249   match(Set dst (AddI (LShiftI src1 src2) src3));
 5250 
 5251   size(4);
 5252   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
 5253   ins_encode %{
 5254     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 5255   %}
 5256   ins_pipe(ialu_reg_reg);
 5257 %}
 5258 
 5259 
 5260 instruct addshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5261   match(Set dst (AddI (LShiftI src1 src2) src3));
 5262 
 5263   size(4);
 5264   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
 5265   ins_encode %{
 5266     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
 5267   %}
 5268   ins_pipe(ialu_reg_reg);
 5269 %}
 5270 
 5271 instruct addsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5272   match(Set dst (AddI (RShiftI src1 src2) src3));
 5273 
 5274   size(4);
 5275   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
 5276   ins_encode %{
 5277     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
 5278   %}
 5279   ins_pipe(ialu_reg_reg);
 5280 %}
 5281 
 5282 instruct addsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5283   match(Set dst (AddI (RShiftI src1 src2) src3));
 5284 
 5285   size(4);
 5286   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
 5287   ins_encode %{
 5288     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
 5289   %}
 5290   ins_pipe(ialu_reg_reg);
 5291 %}
 5292 
 5293 instruct addshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5294   match(Set dst (AddI (URShiftI src1 src2) src3));
 5295 
 5296   size(4);
 5297   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
 5298   ins_encode %{
 5299     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 5300   %}
 5301   ins_pipe(ialu_reg_reg);
 5302 %}
 5303 
 5304 instruct addshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5305   match(Set dst (AddI (URShiftI src1 src2) src3));
 5306 
 5307   size(4);
 5308   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
 5309   ins_encode %{
 5310     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 5311   %}
 5312   ins_pipe(ialu_reg_reg);
 5313 %}
 5314 
 5315 // Immediate Addition
 5316 instruct addI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
 5317   match(Set dst (AddI src1 src2));
 5318 
 5319   size(4);
 5320   format %{ "add_32 $dst,$src1,$src2\t! int" %}
 5321   ins_encode %{
 5322     __ add_32($dst$$Register, $src1$$Register, $src2$$constant);
 5323   %}
 5324   ins_pipe(ialu_reg_imm);
 5325 %}
 5326 
 5327 // Pointer Register Addition
 5328 instruct addP_reg_reg(iRegP dst, iRegP src1, iRegX src2) %{
 5329   match(Set dst (AddP src1 src2));
 5330 
 5331   size(4);
 5332   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
 5333   ins_encode %{
 5334     __ add($dst$$Register, $src1$$Register, $src2$$Register);
 5335   %}
 5336   ins_pipe(ialu_reg_reg);
 5337 %}
 5338 
 5339 
 5340 // shifted iRegX operand
 5341 operand shiftedX(iRegX src2, shimmX src3) %{
 5342 //constraint(ALLOC_IN_RC(sp_ptr_reg));
 5343   match(LShiftX src2 src3);
 5344 
 5345   op_cost(1);
 5346   format %{ "$src2 << $src3" %}
 5347   interface(MEMORY_INTER) %{
 5348     base($src2);
 5349     index(0xff);
 5350     scale($src3);
 5351     disp(0x0);
 5352   %}
 5353 %}
 5354 
 5355 instruct addshlP_reg_reg_imm(iRegP dst, iRegP src1, shiftedX src2) %{
 5356   match(Set dst (AddP src1 src2));
 5357 
 5358   ins_cost(DEFAULT_COST * 3/2);
 5359   size(4);
 5360   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
 5361   ins_encode %{
 5362     Register base = reg_to_register_object($src2$$base);
 5363     __ add($dst$$Register, $src1$$Register, AsmOperand(base, lsl, $src2$$scale));
 5364   %}
 5365   ins_pipe(ialu_reg_reg);
 5366 %}
 5367 
 5368 // Pointer Immediate Addition
 5369 instruct addP_reg_aimmX(iRegP dst, iRegP src1, aimmX src2) %{
 5370   match(Set dst (AddP src1 src2));
 5371 
 5372   size(4);
 5373   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
 5374   ins_encode %{
 5375     __ add($dst$$Register, $src1$$Register, $src2$$constant);
 5376   %}
 5377   ins_pipe(ialu_reg_imm);
 5378 %}
 5379 
 5380 // Long Addition
 5381 instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg ccr) %{
 5382   match(Set dst (AddL src1 src2));
 5383   effect(KILL ccr);
 5384   size(8);
 5385   format %{ "ADDS    $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
 5386             "ADC     $dst.hi,$src1.hi,$src2.hi" %}
 5387   ins_encode %{
 5388     __ adds($dst$$Register, $src1$$Register, $src2$$Register);
 5389     __ adc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 5390   %}
 5391   ins_pipe(ialu_reg_reg);
 5392 %}
 5393 
 5394 // TODO
 5395 
 5396 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5397 // (hi($con$$constant), lo($con$$constant)) becomes
 5398 instruct addL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg ccr) %{
 5399   match(Set dst (AddL src1 con));
 5400   effect(KILL ccr);
 5401   size(8);
 5402   format %{ "ADDS    $dst.lo,$src1.lo,$con\t! long\n\t"
 5403             "ADC     $dst.hi,$src1.hi,0" %}
 5404   ins_encode %{
 5405     __ adds($dst$$Register, $src1$$Register, $con$$constant);
 5406     __ adc($dst$$Register->successor(), $src1$$Register->successor(), 0);
 5407   %}
 5408   ins_pipe(ialu_reg_imm);
 5409 %}
 5410 
 5411 //----------Conditional_store--------------------------------------------------
 5412 // Conditional-store of the updated heap-top.
 5413 // Used during allocation of the shared heap.
 5414 // Sets flags (EQ) on success.
 5415 
 5416 // LoadP-locked.
 5417 instruct loadPLocked(iRegP dst, memoryex mem) %{
 5418   match(Set dst (LoadPLocked mem));
 5419   size(4);
 5420   format %{ "LDREX  $dst,$mem" %}
 5421   ins_encode %{
 5422     __ ldrex($dst$$Register,$mem$$Address);
 5423   %}
 5424   ins_pipe(iload_mem);
 5425 %}
 5426 
 5427 instruct storePConditional( memoryex heap_top_ptr, iRegP oldval, iRegP newval, iRegI tmp, flagsRegP pcc ) %{
 5428   predicate(_kids[1]->_kids[0]->_leaf->Opcode() == Op_LoadPLocked); // only works in conjunction with a LoadPLocked node
 5429   match(Set pcc (StorePConditional heap_top_ptr (Binary oldval newval)));
 5430   effect( TEMP tmp );
 5431   size(8);
 5432   format %{ "STREX  $tmp,$newval,$heap_top_ptr\n\t"
 5433             "CMP    $tmp, 0" %}
 5434   ins_encode %{
 5435     __ strex($tmp$$Register, $newval$$Register, $heap_top_ptr$$Address);
 5436     __ cmp($tmp$$Register, 0);
 5437   %}
 5438   ins_pipe( long_memory_op );
 5439 %}
 5440 
 5441 // Conditional-store of an intx value.
 5442 instruct storeXConditional( memoryex mem, iRegX oldval, iRegX newval, iRegX tmp, flagsReg icc ) %{
 5443   match(Set icc (StoreIConditional mem (Binary oldval newval)));
 5444   effect( TEMP tmp );
 5445   size(28);
 5446   format %{ "loop: \n\t"
 5447             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem], DOESN'T set $newval=[$mem] in any case\n\t"
 5448             "XORS     $tmp,$tmp, $oldval\n\t"
 5449             "STREX.eq $tmp, $newval, $mem\n\t"
 5450             "CMP.eq   $tmp, 1 \n\t"
 5451             "B.eq     loop \n\t"
 5452             "TEQ      $tmp, 0\n\t"
 5453             "membar   LoadStore|LoadLoad" %}
 5454   ins_encode %{
 5455     Label loop;
 5456     __ bind(loop);
 5457     __ ldrex($tmp$$Register, $mem$$Address);
 5458     __ eors($tmp$$Register, $tmp$$Register, $oldval$$Register);
 5459     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5460     __ cmp($tmp$$Register, 1, eq);
 5461     __ b(loop, eq);
 5462     __ teq($tmp$$Register, 0);
 5463     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadStore | MacroAssembler::LoadLoad), noreg);
 5464   %}
 5465   ins_pipe( long_memory_op );
 5466 %}
 5467 
 5468 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
 5469 
 5470 instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegLd newval, iRegI res, iRegLd tmp, flagsReg ccr ) %{
 5471   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
 5472   effect( KILL ccr, TEMP tmp);
 5473   size(32);
 5474   format %{ "loop: \n\t"
 5475             "LDREXD   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
 5476             "CMP      $tmp.lo, $oldval.lo\n\t"
 5477             "CMP.eq   $tmp.hi, $oldval.hi\n\t"
 5478             "STREXD.eq $tmp, $newval, $mem\n\t"
 5479             "MOV.ne   $tmp, 0 \n\t"
 5480             "XORS.eq  $tmp,$tmp, 1 \n\t"
 5481             "B.eq     loop \n\t"
 5482             "MOV      $res, $tmp" %}
 5483   ins_encode %{
 5484     Label loop;
 5485     __ bind(loop);
 5486     __ ldrexd($tmp$$Register, $mem$$Address);
 5487     __ cmp($tmp$$Register, $oldval$$Register);
 5488     __ cmp($tmp$$Register->successor(), $oldval$$Register->successor(), eq);
 5489     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5490     __ mov($tmp$$Register, 0, ne);
 5491     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
 5492     __ b(loop, eq);
 5493     __ mov($res$$Register, $tmp$$Register);
 5494   %}
 5495   ins_pipe( long_memory_op );
 5496 %}
 5497 
 5498 
 5499 instruct compareAndSwapI_bool(memoryex mem, iRegI oldval, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
 5500   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
 5501   effect( KILL ccr, TEMP tmp);
 5502   size(28);
 5503   format %{ "loop: \n\t"
 5504             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
 5505             "CMP      $tmp, $oldval\n\t"
 5506             "STREX.eq $tmp, $newval, $mem\n\t"
 5507             "MOV.ne   $tmp, 0 \n\t"
 5508             "XORS.eq  $tmp,$tmp, 1 \n\t"
 5509             "B.eq     loop \n\t"
 5510             "MOV      $res, $tmp" %}
 5511 
 5512   ins_encode %{
 5513     Label loop;
 5514     __ bind(loop);
 5515     __ ldrex($tmp$$Register,$mem$$Address);
 5516     __ cmp($tmp$$Register, $oldval$$Register);
 5517     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5518     __ mov($tmp$$Register, 0, ne);
 5519     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
 5520     __ b(loop, eq);
 5521     __ mov($res$$Register, $tmp$$Register);
 5522   %}
 5523   ins_pipe( long_memory_op );
 5524 %}
 5525 
 5526 instruct compareAndSwapP_bool(memoryex mem, iRegP oldval, iRegP newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
 5527   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
 5528   effect( KILL ccr, TEMP tmp);
 5529   size(28);
 5530   format %{ "loop: \n\t"
 5531             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
 5532             "CMP      $tmp, $oldval\n\t"
 5533             "STREX.eq $tmp, $newval, $mem\n\t"
 5534             "MOV.ne   $tmp, 0 \n\t"
 5535             "EORS.eq  $tmp,$tmp, 1 \n\t"
 5536             "B.eq     loop \n\t"
 5537             "MOV      $res, $tmp" %}
 5538 
 5539   ins_encode %{
 5540     Label loop;
 5541     __ bind(loop);
 5542     __ ldrex($tmp$$Register,$mem$$Address);
 5543     __ cmp($tmp$$Register, $oldval$$Register);
 5544     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5545     __ mov($tmp$$Register, 0, ne);
 5546     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
 5547     __ b(loop, eq);
 5548     __ mov($res$$Register, $tmp$$Register);
 5549   %}
 5550   ins_pipe( long_memory_op );
 5551 %}
 5552 
 5553 instruct xaddI_aimmI_no_res(memoryex mem, aimmI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5554   predicate(n->as_LoadStore()->result_not_used());
 5555   match(Set dummy (GetAndAddI mem add));
 5556   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
 5557   size(20);
 5558   format %{ "loop: \n\t"
 5559             "LDREX    $tmp1, $mem\n\t"
 5560             "ADD      $tmp1, $tmp1, $add\n\t"
 5561             "STREX    $tmp2, $tmp1, $mem\n\t"
 5562             "CMP      $tmp2, 0 \n\t"
 5563             "B.ne     loop \n\t" %}
 5564 
 5565   ins_encode %{
 5566     Label loop;
 5567     __ bind(loop);
 5568     __ ldrex($tmp1$$Register,$mem$$Address);
 5569     __ add($tmp1$$Register, $tmp1$$Register, $add$$constant);
 5570     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5571     __ cmp($tmp2$$Register, 0);
 5572     __ b(loop, ne);
 5573   %}
 5574   ins_pipe( long_memory_op );
 5575 %}
 5576 
 5577 instruct xaddI_reg_no_res(memoryex mem, iRegI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5578   predicate(n->as_LoadStore()->result_not_used());
 5579   match(Set dummy (GetAndAddI mem add));
 5580   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
 5581   size(20);
 5582   format %{ "loop: \n\t"
 5583             "LDREX    $tmp1, $mem\n\t"
 5584             "ADD      $tmp1, $tmp1, $add\n\t"
 5585             "STREX    $tmp2, $tmp1, $mem\n\t"
 5586             "CMP      $tmp2, 0 \n\t"
 5587             "B.ne     loop \n\t" %}
 5588 
 5589   ins_encode %{
 5590     Label loop;
 5591     __ bind(loop);
 5592     __ ldrex($tmp1$$Register,$mem$$Address);
 5593     __ add($tmp1$$Register, $tmp1$$Register, $add$$Register);
 5594     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5595     __ cmp($tmp2$$Register, 0);
 5596     __ b(loop, ne);
 5597   %}
 5598   ins_pipe( long_memory_op );
 5599 %}
 5600 
 5601 instruct xaddI_aimmI(memoryex mem, aimmI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5602   match(Set res (GetAndAddI mem add));
 5603   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5604   size(20);
 5605   format %{ "loop: \n\t"
 5606             "LDREX    $res, $mem\n\t"
 5607             "ADD      $tmp1, $res, $add\n\t"
 5608             "STREX    $tmp2, $tmp1, $mem\n\t"
 5609             "CMP      $tmp2, 0 \n\t"
 5610             "B.ne     loop \n\t" %}
 5611 
 5612   ins_encode %{
 5613     Label loop;
 5614     __ bind(loop);
 5615     __ ldrex($res$$Register,$mem$$Address);
 5616     __ add($tmp1$$Register, $res$$Register, $add$$constant);
 5617     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5618     __ cmp($tmp2$$Register, 0);
 5619     __ b(loop, ne);
 5620   %}
 5621   ins_pipe( long_memory_op );
 5622 %}
 5623 
 5624 instruct xaddI_reg(memoryex mem, iRegI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5625   match(Set res (GetAndAddI mem add));
 5626   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5627   size(20);
 5628   format %{ "loop: \n\t"
 5629             "LDREX    $res, $mem\n\t"
 5630             "ADD      $tmp1, $res, $add\n\t"
 5631             "STREX    $tmp2, $tmp1, $mem\n\t"
 5632             "CMP      $tmp2, 0 \n\t"
 5633             "B.ne     loop \n\t" %}
 5634 
 5635   ins_encode %{
 5636     Label loop;
 5637     __ bind(loop);
 5638     __ ldrex($res$$Register,$mem$$Address);
 5639     __ add($tmp1$$Register, $res$$Register, $add$$Register);
 5640     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5641     __ cmp($tmp2$$Register, 0);
 5642     __ b(loop, ne);
 5643   %}
 5644   ins_pipe( long_memory_op );
 5645 %}
 5646 
 5647 instruct xaddL_reg_no_res(memoryex mem, iRegL add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5648   predicate(n->as_LoadStore()->result_not_used());
 5649   match(Set dummy (GetAndAddL mem add));
 5650   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
 5651   size(24);
 5652   format %{ "loop: \n\t"
 5653             "LDREXD   $tmp1, $mem\n\t"
 5654             "ADDS     $tmp1.lo, $tmp1.lo, $add.lo\n\t"
 5655             "ADC      $tmp1.hi, $tmp1.hi, $add.hi\n\t"
 5656             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5657             "CMP      $tmp2, 0 \n\t"
 5658             "B.ne     loop \n\t" %}
 5659 
 5660   ins_encode %{
 5661     Label loop;
 5662     __ bind(loop);
 5663     __ ldrexd($tmp1$$Register, $mem$$Address);
 5664     __ adds($tmp1$$Register, $tmp1$$Register, $add$$Register);
 5665     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), $add$$Register->successor());
 5666     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5667     __ cmp($tmp2$$Register, 0);
 5668     __ b(loop, ne);
 5669   %}
 5670   ins_pipe( long_memory_op );
 5671 %}
 5672 
 5673 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5674 // (hi($con$$constant), lo($con$$constant)) becomes
 5675 instruct xaddL_immRot_no_res(memoryex mem, immLlowRot add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5676   predicate(n->as_LoadStore()->result_not_used());
 5677   match(Set dummy (GetAndAddL mem add));
 5678   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
 5679   size(24);
 5680   format %{ "loop: \n\t"
 5681             "LDREXD   $tmp1, $mem\n\t"
 5682             "ADDS     $tmp1.lo, $tmp1.lo, $add\n\t"
 5683             "ADC      $tmp1.hi, $tmp1.hi, 0\n\t"
 5684             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5685             "CMP      $tmp2, 0 \n\t"
 5686             "B.ne     loop \n\t" %}
 5687 
 5688   ins_encode %{
 5689     Label loop;
 5690     __ bind(loop);
 5691     __ ldrexd($tmp1$$Register, $mem$$Address);
 5692     __ adds($tmp1$$Register, $tmp1$$Register, $add$$constant);
 5693     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), 0);
 5694     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5695     __ cmp($tmp2$$Register, 0);
 5696     __ b(loop, ne);
 5697   %}
 5698   ins_pipe( long_memory_op );
 5699 %}
 5700 
 5701 instruct xaddL_reg(memoryex mem, iRegL add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5702   match(Set res (GetAndAddL mem add));
 5703   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5704   size(24);
 5705   format %{ "loop: \n\t"
 5706             "LDREXD   $res, $mem\n\t"
 5707             "ADDS     $tmp1.lo, $res.lo, $add.lo\n\t"
 5708             "ADC      $tmp1.hi, $res.hi, $add.hi\n\t"
 5709             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5710             "CMP      $tmp2, 0 \n\t"
 5711             "B.ne     loop \n\t" %}
 5712 
 5713   ins_encode %{
 5714     Label loop;
 5715     __ bind(loop);
 5716     __ ldrexd($res$$Register, $mem$$Address);
 5717     __ adds($tmp1$$Register, $res$$Register, $add$$Register);
 5718     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), $add$$Register->successor());
 5719     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5720     __ cmp($tmp2$$Register, 0);
 5721     __ b(loop, ne);
 5722   %}
 5723   ins_pipe( long_memory_op );
 5724 %}
 5725 
 5726 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5727 // (hi($con$$constant), lo($con$$constant)) becomes
 5728 instruct xaddL_immRot(memoryex mem, immLlowRot add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5729   match(Set res (GetAndAddL mem add));
 5730   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5731   size(24);
 5732   format %{ "loop: \n\t"
 5733             "LDREXD   $res, $mem\n\t"
 5734             "ADDS     $tmp1.lo, $res.lo, $add\n\t"
 5735             "ADC      $tmp1.hi, $res.hi, 0\n\t"
 5736             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5737             "CMP      $tmp2, 0 \n\t"
 5738             "B.ne     loop \n\t" %}
 5739 
 5740   ins_encode %{
 5741     Label loop;
 5742     __ bind(loop);
 5743     __ ldrexd($res$$Register, $mem$$Address);
 5744     __ adds($tmp1$$Register, $res$$Register, $add$$constant);
 5745     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), 0);
 5746     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5747     __ cmp($tmp2$$Register, 0);
 5748     __ b(loop, ne);
 5749   %}
 5750   ins_pipe( long_memory_op );
 5751 %}
 5752 
 5753 instruct xchgI(memoryex mem, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr) %{
 5754   match(Set res (GetAndSetI mem newval));
 5755   effect(KILL ccr, TEMP tmp, TEMP res);
 5756   size(16);
 5757   format %{ "loop: \n\t"
 5758             "LDREX    $res, $mem\n\t"
 5759             "STREX    $tmp, $newval, $mem\n\t"
 5760             "CMP      $tmp, 0 \n\t"
 5761             "B.ne     loop \n\t" %}
 5762 
 5763   ins_encode %{
 5764     Label loop;
 5765     __ bind(loop);
 5766     __ ldrex($res$$Register,$mem$$Address);
 5767     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
 5768     __ cmp($tmp$$Register, 0);
 5769     __ b(loop, ne);
 5770   %}
 5771   ins_pipe( long_memory_op );
 5772 %}
 5773 
 5774 instruct xchgL(memoryex mem, iRegLd newval, iRegLd res, iRegI tmp, flagsReg ccr) %{
 5775   match(Set res (GetAndSetL mem newval));
 5776   effect( KILL ccr, TEMP tmp, TEMP res);
 5777   size(16);
 5778   format %{ "loop: \n\t"
 5779             "LDREXD   $res, $mem\n\t"
 5780             "STREXD   $tmp, $newval, $mem\n\t"
 5781             "CMP      $tmp, 0 \n\t"
 5782             "B.ne     loop \n\t" %}
 5783 
 5784   ins_encode %{
 5785     Label loop;
 5786     __ bind(loop);
 5787     __ ldrexd($res$$Register, $mem$$Address);
 5788     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address);
 5789     __ cmp($tmp$$Register, 0);
 5790     __ b(loop, ne);
 5791   %}
 5792   ins_pipe( long_memory_op );
 5793 %}
 5794 
 5795 instruct xchgP(memoryex mem, iRegP newval, iRegP res, iRegI tmp, flagsReg ccr) %{
 5796   match(Set res (GetAndSetP mem newval));
 5797   effect(KILL ccr, TEMP tmp, TEMP res);
 5798   size(16);
 5799   format %{ "loop: \n\t"
 5800             "LDREX    $res, $mem\n\t"
 5801             "STREX    $tmp, $newval, $mem\n\t"
 5802             "CMP      $tmp, 0 \n\t"
 5803             "B.ne     loop \n\t" %}
 5804 
 5805   ins_encode %{
 5806     Label loop;
 5807     __ bind(loop);
 5808     __ ldrex($res$$Register,$mem$$Address);
 5809     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
 5810     __ cmp($tmp$$Register, 0);
 5811     __ b(loop, ne);
 5812   %}
 5813   ins_pipe( long_memory_op );
 5814 %}
 5815 
 5816 //---------------------
 5817 // Subtraction Instructions
 5818 // Register Subtraction
 5819 instruct subI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 5820   match(Set dst (SubI src1 src2));
 5821 
 5822   size(4);
 5823   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
 5824   ins_encode %{
 5825     __ sub_32($dst$$Register, $src1$$Register, $src2$$Register);
 5826   %}
 5827   ins_pipe(ialu_reg_reg);
 5828 %}
 5829 
 5830 instruct subshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5831   match(Set dst (SubI src1 (LShiftI src2 src3)));
 5832 
 5833   size(4);
 5834   format %{ "SUB    $dst,$src1,$src2<<$src3" %}
 5835   ins_encode %{
 5836     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 5837   %}
 5838   ins_pipe(ialu_reg_reg);
 5839 %}
 5840 
 5841 instruct subshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 5842   match(Set dst (SubI src1 (LShiftI src2 src3)));
 5843 
 5844   size(4);
 5845   format %{ "sub_32 $dst,$src1,$src2<<$src3\t! int" %}
 5846   ins_encode %{
 5847     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 5848   %}
 5849   ins_pipe(ialu_reg_reg);
 5850 %}
 5851 
 5852 instruct subsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5853   match(Set dst (SubI src1 (RShiftI src2 src3)));
 5854 
 5855   size(4);
 5856   format %{ "SUB    $dst,$src1,$src2>>$src3" %}
 5857   ins_encode %{
 5858     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 5859   %}
 5860   ins_pipe(ialu_reg_reg);
 5861 %}
 5862 
 5863 instruct subsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 5864   match(Set dst (SubI src1 (RShiftI src2 src3)));
 5865 
 5866   size(4);
 5867   format %{ "sub_32 $dst,$src1,$src2>>$src3\t! int" %}
 5868   ins_encode %{
 5869     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 5870   %}
 5871   ins_pipe(ialu_reg_reg);
 5872 %}
 5873 
 5874 instruct subshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5875   match(Set dst (SubI src1 (URShiftI src2 src3)));
 5876 
 5877   size(4);
 5878   format %{ "SUB    $dst,$src1,$src2>>>$src3" %}
 5879   ins_encode %{
 5880     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 5881   %}
 5882   ins_pipe(ialu_reg_reg);
 5883 %}
 5884 
 5885 instruct subshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 5886   match(Set dst (SubI src1 (URShiftI src2 src3)));
 5887 
 5888   size(4);
 5889   format %{ "sub_32 $dst,$src1,$src2>>>$src3\t! int" %}
 5890   ins_encode %{
 5891     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 5892   %}
 5893   ins_pipe(ialu_reg_reg);
 5894 %}
 5895 
 5896 instruct rsbshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5897   match(Set dst (SubI (LShiftI src1 src2) src3));
 5898 
 5899   size(4);
 5900   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
 5901   ins_encode %{
 5902     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 5903   %}
 5904   ins_pipe(ialu_reg_reg);
 5905 %}
 5906 
 5907 instruct rsbshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5908   match(Set dst (SubI (LShiftI src1 src2) src3));
 5909 
 5910   size(4);
 5911   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
 5912   ins_encode %{
 5913     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
 5914   %}
 5915   ins_pipe(ialu_reg_reg);
 5916 %}
 5917 
 5918 instruct rsbsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5919   match(Set dst (SubI (RShiftI src1 src2) src3));
 5920 
 5921   size(4);
 5922   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
 5923   ins_encode %{
 5924     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
 5925   %}
 5926   ins_pipe(ialu_reg_reg);
 5927 %}
 5928 
 5929 instruct rsbsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5930   match(Set dst (SubI (RShiftI src1 src2) src3));
 5931 
 5932   size(4);
 5933   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
 5934   ins_encode %{
 5935     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
 5936   %}
 5937   ins_pipe(ialu_reg_reg);
 5938 %}
 5939 
 5940 instruct rsbshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5941   match(Set dst (SubI (URShiftI src1 src2) src3));
 5942 
 5943   size(4);
 5944   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
 5945   ins_encode %{
 5946     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 5947   %}
 5948   ins_pipe(ialu_reg_reg);
 5949 %}
 5950 
 5951 instruct rsbshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5952   match(Set dst (SubI (URShiftI src1 src2) src3));
 5953 
 5954   size(4);
 5955   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
 5956   ins_encode %{
 5957     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 5958   %}
 5959   ins_pipe(ialu_reg_reg);
 5960 %}
 5961 
 5962 // Immediate Subtraction
 5963 instruct subI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
 5964   match(Set dst (SubI src1 src2));
 5965 
 5966   size(4);
 5967   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
 5968   ins_encode %{
 5969     __ sub_32($dst$$Register, $src1$$Register, $src2$$constant);
 5970   %}
 5971   ins_pipe(ialu_reg_imm);
 5972 %}
 5973 
 5974 instruct subI_reg_immRotneg(iRegI dst, iRegI src1, aimmIneg src2) %{
 5975   match(Set dst (AddI src1 src2));
 5976 
 5977   size(4);
 5978   format %{ "sub_32 $dst,$src1,-($src2)\t! int" %}
 5979   ins_encode %{
 5980     __ sub_32($dst$$Register, $src1$$Register, -$src2$$constant);
 5981   %}
 5982   ins_pipe(ialu_reg_imm);
 5983 %}
 5984 
 5985 instruct subI_immRot_reg(iRegI dst, immIRot src1, iRegI src2) %{
 5986   match(Set dst (SubI src1 src2));
 5987 
 5988   size(4);
 5989   format %{ "RSB    $dst,$src2,src1" %}
 5990   ins_encode %{
 5991     __ rsb($dst$$Register, $src2$$Register, $src1$$constant);
 5992   %}
 5993   ins_pipe(ialu_zero_reg);
 5994 %}
 5995 
 5996 // Register Subtraction
 5997 instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg icc ) %{
 5998   match(Set dst (SubL src1 src2));
 5999   effect (KILL icc);
 6000 
 6001   size(8);
 6002   format %{ "SUBS   $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
 6003             "SBC    $dst.hi,$src1.hi,$src2.hi" %}
 6004   ins_encode %{
 6005     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
 6006     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 6007   %}
 6008   ins_pipe(ialu_reg_reg);
 6009 %}
 6010 
 6011 // TODO
 6012 
 6013 // Immediate Subtraction
 6014 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 6015 // (hi($con$$constant), lo($con$$constant)) becomes
 6016 instruct subL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg icc) %{
 6017   match(Set dst (SubL src1 con));
 6018   effect (KILL icc);
 6019 
 6020   size(8);
 6021   format %{ "SUB    $dst.lo,$src1.lo,$con\t! long\n\t"
 6022             "SBC    $dst.hi,$src1.hi,0" %}
 6023   ins_encode %{
 6024     __ subs($dst$$Register, $src1$$Register, $con$$constant);
 6025     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), 0);
 6026   %}
 6027   ins_pipe(ialu_reg_imm);
 6028 %}
 6029 
 6030 // Long negation
 6031 instruct negL_reg_reg(iRegL dst, immL0 zero, iRegL src2, flagsReg icc) %{
 6032   match(Set dst (SubL zero src2));
 6033   effect (KILL icc);
 6034 
 6035   size(8);
 6036   format %{ "RSBS   $dst.lo,$src2.lo,0\t! long\n\t"
 6037             "RSC    $dst.hi,$src2.hi,0" %}
 6038   ins_encode %{
 6039     __ rsbs($dst$$Register, $src2$$Register, 0);
 6040     __ rsc($dst$$Register->successor(), $src2$$Register->successor(), 0);
 6041   %}
 6042   ins_pipe(ialu_zero_reg);
 6043 %}
 6044 
 6045 // Multiplication Instructions
 6046 // Integer Multiplication
 6047 // Register Multiplication
 6048 instruct mulI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6049   match(Set dst (MulI src1 src2));
 6050 
 6051   size(4);
 6052   format %{ "mul_32 $dst,$src1,$src2" %}
 6053   ins_encode %{
 6054     __ mul_32($dst$$Register, $src1$$Register, $src2$$Register);
 6055   %}
 6056   ins_pipe(imul_reg_reg);
 6057 %}
 6058 
 6059 instruct mulL_lo1_hi2(iRegL dst, iRegL src1, iRegL src2) %{
 6060   effect(DEF dst, USE src1, USE src2);
 6061   size(4);
 6062   format %{ "MUL  $dst.hi,$src1.lo,$src2.hi\t! long" %}
 6063   ins_encode %{
 6064     __ mul($dst$$Register->successor(), $src1$$Register, $src2$$Register->successor());
 6065   %}
 6066   ins_pipe(imul_reg_reg);
 6067 %}
 6068 
 6069 instruct mulL_hi1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
 6070   effect(USE_DEF dst, USE src1, USE src2);
 6071   size(8);
 6072   format %{ "MLA  $dst.hi,$src1.hi,$src2.lo,$dst.hi\t! long\n\t"
 6073             "MOV  $dst.lo, 0"%}
 6074   ins_encode %{
 6075     __ mla($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register, $dst$$Register->successor());
 6076     __ mov($dst$$Register, 0);
 6077   %}
 6078   ins_pipe(imul_reg_reg);
 6079 %}
 6080 
 6081 instruct mulL_lo1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
 6082   effect(USE_DEF dst, USE src1, USE src2);
 6083   size(4);
 6084   format %{ "UMLAL  $dst.lo,$dst.hi,$src1,$src2\t! long" %}
 6085   ins_encode %{
 6086     __ umlal($dst$$Register, $dst$$Register->successor(), $src1$$Register, $src2$$Register);
 6087   %}
 6088   ins_pipe(imul_reg_reg);
 6089 %}
 6090 
 6091 instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 6092   match(Set dst (MulL src1 src2));
 6093 
 6094   expand %{
 6095     mulL_lo1_hi2(dst, src1, src2);
 6096     mulL_hi1_lo2(dst, src1, src2);
 6097     mulL_lo1_lo2(dst, src1, src2);
 6098   %}
 6099 %}
 6100 
 6101 // Integer Division
 6102 // Register Division
 6103 instruct divI_reg_reg(R1RegI dst, R0RegI src1, R2RegI src2, LRRegP lr, flagsReg ccr) %{
 6104   match(Set dst (DivI src1 src2));
 6105   effect( KILL ccr, KILL src1, KILL src2, KILL lr);
 6106   ins_cost((2+71)*DEFAULT_COST);
 6107 
 6108   format %{ "DIV   $dst,$src1,$src2 ! call to StubRoutines::Arm::idiv_irem_entry()" %}
 6109   ins_encode %{
 6110     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
 6111   %}
 6112   ins_pipe(sdiv_reg_reg);
 6113 %}
 6114 
 6115 // Register Long Division
 6116 instruct divL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
 6117   match(Set dst (DivL src1 src2));
 6118   effect(CALL);
 6119   ins_cost(DEFAULT_COST*71);
 6120   format %{ "DIVL  $src1,$src2,$dst\t! long ! call to SharedRuntime::ldiv" %}
 6121   ins_encode %{
 6122     address target = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);
 6123     __ call(target, relocInfo::runtime_call_type);
 6124   %}
 6125   ins_pipe(divL_reg_reg);
 6126 %}
 6127 
 6128 // Integer Remainder
 6129 // Register Remainder
 6130 instruct modI_reg_reg(R0RegI dst, R0RegI src1, R2RegI src2, R1RegI temp, LRRegP lr, flagsReg ccr ) %{
 6131   match(Set dst (ModI src1 src2));
 6132   effect( KILL ccr, KILL temp, KILL src2, KILL lr);
 6133 
 6134   format %{ "MODI   $dst,$src1,$src2\t ! call to StubRoutines::Arm::idiv_irem_entry" %}
 6135   ins_encode %{
 6136     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
 6137   %}
 6138   ins_pipe(sdiv_reg_reg);
 6139 %}
 6140 
 6141 // Register Long Remainder
 6142 instruct modL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
 6143   match(Set dst (ModL src1 src2));
 6144   effect(CALL);
 6145   ins_cost(MEMORY_REF_COST); // FIXME
 6146   format %{ "modL    $dst,$src1,$src2\t ! call to SharedRuntime::lrem" %}
 6147   ins_encode %{
 6148     address target = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
 6149     __ call(target, relocInfo::runtime_call_type);
 6150   %}
 6151   ins_pipe(divL_reg_reg);
 6152 %}
 6153 
 6154 // Integer Shift Instructions
 6155 
 6156 // Register Shift Left
 6157 instruct shlI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6158   match(Set dst (LShiftI src1 src2));
 6159 
 6160   size(4);
 6161   format %{ "LSL  $dst,$src1,$src2 \n\t" %}
 6162   ins_encode %{
 6163     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 6164   %}
 6165   ins_pipe(ialu_reg_reg);
 6166 %}
 6167 
 6168 // Register Shift Left Immediate
 6169 instruct shlI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
 6170   match(Set dst (LShiftI src1 src2));
 6171 
 6172   size(4);
 6173   format %{ "LSL    $dst,$src1,$src2\t! int" %}
 6174   ins_encode %{
 6175     __ logical_shift_left($dst$$Register, $src1$$Register, $src2$$constant);
 6176   %}
 6177   ins_pipe(ialu_reg_imm);
 6178 %}
 6179 
 6180 instruct shlL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
 6181   effect(USE_DEF dst, USE src1, USE src2);
 6182   size(4);
 6183   format %{"OR  $dst.hi,$dst.hi,($src1.hi << $src2)"  %}
 6184   ins_encode %{
 6185     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$Register));
 6186   %}
 6187   ins_pipe(ialu_reg_reg);
 6188 %}
 6189 
 6190 instruct shlL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
 6191   effect(USE_DEF dst, USE src1, USE src2);
 6192   size(4);
 6193   format %{ "LSL  $dst.lo,$src1.lo,$src2 \n\t" %}
 6194   ins_encode %{
 6195     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 6196   %}
 6197   ins_pipe(ialu_reg_reg);
 6198 %}
 6199 
 6200 instruct shlL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
 6201   effect(DEF dst, USE src1, USE src2, KILL ccr);
 6202   size(16);
 6203   format %{ "SUBS  $dst.hi,$src2,32 \n\t"
 6204             "LSLpl $dst.hi,$src1.lo,$dst.hi \n\t"
 6205             "RSBmi $dst.hi,$dst.hi,0 \n\t"
 6206             "LSRmi $dst.hi,$src1.lo,$dst.hi" %}
 6207 
 6208   ins_encode %{
 6209     // $src1$$Register and $dst$$Register->successor() can't be the same
 6210     __ subs($dst$$Register->successor(), $src2$$Register, 32);
 6211     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $dst$$Register->successor()), pl);
 6212     __ rsb($dst$$Register->successor(), $dst$$Register->successor(), 0, mi);
 6213     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsr, $dst$$Register->successor()), mi);
 6214   %}
 6215   ins_pipe(ialu_reg_reg);
 6216 %}
 6217 
 6218 instruct shlL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
 6219   match(Set dst (LShiftL src1 src2));
 6220 
 6221   expand %{
 6222     flagsReg ccr;
 6223     shlL_reg_reg_overlap(dst, src1, src2, ccr);
 6224     shlL_reg_reg_merge_hi(dst, src1, src2);
 6225     shlL_reg_reg_merge_lo(dst, src1, src2);
 6226   %}
 6227 %}
 6228 
 6229 // Register Shift Left Immediate
 6230 instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
 6231   match(Set dst (LShiftL src1 src2));
 6232 
 6233   size(8);
 6234   format %{ "LSL   $dst.hi,$src1.lo,$src2-32\t! or mov if $src2==32\n\t"
 6235             "MOV   $dst.lo, 0" %}
 6236   ins_encode %{
 6237     if ($src2$$constant == 32) {
 6238       __ mov($dst$$Register->successor(), $src1$$Register);
 6239     } else {
 6240       __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $src2$$constant-32));
 6241     }
 6242     __ mov($dst$$Register, 0);
 6243   %}
 6244   ins_pipe(ialu_reg_imm);
 6245 %}
 6246 
 6247 instruct shlL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
 6248   match(Set dst (LShiftL src1 src2));
 6249 
 6250   size(12);
 6251   format %{ "LSL   $dst.hi,$src1.lo,$src2\n\t"
 6252             "OR    $dst.hi, $dst.hi, $src1.lo >> 32-$src2\n\t"
 6253             "LSL   $dst.lo,$src1.lo,$src2" %}
 6254   ins_encode %{
 6255     // The order of the following 3 instructions matters: src1.lo and
 6256     // dst.hi can't overlap but src.hi and dst.hi can.
 6257     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$constant));
 6258     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register, lsr, 32-$src2$$constant));
 6259     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
 6260   %}
 6261   ins_pipe(ialu_reg_imm);
 6262 %}
 6263 
 6264 // Register Arithmetic Shift Right
 6265 instruct sarI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6266   match(Set dst (RShiftI src1 src2));
 6267   size(4);
 6268   format %{ "ASR    $dst,$src1,$src2\t! int" %}
 6269   ins_encode %{
 6270     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
 6271   %}
 6272   ins_pipe(ialu_reg_reg);
 6273 %}
 6274 
 6275 // Register Arithmetic Shift Right Immediate
 6276 instruct sarI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
 6277   match(Set dst (RShiftI src1 src2));
 6278 
 6279   size(4);
 6280   format %{ "ASR    $dst,$src1,$src2" %}
 6281   ins_encode %{
 6282     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
 6283   %}
 6284   ins_pipe(ialu_reg_imm);
 6285 %}
 6286 
 6287 // Register Shift Right Arithmetic Long
 6288 instruct sarL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
 6289   effect(USE_DEF dst, USE src1, USE src2);
 6290   size(4);
 6291   format %{ "OR  $dst.lo,$dst.lo,($src1.lo >> $src2)"  %}
 6292   ins_encode %{
 6293     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6294   %}
 6295   ins_pipe(ialu_reg_reg);
 6296 %}
 6297 
 6298 instruct sarL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
 6299   effect(USE_DEF dst, USE src1, USE src2);
 6300   size(4);
 6301   format %{ "ASR  $dst.hi,$src1.hi,$src2 \n\t" %}
 6302   ins_encode %{
 6303     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$Register));
 6304   %}
 6305   ins_pipe(ialu_reg_reg);
 6306 %}
 6307 
 6308 instruct sarL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
 6309   effect(DEF dst, USE src1, USE src2, KILL ccr);
 6310   size(16);
 6311   format %{ "SUBS  $dst.lo,$src2,32 \n\t"
 6312             "ASRpl $dst.lo,$src1.hi,$dst.lo \n\t"
 6313             "RSBmi $dst.lo,$dst.lo,0 \n\t"
 6314             "LSLmi $dst.lo,$src1.hi,$dst.lo" %}
 6315 
 6316   ins_encode %{
 6317     // $src1$$Register->successor() and $dst$$Register can't be the same
 6318     __ subs($dst$$Register, $src2$$Register, 32);
 6319     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $dst$$Register), pl);
 6320     __ rsb($dst$$Register, $dst$$Register, 0, mi);
 6321     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
 6322   %}
 6323   ins_pipe(ialu_reg_reg);
 6324 %}
 6325 
 6326 instruct sarL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
 6327   match(Set dst (RShiftL src1 src2));
 6328 
 6329   expand %{
 6330     flagsReg ccr;
 6331     sarL_reg_reg_overlap(dst, src1, src2, ccr);
 6332     sarL_reg_reg_merge_lo(dst, src1, src2);
 6333     sarL_reg_reg_merge_hi(dst, src1, src2);
 6334   %}
 6335 %}
 6336 
 6337 // Register Shift Left Immediate
 6338 instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
 6339   match(Set dst (RShiftL src1 src2));
 6340 
 6341   size(8);
 6342   format %{ "ASR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
 6343             "ASR   $dst.hi,$src1.hi, $src2" %}
 6344   ins_encode %{
 6345     if ($src2$$constant == 32) {
 6346       __ mov($dst$$Register, $src1$$Register->successor());
 6347     } else{
 6348       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $src2$$constant-32));
 6349     }
 6350     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, 0));
 6351   %}
 6352 
 6353   ins_pipe(ialu_reg_imm);
 6354 %}
 6355 
 6356 instruct sarL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
 6357   match(Set dst (RShiftL src1 src2));
 6358   size(12);
 6359   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
 6360             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
 6361             "ASR   $dst.hi,$src1.hi,$src2" %}
 6362   ins_encode %{
 6363     // The order of the following 3 instructions matters: src1.lo and
 6364     // dst.hi can't overlap but src.hi and dst.hi can.
 6365     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6366     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
 6367     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$constant));
 6368   %}
 6369   ins_pipe(ialu_reg_imm);
 6370 %}
 6371 
 6372 // Register Shift Right
 6373 instruct shrI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6374   match(Set dst (URShiftI src1 src2));
 6375   size(4);
 6376   format %{ "LSR    $dst,$src1,$src2\t! int" %}
 6377   ins_encode %{
 6378     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6379   %}
 6380   ins_pipe(ialu_reg_reg);
 6381 %}
 6382 
 6383 // Register Shift Right Immediate
 6384 instruct shrI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
 6385   match(Set dst (URShiftI src1 src2));
 6386 
 6387   size(4);
 6388   format %{ "LSR    $dst,$src1,$src2" %}
 6389   ins_encode %{
 6390     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6391   %}
 6392   ins_pipe(ialu_reg_imm);
 6393 %}
 6394 
 6395 // Register Shift Right
 6396 instruct shrL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
 6397   effect(USE_DEF dst, USE src1, USE src2);
 6398   size(4);
 6399   format %{ "OR   $dst.lo,$dst,($src1.lo >>> $src2)"  %}
 6400   ins_encode %{
 6401     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6402   %}
 6403   ins_pipe(ialu_reg_reg);
 6404 %}
 6405 
 6406 instruct shrL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
 6407   effect(USE_DEF dst, USE src1, USE src2);
 6408   size(4);
 6409   format %{ "LSR  $dst.hi,$src1.hi,$src2 \n\t" %}
 6410   ins_encode %{
 6411     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$Register));
 6412   %}
 6413   ins_pipe(ialu_reg_reg);
 6414 %}
 6415 
 6416 instruct shrL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
 6417   effect(DEF dst, USE src1, USE src2, KILL ccr);
 6418   size(16);
 6419   format %{ "SUBS  $dst,$src2,32 \n\t"
 6420             "LSRpl $dst,$src1.hi,$dst \n\t"
 6421             "RSBmi $dst,$dst,0 \n\t"
 6422             "LSLmi $dst,$src1.hi,$dst" %}
 6423 
 6424   ins_encode %{
 6425     // $src1$$Register->successor() and $dst$$Register can't be the same
 6426     __ subs($dst$$Register, $src2$$Register, 32);
 6427     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $dst$$Register), pl);
 6428     __ rsb($dst$$Register, $dst$$Register, 0, mi);
 6429     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
 6430   %}
 6431   ins_pipe(ialu_reg_reg);
 6432 %}
 6433 
 6434 instruct shrL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
 6435   match(Set dst (URShiftL src1 src2));
 6436 
 6437   expand %{
 6438     flagsReg ccr;
 6439     shrL_reg_reg_overlap(dst, src1, src2, ccr);
 6440     shrL_reg_reg_merge_lo(dst, src1, src2);
 6441     shrL_reg_reg_merge_hi(dst, src1, src2);
 6442   %}
 6443 %}
 6444 
 6445 // Register Shift Right Immediate
 6446 instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
 6447   match(Set dst (URShiftL src1 src2));
 6448 
 6449   size(8);
 6450   format %{ "LSR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
 6451             "MOV   $dst.hi, 0" %}
 6452   ins_encode %{
 6453     if ($src2$$constant == 32) {
 6454       __ mov($dst$$Register, $src1$$Register->successor());
 6455     } else {
 6456       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $src2$$constant-32));
 6457     }
 6458     __ mov($dst$$Register->successor(), 0);
 6459   %}
 6460 
 6461   ins_pipe(ialu_reg_imm);
 6462 %}
 6463 
 6464 instruct shrL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
 6465   match(Set dst (URShiftL src1 src2));
 6466 
 6467   size(12);
 6468   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
 6469             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
 6470             "LSR   $dst.hi,$src1.hi,$src2" %}
 6471   ins_encode %{
 6472     // The order of the following 3 instructions matters: src1.lo and
 6473     // dst.hi can't overlap but src.hi and dst.hi can.
 6474     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6475     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
 6476     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$constant));
 6477   %}
 6478   ins_pipe(ialu_reg_imm);
 6479 %}
 6480 
 6481 
 6482 instruct shrP_reg_imm5(iRegX dst, iRegP src1, immU5 src2) %{
 6483   match(Set dst (URShiftI (CastP2X src1) src2));
 6484   size(4);
 6485   format %{ "LSR    $dst,$src1,$src2\t! Cast ptr $src1 to int and shift" %}
 6486   ins_encode %{
 6487     __ logical_shift_right($dst$$Register, $src1$$Register, $src2$$constant);
 6488   %}
 6489   ins_pipe(ialu_reg_imm);
 6490 %}
 6491 
 6492 //----------Floating Point Arithmetic Instructions-----------------------------
 6493 
 6494 //  Add float single precision
 6495 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
 6496   match(Set dst (AddF src1 src2));
 6497 
 6498   size(4);
 6499   format %{ "FADDS  $dst,$src1,$src2" %}
 6500   ins_encode %{
 6501     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6502   %}
 6503 
 6504   ins_pipe(faddF_reg_reg);
 6505 %}
 6506 
 6507 //  Add float double precision
 6508 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
 6509   match(Set dst (AddD src1 src2));
 6510 
 6511   size(4);
 6512   format %{ "FADDD  $dst,$src1,$src2" %}
 6513   ins_encode %{
 6514     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6515   %}
 6516 
 6517   ins_pipe(faddD_reg_reg);
 6518 %}
 6519 
 6520 //  Sub float single precision
 6521 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
 6522   match(Set dst (SubF src1 src2));
 6523 
 6524   size(4);
 6525   format %{ "FSUBS  $dst,$src1,$src2" %}
 6526   ins_encode %{
 6527     __ sub_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6528   %}
 6529   ins_pipe(faddF_reg_reg);
 6530 %}
 6531 
 6532 //  Sub float double precision
 6533 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
 6534   match(Set dst (SubD src1 src2));
 6535 
 6536   size(4);
 6537   format %{ "FSUBD  $dst,$src1,$src2" %}
 6538   ins_encode %{
 6539     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6540   %}
 6541   ins_pipe(faddD_reg_reg);
 6542 %}
 6543 
 6544 //  Mul float single precision
 6545 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
 6546   match(Set dst (MulF src1 src2));
 6547 
 6548   size(4);
 6549   format %{ "FMULS  $dst,$src1,$src2" %}
 6550   ins_encode %{
 6551     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6552   %}
 6553 
 6554   ins_pipe(fmulF_reg_reg);
 6555 %}
 6556 
 6557 //  Mul float double precision
 6558 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
 6559   match(Set dst (MulD src1 src2));
 6560 
 6561   size(4);
 6562   format %{ "FMULD  $dst,$src1,$src2" %}
 6563   ins_encode %{
 6564     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6565   %}
 6566 
 6567   ins_pipe(fmulD_reg_reg);
 6568 %}
 6569 
 6570 //  Div float single precision
 6571 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
 6572   match(Set dst (DivF src1 src2));
 6573 
 6574   size(4);
 6575   format %{ "FDIVS  $dst,$src1,$src2" %}
 6576   ins_encode %{
 6577     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6578   %}
 6579 
 6580   ins_pipe(fdivF_reg_reg);
 6581 %}
 6582 
 6583 //  Div float double precision
 6584 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
 6585   match(Set dst (DivD src1 src2));
 6586 
 6587   size(4);
 6588   format %{ "FDIVD  $dst,$src1,$src2" %}
 6589   ins_encode %{
 6590     __ div_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6591   %}
 6592 
 6593   ins_pipe(fdivD_reg_reg);
 6594 %}
 6595 
 6596 //  Absolute float double precision
 6597 instruct absD_reg(regD dst, regD src) %{
 6598   match(Set dst (AbsD src));
 6599 
 6600   size(4);
 6601   format %{ "FABSd  $dst,$src" %}
 6602   ins_encode %{
 6603     __ abs_double($dst$$FloatRegister, $src$$FloatRegister);
 6604   %}
 6605   ins_pipe(faddD_reg);
 6606 %}
 6607 
 6608 //  Absolute float single precision
 6609 instruct absF_reg(regF dst, regF src) %{
 6610   match(Set dst (AbsF src));
 6611   format %{ "FABSs  $dst,$src" %}
 6612   ins_encode %{
 6613     __ abs_float($dst$$FloatRegister, $src$$FloatRegister);
 6614   %}
 6615   ins_pipe(faddF_reg);
 6616 %}
 6617 
 6618 instruct negF_reg(regF dst, regF src) %{
 6619   match(Set dst (NegF src));
 6620 
 6621   size(4);
 6622   format %{ "FNEGs  $dst,$src" %}
 6623   ins_encode %{
 6624     __ neg_float($dst$$FloatRegister, $src$$FloatRegister);
 6625   %}
 6626   ins_pipe(faddF_reg);
 6627 %}
 6628 
 6629 instruct negD_reg(regD dst, regD src) %{
 6630   match(Set dst (NegD src));
 6631 
 6632   format %{ "FNEGd  $dst,$src" %}
 6633   ins_encode %{
 6634     __ neg_double($dst$$FloatRegister, $src$$FloatRegister);
 6635   %}
 6636   ins_pipe(faddD_reg);
 6637 %}
 6638 
 6639 //  Sqrt float double precision
 6640 instruct sqrtF_reg_reg(regF dst, regF src) %{
 6641   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
 6642 
 6643   size(4);
 6644   format %{ "FSQRTS $dst,$src" %}
 6645   ins_encode %{
 6646     __ sqrt_float($dst$$FloatRegister, $src$$FloatRegister);
 6647   %}
 6648   ins_pipe(fdivF_reg_reg);
 6649 %}
 6650 
 6651 //  Sqrt float double precision
 6652 instruct sqrtD_reg_reg(regD dst, regD src) %{
 6653   match(Set dst (SqrtD src));
 6654 
 6655   size(4);
 6656   format %{ "FSQRTD $dst,$src" %}
 6657   ins_encode %{
 6658     __ sqrt_double($dst$$FloatRegister, $src$$FloatRegister);
 6659   %}
 6660   ins_pipe(fdivD_reg_reg);
 6661 %}
 6662 
 6663 //----------Logical Instructions-----------------------------------------------
 6664 // And Instructions
 6665 // Register And
 6666 instruct andI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6667   match(Set dst (AndI src1 src2));
 6668 
 6669   size(4);
 6670   format %{ "and_32 $dst,$src1,$src2" %}
 6671   ins_encode %{
 6672     __ and_32($dst$$Register, $src1$$Register, $src2$$Register);
 6673   %}
 6674   ins_pipe(ialu_reg_reg);
 6675 %}
 6676 
 6677 instruct andshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6678   match(Set dst (AndI src1 (LShiftI src2 src3)));
 6679 
 6680   size(4);
 6681   format %{ "AND    $dst,$src1,$src2<<$src3" %}
 6682   ins_encode %{
 6683     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 6684   %}
 6685   ins_pipe(ialu_reg_reg);
 6686 %}
 6687 
 6688 instruct andshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6689   match(Set dst (AndI src1 (LShiftI src2 src3)));
 6690 
 6691   size(4);
 6692   format %{ "and_32 $dst,$src1,$src2<<$src3" %}
 6693   ins_encode %{
 6694     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 6695   %}
 6696   ins_pipe(ialu_reg_reg);
 6697 %}
 6698 
 6699 instruct andsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6700   match(Set dst (AndI src1 (RShiftI src2 src3)));
 6701 
 6702   size(4);
 6703   format %{ "AND    $dst,$src1,$src2>>$src3" %}
 6704   ins_encode %{
 6705     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 6706   %}
 6707   ins_pipe(ialu_reg_reg);
 6708 %}
 6709 
 6710 instruct andsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6711   match(Set dst (AndI src1 (RShiftI src2 src3)));
 6712 
 6713   size(4);
 6714   format %{ "and_32 $dst,$src1,$src2>>$src3" %}
 6715   ins_encode %{
 6716     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 6717   %}
 6718   ins_pipe(ialu_reg_reg);
 6719 %}
 6720 
 6721 instruct andshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6722   match(Set dst (AndI src1 (URShiftI src2 src3)));
 6723 
 6724   size(4);
 6725   format %{ "AND    $dst,$src1,$src2>>>$src3" %}
 6726   ins_encode %{
 6727     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 6728   %}
 6729   ins_pipe(ialu_reg_reg);
 6730 %}
 6731 
 6732 instruct andshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6733   match(Set dst (AndI src1 (URShiftI src2 src3)));
 6734 
 6735   size(4);
 6736   format %{ "and_32 $dst,$src1,$src2>>>$src3" %}
 6737   ins_encode %{
 6738     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 6739   %}
 6740   ins_pipe(ialu_reg_reg);
 6741 %}
 6742 
 6743 // Immediate And
 6744 instruct andI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
 6745   match(Set dst (AndI src1 src2));
 6746 
 6747   size(4);
 6748   format %{ "and_32 $dst,$src1,$src2\t! int" %}
 6749   ins_encode %{
 6750     __ and_32($dst$$Register, $src1$$Register, $src2$$constant);
 6751   %}
 6752   ins_pipe(ialu_reg_imm);
 6753 %}
 6754 
 6755 instruct andI_reg_limmn(iRegI dst, iRegI src1, limmIn src2) %{
 6756   match(Set dst (AndI src1 src2));
 6757 
 6758   size(4);
 6759   format %{ "bic    $dst,$src1,~$src2\t! int" %}
 6760   ins_encode %{
 6761     __ bic($dst$$Register, $src1$$Register, ~$src2$$constant);
 6762   %}
 6763   ins_pipe(ialu_reg_imm);
 6764 %}
 6765 
 6766 // Register And Long
 6767 instruct andL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 6768   match(Set dst (AndL src1 src2));
 6769 
 6770   ins_cost(DEFAULT_COST);
 6771   size(8);
 6772   format %{ "AND    $dst,$src1,$src2\t! long" %}
 6773   ins_encode %{
 6774     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
 6775     __ andr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 6776   %}
 6777   ins_pipe(ialu_reg_reg);
 6778 %}
 6779 
 6780 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 6781 // (hi($con$$constant), lo($con$$constant)) becomes
 6782 instruct andL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
 6783   match(Set dst (AndL src1 con));
 6784   ins_cost(DEFAULT_COST);
 6785   size(8);
 6786   format %{ "AND    $dst,$src1,$con\t! long" %}
 6787   ins_encode %{
 6788     __ andr($dst$$Register, $src1$$Register, $con$$constant);
 6789     __ andr($dst$$Register->successor(), $src1$$Register->successor(), 0);
 6790   %}
 6791   ins_pipe(ialu_reg_imm);
 6792 %}
 6793 
 6794 // Or Instructions
 6795 // Register Or
 6796 instruct orI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6797   match(Set dst (OrI src1 src2));
 6798 
 6799   size(4);
 6800   format %{ "orr_32 $dst,$src1,$src2\t! int" %}
 6801   ins_encode %{
 6802     __ orr_32($dst$$Register, $src1$$Register, $src2$$Register);
 6803   %}
 6804   ins_pipe(ialu_reg_reg);
 6805 %}
 6806 
 6807 instruct orshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6808   match(Set dst (OrI src1 (LShiftI src2 src3)));
 6809 
 6810   size(4);
 6811   format %{ "OR    $dst,$src1,$src2<<$src3" %}
 6812   ins_encode %{
 6813     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 6814   %}
 6815   ins_pipe(ialu_reg_reg);
 6816 %}
 6817 
 6818 instruct orshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6819   match(Set dst (OrI src1 (LShiftI src2 src3)));
 6820 
 6821   size(4);
 6822   format %{ "orr_32 $dst,$src1,$src2<<$src3" %}
 6823   ins_encode %{
 6824     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 6825   %}
 6826   ins_pipe(ialu_reg_reg);
 6827 %}
 6828 
 6829 instruct orsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6830   match(Set dst (OrI src1 (RShiftI src2 src3)));
 6831 
 6832   size(4);
 6833   format %{ "OR    $dst,$src1,$src2>>$src3" %}
 6834   ins_encode %{
 6835     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 6836   %}
 6837   ins_pipe(ialu_reg_reg);
 6838 %}
 6839 
 6840 instruct orsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6841   match(Set dst (OrI src1 (RShiftI src2 src3)));
 6842 
 6843   size(4);
 6844   format %{ "orr_32 $dst,$src1,$src2>>$src3" %}
 6845   ins_encode %{
 6846     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 6847   %}
 6848   ins_pipe(ialu_reg_reg);
 6849 %}
 6850 
 6851 instruct orshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6852   match(Set dst (OrI src1 (URShiftI src2 src3)));
 6853 
 6854   size(4);
 6855   format %{ "OR    $dst,$src1,$src2>>>$src3" %}
 6856   ins_encode %{
 6857     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 6858   %}
 6859   ins_pipe(ialu_reg_reg);
 6860 %}
 6861 
 6862 instruct orshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6863   match(Set dst (OrI src1 (URShiftI src2 src3)));
 6864 
 6865   size(4);
 6866   format %{ "orr_32 $dst,$src1,$src2>>>$src3" %}
 6867   ins_encode %{
 6868     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 6869   %}
 6870   ins_pipe(ialu_reg_reg);
 6871 %}
 6872 
 6873 // Immediate Or
 6874 instruct orI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
 6875   match(Set dst (OrI src1 src2));
 6876 
 6877   size(4);
 6878   format %{ "orr_32  $dst,$src1,$src2" %}
 6879   ins_encode %{
 6880     __ orr_32($dst$$Register, $src1$$Register, $src2$$constant);
 6881   %}
 6882   ins_pipe(ialu_reg_imm);
 6883 %}
 6884 // TODO: orn_32 with limmIn
 6885 
 6886 // Register Or Long
 6887 instruct orL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 6888   match(Set dst (OrL src1 src2));
 6889 
 6890   ins_cost(DEFAULT_COST);
 6891   size(8);
 6892   format %{ "OR     $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
 6893             "OR     $dst.hi,$src1.hi,$src2.hi" %}
 6894   ins_encode %{
 6895     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
 6896     __ orr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 6897   %}
 6898   ins_pipe(ialu_reg_reg);
 6899 %}
 6900 
 6901 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 6902 // (hi($con$$constant), lo($con$$constant)) becomes
 6903 instruct orL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
 6904   match(Set dst (OrL src1 con));
 6905   ins_cost(DEFAULT_COST);
 6906   size(8);
 6907   format %{ "OR     $dst.lo,$src1.lo,$con\t! long\n\t"
 6908             "OR     $dst.hi,$src1.hi,$con" %}
 6909   ins_encode %{
 6910     __ orr($dst$$Register, $src1$$Register, $con$$constant);
 6911     __ orr($dst$$Register->successor(), $src1$$Register->successor(), 0);
 6912   %}
 6913   ins_pipe(ialu_reg_imm);
 6914 %}
 6915 
 6916 #ifdef TODO
 6917 // Use SPRegP to match Rthread (TLS register) without spilling.
 6918 // Use store_ptr_RegP to match Rthread (TLS register) without spilling.
 6919 // Use sp_ptr_RegP to match Rthread (TLS register) without spilling.
 6920 instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
 6921   match(Set dst (OrI src1 (CastP2X src2)));
 6922   size(4);
 6923   format %{ "OR     $dst,$src1,$src2" %}
 6924   ins_encode %{
 6925     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
 6926   %}
 6927   ins_pipe(ialu_reg_reg);
 6928 %}
 6929 #endif
 6930 
 6931 // Xor Instructions
 6932 // Register Xor
 6933 instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6934   match(Set dst (XorI src1 src2));
 6935 
 6936   size(4);
 6937   format %{ "eor_32 $dst,$src1,$src2" %}
 6938   ins_encode %{
 6939     __ eor_32($dst$$Register, $src1$$Register, $src2$$Register);
 6940   %}
 6941   ins_pipe(ialu_reg_reg);
 6942 %}
 6943 
 6944 instruct xorshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6945   match(Set dst (XorI src1 (LShiftI src2 src3)));
 6946 
 6947   size(4);
 6948   format %{ "XOR    $dst,$src1,$src2<<$src3" %}
 6949   ins_encode %{
 6950     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 6951   %}
 6952   ins_pipe(ialu_reg_reg);
 6953 %}
 6954 
 6955 instruct xorshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6956   match(Set dst (XorI src1 (LShiftI src2 src3)));
 6957 
 6958   size(4);
 6959   format %{ "eor_32 $dst,$src1,$src2<<$src3" %}
 6960   ins_encode %{
 6961     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 6962   %}
 6963   ins_pipe(ialu_reg_reg);
 6964 %}
 6965 
 6966 instruct xorsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6967   match(Set dst (XorI src1 (RShiftI src2 src3)));
 6968 
 6969   size(4);
 6970   format %{ "XOR    $dst,$src1,$src2>>$src3" %}
 6971   ins_encode %{
 6972     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 6973   %}
 6974   ins_pipe(ialu_reg_reg);
 6975 %}
 6976 
 6977 instruct xorsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6978   match(Set dst (XorI src1 (RShiftI src2 src3)));
 6979 
 6980   size(4);
 6981   format %{ "eor_32 $dst,$src1,$src2>>$src3" %}
 6982   ins_encode %{
 6983     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 6984   %}
 6985   ins_pipe(ialu_reg_reg);
 6986 %}
 6987 
 6988 instruct xorshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6989   match(Set dst (XorI src1 (URShiftI src2 src3)));
 6990 
 6991   size(4);
 6992   format %{ "XOR    $dst,$src1,$src2>>>$src3" %}
 6993   ins_encode %{
 6994     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 6995   %}
 6996   ins_pipe(ialu_reg_reg);
 6997 %}
 6998 
 6999 instruct xorshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 7000   match(Set dst (XorI src1 (URShiftI src2 src3)));
 7001 
 7002   size(4);
 7003   format %{ "eor_32 $dst,$src1,$src2>>>$src3" %}
 7004   ins_encode %{
 7005     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 7006   %}
 7007   ins_pipe(ialu_reg_reg);
 7008 %}
 7009 
 7010 // Immediate Xor
 7011 instruct xorI_reg_imm(iRegI dst, iRegI src1, limmI src2) %{
 7012   match(Set dst (XorI src1 src2));
 7013 
 7014   size(4);
 7015   format %{ "eor_32 $dst,$src1,$src2" %}
 7016   ins_encode %{
 7017     __ eor_32($dst$$Register, $src1$$Register, $src2$$constant);
 7018   %}
 7019   ins_pipe(ialu_reg_imm);
 7020 %}
 7021 
 7022 // Register Xor Long
 7023 instruct xorL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 7024   match(Set dst (XorL src1 src2));
 7025   ins_cost(DEFAULT_COST);
 7026   size(8);
 7027   format %{ "XOR     $dst.hi,$src1.hi,$src2.hi\t! long\n\t"
 7028             "XOR     $dst.lo,$src1.lo,$src2.lo\t! long" %}
 7029   ins_encode %{
 7030     __ eor($dst$$Register, $src1$$Register, $src2$$Register);
 7031     __ eor($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 7032   %}
 7033   ins_pipe(ialu_reg_reg);
 7034 %}
 7035 
 7036 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7037 // (hi($con$$constant), lo($con$$constant)) becomes
 7038 instruct xorL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
 7039   match(Set dst (XorL src1 con));
 7040   ins_cost(DEFAULT_COST);
 7041   size(8);
 7042   format %{ "XOR     $dst.hi,$src1.hi,$con\t! long\n\t"
 7043             "XOR     $dst.lo,$src1.lo,0\t! long" %}
 7044   ins_encode %{
 7045     __ eor($dst$$Register, $src1$$Register, $con$$constant);
 7046     __ eor($dst$$Register->successor(), $src1$$Register->successor(), 0);
 7047   %}
 7048   ins_pipe(ialu_reg_imm);
 7049 %}
 7050 
 7051 //----------Convert to Boolean-------------------------------------------------
 7052 instruct convI2B( iRegI dst, iRegI src, flagsReg ccr ) %{
 7053   match(Set dst (Conv2B src));
 7054   effect(KILL ccr);
 7055   size(12);
 7056   ins_cost(DEFAULT_COST*2);
 7057   format %{ "TST    $src,$src \n\t"
 7058             "MOV    $dst, 0   \n\t"
 7059             "MOV.ne $dst, 1" %}
 7060   ins_encode %{ // FIXME: can do better?
 7061     __ tst($src$$Register, $src$$Register);
 7062     __ mov($dst$$Register, 0);
 7063     __ mov($dst$$Register, 1, ne);
 7064   %}
 7065   ins_pipe(ialu_reg_ialu);
 7066 %}
 7067 
 7068 instruct convP2B( iRegI dst, iRegP src, flagsReg ccr ) %{
 7069   match(Set dst (Conv2B src));
 7070   effect(KILL ccr);
 7071   size(12);
 7072   ins_cost(DEFAULT_COST*2);
 7073   format %{ "TST    $src,$src \n\t"
 7074             "MOV    $dst, 0   \n\t"
 7075             "MOV.ne $dst, 1" %}
 7076   ins_encode %{
 7077     __ tst($src$$Register, $src$$Register);
 7078     __ mov($dst$$Register, 0);
 7079     __ mov($dst$$Register, 1, ne);
 7080   %}
 7081   ins_pipe(ialu_reg_ialu);
 7082 %}
 7083 
 7084 instruct cmpLTMask_reg_reg( iRegI dst, iRegI p, iRegI q, flagsReg ccr ) %{
 7085   match(Set dst (CmpLTMask p q));
 7086   effect( KILL ccr );
 7087   ins_cost(DEFAULT_COST*3);
 7088   format %{ "CMP    $p,$q\n\t"
 7089             "MOV    $dst, #0\n\t"
 7090             "MOV.lt $dst, #-1" %}
 7091   ins_encode %{
 7092     __ cmp($p$$Register, $q$$Register);
 7093     __ mov($dst$$Register, 0);
 7094     __ mvn($dst$$Register, 0, lt);
 7095   %}
 7096   ins_pipe(ialu_reg_reg_ialu);
 7097 %}
 7098 
 7099 instruct cmpLTMask_reg_imm( iRegI dst, iRegI p, aimmI q, flagsReg ccr ) %{
 7100   match(Set dst (CmpLTMask p q));
 7101   effect( KILL ccr );
 7102   ins_cost(DEFAULT_COST*3);
 7103   format %{ "CMP    $p,$q\n\t"
 7104             "MOV    $dst, #0\n\t"
 7105             "MOV.lt $dst, #-1" %}
 7106   ins_encode %{
 7107     __ cmp($p$$Register, $q$$constant);
 7108     __ mov($dst$$Register, 0);
 7109     __ mvn($dst$$Register, 0, lt);
 7110   %}
 7111   ins_pipe(ialu_reg_reg_ialu);
 7112 %}
 7113 
 7114 instruct cadd_cmpLTMask3( iRegI p, iRegI q, iRegI y, iRegI z, flagsReg ccr ) %{
 7115   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
 7116   effect( KILL ccr );
 7117   ins_cost(DEFAULT_COST*2);
 7118   format %{ "CMP    $p,$q\n\t"
 7119             "ADD.lt $z,$y,$z" %}
 7120   ins_encode %{
 7121     __ cmp($p$$Register, $q$$Register);
 7122     __ add($z$$Register, $y$$Register, $z$$Register, lt);
 7123   %}
 7124   ins_pipe( cadd_cmpltmask );
 7125 %}
 7126 
 7127 // FIXME: remove unused "dst"
 7128 instruct cadd_cmpLTMask4( iRegI dst, iRegI p, aimmI q, iRegI y, iRegI z, flagsReg ccr ) %{
 7129   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
 7130   effect( KILL ccr );
 7131   ins_cost(DEFAULT_COST*2);
 7132   format %{ "CMP    $p,$q\n\t"
 7133             "ADD.lt $z,$y,$z" %}
 7134   ins_encode %{
 7135     __ cmp($p$$Register, $q$$constant);
 7136     __ add($z$$Register, $y$$Register, $z$$Register, lt);
 7137   %}
 7138   ins_pipe( cadd_cmpltmask );
 7139 %}
 7140 
 7141 instruct cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, flagsReg ccr ) %{
 7142   match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
 7143   effect( KILL ccr );
 7144   ins_cost(DEFAULT_COST*2);
 7145   format %{ "SUBS   $p,$p,$q\n\t"
 7146             "ADD.lt $p,$y,$p" %}
 7147   ins_encode %{
 7148     __ subs($p$$Register, $p$$Register, $q$$Register);
 7149     __ add($p$$Register, $y$$Register, $p$$Register, lt);
 7150   %}
 7151   ins_pipe( cadd_cmpltmask );
 7152 %}
 7153 
 7154 //----------Arithmetic Conversion Instructions---------------------------------
 7155 // The conversions operations are all Alpha sorted.  Please keep it that way!
 7156 
 7157 instruct convD2F_reg(regF dst, regD src) %{
 7158   match(Set dst (ConvD2F src));
 7159   size(4);
 7160   format %{ "FCVTSD  $dst,$src" %}
 7161   ins_encode %{
 7162     __ convert_d2f($dst$$FloatRegister, $src$$FloatRegister);
 7163   %}
 7164   ins_pipe(fcvtD2F);
 7165 %}
 7166 
 7167 // Convert a double to an int in a float register.
 7168 // If the double is a NAN, stuff a zero in instead.
 7169 
 7170 instruct convD2I_reg_reg(iRegI dst, regD src, regF tmp) %{
 7171   match(Set dst (ConvD2I src));
 7172   effect( TEMP tmp );
 7173   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
 7174   format %{ "FTOSIZD  $tmp,$src\n\t"
 7175             "FMRS     $dst, $tmp" %}
 7176   ins_encode %{
 7177     __ ftosizd($tmp$$FloatRegister, $src$$FloatRegister);
 7178     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 7179   %}
 7180   ins_pipe(fcvtD2I);
 7181 %}
 7182 
 7183 // Convert a double to a long in a double register.
 7184 // If the double is a NAN, stuff a zero in instead.
 7185 
 7186 // Double to Long conversion
 7187 instruct convD2L_reg(R0R1RegL dst, regD src) %{
 7188   match(Set dst (ConvD2L src));
 7189   effect(CALL);
 7190   ins_cost(MEMORY_REF_COST); // FIXME
 7191   format %{ "convD2L    $dst,$src\t ! call to SharedRuntime::d2l" %}
 7192   ins_encode %{
 7193 #ifndef __ABI_HARD__
 7194     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
 7195 #else
 7196     if ($src$$FloatRegister != D0) {
 7197       __ mov_double(D0, $src$$FloatRegister);
 7198     }
 7199 #endif
 7200     address target = CAST_FROM_FN_PTR(address, SharedRuntime::d2l);
 7201     __ call(target, relocInfo::runtime_call_type);
 7202   %}
 7203   ins_pipe(fcvtD2L);
 7204 %}
 7205 
 7206 instruct convF2D_reg(regD dst, regF src) %{
 7207   match(Set dst (ConvF2D src));
 7208   size(4);
 7209   format %{ "FCVTDS  $dst,$src" %}
 7210   ins_encode %{
 7211     __ convert_f2d($dst$$FloatRegister, $src$$FloatRegister);
 7212   %}
 7213   ins_pipe(fcvtF2D);
 7214 %}
 7215 
 7216 instruct convF2I_reg_reg(iRegI dst, regF src, regF tmp) %{
 7217   match(Set dst (ConvF2I src));
 7218   effect( TEMP tmp );
 7219   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
 7220   size(8);
 7221   format %{ "FTOSIZS  $tmp,$src\n\t"
 7222             "FMRS     $dst, $tmp" %}
 7223   ins_encode %{
 7224     __ ftosizs($tmp$$FloatRegister, $src$$FloatRegister);
 7225     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 7226   %}
 7227   ins_pipe(fcvtF2I);
 7228 %}
 7229 
 7230 // Float to Long conversion
 7231 instruct convF2L_reg(R0R1RegL dst, regF src, R0RegI arg1) %{
 7232   match(Set dst (ConvF2L src));
 7233   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
 7234   effect(CALL);
 7235   format %{ "convF2L  $dst,$src\t! call to SharedRuntime::f2l" %}
 7236   ins_encode %{
 7237 #ifndef __ABI_HARD__
 7238     __ fmrs($arg1$$Register, $src$$FloatRegister);
 7239 #else
 7240     if($src$$FloatRegister != S0) {
 7241       __ mov_float(S0, $src$$FloatRegister);
 7242     }
 7243 #endif
 7244     address target = CAST_FROM_FN_PTR(address, SharedRuntime::f2l);
 7245     __ call(target, relocInfo::runtime_call_type);
 7246   %}
 7247   ins_pipe(fcvtF2L);
 7248 %}
 7249 
 7250 instruct convI2D_reg_reg(iRegI src, regD_low dst) %{
 7251   match(Set dst (ConvI2D src));
 7252   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
 7253   size(8);
 7254   format %{ "FMSR     $dst,$src \n\t"
 7255             "FSITOD   $dst $dst"%}
 7256   ins_encode %{
 7257       __ fmsr($dst$$FloatRegister, $src$$Register);
 7258       __ fsitod($dst$$FloatRegister, $dst$$FloatRegister);
 7259   %}
 7260   ins_pipe(fcvtI2D);
 7261 %}
 7262 
 7263 instruct convI2F_reg_reg( regF dst, iRegI src ) %{
 7264   match(Set dst (ConvI2F src));
 7265   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
 7266   size(8);
 7267   format %{ "FMSR     $dst,$src \n\t"
 7268             "FSITOS   $dst, $dst"%}
 7269   ins_encode %{
 7270       __ fmsr($dst$$FloatRegister, $src$$Register);
 7271       __ fsitos($dst$$FloatRegister, $dst$$FloatRegister);
 7272   %}
 7273   ins_pipe(fcvtI2F);
 7274 %}
 7275 
 7276 instruct convI2L_reg(iRegL dst, iRegI src) %{
 7277   match(Set dst (ConvI2L src));
 7278   size(8);
 7279   format %{ "MOV    $dst.lo, $src \n\t"
 7280             "ASR    $dst.hi,$src,31\t! int->long" %}
 7281   ins_encode %{
 7282     __ mov($dst$$Register, $src$$Register);
 7283     __ mov($dst$$Register->successor(), AsmOperand($src$$Register, asr, 31));
 7284   %}
 7285   ins_pipe(ialu_reg_reg);
 7286 %}
 7287 
 7288 // Zero-extend convert int to long
 7289 instruct convI2L_reg_zex(iRegL dst, iRegI src, immL_32bits mask ) %{
 7290   match(Set dst (AndL (ConvI2L src) mask) );
 7291   size(8);
 7292   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend int to long\n\t"
 7293             "MOV    $dst.hi, 0"%}
 7294   ins_encode %{
 7295     __ mov($dst$$Register, $src$$Register);
 7296     __ mov($dst$$Register->successor(), 0);
 7297   %}
 7298   ins_pipe(ialu_reg_reg);
 7299 %}
 7300 
 7301 // Zero-extend long
 7302 instruct zerox_long(iRegL dst, iRegL src, immL_32bits mask ) %{
 7303   match(Set dst (AndL src mask) );
 7304   size(8);
 7305   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend long\n\t"
 7306             "MOV    $dst.hi, 0"%}
 7307   ins_encode %{
 7308     __ mov($dst$$Register, $src$$Register);
 7309     __ mov($dst$$Register->successor(), 0);
 7310   %}
 7311   ins_pipe(ialu_reg_reg);
 7312 %}
 7313 
 7314 instruct MoveF2I_reg_reg(iRegI dst, regF src) %{
 7315   match(Set dst (MoveF2I src));
 7316   effect(DEF dst, USE src);
 7317   ins_cost(MEMORY_REF_COST); // FIXME
 7318 
 7319   size(4);
 7320   format %{ "FMRS   $dst,$src\t! MoveF2I" %}
 7321   ins_encode %{
 7322     __ fmrs($dst$$Register, $src$$FloatRegister);
 7323   %}
 7324   ins_pipe(iload_mem); // FIXME
 7325 %}
 7326 
 7327 instruct MoveI2F_reg_reg(regF dst, iRegI src) %{
 7328   match(Set dst (MoveI2F src));
 7329   ins_cost(MEMORY_REF_COST); // FIXME
 7330 
 7331   size(4);
 7332   format %{ "FMSR   $dst,$src\t! MoveI2F" %}
 7333   ins_encode %{
 7334     __ fmsr($dst$$FloatRegister, $src$$Register);
 7335   %}
 7336   ins_pipe(iload_mem); // FIXME
 7337 %}
 7338 
 7339 instruct MoveD2L_reg_reg(iRegL dst, regD src) %{
 7340   match(Set dst (MoveD2L src));
 7341   effect(DEF dst, USE src);
 7342   ins_cost(MEMORY_REF_COST); // FIXME
 7343 
 7344   size(4);
 7345   format %{ "FMRRD    $dst,$src\t! MoveD2L" %}
 7346   ins_encode %{
 7347     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
 7348   %}
 7349   ins_pipe(iload_mem); // FIXME
 7350 %}
 7351 
 7352 instruct MoveL2D_reg_reg(regD dst, iRegL src) %{
 7353   match(Set dst (MoveL2D src));
 7354   effect(DEF dst, USE src);
 7355   ins_cost(MEMORY_REF_COST); // FIXME
 7356 
 7357   size(4);
 7358   format %{ "FMDRR   $dst,$src\t! MoveL2D" %}
 7359   ins_encode %{
 7360     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
 7361   %}
 7362   ins_pipe(ialu_reg_reg); // FIXME
 7363 %}
 7364 
 7365 //-----------
 7366 // Long to Double conversion
 7367 
 7368 // Magic constant, 0x43300000
 7369 instruct loadConI_x43300000(iRegI dst) %{
 7370   effect(DEF dst);
 7371   size(8);
 7372   format %{ "MOV_SLOW  $dst,0x43300000\t! 2^52" %}
 7373   ins_encode %{
 7374     __ mov_slow($dst$$Register, 0x43300000);
 7375   %}
 7376   ins_pipe(ialu_none);
 7377 %}
 7378 
 7379 // Magic constant, 0x41f00000
 7380 instruct loadConI_x41f00000(iRegI dst) %{
 7381   effect(DEF dst);
 7382   size(8);
 7383   format %{ "MOV_SLOW  $dst, 0x41f00000\t! 2^32" %}
 7384   ins_encode %{
 7385     __ mov_slow($dst$$Register, 0x41f00000);
 7386   %}
 7387   ins_pipe(ialu_none);
 7388 %}
 7389 
 7390 instruct loadConI_x0(iRegI dst) %{
 7391   effect(DEF dst);
 7392   size(4);
 7393   format %{ "MOV  $dst, 0x0\t! 0" %}
 7394   ins_encode %{
 7395     __ mov($dst$$Register, 0);
 7396   %}
 7397   ins_pipe(ialu_none);
 7398 %}
 7399 
 7400 // Construct a double from two float halves
 7401 instruct regDHi_regDLo_to_regD(regD_low dst, regD_low src1, regD_low src2) %{
 7402   effect(DEF dst, USE src1, USE src2);
 7403   size(8);
 7404   format %{ "FCPYS  $dst.hi,$src1.hi\n\t"
 7405             "FCPYS  $dst.lo,$src2.lo" %}
 7406   ins_encode %{
 7407     __ fcpys($dst$$FloatRegister->successor(), $src1$$FloatRegister->successor());
 7408     __ fcpys($dst$$FloatRegister, $src2$$FloatRegister);
 7409   %}
 7410   ins_pipe(faddD_reg_reg);
 7411 %}
 7412 
 7413 // Convert integer in high half of a double register (in the lower half of
 7414 // the double register file) to double
 7415 instruct convI2D_regDHi_regD(regD dst, regD_low src) %{
 7416   effect(DEF dst, USE src);
 7417   size(4);
 7418   format %{ "FSITOD  $dst,$src" %}
 7419   ins_encode %{
 7420     __ fsitod($dst$$FloatRegister, $src$$FloatRegister->successor());
 7421   %}
 7422   ins_pipe(fcvtLHi2D);
 7423 %}
 7424 
 7425 // Add float double precision
 7426 instruct addD_regD_regD(regD dst, regD src1, regD src2) %{
 7427   effect(DEF dst, USE src1, USE src2);
 7428   size(4);
 7429   format %{ "FADDD  $dst,$src1,$src2" %}
 7430   ins_encode %{
 7431     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 7432   %}
 7433   ins_pipe(faddD_reg_reg);
 7434 %}
 7435 
 7436 // Sub float double precision
 7437 instruct subD_regD_regD(regD dst, regD src1, regD src2) %{
 7438   effect(DEF dst, USE src1, USE src2);
 7439   size(4);
 7440   format %{ "FSUBD  $dst,$src1,$src2" %}
 7441   ins_encode %{
 7442     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 7443   %}
 7444   ins_pipe(faddD_reg_reg);
 7445 %}
 7446 
 7447 // Mul float double precision
 7448 instruct mulD_regD_regD(regD dst, regD src1, regD src2) %{
 7449   effect(DEF dst, USE src1, USE src2);
 7450   size(4);
 7451   format %{ "FMULD  $dst,$src1,$src2" %}
 7452   ins_encode %{
 7453     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 7454   %}
 7455   ins_pipe(fmulD_reg_reg);
 7456 %}
 7457 
 7458 instruct regL_to_regD(regD dst, iRegL src) %{
 7459   // No match rule to avoid chain rule match.
 7460   effect(DEF dst, USE src);
 7461   ins_cost(MEMORY_REF_COST);
 7462   size(4);
 7463   format %{ "FMDRR   $dst,$src\t! regL to regD" %}
 7464   ins_encode %{
 7465     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
 7466   %}
 7467   ins_pipe(ialu_reg_reg); // FIXME
 7468 %}
 7469 
 7470 instruct regI_regI_to_regD(regD dst, iRegI src1, iRegI src2) %{
 7471   // No match rule to avoid chain rule match.
 7472   effect(DEF dst, USE src1, USE src2);
 7473   ins_cost(MEMORY_REF_COST);
 7474   size(4);
 7475   format %{ "FMDRR   $dst,$src1,$src2\t! regI,regI to regD" %}
 7476   ins_encode %{
 7477     __ fmdrr($dst$$FloatRegister, $src1$$Register, $src2$$Register);
 7478   %}
 7479   ins_pipe(ialu_reg_reg); // FIXME
 7480 %}
 7481 
 7482 instruct convL2D_reg_slow_fxtof(regD dst, iRegL src) %{
 7483   match(Set dst (ConvL2D src));
 7484   ins_cost(DEFAULT_COST*8 + MEMORY_REF_COST*6); // FIXME
 7485 
 7486   expand %{
 7487     regD_low   tmpsrc;
 7488     iRegI      ix43300000;
 7489     iRegI      ix41f00000;
 7490     iRegI      ix0;
 7491     regD_low   dx43300000;
 7492     regD       dx41f00000;
 7493     regD       tmp1;
 7494     regD_low   tmp2;
 7495     regD       tmp3;
 7496     regD       tmp4;
 7497 
 7498     regL_to_regD(tmpsrc, src);
 7499 
 7500     loadConI_x43300000(ix43300000);
 7501     loadConI_x41f00000(ix41f00000);
 7502     loadConI_x0(ix0);
 7503 
 7504     regI_regI_to_regD(dx43300000, ix0, ix43300000);
 7505     regI_regI_to_regD(dx41f00000, ix0, ix41f00000);
 7506 
 7507     convI2D_regDHi_regD(tmp1, tmpsrc);
 7508     regDHi_regDLo_to_regD(tmp2, dx43300000, tmpsrc);
 7509     subD_regD_regD(tmp3, tmp2, dx43300000);
 7510     mulD_regD_regD(tmp4, tmp1, dx41f00000);
 7511     addD_regD_regD(dst, tmp3, tmp4);
 7512   %}
 7513 %}
 7514 
 7515 instruct convL2I_reg(iRegI dst, iRegL src) %{
 7516   match(Set dst (ConvL2I src));
 7517   size(4);
 7518   format %{ "MOV    $dst,$src.lo\t! long->int" %}
 7519   ins_encode %{
 7520     __ mov($dst$$Register, $src$$Register);
 7521   %}
 7522   ins_pipe(ialu_move_reg_I_to_L);
 7523 %}
 7524 
 7525 // Register Shift Right Immediate
 7526 instruct shrL_reg_imm6_L2I(iRegI dst, iRegL src, immI_32_63 cnt) %{
 7527   match(Set dst (ConvL2I (RShiftL src cnt)));
 7528   size(4);
 7529   format %{ "ASR    $dst,$src.hi,($cnt - 32)\t! long->int or mov if $cnt==32" %}
 7530   ins_encode %{
 7531     if ($cnt$$constant == 32) {
 7532       __ mov($dst$$Register, $src$$Register->successor());
 7533     } else {
 7534       __ mov($dst$$Register, AsmOperand($src$$Register->successor(), asr, $cnt$$constant - 32));
 7535     }
 7536   %}
 7537   ins_pipe(ialu_reg_imm);
 7538 %}
 7539 
 7540 
 7541 //----------Control Flow Instructions------------------------------------------
 7542 // Compare Instructions
 7543 // Compare Integers
 7544 instruct compI_iReg(flagsReg icc, iRegI op1, iRegI op2) %{
 7545   match(Set icc (CmpI op1 op2));
 7546   effect( DEF icc, USE op1, USE op2 );
 7547 
 7548   size(4);
 7549   format %{ "cmp_32 $op1,$op2\t! int" %}
 7550   ins_encode %{
 7551     __ cmp_32($op1$$Register, $op2$$Register);
 7552   %}
 7553   ins_pipe(ialu_cconly_reg_reg);
 7554 %}
 7555 
 7556 #ifdef _LP64
 7557 // Compare compressed pointers
 7558 instruct compN_reg2(flagsRegU icc, iRegN op1, iRegN op2) %{
 7559   match(Set icc (CmpN op1 op2));
 7560   effect( DEF icc, USE op1, USE op2 );
 7561 
 7562   size(4);
 7563   format %{ "cmp_32 $op1,$op2\t! int" %}
 7564   ins_encode %{
 7565     __ cmp_32($op1$$Register, $op2$$Register);
 7566   %}
 7567   ins_pipe(ialu_cconly_reg_reg);
 7568 %}
 7569 #endif
 7570 
 7571 instruct compU_iReg(flagsRegU icc, iRegI op1, iRegI op2) %{
 7572   match(Set icc (CmpU op1 op2));
 7573 
 7574   size(4);
 7575   format %{ "cmp_32 $op1,$op2\t! unsigned int" %}
 7576   ins_encode %{
 7577     __ cmp_32($op1$$Register, $op2$$Register);
 7578   %}
 7579   ins_pipe(ialu_cconly_reg_reg);
 7580 %}
 7581 
 7582 instruct compI_iReg_immneg(flagsReg icc, iRegI op1, aimmIneg op2) %{
 7583   match(Set icc (CmpI op1 op2));
 7584   effect( DEF icc, USE op1 );
 7585 
 7586   size(4);
 7587   format %{ "cmn_32 $op1,-$op2\t! int" %}
 7588   ins_encode %{
 7589     __ cmn_32($op1$$Register, -$op2$$constant);
 7590   %}
 7591   ins_pipe(ialu_cconly_reg_imm);
 7592 %}
 7593 
 7594 instruct compI_iReg_imm(flagsReg icc, iRegI op1, aimmI op2) %{
 7595   match(Set icc (CmpI op1 op2));
 7596   effect( DEF icc, USE op1 );
 7597 
 7598   size(4);
 7599   format %{ "cmp_32 $op1,$op2\t! int" %}
 7600   ins_encode %{
 7601     __ cmp_32($op1$$Register, $op2$$constant);
 7602   %}
 7603   ins_pipe(ialu_cconly_reg_imm);
 7604 %}
 7605 
 7606 instruct testI_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immI0 zero ) %{
 7607   match(Set icc (CmpI (AndI op1 op2) zero));
 7608   size(4);
 7609   format %{ "tst_32 $op2,$op1" %}
 7610 
 7611   ins_encode %{
 7612     __ tst_32($op1$$Register, $op2$$Register);
 7613   %}
 7614   ins_pipe(ialu_cconly_reg_reg_zero);
 7615 %}
 7616 
 7617 instruct testshlI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
 7618   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
 7619   size(4);
 7620   format %{ "TST   $op2,$op1<<$op3" %}
 7621 
 7622   ins_encode %{
 7623     __ tst($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$Register));
 7624   %}
 7625   ins_pipe(ialu_cconly_reg_reg_zero);
 7626 %}
 7627 
 7628 instruct testshlI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
 7629   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
 7630   size(4);
 7631   format %{ "tst_32 $op2,$op1<<$op3" %}
 7632 
 7633   ins_encode %{
 7634     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$constant));
 7635   %}
 7636   ins_pipe(ialu_cconly_reg_reg_zero);
 7637 %}
 7638 
 7639 instruct testsarI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
 7640   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
 7641   size(4);
 7642   format %{ "TST   $op2,$op1<<$op3" %}
 7643 
 7644   ins_encode %{
 7645     __ tst($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$Register));
 7646   %}
 7647   ins_pipe(ialu_cconly_reg_reg_zero);
 7648 %}
 7649 
 7650 instruct testsarI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
 7651   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
 7652   size(4);
 7653   format %{ "tst_32 $op2,$op1<<$op3" %}
 7654 
 7655   ins_encode %{
 7656     __ tst_32($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$constant));
 7657   %}
 7658   ins_pipe(ialu_cconly_reg_reg_zero);
 7659 %}
 7660 
 7661 instruct testshrI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
 7662   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
 7663   size(4);
 7664   format %{ "TST   $op2,$op1<<$op3" %}
 7665 
 7666   ins_encode %{
 7667     __ tst($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$Register));
 7668   %}
 7669   ins_pipe(ialu_cconly_reg_reg_zero);
 7670 %}
 7671 
 7672 instruct testshrI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
 7673   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
 7674   size(4);
 7675   format %{ "tst_32 $op2,$op1<<$op3" %}
 7676 
 7677   ins_encode %{
 7678     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$constant));
 7679   %}
 7680   ins_pipe(ialu_cconly_reg_reg_zero);
 7681 %}
 7682 
 7683 instruct testI_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, limmI op2, immI0 zero ) %{
 7684   match(Set icc (CmpI (AndI op1 op2) zero));
 7685   size(4);
 7686   format %{ "tst_32 $op2,$op1" %}
 7687 
 7688   ins_encode %{
 7689     __ tst_32($op1$$Register, $op2$$constant);
 7690   %}
 7691   ins_pipe(ialu_cconly_reg_imm_zero);
 7692 %}
 7693 
 7694 instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7695   match(Set xcc (CmpL op1 op2));
 7696   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
 7697 
 7698   size(8);
 7699   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! long\n\t"
 7700             "SBCS    $tmp,$op1.hi,$op2.hi" %}
 7701   ins_encode %{
 7702     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
 7703     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
 7704   %}
 7705   ins_pipe(ialu_cconly_reg_reg);
 7706 %}
 7707 
 7708 instruct compUL_reg_reg_LTGE(flagsRegUL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7709   match(Set xcc (CmpUL op1 op2));
 7710   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
 7711 
 7712   size(8);
 7713   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! unsigned long\n\t"
 7714             "SBCS    $tmp,$op1.hi,$op2.hi" %}
 7715   ins_encode %{
 7716     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
 7717     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
 7718   %}
 7719   ins_pipe(ialu_cconly_reg_reg);
 7720 %}
 7721 
 7722 instruct compL_reg_reg_EQNE(flagsRegL_EQNE xcc, iRegL op1, iRegL op2) %{
 7723   match(Set xcc (CmpL op1 op2));
 7724   effect( DEF xcc, USE op1, USE op2 );
 7725 
 7726   size(8);
 7727   format %{ "TEQ    $op1.hi,$op2.hi\t\t! long\n\t"
 7728             "TEQ.eq $op1.lo,$op2.lo" %}
 7729   ins_encode %{
 7730     __ teq($op1$$Register->successor(), $op2$$Register->successor());
 7731     __ teq($op1$$Register, $op2$$Register, eq);
 7732   %}
 7733   ins_pipe(ialu_cconly_reg_reg);
 7734 %}
 7735 
 7736 instruct compL_reg_reg_LEGT(flagsRegL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7737   match(Set xcc (CmpL op1 op2));
 7738   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
 7739 
 7740   size(8);
 7741   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! long\n\t"
 7742             "SBCS    $tmp,$op2.hi,$op1.hi" %}
 7743   ins_encode %{
 7744     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
 7745     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
 7746   %}
 7747   ins_pipe(ialu_cconly_reg_reg);
 7748 %}
 7749 
 7750 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7751 // (hi($con$$constant), lo($con$$constant)) becomes
 7752 instruct compL_reg_con_LTGE(flagsRegL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7753   match(Set xcc (CmpL op1 con));
 7754   effect( DEF xcc, USE op1, USE con, TEMP tmp );
 7755 
 7756   size(8);
 7757   format %{ "SUBS    $tmp,$op1.low,$con\t\t! long\n\t"
 7758             "SBCS    $tmp,$op1.hi,0" %}
 7759   ins_encode %{
 7760     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
 7761     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7762   %}
 7763 
 7764   ins_pipe(ialu_cconly_reg_reg);
 7765 %}
 7766 
 7767 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7768 // (hi($con$$constant), lo($con$$constant)) becomes
 7769 instruct compL_reg_con_EQNE(flagsRegL_EQNE xcc, iRegL op1, immLlowRot con) %{
 7770   match(Set xcc (CmpL op1 con));
 7771   effect( DEF xcc, USE op1, USE con );
 7772 
 7773   size(8);
 7774   format %{ "TEQ    $op1.hi,0\t\t! long\n\t"
 7775             "TEQ.eq $op1.lo,$con" %}
 7776   ins_encode %{
 7777     __ teq($op1$$Register->successor(), 0);
 7778     __ teq($op1$$Register, $con$$constant, eq);
 7779   %}
 7780 
 7781   ins_pipe(ialu_cconly_reg_reg);
 7782 %}
 7783 
 7784 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7785 // (hi($con$$constant), lo($con$$constant)) becomes
 7786 instruct compL_reg_con_LEGT(flagsRegL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7787   match(Set xcc (CmpL op1 con));
 7788   effect( DEF xcc, USE op1, USE con, TEMP tmp );
 7789 
 7790   size(8);
 7791   format %{ "RSBS    $tmp,$op1.low,$con\t\t! long\n\t"
 7792             "RSCS    $tmp,$op1.hi,0" %}
 7793   ins_encode %{
 7794     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
 7795     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7796   %}
 7797 
 7798   ins_pipe(ialu_cconly_reg_reg);
 7799 %}
 7800 
 7801 instruct compUL_reg_reg_EQNE(flagsRegUL_EQNE xcc, iRegL op1, iRegL op2) %{
 7802   match(Set xcc (CmpUL op1 op2));
 7803   effect(DEF xcc, USE op1, USE op2);
 7804 
 7805   size(8);
 7806   format %{ "TEQ    $op1.hi,$op2.hi\t\t! unsigned long\n\t"
 7807             "TEQ.eq $op1.lo,$op2.lo" %}
 7808   ins_encode %{
 7809     __ teq($op1$$Register->successor(), $op2$$Register->successor());
 7810     __ teq($op1$$Register, $op2$$Register, eq);
 7811   %}
 7812   ins_pipe(ialu_cconly_reg_reg);
 7813 %}
 7814 
 7815 instruct compUL_reg_reg_LEGT(flagsRegUL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7816   match(Set xcc (CmpUL op1 op2));
 7817   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
 7818 
 7819   size(8);
 7820   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! unsigned long\n\t"
 7821             "SBCS    $tmp,$op2.hi,$op1.hi" %}
 7822   ins_encode %{
 7823     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
 7824     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
 7825   %}
 7826   ins_pipe(ialu_cconly_reg_reg);
 7827 %}
 7828 
 7829 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7830 // (hi($con$$constant), lo($con$$constant)) becomes
 7831 instruct compUL_reg_con_LTGE(flagsRegUL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7832   match(Set xcc (CmpUL op1 con));
 7833   effect(DEF xcc, USE op1, USE con, TEMP tmp);
 7834 
 7835   size(8);
 7836   format %{ "SUBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
 7837             "SBCS    $tmp,$op1.hi,0" %}
 7838   ins_encode %{
 7839     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
 7840     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7841   %}
 7842 
 7843   ins_pipe(ialu_cconly_reg_reg);
 7844 %}
 7845 
 7846 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7847 // (hi($con$$constant), lo($con$$constant)) becomes
 7848 instruct compUL_reg_con_EQNE(flagsRegUL_EQNE xcc, iRegL op1, immLlowRot con) %{
 7849   match(Set xcc (CmpUL op1 con));
 7850   effect(DEF xcc, USE op1, USE con);
 7851 
 7852   size(8);
 7853   format %{ "TEQ    $op1.hi,0\t\t! unsigned long\n\t"
 7854             "TEQ.eq $op1.lo,$con" %}
 7855   ins_encode %{
 7856     __ teq($op1$$Register->successor(), 0);
 7857     __ teq($op1$$Register, $con$$constant, eq);
 7858   %}
 7859 
 7860   ins_pipe(ialu_cconly_reg_reg);
 7861 %}
 7862 
 7863 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7864 // (hi($con$$constant), lo($con$$constant)) becomes
 7865 instruct compUL_reg_con_LEGT(flagsRegUL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7866   match(Set xcc (CmpUL op1 con));
 7867   effect(DEF xcc, USE op1, USE con, TEMP tmp);
 7868 
 7869   size(8);
 7870   format %{ "RSBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
 7871             "RSCS    $tmp,$op1.hi,0" %}
 7872   ins_encode %{
 7873     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
 7874     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7875   %}
 7876 
 7877   ins_pipe(ialu_cconly_reg_reg);
 7878 %}
 7879 
 7880 /* instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ */
 7881 /*   match(Set xcc (CmpL (AndL op1 op2) zero)); */
 7882 /*   ins_encode %{ */
 7883 /*     __ stop("testL_reg_reg unimplemented"); */
 7884 /*   %} */
 7885 /*   ins_pipe(ialu_cconly_reg_reg); */
 7886 /* %} */
 7887 
 7888 /* // useful for checking the alignment of a pointer: */
 7889 /* instruct testL_reg_con(flagsRegL xcc, iRegL op1, immLlowRot con, immL0 zero) %{ */
 7890 /*   match(Set xcc (CmpL (AndL op1 con) zero)); */
 7891 /*   ins_encode %{ */
 7892 /*     __ stop("testL_reg_con unimplemented"); */
 7893 /*   %} */
 7894 /*   ins_pipe(ialu_cconly_reg_reg); */
 7895 /* %} */
 7896 
 7897 instruct compU_iReg_imm(flagsRegU icc, iRegI op1, aimmU31 op2 ) %{
 7898   match(Set icc (CmpU op1 op2));
 7899 
 7900   size(4);
 7901   format %{ "cmp_32 $op1,$op2\t! unsigned" %}
 7902   ins_encode %{
 7903     __ cmp_32($op1$$Register, $op2$$constant);
 7904   %}
 7905   ins_pipe(ialu_cconly_reg_imm);
 7906 %}
 7907 
 7908 // Compare Pointers
 7909 instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{
 7910   match(Set pcc (CmpP op1 op2));
 7911 
 7912   size(4);
 7913   format %{ "CMP    $op1,$op2\t! ptr" %}
 7914   ins_encode %{
 7915     __ cmp($op1$$Register, $op2$$Register);
 7916   %}
 7917   ins_pipe(ialu_cconly_reg_reg);
 7918 %}
 7919 
 7920 instruct compP_iRegP_imm(flagsRegP pcc, iRegP op1, aimmP op2 ) %{
 7921   match(Set pcc (CmpP op1 op2));
 7922 
 7923   size(4);
 7924   format %{ "CMP    $op1,$op2\t! ptr" %}
 7925   ins_encode %{
 7926     assert($op2$$constant == 0 || _opnds[2]->constant_reloc() == relocInfo::none, "reloc in cmp?");
 7927     __ cmp($op1$$Register, $op2$$constant);
 7928   %}
 7929   ins_pipe(ialu_cconly_reg_imm);
 7930 %}
 7931 
 7932 //----------Max and Min--------------------------------------------------------
 7933 // Min Instructions
 7934 // Conditional move for min
 7935 instruct cmovI_reg_lt( iRegI op2, iRegI op1, flagsReg icc ) %{
 7936   effect( USE_DEF op2, USE op1, USE icc );
 7937 
 7938   size(4);
 7939   format %{ "MOV.lt  $op2,$op1\t! min" %}
 7940   ins_encode %{
 7941     __ mov($op2$$Register, $op1$$Register, lt);
 7942   %}
 7943   ins_pipe(ialu_reg_flags);
 7944 %}
 7945 
 7946 // Min Register with Register.
 7947 instruct minI_eReg(iRegI op1, iRegI op2) %{
 7948   match(Set op2 (MinI op1 op2));
 7949   ins_cost(DEFAULT_COST*2);
 7950   expand %{
 7951     flagsReg icc;
 7952     compI_iReg(icc,op1,op2);
 7953     cmovI_reg_lt(op2,op1,icc);
 7954   %}
 7955 %}
 7956 
 7957 // Max Instructions
 7958 // Conditional move for max
 7959 instruct cmovI_reg_gt( iRegI op2, iRegI op1, flagsReg icc ) %{
 7960   effect( USE_DEF op2, USE op1, USE icc );
 7961   format %{ "MOV.gt  $op2,$op1\t! max" %}
 7962   ins_encode %{
 7963     __ mov($op2$$Register, $op1$$Register, gt);
 7964   %}
 7965   ins_pipe(ialu_reg_flags);
 7966 %}
 7967 
 7968 // Max Register with Register
 7969 instruct maxI_eReg(iRegI op1, iRegI op2) %{
 7970   match(Set op2 (MaxI op1 op2));
 7971   ins_cost(DEFAULT_COST*2);
 7972   expand %{
 7973     flagsReg icc;
 7974     compI_iReg(icc,op1,op2);
 7975     cmovI_reg_gt(op2,op1,icc);
 7976   %}
 7977 %}
 7978 
 7979 
 7980 //----------Float Compares----------------------------------------------------
 7981 // Compare floating, generate condition code
 7982 instruct cmpF_cc(flagsRegF fcc, flagsReg icc, regF src1, regF src2) %{
 7983   match(Set icc (CmpF src1 src2));
 7984   effect(KILL fcc);
 7985 
 7986   size(8);
 7987   format %{ "FCMPs  $src1,$src2\n\t"
 7988             "FMSTAT" %}
 7989   ins_encode %{
 7990     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
 7991     __ fmstat();
 7992   %}
 7993   ins_pipe(faddF_fcc_reg_reg_zero);
 7994 %}
 7995 
 7996 instruct cmpF0_cc(flagsRegF fcc, flagsReg icc, regF src1, immF0 src2) %{
 7997   match(Set icc (CmpF src1 src2));
 7998   effect(KILL fcc);
 7999 
 8000   size(8);
 8001   format %{ "FCMPs  $src1,$src2\n\t"
 8002             "FMSTAT" %}
 8003   ins_encode %{
 8004     __ fcmpzs($src1$$FloatRegister);
 8005     __ fmstat();
 8006   %}
 8007   ins_pipe(faddF_fcc_reg_reg_zero);
 8008 %}
 8009 
 8010 instruct cmpD_cc(flagsRegF fcc, flagsReg icc, regD src1, regD src2) %{
 8011   match(Set icc (CmpD src1 src2));
 8012   effect(KILL fcc);
 8013 
 8014   size(8);
 8015   format %{ "FCMPd  $src1,$src2 \n\t"
 8016             "FMSTAT" %}
 8017   ins_encode %{
 8018     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
 8019     __ fmstat();
 8020   %}
 8021   ins_pipe(faddD_fcc_reg_reg_zero);
 8022 %}
 8023 
 8024 instruct cmpD0_cc(flagsRegF fcc, flagsReg icc, regD src1, immD0 src2) %{
 8025   match(Set icc (CmpD src1 src2));
 8026   effect(KILL fcc);
 8027 
 8028   size(8);
 8029   format %{ "FCMPZd  $src1,$src2 \n\t"
 8030             "FMSTAT" %}
 8031   ins_encode %{
 8032     __ fcmpzd($src1$$FloatRegister);
 8033     __ fmstat();
 8034   %}
 8035   ins_pipe(faddD_fcc_reg_reg_zero);
 8036 %}
 8037 
 8038 // Compare floating, generate -1,0,1
 8039 instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsRegF fcc) %{
 8040   match(Set dst (CmpF3 src1 src2));
 8041   effect(KILL fcc);
 8042   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 8043   size(20);
 8044   // same number of instructions as code using conditional moves but
 8045   // doesn't kill integer condition register
 8046   format %{ "FCMPs  $dst,$src1,$src2 \n\t"
 8047             "VMRS   $dst, FPSCR \n\t"
 8048             "OR     $dst, $dst, 0x08000000 \n\t"
 8049             "EOR    $dst, $dst, $dst << 3 \n\t"
 8050             "MOV    $dst, $dst >> 30" %}
 8051   ins_encode %{
 8052     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
 8053     __ floating_cmp($dst$$Register);
 8054   %}
 8055   ins_pipe( floating_cmp );
 8056 %}
 8057 
 8058 instruct cmpF0_reg(iRegI dst, regF src1, immF0 src2, flagsRegF fcc) %{
 8059   match(Set dst (CmpF3 src1 src2));
 8060   effect(KILL fcc);
 8061   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 8062   size(20);
 8063   // same number of instructions as code using conditional moves but
 8064   // doesn't kill integer condition register
 8065   format %{ "FCMPZs $dst,$src1,$src2 \n\t"
 8066             "VMRS   $dst, FPSCR \n\t"
 8067             "OR     $dst, $dst, 0x08000000 \n\t"
 8068             "EOR    $dst, $dst, $dst << 3 \n\t"
 8069             "MOV    $dst, $dst >> 30" %}
 8070   ins_encode %{
 8071     __ fcmpzs($src1$$FloatRegister);
 8072     __ floating_cmp($dst$$Register);
 8073   %}
 8074   ins_pipe( floating_cmp );
 8075 %}
 8076 
 8077 instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsRegF fcc) %{
 8078   match(Set dst (CmpD3 src1 src2));
 8079   effect(KILL fcc);
 8080   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 8081   size(20);
 8082   // same number of instructions as code using conditional moves but
 8083   // doesn't kill integer condition register
 8084   format %{ "FCMPd  $dst,$src1,$src2 \n\t"
 8085             "VMRS   $dst, FPSCR \n\t"
 8086             "OR     $dst, $dst, 0x08000000 \n\t"
 8087             "EOR    $dst, $dst, $dst << 3 \n\t"
 8088             "MOV    $dst, $dst >> 30" %}
 8089   ins_encode %{
 8090     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
 8091     __ floating_cmp($dst$$Register);
 8092   %}
 8093   ins_pipe( floating_cmp );
 8094 %}
 8095 
 8096 instruct cmpD0_reg(iRegI dst, regD src1, immD0 src2, flagsRegF fcc) %{
 8097   match(Set dst (CmpD3 src1 src2));
 8098   effect(KILL fcc);
 8099   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 8100   size(20);
 8101   // same number of instructions as code using conditional moves but
 8102   // doesn't kill integer condition register
 8103   format %{ "FCMPZd $dst,$src1,$src2 \n\t"
 8104             "VMRS   $dst, FPSCR \n\t"
 8105             "OR     $dst, $dst, 0x08000000 \n\t"
 8106             "EOR    $dst, $dst, $dst << 3 \n\t"
 8107             "MOV    $dst, $dst >> 30" %}
 8108   ins_encode %{
 8109     __ fcmpzd($src1$$FloatRegister);
 8110     __ floating_cmp($dst$$Register);
 8111   %}
 8112   ins_pipe( floating_cmp );
 8113 %}
 8114 
 8115 //----------Branches---------------------------------------------------------
 8116 // Jump
 8117 // (compare 'operand indIndex' and 'instruct addP_reg_reg' above)
 8118 // FIXME
 8119 instruct jumpXtnd(iRegX switch_val, iRegP tmp) %{
 8120   match(Jump switch_val);
 8121   effect(TEMP tmp);
 8122   ins_cost(350);
 8123   format %{  "ADD    $tmp, $constanttablebase, $switch_val\n\t"
 8124              "LDR    $tmp,[$tmp + $constantoffset]\n\t"
 8125              "BX     $tmp" %}
 8126   size(20);
 8127   ins_encode %{
 8128     Register table_reg;
 8129     Register label_reg = $tmp$$Register;
 8130     if (constant_offset() == 0) {
 8131       table_reg = $constanttablebase;
 8132       __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
 8133     } else {
 8134       table_reg = $tmp$$Register;
 8135       int offset = $constantoffset;
 8136       if (is_memoryP(offset)) {
 8137         __ add(table_reg, $constanttablebase, $switch_val$$Register);
 8138         __ ldr(label_reg, Address(table_reg, offset));
 8139       } else {
 8140         __ mov_slow(table_reg, $constantoffset);
 8141         __ add(table_reg, $constanttablebase, table_reg);
 8142         __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
 8143       }
 8144     }
 8145     __ jump(label_reg); // ldr + b better than ldr to PC for branch predictor?
 8146     //    __ ldr(PC, Address($table$$Register, $switch_val$$Register));
 8147   %}
 8148   ins_pipe(ialu_reg_reg);
 8149 %}
 8150 
 8151 // // Direct Branch.
 8152 instruct branch(label labl) %{
 8153   match(Goto);
 8154   effect(USE labl);
 8155 
 8156   size(4);
 8157   ins_cost(BRANCH_COST);
 8158   format %{ "B     $labl" %}
 8159   ins_encode %{
 8160     __ b(*($labl$$label));
 8161   %}
 8162   ins_pipe(br);
 8163 %}
 8164 
 8165 // Conditional Direct Branch
 8166 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{
 8167   match(If cmp icc);
 8168   effect(USE labl);
 8169 
 8170   size(4);
 8171   ins_cost(BRANCH_COST);
 8172   format %{ "B$cmp   $icc,$labl" %}
 8173   ins_encode %{
 8174     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8175   %}
 8176   ins_pipe(br_cc);
 8177 %}
 8178 
 8179 #ifdef ARM
 8180 instruct branchCon_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, label labl) %{
 8181   match(If cmp icc);
 8182   effect(USE labl);
 8183   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);
 8184 
 8185   size(4);
 8186   ins_cost(BRANCH_COST);
 8187   format %{ "B$cmp   $icc,$labl" %}
 8188   ins_encode %{
 8189     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8190   %}
 8191   ins_pipe(br_cc);
 8192 %}
 8193 #endif
 8194 
 8195 
 8196 instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{
 8197   match(If cmp icc);
 8198   effect(USE labl);
 8199 
 8200   size(4);
 8201   ins_cost(BRANCH_COST);
 8202   format %{ "B$cmp  $icc,$labl" %}
 8203   ins_encode %{
 8204     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8205   %}
 8206   ins_pipe(br_cc);
 8207 %}
 8208 
 8209 instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{
 8210   match(If cmp pcc);
 8211   effect(USE labl);
 8212 
 8213   size(4);
 8214   ins_cost(BRANCH_COST);
 8215   format %{ "B$cmp  $pcc,$labl" %}
 8216   ins_encode %{
 8217     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8218   %}
 8219   ins_pipe(br_cc);
 8220 %}
 8221 
 8222 instruct branchConL_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, label labl) %{
 8223   match(If cmp xcc);
 8224   effect(USE labl);
 8225   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8226 
 8227   size(4);
 8228   ins_cost(BRANCH_COST);
 8229   format %{ "B$cmp  $xcc,$labl" %}
 8230   ins_encode %{
 8231     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8232   %}
 8233   ins_pipe(br_cc);
 8234 %}
 8235 
 8236 instruct branchConL_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, label labl) %{
 8237   match(If cmp xcc);
 8238   effect(USE labl);
 8239   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8240 
 8241   size(4);
 8242   ins_cost(BRANCH_COST);
 8243   format %{ "B$cmp  $xcc,$labl" %}
 8244   ins_encode %{
 8245     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8246   %}
 8247   ins_pipe(br_cc);
 8248 %}
 8249 
 8250 instruct branchConL_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, label labl) %{
 8251   match(If cmp xcc);
 8252   effect(USE labl);
 8253   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le );
 8254 
 8255   size(4);
 8256   ins_cost(BRANCH_COST);
 8257   format %{ "B$cmp  $xcc,$labl" %}
 8258   ins_encode %{
 8259     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8260   %}
 8261   ins_pipe(br_cc);
 8262 %}
 8263 
 8264 instruct branchConUL_LTGE(cmpOpUL cmp, flagsRegUL_LTGE xcc, label labl) %{
 8265   match(If cmp xcc);
 8266   effect(USE labl);
 8267   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8268 
 8269   size(4);
 8270   ins_cost(BRANCH_COST);
 8271   format %{ "B$cmp  $xcc,$labl" %}
 8272   ins_encode %{
 8273     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8274   %}
 8275   ins_pipe(br_cc);
 8276 %}
 8277 
 8278 instruct branchConUL_EQNE(cmpOpUL cmp, flagsRegUL_EQNE xcc, label labl) %{
 8279   match(If cmp xcc);
 8280   effect(USE labl);
 8281   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8282 
 8283   size(4);
 8284   ins_cost(BRANCH_COST);
 8285   format %{ "B$cmp  $xcc,$labl" %}
 8286   ins_encode %{
 8287     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8288   %}
 8289   ins_pipe(br_cc);
 8290 %}
 8291 
 8292 instruct branchConUL_LEGT(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, label labl) %{
 8293   match(If cmp xcc);
 8294   effect(USE labl);
 8295   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le);
 8296 
 8297   size(4);
 8298   ins_cost(BRANCH_COST);
 8299   format %{ "B$cmp  $xcc,$labl" %}
 8300   ins_encode %{
 8301     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8302   %}
 8303   ins_pipe(br_cc);
 8304 %}
 8305 
 8306 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
 8307   match(CountedLoopEnd cmp icc);
 8308   effect(USE labl);
 8309 
 8310   size(4);
 8311   ins_cost(BRANCH_COST);
 8312   format %{ "B$cmp   $icc,$labl\t! Loop end" %}
 8313   ins_encode %{
 8314     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8315   %}
 8316   ins_pipe(br_cc);
 8317 %}
 8318 
 8319 // instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{
 8320 //   match(CountedLoopEnd cmp icc);
 8321 //   ins_pipe(br_cc);
 8322 // %}
 8323 
 8324 // ============================================================================
 8325 // Long Compare
 8326 //
 8327 // Currently we hold longs in 2 registers.  Comparing such values efficiently
 8328 // is tricky.  The flavor of compare used depends on whether we are testing
 8329 // for LT, LE, or EQ.  For a simple LT test we can check just the sign bit.
 8330 // The GE test is the negated LT test.  The LE test can be had by commuting
 8331 // the operands (yielding a GE test) and then negating; negate again for the
 8332 // GT test.  The EQ test is done by ORcc'ing the high and low halves, and the
 8333 // NE test is negated from that.
 8334 
 8335 // Due to a shortcoming in the ADLC, it mixes up expressions like:
 8336 // (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)).  Note the
 8337 // difference between 'Y' and '0L'.  The tree-matches for the CmpI sections
 8338 // are collapsed internally in the ADLC's dfa-gen code.  The match for
 8339 // (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the
 8340 // foo match ends up with the wrong leaf.  One fix is to not match both
 8341 // reg-reg and reg-zero forms of long-compare.  This is unfortunate because
 8342 // both forms beat the trinary form of long-compare and both are very useful
 8343 // on Intel which has so few registers.
 8344 
 8345 // instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{
 8346 //   match(If cmp xcc);
 8347 //   ins_pipe(br_cc);
 8348 // %}
 8349 
 8350 // Manifest a CmpL3 result in an integer register.  Very painful.
 8351 // This is the test to avoid.
 8352 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
 8353   match(Set dst (CmpL3 src1 src2) );
 8354   effect( KILL ccr );
 8355   ins_cost(6*DEFAULT_COST); // FIXME
 8356   size(32);
 8357   format %{
 8358       "CMP    $src1.hi, $src2.hi\t\t! long\n"
 8359     "\tMOV.gt $dst, 1\n"
 8360     "\tmvn.lt $dst, 0\n"
 8361     "\tB.ne   done\n"
 8362     "\tSUBS   $dst, $src1.lo, $src2.lo\n"
 8363     "\tMOV.hi $dst, 1\n"
 8364     "\tmvn.lo $dst, 0\n"
 8365     "done:"     %}
 8366   ins_encode %{
 8367     Label done;
 8368     __ cmp($src1$$Register->successor(), $src2$$Register->successor());
 8369     __ mov($dst$$Register, 1, gt);
 8370     __ mvn($dst$$Register, 0, lt);
 8371     __ b(done, ne);
 8372     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
 8373     __ mov($dst$$Register, 1, hi);
 8374     __ mvn($dst$$Register, 0, lo);
 8375     __ bind(done);
 8376   %}
 8377   ins_pipe(cmpL_reg);
 8378 %}
 8379 
 8380 // Conditional move
 8381 instruct cmovLL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, iRegL src) %{
 8382   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8383   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8384 
 8385   ins_cost(150);
 8386   size(8);
 8387   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8388             "MOV$cmp  $dst,$src.hi" %}
 8389   ins_encode %{
 8390     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8391     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8392   %}
 8393   ins_pipe(ialu_reg);
 8394 %}
 8395 
 8396 instruct cmovLL_reg_LTGE_U(cmpOpL cmp, flagsRegUL_LTGE xcc, iRegL dst, iRegL src) %{
 8397   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8398   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8399 
 8400   ins_cost(150);
 8401   size(8);
 8402   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8403             "MOV$cmp  $dst,$src.hi" %}
 8404   ins_encode %{
 8405     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8406     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8407   %}
 8408   ins_pipe(ialu_reg);
 8409 %}
 8410 
 8411 instruct cmovLL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, iRegL src) %{
 8412   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8413   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8414 
 8415   ins_cost(150);
 8416   size(8);
 8417   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8418             "MOV$cmp  $dst,$src.hi" %}
 8419   ins_encode %{
 8420     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8421     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8422   %}
 8423   ins_pipe(ialu_reg);
 8424 %}
 8425 
 8426 instruct cmovLL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, iRegL src) %{
 8427   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8428   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8429 
 8430   ins_cost(150);
 8431   size(8);
 8432   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8433             "MOV$cmp  $dst,$src.hi" %}
 8434   ins_encode %{
 8435     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8436     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8437   %}
 8438   ins_pipe(ialu_reg);
 8439 %}
 8440 
 8441 instruct cmovLL_reg_LEGT_U(cmpOpL_commute cmp, flagsRegUL_LEGT xcc, iRegL dst, iRegL src) %{
 8442   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8443   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8444 
 8445   ins_cost(150);
 8446   size(8);
 8447   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8448             "MOV$cmp  $dst,$src.hi" %}
 8449   ins_encode %{
 8450     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8451     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8452   %}
 8453   ins_pipe(ialu_reg);
 8454 %}
 8455 
 8456 instruct cmovLL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, immL0 src) %{
 8457   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8458   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8459   ins_cost(140);
 8460   size(8);
 8461   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8462             "MOV$cmp  $dst,0" %}
 8463   ins_encode %{
 8464     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8465     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8466   %}
 8467   ins_pipe(ialu_imm);
 8468 %}
 8469 
 8470 instruct cmovLL_imm_LTGE_U(cmpOpL cmp, flagsRegUL_LTGE xcc, iRegL dst, immL0 src) %{
 8471   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8472   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8473   ins_cost(140);
 8474   size(8);
 8475   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8476             "MOV$cmp  $dst,0" %}
 8477   ins_encode %{
 8478     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8479     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8480   %}
 8481   ins_pipe(ialu_imm);
 8482 %}
 8483 
 8484 instruct cmovLL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, immL0 src) %{
 8485   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8486   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8487   ins_cost(140);
 8488   size(8);
 8489   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8490             "MOV$cmp  $dst,0" %}
 8491   ins_encode %{
 8492     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8493     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8494   %}
 8495   ins_pipe(ialu_imm);
 8496 %}
 8497 
 8498 instruct cmovLL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, immL0 src) %{
 8499   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8500   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8501   ins_cost(140);
 8502   size(8);
 8503   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8504             "MOV$cmp  $dst,0" %}
 8505   ins_encode %{
 8506     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8507     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8508   %}
 8509   ins_pipe(ialu_imm);
 8510 %}
 8511 
 8512 instruct cmovIL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, iRegI src) %{
 8513   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8514   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8515 
 8516   ins_cost(150);
 8517   size(4);
 8518   format %{ "MOV$cmp  $dst,$src" %}
 8519   ins_encode %{
 8520     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8521   %}
 8522   ins_pipe(ialu_reg);
 8523 %}
 8524 
 8525 instruct cmovIL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, iRegI src) %{
 8526   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8527   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8528 
 8529   ins_cost(150);
 8530   size(4);
 8531   format %{ "MOV$cmp  $dst,$src" %}
 8532   ins_encode %{
 8533     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8534   %}
 8535   ins_pipe(ialu_reg);
 8536 %}
 8537 
 8538 instruct cmovIL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, iRegI src) %{
 8539   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8540   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8541 
 8542   ins_cost(150);
 8543   size(4);
 8544   format %{ "MOV$cmp  $dst,$src" %}
 8545   ins_encode %{
 8546     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8547   %}
 8548   ins_pipe(ialu_reg);
 8549 %}
 8550 
 8551 instruct cmovIL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immI16 src) %{
 8552   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8553   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8554 
 8555   ins_cost(140);
 8556   format %{ "MOVW$cmp  $dst,$src" %}
 8557   ins_encode %{
 8558     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8559   %}
 8560   ins_pipe(ialu_imm);
 8561 %}
 8562 
 8563 instruct cmovIL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, immI16 src) %{
 8564   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8565   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8566 
 8567   ins_cost(140);
 8568   format %{ "MOVW$cmp  $dst,$src" %}
 8569   ins_encode %{
 8570     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8571   %}
 8572   ins_pipe(ialu_imm);
 8573 %}
 8574 
 8575 instruct cmovIL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immI16 src) %{
 8576   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8577   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8578 
 8579   ins_cost(140);
 8580   format %{ "MOVW$cmp  $dst,$src" %}
 8581   ins_encode %{
 8582     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8583   %}
 8584   ins_pipe(ialu_imm);
 8585 %}
 8586 
 8587 instruct cmovPL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, iRegP src) %{
 8588   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8589   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8590 
 8591   ins_cost(150);
 8592   size(4);
 8593   format %{ "MOV$cmp  $dst,$src" %}
 8594   ins_encode %{
 8595     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8596   %}
 8597   ins_pipe(ialu_reg);
 8598 %}
 8599 
 8600 instruct cmovPL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, iRegP src) %{
 8601   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8602   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8603 
 8604   ins_cost(150);
 8605   size(4);
 8606   format %{ "MOV$cmp  $dst,$src" %}
 8607   ins_encode %{
 8608     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8609   %}
 8610   ins_pipe(ialu_reg);
 8611 %}
 8612 
 8613 instruct cmovPL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, iRegP src) %{
 8614   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8615   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8616 
 8617   ins_cost(150);
 8618   size(4);
 8619   format %{ "MOV$cmp  $dst,$src" %}
 8620   ins_encode %{
 8621     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8622   %}
 8623   ins_pipe(ialu_reg);
 8624 %}
 8625 
 8626 instruct cmovPL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, immP0 src) %{
 8627   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8628   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8629 
 8630   ins_cost(140);
 8631   format %{ "MOVW$cmp  $dst,$src" %}
 8632   ins_encode %{
 8633     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8634   %}
 8635   ins_pipe(ialu_imm);
 8636 %}
 8637 
 8638 instruct cmovPL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, immP0 src) %{
 8639   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8640   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8641 
 8642   ins_cost(140);
 8643   format %{ "MOVW$cmp  $dst,$src" %}
 8644   ins_encode %{
 8645     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8646   %}
 8647   ins_pipe(ialu_imm);
 8648 %}
 8649 
 8650 instruct cmovPL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, immP0 src) %{
 8651   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8652   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8653 
 8654   ins_cost(140);
 8655   format %{ "MOVW$cmp  $dst,$src" %}
 8656   ins_encode %{
 8657     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8658   %}
 8659   ins_pipe(ialu_imm);
 8660 %}
 8661 
 8662 instruct cmovFL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regF dst, regF src) %{
 8663   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
 8664   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8665   ins_cost(150);
 8666   size(4);
 8667   format %{ "FCPYS$cmp $dst,$src" %}
 8668   ins_encode %{
 8669     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8670   %}
 8671   ins_pipe(int_conditional_float_move);
 8672 %}
 8673 
 8674 instruct cmovFL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regF dst, regF src) %{
 8675   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
 8676   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8677   ins_cost(150);
 8678   size(4);
 8679   format %{ "FCPYS$cmp $dst,$src" %}
 8680   ins_encode %{
 8681     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8682   %}
 8683   ins_pipe(int_conditional_float_move);
 8684 %}
 8685 
 8686 instruct cmovFL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regF dst, regF src) %{
 8687   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
 8688   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8689   ins_cost(150);
 8690   size(4);
 8691   format %{ "FCPYS$cmp $dst,$src" %}
 8692   ins_encode %{
 8693     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8694   %}
 8695   ins_pipe(int_conditional_float_move);
 8696 %}
 8697 
 8698 instruct cmovDL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regD dst, regD src) %{
 8699   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
 8700   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8701 
 8702   ins_cost(150);
 8703   size(4);
 8704   format %{ "FCPYD$cmp $dst,$src" %}
 8705   ins_encode %{
 8706     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8707   %}
 8708   ins_pipe(int_conditional_float_move);
 8709 %}
 8710 
 8711 instruct cmovDL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regD dst, regD src) %{
 8712   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
 8713   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8714 
 8715   ins_cost(150);
 8716   size(4);
 8717   format %{ "FCPYD$cmp $dst,$src" %}
 8718   ins_encode %{
 8719     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8720   %}
 8721   ins_pipe(int_conditional_float_move);
 8722 %}
 8723 
 8724 instruct cmovDL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regD dst, regD src) %{
 8725   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
 8726   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8727 
 8728   ins_cost(150);
 8729   size(4);
 8730   format %{ "FCPYD$cmp $dst,$src" %}
 8731   ins_encode %{
 8732     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8733   %}
 8734   ins_pipe(int_conditional_float_move);
 8735 %}
 8736 
 8737 // ============================================================================
 8738 // Safepoint Instruction
 8739 // rather than KILL R12, it would be better to use any reg as
 8740 // TEMP. Can't do that at this point because it crashes the compiler
 8741 instruct safePoint_poll(iRegP poll, R12RegI tmp, flagsReg icc) %{
 8742   match(SafePoint poll);
 8743   effect(USE poll, KILL tmp, KILL icc);
 8744 
 8745   size(4);
 8746   format %{ "LDR   $tmp,[$poll]\t! Safepoint: poll for GC" %}
 8747   ins_encode %{
 8748     __ relocate(relocInfo::poll_type);
 8749     __ ldr($tmp$$Register, Address($poll$$Register));
 8750   %}
 8751   ins_pipe(loadPollP);
 8752 %}
 8753 
 8754 
 8755 // ============================================================================
 8756 // Call Instructions
 8757 // Call Java Static Instruction
 8758 instruct CallStaticJavaDirect( method meth ) %{
 8759   match(CallStaticJava);
 8760   predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke());
 8761   effect(USE meth);
 8762 
 8763   ins_cost(CALL_COST);
 8764   format %{ "CALL,static ==> " %}
 8765   ins_encode( Java_Static_Call( meth ), call_epilog );
 8766   ins_pipe(simple_call);
 8767 %}
 8768 
 8769 // Call Java Static Instruction (method handle version)
 8770 instruct CallStaticJavaHandle( method meth ) %{
 8771   match(CallStaticJava);
 8772   predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke());
 8773   effect(USE meth);
 8774   // FP is saved by all callees (for interpreter stack correction).
 8775   // We use it here for a similar purpose, in {preserve,restore}_FP.
 8776 
 8777   ins_cost(CALL_COST);
 8778   format %{ "CALL,static/MethodHandle ==> " %}
 8779   ins_encode( preserve_SP, Java_Static_Call( meth ), restore_SP, call_epilog );
 8780   ins_pipe(simple_call);
 8781 %}
 8782 
 8783 // Call Java Dynamic Instruction
 8784 instruct CallDynamicJavaDirect( method meth ) %{
 8785   match(CallDynamicJava);
 8786   effect(USE meth);
 8787 
 8788   ins_cost(CALL_COST);
 8789   format %{ "MOV_OOP    (empty),R_R8\n\t"
 8790             "CALL,dynamic  ; NOP ==> " %}
 8791   ins_encode( Java_Dynamic_Call( meth ), call_epilog );
 8792   ins_pipe(call);
 8793 %}
 8794 
 8795 // Call Runtime Instruction
 8796 instruct CallRuntimeDirect(method meth) %{
 8797   match(CallRuntime);
 8798   effect(USE meth);
 8799   ins_cost(CALL_COST);
 8800   format %{ "CALL,runtime" %}
 8801   ins_encode( Java_To_Runtime( meth ),
 8802               call_epilog );
 8803   ins_pipe(simple_call);
 8804 %}
 8805 
 8806 // Call runtime without safepoint - same as CallRuntime
 8807 instruct CallLeafDirect(method meth) %{
 8808   match(CallLeaf);
 8809   effect(USE meth);
 8810   ins_cost(CALL_COST);
 8811   format %{ "CALL,runtime leaf" %}
 8812   // TODO: ned save_last_PC here?
 8813   ins_encode( Java_To_Runtime( meth ),
 8814               call_epilog );
 8815   ins_pipe(simple_call);
 8816 %}
 8817 
 8818 // Call runtime without safepoint - same as CallLeaf
 8819 instruct CallLeafNoFPDirect(method meth) %{
 8820   match(CallLeafNoFP);
 8821   effect(USE meth);
 8822   ins_cost(CALL_COST);
 8823   format %{ "CALL,runtime leaf nofp" %}
 8824   // TODO: ned save_last_PC here?
 8825   ins_encode( Java_To_Runtime( meth ),
 8826               call_epilog );
 8827   ins_pipe(simple_call);
 8828 %}
 8829 
 8830 // Tail Call; Jump from runtime stub to Java code.
 8831 // Also known as an 'interprocedural jump'.
 8832 // Target of jump will eventually return to caller.
 8833 // TailJump below removes the return address.
 8834 instruct TailCalljmpInd(IPRegP jump_target, inline_cache_regP method_ptr) %{
 8835   match(TailCall jump_target method_ptr);
 8836 
 8837   ins_cost(CALL_COST);
 8838   format %{ "MOV    Rexception_pc, LR\n\t"
 8839             "jump   $jump_target  \t! $method_ptr holds method" %}
 8840   ins_encode %{
 8841     __ mov(Rexception_pc, LR);   // this is used only to call
 8842                                  // StubRoutines::forward_exception_entry()
 8843                                  // which expects PC of exception in
 8844                                  // R5. FIXME?
 8845     __ jump($jump_target$$Register);
 8846   %}
 8847   ins_pipe(tail_call);
 8848 %}
 8849 
 8850 
 8851 // Return Instruction
 8852 instruct Ret() %{
 8853   match(Return);
 8854 
 8855   format %{ "ret LR" %}
 8856 
 8857   ins_encode %{
 8858     __ ret(LR);
 8859   %}
 8860 
 8861   ins_pipe(br);
 8862 %}
 8863 
 8864 
 8865 // Tail Jump; remove the return address; jump to target.
 8866 // TailCall above leaves the return address around.
 8867 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
 8868 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
 8869 // "restore" before this instruction (in Epilogue), we need to materialize it
 8870 // in %i0.
 8871 instruct tailjmpInd(IPRegP jump_target, RExceptionRegP ex_oop) %{
 8872   match( TailJump jump_target ex_oop );
 8873   ins_cost(CALL_COST);
 8874   format %{ "MOV    Rexception_pc, LR\n\t"
 8875             "jump   $jump_target \t! $ex_oop holds exc. oop" %}
 8876   ins_encode %{
 8877     __ mov(Rexception_pc, LR);
 8878     __ jump($jump_target$$Register);
 8879   %}
 8880   ins_pipe(tail_call);
 8881 %}
 8882 
 8883 // Create exception oop: created by stack-crawling runtime code.
 8884 // Created exception is now available to this handler, and is setup
 8885 // just prior to jumping to this handler.  No code emitted.
 8886 instruct CreateException( RExceptionRegP ex_oop )
 8887 %{
 8888   match(Set ex_oop (CreateEx));
 8889   ins_cost(0);
 8890 
 8891   size(0);
 8892   // use the following format syntax
 8893   format %{ "! exception oop is in Rexception_obj; no code emitted" %}
 8894   ins_encode();
 8895   ins_pipe(empty);
 8896 %}
 8897 
 8898 
 8899 // Rethrow exception:
 8900 // The exception oop will come in the first argument position.
 8901 // Then JUMP (not call) to the rethrow stub code.
 8902 instruct RethrowException()
 8903 %{
 8904   match(Rethrow);
 8905   ins_cost(CALL_COST);
 8906 
 8907   // use the following format syntax
 8908   format %{ "b    rethrow_stub" %}
 8909   ins_encode %{
 8910     Register scratch = R1_tmp;
 8911     assert_different_registers(scratch, c_rarg0, LR);
 8912     __ jump(OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type, scratch);
 8913   %}
 8914   ins_pipe(tail_call);
 8915 %}
 8916 
 8917 
 8918 // Die now
 8919 instruct ShouldNotReachHere( )
 8920 %{
 8921   match(Halt);
 8922   ins_cost(CALL_COST);
 8923 
 8924   // Use the following format syntax
 8925   format %{ "ShouldNotReachHere" %}
 8926   ins_encode %{
 8927     if (is_reachable()) {
 8928       __ stop(_halt_reason);
 8929     }
 8930   %}
 8931   ins_pipe(tail_call);
 8932 %}
 8933 
 8934 // ============================================================================
 8935 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
 8936 // array for an instance of the superklass.  Set a hidden internal cache on a
 8937 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
 8938 // not zero for a miss or zero for a hit.  The encoding ALSO sets flags.
 8939 instruct partialSubtypeCheck( R0RegP index, R1RegP sub, R2RegP super, flagsRegP pcc, LRRegP lr ) %{
 8940   match(Set index (PartialSubtypeCheck sub super));
 8941   effect( KILL pcc, KILL lr );
 8942   ins_cost(DEFAULT_COST*10);
 8943   format %{ "CALL   PartialSubtypeCheck" %}
 8944   ins_encode %{
 8945     __ call(StubRoutines::Arm::partial_subtype_check(), relocInfo::runtime_call_type);
 8946   %}
 8947   ins_pipe(partial_subtype_check_pipe);
 8948 %}
 8949 
 8950 /* instruct partialSubtypeCheck_vs_zero( flagsRegP pcc, o1RegP sub, o2RegP super, immP0 zero, o0RegP idx, o7RegP o7 ) %{ */
 8951 /*   match(Set pcc (CmpP (PartialSubtypeCheck sub super) zero)); */
 8952 /*   ins_pipe(partial_subtype_check_pipe); */
 8953 /* %} */
 8954 
 8955 
 8956 // ============================================================================
 8957 // inlined locking and unlocking
 8958 
 8959 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch )
 8960 %{
 8961   match(Set pcc (FastLock object box));
 8962 
 8963   effect(TEMP scratch, TEMP scratch2);
 8964   ins_cost(DEFAULT_COST*3);
 8965 
 8966   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2" %}
 8967   ins_encode %{
 8968     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
 8969   %}
 8970   ins_pipe(long_memory_op);
 8971 %}
 8972 
 8973 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch ) %{
 8974   match(Set pcc (FastUnlock object box));
 8975   effect(TEMP scratch, TEMP scratch2);
 8976   ins_cost(100);
 8977 
 8978   format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2" %}
 8979   ins_encode %{
 8980     __ fast_unlock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
 8981   %}
 8982   ins_pipe(long_memory_op);
 8983 %}
 8984 
 8985 // Count and Base registers are fixed because the allocator cannot
 8986 // kill unknown registers.  The encodings are generic.
 8987 instruct clear_array(iRegX cnt, iRegP base, iRegI temp, iRegX zero, Universe dummy, flagsReg cpsr) %{
 8988   match(Set dummy (ClearArray cnt base));
 8989   effect(TEMP temp, TEMP zero, KILL cpsr);
 8990   ins_cost(300);
 8991   format %{ "MOV    $zero,0\n"
 8992       "        MOV    $temp,$cnt\n"
 8993       "loop:   SUBS   $temp,$temp,4\t! Count down a dword of bytes\n"
 8994       "        STR.ge $zero,[$base+$temp]\t! delay slot"
 8995       "        B.gt   loop\t\t! Clearing loop\n" %}
 8996   ins_encode %{
 8997     __ mov($zero$$Register, 0);
 8998     __ mov($temp$$Register, $cnt$$Register);
 8999     Label(loop);
 9000     __ bind(loop);
 9001     __ subs($temp$$Register, $temp$$Register, 4);
 9002     __ str($zero$$Register, Address($base$$Register, $temp$$Register), ge);
 9003     __ b(loop, gt);
 9004   %}
 9005   ins_pipe(long_memory_op);
 9006 %}
 9007 
 9008 #ifdef XXX
 9009 // FIXME: Why R0/R1/R2/R3?
 9010 instruct string_compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result,
 9011                         iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 9012   predicate(!CompactStrings);
 9013   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
 9014   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, TEMP tmp1, TEMP tmp2);
 9015   ins_cost(300);
 9016   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // TEMP $tmp1, $tmp2" %}
 9017   ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result, tmp1, tmp2) );
 9018 
 9019   ins_pipe(long_memory_op);
 9020 %}
 9021 
 9022 // FIXME: Why R0/R1/R2?
 9023 instruct string_equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2,
 9024                        flagsReg ccr) %{
 9025   predicate(!CompactStrings);
 9026   match(Set result (StrEquals (Binary str1 str2) cnt));
 9027   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp1, TEMP tmp2, TEMP result, KILL ccr);
 9028 
 9029   ins_cost(300);
 9030   format %{ "String Equals $str1,$str2,$cnt -> $result   // TEMP $tmp1, $tmp2" %}
 9031   ins_encode( enc_String_Equals(str1, str2, cnt, result, tmp1, tmp2) );
 9032   ins_pipe(long_memory_op);
 9033 %}
 9034 
 9035 // FIXME: Why R0/R1?
 9036 instruct array_equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result,
 9037                       flagsReg ccr) %{
 9038   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
 9039   match(Set result (AryEq ary1 ary2));
 9040   effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP result, KILL ccr);
 9041 
 9042   ins_cost(300);
 9043   format %{ "Array Equals $ary1,$ary2 -> $result   // TEMP $tmp1,$tmp2,$tmp3" %}
 9044   ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, result));
 9045   ins_pipe(long_memory_op);
 9046 %}
 9047 #endif
 9048 
 9049 //---------- Zeros Count Instructions ------------------------------------------
 9050 
 9051 instruct countLeadingZerosI(iRegI dst, iRegI src) %{
 9052   match(Set dst (CountLeadingZerosI src));
 9053   size(4);
 9054   format %{ "CLZ_32 $dst,$src" %}
 9055   ins_encode %{
 9056     __ clz_32($dst$$Register, $src$$Register);
 9057   %}
 9058   ins_pipe(ialu_reg);
 9059 %}
 9060 
 9061 instruct countLeadingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
 9062   match(Set dst (CountLeadingZerosL src));
 9063   effect(TEMP tmp, TEMP dst, KILL ccr);
 9064   size(16);
 9065   format %{ "CLZ    $dst,$src.hi\n\t"
 9066             "TEQ    $dst,32\n\t"
 9067             "CLZ.eq $tmp,$src.lo\n\t"
 9068             "ADD.eq $dst, $dst, $tmp\n\t" %}
 9069   ins_encode %{
 9070     __ clz($dst$$Register, $src$$Register->successor());
 9071     __ teq($dst$$Register, 32);
 9072     __ clz($tmp$$Register, $src$$Register, eq);
 9073     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
 9074   %}
 9075   ins_pipe(ialu_reg);
 9076 %}
 9077 
 9078 instruct countTrailingZerosI(iRegI dst, iRegI src, iRegI tmp) %{
 9079   match(Set dst (CountTrailingZerosI src));
 9080   effect(TEMP tmp);
 9081   size(8);
 9082   format %{ "RBIT_32 $tmp, $src\n\t"
 9083             "CLZ_32  $dst,$tmp" %}
 9084   ins_encode %{
 9085     __ rbit_32($tmp$$Register, $src$$Register);
 9086     __ clz_32($dst$$Register, $tmp$$Register);
 9087   %}
 9088   ins_pipe(ialu_reg);
 9089 %}
 9090 
 9091 instruct countTrailingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
 9092   match(Set dst (CountTrailingZerosL src));
 9093   effect(TEMP tmp, TEMP dst, KILL ccr);
 9094   size(24);
 9095   format %{ "RBIT   $tmp,$src.lo\n\t"
 9096             "CLZ    $dst,$tmp\n\t"
 9097             "TEQ    $dst,32\n\t"
 9098             "RBIT   $tmp,$src.hi\n\t"
 9099             "CLZ.eq $tmp,$tmp\n\t"
 9100             "ADD.eq $dst,$dst,$tmp\n\t" %}
 9101   ins_encode %{
 9102     __ rbit($tmp$$Register, $src$$Register);
 9103     __ clz($dst$$Register, $tmp$$Register);
 9104     __ teq($dst$$Register, 32);
 9105     __ rbit($tmp$$Register, $src$$Register->successor());
 9106     __ clz($tmp$$Register, $tmp$$Register, eq);
 9107     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
 9108   %}
 9109   ins_pipe(ialu_reg);
 9110 %}
 9111 
 9112 
 9113 //---------- Population Count Instructions -------------------------------------
 9114 
 9115 instruct popCountI(iRegI dst, iRegI src, regD_low tmp) %{
 9116   predicate(UsePopCountInstruction);
 9117   match(Set dst (PopCountI src));
 9118   effect(TEMP tmp);
 9119 
 9120   format %{ "FMSR       $tmp,$src\n\t"
 9121             "VCNT.8     $tmp,$tmp\n\t"
 9122             "VPADDL.U8  $tmp,$tmp\n\t"
 9123             "VPADDL.U16 $tmp,$tmp\n\t"
 9124             "FMRS       $dst,$tmp" %}
 9125   size(20);
 9126 
 9127   ins_encode %{
 9128     __ fmsr($tmp$$FloatRegister, $src$$Register);
 9129     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
 9130     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
 9131     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
 9132     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 9133   %}
 9134   ins_pipe(ialu_reg); // FIXME
 9135 %}
 9136 
 9137 // Note: Long.bitCount(long) returns an int.
 9138 instruct popCountL(iRegI dst, iRegL src, regD_low tmp) %{
 9139   predicate(UsePopCountInstruction);
 9140   match(Set dst (PopCountL src));
 9141   effect(TEMP tmp);
 9142 
 9143   format %{ "FMDRR       $tmp,$src.lo,$src.hi\n\t"
 9144             "VCNT.8      $tmp,$tmp\n\t"
 9145             "VPADDL.U8   $tmp,$tmp\n\t"
 9146             "VPADDL.U16  $tmp,$tmp\n\t"
 9147             "VPADDL.U32  $tmp,$tmp\n\t"
 9148             "FMRS        $dst,$tmp" %}
 9149 
 9150   size(32);
 9151 
 9152   ins_encode %{
 9153     __ fmdrr($tmp$$FloatRegister, $src$$Register, $src$$Register->successor());
 9154     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
 9155     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
 9156     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
 9157     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 32, 0);
 9158     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 9159   %}
 9160   ins_pipe(ialu_reg);
 9161 %}
 9162 
 9163 
 9164 // ============================================================================
 9165 //------------Bytes reverse--------------------------------------------------
 9166 
 9167 instruct bytes_reverse_int(iRegI dst, iRegI src) %{
 9168   match(Set dst (ReverseBytesI src));
 9169 
 9170   size(4);
 9171   format %{ "REV32 $dst,$src" %}
 9172   ins_encode %{
 9173     __ rev($dst$$Register, $src$$Register);
 9174   %}
 9175   ins_pipe( iload_mem ); // FIXME
 9176 %}
 9177 
 9178 instruct bytes_reverse_long(iRegL dst, iRegL src) %{
 9179   match(Set dst (ReverseBytesL src));
 9180   effect(TEMP dst);
 9181   size(8);
 9182   format %{ "REV $dst.lo,$src.lo\n\t"
 9183             "REV $dst.hi,$src.hi" %}
 9184   ins_encode %{
 9185     __ rev($dst$$Register, $src$$Register->successor());
 9186     __ rev($dst$$Register->successor(), $src$$Register);
 9187   %}
 9188   ins_pipe( iload_mem ); // FIXME
 9189 %}
 9190 
 9191 instruct bytes_reverse_unsigned_short(iRegI dst, iRegI src) %{
 9192   match(Set dst (ReverseBytesUS src));
 9193   size(4);
 9194   format %{ "REV16 $dst,$src" %}
 9195   ins_encode %{
 9196     __ rev16($dst$$Register, $src$$Register);
 9197   %}
 9198   ins_pipe( iload_mem ); // FIXME
 9199 %}
 9200 
 9201 instruct bytes_reverse_short(iRegI dst, iRegI src) %{
 9202   match(Set dst (ReverseBytesS src));
 9203   size(4);
 9204   format %{ "REVSH $dst,$src" %}
 9205   ins_encode %{
 9206     __ revsh($dst$$Register, $src$$Register);
 9207   %}
 9208   ins_pipe( iload_mem ); // FIXME
 9209 %}
 9210 
 9211 
 9212 // ====================VECTOR INSTRUCTIONS=====================================
 9213 
 9214 // Load Aligned Packed values into a Double Register
 9215 instruct loadV8(vecD dst, memoryD mem) %{
 9216   predicate(n->as_LoadVector()->memory_size() == 8);
 9217   match(Set dst (LoadVector mem));
 9218   ins_cost(MEMORY_REF_COST);
 9219   size(4);
 9220   format %{ "FLDD   $mem,$dst\t! load vector (8 bytes)" %}
 9221   ins_encode %{
 9222     __ ldr_double($dst$$FloatRegister, $mem$$Address);
 9223   %}
 9224   ins_pipe(floadD_mem);
 9225 %}
 9226 
 9227 // Load Aligned Packed values into a Double Register Pair
 9228 instruct loadV16(vecX dst, memoryvld mem) %{
 9229   predicate(n->as_LoadVector()->memory_size() == 16);
 9230   match(Set dst (LoadVector mem));
 9231   ins_cost(MEMORY_REF_COST);
 9232   size(4);
 9233   format %{ "VLD1   $mem,$dst.Q\t! load vector (16 bytes)" %}
 9234   ins_encode %{
 9235     __ vld1($dst$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
 9236   %}
 9237   ins_pipe(floadD_mem); // FIXME
 9238 %}
 9239 
 9240 // Store Vector in Double register to memory
 9241 instruct storeV8(memoryD mem, vecD src) %{
 9242   predicate(n->as_StoreVector()->memory_size() == 8);
 9243   match(Set mem (StoreVector mem src));
 9244   ins_cost(MEMORY_REF_COST);
 9245   size(4);
 9246   format %{ "FSTD   $src,$mem\t! store vector (8 bytes)" %}
 9247   ins_encode %{
 9248     __ str_double($src$$FloatRegister, $mem$$Address);
 9249   %}
 9250   ins_pipe(fstoreD_mem_reg);
 9251 %}
 9252 
 9253 // Store Vector in Double Register Pair to memory
 9254 instruct storeV16(memoryvld mem, vecX src) %{
 9255   predicate(n->as_StoreVector()->memory_size() == 16);
 9256   match(Set mem (StoreVector mem src));
 9257   ins_cost(MEMORY_REF_COST);
 9258   size(4);
 9259   format %{ "VST1   $src,$mem\t! store vector (16 bytes)" %}
 9260   ins_encode %{
 9261     __ vst1($src$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
 9262   %}
 9263   ins_pipe(fstoreD_mem_reg); // FIXME
 9264 %}
 9265 
 9266 // Replicate scalar to packed byte values in Double register
 9267 instruct Repl8B_reg(vecD dst, iRegI src, iRegI tmp) %{
 9268   predicate(n->as_Vector()->length() == 8);
 9269   match(Set dst (ReplicateB src));
 9270   ins_cost(DEFAULT_COST*4);
 9271   effect(TEMP tmp);
 9272   size(16);
 9273 
 9274   // FIXME: could use PKH instruction instead?
 9275   format %{ "LSL      $tmp, $src, 24 \n\t"
 9276             "OR       $tmp, $tmp, ($tmp >> 8) \n\t"
 9277             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
 9278             "FMDRR    $dst,$tmp,$tmp\t" %}
 9279   ins_encode %{
 9280     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 24));
 9281     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 8));
 9282     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
 9283     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 9284   %}
 9285   ins_pipe(ialu_reg); // FIXME
 9286 %}
 9287 
 9288 // Replicate scalar to packed byte values in Double register
 9289 instruct Repl8B_reg_simd(vecD dst, iRegI src) %{
 9290   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9291   match(Set dst (ReplicateB src));
 9292   size(4);
 9293 
 9294   format %{ "VDUP.8 $dst,$src\t" %}
 9295   ins_encode %{
 9296     bool quad = false;
 9297     __ vdupI($dst$$FloatRegister, $src$$Register,
 9298              MacroAssembler::VELEM_SIZE_8, quad);
 9299   %}
 9300   ins_pipe(ialu_reg); // FIXME
 9301 %}
 9302 
 9303 // Replicate scalar to packed byte values in Double register pair
 9304 instruct Repl16B_reg(vecX dst, iRegI src) %{
 9305   predicate(n->as_Vector()->length_in_bytes() == 16);
 9306   match(Set dst (ReplicateB src));
 9307   size(4);
 9308 
 9309   format %{ "VDUP.8 $dst.Q,$src\t" %}
 9310   ins_encode %{
 9311     bool quad = true;
 9312     __ vdupI($dst$$FloatRegister, $src$$Register,
 9313              MacroAssembler::VELEM_SIZE_8, quad);
 9314   %}
 9315   ins_pipe(ialu_reg); // FIXME
 9316 %}
 9317 
 9318 // Replicate scalar constant to packed byte values in Double register
 9319 instruct Repl8B_immI(vecD dst, immI src, iRegI tmp) %{
 9320   predicate(n->as_Vector()->length() == 8);
 9321   match(Set dst (ReplicateB src));
 9322   ins_cost(DEFAULT_COST*2);
 9323   effect(TEMP tmp);
 9324   size(12);
 9325 
 9326   format %{ "MOV      $tmp, Repl4($src))\n\t"
 9327             "FMDRR    $dst,$tmp,$tmp\t" %}
 9328   ins_encode( LdReplImmI(src, dst, tmp, (4), (1)) );
 9329   ins_pipe(loadConFD); // FIXME
 9330 %}
 9331 
 9332 // Replicate scalar constant to packed byte values in Double register
 9333 // TODO: support negative constants with MVNI?
 9334 instruct Repl8B_immU8(vecD dst, immU8 src) %{
 9335   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9336   match(Set dst (ReplicateB src));
 9337   size(4);
 9338 
 9339   format %{ "VMOV.U8  $dst,$src" %}
 9340   ins_encode %{
 9341     bool quad = false;
 9342     __ vmovI($dst$$FloatRegister, $src$$constant,
 9343              MacroAssembler::VELEM_SIZE_8, quad);
 9344   %}
 9345   ins_pipe(loadConFD); // FIXME
 9346 %}
 9347 
 9348 // Replicate scalar constant to packed byte values in Double register pair
 9349 instruct Repl16B_immU8(vecX dst, immU8 src) %{
 9350   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
 9351   match(Set dst (ReplicateB src));
 9352   size(4);
 9353 
 9354   format %{ "VMOV.U8  $dst.Q,$src" %}
 9355   ins_encode %{
 9356     bool quad = true;
 9357     __ vmovI($dst$$FloatRegister, $src$$constant,
 9358              MacroAssembler::VELEM_SIZE_8, quad);
 9359   %}
 9360   ins_pipe(loadConFD); // FIXME
 9361 %}
 9362 
 9363 // Replicate scalar to packed short/char values into Double register
 9364 instruct Repl4S_reg(vecD dst, iRegI src, iRegI tmp) %{
 9365   predicate(n->as_Vector()->length() == 4);
 9366   match(Set dst (ReplicateS src));
 9367   ins_cost(DEFAULT_COST*3);
 9368   effect(TEMP tmp);
 9369   size(12);
 9370 
 9371   // FIXME: could use PKH instruction instead?
 9372   format %{ "LSL      $tmp, $src, 16 \n\t"
 9373             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
 9374             "FMDRR    $dst,$tmp,$tmp\t" %}
 9375   ins_encode %{
 9376     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 16));
 9377     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
 9378     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 9379   %}
 9380   ins_pipe(ialu_reg); // FIXME
 9381 %}
 9382 
 9383 // Replicate scalar to packed byte values in Double register
 9384 instruct Repl4S_reg_simd(vecD dst, iRegI src) %{
 9385   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9386   match(Set dst (ReplicateS src));
 9387   size(4);
 9388 
 9389   format %{ "VDUP.16 $dst,$src\t" %}
 9390   ins_encode %{
 9391     bool quad = false;
 9392     __ vdupI($dst$$FloatRegister, $src$$Register,
 9393              MacroAssembler::VELEM_SIZE_16, quad);
 9394   %}
 9395   ins_pipe(ialu_reg); // FIXME
 9396 %}
 9397 
 9398 // Replicate scalar to packed byte values in Double register pair
 9399 instruct Repl8S_reg(vecX dst, iRegI src) %{
 9400   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
 9401   match(Set dst (ReplicateS src));
 9402   size(4);
 9403 
 9404   format %{ "VDUP.16 $dst.Q,$src\t" %}
 9405   ins_encode %{
 9406     bool quad = true;
 9407     __ vdupI($dst$$FloatRegister, $src$$Register,
 9408              MacroAssembler::VELEM_SIZE_16, quad);
 9409   %}
 9410   ins_pipe(ialu_reg); // FIXME
 9411 %}
 9412 
 9413 
 9414 // Replicate scalar constant to packed short/char values in Double register
 9415 instruct Repl4S_immI(vecD dst, immI src, iRegP tmp) %{
 9416   predicate(n->as_Vector()->length() == 4);
 9417   match(Set dst (ReplicateS src));
 9418   effect(TEMP tmp);
 9419   size(12);
 9420   ins_cost(DEFAULT_COST*4); // FIXME
 9421 
 9422   format %{ "MOV      $tmp, Repl2($src))\n\t"
 9423             "FMDRR    $dst,$tmp,$tmp\t" %}
 9424   ins_encode( LdReplImmI(src, dst, tmp, (2), (2)) );
 9425   ins_pipe(loadConFD); // FIXME
 9426 %}
 9427 
 9428 // Replicate scalar constant to packed byte values in Double register
 9429 instruct Repl4S_immU8(vecD dst, immU8 src) %{
 9430   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9431   match(Set dst (ReplicateS src));
 9432   size(4);
 9433 
 9434   format %{ "VMOV.U16  $dst,$src" %}
 9435   ins_encode %{
 9436     bool quad = false;
 9437     __ vmovI($dst$$FloatRegister, $src$$constant,
 9438              MacroAssembler::VELEM_SIZE_16, quad);
 9439   %}
 9440   ins_pipe(loadConFD); // FIXME
 9441 %}
 9442 
 9443 // Replicate scalar constant to packed byte values in Double register pair
 9444 instruct Repl8S_immU8(vecX dst, immU8 src) %{
 9445   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
 9446   match(Set dst (ReplicateS src));
 9447   size(4);
 9448 
 9449   format %{ "VMOV.U16  $dst.Q,$src" %}
 9450   ins_encode %{
 9451     bool quad = true;
 9452     __ vmovI($dst$$FloatRegister, $src$$constant,
 9453              MacroAssembler::VELEM_SIZE_16, quad);
 9454   %}
 9455   ins_pipe(loadConFD); // FIXME
 9456 %}
 9457 
 9458 // Replicate scalar to packed int values in Double register
 9459 instruct Repl2I_reg(vecD dst, iRegI src) %{
 9460   predicate(n->as_Vector()->length() == 2);
 9461   match(Set dst (ReplicateI src));
 9462   size(4);
 9463 
 9464   format %{ "FMDRR    $dst,$src,$src\t" %}
 9465   ins_encode %{
 9466     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
 9467   %}
 9468   ins_pipe(ialu_reg); // FIXME
 9469 %}
 9470 
 9471 // Replicate scalar to packed int values in Double register pair
 9472 instruct Repl4I_reg(vecX dst, iRegI src) %{
 9473   predicate(n->as_Vector()->length() == 4);
 9474   match(Set dst (ReplicateI src));
 9475   ins_cost(DEFAULT_COST*2);
 9476   size(8);
 9477 
 9478   format %{ "FMDRR    $dst.lo,$src,$src\n\t"
 9479             "FMDRR    $dst.hi,$src,$src" %}
 9480 
 9481   ins_encode %{
 9482     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
 9483     __ fmdrr($dst$$FloatRegister->successor()->successor(),
 9484              $src$$Register, $src$$Register);
 9485   %}
 9486   ins_pipe(ialu_reg); // FIXME
 9487 %}
 9488 
 9489 // Replicate scalar to packed int values in Double register
 9490 instruct Repl2I_reg_simd(vecD dst, iRegI src) %{
 9491   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9492   match(Set dst (ReplicateI src));
 9493   size(4);
 9494 
 9495   format %{ "VDUP.32 $dst.D,$src\t" %}
 9496   ins_encode %{
 9497     bool quad = false;
 9498     __ vdupI($dst$$FloatRegister, $src$$Register,
 9499              MacroAssembler::VELEM_SIZE_32, quad);
 9500   %}
 9501   ins_pipe(ialu_reg); // FIXME
 9502 %}
 9503 
 9504 // Replicate scalar to packed int values in Double register pair
 9505 instruct Repl4I_reg_simd(vecX dst, iRegI src) %{
 9506   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
 9507   match(Set dst (ReplicateI src));
 9508   size(4);
 9509 
 9510   format %{ "VDUP.32 $dst.Q,$src\t" %}
 9511   ins_encode %{
 9512     bool quad = true;
 9513     __ vdupI($dst$$FloatRegister, $src$$Register,
 9514              MacroAssembler::VELEM_SIZE_32, quad);
 9515   %}
 9516   ins_pipe(ialu_reg); // FIXME
 9517 %}
 9518 
 9519 
 9520 // Replicate scalar zero constant to packed int values in Double register
 9521 instruct Repl2I_immI(vecD dst, immI src, iRegI tmp) %{
 9522   predicate(n->as_Vector()->length() == 2);
 9523   match(Set dst (ReplicateI src));
 9524   effect(TEMP tmp);
 9525   size(12);
 9526   ins_cost(DEFAULT_COST*4); // FIXME
 9527 
 9528   format %{ "MOV      $tmp, Repl1($src))\n\t"
 9529             "FMDRR    $dst,$tmp,$tmp\t" %}
 9530   ins_encode( LdReplImmI(src, dst, tmp, (1), (4)) );
 9531   ins_pipe(loadConFD); // FIXME
 9532 %}
 9533 
 9534 // Replicate scalar constant to packed byte values in Double register
 9535 instruct Repl2I_immU8(vecD dst, immU8 src) %{
 9536   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9537   match(Set dst (ReplicateI src));
 9538   size(4);
 9539 
 9540   format %{ "VMOV.I32  $dst.D,$src" %}
 9541   ins_encode %{
 9542     bool quad = false;
 9543     __ vmovI($dst$$FloatRegister, $src$$constant,
 9544              MacroAssembler::VELEM_SIZE_32, quad);
 9545   %}
 9546   ins_pipe(loadConFD); // FIXME
 9547 %}
 9548 
 9549 // Replicate scalar constant to packed byte values in Double register pair
 9550 instruct Repl4I_immU8(vecX dst, immU8 src) %{
 9551   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
 9552   match(Set dst (ReplicateI src));
 9553   size(4);
 9554 
 9555   format %{ "VMOV.I32  $dst.Q,$src" %}
 9556   ins_encode %{
 9557     bool quad = true;
 9558     __ vmovI($dst$$FloatRegister, $src$$constant,
 9559              MacroAssembler::VELEM_SIZE_32, quad);
 9560   %}
 9561   ins_pipe(loadConFD); // FIXME
 9562 %}
 9563 
 9564 // Replicate scalar to packed byte values in Double register pair
 9565 instruct Repl2L_reg(vecX dst, iRegL src) %{
 9566   predicate(n->as_Vector()->length() == 2);
 9567   match(Set dst (ReplicateL src));
 9568   size(8);
 9569   ins_cost(DEFAULT_COST*2); // FIXME
 9570 
 9571   format %{ "FMDRR $dst.D,$src.lo,$src.hi\t\n"
 9572             "FMDRR $dst.D.next,$src.lo,$src.hi" %}
 9573   ins_encode %{
 9574     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
 9575     __ fmdrr($dst$$FloatRegister->successor()->successor(),
 9576              $src$$Register, $src$$Register->successor());
 9577   %}
 9578   ins_pipe(ialu_reg); // FIXME
 9579 %}
 9580 
 9581 
 9582 // Replicate scalar to packed float values in Double register
 9583 instruct Repl2F_regI(vecD dst, iRegI src) %{
 9584   predicate(n->as_Vector()->length() == 2);
 9585   match(Set dst (ReplicateF src));
 9586   size(4);
 9587 
 9588   format %{ "FMDRR    $dst.D,$src,$src\t" %}
 9589   ins_encode %{
 9590     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
 9591   %}
 9592   ins_pipe(ialu_reg); // FIXME
 9593 %}
 9594 
 9595 // Replicate scalar to packed float values in Double register
 9596 instruct Repl2F_reg_vfp(vecD dst, regF src) %{
 9597   predicate(n->as_Vector()->length() == 2);
 9598   match(Set dst (ReplicateF src));
 9599   size(4*2);
 9600   ins_cost(DEFAULT_COST*2); // FIXME
 9601 
 9602   expand %{
 9603     iRegI tmp;
 9604     MoveF2I_reg_reg(tmp, src);
 9605     Repl2F_regI(dst,tmp);
 9606   %}
 9607 %}
 9608 
 9609 // Replicate scalar to packed float values in Double register
 9610 instruct Repl2F_reg_simd(vecD dst, regF src) %{
 9611   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9612   match(Set dst (ReplicateF src));
 9613   size(4);
 9614   ins_cost(DEFAULT_COST); // FIXME
 9615 
 9616   format %{ "VDUP.32  $dst.D,$src.D\t" %}
 9617   ins_encode %{
 9618     bool quad = false;
 9619     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
 9620   %}
 9621   ins_pipe(ialu_reg); // FIXME
 9622 %}
 9623 
 9624 // Replicate scalar to packed float values in Double register pair
 9625 instruct Repl4F_reg(vecX dst, regF src, iRegI tmp) %{
 9626   predicate(n->as_Vector()->length() == 4);
 9627   match(Set dst (ReplicateF src));
 9628   effect(TEMP tmp);
 9629   size(4*3);
 9630   ins_cost(DEFAULT_COST*3); // FIXME
 9631 
 9632   format %{ "FMRS     $tmp,$src\n\t"
 9633             "FMDRR    $dst.D,$tmp,$tmp\n\t"
 9634             "FMDRR    $dst.D.next,$tmp,$tmp\t" %}
 9635   ins_encode %{
 9636     __ fmrs($tmp$$Register, $src$$FloatRegister);
 9637     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 9638     __ fmdrr($dst$$FloatRegister->successor()->successor(),
 9639              $tmp$$Register, $tmp$$Register);
 9640   %}
 9641   ins_pipe(ialu_reg); // FIXME
 9642 %}
 9643 
 9644 // Replicate scalar to packed float values in Double register pair
 9645 instruct Repl4F_reg_simd(vecX dst, regF src) %{
 9646   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
 9647   match(Set dst (ReplicateF src));
 9648   size(4);
 9649   ins_cost(DEFAULT_COST); // FIXME
 9650 
 9651   format %{ "VDUP.32  $dst.Q,$src.D\t" %}
 9652   ins_encode %{
 9653     bool quad = true;
 9654     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
 9655   %}
 9656   ins_pipe(ialu_reg); // FIXME
 9657 %}
 9658 
 9659 // Replicate scalar zero constant to packed float values in Double register
 9660 instruct Repl2F_immI(vecD dst, immF src, iRegI tmp) %{
 9661   predicate(n->as_Vector()->length() == 2);
 9662   match(Set dst (ReplicateF src));
 9663   effect(TEMP tmp);
 9664   size(12);
 9665   ins_cost(DEFAULT_COST*4); // FIXME
 9666 
 9667   format %{ "MOV      $tmp, Repl1($src))\n\t"
 9668             "FMDRR    $dst,$tmp,$tmp\t" %}
 9669   ins_encode( LdReplImmF(src, dst, tmp) );
 9670   ins_pipe(loadConFD); // FIXME
 9671 %}
 9672 
 9673 // Replicate scalar to packed double float values in Double register pair
 9674 instruct Repl2D_reg(vecX dst, regD src) %{
 9675   predicate(n->as_Vector()->length() == 2);
 9676   match(Set dst (ReplicateD src));
 9677   size(4*2);
 9678   ins_cost(DEFAULT_COST*2); // FIXME
 9679 
 9680   format %{ "FCPYD    $dst.D.a,$src\n\t"
 9681             "FCPYD    $dst.D.b,$src\t" %}
 9682   ins_encode %{
 9683     FloatRegister dsta = $dst$$FloatRegister;
 9684     FloatRegister src = $src$$FloatRegister;
 9685     __ fcpyd(dsta, src);
 9686     FloatRegister dstb = dsta->successor()->successor();
 9687     __ fcpyd(dstb, src);
 9688   %}
 9689   ins_pipe(ialu_reg); // FIXME
 9690 %}
 9691 
 9692 // ====================VECTOR ARITHMETIC=======================================
 9693 
 9694 // --------------------------------- ADD --------------------------------------
 9695 
 9696 // Bytes vector add
 9697 instruct vadd8B_reg(vecD dst, vecD src1, vecD src2) %{
 9698   predicate(n->as_Vector()->length() == 8);
 9699   match(Set dst (AddVB src1 src2));
 9700   format %{ "VADD.I8 $dst,$src1,$src2\t! add packed8B" %}
 9701   size(4);
 9702   ins_encode %{
 9703     bool quad = false;
 9704     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9705              MacroAssembler::VELEM_SIZE_8, quad);
 9706   %}
 9707   ins_pipe( ialu_reg_reg ); // FIXME
 9708 %}
 9709 
 9710 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
 9711   predicate(n->as_Vector()->length() == 16);
 9712   match(Set dst (AddVB src1 src2));
 9713   size(4);
 9714   format %{ "VADD.I8 $dst.Q,$src1.Q,$src2.Q\t! add packed16B" %}
 9715   ins_encode %{
 9716     bool quad = true;
 9717     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9718              MacroAssembler::VELEM_SIZE_8, quad);
 9719   %}
 9720   ins_pipe( ialu_reg_reg ); // FIXME
 9721 %}
 9722 
 9723 // Shorts/Chars vector add
 9724 instruct vadd4S_reg(vecD dst, vecD src1, vecD src2) %{
 9725   predicate(n->as_Vector()->length() == 4);
 9726   match(Set dst (AddVS src1 src2));
 9727   size(4);
 9728   format %{ "VADD.I16 $dst,$src1,$src2\t! add packed4S" %}
 9729   ins_encode %{
 9730     bool quad = false;
 9731     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9732              MacroAssembler::VELEM_SIZE_16, quad);
 9733   %}
 9734   ins_pipe( ialu_reg_reg ); // FIXME
 9735 %}
 9736 
 9737 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
 9738   predicate(n->as_Vector()->length() == 8);
 9739   match(Set dst (AddVS src1 src2));
 9740   size(4);
 9741   format %{ "VADD.I16 $dst.Q,$src1.Q,$src2.Q\t! add packed8S" %}
 9742   ins_encode %{
 9743     bool quad = true;
 9744     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9745              MacroAssembler::VELEM_SIZE_16, quad);
 9746   %}
 9747   ins_pipe( ialu_reg_reg ); // FIXME
 9748 %}
 9749 
 9750 // Integers vector add
 9751 instruct vadd2I_reg(vecD dst, vecD src1, vecD src2) %{
 9752   predicate(n->as_Vector()->length() == 2);
 9753   match(Set dst (AddVI src1 src2));
 9754   size(4);
 9755   format %{ "VADD.I32 $dst.D,$src1.D,$src2.D\t! add packed2I" %}
 9756   ins_encode %{
 9757     bool quad = false;
 9758     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9759              MacroAssembler::VELEM_SIZE_32, quad);
 9760   %}
 9761   ins_pipe( ialu_reg_reg ); // FIXME
 9762 %}
 9763 
 9764 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
 9765   predicate(n->as_Vector()->length() == 4);
 9766   match(Set dst (AddVI src1 src2));
 9767   size(4);
 9768   format %{ "VADD.I32 $dst.Q,$src1.Q,$src2.Q\t! add packed4I" %}
 9769   ins_encode %{
 9770     bool quad = true;
 9771     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9772              MacroAssembler::VELEM_SIZE_32, quad);
 9773   %}
 9774   ins_pipe( ialu_reg_reg ); // FIXME
 9775 %}
 9776 
 9777 // Longs vector add
 9778 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
 9779   predicate(n->as_Vector()->length() == 2);
 9780   match(Set dst (AddVL src1 src2));
 9781   size(4);
 9782   format %{ "VADD.I64 $dst.Q,$src1.Q,$src2.Q\t! add packed2L" %}
 9783   ins_encode %{
 9784     bool quad = true;
 9785     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9786              MacroAssembler::VELEM_SIZE_64, quad);
 9787   %}
 9788   ins_pipe( ialu_reg_reg ); // FIXME
 9789 %}
 9790 
 9791 // Floats vector add
 9792 instruct vadd2F_reg(vecD dst, vecD src1, vecD src2) %{
 9793   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
 9794   match(Set dst (AddVF src1 src2));
 9795   size(4);
 9796   format %{ "VADD.F32 $dst,$src1,$src2\t! add packed2F" %}
 9797   ins_encode %{
 9798     bool quad = false;
 9799     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9800              MacroAssembler::VFA_SIZE_F32, quad);
 9801   %}
 9802   ins_pipe( faddD_reg_reg ); // FIXME
 9803 %}
 9804 
 9805 instruct vadd2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
 9806   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
 9807   match(Set dst (AddVF src1 src2));
 9808   ins_cost(DEFAULT_COST*2); // FIXME
 9809 
 9810   size(4*2);
 9811   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
 9812             "FADDS  $dst.b,$src1.b,$src2.b" %}
 9813   ins_encode %{
 9814     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 9815     __ add_float($dst$$FloatRegister->successor(),
 9816              $src1$$FloatRegister->successor(),
 9817              $src2$$FloatRegister->successor());
 9818   %}
 9819 
 9820   ins_pipe(faddF_reg_reg); // FIXME
 9821 %}
 9822 
 9823 instruct vadd4F_reg_simd(vecX dst, vecX src1, vecX src2) %{
 9824   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
 9825   match(Set dst (AddVF src1 src2));
 9826   size(4);
 9827   format %{ "VADD.F32 $dst.Q,$src1.Q,$src2.Q\t! add packed4F" %}
 9828   ins_encode %{
 9829     bool quad = true;
 9830     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9831              MacroAssembler::VFA_SIZE_F32, quad);
 9832   %}
 9833   ins_pipe( faddD_reg_reg ); // FIXME
 9834 %}
 9835 
 9836 instruct vadd4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
 9837   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
 9838   match(Set dst (AddVF src1 src2));
 9839   size(4*4);
 9840   ins_cost(DEFAULT_COST*4); // FIXME
 9841 
 9842   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
 9843             "FADDS  $dst.b,$src1.b,$src2.b\n\t"
 9844             "FADDS  $dst.c,$src1.c,$src2.c\n\t"
 9845             "FADDS  $dst.d,$src1.d,$src2.d" %}
 9846 
 9847   ins_encode %{
 9848     FloatRegister dsta = $dst$$FloatRegister;
 9849     FloatRegister src1a = $src1$$FloatRegister;
 9850     FloatRegister src2a = $src2$$FloatRegister;
 9851     __ add_float(dsta, src1a, src2a);
 9852     FloatRegister dstb = dsta->successor();
 9853     FloatRegister src1b = src1a->successor();
 9854     FloatRegister src2b = src2a->successor();
 9855     __ add_float(dstb, src1b, src2b);
 9856     FloatRegister dstc = dstb->successor();
 9857     FloatRegister src1c = src1b->successor();
 9858     FloatRegister src2c = src2b->successor();
 9859     __ add_float(dstc, src1c, src2c);
 9860     FloatRegister dstd = dstc->successor();
 9861     FloatRegister src1d = src1c->successor();
 9862     FloatRegister src2d = src2c->successor();
 9863     __ add_float(dstd, src1d, src2d);
 9864   %}
 9865 
 9866   ins_pipe(faddF_reg_reg); // FIXME
 9867 %}
 9868 
 9869 instruct vadd2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
 9870   predicate(n->as_Vector()->length() == 2);
 9871   match(Set dst (AddVD src1 src2));
 9872   size(4*2);
 9873   ins_cost(DEFAULT_COST*2); // FIXME
 9874 
 9875   format %{ "FADDD  $dst.a,$src1.a,$src2.a\n\t"
 9876             "FADDD  $dst.b,$src1.b,$src2.b" %}
 9877 
 9878   ins_encode %{
 9879     FloatRegister dsta = $dst$$FloatRegister;
 9880     FloatRegister src1a = $src1$$FloatRegister;
 9881     FloatRegister src2a = $src2$$FloatRegister;
 9882     __ add_double(dsta, src1a, src2a);
 9883     FloatRegister dstb = dsta->successor()->successor();
 9884     FloatRegister src1b = src1a->successor()->successor();
 9885     FloatRegister src2b = src2a->successor()->successor();
 9886     __ add_double(dstb, src1b, src2b);
 9887   %}
 9888 
 9889   ins_pipe(faddF_reg_reg); // FIXME
 9890 %}
 9891 
 9892 
 9893 // Bytes vector sub
 9894 instruct vsub8B_reg(vecD dst, vecD src1, vecD src2) %{
 9895   predicate(n->as_Vector()->length() == 8);
 9896   match(Set dst (SubVB src1 src2));
 9897   size(4);
 9898   format %{ "VSUB.I8 $dst,$src1,$src2\t! sub packed8B" %}
 9899   ins_encode %{
 9900     bool quad = false;
 9901     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9902              MacroAssembler::VELEM_SIZE_8, quad);
 9903   %}
 9904   ins_pipe( ialu_reg_reg ); // FIXME
 9905 %}
 9906 
 9907 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
 9908   predicate(n->as_Vector()->length() == 16);
 9909   match(Set dst (SubVB src1 src2));
 9910   size(4);
 9911   format %{ "VSUB.I8 $dst.Q,$src1.Q,$src2.Q\t! sub packed16B" %}
 9912   ins_encode %{
 9913     bool quad = true;
 9914     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9915              MacroAssembler::VELEM_SIZE_8, quad);
 9916   %}
 9917   ins_pipe( ialu_reg_reg ); // FIXME
 9918 %}
 9919 
 9920 // Shorts/Chars vector sub
 9921 instruct vsub4S_reg(vecD dst, vecD src1, vecD src2) %{
 9922   predicate(n->as_Vector()->length() == 4);
 9923   match(Set dst (SubVS src1 src2));
 9924   size(4);
 9925   format %{ "VSUB.I16 $dst,$src1,$src2\t! sub packed4S" %}
 9926   ins_encode %{
 9927     bool quad = false;
 9928     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9929              MacroAssembler::VELEM_SIZE_16, quad);
 9930   %}
 9931   ins_pipe( ialu_reg_reg ); // FIXME
 9932 %}
 9933 
 9934 instruct vsub16S_reg(vecX dst, vecX src1, vecX src2) %{
 9935   predicate(n->as_Vector()->length() == 8);
 9936   match(Set dst (SubVS src1 src2));
 9937   size(4);
 9938   format %{ "VSUB.I16 $dst.Q,$src1.Q,$src2.Q\t! sub packed8S" %}
 9939   ins_encode %{
 9940     bool quad = true;
 9941     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9942              MacroAssembler::VELEM_SIZE_16, quad);
 9943   %}
 9944   ins_pipe( ialu_reg_reg ); // FIXME
 9945 %}
 9946 
 9947 // Integers vector sub
 9948 instruct vsub2I_reg(vecD dst, vecD src1, vecD src2) %{
 9949   predicate(n->as_Vector()->length() == 2);
 9950   match(Set dst (SubVI src1 src2));
 9951   size(4);
 9952   format %{ "VSUB.I32 $dst,$src1,$src2\t! sub packed2I" %}
 9953   ins_encode %{
 9954     bool quad = false;
 9955     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9956              MacroAssembler::VELEM_SIZE_32, quad);
 9957   %}
 9958   ins_pipe( ialu_reg_reg ); // FIXME
 9959 %}
 9960 
 9961 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
 9962   predicate(n->as_Vector()->length() == 4);
 9963   match(Set dst (SubVI src1 src2));
 9964   size(4);
 9965   format %{ "VSUB.I32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4I" %}
 9966   ins_encode %{
 9967     bool quad = true;
 9968     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9969              MacroAssembler::VELEM_SIZE_32, quad);
 9970   %}
 9971   ins_pipe( ialu_reg_reg ); // FIXME
 9972 %}
 9973 
 9974 // Longs vector sub
 9975 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
 9976   predicate(n->as_Vector()->length() == 2);
 9977   match(Set dst (SubVL src1 src2));
 9978   size(4);
 9979   format %{ "VSUB.I64 $dst.Q,$src1.Q,$src2.Q\t! sub packed2L" %}
 9980   ins_encode %{
 9981     bool quad = true;
 9982     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9983              MacroAssembler::VELEM_SIZE_64, quad);
 9984   %}
 9985   ins_pipe( ialu_reg_reg ); // FIXME
 9986 %}
 9987 
 9988 // Floats vector sub
 9989 instruct vsub2F_reg(vecD dst, vecD src1, vecD src2) %{
 9990   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
 9991   match(Set dst (SubVF src1 src2));
 9992   size(4);
 9993   format %{ "VSUB.F32 $dst,$src1,$src2\t! sub packed2F" %}
 9994   ins_encode %{
 9995     bool quad = false;
 9996     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9997              MacroAssembler::VFA_SIZE_F32, quad);
 9998   %}
 9999   ins_pipe( faddF_reg_reg ); // FIXME
10000 %}
10001 
10002 instruct vsub2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10003   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
10004   match(Set dst (SubVF src1 src2));
10005   size(4*2);
10006   ins_cost(DEFAULT_COST*2); // FIXME
10007 
10008   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10009             "FSUBS  $dst.b,$src1.b,$src2.b" %}
10010 
10011   ins_encode %{
10012     FloatRegister dsta = $dst$$FloatRegister;
10013     FloatRegister src1a = $src1$$FloatRegister;
10014     FloatRegister src2a = $src2$$FloatRegister;
10015     __ sub_float(dsta, src1a, src2a);
10016     FloatRegister dstb = dsta->successor();
10017     FloatRegister src1b = src1a->successor();
10018     FloatRegister src2b = src2a->successor();
10019     __ sub_float(dstb, src1b, src2b);
10020   %}
10021 
10022   ins_pipe(faddF_reg_reg); // FIXME
10023 %}
10024 
10025 
10026 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
10027   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
10028   match(Set dst (SubVF src1 src2));
10029   size(4);
10030   format %{ "VSUB.F32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4F" %}
10031   ins_encode %{
10032     bool quad = true;
10033     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10034              MacroAssembler::VFA_SIZE_F32, quad);
10035   %}
10036   ins_pipe( faddF_reg_reg ); // FIXME
10037 %}
10038 
10039 instruct vsub4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10040   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
10041   match(Set dst (SubVF src1 src2));
10042   size(4*4);
10043   ins_cost(DEFAULT_COST*4); // FIXME
10044 
10045   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10046             "FSUBS  $dst.b,$src1.b,$src2.b\n\t"
10047             "FSUBS  $dst.c,$src1.c,$src2.c\n\t"
10048             "FSUBS  $dst.d,$src1.d,$src2.d" %}
10049 
10050   ins_encode %{
10051     FloatRegister dsta = $dst$$FloatRegister;
10052     FloatRegister src1a = $src1$$FloatRegister;
10053     FloatRegister src2a = $src2$$FloatRegister;
10054     __ sub_float(dsta, src1a, src2a);
10055     FloatRegister dstb = dsta->successor();
10056     FloatRegister src1b = src1a->successor();
10057     FloatRegister src2b = src2a->successor();
10058     __ sub_float(dstb, src1b, src2b);
10059     FloatRegister dstc = dstb->successor();
10060     FloatRegister src1c = src1b->successor();
10061     FloatRegister src2c = src2b->successor();
10062     __ sub_float(dstc, src1c, src2c);
10063     FloatRegister dstd = dstc->successor();
10064     FloatRegister src1d = src1c->successor();
10065     FloatRegister src2d = src2c->successor();
10066     __ sub_float(dstd, src1d, src2d);
10067   %}
10068 
10069   ins_pipe(faddF_reg_reg); // FIXME
10070 %}
10071 
10072 instruct vsub2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10073   predicate(n->as_Vector()->length() == 2);
10074   match(Set dst (SubVD src1 src2));
10075   size(4*2);
10076   ins_cost(DEFAULT_COST*2); // FIXME
10077 
10078   format %{ "FSUBD  $dst.a,$src1.a,$src2.a\n\t"
10079             "FSUBD  $dst.b,$src1.b,$src2.b" %}
10080 
10081   ins_encode %{
10082     FloatRegister dsta = $dst$$FloatRegister;
10083     FloatRegister src1a = $src1$$FloatRegister;
10084     FloatRegister src2a = $src2$$FloatRegister;
10085     __ sub_double(dsta, src1a, src2a);
10086     FloatRegister dstb = dsta->successor()->successor();
10087     FloatRegister src1b = src1a->successor()->successor();
10088     FloatRegister src2b = src2a->successor()->successor();
10089     __ sub_double(dstb, src1b, src2b);
10090   %}
10091 
10092   ins_pipe(faddF_reg_reg); // FIXME
10093 %}
10094 
10095 // Shorts/Chars vector mul
10096 instruct vmul4S_reg(vecD dst, vecD src1, vecD src2) %{
10097   predicate(n->as_Vector()->length() == 4);
10098   match(Set dst (MulVS src1 src2));
10099   size(4);
10100   format %{ "VMUL.I16 $dst,$src1,$src2\t! mul packed4S" %}
10101   ins_encode %{
10102     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10103              MacroAssembler::VELEM_SIZE_16, 0);
10104   %}
10105   ins_pipe( ialu_reg_reg ); // FIXME
10106 %}
10107 
10108 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2) %{
10109   predicate(n->as_Vector()->length() == 8);
10110   match(Set dst (MulVS src1 src2));
10111   size(4);
10112   format %{ "VMUL.I16 $dst.Q,$src1.Q,$src2.Q\t! mul packed8S" %}
10113   ins_encode %{
10114     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10115              MacroAssembler::VELEM_SIZE_16, 1);
10116   %}
10117   ins_pipe( ialu_reg_reg ); // FIXME
10118 %}
10119 
10120 // Integers vector mul
10121 instruct vmul2I_reg(vecD dst, vecD src1, vecD src2) %{
10122   predicate(n->as_Vector()->length() == 2);
10123   match(Set dst (MulVI src1 src2));
10124   size(4);
10125   format %{ "VMUL.I32 $dst,$src1,$src2\t! mul packed2I" %}
10126   ins_encode %{
10127     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10128              MacroAssembler::VELEM_SIZE_32, 0);
10129   %}
10130   ins_pipe( ialu_reg_reg ); // FIXME
10131 %}
10132 
10133 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
10134   predicate(n->as_Vector()->length() == 4);
10135   match(Set dst (MulVI src1 src2));
10136   size(4);
10137   format %{ "VMUL.I32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4I" %}
10138   ins_encode %{
10139     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10140              MacroAssembler::VELEM_SIZE_32, 1);
10141   %}
10142   ins_pipe( ialu_reg_reg ); // FIXME
10143 %}
10144 
10145 // Floats vector mul
10146 instruct vmul2F_reg(vecD dst, vecD src1, vecD src2) %{
10147   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
10148   match(Set dst (MulVF src1 src2));
10149   size(4);
10150   format %{ "VMUL.F32 $dst,$src1,$src2\t! mul packed2F" %}
10151   ins_encode %{
10152     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10153              MacroAssembler::VFA_SIZE_F32, 0);
10154   %}
10155   ins_pipe( fmulF_reg_reg ); // FIXME
10156 %}
10157 
10158 instruct vmul2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10159   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
10160   match(Set dst (MulVF src1 src2));
10161   size(4*2);
10162   ins_cost(DEFAULT_COST*2); // FIXME
10163 
10164   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10165             "FMULS  $dst.b,$src1.b,$src2.b" %}
10166   ins_encode %{
10167     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10168     __ mul_float($dst$$FloatRegister->successor(),
10169              $src1$$FloatRegister->successor(),
10170              $src2$$FloatRegister->successor());
10171   %}
10172 
10173   ins_pipe(fmulF_reg_reg); // FIXME
10174 %}
10175 
10176 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
10177   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
10178   match(Set dst (MulVF src1 src2));
10179   size(4);
10180   format %{ "VMUL.F32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4F" %}
10181   ins_encode %{
10182     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10183              MacroAssembler::VFA_SIZE_F32, 1);
10184   %}
10185   ins_pipe( fmulF_reg_reg ); // FIXME
10186 %}
10187 
10188 instruct vmul4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10189   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
10190   match(Set dst (MulVF src1 src2));
10191   size(4*4);
10192   ins_cost(DEFAULT_COST*4); // FIXME
10193 
10194   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10195             "FMULS  $dst.b,$src1.b,$src2.b\n\t"
10196             "FMULS  $dst.c,$src1.c,$src2.c\n\t"
10197             "FMULS  $dst.d,$src1.d,$src2.d" %}
10198 
10199   ins_encode %{
10200     FloatRegister dsta = $dst$$FloatRegister;
10201     FloatRegister src1a = $src1$$FloatRegister;
10202     FloatRegister src2a = $src2$$FloatRegister;
10203     __ mul_float(dsta, src1a, src2a);
10204     FloatRegister dstb = dsta->successor();
10205     FloatRegister src1b = src1a->successor();
10206     FloatRegister src2b = src2a->successor();
10207     __ mul_float(dstb, src1b, src2b);
10208     FloatRegister dstc = dstb->successor();
10209     FloatRegister src1c = src1b->successor();
10210     FloatRegister src2c = src2b->successor();
10211     __ mul_float(dstc, src1c, src2c);
10212     FloatRegister dstd = dstc->successor();
10213     FloatRegister src1d = src1c->successor();
10214     FloatRegister src2d = src2c->successor();
10215     __ mul_float(dstd, src1d, src2d);
10216   %}
10217 
10218   ins_pipe(fmulF_reg_reg); // FIXME
10219 %}
10220 
10221 instruct vmul2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10222   predicate(n->as_Vector()->length() == 2);
10223   match(Set dst (MulVD src1 src2));
10224   size(4*2);
10225   ins_cost(DEFAULT_COST*2); // FIXME
10226 
10227   format %{ "FMULD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10228             "FMULD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10229   ins_encode %{
10230     FloatRegister dsta = $dst$$FloatRegister;
10231     FloatRegister src1a = $src1$$FloatRegister;
10232     FloatRegister src2a = $src2$$FloatRegister;
10233     __ mul_double(dsta, src1a, src2a);
10234     FloatRegister dstb = dsta->successor()->successor();
10235     FloatRegister src1b = src1a->successor()->successor();
10236     FloatRegister src2b = src2a->successor()->successor();
10237     __ mul_double(dstb, src1b, src2b);
10238   %}
10239 
10240   ins_pipe(fmulD_reg_reg); // FIXME
10241 %}
10242 
10243 
10244 // Floats vector div
10245 instruct vdiv2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10246   predicate(n->as_Vector()->length() == 2);
10247   match(Set dst (DivVF src1 src2));
10248   size(4*2);
10249   ins_cost(DEFAULT_COST*2); // FIXME
10250 
10251   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10252             "FDIVS  $dst.b,$src1.b,$src2.b" %}
10253   ins_encode %{
10254     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10255     __ div_float($dst$$FloatRegister->successor(),
10256              $src1$$FloatRegister->successor(),
10257              $src2$$FloatRegister->successor());
10258   %}
10259 
10260   ins_pipe(fdivF_reg_reg); // FIXME
10261 %}
10262 
10263 instruct vdiv4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10264   predicate(n->as_Vector()->length() == 4);
10265   match(Set dst (DivVF src1 src2));
10266   size(4*4);
10267   ins_cost(DEFAULT_COST*4); // FIXME
10268 
10269   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10270             "FDIVS  $dst.b,$src1.b,$src2.b\n\t"
10271             "FDIVS  $dst.c,$src1.c,$src2.c\n\t"
10272             "FDIVS  $dst.d,$src1.d,$src2.d" %}
10273 
10274   ins_encode %{
10275     FloatRegister dsta = $dst$$FloatRegister;
10276     FloatRegister src1a = $src1$$FloatRegister;
10277     FloatRegister src2a = $src2$$FloatRegister;
10278     __ div_float(dsta, src1a, src2a);
10279     FloatRegister dstb = dsta->successor();
10280     FloatRegister src1b = src1a->successor();
10281     FloatRegister src2b = src2a->successor();
10282     __ div_float(dstb, src1b, src2b);
10283     FloatRegister dstc = dstb->successor();
10284     FloatRegister src1c = src1b->successor();
10285     FloatRegister src2c = src2b->successor();
10286     __ div_float(dstc, src1c, src2c);
10287     FloatRegister dstd = dstc->successor();
10288     FloatRegister src1d = src1c->successor();
10289     FloatRegister src2d = src2c->successor();
10290     __ div_float(dstd, src1d, src2d);
10291   %}
10292 
10293   ins_pipe(fdivF_reg_reg); // FIXME
10294 %}
10295 
10296 instruct vdiv2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10297   predicate(n->as_Vector()->length() == 2);
10298   match(Set dst (DivVD src1 src2));
10299   size(4*2);
10300   ins_cost(DEFAULT_COST*2); // FIXME
10301 
10302   format %{ "FDIVD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10303             "FDIVD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10304   ins_encode %{
10305     FloatRegister dsta = $dst$$FloatRegister;
10306     FloatRegister src1a = $src1$$FloatRegister;
10307     FloatRegister src2a = $src2$$FloatRegister;
10308     __ div_double(dsta, src1a, src2a);
10309     FloatRegister dstb = dsta->successor()->successor();
10310     FloatRegister src1b = src1a->successor()->successor();
10311     FloatRegister src2b = src2a->successor()->successor();
10312     __ div_double(dstb, src1b, src2b);
10313   %}
10314 
10315   ins_pipe(fdivD_reg_reg); // FIXME
10316 %}
10317 
10318 // --------------------------------- NEG --------------------------------------
10319 
10320 instruct vneg8B_reg(vecD dst, vecD src) %{
10321   predicate(n->as_Vector()->length_in_bytes() == 8);
10322   effect(DEF dst, USE src);
10323   size(4);
10324   ins_cost(DEFAULT_COST); // FIXME
10325   format %{ "VNEG.S8 $dst.D,$src.D\t! neg packed8B" %}
10326   ins_encode %{
10327     bool quad = false;
10328     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
10329               MacroAssembler::VELEM_SIZE_8, quad);
10330   %}
10331   ins_pipe( ialu_reg_reg ); // FIXME
10332 %}
10333 
10334 instruct vneg16B_reg(vecX dst, vecX src) %{
10335   predicate(n->as_Vector()->length_in_bytes() == 16);
10336   effect(DEF dst, USE src);
10337   size(4);
10338   ins_cost(DEFAULT_COST); // FIXME
10339   format %{ "VNEG.S8 $dst.Q,$src.Q\t! neg0 packed16B" %}
10340   ins_encode %{
10341     bool _float = false;
10342     bool quad = true;
10343     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
10344               MacroAssembler::VELEM_SIZE_8, quad);
10345   %}
10346   ins_pipe( ialu_reg_reg ); // FIXME
10347 %}
10348 
10349 // ------------------------------ Shift ---------------------------------------
10350 
10351 instruct vslcntD(vecD dst, iRegI cnt) %{
10352   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
10353   match(Set dst (LShiftCntV cnt));
10354   size(4);
10355   ins_cost(DEFAULT_COST); // FIXME
10356   expand %{
10357     Repl8B_reg_simd(dst, cnt);
10358   %}
10359 %}
10360 
10361 instruct vslcntX(vecX dst, iRegI cnt) %{
10362   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
10363   match(Set dst (LShiftCntV cnt));
10364   size(4);
10365   ins_cost(DEFAULT_COST); // FIXME
10366   expand %{
10367     Repl16B_reg(dst, cnt);
10368   %}
10369 %}
10370 
10371 // Low bits of vector "shift" elements are used, so it
10372 // doesn't matter if we treat it as ints or bytes here.
10373 instruct vsrcntD(vecD dst, iRegI cnt) %{
10374   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
10375   match(Set dst (RShiftCntV cnt));
10376   size(4*2);
10377   ins_cost(DEFAULT_COST*2); // FIXME
10378 
10379   format %{ "VDUP.8 $dst.D,$cnt\n\t"
10380             "VNEG.S8 $dst.D,$dst.D\t! neg packed8B" %}
10381   ins_encode %{
10382     bool quad = false;
10383     __ vdupI($dst$$FloatRegister, $cnt$$Register,
10384              MacroAssembler::VELEM_SIZE_8, quad);
10385     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
10386               MacroAssembler::VELEM_SIZE_8, quad);
10387   %}
10388   ins_pipe( ialu_reg_reg ); // FIXME
10389 %}
10390 
10391 instruct vsrcntX(vecX dst, iRegI cnt) %{
10392   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
10393   match(Set dst (RShiftCntV cnt));
10394   size(4*2);
10395   ins_cost(DEFAULT_COST*2); // FIXME
10396   format %{ "VDUP.8 $dst.Q,$cnt\n\t"
10397             "VNEG.S8 $dst.Q,$dst.Q\t! neg packed16B" %}
10398   ins_encode %{
10399     bool quad = true;
10400     __ vdupI($dst$$FloatRegister, $cnt$$Register,
10401              MacroAssembler::VELEM_SIZE_8, quad);
10402     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
10403               MacroAssembler::VELEM_SIZE_8, quad);
10404   %}
10405   ins_pipe( ialu_reg_reg ); // FIXME
10406 %}
10407 
10408 // Byte vector logical left/right shift based on sign
10409 instruct vsh8B_reg(vecD dst, vecD src, vecD shift) %{
10410   predicate(n->as_Vector()->length() == 8);
10411   effect(DEF dst, USE src, USE shift);
10412   size(4);
10413   ins_cost(DEFAULT_COST); // FIXME
10414   format %{
10415     "VSHL.U8 $dst.D,$src.D,$shift.D\t! logical left/right shift packed8B"
10416   %}
10417   ins_encode %{
10418     bool quad = false;
10419     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10420               MacroAssembler::VELEM_SIZE_8, quad);
10421   %}
10422   ins_pipe( ialu_reg_reg ); // FIXME
10423 %}
10424 
10425 instruct vsh16B_reg(vecX dst, vecX src, vecX shift) %{
10426   predicate(n->as_Vector()->length() == 16);
10427   effect(DEF dst, USE src, USE shift);
10428   size(4);
10429   ins_cost(DEFAULT_COST); // FIXME
10430   format %{
10431     "VSHL.U8 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed16B"
10432   %}
10433   ins_encode %{
10434     bool quad = true;
10435     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10436               MacroAssembler::VELEM_SIZE_8, quad);
10437   %}
10438   ins_pipe( ialu_reg_reg ); // FIXME
10439 %}
10440 
10441 // Shorts/Char vector logical left/right shift based on sign
10442 instruct vsh4S_reg(vecD dst, vecD src, vecD shift) %{
10443   predicate(n->as_Vector()->length() == 4);
10444   effect(DEF dst, USE src, USE shift);
10445   size(4);
10446   ins_cost(DEFAULT_COST); // FIXME
10447   format %{
10448     "VSHL.U16 $dst.D,$src.D,$shift.D\t! logical left/right shift packed4S"
10449   %}
10450   ins_encode %{
10451     bool quad = false;
10452     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10453               MacroAssembler::VELEM_SIZE_16, quad);
10454   %}
10455   ins_pipe( ialu_reg_reg ); // FIXME
10456 %}
10457 
10458 instruct vsh8S_reg(vecX dst, vecX src, vecX shift) %{
10459   predicate(n->as_Vector()->length() == 8);
10460   effect(DEF dst, USE src, USE shift);
10461   size(4);
10462   ins_cost(DEFAULT_COST); // FIXME
10463   format %{
10464     "VSHL.U16 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed8S"
10465   %}
10466   ins_encode %{
10467     bool quad = true;
10468     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10469               MacroAssembler::VELEM_SIZE_16, quad);
10470   %}
10471   ins_pipe( ialu_reg_reg ); // FIXME
10472 %}
10473 
10474 // Integers vector logical left/right shift based on sign
10475 instruct vsh2I_reg(vecD dst, vecD src, vecD shift) %{
10476   predicate(n->as_Vector()->length() == 2);
10477   effect(DEF dst, USE src, USE shift);
10478   size(4);
10479   ins_cost(DEFAULT_COST); // FIXME
10480   format %{
10481     "VSHL.U32 $dst.D,$src.D,$shift.D\t! logical left/right shift packed2I"
10482   %}
10483   ins_encode %{
10484     bool quad = false;
10485     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10486               MacroAssembler::VELEM_SIZE_32, quad);
10487   %}
10488   ins_pipe( ialu_reg_reg ); // FIXME
10489 %}
10490 
10491 instruct vsh4I_reg(vecX dst, vecX src, vecX shift) %{
10492   predicate(n->as_Vector()->length() == 4);
10493   effect(DEF dst, USE src, USE shift);
10494   size(4);
10495   ins_cost(DEFAULT_COST); // FIXME
10496   format %{
10497     "VSHL.U32 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed4I"
10498   %}
10499   ins_encode %{
10500     bool quad = true;
10501     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10502               MacroAssembler::VELEM_SIZE_32, quad);
10503   %}
10504   ins_pipe( ialu_reg_reg ); // FIXME
10505 %}
10506 
10507 // Longs vector logical left/right shift based on sign
10508 instruct vsh2L_reg(vecX dst, vecX src, vecX shift) %{
10509   predicate(n->as_Vector()->length() == 2);
10510   effect(DEF dst, USE src, USE shift);
10511   size(4);
10512   ins_cost(DEFAULT_COST); // FIXME
10513   format %{
10514     "VSHL.U64 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed2L"
10515   %}
10516   ins_encode %{
10517     bool quad = true;
10518     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10519               MacroAssembler::VELEM_SIZE_64, quad);
10520   %}
10521   ins_pipe( ialu_reg_reg ); // FIXME
10522 %}
10523 
10524 // ------------------------------ LeftShift -----------------------------------
10525 
10526 // Byte vector left shift
10527 instruct vsl8B_reg(vecD dst, vecD src, vecD shift) %{
10528   predicate(n->as_Vector()->length() == 8);
10529   match(Set dst (LShiftVB src shift));
10530   size(4*1);
10531   ins_cost(DEFAULT_COST*1); // FIXME
10532   expand %{
10533     vsh8B_reg(dst, src, shift);
10534   %}
10535 %}
10536 
10537 instruct vsl16B_reg(vecX dst, vecX src, vecX shift) %{
10538   predicate(n->as_Vector()->length() == 16);
10539   match(Set dst (LShiftVB src shift));
10540   size(4*1);
10541   ins_cost(DEFAULT_COST*1); // FIXME
10542   expand %{
10543     vsh16B_reg(dst, src, shift);
10544   %}
10545 %}
10546 
10547 instruct vsl8B_immI(vecD dst, vecD src, immI shift) %{
10548   predicate(n->as_Vector()->length() == 8);
10549   match(Set dst (LShiftVB src (LShiftCntV shift)));
10550   size(4);
10551   ins_cost(DEFAULT_COST); // FIXME
10552   format %{
10553     "VSHL.I8 $dst.D,$src.D,$shift\t! logical left shift packed8B"
10554   %}
10555   ins_encode %{
10556     bool quad = false;
10557     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10558              quad);
10559   %}
10560   ins_pipe( ialu_reg_reg ); // FIXME
10561 %}
10562 
10563 instruct vsl16B_immI(vecX dst, vecX src, immI shift) %{
10564   predicate(n->as_Vector()->length() == 16);
10565   match(Set dst (LShiftVB src (LShiftCntV shift)));
10566   size(4);
10567   ins_cost(DEFAULT_COST); // FIXME
10568   format %{
10569     "VSHL.I8 $dst.Q,$src.Q,$shift\t! logical left shift packed16B"
10570   %}
10571   ins_encode %{
10572     bool quad = true;
10573     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10574              quad);
10575   %}
10576   ins_pipe( ialu_reg_reg ); // FIXME
10577 %}
10578 
10579 // Shorts/Chars vector logical left/right shift
10580 instruct vsl4S_reg(vecD dst, vecD src, vecD shift) %{
10581   predicate(n->as_Vector()->length() == 4);
10582   match(Set dst (LShiftVS src shift));
10583   match(Set dst (URShiftVS src shift));
10584   size(4*1);
10585   ins_cost(DEFAULT_COST*1); // FIXME
10586   expand %{
10587     vsh4S_reg(dst, src, shift);
10588   %}
10589 %}
10590 
10591 instruct vsl8S_reg(vecX dst, vecX src, vecX shift) %{
10592   predicate(n->as_Vector()->length() == 8);
10593   match(Set dst (LShiftVS src shift));
10594   match(Set dst (URShiftVS src shift));
10595   size(4*1);
10596   ins_cost(DEFAULT_COST*1); // FIXME
10597   expand %{
10598     vsh8S_reg(dst, src, shift);
10599   %}
10600 %}
10601 
10602 instruct vsl4S_immI(vecD dst, vecD src, immI shift) %{
10603   predicate(n->as_Vector()->length() == 4);
10604   match(Set dst (LShiftVS src (LShiftCntV shift)));
10605   size(4);
10606   ins_cost(DEFAULT_COST); // FIXME
10607   format %{
10608     "VSHL.I16 $dst.D,$src.D,$shift\t! logical left shift packed4S"
10609   %}
10610   ins_encode %{
10611     bool quad = false;
10612     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10613              quad);
10614   %}
10615   ins_pipe( ialu_reg_reg ); // FIXME
10616 %}
10617 
10618 instruct vsl8S_immI(vecX dst, vecX src, immI shift) %{
10619   predicate(n->as_Vector()->length() == 8);
10620   match(Set dst (LShiftVS src shift));
10621   size(4);
10622   ins_cost(DEFAULT_COST); // FIXME
10623   format %{
10624     "VSHL.I16 $dst.Q,$src.Q,$shift\t! logical left shift packed8S"
10625   %}
10626   ins_encode %{
10627     bool quad = true;
10628     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10629              quad);
10630   %}
10631   ins_pipe( ialu_reg_reg ); // FIXME
10632 %}
10633 
10634 // Integers vector logical left/right shift
10635 instruct vsl2I_reg(vecD dst, vecD src, vecD shift) %{
10636   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10637   match(Set dst (LShiftVI src shift));
10638   match(Set dst (URShiftVI src shift));
10639   size(4*1);
10640   ins_cost(DEFAULT_COST*1); // FIXME
10641   expand %{
10642     vsh2I_reg(dst, src, shift);
10643   %}
10644 %}
10645 
10646 instruct vsl4I_reg(vecX dst, vecX src, vecX shift) %{
10647   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10648   match(Set dst (LShiftVI src shift));
10649   match(Set dst (URShiftVI src shift));
10650   size(4*1);
10651   ins_cost(DEFAULT_COST*1); // FIXME
10652   expand %{
10653     vsh4I_reg(dst, src, shift);
10654   %}
10655 %}
10656 
10657 instruct vsl2I_immI(vecD dst, vecD src, immI shift) %{
10658   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10659   match(Set dst (LShiftVI src (LShiftCntV shift)));
10660   size(4);
10661   ins_cost(DEFAULT_COST); // FIXME
10662   format %{
10663     "VSHL.I32 $dst.D,$src.D,$shift\t! logical left shift packed2I"
10664   %}
10665   ins_encode %{
10666     bool quad = false;
10667     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10668              quad);
10669   %}
10670   ins_pipe( ialu_reg_reg ); // FIXME
10671 %}
10672 
10673 instruct vsl4I_immI(vecX dst, vecX src, immI shift) %{
10674   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10675   match(Set dst (LShiftVI src (LShiftCntV shift)));
10676   size(4);
10677   ins_cost(DEFAULT_COST); // FIXME
10678   format %{
10679     "VSHL.I32 $dst.Q,$src.Q,$shift\t! logical left shift packed4I"
10680   %}
10681   ins_encode %{
10682     bool quad = true;
10683     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10684              quad);
10685   %}
10686   ins_pipe( ialu_reg_reg ); // FIXME
10687 %}
10688 
10689 // Longs vector logical left/right shift
10690 instruct vsl2L_reg(vecX dst, vecX src, vecX shift) %{
10691   predicate(n->as_Vector()->length() == 2);
10692   match(Set dst (LShiftVL src shift));
10693   match(Set dst (URShiftVL src shift));
10694   size(4*1);
10695   ins_cost(DEFAULT_COST*1); // FIXME
10696   expand %{
10697     vsh2L_reg(dst, src, shift);
10698   %}
10699 %}
10700 
10701 instruct vsl2L_immI(vecX dst, vecX src, immI shift) %{
10702   predicate(n->as_Vector()->length() == 2);
10703   match(Set dst (LShiftVL src (LShiftCntV shift)));
10704   size(4);
10705   ins_cost(DEFAULT_COST); // FIXME
10706   format %{
10707     "VSHL.I64 $dst.Q,$src.Q,$shift\t! logical left shift packed2L"
10708   %}
10709   ins_encode %{
10710     bool quad = true;
10711     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
10712              quad);
10713   %}
10714   ins_pipe( ialu_reg_reg ); // FIXME
10715 %}
10716 
10717 // ----------------------- LogicalRightShift -----------------------------------
10718 
10719 // Bytes/Shorts vector logical right shift produces incorrect Java result
10720 // for negative data because java code convert short value into int with
10721 // sign extension before a shift.
10722 
10723 // Chars vector logical right shift
10724 instruct vsrl4S_immI(vecD dst, vecD src, immI shift) %{
10725   predicate(n->as_Vector()->length() == 4);
10726   match(Set dst (URShiftVS src (RShiftCntV shift)));
10727   size(4);
10728   ins_cost(DEFAULT_COST); // FIXME
10729   format %{
10730     "VSHR.U16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
10731   %}
10732   ins_encode %{
10733     bool quad = false;
10734     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10735              quad);
10736   %}
10737   ins_pipe( ialu_reg_reg ); // FIXME
10738 %}
10739 
10740 instruct vsrl8S_immI(vecX dst, vecX src, immI shift) %{
10741   predicate(n->as_Vector()->length() == 8);
10742   match(Set dst (URShiftVS src (RShiftCntV shift)));
10743   size(4);
10744   ins_cost(DEFAULT_COST); // FIXME
10745   format %{
10746     "VSHR.U16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
10747   %}
10748   ins_encode %{
10749     bool quad = true;
10750     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10751              quad);
10752   %}
10753   ins_pipe( ialu_reg_reg ); // FIXME
10754 %}
10755 
10756 // Integers vector logical right shift
10757 instruct vsrl2I_immI(vecD dst, vecD src, immI shift) %{
10758   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10759   match(Set dst (URShiftVI src (RShiftCntV shift)));
10760   size(4);
10761   ins_cost(DEFAULT_COST); // FIXME
10762   format %{
10763     "VSHR.U32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
10764   %}
10765   ins_encode %{
10766     bool quad = false;
10767     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10768              quad);
10769   %}
10770   ins_pipe( ialu_reg_reg ); // FIXME
10771 %}
10772 
10773 instruct vsrl4I_immI(vecX dst, vecX src, immI shift) %{
10774   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10775   match(Set dst (URShiftVI src (RShiftCntV shift)));
10776   size(4);
10777   ins_cost(DEFAULT_COST); // FIXME
10778   format %{
10779     "VSHR.U32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
10780   %}
10781   ins_encode %{
10782     bool quad = true;
10783     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10784              quad);
10785   %}
10786   ins_pipe( ialu_reg_reg ); // FIXME
10787 %}
10788 
10789 // Longs vector logical right shift
10790 instruct vsrl2L_immI(vecX dst, vecX src, immI shift) %{
10791   predicate(n->as_Vector()->length() == 2);
10792   match(Set dst (URShiftVL src (RShiftCntV shift)));
10793   size(4);
10794   ins_cost(DEFAULT_COST); // FIXME
10795   format %{
10796     "VSHR.U64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
10797   %}
10798   ins_encode %{
10799     bool quad = true;
10800     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
10801              quad);
10802   %}
10803   ins_pipe( ialu_reg_reg ); // FIXME
10804 %}
10805 
10806 // ------------------- ArithmeticRightShift -----------------------------------
10807 
10808 // Bytes vector arithmetic left/right shift based on sign
10809 instruct vsha8B_reg(vecD dst, vecD src, vecD shift) %{
10810   predicate(n->as_Vector()->length() == 8);
10811   effect(DEF dst, USE src, USE shift);
10812   size(4);
10813   ins_cost(DEFAULT_COST); // FIXME
10814   format %{
10815     "VSHL.S8 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed8B"
10816   %}
10817   ins_encode %{
10818     bool quad = false;
10819     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10820               MacroAssembler::VELEM_SIZE_8, quad);
10821   %}
10822   ins_pipe( ialu_reg_reg ); // FIXME
10823 %}
10824 
10825 instruct vsha16B_reg(vecX dst, vecX src, vecX shift) %{
10826   predicate(n->as_Vector()->length() == 16);
10827   effect(DEF dst, USE src, USE shift);
10828   size(4);
10829   ins_cost(DEFAULT_COST); // FIXME
10830   format %{
10831     "VSHL.S8 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed16B"
10832   %}
10833   ins_encode %{
10834     bool quad = true;
10835     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10836               MacroAssembler::VELEM_SIZE_8, quad);
10837   %}
10838   ins_pipe( ialu_reg_reg ); // FIXME
10839 %}
10840 
10841 // Shorts vector arithmetic left/right shift based on sign
10842 instruct vsha4S_reg(vecD dst, vecD src, vecD shift) %{
10843   predicate(n->as_Vector()->length() == 4);
10844   effect(DEF dst, USE src, USE shift);
10845   size(4);
10846   ins_cost(DEFAULT_COST); // FIXME
10847   format %{
10848     "VSHL.S16 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed4S"
10849   %}
10850   ins_encode %{
10851     bool quad = false;
10852     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10853               MacroAssembler::VELEM_SIZE_16, quad);
10854   %}
10855   ins_pipe( ialu_reg_reg ); // FIXME
10856 %}
10857 
10858 instruct vsha8S_reg(vecX dst, vecX src, vecX shift) %{
10859   predicate(n->as_Vector()->length() == 8);
10860   effect(DEF dst, USE src, USE shift);
10861   size(4);
10862   ins_cost(DEFAULT_COST); // FIXME
10863   format %{
10864     "VSHL.S16 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed8S"
10865   %}
10866   ins_encode %{
10867     bool quad = true;
10868     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10869               MacroAssembler::VELEM_SIZE_16, quad);
10870   %}
10871   ins_pipe( ialu_reg_reg ); // FIXME
10872 %}
10873 
10874 // Integers vector arithmetic left/right shift based on sign
10875 instruct vsha2I_reg(vecD dst, vecD src, vecD shift) %{
10876   predicate(n->as_Vector()->length() == 2);
10877   effect(DEF dst, USE src, USE shift);
10878   size(4);
10879   ins_cost(DEFAULT_COST); // FIXME
10880   format %{
10881     "VSHL.S32 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed2I"
10882   %}
10883   ins_encode %{
10884     bool quad = false;
10885     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10886               MacroAssembler::VELEM_SIZE_32, quad);
10887   %}
10888   ins_pipe( ialu_reg_reg ); // FIXME
10889 %}
10890 
10891 instruct vsha4I_reg(vecX dst, vecX src, vecX shift) %{
10892   predicate(n->as_Vector()->length() == 4);
10893   effect(DEF dst, USE src, USE shift);
10894   size(4);
10895   ins_cost(DEFAULT_COST); // FIXME
10896   format %{
10897     "VSHL.S32 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed4I"
10898   %}
10899   ins_encode %{
10900     bool quad = true;
10901     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10902               MacroAssembler::VELEM_SIZE_32, quad);
10903   %}
10904   ins_pipe( ialu_reg_reg ); // FIXME
10905 %}
10906 
10907 // Longs vector arithmetic left/right shift based on sign
10908 instruct vsha2L_reg(vecX dst, vecX src, vecX shift) %{
10909   predicate(n->as_Vector()->length() == 2);
10910   effect(DEF dst, USE src, USE shift);
10911   size(4);
10912   ins_cost(DEFAULT_COST); // FIXME
10913   format %{
10914     "VSHL.S64 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed2L"
10915   %}
10916   ins_encode %{
10917     bool quad = true;
10918     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10919               MacroAssembler::VELEM_SIZE_64, quad);
10920   %}
10921   ins_pipe( ialu_reg_reg ); // FIXME
10922 %}
10923 
10924 // Byte vector arithmetic right shift
10925 
10926 instruct vsra8B_reg(vecD dst, vecD src, vecD shift) %{
10927   predicate(n->as_Vector()->length() == 8);
10928   match(Set dst (RShiftVB src shift));
10929   size(4);
10930   ins_cost(DEFAULT_COST); // FIXME
10931   expand %{
10932     vsha8B_reg(dst, src, shift);
10933   %}
10934 %}
10935 
10936 instruct vsrl16B_reg(vecX dst, vecX src, vecX shift) %{
10937   predicate(n->as_Vector()->length() == 16);
10938   match(Set dst (RShiftVB src shift));
10939   size(4);
10940   ins_cost(DEFAULT_COST); // FIXME
10941   expand %{
10942     vsha16B_reg(dst, src, shift);
10943   %}
10944 %}
10945 
10946 instruct vsrl8B_immI(vecD dst, vecD src, immI shift) %{
10947   predicate(n->as_Vector()->length() == 8);
10948   match(Set dst (RShiftVB src shift));
10949   size(4);
10950   ins_cost(DEFAULT_COST); // FIXME
10951   format %{
10952     "VSHR.S8 $dst.D,$src.D,$shift\t! logical right shift packed8B"
10953   %}
10954   ins_encode %{
10955     bool quad = false;
10956     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10957              quad);
10958   %}
10959   ins_pipe( ialu_reg_reg ); // FIXME
10960 %}
10961 
10962 instruct vsrl16B_immI(vecX dst, vecX src, immI shift) %{
10963   predicate(n->as_Vector()->length() == 16);
10964   match(Set dst (RShiftVB src shift));
10965   size(4);
10966   ins_cost(DEFAULT_COST); // FIXME
10967   format %{
10968     "VSHR.S8 $dst.Q,$src.Q,$shift\t! logical right shift packed16B"
10969   %}
10970   ins_encode %{
10971     bool quad = true;
10972     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10973              quad);
10974   %}
10975   ins_pipe( ialu_reg_reg ); // FIXME
10976 %}
10977 
10978 // Shorts vector arithmetic right shift
10979 instruct vsra4S_reg(vecD dst, vecD src, vecD shift) %{
10980   predicate(n->as_Vector()->length() == 4);
10981   match(Set dst (RShiftVS src shift));
10982   size(4);
10983   ins_cost(DEFAULT_COST); // FIXME
10984   expand %{
10985     vsha4S_reg(dst, src, shift);
10986   %}
10987 %}
10988 
10989 instruct vsra8S_reg(vecX dst, vecX src, vecX shift) %{
10990   predicate(n->as_Vector()->length() == 8);
10991   match(Set dst (RShiftVS src shift));
10992   size(4);
10993   ins_cost(DEFAULT_COST); // FIXME
10994   expand %{
10995     vsha8S_reg(dst, src, shift);
10996   %}
10997 %}
10998 
10999 instruct vsra4S_immI(vecD dst, vecD src, immI shift) %{
11000   predicate(n->as_Vector()->length() == 4);
11001   match(Set dst (RShiftVS src shift));
11002   size(4);
11003   ins_cost(DEFAULT_COST); // FIXME
11004   format %{
11005     "VSHR.S16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
11006   %}
11007   ins_encode %{
11008     bool quad = false;
11009     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
11010              quad);
11011   %}
11012   ins_pipe( ialu_reg_reg ); // FIXME
11013 %}
11014 
11015 instruct vsra8S_immI(vecX dst, vecX src, immI shift) %{
11016   predicate(n->as_Vector()->length() == 8);
11017   match(Set dst (RShiftVS src shift));
11018   size(4);
11019   ins_cost(DEFAULT_COST); // FIXME
11020   format %{
11021     "VSHR.S16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
11022   %}
11023   ins_encode %{
11024     bool quad = true;
11025     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
11026              quad);
11027   %}
11028   ins_pipe( ialu_reg_reg ); // FIXME
11029 %}
11030 
11031 // Integers vector arithmetic right shift
11032 instruct vsra2I_reg(vecD dst, vecD src, vecD shift) %{
11033   predicate(n->as_Vector()->length() == 2);
11034   match(Set dst (RShiftVI src shift));
11035   size(4);
11036   ins_cost(DEFAULT_COST); // FIXME
11037   expand %{
11038     vsha2I_reg(dst, src, shift);
11039   %}
11040 %}
11041 
11042 instruct vsra4I_reg(vecX dst, vecX src, vecX shift) %{
11043   predicate(n->as_Vector()->length() == 4);
11044   match(Set dst (RShiftVI src shift));
11045   size(4);
11046   ins_cost(DEFAULT_COST); // FIXME
11047   expand %{
11048     vsha4I_reg(dst, src, shift);
11049   %}
11050 %}
11051 
11052 instruct vsra2I_immI(vecD dst, vecD src, immI shift) %{
11053   predicate(n->as_Vector()->length() == 2);
11054   match(Set dst (RShiftVI src shift));
11055   size(4);
11056   ins_cost(DEFAULT_COST); // FIXME
11057   format %{
11058     "VSHR.S32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
11059   %}
11060   ins_encode %{
11061     bool quad = false;
11062     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11063              quad);
11064   %}
11065   ins_pipe( ialu_reg_reg ); // FIXME
11066 %}
11067 
11068 instruct vsra4I_immI(vecX dst, vecX src, immI shift) %{
11069   predicate(n->as_Vector()->length() == 4);
11070   match(Set dst (RShiftVI src shift));
11071   size(4);
11072   ins_cost(DEFAULT_COST); // FIXME
11073   format %{
11074     "VSHR.S32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
11075   %}
11076   ins_encode %{
11077     bool quad = true;
11078     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11079              quad);
11080   %}
11081   ins_pipe( ialu_reg_reg ); // FIXME
11082 %}
11083 
11084 // Longs vector arithmetic right shift
11085 instruct vsra2L_reg(vecX dst, vecX src, vecX shift) %{
11086   predicate(n->as_Vector()->length() == 2);
11087   match(Set dst (RShiftVL src shift));
11088   size(4);
11089   ins_cost(DEFAULT_COST); // FIXME
11090   expand %{
11091     vsha2L_reg(dst, src, shift);
11092   %}
11093 %}
11094 
11095 instruct vsra2L_immI(vecX dst, vecX src, immI shift) %{
11096   predicate(n->as_Vector()->length() == 2);
11097   match(Set dst (RShiftVL src shift));
11098   size(4);
11099   ins_cost(DEFAULT_COST); // FIXME
11100   format %{
11101     "VSHR.S64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
11102   %}
11103   ins_encode %{
11104     bool quad = true;
11105     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
11106              quad);
11107   %}
11108   ins_pipe( ialu_reg_reg ); // FIXME
11109 %}
11110 
11111 // --------------------------------- AND --------------------------------------
11112 
11113 instruct vandD(vecD dst, vecD src1, vecD src2) %{
11114   predicate(n->as_Vector()->length_in_bytes() == 8);
11115   match(Set dst (AndV src1 src2));
11116   format %{ "VAND    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11117   ins_encode %{
11118     bool quad = false;
11119     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11120              quad);
11121   %}
11122   ins_pipe( ialu_reg_reg ); // FIXME
11123 %}
11124 
11125 instruct vandX(vecX dst, vecX src1, vecX src2) %{
11126   predicate(n->as_Vector()->length_in_bytes() == 16);
11127   match(Set dst (AndV src1 src2));
11128   format %{ "VAND    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11129   ins_encode %{
11130     bool quad = true;
11131     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11132              quad);
11133   %}
11134   ins_pipe( ialu_reg_reg ); // FIXME
11135 %}
11136 
11137 // --------------------------------- OR ---------------------------------------
11138 
11139 instruct vorD(vecD dst, vecD src1, vecD src2) %{
11140   predicate(n->as_Vector()->length_in_bytes() == 8);
11141   match(Set dst (OrV src1 src2));
11142   format %{ "VOR     $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11143   ins_encode %{
11144     bool quad = false;
11145     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11146             quad);
11147   %}
11148   ins_pipe( ialu_reg_reg ); // FIXME
11149 %}
11150 
11151 instruct vorX(vecX dst, vecX src1, vecX src2) %{
11152   predicate(n->as_Vector()->length_in_bytes() == 16);
11153   match(Set dst (OrV src1 src2));
11154   format %{ "VOR     $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11155   ins_encode %{
11156     bool quad = true;
11157     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11158             quad);
11159   %}
11160   ins_pipe( ialu_reg_reg ); // FIXME
11161 %}
11162 
11163 // --------------------------------- XOR --------------------------------------
11164 
11165 instruct vxorD(vecD dst, vecD src1, vecD src2) %{
11166   predicate(n->as_Vector()->length_in_bytes() == 8);
11167   match(Set dst (XorV src1 src2));
11168   format %{ "VXOR    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11169   ins_encode %{
11170     bool quad = false;
11171     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11172              quad);
11173   %}
11174   ins_pipe( ialu_reg_reg ); // FIXME
11175 %}
11176 
11177 instruct vxorX(vecX dst, vecX src1, vecX src2) %{
11178   predicate(n->as_Vector()->length_in_bytes() == 16);
11179   match(Set dst (XorV src1 src2));
11180   format %{ "VXOR    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11181   ins_encode %{
11182     bool quad = true;
11183     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11184              quad);
11185   %}
11186   ins_pipe( ialu_reg_reg ); // FIXME
11187 %}
11188 
11189 
11190 //----------PEEPHOLE RULES-----------------------------------------------------
11191 // These must follow all instruction definitions as they use the names
11192 // defined in the instructions definitions.
11193 //
11194 // peepmatch ( root_instr_name [preceding_instruction]* );
11195 //
11196 // peepconstraint %{
11197 // (instruction_number.operand_name relational_op instruction_number.operand_name
11198 //  [, ...] );
11199 // // instruction numbers are zero-based using left to right order in peepmatch
11200 //
11201 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
11202 // // provide an instruction_number.operand_name for each operand that appears
11203 // // in the replacement instruction's match rule
11204 //
11205 // ---------VM FLAGS---------------------------------------------------------
11206 //
11207 // All peephole optimizations can be turned off using -XX:-OptoPeephole
11208 //
11209 // Each peephole rule is given an identifying number starting with zero and
11210 // increasing by one in the order seen by the parser.  An individual peephole
11211 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
11212 // on the command-line.
11213 //
11214 // ---------CURRENT LIMITATIONS----------------------------------------------
11215 //
11216 // Only match adjacent instructions in same basic block
11217 // Only equality constraints
11218 // Only constraints between operands, not (0.dest_reg == EAX_enc)
11219 // Only one replacement instruction
11220 //
11221 // ---------EXAMPLE----------------------------------------------------------
11222 //
11223 // // pertinent parts of existing instructions in architecture description
11224 // instruct movI(eRegI dst, eRegI src) %{
11225 //   match(Set dst (CopyI src));
11226 // %}
11227 //
11228 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
11229 //   match(Set dst (AddI dst src));
11230 //   effect(KILL cr);
11231 // %}
11232 //
11233 // // Change (inc mov) to lea
11234 // peephole %{
11235 //   // increment preceeded by register-register move
11236 //   peepmatch ( incI_eReg movI );
11237 //   // require that the destination register of the increment
11238 //   // match the destination register of the move
11239 //   peepconstraint ( 0.dst == 1.dst );
11240 //   // construct a replacement instruction that sets
11241 //   // the destination to ( move's source register + one )
11242 //   peepreplace ( incI_eReg_immI1( 0.dst 1.src 0.src ) );
11243 // %}
11244 //
11245 
11246 // // Change load of spilled value to only a spill
11247 // instruct storeI(memory mem, eRegI src) %{
11248 //   match(Set mem (StoreI mem src));
11249 // %}
11250 //
11251 // instruct loadI(eRegI dst, memory mem) %{
11252 //   match(Set dst (LoadI mem));
11253 // %}
11254 //
11255 // peephole %{
11256 //   peepmatch ( loadI storeI );
11257 //   peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
11258 //   peepreplace ( storeI( 1.mem 1.mem 1.src ) );
11259 // %}
11260 
11261 //----------SMARTSPILL RULES---------------------------------------------------
11262 // These must follow all instruction definitions as they use the names
11263 // defined in the instructions definitions.
11264 //
11265 // ARM will probably not have any of these rules due to RISC instruction set.
11266 
11267 //----------PIPELINE-----------------------------------------------------------
11268 // Rules which define the behavior of the target architectures pipeline.