1 //
    2 // Copyright (c) 2008, 2020, 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 // Indicate if the safepoint node needs the polling page as an input.
  150 // Since ARM does not have absolute addressing, it does.
  151 bool SafePointNode::needs_polling_address_input() {
  152   return true;
  153 }
  154 
  155 // emit an interrupt that is caught by the debugger (for debugging compiler)
  156 void emit_break(CodeBuffer &cbuf) {
  157   C2_MacroAssembler _masm(&cbuf);
  158   __ breakpoint();
  159 }
  160 
  161 #ifndef PRODUCT
  162 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream *st ) const {
  163   st->print("TA");
  164 }
  165 #endif
  166 
  167 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  168   emit_break(cbuf);
  169 }
  170 
  171 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
  172   return MachNode::size(ra_);
  173 }
  174 
  175 
  176 void emit_nop(CodeBuffer &cbuf) {
  177   C2_MacroAssembler _masm(&cbuf);
  178   __ nop();
  179 }
  180 
  181 
  182 void emit_call_reloc(CodeBuffer &cbuf, const MachCallNode *n, MachOper *m, RelocationHolder const& rspec) {
  183   int ret_addr_offset0 = n->as_MachCall()->ret_addr_offset();
  184   int call_site_offset = cbuf.insts()->mark_off();
  185   C2_MacroAssembler _masm(&cbuf);
  186   __ set_inst_mark(); // needed in emit_to_interp_stub() to locate the call
  187   address target = (address)m->method();
  188   assert(n->as_MachCall()->entry_point() == target, "sanity");
  189   assert(maybe_far_call(n) == !__ reachable_from_cache(target), "sanity");
  190   assert(cache_reachable() == __ cache_fully_reachable(), "sanity");
  191 
  192   assert(target != NULL, "need real address");
  193 
  194   int ret_addr_offset = -1;
  195   if (rspec.type() == relocInfo::runtime_call_type) {
  196     __ call(target, rspec);
  197     ret_addr_offset = __ offset();
  198   } else {
  199     // scratches Rtemp
  200     ret_addr_offset = __ patchable_call(target, rspec, true);
  201   }
  202   assert(ret_addr_offset - call_site_offset == ret_addr_offset0, "fix ret_addr_offset()");
  203 }
  204 
  205 //=============================================================================
  206 // REQUIRED FUNCTIONALITY for encoding
  207 void emit_lo(CodeBuffer &cbuf, int val) {  }
  208 void emit_hi(CodeBuffer &cbuf, int val) {  }
  209 
  210 
  211 //=============================================================================
  212 const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask();
  213 
  214 int ConstantTable::calculate_table_base_offset() const {
  215   int offset = -(size() / 2);
  216   // flds, fldd: 8-bit  offset multiplied by 4: +/- 1024
  217   // ldr, ldrb : 12-bit offset:                 +/- 4096
  218   if (!Assembler::is_simm10(offset)) {
  219     offset = Assembler::min_simm10;
  220   }
  221   return offset;
  222 }
  223 
  224 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
  225 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
  226   ShouldNotReachHere();
  227 }
  228 
  229 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
  230   Compile* C = ra_->C;
  231   ConstantTable& constant_table = C->output()->constant_table();
  232   C2_MacroAssembler _masm(&cbuf);
  233 
  234   Register r = as_Register(ra_->get_encode(this));
  235   CodeSection* consts_section = __ code()->consts();
  236   int consts_size = consts_section->align_at_start(consts_section->size());
  237   assert(constant_table.size() == consts_size, "must be: %d == %d", constant_table.size(), consts_size);
  238 
  239   // Materialize the constant table base.
  240   address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
  241   RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
  242   __ mov_address(r, baseaddr, rspec);
  243 }
  244 
  245 uint MachConstantBaseNode::size(PhaseRegAlloc*) const {
  246   return 8;
  247 }
  248 
  249 #ifndef PRODUCT
  250 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
  251   char reg[128];
  252   ra_->dump_register(this, reg);
  253   st->print("MOV_SLOW    &constanttable,%s\t! constant table base", reg);
  254 }
  255 #endif
  256 
  257 #ifndef PRODUCT
  258 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  259   Compile* C = ra_->C;
  260 
  261   for (int i = 0; i < OptoPrologueNops; i++) {
  262     st->print_cr("NOP"); st->print("\t");
  263   }
  264 
  265   size_t framesize = C->output()->frame_size_in_bytes();
  266   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  267   int bangsize = C->output()->bang_size_in_bytes();
  268   // Remove two words for return addr and rbp,
  269   framesize -= 2*wordSize;
  270   bangsize -= 2*wordSize;
  271 
  272   // Calls to C2R adapters often do not accept exceptional returns.
  273   // We require that their callers must bang for them.  But be careful, because
  274   // some VM calls (such as call site linkage) can use several kilobytes of
  275   // stack.  But the stack safety zone should account for that.
  276   // See bugs 4446381, 4468289, 4497237.
  277   if (C->output()->need_stack_bang(bangsize)) {
  278     st->print_cr("! stack bang (%d bytes)", bangsize); st->print("\t");
  279   }
  280   st->print_cr("PUSH   R_FP|R_LR_LR"); st->print("\t");
  281   if (framesize != 0) {
  282     st->print   ("SUB    R_SP, R_SP, " SIZE_FORMAT,framesize);
  283   }
  284 }
  285 #endif
  286 
  287 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  288   Compile* C = ra_->C;
  289   C2_MacroAssembler _masm(&cbuf);
  290 
  291   for (int i = 0; i < OptoPrologueNops; i++) {
  292     __ nop();
  293   }
  294 
  295   size_t framesize = C->output()->frame_size_in_bytes();
  296   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  297   int bangsize = C->output()->bang_size_in_bytes();
  298   // Remove two words for return addr and fp,
  299   framesize -= 2*wordSize;
  300   bangsize -= 2*wordSize;
  301 
  302   // Calls to C2R adapters often do not accept exceptional returns.
  303   // We require that their callers must bang for them.  But be careful, because
  304   // some VM calls (such as call site linkage) can use several kilobytes of
  305   // stack.  But the stack safety zone should account for that.
  306   // See bugs 4446381, 4468289, 4497237.
  307   if (C->output()->need_stack_bang(bangsize)) {
  308     __ arm_stack_overflow_check(bangsize, Rtemp);
  309   }
  310 
  311   __ raw_push(FP, LR);
  312   if (framesize != 0) {
  313     __ sub_slow(SP, SP, framesize);
  314   }
  315 
  316   // offset from scratch buffer is not valid
  317   if (strcmp(cbuf.name(), "Compile::Fill_buffer") == 0) {
  318     C->output()->set_frame_complete( __ offset() );
  319   }
  320 
  321   if (C->has_mach_constant_base_node()) {
  322     // NOTE: We set the table base offset here because users might be
  323     // emitted before MachConstantBaseNode.
  324     ConstantTable& constant_table = C->output()->constant_table();
  325     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
  326   }
  327 }
  328 
  329 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
  330   return MachNode::size(ra_);
  331 }
  332 
  333 int MachPrologNode::reloc() const {
  334   return 10; // a large enough number
  335 }
  336 
  337 //=============================================================================
  338 #ifndef PRODUCT
  339 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  340   Compile* C = ra_->C;
  341 
  342   size_t framesize = C->output()->frame_size_in_bytes();
  343   framesize -= 2*wordSize;
  344 
  345   if (framesize != 0) {
  346     st->print("ADD    R_SP, R_SP, " SIZE_FORMAT "\n\t",framesize);
  347   }
  348   st->print("POP    R_FP|R_LR_LR");
  349 
  350   if (do_polling() && ra_->C->is_method_compilation()) {
  351     st->print("\n\t");
  352     st->print("MOV    Rtemp, #PollAddr\t! Load Polling address\n\t");
  353     st->print("LDR    Rtemp,[Rtemp]\t!Poll for Safepointing");
  354   }
  355 }
  356 #endif
  357 
  358 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  359   C2_MacroAssembler _masm(&cbuf);
  360   Compile* C = ra_->C;
  361 
  362   size_t framesize = C->output()->frame_size_in_bytes();
  363   framesize -= 2*wordSize;
  364   if (framesize != 0) {
  365     __ add_slow(SP, SP, framesize);
  366   }
  367   __ raw_pop(FP, LR);
  368 
  369   // If this does safepoint polling, then do it here
  370   if (do_polling() && ra_->C->is_method_compilation()) {
  371     __ read_polling_page(Rtemp, relocInfo::poll_return_type);
  372   }
  373 }
  374 
  375 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
  376   return MachNode::size(ra_);
  377 }
  378 
  379 int MachEpilogNode::reloc() const {
  380   return 16; // a large enough number
  381 }
  382 
  383 const Pipeline * MachEpilogNode::pipeline() const {
  384   return MachNode::pipeline_class();
  385 }
  386 
  387 //=============================================================================
  388 
  389 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
  390 enum RC { rc_bad, rc_int, rc_float, rc_stack };
  391 static enum RC rc_class( OptoReg::Name reg ) {
  392   if (!OptoReg::is_valid(reg)) return rc_bad;
  393   if (OptoReg::is_stack(reg)) return rc_stack;
  394   VMReg r = OptoReg::as_VMReg(reg);
  395   if (r->is_Register()) return rc_int;
  396   assert(r->is_FloatRegister(), "must be");
  397   return rc_float;
  398 }
  399 
  400 static inline bool is_iRegLd_memhd(OptoReg::Name src_first, OptoReg::Name src_second, int offset) {
  401   int rlo = Matcher::_regEncode[src_first];
  402   int rhi = Matcher::_regEncode[src_second];
  403   if (!((rlo&1)==0 && (rlo+1 == rhi))) {
  404     tty->print_cr("CAUGHT BAD LDRD/STRD");
  405   }
  406   return (rlo&1)==0 && (rlo+1 == rhi) && is_memoryHD(offset);
  407 }
  408 
  409 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
  410                                         PhaseRegAlloc *ra_,
  411                                         bool do_size,
  412                                         outputStream* st ) const {
  413   // Get registers to move
  414   OptoReg::Name src_second = ra_->get_reg_second(in(1));
  415   OptoReg::Name src_first = ra_->get_reg_first(in(1));
  416   OptoReg::Name dst_second = ra_->get_reg_second(this );
  417   OptoReg::Name dst_first = ra_->get_reg_first(this );
  418 
  419   enum RC src_second_rc = rc_class(src_second);
  420   enum RC src_first_rc = rc_class(src_first);
  421   enum RC dst_second_rc = rc_class(dst_second);
  422   enum RC dst_first_rc = rc_class(dst_first);
  423 
  424   assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
  425 
  426   // Generate spill code!
  427   int size = 0;
  428 
  429   if (src_first == dst_first && src_second == dst_second)
  430     return size;            // Self copy, no move
  431 
  432 #ifdef TODO
  433   if (bottom_type()->isa_vect() != NULL) {
  434   }
  435 #endif
  436 
  437   // Shared code does not expect instruction set capability based bailouts here.
  438   // Handle offset unreachable bailout with minimal change in shared code.
  439   // Bailout only for real instruction emit.
  440   // This requires a single comment change in shared code. ( see output.cpp "Normal" instruction case )
  441 
  442   C2_MacroAssembler _masm(cbuf);
  443 
  444   // --------------------------------------
  445   // Check for mem-mem move.  Load into unused float registers and fall into
  446   // the float-store case.
  447   if (src_first_rc == rc_stack && dst_first_rc == rc_stack) {
  448     int offset = ra_->reg2offset(src_first);
  449     if (cbuf && !is_memoryfp(offset)) {
  450       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  451       return 0;
  452     } else {
  453       if (src_second_rc != rc_bad) {
  454         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
  455         src_first     = OptoReg::Name(R_mem_copy_lo_num);
  456         src_second    = OptoReg::Name(R_mem_copy_hi_num);
  457         src_first_rc  = rc_float;
  458         src_second_rc = rc_float;
  459         if (cbuf) {
  460           __ ldr_double(Rmemcopy, Address(SP, offset));
  461         } else if (!do_size) {
  462           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  463         }
  464       } else {
  465         src_first     = OptoReg::Name(R_mem_copy_lo_num);
  466         src_first_rc  = rc_float;
  467         if (cbuf) {
  468           __ ldr_float(Rmemcopy, Address(SP, offset));
  469         } else if (!do_size) {
  470           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  471         }
  472       }
  473       size += 4;
  474     }
  475   }
  476 
  477   if (src_second_rc == rc_stack && dst_second_rc == rc_stack) {
  478     Unimplemented();
  479   }
  480 
  481   // --------------------------------------
  482   // Check for integer reg-reg copy
  483   if (src_first_rc == rc_int && dst_first_rc == rc_int) {
  484     // Else normal reg-reg copy
  485     assert( src_second != dst_first, "smashed second before evacuating it" );
  486     if (cbuf) {
  487       __ mov(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
  488 #ifndef PRODUCT
  489     } else if (!do_size) {
  490       st->print("MOV    R_%s, R_%s\t# spill",
  491                 Matcher::regName[dst_first],
  492                 Matcher::regName[src_first]);
  493 #endif
  494     }
  495     size += 4;
  496   }
  497 
  498   // Check for integer store
  499   if (src_first_rc == rc_int && dst_first_rc == rc_stack) {
  500     int offset = ra_->reg2offset(dst_first);
  501     if (cbuf && !is_memoryI(offset)) {
  502       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  503       return 0;
  504     } else {
  505       if (src_second_rc != rc_bad && is_iRegLd_memhd(src_first, src_second, offset)) {
  506         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
  507         if (cbuf) {
  508           __ str_64(reg_to_register_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  509 #ifndef PRODUCT
  510         } else if (!do_size) {
  511           if (size != 0) st->print("\n\t");
  512           st->print(STR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
  513 #endif
  514         }
  515         return size + 4;
  516       } else {
  517         if (cbuf) {
  518           __ str_32(reg_to_register_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  519 #ifndef PRODUCT
  520         } else if (!do_size) {
  521           if (size != 0) st->print("\n\t");
  522           st->print(STR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
  523 #endif
  524         }
  525       }
  526     }
  527     size += 4;
  528   }
  529 
  530   // Check for integer load
  531   if (dst_first_rc == rc_int && src_first_rc == rc_stack) {
  532     int offset = ra_->reg2offset(src_first);
  533     if (cbuf && !is_memoryI(offset)) {
  534       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  535       return 0;
  536     } else {
  537       if (src_second_rc != rc_bad && is_iRegLd_memhd(dst_first, dst_second, offset)) {
  538         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
  539         if (cbuf) {
  540           __ ldr_64(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  541 #ifndef PRODUCT
  542         } else if (!do_size) {
  543           if (size != 0) st->print("\n\t");
  544           st->print(LDR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
  545 #endif
  546         }
  547         return size + 4;
  548       } else {
  549         if (cbuf) {
  550           __ ldr_32(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  551 #ifndef PRODUCT
  552         } else if (!do_size) {
  553           if (size != 0) st->print("\n\t");
  554           st->print(LDR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
  555 #endif
  556         }
  557       }
  558     }
  559     size += 4;
  560   }
  561 
  562   // Check for float reg-reg copy
  563   if (src_first_rc == rc_float && dst_first_rc == rc_float) {
  564     if (src_second_rc != rc_bad) {
  565       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");
  566       if (cbuf) {
  567       __ mov_double(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
  568 #ifndef PRODUCT
  569       } else if (!do_size) {
  570         st->print(MOV_DOUBLE "    R_%s, R_%s\t# spill",
  571                   Matcher::regName[dst_first],
  572                   Matcher::regName[src_first]);
  573 #endif
  574       }
  575       return 4;
  576     }
  577     if (cbuf) {
  578       __ mov_float(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
  579 #ifndef PRODUCT
  580     } else if (!do_size) {
  581       st->print(MOV_FLOAT "    R_%s, R_%s\t# spill",
  582                 Matcher::regName[dst_first],
  583                 Matcher::regName[src_first]);
  584 #endif
  585     }
  586     size = 4;
  587   }
  588 
  589   // Check for float store
  590   if (src_first_rc == rc_float && dst_first_rc == rc_stack) {
  591     int offset = ra_->reg2offset(dst_first);
  592     if (cbuf && !is_memoryfp(offset)) {
  593       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  594       return 0;
  595     } else {
  596       // Further check for aligned-adjacent pair, so we can use a double store
  597       if (src_second_rc != rc_bad) {
  598         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");
  599         if (cbuf) {
  600           __ str_double(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  601 #ifndef PRODUCT
  602         } else if (!do_size) {
  603           if (size != 0) st->print("\n\t");
  604           st->print(STR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  605 #endif
  606         }
  607         return size + 4;
  608       } else {
  609         if (cbuf) {
  610           __ str_float(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(SP, offset));
  611 #ifndef PRODUCT
  612         } else if (!do_size) {
  613           if (size != 0) st->print("\n\t");
  614           st->print(STR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
  615 #endif
  616         }
  617       }
  618     }
  619     size += 4;
  620   }
  621 
  622   // Check for float load
  623   if (dst_first_rc == rc_float && src_first_rc == rc_stack) {
  624     int offset = ra_->reg2offset(src_first);
  625     if (cbuf && !is_memoryfp(offset)) {
  626       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  627       return 0;
  628     } else {
  629       // Further check for aligned-adjacent pair, so we can use a double store
  630       if (src_second_rc != rc_bad) {
  631         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");
  632         if (cbuf) {
  633           __ ldr_double(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  634 #ifndef PRODUCT
  635         } else if (!do_size) {
  636           if (size != 0) st->print("\n\t");
  637           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
  638 #endif
  639         }
  640         return size + 4;
  641       } else {
  642         if (cbuf) {
  643           __ ldr_float(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
  644 #ifndef PRODUCT
  645         } else if (!do_size) {
  646           if (size != 0) st->print("\n\t");
  647           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
  648 #endif
  649         }
  650       }
  651     }
  652     size += 4;
  653   }
  654 
  655   // check for int reg -> float reg move
  656   if (src_first_rc == rc_int && dst_first_rc == rc_float) {
  657     // Further check for aligned-adjacent pair, so we can use a single instruction
  658     if (src_second_rc != rc_bad) {
  659       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
  660       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
  661       assert(src_second_rc == rc_int && dst_second_rc == rc_float, "unsupported");
  662       if (cbuf) {
  663         __ 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]));
  664 #ifndef PRODUCT
  665       } else if (!do_size) {
  666         if (size != 0) st->print("\n\t");
  667         st->print("FMDRR   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first), OptoReg::regname(src_second));
  668 #endif
  669       }
  670       return size + 4;
  671     } else {
  672       if (cbuf) {
  673         __ fmsr(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
  674 #ifndef PRODUCT
  675       } else if (!do_size) {
  676         if (size != 0) st->print("\n\t");
  677         st->print(FMSR "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
  678 #endif
  679       }
  680       size += 4;
  681     }
  682   }
  683 
  684   // check for float reg -> int reg move
  685   if (src_first_rc == rc_float && dst_first_rc == rc_int) {
  686     // Further check for aligned-adjacent pair, so we can use a single instruction
  687     if (src_second_rc != rc_bad) {
  688       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
  689       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
  690       assert(src_second_rc == rc_float && dst_second_rc == rc_int, "unsupported");
  691       if (cbuf) {
  692         __ 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]));
  693 #ifndef PRODUCT
  694       } else if (!do_size) {
  695         if (size != 0) st->print("\n\t");
  696         st->print("FMRRD   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(dst_second), OptoReg::regname(src_first));
  697 #endif
  698       }
  699       return size + 4;
  700     } else {
  701       if (cbuf) {
  702         __ fmrs(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
  703 #ifndef PRODUCT
  704       } else if (!do_size) {
  705         if (size != 0) st->print("\n\t");
  706         st->print(FMRS "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
  707 #endif
  708       }
  709       size += 4;
  710     }
  711   }
  712 
  713   // --------------------------------------------------------------------
  714   // Check for hi bits still needing moving.  Only happens for misaligned
  715   // arguments to native calls.
  716   if (src_second == dst_second)
  717     return size;               // Self copy; no move
  718   assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" );
  719 
  720   // Check for integer reg-reg copy.  Hi bits are stuck up in the top
  721   // 32-bits of a 64-bit register, but are needed in low bits of another
  722   // register (else it's a hi-bits-to-hi-bits copy which should have
  723   // happened already as part of a 64-bit move)
  724   if (src_second_rc == rc_int && dst_second_rc == rc_int) {
  725     if (cbuf) {
  726       __ mov(reg_to_register_object(Matcher::_regEncode[dst_second]), reg_to_register_object(Matcher::_regEncode[src_second]));
  727 #ifndef PRODUCT
  728     } else if (!do_size) {
  729       if (size != 0) st->print("\n\t");
  730       st->print("MOV    R_%s, R_%s\t# spill high",
  731                 Matcher::regName[dst_second],
  732                 Matcher::regName[src_second]);
  733 #endif
  734     }
  735     return size+4;
  736   }
  737 
  738   // Check for high word integer store
  739   if (src_second_rc == rc_int && dst_second_rc == rc_stack) {
  740     int offset = ra_->reg2offset(dst_second);
  741 
  742     if (cbuf && !is_memoryP(offset)) {
  743       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  744       return 0;
  745     } else {
  746       if (cbuf) {
  747         __ str(reg_to_register_object(Matcher::_regEncode[src_second]), Address(SP, offset));
  748 #ifndef PRODUCT
  749       } else if (!do_size) {
  750         if (size != 0) st->print("\n\t");
  751         st->print("STR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_second), offset);
  752 #endif
  753       }
  754     }
  755     return size + 4;
  756   }
  757 
  758   // Check for high word integer load
  759   if (dst_second_rc == rc_int && src_second_rc == rc_stack) {
  760     int offset = ra_->reg2offset(src_second);
  761     if (cbuf && !is_memoryP(offset)) {
  762       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
  763       return 0;
  764     } else {
  765       if (cbuf) {
  766         __ ldr(reg_to_register_object(Matcher::_regEncode[dst_second]), Address(SP, offset));
  767 #ifndef PRODUCT
  768       } else if (!do_size) {
  769         if (size != 0) st->print("\n\t");
  770         st->print("LDR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_second), offset);
  771 #endif
  772       }
  773     }
  774     return size + 4;
  775   }
  776 
  777   Unimplemented();
  778   return 0; // Mute compiler
  779 }
  780 
  781 #ifndef PRODUCT
  782 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  783   implementation( NULL, ra_, false, st );
  784 }
  785 #endif
  786 
  787 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  788   implementation( &cbuf, ra_, false, NULL );
  789 }
  790 
  791 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
  792   return implementation( NULL, ra_, true, NULL );
  793 }
  794 
  795 //=============================================================================
  796 #ifndef PRODUCT
  797 void MachNopNode::format( PhaseRegAlloc *, outputStream *st ) const {
  798   st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
  799 }
  800 #endif
  801 
  802 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
  803   C2_MacroAssembler _masm(&cbuf);
  804   for(int i = 0; i < _count; i += 1) {
  805     __ nop();
  806   }
  807 }
  808 
  809 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
  810   return 4 * _count;
  811 }
  812 
  813 
  814 //=============================================================================
  815 #ifndef PRODUCT
  816 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  817   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  818   int reg = ra_->get_reg_first(this);
  819   st->print("ADD    %s,R_SP+#%d",Matcher::regName[reg], offset);
  820 }
  821 #endif
  822 
  823 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  824   C2_MacroAssembler _masm(&cbuf);
  825   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  826   int reg = ra_->get_encode(this);
  827   Register dst = reg_to_register_object(reg);
  828 
  829   if (is_aimm(offset)) {
  830     __ add(dst, SP, offset);
  831   } else {
  832     __ mov_slow(dst, offset);
  833     __ add(dst, SP, dst);
  834   }
  835 }
  836 
  837 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
  838   // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_)
  839   assert(ra_ == ra_->C->regalloc(), "sanity");
  840   return ra_->C->output()->scratch_emit_size(this);
  841 }
  842 
  843 //=============================================================================
  844 #ifndef PRODUCT
  845 #define R_RTEMP "R_R12"
  846 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
  847   st->print_cr("\nUEP:");
  848   if (UseCompressedClassPointers) {
  849     st->print_cr("\tLDR_w " R_RTEMP ",[R_R0 + oopDesc::klass_offset_in_bytes]\t! Inline cache check");
  850     st->print_cr("\tdecode_klass " R_RTEMP);
  851   } else {
  852     st->print_cr("\tLDR   " R_RTEMP ",[R_R0 + oopDesc::klass_offset_in_bytes]\t! Inline cache check");
  853   }
  854   st->print_cr("\tCMP   " R_RTEMP ",R_R8" );
  855   st->print   ("\tB.NE  SharedRuntime::handle_ic_miss_stub");
  856 }
  857 #endif
  858 
  859 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  860   C2_MacroAssembler _masm(&cbuf);
  861   Register iCache  = reg_to_register_object(Matcher::inline_cache_reg_encode());
  862   assert(iCache == Ricklass, "should be");
  863   Register receiver = R0;
  864 
  865   __ load_klass(Rtemp, receiver);
  866   __ cmp(Rtemp, iCache);
  867   __ jump(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type, noreg, ne);
  868 }
  869 
  870 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
  871   return MachNode::size(ra_);
  872 }
  873 
  874 
  875 //=============================================================================
  876 
  877 // Emit exception handler code.
  878 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) {
  879   C2_MacroAssembler _masm(&cbuf);
  880 
  881   address base = __ start_a_stub(size_exception_handler());
  882   if (base == NULL) {
  883     ciEnv::current()->record_failure("CodeCache is full");
  884     return 0;  // CodeBuffer::expand failed
  885   }
  886 
  887   int offset = __ offset();
  888 
  889   // OK to trash LR, because exception blob will kill it
  890   __ jump(OptoRuntime::exception_blob()->entry_point(), relocInfo::runtime_call_type, LR_tmp);
  891 
  892   assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
  893 
  894   __ end_a_stub();
  895 
  896   return offset;
  897 }
  898 
  899 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
  900   // Can't use any of the current frame's registers as we may have deopted
  901   // at a poll and everything can be live.
  902   C2_MacroAssembler _masm(&cbuf);
  903 
  904   address base = __ start_a_stub(size_deopt_handler());
  905   if (base == NULL) {
  906     ciEnv::current()->record_failure("CodeCache is full");
  907     return 0;  // CodeBuffer::expand failed
  908   }
  909 
  910   int offset = __ offset();
  911   address deopt_pc = __ pc();
  912 
  913   __ sub(SP, SP, wordSize); // make room for saved PC
  914   __ push(LR); // save LR that may be live when we get here
  915   __ mov_relative_address(LR, deopt_pc);
  916   __ str(LR, Address(SP, wordSize)); // save deopt PC
  917   __ pop(LR); // restore LR
  918   __ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, noreg);
  919 
  920   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
  921 
  922   __ end_a_stub();
  923   return offset;
  924 }
  925 
  926 const bool Matcher::match_rule_supported(int opcode) {
  927   if (!has_match_rule(opcode))
  928     return false;
  929 
  930   switch (opcode) {
  931   case Op_PopCountI:
  932   case Op_PopCountL:
  933     if (!UsePopCountInstruction)
  934       return false;
  935     break;
  936   case Op_LShiftCntV:
  937   case Op_RShiftCntV:
  938   case Op_AddVB:
  939   case Op_AddVS:
  940   case Op_AddVI:
  941   case Op_AddVL:
  942   case Op_SubVB:
  943   case Op_SubVS:
  944   case Op_SubVI:
  945   case Op_SubVL:
  946   case Op_MulVS:
  947   case Op_MulVI:
  948   case Op_LShiftVB:
  949   case Op_LShiftVS:
  950   case Op_LShiftVI:
  951   case Op_LShiftVL:
  952   case Op_RShiftVB:
  953   case Op_RShiftVS:
  954   case Op_RShiftVI:
  955   case Op_RShiftVL:
  956   case Op_URShiftVB:
  957   case Op_URShiftVS:
  958   case Op_URShiftVI:
  959   case Op_URShiftVL:
  960   case Op_AndV:
  961   case Op_OrV:
  962   case Op_XorV:
  963     return VM_Version::has_simd();
  964   case Op_LoadVector:
  965   case Op_StoreVector:
  966   case Op_AddVF:
  967   case Op_SubVF:
  968   case Op_MulVF:
  969     return VM_Version::has_vfp() || VM_Version::has_simd();
  970   case Op_AddVD:
  971   case Op_SubVD:
  972   case Op_MulVD:
  973   case Op_DivVF:
  974   case Op_DivVD:
  975     return VM_Version::has_vfp();
  976   }
  977 
  978   return true;  // Per default match rules are supported.
  979 }
  980 
  981 const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
  982 
  983   // TODO
  984   // identify extra cases that we might want to provide match rules for
  985   // e.g. Op_ vector nodes and other intrinsics while guarding with vlen
  986   bool ret_value = match_rule_supported(opcode);
  987   // Add rules here.
  988 
  989   return ret_value;  // Per default match rules are supported.
  990 }
  991 
  992 const bool Matcher::has_predicated_vectors(void) {
  993   return false;
  994 }
  995 
  996 const int Matcher::float_pressure(int default_pressure_threshold) {
  997   return default_pressure_threshold;
  998 }
  999 
 1000 int Matcher::regnum_to_fpu_offset(int regnum) {
 1001   return regnum - 32; // The FP registers are in the second chunk
 1002 }
 1003 
 1004 // Vector width in bytes
 1005 const int Matcher::vector_width_in_bytes(BasicType bt) {
 1006   return MaxVectorSize;
 1007 }
 1008 
 1009 // Vector ideal reg corresponding to specified size in bytes
 1010 const uint Matcher::vector_ideal_reg(int size) {
 1011   assert(MaxVectorSize >= size, "");
 1012   switch(size) {
 1013     case  8: return Op_VecD;
 1014     case 16: return Op_VecX;
 1015   }
 1016   ShouldNotReachHere();
 1017   return 0;
 1018 }
 1019 
 1020 // Limits on vector size (number of elements) loaded into vector.
 1021 const int Matcher::max_vector_size(const BasicType bt) {
 1022   assert(is_java_primitive(bt), "only primitive type vectors");
 1023   return vector_width_in_bytes(bt)/type2aelembytes(bt);
 1024 }
 1025 
 1026 const int Matcher::min_vector_size(const BasicType bt) {
 1027   assert(is_java_primitive(bt), "only primitive type vectors");
 1028   return 8/type2aelembytes(bt);
 1029 }
 1030 
 1031 // ARM doesn't support misaligned vectors store/load.
 1032 const bool Matcher::misaligned_vectors_ok() {
 1033   return false;
 1034 }
 1035 
 1036 // ARM doesn't support AES intrinsics
 1037 const bool Matcher::pass_original_key_for_aes() {
 1038   return false;
 1039 }
 1040 
 1041 const bool Matcher::convL2FSupported(void) {
 1042   return false;
 1043 }
 1044 
 1045 // Is this branch offset short enough that a short branch can be used?
 1046 //
 1047 // NOTE: If the platform does not provide any short branch variants, then
 1048 //       this method should return false for offset 0.
 1049 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
 1050   // The passed offset is relative to address of the branch.
 1051   // On ARM a branch displacement is calculated relative to address
 1052   // of the branch + 8.
 1053   //
 1054   // offset -= 8;
 1055   // return (Assembler::is_simm24(offset));
 1056   return false;
 1057 }
 1058 
 1059 const bool Matcher::isSimpleConstant64(jlong value) {
 1060   // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
 1061   return false;
 1062 }
 1063 
 1064 // No scaling for the parameter the ClearArray node.
 1065 const bool Matcher::init_array_count_is_in_bytes = true;
 1066 
 1067 // Needs 2 CMOV's for longs.
 1068 const int Matcher::long_cmove_cost() { return 2; }
 1069 
 1070 // CMOVF/CMOVD are expensive on ARM.
 1071 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
 1072 
 1073 // Does the CPU require late expand (see block.cpp for description of late expand)?
 1074 const bool Matcher::require_postalloc_expand = false;
 1075 
 1076 // Do we need to mask the count passed to shift instructions or does
 1077 // the cpu only look at the lower 5/6 bits anyway?
 1078 // FIXME: does this handle vector shifts as well?
 1079 const bool Matcher::need_masked_shift_count = true;
 1080 
 1081 const bool Matcher::convi2l_type_required = true;
 1082 
 1083 // No support for generic vector operands.
 1084 const bool Matcher::supports_generic_vector_operands  = false;
 1085 
 1086 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) {
 1087   ShouldNotReachHere(); // generic vector operands not supported
 1088   return NULL;
 1089 }
 1090 
 1091 bool Matcher::is_generic_reg2reg_move(MachNode* m) {
 1092   ShouldNotReachHere();  // generic vector operands not supported
 1093   return false;
 1094 }
 1095 
 1096 bool Matcher::is_generic_vector(MachOper* opnd)  {
 1097   ShouldNotReachHere();  // generic vector operands not supported
 1098   return false;
 1099 }
 1100 
 1101 // Should the matcher clone input 'm' of node 'n'?
 1102 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
 1103   if (is_vshift_con_pattern(n, m)) { // ShiftV src (ShiftCntV con)
 1104     mstack.push(m, Visit);           // m = ShiftCntV
 1105     return true;
 1106   }
 1107   return false;
 1108 }
 1109 
 1110 // Should the Matcher clone shifts on addressing modes, expecting them
 1111 // to be subsumed into complex addressing expressions or compute them
 1112 // into registers?
 1113 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
 1114   return clone_base_plus_offset_address(m, mstack, address_visited);
 1115 }
 1116 
 1117 void Compile::reshape_address(AddPNode* addp) {
 1118 }
 1119 
 1120 bool Matcher::narrow_oop_use_complex_address() {
 1121   NOT_LP64(ShouldNotCallThis());
 1122   assert(UseCompressedOops, "only for compressed oops code");
 1123   return false;
 1124 }
 1125 
 1126 bool Matcher::narrow_klass_use_complex_address() {
 1127   NOT_LP64(ShouldNotCallThis());
 1128   assert(UseCompressedClassPointers, "only for compressed klass code");
 1129   return false;
 1130 }
 1131 
 1132 bool Matcher::const_oop_prefer_decode() {
 1133   NOT_LP64(ShouldNotCallThis());
 1134   return true;
 1135 }
 1136 
 1137 bool Matcher::const_klass_prefer_decode() {
 1138   NOT_LP64(ShouldNotCallThis());
 1139   return true;
 1140 }
 1141 
 1142 // Is it better to copy float constants, or load them directly from memory?
 1143 // Intel can load a float constant from a direct address, requiring no
 1144 // extra registers.  Most RISCs will have to materialize an address into a
 1145 // register first, so they would do better to copy the constant from stack.
 1146 const bool Matcher::rematerialize_float_constants = false;
 1147 
 1148 // If CPU can load and store mis-aligned doubles directly then no fixup is
 1149 // needed.  Else we split the double into 2 integer pieces and move it
 1150 // piece-by-piece.  Only happens when passing doubles into C code as the
 1151 // Java calling convention forces doubles to be aligned.
 1152 const bool Matcher::misaligned_doubles_ok = false;
 1153 
 1154 // No-op on ARM.
 1155 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {
 1156 }
 1157 
 1158 // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode.
 1159 const bool Matcher::strict_fp_requires_explicit_rounding = false;
 1160 
 1161 // Are floats converted to double when stored to stack during deoptimization?
 1162 // ARM does not handle callee-save floats.
 1163 bool Matcher::float_in_double() {
 1164   return false;
 1165 }
 1166 
 1167 // Do ints take an entire long register or just half?
 1168 // Note that we if-def off of _LP64.
 1169 // The relevant question is how the int is callee-saved.  In _LP64
 1170 // the whole long is written but de-opt'ing will have to extract
 1171 // the relevant 32 bits, in not-_LP64 only the low 32 bits is written.
 1172 #ifdef _LP64
 1173 const bool Matcher::int_in_long = true;
 1174 #else
 1175 const bool Matcher::int_in_long = false;
 1176 #endif
 1177 
 1178 // Return whether or not this register is ever used as an argument.  This
 1179 // function is used on startup to build the trampoline stubs in generateOptoStub.
 1180 // Registers not mentioned will be killed by the VM call in the trampoline, and
 1181 // arguments in those registers not be available to the callee.
 1182 bool Matcher::can_be_java_arg( int reg ) {
 1183   if (reg == R_R0_num ||
 1184       reg == R_R1_num ||
 1185       reg == R_R2_num ||
 1186       reg == R_R3_num) return true;
 1187 
 1188   if (reg >= R_S0_num &&
 1189       reg <= R_S13_num) return true;
 1190   return false;
 1191 }
 1192 
 1193 bool Matcher::is_spillable_arg( int reg ) {
 1194   return can_be_java_arg(reg);
 1195 }
 1196 
 1197 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
 1198   return false;
 1199 }
 1200 
 1201 // Register for DIVI projection of divmodI
 1202 RegMask Matcher::divI_proj_mask() {
 1203   ShouldNotReachHere();
 1204   return RegMask();
 1205 }
 1206 
 1207 // Register for MODI projection of divmodI
 1208 RegMask Matcher::modI_proj_mask() {
 1209   ShouldNotReachHere();
 1210   return RegMask();
 1211 }
 1212 
 1213 // Register for DIVL projection of divmodL
 1214 RegMask Matcher::divL_proj_mask() {
 1215   ShouldNotReachHere();
 1216   return RegMask();
 1217 }
 1218 
 1219 // Register for MODL projection of divmodL
 1220 RegMask Matcher::modL_proj_mask() {
 1221   ShouldNotReachHere();
 1222   return RegMask();
 1223 }
 1224 
 1225 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
 1226   return FP_REGP_mask();
 1227 }
 1228 
 1229 bool maybe_far_call(const CallNode *n) {
 1230   return !MacroAssembler::_reachable_from_cache(n->as_Call()->entry_point());
 1231 }
 1232 
 1233 bool maybe_far_call(const MachCallNode *n) {
 1234   return !MacroAssembler::_reachable_from_cache(n->as_MachCall()->entry_point());
 1235 }
 1236 
 1237 %}
 1238 
 1239 //----------ENCODING BLOCK-----------------------------------------------------
 1240 // This block specifies the encoding classes used by the compiler to output
 1241 // byte streams.  Encoding classes are parameterized macros used by
 1242 // Machine Instruction Nodes in order to generate the bit encoding of the
 1243 // instruction.  Operands specify their base encoding interface with the
 1244 // interface keyword.  There are currently supported four interfaces,
 1245 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
 1246 // operand to generate a function which returns its register number when
 1247 // queried.   CONST_INTER causes an operand to generate a function which
 1248 // returns the value of the constant when queried.  MEMORY_INTER causes an
 1249 // operand to generate four functions which return the Base Register, the
 1250 // Index Register, the Scale Value, and the Offset Value of the operand when
 1251 // queried.  COND_INTER causes an operand to generate six functions which
 1252 // return the encoding code (ie - encoding bits for the instruction)
 1253 // associated with each basic boolean condition for a conditional instruction.
 1254 //
 1255 // Instructions specify two basic values for encoding.  Again, a function
 1256 // is available to check if the constant displacement is an oop. They use the
 1257 // ins_encode keyword to specify their encoding classes (which must be
 1258 // a sequence of enc_class names, and their parameters, specified in
 1259 // the encoding block), and they use the
 1260 // opcode keyword to specify, in order, their primary, secondary, and
 1261 // tertiary opcode.  Only the opcode sections which a particular instruction
 1262 // needs for encoding need to be specified.
 1263 encode %{
 1264   enc_class call_epilog %{
 1265     // nothing
 1266   %}
 1267 
 1268   enc_class Java_To_Runtime (method meth) %{
 1269     // CALL directly to the runtime
 1270     emit_call_reloc(cbuf, as_MachCall(), $meth, runtime_call_Relocation::spec());
 1271   %}
 1272 
 1273   enc_class Java_Static_Call (method meth) %{
 1274     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
 1275     // who we intended to call.
 1276 
 1277     if ( !_method) {
 1278       emit_call_reloc(cbuf, as_MachCall(), $meth, runtime_call_Relocation::spec());
 1279     } else {
 1280       int method_index = resolved_method_index(cbuf);
 1281       RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
 1282                                                   : static_call_Relocation::spec(method_index);
 1283       emit_call_reloc(cbuf, as_MachCall(), $meth, rspec);
 1284 
 1285       // Emit stubs for static call.
 1286       address stub = CompiledStaticCall::emit_to_interp_stub(cbuf);
 1287       if (stub == NULL) {
 1288         ciEnv::current()->record_failure("CodeCache is full");
 1289         return;
 1290       }
 1291     }
 1292   %}
 1293 
 1294   enc_class save_last_PC %{
 1295     // preserve mark
 1296     address mark = cbuf.insts()->mark();
 1297     debug_only(int off0 = cbuf.insts_size());
 1298     C2_MacroAssembler _masm(&cbuf);
 1299     int ret_addr_offset = as_MachCall()->ret_addr_offset();
 1300     __ adr(LR, mark + ret_addr_offset);
 1301     __ str(LR, Address(Rthread, JavaThread::last_Java_pc_offset()));
 1302     debug_only(int off1 = cbuf.insts_size());
 1303     assert(off1 - off0 == 2 * Assembler::InstructionSize, "correct size prediction");
 1304     // restore mark
 1305     cbuf.insts()->set_mark(mark);
 1306   %}
 1307 
 1308   enc_class preserve_SP %{
 1309     // preserve mark
 1310     address mark = cbuf.insts()->mark();
 1311     debug_only(int off0 = cbuf.insts_size());
 1312     C2_MacroAssembler _masm(&cbuf);
 1313     // FP is preserved across all calls, even compiled calls.
 1314     // Use it to preserve SP in places where the callee might change the SP.
 1315     __ mov(Rmh_SP_save, SP);
 1316     debug_only(int off1 = cbuf.insts_size());
 1317     assert(off1 - off0 == 4, "correct size prediction");
 1318     // restore mark
 1319     cbuf.insts()->set_mark(mark);
 1320   %}
 1321 
 1322   enc_class restore_SP %{
 1323     C2_MacroAssembler _masm(&cbuf);
 1324     __ mov(SP, Rmh_SP_save);
 1325   %}
 1326 
 1327   enc_class Java_Dynamic_Call (method meth) %{
 1328     C2_MacroAssembler _masm(&cbuf);
 1329     Register R8_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode());
 1330     assert(R8_ic_reg == Ricklass, "should be");
 1331     __ set_inst_mark();
 1332     __ movw(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) & 0xffff);
 1333     __ movt(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) >> 16);
 1334     address  virtual_call_oop_addr = __ inst_mark();
 1335     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
 1336     // who we intended to call.
 1337     int method_index = resolved_method_index(cbuf);
 1338     __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index));
 1339     emit_call_reloc(cbuf, as_MachCall(), $meth, RelocationHolder::none);
 1340   %}
 1341 
 1342   enc_class LdReplImmI(immI src, regD dst, iRegI tmp, int cnt, int wth) %{
 1343     // FIXME: load from constant table?
 1344     // Load a constant replicated "count" times with width "width"
 1345     int count = $cnt$$constant;
 1346     int width = $wth$$constant;
 1347     assert(count*width == 4, "sanity");
 1348     int val = $src$$constant;
 1349     if (width < 4) {
 1350       int bit_width = width * 8;
 1351       val &= (((int)1) << bit_width) - 1; // mask off sign bits
 1352       for (int i = 0; i < count - 1; i++) {
 1353         val |= (val << bit_width);
 1354       }
 1355     }
 1356     C2_MacroAssembler _masm(&cbuf);
 1357 
 1358     if (val == -1) {
 1359       __ mvn($tmp$$Register, 0);
 1360     } else if (val == 0) {
 1361       __ mov($tmp$$Register, 0);
 1362     } else {
 1363       __ movw($tmp$$Register, val & 0xffff);
 1364       __ movt($tmp$$Register, (unsigned int)val >> 16);
 1365     }
 1366     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 1367   %}
 1368 
 1369   enc_class LdReplImmF(immF src, regD dst, iRegI tmp) %{
 1370     // Replicate float con 2 times and pack into vector (8 bytes) in regD.
 1371     float fval = $src$$constant;
 1372     int val = *((int*)&fval);
 1373     C2_MacroAssembler _masm(&cbuf);
 1374 
 1375     if (val == -1) {
 1376       __ mvn($tmp$$Register, 0);
 1377     } else if (val == 0) {
 1378       __ mov($tmp$$Register, 0);
 1379     } else {
 1380       __ movw($tmp$$Register, val & 0xffff);
 1381       __ movt($tmp$$Register, (unsigned int)val >> 16);
 1382     }
 1383     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 1384   %}
 1385 
 1386   enc_class enc_String_Compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result, iRegI tmp1, iRegI tmp2) %{
 1387     Label Ldone, Lloop;
 1388     C2_MacroAssembler _masm(&cbuf);
 1389 
 1390     Register   str1_reg = $str1$$Register;
 1391     Register   str2_reg = $str2$$Register;
 1392     Register   cnt1_reg = $cnt1$$Register; // int
 1393     Register   cnt2_reg = $cnt2$$Register; // int
 1394     Register   tmp1_reg = $tmp1$$Register;
 1395     Register   tmp2_reg = $tmp2$$Register;
 1396     Register result_reg = $result$$Register;
 1397 
 1398     assert_different_registers(str1_reg, str2_reg, cnt1_reg, cnt2_reg, tmp1_reg, tmp2_reg);
 1399 
 1400     // Compute the minimum of the string lengths(str1_reg) and the
 1401     // difference of the string lengths (stack)
 1402 
 1403     // See if the lengths are different, and calculate min in str1_reg.
 1404     // Stash diff in tmp2 in case we need it for a tie-breaker.
 1405     __ subs_32(tmp2_reg, cnt1_reg, cnt2_reg);
 1406     __ mov(cnt1_reg, AsmOperand(cnt1_reg, lsl, exact_log2(sizeof(jchar)))); // scale the limit
 1407     __ mov(cnt1_reg, AsmOperand(cnt2_reg, lsl, exact_log2(sizeof(jchar))), pl); // scale the limit
 1408 
 1409     // reallocate cnt1_reg, cnt2_reg, result_reg
 1410     // Note:  limit_reg holds the string length pre-scaled by 2
 1411     Register limit_reg = cnt1_reg;
 1412     Register  chr2_reg = cnt2_reg;
 1413     Register  chr1_reg = tmp1_reg;
 1414     // str{12} are the base pointers
 1415 
 1416     // Is the minimum length zero?
 1417     __ cmp_32(limit_reg, 0);
 1418     if (result_reg != tmp2_reg) {
 1419       __ mov(result_reg, tmp2_reg, eq);
 1420     }
 1421     __ b(Ldone, eq);
 1422 
 1423     // Load first characters
 1424     __ ldrh(chr1_reg, Address(str1_reg, 0));
 1425     __ ldrh(chr2_reg, Address(str2_reg, 0));
 1426 
 1427     // Compare first characters
 1428     __ subs(chr1_reg, chr1_reg, chr2_reg);
 1429     if (result_reg != chr1_reg) {
 1430       __ mov(result_reg, chr1_reg, ne);
 1431     }
 1432     __ b(Ldone, ne);
 1433 
 1434     {
 1435       // Check after comparing first character to see if strings are equivalent
 1436       // Check if the strings start at same location
 1437       __ cmp(str1_reg, str2_reg);
 1438       // Check if the length difference is zero
 1439       __ cond_cmp(tmp2_reg, 0, eq);
 1440       __ mov(result_reg, 0, eq); // result is zero
 1441       __ b(Ldone, eq);
 1442       // Strings might not be equal
 1443     }
 1444 
 1445     __ subs(chr1_reg, limit_reg, 1 * sizeof(jchar));
 1446     if (result_reg != tmp2_reg) {
 1447       __ mov(result_reg, tmp2_reg, eq);
 1448     }
 1449     __ b(Ldone, eq);
 1450 
 1451     // Shift str1_reg and str2_reg to the end of the arrays, negate limit
 1452     __ add(str1_reg, str1_reg, limit_reg);
 1453     __ add(str2_reg, str2_reg, limit_reg);
 1454     __ neg(limit_reg, chr1_reg);  // limit = -(limit-2)
 1455 
 1456     // Compare the rest of the characters
 1457     __ bind(Lloop);
 1458     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
 1459     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
 1460     __ subs(chr1_reg, chr1_reg, chr2_reg);
 1461     if (result_reg != chr1_reg) {
 1462       __ mov(result_reg, chr1_reg, ne);
 1463     }
 1464     __ b(Ldone, ne);
 1465 
 1466     __ adds(limit_reg, limit_reg, sizeof(jchar));
 1467     __ b(Lloop, ne);
 1468 
 1469     // If strings are equal up to min length, return the length difference.
 1470     if (result_reg != tmp2_reg) {
 1471       __ mov(result_reg, tmp2_reg);
 1472     }
 1473 
 1474     // Otherwise, return the difference between the first mismatched chars.
 1475     __ bind(Ldone);
 1476   %}
 1477 
 1478   enc_class enc_String_Equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2) %{
 1479     Label Lchar, Lchar_loop, Ldone, Lequal;
 1480     C2_MacroAssembler _masm(&cbuf);
 1481 
 1482     Register   str1_reg = $str1$$Register;
 1483     Register   str2_reg = $str2$$Register;
 1484     Register    cnt_reg = $cnt$$Register; // int
 1485     Register   tmp1_reg = $tmp1$$Register;
 1486     Register   tmp2_reg = $tmp2$$Register;
 1487     Register result_reg = $result$$Register;
 1488 
 1489     assert_different_registers(str1_reg, str2_reg, cnt_reg, tmp1_reg, tmp2_reg, result_reg);
 1490 
 1491     __ cmp(str1_reg, str2_reg); //same char[] ?
 1492     __ b(Lequal, eq);
 1493 
 1494     __ cbz_32(cnt_reg, Lequal); // count == 0
 1495 
 1496     //rename registers
 1497     Register limit_reg = cnt_reg;
 1498     Register  chr1_reg = tmp1_reg;
 1499     Register  chr2_reg = tmp2_reg;
 1500 
 1501     __ logical_shift_left(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
 1502 
 1503     //check for alignment and position the pointers to the ends
 1504     __ orr(chr1_reg, str1_reg, str2_reg);
 1505     __ tst(chr1_reg, 0x3);
 1506 
 1507     // notZero means at least one not 4-byte aligned.
 1508     // We could optimize the case when both arrays are not aligned
 1509     // but it is not frequent case and it requires additional checks.
 1510     __ b(Lchar, ne);
 1511 
 1512     // Compare char[] arrays aligned to 4 bytes.
 1513     __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg,
 1514                           chr1_reg, chr2_reg, Ldone);
 1515 
 1516     __ b(Lequal); // equal
 1517 
 1518     // char by char compare
 1519     __ bind(Lchar);
 1520     __ mov(result_reg, 0);
 1521     __ add(str1_reg, limit_reg, str1_reg);
 1522     __ add(str2_reg, limit_reg, str2_reg);
 1523     __ neg(limit_reg, limit_reg); //negate count
 1524 
 1525     // Lchar_loop
 1526     __ bind(Lchar_loop);
 1527     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
 1528     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
 1529     __ cmp(chr1_reg, chr2_reg);
 1530     __ b(Ldone, ne);
 1531     __ adds(limit_reg, limit_reg, sizeof(jchar));
 1532     __ b(Lchar_loop, ne);
 1533 
 1534     __ bind(Lequal);
 1535     __ mov(result_reg, 1);  //equal
 1536 
 1537     __ bind(Ldone);
 1538   %}
 1539 
 1540   enc_class enc_Array_Equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result) %{
 1541     Label Ldone, Lloop, Lequal;
 1542     C2_MacroAssembler _masm(&cbuf);
 1543 
 1544     Register   ary1_reg = $ary1$$Register;
 1545     Register   ary2_reg = $ary2$$Register;
 1546     Register   tmp1_reg = $tmp1$$Register;
 1547     Register   tmp2_reg = $tmp2$$Register;
 1548     Register   tmp3_reg = $tmp3$$Register;
 1549     Register result_reg = $result$$Register;
 1550 
 1551     assert_different_registers(ary1_reg, ary2_reg, tmp1_reg, tmp2_reg, tmp3_reg, result_reg);
 1552 
 1553     int length_offset  = arrayOopDesc::length_offset_in_bytes();
 1554     int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
 1555 
 1556     // return true if the same array
 1557     __ teq(ary1_reg, ary2_reg);
 1558     __ mov(result_reg, 1, eq);
 1559     __ b(Ldone, eq); // equal
 1560 
 1561     __ tst(ary1_reg, ary1_reg);
 1562     __ mov(result_reg, 0, eq);
 1563     __ b(Ldone, eq);    // not equal
 1564 
 1565     __ tst(ary2_reg, ary2_reg);
 1566     __ mov(result_reg, 0, eq);
 1567     __ b(Ldone, eq);    // not equal
 1568 
 1569     //load the lengths of arrays
 1570     __ ldr_s32(tmp1_reg, Address(ary1_reg, length_offset)); // int
 1571     __ ldr_s32(tmp2_reg, Address(ary2_reg, length_offset)); // int
 1572 
 1573     // return false if the two arrays are not equal length
 1574     __ teq_32(tmp1_reg, tmp2_reg);
 1575     __ mov(result_reg, 0, ne);
 1576     __ b(Ldone, ne);    // not equal
 1577 
 1578     __ tst(tmp1_reg, tmp1_reg);
 1579     __ mov(result_reg, 1, eq);
 1580     __ b(Ldone, eq);    // zero-length arrays are equal
 1581 
 1582     // load array addresses
 1583     __ add(ary1_reg, ary1_reg, base_offset);
 1584     __ add(ary2_reg, ary2_reg, base_offset);
 1585 
 1586     // renaming registers
 1587     Register chr1_reg  =  tmp3_reg;   // for characters in ary1
 1588     Register chr2_reg  =  tmp2_reg;   // for characters in ary2
 1589     Register limit_reg =  tmp1_reg;   // length
 1590 
 1591     // set byte count
 1592     __ logical_shift_left_32(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
 1593 
 1594     // Compare char[] arrays aligned to 4 bytes.
 1595     __ char_arrays_equals(ary1_reg, ary2_reg, limit_reg, result_reg,
 1596                           chr1_reg, chr2_reg, Ldone);
 1597     __ bind(Lequal);
 1598     __ mov(result_reg, 1);  //equal
 1599 
 1600     __ bind(Ldone);
 1601     %}
 1602 %}
 1603 
 1604 //----------FRAME--------------------------------------------------------------
 1605 // Definition of frame structure and management information.
 1606 //
 1607 //  S T A C K   L A Y O U T    Allocators stack-slot number
 1608 //                             |   (to get allocators register number
 1609 //  G  Owned by    |        |  v    add VMRegImpl::stack0)
 1610 //  r   CALLER     |        |
 1611 //  o     |        +--------+      pad to even-align allocators stack-slot
 1612 //  w     V        |  pad0  |        numbers; owned by CALLER
 1613 //  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
 1614 //  h     ^        |   in   |  5
 1615 //        |        |  args  |  4   Holes in incoming args owned by SELF
 1616 //  |     |        |        |  3
 1617 //  |     |        +--------+
 1618 //  V     |        | old out|      Empty on Intel, window on Sparc
 1619 //        |    old |preserve|      Must be even aligned.
 1620 //        |     SP-+--------+----> Matcher::_old_SP, 8 (or 16 in LP64)-byte aligned
 1621 //        |        |   in   |  3   area for Intel ret address
 1622 //     Owned by    |preserve|      Empty on Sparc.
 1623 //       SELF      +--------+
 1624 //        |        |  pad2  |  2   pad to align old SP
 1625 //        |        +--------+  1
 1626 //        |        | locks  |  0
 1627 //        |        +--------+----> VMRegImpl::stack0, 8 (or 16 in LP64)-byte aligned
 1628 //        |        |  pad1  | 11   pad to align new SP
 1629 //        |        +--------+
 1630 //        |        |        | 10
 1631 //        |        | spills |  9   spills
 1632 //        V        |        |  8   (pad0 slot for callee)
 1633 //      -----------+--------+----> Matcher::_out_arg_limit, unaligned
 1634 //        ^        |  out   |  7
 1635 //        |        |  args  |  6   Holes in outgoing args owned by CALLEE
 1636 //     Owned by    +--------+
 1637 //      CALLEE     | new out|  6   Empty on Intel, window on Sparc
 1638 //        |    new |preserve|      Must be even-aligned.
 1639 //        |     SP-+--------+----> Matcher::_new_SP, even aligned
 1640 //        |        |        |
 1641 //
 1642 // Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
 1643 //         known from SELF's arguments and the Java calling convention.
 1644 //         Region 6-7 is determined per call site.
 1645 // Note 2: If the calling convention leaves holes in the incoming argument
 1646 //         area, those holes are owned by SELF.  Holes in the outgoing area
 1647 //         are owned by the CALLEE.  Holes should not be nessecary in the
 1648 //         incoming area, as the Java calling convention is completely under
 1649 //         the control of the AD file.  Doubles can be sorted and packed to
 1650 //         avoid holes.  Holes in the outgoing arguments may be nessecary for
 1651 //         varargs C calling conventions.
 1652 // Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
 1653 //         even aligned with pad0 as needed.
 1654 //         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
 1655 //         region 6-11 is even aligned; it may be padded out more so that
 1656 //         the region from SP to FP meets the minimum stack alignment.
 1657 
 1658 frame %{
 1659   // What direction does stack grow in (assumed to be same for native & Java)
 1660   stack_direction(TOWARDS_LOW);
 1661 
 1662   // These two registers define part of the calling convention
 1663   // between compiled code and the interpreter.
 1664   inline_cache_reg(R_Ricklass);          // Inline Cache Register or Method* for I2C
 1665   interpreter_method_oop_reg(R_Rmethod); // Method Oop Register when calling interpreter
 1666 
 1667   // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
 1668   cisc_spilling_operand_name(indOffset);
 1669 
 1670   // Number of stack slots consumed by a Monitor enter
 1671   sync_stack_slots(1 * VMRegImpl::slots_per_word);
 1672 
 1673   // Compiled code's Frame Pointer
 1674   frame_pointer(R_R13);
 1675 
 1676   // Stack alignment requirement
 1677   stack_alignment(StackAlignmentInBytes);
 1678   //  LP64: Alignment size in bytes (128-bit -> 16 bytes)
 1679   // !LP64: Alignment size in bytes (64-bit  ->  8 bytes)
 1680 
 1681   // Number of stack slots between incoming argument block and the start of
 1682   // a new frame.  The PROLOG must add this many slots to the stack.  The
 1683   // EPILOG must remove this many slots.
 1684   // FP + LR
 1685   in_preserve_stack_slots(2 * VMRegImpl::slots_per_word);
 1686 
 1687   // Number of outgoing stack slots killed above the out_preserve_stack_slots
 1688   // for calls to C.  Supports the var-args backing area for register parms.
 1689   // ADLC doesn't support parsing expressions, so I folded the math by hand.
 1690   varargs_C_out_slots_killed( 0);
 1691 
 1692   // The after-PROLOG location of the return address.  Location of
 1693   // return address specifies a type (REG or STACK) and a number
 1694   // representing the register number (i.e. - use a register name) or
 1695   // stack slot.
 1696   // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
 1697   // Otherwise, it is above the locks and verification slot and alignment word
 1698   return_addr(STACK - 1*VMRegImpl::slots_per_word +
 1699               align_up((Compile::current()->in_preserve_stack_slots() +
 1700                         Compile::current()->fixed_slots()),
 1701                        stack_alignment_in_slots()));
 1702 
 1703   // Body of function which returns an OptoRegs array locating
 1704   // arguments either in registers or in stack slots for calling
 1705   // java
 1706   calling_convention %{
 1707     (void) SharedRuntime::java_calling_convention(sig_bt, regs, length, is_outgoing);
 1708 
 1709   %}
 1710 
 1711   // Body of function which returns an OptoRegs array locating
 1712   // arguments either in registers or in stack slots for callin
 1713   // C.
 1714   c_calling_convention %{
 1715     // This is obviously always outgoing
 1716     (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
 1717   %}
 1718 
 1719   // Location of compiled Java return values.  Same as C
 1720   return_value %{
 1721     return c2::return_value(ideal_reg);
 1722   %}
 1723 
 1724 %}
 1725 
 1726 //----------ATTRIBUTES---------------------------------------------------------
 1727 //----------Instruction Attributes---------------------------------------------
 1728 ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute
 1729 ins_attrib ins_size(32);           // Required size attribute (in bits)
 1730 ins_attrib ins_short_branch(0);    // Required flag: is this instruction a
 1731                                    // non-matching short branch variant of some
 1732                                                             // long branch?
 1733 
 1734 //----------OPERANDS-----------------------------------------------------------
 1735 // Operand definitions must precede instruction definitions for correct parsing
 1736 // in the ADLC because operands constitute user defined types which are used in
 1737 // instruction definitions.
 1738 
 1739 //----------Simple Operands----------------------------------------------------
 1740 // Immediate Operands
 1741 // Integer Immediate: 32-bit
 1742 operand immI() %{
 1743   match(ConI);
 1744 
 1745   op_cost(0);
 1746   // formats are generated automatically for constants and base registers
 1747   format %{ %}
 1748   interface(CONST_INTER);
 1749 %}
 1750 
 1751 // Integer Immediate: 8-bit unsigned - for VMOV
 1752 operand immU8() %{
 1753   predicate(0 <= n->get_int() && (n->get_int() <= 255));
 1754   match(ConI);
 1755   op_cost(0);
 1756 
 1757   format %{ %}
 1758   interface(CONST_INTER);
 1759 %}
 1760 
 1761 // Integer Immediate: 16-bit
 1762 operand immI16() %{
 1763   predicate((n->get_int() >> 16) == 0 && VM_Version::supports_movw());
 1764   match(ConI);
 1765   op_cost(0);
 1766 
 1767   format %{ %}
 1768   interface(CONST_INTER);
 1769 %}
 1770 
 1771 // Integer Immediate: offset for half and double word loads and stores
 1772 operand immIHD() %{
 1773   predicate(is_memoryHD(n->get_int()));
 1774   match(ConI);
 1775   op_cost(0);
 1776   format %{ %}
 1777   interface(CONST_INTER);
 1778 %}
 1779 
 1780 // Integer Immediate: offset for fp loads and stores
 1781 operand immIFP() %{
 1782   predicate(is_memoryfp(n->get_int()) && ((n->get_int() & 3) == 0));
 1783   match(ConI);
 1784   op_cost(0);
 1785 
 1786   format %{ %}
 1787   interface(CONST_INTER);
 1788 %}
 1789 
 1790 // Valid scale values for addressing modes and shifts
 1791 operand immU5() %{
 1792   predicate(0 <= n->get_int() && (n->get_int() <= 31));
 1793   match(ConI);
 1794   op_cost(0);
 1795 
 1796   format %{ %}
 1797   interface(CONST_INTER);
 1798 %}
 1799 
 1800 // Integer Immediate: 6-bit
 1801 operand immU6Big() %{
 1802   predicate(n->get_int() >= 32 && n->get_int() <= 63);
 1803   match(ConI);
 1804   op_cost(0);
 1805   format %{ %}
 1806   interface(CONST_INTER);
 1807 %}
 1808 
 1809 // Integer Immediate: 0-bit
 1810 operand immI0() %{
 1811   predicate(n->get_int() == 0);
 1812   match(ConI);
 1813   op_cost(0);
 1814 
 1815   format %{ %}
 1816   interface(CONST_INTER);
 1817 %}
 1818 
 1819 // Integer Immediate: the value 1
 1820 operand immI_1() %{
 1821   predicate(n->get_int() == 1);
 1822   match(ConI);
 1823   op_cost(0);
 1824 
 1825   format %{ %}
 1826   interface(CONST_INTER);
 1827 %}
 1828 
 1829 // Integer Immediate: the value 2
 1830 operand immI_2() %{
 1831   predicate(n->get_int() == 2);
 1832   match(ConI);
 1833   op_cost(0);
 1834 
 1835   format %{ %}
 1836   interface(CONST_INTER);
 1837 %}
 1838 
 1839 // Integer Immediate: the value 3
 1840 operand immI_3() %{
 1841   predicate(n->get_int() == 3);
 1842   match(ConI);
 1843   op_cost(0);
 1844 
 1845   format %{ %}
 1846   interface(CONST_INTER);
 1847 %}
 1848 
 1849 // Integer Immediate: the value 4
 1850 operand immI_4() %{
 1851   predicate(n->get_int() == 4);
 1852   match(ConI);
 1853   op_cost(0);
 1854 
 1855   format %{ %}
 1856   interface(CONST_INTER);
 1857 %}
 1858 
 1859 // Integer Immediate: the value 8
 1860 operand immI_8() %{
 1861   predicate(n->get_int() == 8);
 1862   match(ConI);
 1863   op_cost(0);
 1864 
 1865   format %{ %}
 1866   interface(CONST_INTER);
 1867 %}
 1868 
 1869 // Int Immediate non-negative
 1870 operand immU31()
 1871 %{
 1872   predicate(n->get_int() >= 0);
 1873   match(ConI);
 1874 
 1875   op_cost(0);
 1876   format %{ %}
 1877   interface(CONST_INTER);
 1878 %}
 1879 
 1880 // Integer Immediate: the values 32-63
 1881 operand immI_32_63() %{
 1882   predicate(n->get_int() >= 32 && n->get_int() <= 63);
 1883   match(ConI);
 1884   op_cost(0);
 1885 
 1886   format %{ %}
 1887   interface(CONST_INTER);
 1888 %}
 1889 
 1890 // Immediates for special shifts (sign extend)
 1891 
 1892 // Integer Immediate: the value 16
 1893 operand immI_16() %{
 1894   predicate(n->get_int() == 16);
 1895   match(ConI);
 1896   op_cost(0);
 1897 
 1898   format %{ %}
 1899   interface(CONST_INTER);
 1900 %}
 1901 
 1902 // Integer Immediate: the value 24
 1903 operand immI_24() %{
 1904   predicate(n->get_int() == 24);
 1905   match(ConI);
 1906   op_cost(0);
 1907 
 1908   format %{ %}
 1909   interface(CONST_INTER);
 1910 %}
 1911 
 1912 // Integer Immediate: the value 255
 1913 operand immI_255() %{
 1914   predicate( n->get_int() == 255 );
 1915   match(ConI);
 1916   op_cost(0);
 1917 
 1918   format %{ %}
 1919   interface(CONST_INTER);
 1920 %}
 1921 
 1922 // Integer Immediate: the value 65535
 1923 operand immI_65535() %{
 1924   predicate(n->get_int() == 65535);
 1925   match(ConI);
 1926   op_cost(0);
 1927 
 1928   format %{ %}
 1929   interface(CONST_INTER);
 1930 %}
 1931 
 1932 // Integer Immediates for arithmetic instructions
 1933 
 1934 operand aimmI() %{
 1935   predicate(is_aimm(n->get_int()));
 1936   match(ConI);
 1937   op_cost(0);
 1938 
 1939   format %{ %}
 1940   interface(CONST_INTER);
 1941 %}
 1942 
 1943 operand aimmIneg() %{
 1944   predicate(is_aimm(-n->get_int()));
 1945   match(ConI);
 1946   op_cost(0);
 1947 
 1948   format %{ %}
 1949   interface(CONST_INTER);
 1950 %}
 1951 
 1952 operand aimmU31() %{
 1953   predicate((0 <= n->get_int()) && is_aimm(n->get_int()));
 1954   match(ConI);
 1955   op_cost(0);
 1956 
 1957   format %{ %}
 1958   interface(CONST_INTER);
 1959 %}
 1960 
 1961 // Integer Immediates for logical instructions
 1962 
 1963 operand limmI() %{
 1964   predicate(is_limmI(n->get_int()));
 1965   match(ConI);
 1966   op_cost(0);
 1967 
 1968   format %{ %}
 1969   interface(CONST_INTER);
 1970 %}
 1971 
 1972 operand limmIlow8() %{
 1973   predicate(is_limmI_low(n->get_int(), 8));
 1974   match(ConI);
 1975   op_cost(0);
 1976 
 1977   format %{ %}
 1978   interface(CONST_INTER);
 1979 %}
 1980 
 1981 operand limmU31() %{
 1982   predicate(0 <= n->get_int() && is_limmI(n->get_int()));
 1983   match(ConI);
 1984   op_cost(0);
 1985 
 1986   format %{ %}
 1987   interface(CONST_INTER);
 1988 %}
 1989 
 1990 operand limmIn() %{
 1991   predicate(is_limmI(~n->get_int()));
 1992   match(ConI);
 1993   op_cost(0);
 1994 
 1995   format %{ %}
 1996   interface(CONST_INTER);
 1997 %}
 1998 
 1999 
 2000 // Long Immediate: the value FF
 2001 operand immL_FF() %{
 2002   predicate( n->get_long() == 0xFFL );
 2003   match(ConL);
 2004   op_cost(0);
 2005 
 2006   format %{ %}
 2007   interface(CONST_INTER);
 2008 %}
 2009 
 2010 // Long Immediate: the value FFFF
 2011 operand immL_FFFF() %{
 2012   predicate( n->get_long() == 0xFFFFL );
 2013   match(ConL);
 2014   op_cost(0);
 2015 
 2016   format %{ %}
 2017   interface(CONST_INTER);
 2018 %}
 2019 
 2020 // Pointer Immediate: 32 or 64-bit
 2021 operand immP() %{
 2022   match(ConP);
 2023 
 2024   op_cost(5);
 2025   // formats are generated automatically for constants and base registers
 2026   format %{ %}
 2027   interface(CONST_INTER);
 2028 %}
 2029 
 2030 operand immP0() %{
 2031   predicate(n->get_ptr() == 0);
 2032   match(ConP);
 2033   op_cost(0);
 2034 
 2035   format %{ %}
 2036   interface(CONST_INTER);
 2037 %}
 2038 
 2039 // Pointer Immediate
 2040 operand immN()
 2041 %{
 2042   match(ConN);
 2043 
 2044   op_cost(10);
 2045   format %{ %}
 2046   interface(CONST_INTER);
 2047 %}
 2048 
 2049 operand immNKlass()
 2050 %{
 2051   match(ConNKlass);
 2052 
 2053   op_cost(10);
 2054   format %{ %}
 2055   interface(CONST_INTER);
 2056 %}
 2057 
 2058 // NULL Pointer Immediate
 2059 operand immN0()
 2060 %{
 2061   predicate(n->get_narrowcon() == 0);
 2062   match(ConN);
 2063 
 2064   op_cost(0);
 2065   format %{ %}
 2066   interface(CONST_INTER);
 2067 %}
 2068 
 2069 operand immL() %{
 2070   match(ConL);
 2071   op_cost(40);
 2072   // formats are generated automatically for constants and base registers
 2073   format %{ %}
 2074   interface(CONST_INTER);
 2075 %}
 2076 
 2077 operand immL0() %{
 2078   predicate(n->get_long() == 0L);
 2079   match(ConL);
 2080   op_cost(0);
 2081   // formats are generated automatically for constants and base registers
 2082   format %{ %}
 2083   interface(CONST_INTER);
 2084 %}
 2085 
 2086 // Long Immediate: 16-bit
 2087 operand immL16() %{
 2088   predicate(n->get_long() >= 0 && n->get_long() < (1<<16)  && VM_Version::supports_movw());
 2089   match(ConL);
 2090   op_cost(0);
 2091 
 2092   format %{ %}
 2093   interface(CONST_INTER);
 2094 %}
 2095 
 2096 // Long Immediate: low 32-bit mask
 2097 operand immL_32bits() %{
 2098   predicate(n->get_long() == 0xFFFFFFFFL);
 2099   match(ConL);
 2100   op_cost(0);
 2101 
 2102   format %{ %}
 2103   interface(CONST_INTER);
 2104 %}
 2105 
 2106 // Double Immediate
 2107 operand immD() %{
 2108   match(ConD);
 2109 
 2110   op_cost(40);
 2111   format %{ %}
 2112   interface(CONST_INTER);
 2113 %}
 2114 
 2115 // Double Immediate: +0.0d.
 2116 operand immD0() %{
 2117   predicate(jlong_cast(n->getd()) == 0);
 2118 
 2119   match(ConD);
 2120   op_cost(0);
 2121   format %{ %}
 2122   interface(CONST_INTER);
 2123 %}
 2124 
 2125 operand imm8D() %{
 2126   predicate(Assembler::double_num(n->getd()).can_be_imm8());
 2127   match(ConD);
 2128 
 2129   op_cost(0);
 2130   format %{ %}
 2131   interface(CONST_INTER);
 2132 %}
 2133 
 2134 // Float Immediate
 2135 operand immF() %{
 2136   match(ConF);
 2137 
 2138   op_cost(20);
 2139   format %{ %}
 2140   interface(CONST_INTER);
 2141 %}
 2142 
 2143 // Float Immediate: +0.0f
 2144 operand immF0() %{
 2145   predicate(jint_cast(n->getf()) == 0);
 2146   match(ConF);
 2147 
 2148   op_cost(0);
 2149   format %{ %}
 2150   interface(CONST_INTER);
 2151 %}
 2152 
 2153 // Float Immediate: encoded as 8 bits
 2154 operand imm8F() %{
 2155   predicate(Assembler::float_num(n->getf()).can_be_imm8());
 2156   match(ConF);
 2157 
 2158   op_cost(0);
 2159   format %{ %}
 2160   interface(CONST_INTER);
 2161 %}
 2162 
 2163 // Integer Register Operands
 2164 // Integer Register
 2165 operand iRegI() %{
 2166   constraint(ALLOC_IN_RC(int_reg));
 2167   match(RegI);
 2168   match(R0RegI);
 2169   match(R1RegI);
 2170   match(R2RegI);
 2171   match(R3RegI);
 2172   match(R12RegI);
 2173 
 2174   format %{ %}
 2175   interface(REG_INTER);
 2176 %}
 2177 
 2178 // Pointer Register
 2179 operand iRegP() %{
 2180   constraint(ALLOC_IN_RC(ptr_reg));
 2181   match(RegP);
 2182   match(R0RegP);
 2183   match(R1RegP);
 2184   match(R2RegP);
 2185   match(RExceptionRegP);
 2186   match(R8RegP);
 2187   match(R9RegP);
 2188   match(RthreadRegP); // FIXME: move to sp_ptr_RegP?
 2189   match(R12RegP);
 2190   match(LRRegP);
 2191 
 2192   match(sp_ptr_RegP);
 2193   match(store_ptr_RegP);
 2194 
 2195   format %{ %}
 2196   interface(REG_INTER);
 2197 %}
 2198 
 2199 // GPRs + Rthread + SP
 2200 operand sp_ptr_RegP() %{
 2201   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2202   match(RegP);
 2203   match(iRegP);
 2204   match(SPRegP); // FIXME: check cost
 2205 
 2206   format %{ %}
 2207   interface(REG_INTER);
 2208 %}
 2209 
 2210 
 2211 operand R0RegP() %{
 2212   constraint(ALLOC_IN_RC(R0_regP));
 2213   match(iRegP);
 2214 
 2215   format %{ %}
 2216   interface(REG_INTER);
 2217 %}
 2218 
 2219 operand R1RegP() %{
 2220   constraint(ALLOC_IN_RC(R1_regP));
 2221   match(iRegP);
 2222 
 2223   format %{ %}
 2224   interface(REG_INTER);
 2225 %}
 2226 
 2227 operand R8RegP() %{
 2228   constraint(ALLOC_IN_RC(R8_regP));
 2229   match(iRegP);
 2230 
 2231   format %{ %}
 2232   interface(REG_INTER);
 2233 %}
 2234 
 2235 operand R9RegP() %{
 2236   constraint(ALLOC_IN_RC(R9_regP));
 2237   match(iRegP);
 2238 
 2239   format %{ %}
 2240   interface(REG_INTER);
 2241 %}
 2242 
 2243 operand R12RegP() %{
 2244   constraint(ALLOC_IN_RC(R12_regP));
 2245   match(iRegP);
 2246 
 2247   format %{ %}
 2248   interface(REG_INTER);
 2249 %}
 2250 
 2251 operand R2RegP() %{
 2252   constraint(ALLOC_IN_RC(R2_regP));
 2253   match(iRegP);
 2254 
 2255   format %{ %}
 2256   interface(REG_INTER);
 2257 %}
 2258 
 2259 operand RExceptionRegP() %{
 2260   constraint(ALLOC_IN_RC(Rexception_regP));
 2261   match(iRegP);
 2262 
 2263   format %{ %}
 2264   interface(REG_INTER);
 2265 %}
 2266 
 2267 operand RthreadRegP() %{
 2268   constraint(ALLOC_IN_RC(Rthread_regP));
 2269   match(iRegP);
 2270 
 2271   format %{ %}
 2272   interface(REG_INTER);
 2273 %}
 2274 
 2275 operand IPRegP() %{
 2276   constraint(ALLOC_IN_RC(IP_regP));
 2277   match(iRegP);
 2278 
 2279   format %{ %}
 2280   interface(REG_INTER);
 2281 %}
 2282 
 2283 operand SPRegP() %{
 2284   constraint(ALLOC_IN_RC(SP_regP));
 2285   match(iRegP);
 2286 
 2287   format %{ %}
 2288   interface(REG_INTER);
 2289 %}
 2290 
 2291 operand LRRegP() %{
 2292   constraint(ALLOC_IN_RC(LR_regP));
 2293   match(iRegP);
 2294 
 2295   format %{ %}
 2296   interface(REG_INTER);
 2297 %}
 2298 
 2299 operand R0RegI() %{
 2300   constraint(ALLOC_IN_RC(R0_regI));
 2301   match(iRegI);
 2302 
 2303   format %{ %}
 2304   interface(REG_INTER);
 2305 %}
 2306 
 2307 operand R1RegI() %{
 2308   constraint(ALLOC_IN_RC(R1_regI));
 2309   match(iRegI);
 2310 
 2311   format %{ %}
 2312   interface(REG_INTER);
 2313 %}
 2314 
 2315 operand R2RegI() %{
 2316   constraint(ALLOC_IN_RC(R2_regI));
 2317   match(iRegI);
 2318 
 2319   format %{ %}
 2320   interface(REG_INTER);
 2321 %}
 2322 
 2323 operand R3RegI() %{
 2324   constraint(ALLOC_IN_RC(R3_regI));
 2325   match(iRegI);
 2326 
 2327   format %{ %}
 2328   interface(REG_INTER);
 2329 %}
 2330 
 2331 operand R12RegI() %{
 2332   constraint(ALLOC_IN_RC(R12_regI));
 2333   match(iRegI);
 2334 
 2335   format %{ %}
 2336   interface(REG_INTER);
 2337 %}
 2338 
 2339 // Long Register
 2340 operand iRegL() %{
 2341   constraint(ALLOC_IN_RC(long_reg));
 2342   match(RegL);
 2343   match(R0R1RegL);
 2344   match(R2R3RegL);
 2345 //match(iRegLex);
 2346 
 2347   format %{ %}
 2348   interface(REG_INTER);
 2349 %}
 2350 
 2351 operand iRegLd() %{
 2352   constraint(ALLOC_IN_RC(long_reg_align));
 2353   match(iRegL); // FIXME: allows unaligned R11/R12?
 2354 
 2355   format %{ %}
 2356   interface(REG_INTER);
 2357 %}
 2358 
 2359 // first long arg, or return value
 2360 operand R0R1RegL() %{
 2361   constraint(ALLOC_IN_RC(R0R1_regL));
 2362   match(iRegL);
 2363 
 2364   format %{ %}
 2365   interface(REG_INTER);
 2366 %}
 2367 
 2368 operand R2R3RegL() %{
 2369   constraint(ALLOC_IN_RC(R2R3_regL));
 2370   match(iRegL);
 2371 
 2372   format %{ %}
 2373   interface(REG_INTER);
 2374 %}
 2375 
 2376 // Condition Code Flag Register
 2377 operand flagsReg() %{
 2378   constraint(ALLOC_IN_RC(int_flags));
 2379   match(RegFlags);
 2380 
 2381   format %{ "apsr" %}
 2382   interface(REG_INTER);
 2383 %}
 2384 
 2385 // Result of compare to 0 (TST)
 2386 operand flagsReg_EQNELTGE() %{
 2387   constraint(ALLOC_IN_RC(int_flags));
 2388   match(RegFlags);
 2389 
 2390   format %{ "apsr_EQNELTGE" %}
 2391   interface(REG_INTER);
 2392 %}
 2393 
 2394 // Condition Code Register, unsigned comparisons.
 2395 operand flagsRegU() %{
 2396   constraint(ALLOC_IN_RC(int_flags));
 2397   match(RegFlags);
 2398 #ifdef TODO
 2399   match(RegFlagsP);
 2400 #endif
 2401 
 2402   format %{ "apsr_U" %}
 2403   interface(REG_INTER);
 2404 %}
 2405 
 2406 // Condition Code Register, pointer comparisons.
 2407 operand flagsRegP() %{
 2408   constraint(ALLOC_IN_RC(int_flags));
 2409   match(RegFlags);
 2410 
 2411   format %{ "apsr_P" %}
 2412   interface(REG_INTER);
 2413 %}
 2414 
 2415 // Condition Code Register, long comparisons.
 2416 operand flagsRegL_LTGE() %{
 2417   constraint(ALLOC_IN_RC(int_flags));
 2418   match(RegFlags);
 2419 
 2420   format %{ "apsr_L_LTGE" %}
 2421   interface(REG_INTER);
 2422 %}
 2423 
 2424 operand flagsRegL_EQNE() %{
 2425   constraint(ALLOC_IN_RC(int_flags));
 2426   match(RegFlags);
 2427 
 2428   format %{ "apsr_L_EQNE" %}
 2429   interface(REG_INTER);
 2430 %}
 2431 
 2432 operand flagsRegL_LEGT() %{
 2433   constraint(ALLOC_IN_RC(int_flags));
 2434   match(RegFlags);
 2435 
 2436   format %{ "apsr_L_LEGT" %}
 2437   interface(REG_INTER);
 2438 %}
 2439 
 2440 operand flagsRegUL_LTGE() %{
 2441   constraint(ALLOC_IN_RC(int_flags));
 2442   match(RegFlags);
 2443 
 2444   format %{ "apsr_UL_LTGE" %}
 2445   interface(REG_INTER);
 2446 %}
 2447 
 2448 operand flagsRegUL_EQNE() %{
 2449   constraint(ALLOC_IN_RC(int_flags));
 2450   match(RegFlags);
 2451 
 2452   format %{ "apsr_UL_EQNE" %}
 2453   interface(REG_INTER);
 2454 %}
 2455 
 2456 operand flagsRegUL_LEGT() %{
 2457   constraint(ALLOC_IN_RC(int_flags));
 2458   match(RegFlags);
 2459 
 2460   format %{ "apsr_UL_LEGT" %}
 2461   interface(REG_INTER);
 2462 %}
 2463 
 2464 // Condition Code Register, floating comparisons, unordered same as "less".
 2465 operand flagsRegF() %{
 2466   constraint(ALLOC_IN_RC(float_flags));
 2467   match(RegFlags);
 2468 
 2469   format %{ "fpscr_F" %}
 2470   interface(REG_INTER);
 2471 %}
 2472 
 2473 // Vectors
 2474 operand vecD() %{
 2475   constraint(ALLOC_IN_RC(actual_dflt_reg));
 2476   match(VecD);
 2477 
 2478   format %{ %}
 2479   interface(REG_INTER);
 2480 %}
 2481 
 2482 operand vecX() %{
 2483   constraint(ALLOC_IN_RC(vectorx_reg));
 2484   match(VecX);
 2485 
 2486   format %{ %}
 2487   interface(REG_INTER);
 2488 %}
 2489 
 2490 operand regD() %{
 2491   constraint(ALLOC_IN_RC(actual_dflt_reg));
 2492   match(RegD);
 2493   match(regD_low);
 2494 
 2495   format %{ %}
 2496   interface(REG_INTER);
 2497 %}
 2498 
 2499 operand regF() %{
 2500   constraint(ALLOC_IN_RC(sflt_reg));
 2501   match(RegF);
 2502 
 2503   format %{ %}
 2504   interface(REG_INTER);
 2505 %}
 2506 
 2507 operand regD_low() %{
 2508   constraint(ALLOC_IN_RC(dflt_low_reg));
 2509   match(RegD);
 2510 
 2511   format %{ %}
 2512   interface(REG_INTER);
 2513 %}
 2514 
 2515 // Special Registers
 2516 
 2517 // Method Register
 2518 operand inline_cache_regP(iRegP reg) %{
 2519   constraint(ALLOC_IN_RC(Ricklass_regP));
 2520   match(reg);
 2521   format %{ %}
 2522   interface(REG_INTER);
 2523 %}
 2524 
 2525 operand interpreter_method_oop_regP(iRegP reg) %{
 2526   constraint(ALLOC_IN_RC(Rmethod_regP));
 2527   match(reg);
 2528   format %{ %}
 2529   interface(REG_INTER);
 2530 %}
 2531 
 2532 
 2533 //----------Complex Operands---------------------------------------------------
 2534 // Indirect Memory Reference
 2535 operand indirect(sp_ptr_RegP reg) %{
 2536   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2537   match(reg);
 2538 
 2539   op_cost(100);
 2540   format %{ "[$reg]" %}
 2541   interface(MEMORY_INTER) %{
 2542     base($reg);
 2543     index(0xf); // PC => no index
 2544     scale(0x0);
 2545     disp(0x0);
 2546   %}
 2547 %}
 2548 
 2549 
 2550 // Indirect with Offset in ]-4096, 4096[
 2551 operand indOffset12(sp_ptr_RegP reg, immI12 offset) %{
 2552   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2553   match(AddP reg offset);
 2554 
 2555   op_cost(100);
 2556   format %{ "[$reg + $offset]" %}
 2557   interface(MEMORY_INTER) %{
 2558     base($reg);
 2559     index(0xf); // PC => no index
 2560     scale(0x0);
 2561     disp($offset);
 2562   %}
 2563 %}
 2564 
 2565 // Indirect with offset for float load/store
 2566 operand indOffsetFP(sp_ptr_RegP reg, immIFP offset) %{
 2567   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2568   match(AddP reg offset);
 2569 
 2570   op_cost(100);
 2571   format %{ "[$reg + $offset]" %}
 2572   interface(MEMORY_INTER) %{
 2573     base($reg);
 2574     index(0xf); // PC => no index
 2575     scale(0x0);
 2576     disp($offset);
 2577   %}
 2578 %}
 2579 
 2580 // Indirect with Offset for half and double words
 2581 operand indOffsetHD(sp_ptr_RegP reg, immIHD offset) %{
 2582   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2583   match(AddP reg offset);
 2584 
 2585   op_cost(100);
 2586   format %{ "[$reg + $offset]" %}
 2587   interface(MEMORY_INTER) %{
 2588     base($reg);
 2589     index(0xf); // PC => no index
 2590     scale(0x0);
 2591     disp($offset);
 2592   %}
 2593 %}
 2594 
 2595 // Indirect with Offset and Offset+4 in ]-1024, 1024[
 2596 operand indOffsetFPx2(sp_ptr_RegP reg, immX10x2 offset) %{
 2597   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2598   match(AddP reg offset);
 2599 
 2600   op_cost(100);
 2601   format %{ "[$reg + $offset]" %}
 2602   interface(MEMORY_INTER) %{
 2603     base($reg);
 2604     index(0xf); // PC => no index
 2605     scale(0x0);
 2606     disp($offset);
 2607   %}
 2608 %}
 2609 
 2610 // Indirect with Offset and Offset+4 in ]-4096, 4096[
 2611 operand indOffset12x2(sp_ptr_RegP reg, immI12x2 offset) %{
 2612   constraint(ALLOC_IN_RC(sp_ptr_reg));
 2613   match(AddP reg offset);
 2614 
 2615   op_cost(100);
 2616   format %{ "[$reg + $offset]" %}
 2617   interface(MEMORY_INTER) %{
 2618     base($reg);
 2619     index(0xf); // PC => no index
 2620     scale(0x0);
 2621     disp($offset);
 2622   %}
 2623 %}
 2624 
 2625 // Indirect with Register Index
 2626 operand indIndex(iRegP addr, iRegX index) %{
 2627   constraint(ALLOC_IN_RC(ptr_reg));
 2628   match(AddP addr index);
 2629 
 2630   op_cost(100);
 2631   format %{ "[$addr + $index]" %}
 2632   interface(MEMORY_INTER) %{
 2633     base($addr);
 2634     index($index);
 2635     scale(0x0);
 2636     disp(0x0);
 2637   %}
 2638 %}
 2639 
 2640 // Indirect Memory Times Scale Plus Index Register
 2641 operand indIndexScale(iRegP addr, iRegX index, immU5 scale) %{
 2642   constraint(ALLOC_IN_RC(ptr_reg));
 2643   match(AddP addr (LShiftX index scale));
 2644 
 2645   op_cost(100);
 2646   format %{"[$addr + $index << $scale]" %}
 2647   interface(MEMORY_INTER) %{
 2648     base($addr);
 2649     index($index);
 2650     scale($scale);
 2651     disp(0x0);
 2652   %}
 2653 %}
 2654 
 2655 // Operands for expressing Control Flow
 2656 // NOTE:  Label is a predefined operand which should not be redefined in
 2657 //        the AD file.  It is generically handled within the ADLC.
 2658 
 2659 //----------Conditional Branch Operands----------------------------------------
 2660 // Comparison Op  - This is the operation of the comparison, and is limited to
 2661 //                  the following set of codes:
 2662 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
 2663 //
 2664 // Other attributes of the comparison, such as unsignedness, are specified
 2665 // by the comparison instruction that sets a condition code flags register.
 2666 // That result is represented by a flags operand whose subtype is appropriate
 2667 // to the unsignedness (etc.) of the comparison.
 2668 //
 2669 // Later, the instruction which matches both the Comparison Op (a Bool) and
 2670 // the flags (produced by the Cmp) specifies the coding of the comparison op
 2671 // by matching a specific subtype of Bool operand below, such as cmpOpU.
 2672 
 2673 operand cmpOp() %{
 2674   match(Bool);
 2675 
 2676   format %{ "" %}
 2677   interface(COND_INTER) %{
 2678     equal(0x0);
 2679     not_equal(0x1);
 2680     less(0xb);
 2681     greater_equal(0xa);
 2682     less_equal(0xd);
 2683     greater(0xc);
 2684     overflow(0x0); // unsupported/unimplemented
 2685     no_overflow(0x0); // unsupported/unimplemented
 2686   %}
 2687 %}
 2688 
 2689 // integer comparison with 0, signed
 2690 operand cmpOp0() %{
 2691   match(Bool);
 2692 
 2693   format %{ "" %}
 2694   interface(COND_INTER) %{
 2695     equal(0x0);
 2696     not_equal(0x1);
 2697     less(0x4);
 2698     greater_equal(0x5);
 2699     less_equal(0xd); // unsupported
 2700     greater(0xc); // unsupported
 2701     overflow(0x0); // unsupported/unimplemented
 2702     no_overflow(0x0); // unsupported/unimplemented
 2703   %}
 2704 %}
 2705 
 2706 // Comparison Op, unsigned
 2707 operand cmpOpU() %{
 2708   match(Bool);
 2709 
 2710   format %{ "u" %}
 2711   interface(COND_INTER) %{
 2712     equal(0x0);
 2713     not_equal(0x1);
 2714     less(0x3);
 2715     greater_equal(0x2);
 2716     less_equal(0x9);
 2717     greater(0x8);
 2718     overflow(0x0); // unsupported/unimplemented
 2719     no_overflow(0x0); // unsupported/unimplemented
 2720   %}
 2721 %}
 2722 
 2723 // Comparison Op, pointer (same as unsigned)
 2724 operand cmpOpP() %{
 2725   match(Bool);
 2726 
 2727   format %{ "p" %}
 2728   interface(COND_INTER) %{
 2729     equal(0x0);
 2730     not_equal(0x1);
 2731     less(0x3);
 2732     greater_equal(0x2);
 2733     less_equal(0x9);
 2734     greater(0x8);
 2735     overflow(0x0); // unsupported/unimplemented
 2736     no_overflow(0x0); // unsupported/unimplemented
 2737   %}
 2738 %}
 2739 
 2740 operand cmpOpL() %{
 2741   match(Bool);
 2742 
 2743   format %{ "L" %}
 2744   interface(COND_INTER) %{
 2745     equal(0x0);
 2746     not_equal(0x1);
 2747     less(0xb);
 2748     greater_equal(0xa);
 2749     less_equal(0xd);
 2750     greater(0xc);
 2751     overflow(0x0); // unsupported/unimplemented
 2752     no_overflow(0x0); // unsupported/unimplemented
 2753   %}
 2754 %}
 2755 
 2756 operand cmpOpL_commute() %{
 2757   match(Bool);
 2758 
 2759   format %{ "L" %}
 2760   interface(COND_INTER) %{
 2761     equal(0x0);
 2762     not_equal(0x1);
 2763     less(0xc);
 2764     greater_equal(0xd);
 2765     less_equal(0xa);
 2766     greater(0xb);
 2767     overflow(0x0); // unsupported/unimplemented
 2768     no_overflow(0x0); // unsupported/unimplemented
 2769   %}
 2770 %}
 2771 
 2772 operand cmpOpUL() %{
 2773   match(Bool);
 2774 
 2775   format %{ "UL" %}
 2776   interface(COND_INTER) %{
 2777     equal(0x0);
 2778     not_equal(0x1);
 2779     less(0x3);
 2780     greater_equal(0x2);
 2781     less_equal(0x9);
 2782     greater(0x8);
 2783     overflow(0x0); // unsupported/unimplemented
 2784     no_overflow(0x0); // unsupported/unimplemented
 2785   %}
 2786 %}
 2787 
 2788 operand cmpOpUL_commute() %{
 2789   match(Bool);
 2790 
 2791   format %{ "UL" %}
 2792   interface(COND_INTER) %{
 2793     equal(0x0);
 2794     not_equal(0x1);
 2795     less(0x8);
 2796     greater_equal(0x9);
 2797     less_equal(0x2);
 2798     greater(0x3);
 2799     overflow(0x0); // unsupported/unimplemented
 2800     no_overflow(0x0); // unsupported/unimplemented
 2801   %}
 2802 %}
 2803 
 2804 
 2805 //----------OPERAND CLASSES----------------------------------------------------
 2806 // Operand Classes are groups of operands that are used to simplify
 2807 // instruction definitions by not requiring the AD writer to specify separate
 2808 // instructions for every form of operand when the instruction accepts
 2809 // multiple operand types with the same basic encoding and format.  The classic
 2810 // case of this is memory operands.
 2811 
 2812 opclass memoryI ( indirect, indOffset12, indIndex, indIndexScale );
 2813 opclass memoryP ( indirect, indOffset12, indIndex, indIndexScale );
 2814 opclass memoryF ( indirect, indOffsetFP );
 2815 opclass memoryF2 ( indirect, indOffsetFPx2 );
 2816 opclass memoryD ( indirect, indOffsetFP );
 2817 opclass memoryfp( indirect, indOffsetFP );
 2818 opclass memoryB ( indirect, indIndex, indOffsetHD );
 2819 opclass memoryS ( indirect, indIndex, indOffsetHD );
 2820 opclass memoryL ( indirect, indIndex, indOffsetHD );
 2821 
 2822 opclass memoryScaledI(indIndexScale);
 2823 opclass memoryScaledP(indIndexScale);
 2824 
 2825 // when ldrex/strex is used:
 2826 opclass memoryex ( indirect );
 2827 opclass indIndexMemory( indIndex );
 2828 opclass memorylong ( indirect, indOffset12x2 );
 2829 opclass memoryvld ( indirect /* , write back mode not implemented */ );
 2830 
 2831 //----------PIPELINE-----------------------------------------------------------
 2832 pipeline %{
 2833 
 2834 //----------ATTRIBUTES---------------------------------------------------------
 2835 attributes %{
 2836   fixed_size_instructions;           // Fixed size instructions
 2837   max_instructions_per_bundle = 4;   // Up to 4 instructions per bundle
 2838   instruction_unit_size = 4;         // An instruction is 4 bytes long
 2839   instruction_fetch_unit_size = 16;  // The processor fetches one line
 2840   instruction_fetch_units = 1;       // of 16 bytes
 2841 
 2842   // List of nop instructions
 2843   nops( Nop_A0, Nop_A1, Nop_MS, Nop_FA, Nop_BR );
 2844 %}
 2845 
 2846 //----------RESOURCES----------------------------------------------------------
 2847 // Resources are the functional units available to the machine
 2848 resources(A0, A1, MS, BR, FA, FM, IDIV, FDIV, IALU = A0 | A1);
 2849 
 2850 //----------PIPELINE DESCRIPTION-----------------------------------------------
 2851 // Pipeline Description specifies the stages in the machine's pipeline
 2852 
 2853 pipe_desc(A, P, F, B, I, J, S, R, E, C, M, W, X, T, D);
 2854 
 2855 //----------PIPELINE CLASSES---------------------------------------------------
 2856 // Pipeline Classes describe the stages in which input and output are
 2857 // referenced by the hardware pipeline.
 2858 
 2859 // Integer ALU reg-reg operation
 2860 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 2861     single_instruction;
 2862     dst   : E(write);
 2863     src1  : R(read);
 2864     src2  : R(read);
 2865     IALU  : R;
 2866 %}
 2867 
 2868 // Integer ALU reg-reg long operation
 2869 pipe_class ialu_reg_reg_2(iRegL dst, iRegL src1, iRegL src2) %{
 2870     instruction_count(2);
 2871     dst   : E(write);
 2872     src1  : R(read);
 2873     src2  : R(read);
 2874     IALU  : R;
 2875     IALU  : R;
 2876 %}
 2877 
 2878 // Integer ALU reg-reg long dependent operation
 2879 pipe_class ialu_reg_reg_2_dep(iRegL dst, iRegL src1, iRegL src2, flagsReg cr) %{
 2880     instruction_count(1); multiple_bundles;
 2881     dst   : E(write);
 2882     src1  : R(read);
 2883     src2  : R(read);
 2884     cr    : E(write);
 2885     IALU  : R(2);
 2886 %}
 2887 
 2888 // Integer ALU reg-imm operaion
 2889 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) %{
 2890     single_instruction;
 2891     dst   : E(write);
 2892     src1  : R(read);
 2893     IALU  : R;
 2894 %}
 2895 
 2896 // Integer ALU reg-reg operation with condition code
 2897 pipe_class ialu_cc_reg_reg(iRegI dst, iRegI src1, iRegI src2, flagsReg cr) %{
 2898     single_instruction;
 2899     dst   : E(write);
 2900     cr    : E(write);
 2901     src1  : R(read);
 2902     src2  : R(read);
 2903     IALU  : R;
 2904 %}
 2905 
 2906 // Integer ALU zero-reg operation
 2907 pipe_class ialu_zero_reg(iRegI dst, immI0 zero, iRegI src2) %{
 2908     single_instruction;
 2909     dst   : E(write);
 2910     src2  : R(read);
 2911     IALU  : R;
 2912 %}
 2913 
 2914 // Integer ALU zero-reg operation with condition code only
 2915 pipe_class ialu_cconly_zero_reg(flagsReg cr, iRegI src) %{
 2916     single_instruction;
 2917     cr    : E(write);
 2918     src   : R(read);
 2919     IALU  : R;
 2920 %}
 2921 
 2922 // Integer ALU reg-reg operation with condition code only
 2923 pipe_class ialu_cconly_reg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
 2924     single_instruction;
 2925     cr    : E(write);
 2926     src1  : R(read);
 2927     src2  : R(read);
 2928     IALU  : R;
 2929 %}
 2930 
 2931 // Integer ALU reg-imm operation with condition code only
 2932 pipe_class ialu_cconly_reg_imm(flagsReg cr, iRegI src1) %{
 2933     single_instruction;
 2934     cr    : E(write);
 2935     src1  : R(read);
 2936     IALU  : R;
 2937 %}
 2938 
 2939 // Integer ALU reg-reg-zero operation with condition code only
 2940 pipe_class ialu_cconly_reg_reg_zero(flagsReg cr, iRegI src1, iRegI src2, immI0 zero) %{
 2941     single_instruction;
 2942     cr    : E(write);
 2943     src1  : R(read);
 2944     src2  : R(read);
 2945     IALU  : R;
 2946 %}
 2947 
 2948 // Integer ALU reg-imm-zero operation with condition code only
 2949 pipe_class ialu_cconly_reg_imm_zero(flagsReg cr, iRegI src1, immI0 zero) %{
 2950     single_instruction;
 2951     cr    : E(write);
 2952     src1  : R(read);
 2953     IALU  : R;
 2954 %}
 2955 
 2956 // Integer ALU reg-reg operation with condition code, src1 modified
 2957 pipe_class ialu_cc_rwreg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
 2958     single_instruction;
 2959     cr    : E(write);
 2960     src1  : E(write);
 2961     src1  : R(read);
 2962     src2  : R(read);
 2963     IALU  : R;
 2964 %}
 2965 
 2966 pipe_class cmpL_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg cr ) %{
 2967     multiple_bundles;
 2968     dst   : E(write)+4;
 2969     cr    : E(write);
 2970     src1  : R(read);
 2971     src2  : R(read);
 2972     IALU  : R(3);
 2973     BR    : R(2);
 2974 %}
 2975 
 2976 // Integer ALU operation
 2977 pipe_class ialu_none(iRegI dst) %{
 2978     single_instruction;
 2979     dst   : E(write);
 2980     IALU  : R;
 2981 %}
 2982 
 2983 // Integer ALU reg operation
 2984 pipe_class ialu_reg(iRegI dst, iRegI src) %{
 2985     single_instruction; may_have_no_code;
 2986     dst   : E(write);
 2987     src   : R(read);
 2988     IALU  : R;
 2989 %}
 2990 
 2991 // Integer ALU reg conditional operation
 2992 // This instruction has a 1 cycle stall, and cannot execute
 2993 // in the same cycle as the instruction setting the condition
 2994 // code. We kludge this by pretending to read the condition code
 2995 // 1 cycle earlier, and by marking the functional units as busy
 2996 // for 2 cycles with the result available 1 cycle later than
 2997 // is really the case.
 2998 pipe_class ialu_reg_flags( iRegI op2_out, iRegI op2_in, iRegI op1, flagsReg cr ) %{
 2999     single_instruction;
 3000     op2_out : C(write);
 3001     op1     : R(read);
 3002     cr      : R(read);       // This is really E, with a 1 cycle stall
 3003     BR      : R(2);
 3004     MS      : R(2);
 3005 %}
 3006 
 3007 // Integer ALU reg operation
 3008 pipe_class ialu_move_reg_L_to_I(iRegI dst, iRegL src) %{
 3009     single_instruction; may_have_no_code;
 3010     dst   : E(write);
 3011     src   : R(read);
 3012     IALU  : R;
 3013 %}
 3014 pipe_class ialu_move_reg_I_to_L(iRegL dst, iRegI src) %{
 3015     single_instruction; may_have_no_code;
 3016     dst   : E(write);
 3017     src   : R(read);
 3018     IALU  : R;
 3019 %}
 3020 
 3021 // Two integer ALU reg operations
 3022 pipe_class ialu_reg_2(iRegL dst, iRegL src) %{
 3023     instruction_count(2);
 3024     dst   : E(write);
 3025     src   : R(read);
 3026     A0    : R;
 3027     A1    : R;
 3028 %}
 3029 
 3030 // Two integer ALU reg operations
 3031 pipe_class ialu_move_reg_L_to_L(iRegL dst, iRegL src) %{
 3032     instruction_count(2); may_have_no_code;
 3033     dst   : E(write);
 3034     src   : R(read);
 3035     A0    : R;
 3036     A1    : R;
 3037 %}
 3038 
 3039 // Integer ALU imm operation
 3040 pipe_class ialu_imm(iRegI dst) %{
 3041     single_instruction;
 3042     dst   : E(write);
 3043     IALU  : R;
 3044 %}
 3045 
 3046 pipe_class ialu_imm_n(iRegI dst) %{
 3047     single_instruction;
 3048     dst   : E(write);
 3049     IALU  : R;
 3050 %}
 3051 
 3052 // Integer ALU reg-reg with carry operation
 3053 pipe_class ialu_reg_reg_cy(iRegI dst, iRegI src1, iRegI src2, iRegI cy) %{
 3054     single_instruction;
 3055     dst   : E(write);
 3056     src1  : R(read);
 3057     src2  : R(read);
 3058     IALU  : R;
 3059 %}
 3060 
 3061 // Integer ALU cc operation
 3062 pipe_class ialu_cc(iRegI dst, flagsReg cc) %{
 3063     single_instruction;
 3064     dst   : E(write);
 3065     cc    : R(read);
 3066     IALU  : R;
 3067 %}
 3068 
 3069 // Integer ALU cc / second IALU operation
 3070 pipe_class ialu_reg_ialu( iRegI dst, iRegI src ) %{
 3071     instruction_count(1); multiple_bundles;
 3072     dst   : E(write)+1;
 3073     src   : R(read);
 3074     IALU  : R;
 3075 %}
 3076 
 3077 // Integer ALU cc / second IALU operation
 3078 pipe_class ialu_reg_reg_ialu( iRegI dst, iRegI p, iRegI q ) %{
 3079     instruction_count(1); multiple_bundles;
 3080     dst   : E(write)+1;
 3081     p     : R(read);
 3082     q     : R(read);
 3083     IALU  : R;
 3084 %}
 3085 
 3086 // Integer ALU hi-lo-reg operation
 3087 pipe_class ialu_hi_lo_reg(iRegI dst, immI src) %{
 3088     instruction_count(1); multiple_bundles;
 3089     dst   : E(write)+1;
 3090     IALU  : R(2);
 3091 %}
 3092 
 3093 // Long Constant
 3094 pipe_class loadConL( iRegL dst, immL src ) %{
 3095     instruction_count(2); multiple_bundles;
 3096     dst   : E(write)+1;
 3097     IALU  : R(2);
 3098     IALU  : R(2);
 3099 %}
 3100 
 3101 // Pointer Constant
 3102 pipe_class loadConP( iRegP dst, immP src ) %{
 3103     instruction_count(0); multiple_bundles;
 3104     fixed_latency(6);
 3105 %}
 3106 
 3107 // Long Constant small
 3108 pipe_class loadConLlo( iRegL dst, immL src ) %{
 3109     instruction_count(2);
 3110     dst   : E(write);
 3111     IALU  : R;
 3112     IALU  : R;
 3113 %}
 3114 
 3115 // [PHH] This is wrong for 64-bit.  See LdImmF/D.
 3116 pipe_class loadConFD(regF dst, immF src, iRegP tmp) %{
 3117     instruction_count(1); multiple_bundles;
 3118     src   : R(read);
 3119     dst   : M(write)+1;
 3120     IALU  : R;
 3121     MS    : E;
 3122 %}
 3123 
 3124 // Integer ALU nop operation
 3125 pipe_class ialu_nop() %{
 3126     single_instruction;
 3127     IALU  : R;
 3128 %}
 3129 
 3130 // Integer ALU nop operation
 3131 pipe_class ialu_nop_A0() %{
 3132     single_instruction;
 3133     A0    : R;
 3134 %}
 3135 
 3136 // Integer ALU nop operation
 3137 pipe_class ialu_nop_A1() %{
 3138     single_instruction;
 3139     A1    : R;
 3140 %}
 3141 
 3142 // Integer Multiply reg-reg operation
 3143 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 3144     single_instruction;
 3145     dst   : E(write);
 3146     src1  : R(read);
 3147     src2  : R(read);
 3148     MS    : R(5);
 3149 %}
 3150 
 3151 pipe_class mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 3152     single_instruction;
 3153     dst   : E(write)+4;
 3154     src1  : R(read);
 3155     src2  : R(read);
 3156     MS    : R(6);
 3157 %}
 3158 
 3159 // Integer Divide reg-reg
 3160 pipe_class sdiv_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI temp, flagsReg cr) %{
 3161     instruction_count(1); multiple_bundles;
 3162     dst   : E(write);
 3163     temp  : E(write);
 3164     src1  : R(read);
 3165     src2  : R(read);
 3166     temp  : R(read);
 3167     MS    : R(38);
 3168 %}
 3169 
 3170 // Long Divide
 3171 pipe_class divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 3172     dst  : E(write)+71;
 3173     src1 : R(read);
 3174     src2 : R(read)+1;
 3175     MS   : R(70);
 3176 %}
 3177 
 3178 // Floating Point Add Float
 3179 pipe_class faddF_reg_reg(regF dst, regF src1, regF src2) %{
 3180     single_instruction;
 3181     dst   : X(write);
 3182     src1  : E(read);
 3183     src2  : E(read);
 3184     FA    : R;
 3185 %}
 3186 
 3187 // Floating Point Add Double
 3188 pipe_class faddD_reg_reg(regD dst, regD src1, regD src2) %{
 3189     single_instruction;
 3190     dst   : X(write);
 3191     src1  : E(read);
 3192     src2  : E(read);
 3193     FA    : R;
 3194 %}
 3195 
 3196 // Floating Point Conditional Move based on integer flags
 3197 pipe_class int_conditional_float_move (cmpOp cmp, flagsReg cr, regF dst, regF src) %{
 3198     single_instruction;
 3199     dst   : X(write);
 3200     src   : E(read);
 3201     cr    : R(read);
 3202     FA    : R(2);
 3203     BR    : R(2);
 3204 %}
 3205 
 3206 // Floating Point Conditional Move based on integer flags
 3207 pipe_class int_conditional_double_move (cmpOp cmp, flagsReg cr, regD dst, regD src) %{
 3208     single_instruction;
 3209     dst   : X(write);
 3210     src   : E(read);
 3211     cr    : R(read);
 3212     FA    : R(2);
 3213     BR    : R(2);
 3214 %}
 3215 
 3216 // Floating Point Multiply Float
 3217 pipe_class fmulF_reg_reg(regF dst, regF src1, regF src2) %{
 3218     single_instruction;
 3219     dst   : X(write);
 3220     src1  : E(read);
 3221     src2  : E(read);
 3222     FM    : R;
 3223 %}
 3224 
 3225 // Floating Point Multiply Double
 3226 pipe_class fmulD_reg_reg(regD dst, regD src1, regD src2) %{
 3227     single_instruction;
 3228     dst   : X(write);
 3229     src1  : E(read);
 3230     src2  : E(read);
 3231     FM    : R;
 3232 %}
 3233 
 3234 // Floating Point Divide Float
 3235 pipe_class fdivF_reg_reg(regF dst, regF src1, regF src2) %{
 3236     single_instruction;
 3237     dst   : X(write);
 3238     src1  : E(read);
 3239     src2  : E(read);
 3240     FM    : R;
 3241     FDIV  : C(14);
 3242 %}
 3243 
 3244 // Floating Point Divide Double
 3245 pipe_class fdivD_reg_reg(regD dst, regD src1, regD src2) %{
 3246     single_instruction;
 3247     dst   : X(write);
 3248     src1  : E(read);
 3249     src2  : E(read);
 3250     FM    : R;
 3251     FDIV  : C(17);
 3252 %}
 3253 
 3254 // Floating Point Move/Negate/Abs Float
 3255 pipe_class faddF_reg(regF dst, regF src) %{
 3256     single_instruction;
 3257     dst   : W(write);
 3258     src   : E(read);
 3259     FA    : R(1);
 3260 %}
 3261 
 3262 // Floating Point Move/Negate/Abs Double
 3263 pipe_class faddD_reg(regD dst, regD src) %{
 3264     single_instruction;
 3265     dst   : W(write);
 3266     src   : E(read);
 3267     FA    : R;
 3268 %}
 3269 
 3270 // Floating Point Convert F->D
 3271 pipe_class fcvtF2D(regD dst, regF src) %{
 3272     single_instruction;
 3273     dst   : X(write);
 3274     src   : E(read);
 3275     FA    : R;
 3276 %}
 3277 
 3278 // Floating Point Convert I->D
 3279 pipe_class fcvtI2D(regD dst, regF src) %{
 3280     single_instruction;
 3281     dst   : X(write);
 3282     src   : E(read);
 3283     FA    : R;
 3284 %}
 3285 
 3286 // Floating Point Convert LHi->D
 3287 pipe_class fcvtLHi2D(regD dst, regD src) %{
 3288     single_instruction;
 3289     dst   : X(write);
 3290     src   : E(read);
 3291     FA    : R;
 3292 %}
 3293 
 3294 // Floating Point Convert L->D
 3295 pipe_class fcvtL2D(regD dst, iRegL src) %{
 3296     single_instruction;
 3297     dst   : X(write);
 3298     src   : E(read);
 3299     FA    : R;
 3300 %}
 3301 
 3302 // Floating Point Convert L->F
 3303 pipe_class fcvtL2F(regF dst, iRegL src) %{
 3304     single_instruction;
 3305     dst   : X(write);
 3306     src   : E(read);
 3307     FA    : R;
 3308 %}
 3309 
 3310 // Floating Point Convert D->F
 3311 pipe_class fcvtD2F(regD dst, regF src) %{
 3312     single_instruction;
 3313     dst   : X(write);
 3314     src   : E(read);
 3315     FA    : R;
 3316 %}
 3317 
 3318 // Floating Point Convert I->L
 3319 pipe_class fcvtI2L(regD dst, regF src) %{
 3320     single_instruction;
 3321     dst   : X(write);
 3322     src   : E(read);
 3323     FA    : R;
 3324 %}
 3325 
 3326 // Floating Point Convert D->F
 3327 pipe_class fcvtD2I(iRegI dst, regD src, flagsReg cr) %{
 3328     instruction_count(1); multiple_bundles;
 3329     dst   : X(write)+6;
 3330     src   : E(read);
 3331     FA    : R;
 3332 %}
 3333 
 3334 // Floating Point Convert D->L
 3335 pipe_class fcvtD2L(regD dst, regD src, flagsReg cr) %{
 3336     instruction_count(1); multiple_bundles;
 3337     dst   : X(write)+6;
 3338     src   : E(read);
 3339     FA    : R;
 3340 %}
 3341 
 3342 // Floating Point Convert F->I
 3343 pipe_class fcvtF2I(regF dst, regF src, flagsReg cr) %{
 3344     instruction_count(1); multiple_bundles;
 3345     dst   : X(write)+6;
 3346     src   : E(read);
 3347     FA    : R;
 3348 %}
 3349 
 3350 // Floating Point Convert F->L
 3351 pipe_class fcvtF2L(regD dst, regF src, flagsReg cr) %{
 3352     instruction_count(1); multiple_bundles;
 3353     dst   : X(write)+6;
 3354     src   : E(read);
 3355     FA    : R;
 3356 %}
 3357 
 3358 // Floating Point Convert I->F
 3359 pipe_class fcvtI2F(regF dst, regF src) %{
 3360     single_instruction;
 3361     dst   : X(write);
 3362     src   : E(read);
 3363     FA    : R;
 3364 %}
 3365 
 3366 // Floating Point Compare
 3367 pipe_class faddF_fcc_reg_reg_zero(flagsRegF cr, regF src1, regF src2, immI0 zero) %{
 3368     single_instruction;
 3369     cr    : X(write);
 3370     src1  : E(read);
 3371     src2  : E(read);
 3372     FA    : R;
 3373 %}
 3374 
 3375 // Floating Point Compare
 3376 pipe_class faddD_fcc_reg_reg_zero(flagsRegF cr, regD src1, regD src2, immI0 zero) %{
 3377     single_instruction;
 3378     cr    : X(write);
 3379     src1  : E(read);
 3380     src2  : E(read);
 3381     FA    : R;
 3382 %}
 3383 
 3384 // Floating Add Nop
 3385 pipe_class fadd_nop() %{
 3386     single_instruction;
 3387     FA  : R;
 3388 %}
 3389 
 3390 // Integer Store to Memory
 3391 pipe_class istore_mem_reg(memoryI mem, iRegI src) %{
 3392     single_instruction;
 3393     mem   : R(read);
 3394     src   : C(read);
 3395     MS    : R;
 3396 %}
 3397 
 3398 // Integer Store to Memory
 3399 pipe_class istore_mem_spORreg(memoryI mem, sp_ptr_RegP src) %{
 3400     single_instruction;
 3401     mem   : R(read);
 3402     src   : C(read);
 3403     MS    : R;
 3404 %}
 3405 
 3406 // Float Store
 3407 pipe_class fstoreF_mem_reg(memoryF mem, RegF src) %{
 3408     single_instruction;
 3409     mem : R(read);
 3410     src : C(read);
 3411     MS  : R;
 3412 %}
 3413 
 3414 // Float Store
 3415 pipe_class fstoreF_mem_zero(memoryF mem, immF0 src) %{
 3416     single_instruction;
 3417     mem : R(read);
 3418     MS  : R;
 3419 %}
 3420 
 3421 // Double Store
 3422 pipe_class fstoreD_mem_reg(memoryD mem, RegD src) %{
 3423     instruction_count(1);
 3424     mem : R(read);
 3425     src : C(read);
 3426     MS  : R;
 3427 %}
 3428 
 3429 // Double Store
 3430 pipe_class fstoreD_mem_zero(memoryD mem, immD0 src) %{
 3431     single_instruction;
 3432     mem : R(read);
 3433     MS  : R;
 3434 %}
 3435 
 3436 // Integer Load (when sign bit propagation not needed)
 3437 pipe_class iload_mem(iRegI dst, memoryI mem) %{
 3438     single_instruction;
 3439     mem : R(read);
 3440     dst : C(write);
 3441     MS  : R;
 3442 %}
 3443 
 3444 // Integer Load (when sign bit propagation or masking is needed)
 3445 pipe_class iload_mask_mem(iRegI dst, memoryI mem) %{
 3446     single_instruction;
 3447     mem : R(read);
 3448     dst : M(write);
 3449     MS  : R;
 3450 %}
 3451 
 3452 // Float Load
 3453 pipe_class floadF_mem(regF dst, memoryF mem) %{
 3454     single_instruction;
 3455     mem : R(read);
 3456     dst : M(write);
 3457     MS  : R;
 3458 %}
 3459 
 3460 // Float Load
 3461 pipe_class floadD_mem(regD dst, memoryD mem) %{
 3462     instruction_count(1); multiple_bundles; // Again, unaligned argument is only multiple case
 3463     mem : R(read);
 3464     dst : M(write);
 3465     MS  : R;
 3466 %}
 3467 
 3468 // Memory Nop
 3469 pipe_class mem_nop() %{
 3470     single_instruction;
 3471     MS  : R;
 3472 %}
 3473 
 3474 pipe_class sethi(iRegP dst, immI src) %{
 3475     single_instruction;
 3476     dst  : E(write);
 3477     IALU : R;
 3478 %}
 3479 
 3480 pipe_class loadPollP(iRegP poll) %{
 3481     single_instruction;
 3482     poll : R(read);
 3483     MS   : R;
 3484 %}
 3485 
 3486 pipe_class br(Universe br, label labl) %{
 3487     single_instruction_with_delay_slot;
 3488     BR  : R;
 3489 %}
 3490 
 3491 pipe_class br_cc(Universe br, cmpOp cmp, flagsReg cr, label labl) %{
 3492     single_instruction_with_delay_slot;
 3493     cr    : E(read);
 3494     BR    : R;
 3495 %}
 3496 
 3497 pipe_class br_reg(Universe br, cmpOp cmp, iRegI op1, label labl) %{
 3498     single_instruction_with_delay_slot;
 3499     op1 : E(read);
 3500     BR  : R;
 3501     MS  : R;
 3502 %}
 3503 
 3504 pipe_class br_nop() %{
 3505     single_instruction;
 3506     BR  : R;
 3507 %}
 3508 
 3509 pipe_class simple_call(method meth) %{
 3510     instruction_count(2); multiple_bundles; force_serialization;
 3511     fixed_latency(100);
 3512     BR  : R(1);
 3513     MS  : R(1);
 3514     A0  : R(1);
 3515 %}
 3516 
 3517 pipe_class compiled_call(method meth) %{
 3518     instruction_count(1); multiple_bundles; force_serialization;
 3519     fixed_latency(100);
 3520     MS  : R(1);
 3521 %}
 3522 
 3523 pipe_class call(method meth) %{
 3524     instruction_count(0); multiple_bundles; force_serialization;
 3525     fixed_latency(100);
 3526 %}
 3527 
 3528 pipe_class tail_call(Universe ignore, label labl) %{
 3529     single_instruction; has_delay_slot;
 3530     fixed_latency(100);
 3531     BR  : R(1);
 3532     MS  : R(1);
 3533 %}
 3534 
 3535 pipe_class ret(Universe ignore) %{
 3536     single_instruction; has_delay_slot;
 3537     BR  : R(1);
 3538     MS  : R(1);
 3539 %}
 3540 
 3541 // The real do-nothing guy
 3542 pipe_class empty( ) %{
 3543     instruction_count(0);
 3544 %}
 3545 
 3546 pipe_class long_memory_op() %{
 3547     instruction_count(0); multiple_bundles; force_serialization;
 3548     fixed_latency(25);
 3549     MS  : R(1);
 3550 %}
 3551 
 3552 // Check-cast
 3553 pipe_class partial_subtype_check_pipe(Universe ignore, iRegP array, iRegP match ) %{
 3554     array : R(read);
 3555     match  : R(read);
 3556     IALU   : R(2);
 3557     BR     : R(2);
 3558     MS     : R;
 3559 %}
 3560 
 3561 // Convert FPU flags into +1,0,-1
 3562 pipe_class floating_cmp( iRegI dst, regF src1, regF src2 ) %{
 3563     src1  : E(read);
 3564     src2  : E(read);
 3565     dst   : E(write);
 3566     FA    : R;
 3567     MS    : R(2);
 3568     BR    : R(2);
 3569 %}
 3570 
 3571 // Compare for p < q, and conditionally add y
 3572 pipe_class cadd_cmpltmask( iRegI p, iRegI q, iRegI y ) %{
 3573     p     : E(read);
 3574     q     : E(read);
 3575     y     : E(read);
 3576     IALU  : R(3)
 3577 %}
 3578 
 3579 // Perform a compare, then move conditionally in a branch delay slot.
 3580 pipe_class min_max( iRegI src2, iRegI srcdst ) %{
 3581     src2   : E(read);
 3582     srcdst : E(read);
 3583     IALU   : R;
 3584     BR     : R;
 3585 %}
 3586 
 3587 // Define the class for the Nop node
 3588 define %{
 3589    MachNop = ialu_nop;
 3590 %}
 3591 
 3592 %}
 3593 
 3594 //----------INSTRUCTIONS-------------------------------------------------------
 3595 
 3596 //------------Special Nop instructions for bundling - no match rules-----------
 3597 // Nop using the A0 functional unit
 3598 instruct Nop_A0() %{
 3599   ins_pipe(ialu_nop_A0);
 3600 %}
 3601 
 3602 // Nop using the A1 functional unit
 3603 instruct Nop_A1( ) %{
 3604   ins_pipe(ialu_nop_A1);
 3605 %}
 3606 
 3607 // Nop using the memory functional unit
 3608 instruct Nop_MS( ) %{
 3609   ins_pipe(mem_nop);
 3610 %}
 3611 
 3612 // Nop using the floating add functional unit
 3613 instruct Nop_FA( ) %{
 3614   ins_pipe(fadd_nop);
 3615 %}
 3616 
 3617 // Nop using the branch functional unit
 3618 instruct Nop_BR( ) %{
 3619   ins_pipe(br_nop);
 3620 %}
 3621 
 3622 //----------Load/Store/Move Instructions---------------------------------------
 3623 //----------Load Instructions--------------------------------------------------
 3624 // Load Byte (8bit signed)
 3625 instruct loadB(iRegI dst, memoryB mem) %{
 3626   match(Set dst (LoadB mem));
 3627   ins_cost(MEMORY_REF_COST);
 3628 
 3629   size(4);
 3630   format %{ "LDRSB   $dst,$mem\t! byte -> int" %}
 3631   ins_encode %{
 3632     __ ldrsb($dst$$Register, $mem$$Address);
 3633   %}
 3634   ins_pipe(iload_mask_mem);
 3635 %}
 3636 
 3637 // Load Byte (8bit signed) into a Long Register
 3638 instruct loadB2L(iRegL dst, memoryB mem) %{
 3639   match(Set dst (ConvI2L (LoadB mem)));
 3640   ins_cost(MEMORY_REF_COST);
 3641 
 3642   size(8);
 3643   format %{ "LDRSB $dst.lo,$mem\t! byte -> long\n\t"
 3644             "ASR   $dst.hi,$dst.lo,31" %}
 3645   ins_encode %{
 3646     __ ldrsb($dst$$Register, $mem$$Address);
 3647     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
 3648   %}
 3649   ins_pipe(iload_mask_mem);
 3650 %}
 3651 
 3652 // Load Unsigned Byte (8bit UNsigned) into an int reg
 3653 instruct loadUB(iRegI dst, memoryB mem) %{
 3654   match(Set dst (LoadUB mem));
 3655   ins_cost(MEMORY_REF_COST);
 3656 
 3657   size(4);
 3658   format %{ "LDRB   $dst,$mem\t! ubyte -> int" %}
 3659   ins_encode %{
 3660     __ ldrb($dst$$Register, $mem$$Address);
 3661   %}
 3662   ins_pipe(iload_mem);
 3663 %}
 3664 
 3665 // Load Unsigned Byte (8bit UNsigned) into a Long Register
 3666 instruct loadUB2L(iRegL dst, memoryB mem) %{
 3667   match(Set dst (ConvI2L (LoadUB mem)));
 3668   ins_cost(MEMORY_REF_COST);
 3669 
 3670   size(8);
 3671   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
 3672             "MOV   $dst.hi,0" %}
 3673   ins_encode %{
 3674     __ ldrb($dst$$Register, $mem$$Address);
 3675     __ mov($dst$$Register->successor(), 0);
 3676   %}
 3677   ins_pipe(iload_mem);
 3678 %}
 3679 
 3680 // Load Unsigned Byte (8 bit UNsigned) with immediate mask into Long Register
 3681 instruct loadUB2L_limmI(iRegL dst, memoryB mem, limmIlow8 mask) %{
 3682   match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
 3683 
 3684   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 3685   size(12);
 3686   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
 3687             "MOV   $dst.hi,0\n\t"
 3688             "AND  $dst.lo,$dst.lo,$mask" %}
 3689   ins_encode %{
 3690     __ ldrb($dst$$Register, $mem$$Address);
 3691     __ mov($dst$$Register->successor(), 0);
 3692     __ andr($dst$$Register, $dst$$Register, limmI_low($mask$$constant, 8));
 3693   %}
 3694   ins_pipe(iload_mem);
 3695 %}
 3696 
 3697 // Load Short (16bit signed)
 3698 
 3699 instruct loadS(iRegI dst, memoryS mem) %{
 3700   match(Set dst (LoadS mem));
 3701   ins_cost(MEMORY_REF_COST);
 3702 
 3703   size(4);
 3704   format %{ "LDRSH   $dst,$mem\t! short" %}
 3705   ins_encode %{
 3706     __ ldrsh($dst$$Register, $mem$$Address);
 3707   %}
 3708   ins_pipe(iload_mask_mem);
 3709 %}
 3710 
 3711 // Load Short (16 bit signed) to Byte (8 bit signed)
 3712 instruct loadS2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
 3713   match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
 3714   ins_cost(MEMORY_REF_COST);
 3715 
 3716   size(4);
 3717 
 3718   format %{ "LDRSB   $dst,$mem\t! short -> byte" %}
 3719   ins_encode %{
 3720     __ ldrsb($dst$$Register, $mem$$Address);
 3721   %}
 3722   ins_pipe(iload_mask_mem);
 3723 %}
 3724 
 3725 // Load Short (16bit signed) into a Long Register
 3726 instruct loadS2L(iRegL dst, memoryS mem) %{
 3727   match(Set dst (ConvI2L (LoadS mem)));
 3728   ins_cost(MEMORY_REF_COST);
 3729 
 3730   size(8);
 3731   format %{ "LDRSH $dst.lo,$mem\t! short -> long\n\t"
 3732             "ASR   $dst.hi,$dst.lo,31" %}
 3733   ins_encode %{
 3734     __ ldrsh($dst$$Register, $mem$$Address);
 3735     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
 3736   %}
 3737   ins_pipe(iload_mask_mem);
 3738 %}
 3739 
 3740 // Load Unsigned Short/Char (16bit UNsigned)
 3741 
 3742 
 3743 instruct loadUS(iRegI dst, memoryS mem) %{
 3744   match(Set dst (LoadUS mem));
 3745   ins_cost(MEMORY_REF_COST);
 3746 
 3747   size(4);
 3748   format %{ "LDRH   $dst,$mem\t! ushort/char" %}
 3749   ins_encode %{
 3750     __ ldrh($dst$$Register, $mem$$Address);
 3751   %}
 3752   ins_pipe(iload_mem);
 3753 %}
 3754 
 3755 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
 3756 instruct loadUS2B(iRegI dst, memoryB mem, immI_24 twentyfour) %{
 3757   match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
 3758   ins_cost(MEMORY_REF_COST);
 3759 
 3760   size(4);
 3761   format %{ "LDRSB   $dst,$mem\t! ushort -> byte" %}
 3762   ins_encode %{
 3763     __ ldrsb($dst$$Register, $mem$$Address);
 3764   %}
 3765   ins_pipe(iload_mask_mem);
 3766 %}
 3767 
 3768 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register
 3769 instruct loadUS2L(iRegL dst, memoryS mem) %{
 3770   match(Set dst (ConvI2L (LoadUS mem)));
 3771   ins_cost(MEMORY_REF_COST);
 3772 
 3773   size(8);
 3774   format %{ "LDRH  $dst.lo,$mem\t! short -> long\n\t"
 3775             "MOV   $dst.hi, 0" %}
 3776   ins_encode %{
 3777     __ ldrh($dst$$Register, $mem$$Address);
 3778     __ mov($dst$$Register->successor(), 0);
 3779   %}
 3780   ins_pipe(iload_mem);
 3781 %}
 3782 
 3783 // Load Unsigned Short/Char (16bit UNsigned) with mask 0xFF into a Long Register
 3784 instruct loadUS2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
 3785   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
 3786   ins_cost(MEMORY_REF_COST);
 3787 
 3788   size(8);
 3789   format %{ "LDRB  $dst.lo,$mem\t! \n\t"
 3790             "MOV   $dst.hi, 0" %}
 3791   ins_encode %{
 3792     __ ldrb($dst$$Register, $mem$$Address);
 3793     __ mov($dst$$Register->successor(), 0);
 3794   %}
 3795   ins_pipe(iload_mem);
 3796 %}
 3797 
 3798 // Load Unsigned Short/Char (16bit UNsigned) with a immediate mask into a Long Register
 3799 instruct loadUS2L_limmI(iRegL dst, memoryS mem, limmI mask) %{
 3800   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
 3801   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 3802 
 3803   size(12);
 3804   format %{ "LDRH   $dst,$mem\t! ushort/char & mask -> long\n\t"
 3805             "MOV    $dst.hi, 0\n\t"
 3806             "AND    $dst,$dst,$mask" %}
 3807   ins_encode %{
 3808     __ ldrh($dst$$Register, $mem$$Address);
 3809     __ mov($dst$$Register->successor(), 0);
 3810     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
 3811   %}
 3812   ins_pipe(iload_mem);
 3813 %}
 3814 
 3815 // Load Integer
 3816 
 3817 
 3818 instruct loadI(iRegI dst, memoryI mem) %{
 3819   match(Set dst (LoadI mem));
 3820   ins_cost(MEMORY_REF_COST);
 3821 
 3822   size(4);
 3823   format %{ "ldr_s32 $dst,$mem\t! int" %}
 3824   ins_encode %{
 3825     __ ldr_s32($dst$$Register, $mem$$Address);
 3826   %}
 3827   ins_pipe(iload_mem);
 3828 %}
 3829 
 3830 // Load Integer to Byte (8 bit signed)
 3831 instruct loadI2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
 3832   match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
 3833   ins_cost(MEMORY_REF_COST);
 3834 
 3835   size(4);
 3836 
 3837   format %{ "LDRSB   $dst,$mem\t! int -> byte" %}
 3838   ins_encode %{
 3839     __ ldrsb($dst$$Register, $mem$$Address);
 3840   %}
 3841   ins_pipe(iload_mask_mem);
 3842 %}
 3843 
 3844 // Load Integer to Unsigned Byte (8 bit UNsigned)
 3845 instruct loadI2UB(iRegI dst, memoryB mem, immI_255 mask) %{
 3846   match(Set dst (AndI (LoadI mem) mask));
 3847   ins_cost(MEMORY_REF_COST);
 3848 
 3849   size(4);
 3850 
 3851   format %{ "LDRB   $dst,$mem\t! int -> ubyte" %}
 3852   ins_encode %{
 3853     __ ldrb($dst$$Register, $mem$$Address);
 3854   %}
 3855   ins_pipe(iload_mask_mem);
 3856 %}
 3857 
 3858 // Load Integer to Short (16 bit signed)
 3859 instruct loadI2S(iRegI dst, memoryS mem, immI_16 sixteen) %{
 3860   match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
 3861   ins_cost(MEMORY_REF_COST);
 3862 
 3863   size(4);
 3864   format %{ "LDRSH   $dst,$mem\t! int -> short" %}
 3865   ins_encode %{
 3866     __ ldrsh($dst$$Register, $mem$$Address);
 3867   %}
 3868   ins_pipe(iload_mask_mem);
 3869 %}
 3870 
 3871 // Load Integer to Unsigned Short (16 bit UNsigned)
 3872 instruct loadI2US(iRegI dst, memoryS mem, immI_65535 mask) %{
 3873   match(Set dst (AndI (LoadI mem) mask));
 3874   ins_cost(MEMORY_REF_COST);
 3875 
 3876   size(4);
 3877   format %{ "LDRH   $dst,$mem\t! int -> ushort/char" %}
 3878   ins_encode %{
 3879     __ ldrh($dst$$Register, $mem$$Address);
 3880   %}
 3881   ins_pipe(iload_mask_mem);
 3882 %}
 3883 
 3884 // Load Integer into a Long Register
 3885 instruct loadI2L(iRegL dst, memoryI mem) %{
 3886   match(Set dst (ConvI2L (LoadI mem)));
 3887   ins_cost(MEMORY_REF_COST);
 3888 
 3889   size(8);
 3890   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
 3891             "ASR   $dst.hi,$dst.lo,31\t! int->long" %}
 3892   ins_encode %{
 3893     __ ldr($dst$$Register, $mem$$Address);
 3894     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
 3895   %}
 3896   ins_pipe(iload_mask_mem);
 3897 %}
 3898 
 3899 // Load Integer with mask 0xFF into a Long Register
 3900 instruct loadI2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
 3901   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3902   ins_cost(MEMORY_REF_COST);
 3903 
 3904   size(8);
 3905   format %{ "LDRB   $dst.lo,$mem\t! int & 0xFF -> long\n\t"
 3906             "MOV    $dst.hi, 0" %}
 3907   ins_encode %{
 3908     __ ldrb($dst$$Register, $mem$$Address);
 3909     __ mov($dst$$Register->successor(), 0);
 3910   %}
 3911   ins_pipe(iload_mem);
 3912 %}
 3913 
 3914 // Load Integer with mask 0xFFFF into a Long Register
 3915 instruct loadI2L_immI_65535(iRegL dst, memoryS mem, immI_65535 mask) %{
 3916   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3917   ins_cost(MEMORY_REF_COST);
 3918 
 3919   size(8);
 3920   format %{ "LDRH   $dst,$mem\t! int & 0xFFFF -> long\n\t"
 3921             "MOV    $dst.hi, 0" %}
 3922   ins_encode %{
 3923     __ ldrh($dst$$Register, $mem$$Address);
 3924     __ mov($dst$$Register->successor(), 0);
 3925   %}
 3926   ins_pipe(iload_mask_mem);
 3927 %}
 3928 
 3929 // Load Integer with a 31-bit immediate mask into a Long Register
 3930 instruct loadI2L_limmU31(iRegL dst, memoryI mem, limmU31 mask) %{
 3931   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3932   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 3933 
 3934   size(12);
 3935   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
 3936             "MOV    $dst.hi, 0\n\t"
 3937             "AND   $dst,$dst,$mask" %}
 3938 
 3939   ins_encode %{
 3940     __ ldr($dst$$Register, $mem$$Address);
 3941     __ mov($dst$$Register->successor(), 0);
 3942     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
 3943   %}
 3944   ins_pipe(iload_mem);
 3945 %}
 3946 
 3947 // Load Integer with a 31-bit mask into a Long Register
 3948 // FIXME: use iRegI mask, remove tmp?
 3949 instruct loadI2L_immU31(iRegL dst, memoryI mem, immU31 mask, iRegI tmp) %{
 3950   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
 3951   effect(TEMP dst, TEMP tmp);
 3952 
 3953   ins_cost(MEMORY_REF_COST + 4*DEFAULT_COST);
 3954   size(20);
 3955   format %{ "LDR      $mem,$dst\t! int & 31-bit mask -> long\n\t"
 3956             "MOV      $dst.hi, 0\n\t"
 3957             "MOV_SLOW $tmp,$mask\n\t"
 3958             "AND      $dst,$tmp,$dst" %}
 3959   ins_encode %{
 3960     __ ldr($dst$$Register, $mem$$Address);
 3961     __ mov($dst$$Register->successor(), 0);
 3962     __ mov_slow($tmp$$Register, $mask$$constant);
 3963     __ andr($dst$$Register, $dst$$Register, $tmp$$Register);
 3964   %}
 3965   ins_pipe(iload_mem);
 3966 %}
 3967 
 3968 // Load Unsigned Integer into a Long Register
 3969 instruct loadUI2L(iRegL dst, memoryI mem, immL_32bits mask) %{
 3970   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
 3971   ins_cost(MEMORY_REF_COST);
 3972 
 3973   size(8);
 3974   format %{ "LDR   $dst.lo,$mem\t! uint -> long\n\t"
 3975             "MOV   $dst.hi,0" %}
 3976   ins_encode %{
 3977     __ ldr($dst$$Register, $mem$$Address);
 3978     __ mov($dst$$Register->successor(), 0);
 3979   %}
 3980   ins_pipe(iload_mem);
 3981 %}
 3982 
 3983 // Load Long
 3984 
 3985 
 3986 instruct loadL(iRegLd dst, memoryL mem ) %{
 3987   predicate(!((LoadLNode*)n)->require_atomic_access());
 3988   match(Set dst (LoadL mem));
 3989   effect(TEMP dst);
 3990   ins_cost(MEMORY_REF_COST);
 3991 
 3992   size(4);
 3993   format %{ "ldr_64  $dst,$mem\t! long" %}
 3994   ins_encode %{
 3995     __ ldr_64($dst$$Register, $mem$$Address);
 3996   %}
 3997   ins_pipe(iload_mem);
 3998 %}
 3999 
 4000 instruct loadL_2instr(iRegL dst, memorylong mem ) %{
 4001   predicate(!((LoadLNode*)n)->require_atomic_access());
 4002   match(Set dst (LoadL mem));
 4003   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
 4004 
 4005   size(8);
 4006   format %{ "LDR    $dst.lo,$mem \t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
 4007             "LDR    $dst.hi,$mem+4 or $mem" %}
 4008   ins_encode %{
 4009     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 4010     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 4011 
 4012     if ($dst$$Register == reg_to_register_object($mem$$base)) {
 4013       __ ldr($dst$$Register->successor(), Amemhi);
 4014       __ ldr($dst$$Register, Amemlo);
 4015     } else {
 4016       __ ldr($dst$$Register, Amemlo);
 4017       __ ldr($dst$$Register->successor(), Amemhi);
 4018     }
 4019   %}
 4020   ins_pipe(iload_mem);
 4021 %}
 4022 
 4023 instruct loadL_volatile(iRegL dst, indirect mem ) %{
 4024   predicate(((LoadLNode*)n)->require_atomic_access());
 4025   match(Set dst (LoadL mem));
 4026   ins_cost(MEMORY_REF_COST);
 4027 
 4028   size(4);
 4029   format %{ "LDMIA    $dst,$mem\t! long" %}
 4030   ins_encode %{
 4031     // FIXME: why is ldmia considered atomic?  Should be ldrexd
 4032     RegisterSet set($dst$$Register);
 4033     set = set | reg_to_register_object($dst$$reg + 1);
 4034     __ ldmia(reg_to_register_object($mem$$base), set);
 4035   %}
 4036   ins_pipe(iload_mem);
 4037 %}
 4038 
 4039 instruct loadL_volatile_fp(iRegL dst, memoryD mem ) %{
 4040   predicate(((LoadLNode*)n)->require_atomic_access());
 4041   match(Set dst (LoadL mem));
 4042   ins_cost(MEMORY_REF_COST);
 4043 
 4044   size(8);
 4045   format %{ "FLDD      S14, $mem"
 4046             "FMRRD    $dst, S14\t! long \n't" %}
 4047   ins_encode %{
 4048     __ fldd(S14, $mem$$Address);
 4049     __ fmrrd($dst$$Register, $dst$$Register->successor(), S14);
 4050   %}
 4051   ins_pipe(iload_mem);
 4052 %}
 4053 
 4054 instruct loadL_unaligned(iRegL dst, memorylong mem ) %{
 4055   match(Set dst (LoadL_unaligned mem));
 4056   ins_cost(MEMORY_REF_COST);
 4057 
 4058   size(8);
 4059   format %{ "LDR    $dst.lo,$mem\t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
 4060             "LDR    $dst.hi,$mem+4" %}
 4061   ins_encode %{
 4062     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 4063     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 4064 
 4065     if ($dst$$Register == reg_to_register_object($mem$$base)) {
 4066       __ ldr($dst$$Register->successor(), Amemhi);
 4067       __ ldr($dst$$Register, Amemlo);
 4068     } else {
 4069       __ ldr($dst$$Register, Amemlo);
 4070       __ ldr($dst$$Register->successor(), Amemhi);
 4071     }
 4072   %}
 4073   ins_pipe(iload_mem);
 4074 %}
 4075 
 4076 // Load Range
 4077 instruct loadRange(iRegI dst, memoryI mem) %{
 4078   match(Set dst (LoadRange mem));
 4079   ins_cost(MEMORY_REF_COST);
 4080 
 4081   size(4);
 4082   format %{ "LDR_u32 $dst,$mem\t! range" %}
 4083   ins_encode %{
 4084     __ ldr_u32($dst$$Register, $mem$$Address);
 4085   %}
 4086   ins_pipe(iload_mem);
 4087 %}
 4088 
 4089 // Load Pointer
 4090 
 4091 
 4092 instruct loadP(iRegP dst, memoryP mem) %{
 4093   match(Set dst (LoadP mem));
 4094   ins_cost(MEMORY_REF_COST);
 4095   size(4);
 4096 
 4097   format %{ "LDR   $dst,$mem\t! ptr" %}
 4098   ins_encode %{
 4099     __ ldr($dst$$Register, $mem$$Address);
 4100   %}
 4101   ins_pipe(iload_mem);
 4102 %}
 4103 
 4104 #ifdef XXX
 4105 // FIXME XXXX
 4106 //instruct loadSP(iRegP dst, memoryP mem) %{
 4107 instruct loadSP(SPRegP dst, memoryP mem, iRegP tmp) %{
 4108   match(Set dst (LoadP mem));
 4109   effect(TEMP tmp);
 4110   ins_cost(MEMORY_REF_COST+1);
 4111   size(8);
 4112 
 4113   format %{ "LDR   $tmp,$mem\t! ptr\n\t"
 4114             "MOV   $dst,$tmp\t! ptr" %}
 4115   ins_encode %{
 4116     __ ldr($tmp$$Register, $mem$$Address);
 4117     __ mov($dst$$Register, $tmp$$Register);
 4118   %}
 4119   ins_pipe(iload_mem);
 4120 %}
 4121 #endif
 4122 
 4123 #ifdef _LP64
 4124 // Load Compressed Pointer
 4125 
 4126 // XXX This variant shouldn't be necessary if 6217251 is implemented
 4127 instruct loadNoff(iRegN dst, memoryScaledI mem, aimmX off, iRegP tmp) %{
 4128   match(Set dst (LoadN (AddP mem off)));
 4129   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
 4130   effect(TEMP tmp);
 4131   size(4 * 2);
 4132 
 4133   format %{ "ldr_u32 $dst,$mem+$off\t! compressed ptr temp=$tmp" %}
 4134   ins_encode %{
 4135     Register base = reg_to_register_object($mem$$base);
 4136     __ add($tmp$$Register, base, $off$$constant);
 4137     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 4138     __ ldr_u32($dst$$Register, nmem);
 4139   %}
 4140   ins_pipe(iload_mem);
 4141 %}
 4142 
 4143 instruct loadN(iRegN dst, memoryI mem) %{
 4144   match(Set dst (LoadN mem));
 4145   ins_cost(MEMORY_REF_COST);
 4146   size(4);
 4147 
 4148   format %{ "ldr_u32 $dst,$mem\t! compressed ptr" %}
 4149   ins_encode %{
 4150     __ ldr_u32($dst$$Register, $mem$$Address);
 4151   %}
 4152   ins_pipe(iload_mem);
 4153 %}
 4154 #endif
 4155 
 4156 // Load Klass Pointer
 4157 instruct loadKlass(iRegP dst, memoryI mem) %{
 4158   match(Set dst (LoadKlass mem));
 4159   ins_cost(MEMORY_REF_COST);
 4160   size(4);
 4161 
 4162   format %{ "LDR   $dst,$mem\t! klass ptr" %}
 4163   ins_encode %{
 4164     __ ldr($dst$$Register, $mem$$Address);
 4165   %}
 4166   ins_pipe(iload_mem);
 4167 %}
 4168 
 4169 #ifdef _LP64
 4170 // Load narrow Klass Pointer
 4171 instruct loadNKlass(iRegN dst, memoryI mem) %{
 4172   match(Set dst (LoadNKlass mem));
 4173   ins_cost(MEMORY_REF_COST);
 4174   size(4);
 4175 
 4176   format %{ "ldr_u32 $dst,$mem\t! compressed klass ptr" %}
 4177   ins_encode %{
 4178     __ ldr_u32($dst$$Register, $mem$$Address);
 4179   %}
 4180   ins_pipe(iload_mem);
 4181 %}
 4182 #endif
 4183 
 4184 
 4185 instruct loadD(regD dst, memoryD mem) %{
 4186   match(Set dst (LoadD mem));
 4187   ins_cost(MEMORY_REF_COST);
 4188 
 4189   size(4);
 4190   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
 4191   // only LDREXD and STREXD are 64-bit single-copy atomic
 4192   format %{ "FLDD   $dst,$mem" %}
 4193   ins_encode %{
 4194     __ ldr_double($dst$$FloatRegister, $mem$$Address);
 4195   %}
 4196   ins_pipe(floadD_mem);
 4197 %}
 4198 
 4199 // Load Double - UNaligned
 4200 instruct loadD_unaligned(regD_low dst, memoryF2 mem ) %{
 4201   match(Set dst (LoadD_unaligned mem));
 4202   ins_cost(MEMORY_REF_COST*2+DEFAULT_COST);
 4203   size(8);
 4204   format %{ "FLDS    $dst.lo,$mem\t! misaligned double\n"
 4205           "\tFLDS    $dst.hi,$mem+4\t!" %}
 4206   ins_encode %{
 4207     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 4208     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 4209       __ flds($dst$$FloatRegister, Amemlo);
 4210       __ flds($dst$$FloatRegister->successor(), Amemhi);
 4211   %}
 4212   ins_pipe(iload_mem);
 4213 %}
 4214 
 4215 
 4216 instruct loadF(regF dst, memoryF mem) %{
 4217   match(Set dst (LoadF mem));
 4218 
 4219   ins_cost(MEMORY_REF_COST);
 4220   size(4);
 4221   format %{ "FLDS    $dst,$mem" %}
 4222   ins_encode %{
 4223     __ ldr_float($dst$$FloatRegister, $mem$$Address);
 4224   %}
 4225   ins_pipe(floadF_mem);
 4226 %}
 4227 
 4228 
 4229 // // Load Constant
 4230 instruct loadConI( iRegI dst, immI src ) %{
 4231   match(Set dst src);
 4232   ins_cost(DEFAULT_COST * 3/2);
 4233   format %{ "MOV_SLOW    $dst, $src" %}
 4234   ins_encode %{
 4235     __ mov_slow($dst$$Register, $src$$constant);
 4236   %}
 4237   ins_pipe(ialu_hi_lo_reg);
 4238 %}
 4239 
 4240 instruct loadConIMov( iRegI dst, immIMov src ) %{
 4241   match(Set dst src);
 4242   size(4);
 4243   format %{ "MOV    $dst, $src" %}
 4244   ins_encode %{
 4245     __ mov($dst$$Register, $src$$constant);
 4246   %}
 4247   ins_pipe(ialu_imm);
 4248 %}
 4249 
 4250 instruct loadConIMovn( iRegI dst, immIRotn src ) %{
 4251   match(Set dst src);
 4252   size(4);
 4253   format %{ "MVN    $dst, ~$src" %}
 4254   ins_encode %{
 4255     __ mvn($dst$$Register, ~$src$$constant);
 4256   %}
 4257   ins_pipe(ialu_imm_n);
 4258 %}
 4259 
 4260 instruct loadConI16( iRegI dst, immI16 src ) %{
 4261   match(Set dst src);
 4262   size(4);
 4263   format %{ "MOVW    $dst, $src" %}
 4264   ins_encode %{
 4265     __ movw($dst$$Register, $src$$constant);
 4266   %}
 4267   ins_pipe(ialu_imm_n);
 4268 %}
 4269 
 4270 instruct loadConP(iRegP dst, immP src) %{
 4271   match(Set dst src);
 4272   ins_cost(DEFAULT_COST * 3/2);
 4273   format %{ "MOV_SLOW    $dst,$src\t!ptr" %}
 4274   ins_encode %{
 4275     relocInfo::relocType constant_reloc = _opnds[1]->constant_reloc();
 4276     intptr_t val = $src$$constant;
 4277     if (constant_reloc == relocInfo::oop_type) {
 4278       __ mov_oop($dst$$Register, (jobject)val);
 4279     } else if (constant_reloc == relocInfo::metadata_type) {
 4280       __ mov_metadata($dst$$Register, (Metadata*)val);
 4281     } else {
 4282       __ mov_slow($dst$$Register, val);
 4283     }
 4284   %}
 4285   ins_pipe(loadConP);
 4286 %}
 4287 
 4288 
 4289 instruct loadConL(iRegL dst, immL src) %{
 4290   match(Set dst src);
 4291   ins_cost(DEFAULT_COST * 4);
 4292   format %{ "MOV_SLOW   $dst.lo, $src & 0x0FFFFFFFFL \t! long\n\t"
 4293             "MOV_SLOW   $dst.hi, $src >> 32" %}
 4294   ins_encode %{
 4295     __ mov_slow(reg_to_register_object($dst$$reg), $src$$constant & 0x0FFFFFFFFL);
 4296     __ mov_slow(reg_to_register_object($dst$$reg + 1), ((julong)($src$$constant)) >> 32);
 4297   %}
 4298   ins_pipe(loadConL);
 4299 %}
 4300 
 4301 instruct loadConL16( iRegL dst, immL16 src ) %{
 4302   match(Set dst src);
 4303   ins_cost(DEFAULT_COST * 2);
 4304 
 4305   size(8);
 4306   format %{ "MOVW    $dst.lo, $src \n\t"
 4307             "MOVW    $dst.hi, 0 \n\t" %}
 4308   ins_encode %{
 4309     __ movw($dst$$Register, $src$$constant);
 4310     __ movw($dst$$Register->successor(), 0);
 4311   %}
 4312   ins_pipe(ialu_imm);
 4313 %}
 4314 
 4315 instruct loadConF_imm8(regF dst, imm8F src) %{
 4316   match(Set dst src);
 4317   ins_cost(DEFAULT_COST);
 4318   size(4);
 4319 
 4320   format %{ "FCONSTS      $dst, $src"%}
 4321 
 4322   ins_encode %{
 4323     __ fconsts($dst$$FloatRegister, Assembler::float_num($src$$constant).imm8());
 4324   %}
 4325   ins_pipe(loadConFD); // FIXME
 4326 %}
 4327 
 4328 
 4329 instruct loadConF(regF dst, immF src, iRegI tmp) %{
 4330   match(Set dst src);
 4331   ins_cost(DEFAULT_COST * 2);
 4332   effect(TEMP tmp);
 4333   size(3*4);
 4334 
 4335   format %{ "MOV_SLOW  $tmp, $src\n\t"
 4336             "FMSR      $dst, $tmp"%}
 4337 
 4338   ins_encode %{
 4339     // FIXME revisit once 6961697 is in
 4340     union {
 4341       jfloat f;
 4342       int i;
 4343     } v;
 4344     v.f = $src$$constant;
 4345     __ mov_slow($tmp$$Register, v.i);
 4346     __ fmsr($dst$$FloatRegister, $tmp$$Register);
 4347   %}
 4348   ins_pipe(loadConFD); // FIXME
 4349 %}
 4350 
 4351 instruct loadConD_imm8(regD dst, imm8D src) %{
 4352   match(Set dst src);
 4353   ins_cost(DEFAULT_COST);
 4354   size(4);
 4355 
 4356   format %{ "FCONSTD      $dst, $src"%}
 4357 
 4358   ins_encode %{
 4359     __ fconstd($dst$$FloatRegister, Assembler::double_num($src$$constant).imm8());
 4360   %}
 4361   ins_pipe(loadConFD); // FIXME
 4362 %}
 4363 
 4364 instruct loadConD(regD dst, immD src, iRegP tmp) %{
 4365   match(Set dst src);
 4366   effect(TEMP tmp);
 4367   ins_cost(MEMORY_REF_COST);
 4368   format %{ "FLDD  $dst, [$constanttablebase + $constantoffset]\t! load from constant table: double=$src" %}
 4369 
 4370   ins_encode %{
 4371     Register r = $constanttablebase;
 4372     int offset  = $constantoffset($src);
 4373     if (!is_memoryD(offset)) {                // can't use a predicate
 4374                                               // in load constant instructs
 4375       __ add_slow($tmp$$Register, r, offset);
 4376       r = $tmp$$Register;
 4377       offset = 0;
 4378     }
 4379     __ ldr_double($dst$$FloatRegister, Address(r, offset));
 4380   %}
 4381   ins_pipe(loadConFD);
 4382 %}
 4383 
 4384 // Prefetch instructions.
 4385 // Must be safe to execute with invalid address (cannot fault).
 4386 
 4387 instruct prefetchAlloc_mp( memoryP mem ) %{
 4388   predicate(VM_Version::has_multiprocessing_extensions());
 4389   match( PrefetchAllocation mem );
 4390   ins_cost(MEMORY_REF_COST);
 4391   size(4);
 4392 
 4393   format %{ "PLDW $mem\t! Prefetch allocation" %}
 4394   ins_encode %{
 4395     __ pldw($mem$$Address);
 4396   %}
 4397   ins_pipe(iload_mem);
 4398 %}
 4399 
 4400 instruct prefetchAlloc_sp( memoryP mem ) %{
 4401   predicate(!VM_Version::has_multiprocessing_extensions());
 4402   match( PrefetchAllocation mem );
 4403   ins_cost(MEMORY_REF_COST);
 4404   size(4);
 4405 
 4406   format %{ "PLD $mem\t! Prefetch allocation" %}
 4407   ins_encode %{
 4408     __ pld($mem$$Address);
 4409   %}
 4410   ins_pipe(iload_mem);
 4411 %}
 4412 
 4413 
 4414 //----------Store Instructions-------------------------------------------------
 4415 // Store Byte
 4416 instruct storeB(memoryB mem, store_RegI src) %{
 4417   match(Set mem (StoreB mem src));
 4418   ins_cost(MEMORY_REF_COST);
 4419 
 4420   size(4);
 4421   format %{ "STRB    $src,$mem\t! byte" %}
 4422   ins_encode %{
 4423     __ strb($src$$Register, $mem$$Address);
 4424   %}
 4425   ins_pipe(istore_mem_reg);
 4426 %}
 4427 
 4428 instruct storeCM(memoryB mem, store_RegI src) %{
 4429   match(Set mem (StoreCM mem src));
 4430   ins_cost(MEMORY_REF_COST);
 4431 
 4432   size(4);
 4433   format %{ "STRB    $src,$mem\t! CMS card-mark byte" %}
 4434   ins_encode %{
 4435     __ strb($src$$Register, $mem$$Address);
 4436   %}
 4437   ins_pipe(istore_mem_reg);
 4438 %}
 4439 
 4440 // Store Char/Short
 4441 
 4442 
 4443 instruct storeC(memoryS mem, store_RegI src) %{
 4444   match(Set mem (StoreC mem src));
 4445   ins_cost(MEMORY_REF_COST);
 4446 
 4447   size(4);
 4448   format %{ "STRH    $src,$mem\t! short" %}
 4449   ins_encode %{
 4450     __ strh($src$$Register, $mem$$Address);
 4451   %}
 4452   ins_pipe(istore_mem_reg);
 4453 %}
 4454 
 4455 // Store Integer
 4456 
 4457 
 4458 instruct storeI(memoryI mem, store_RegI src) %{
 4459   match(Set mem (StoreI mem src));
 4460   ins_cost(MEMORY_REF_COST);
 4461 
 4462   size(4);
 4463   format %{ "str_32 $src,$mem" %}
 4464   ins_encode %{
 4465     __ str_32($src$$Register, $mem$$Address);
 4466   %}
 4467   ins_pipe(istore_mem_reg);
 4468 %}
 4469 
 4470 // Store Long
 4471 
 4472 
 4473 instruct storeL(memoryL mem, store_RegLd src) %{
 4474   predicate(!((StoreLNode*)n)->require_atomic_access());
 4475   match(Set mem (StoreL mem src));
 4476   ins_cost(MEMORY_REF_COST);
 4477 
 4478   size(4);
 4479   format %{ "str_64  $src,$mem\t! long\n\t" %}
 4480 
 4481   ins_encode %{
 4482     __ str_64($src$$Register, $mem$$Address);
 4483   %}
 4484   ins_pipe(istore_mem_reg);
 4485 %}
 4486 
 4487 instruct storeL_2instr(memorylong mem, iRegL src) %{
 4488   predicate(!((StoreLNode*)n)->require_atomic_access());
 4489   match(Set mem (StoreL mem src));
 4490   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
 4491 
 4492   size(8);
 4493   format %{ "STR    $src.lo,$mem\t! long\n\t"
 4494             "STR    $src.hi,$mem+4" %}
 4495 
 4496   ins_encode %{
 4497     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
 4498     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
 4499     __ str($src$$Register, Amemlo);
 4500     __ str($src$$Register->successor(), Amemhi);
 4501   %}
 4502   ins_pipe(istore_mem_reg);
 4503 %}
 4504 
 4505 instruct storeL_volatile(indirect mem, iRegL src) %{
 4506   predicate(((StoreLNode*)n)->require_atomic_access());
 4507   match(Set mem (StoreL mem src));
 4508   ins_cost(MEMORY_REF_COST);
 4509   size(4);
 4510   format %{ "STMIA    $src,$mem\t! long" %}
 4511   ins_encode %{
 4512     // FIXME: why is stmia considered atomic?  Should be strexd
 4513     RegisterSet set($src$$Register);
 4514     set = set | reg_to_register_object($src$$reg + 1);
 4515     __ stmia(reg_to_register_object($mem$$base), set);
 4516   %}
 4517   ins_pipe(istore_mem_reg);
 4518 %}
 4519 
 4520 instruct storeL_volatile_fp(memoryD mem, iRegL src) %{
 4521   predicate(((StoreLNode*)n)->require_atomic_access());
 4522   match(Set mem (StoreL mem src));
 4523   ins_cost(MEMORY_REF_COST);
 4524   size(8);
 4525   format %{ "FMDRR    S14, $src\t! long \n\t"
 4526             "FSTD     S14, $mem" %}
 4527   ins_encode %{
 4528     __ fmdrr(S14, $src$$Register, $src$$Register->successor());
 4529     __ fstd(S14, $mem$$Address);
 4530   %}
 4531   ins_pipe(istore_mem_reg);
 4532 %}
 4533 
 4534 #ifdef XXX
 4535 // Move SP Pointer
 4536 //instruct movSP(sp_ptr_RegP dst, SPRegP src) %{
 4537 //instruct movSP(iRegP dst, SPRegP src) %{
 4538 instruct movSP(store_ptr_RegP dst, SPRegP src) %{
 4539   match(Set dst src);
 4540 //predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con == TypeFunc::FramePtr);
 4541   ins_cost(MEMORY_REF_COST);
 4542   size(4);
 4543 
 4544   format %{ "MOV    $dst,$src\t! SP ptr\n\t" %}
 4545   ins_encode %{
 4546     assert(false, "XXX1 got here");
 4547     __ mov($dst$$Register, SP);
 4548     __ mov($dst$$Register, $src$$Register);
 4549   %}
 4550   ins_pipe(ialu_reg);
 4551 %}
 4552 #endif
 4553 
 4554 
 4555 // Store Pointer
 4556 
 4557 
 4558 instruct storeP(memoryP mem, store_ptr_RegP src) %{
 4559   match(Set mem (StoreP mem src));
 4560   ins_cost(MEMORY_REF_COST);
 4561   size(4);
 4562 
 4563   format %{ "STR    $src,$mem\t! ptr" %}
 4564   ins_encode %{
 4565     __ str($src$$Register, $mem$$Address);
 4566   %}
 4567   ins_pipe(istore_mem_spORreg);
 4568 %}
 4569 
 4570 
 4571 #ifdef _LP64
 4572 // Store Compressed Pointer
 4573 
 4574 
 4575 instruct storeN(memoryI mem, store_RegN src) %{
 4576   match(Set mem (StoreN mem src));
 4577   ins_cost(MEMORY_REF_COST);
 4578   size(4);
 4579 
 4580   format %{ "str_32 $src,$mem\t! compressed ptr" %}
 4581   ins_encode %{
 4582     __ str_32($src$$Register, $mem$$Address);
 4583   %}
 4584   ins_pipe(istore_mem_reg);
 4585 %}
 4586 
 4587 
 4588 // Store Compressed Klass Pointer
 4589 instruct storeNKlass(memoryI mem, store_RegN src) %{
 4590   match(Set mem (StoreNKlass mem src));
 4591   ins_cost(MEMORY_REF_COST);
 4592   size(4);
 4593 
 4594   format %{ "str_32 $src,$mem\t! compressed klass ptr" %}
 4595   ins_encode %{
 4596     __ str_32($src$$Register, $mem$$Address);
 4597   %}
 4598   ins_pipe(istore_mem_reg);
 4599 %}
 4600 #endif
 4601 
 4602 // Store Double
 4603 
 4604 
 4605 instruct storeD(memoryD mem, regD src) %{
 4606   match(Set mem (StoreD mem src));
 4607   ins_cost(MEMORY_REF_COST);
 4608 
 4609   size(4);
 4610   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
 4611   // only LDREXD and STREXD are 64-bit single-copy atomic
 4612   format %{ "FSTD   $src,$mem" %}
 4613   ins_encode %{
 4614     __ str_double($src$$FloatRegister, $mem$$Address);
 4615   %}
 4616   ins_pipe(fstoreD_mem_reg);
 4617 %}
 4618 
 4619 
 4620 // Store Float
 4621 
 4622 
 4623 instruct storeF( memoryF mem, regF src) %{
 4624   match(Set mem (StoreF mem src));
 4625   ins_cost(MEMORY_REF_COST);
 4626 
 4627   size(4);
 4628   format %{ "FSTS    $src,$mem" %}
 4629   ins_encode %{
 4630     __ str_float($src$$FloatRegister, $mem$$Address);
 4631   %}
 4632   ins_pipe(fstoreF_mem_reg);
 4633 %}
 4634 
 4635 
 4636 //----------MemBar Instructions-----------------------------------------------
 4637 // Memory barrier flavors
 4638 
 4639 // pattern-match out unnecessary membars
 4640 instruct membar_storestore() %{
 4641   match(MemBarStoreStore);
 4642   ins_cost(4*MEMORY_REF_COST);
 4643 
 4644   size(4);
 4645   format %{ "MEMBAR-storestore" %}
 4646   ins_encode %{
 4647     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore), noreg);
 4648   %}
 4649   ins_pipe(long_memory_op);
 4650 %}
 4651 
 4652 instruct membar_acquire() %{
 4653   match(MemBarAcquire);
 4654   match(LoadFence);
 4655   ins_cost(4*MEMORY_REF_COST);
 4656 
 4657   size(4);
 4658   format %{ "MEMBAR-acquire" %}
 4659   ins_encode %{
 4660     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), noreg);
 4661   %}
 4662   ins_pipe(long_memory_op);
 4663 %}
 4664 
 4665 instruct membar_acquire_lock() %{
 4666   match(MemBarAcquireLock);
 4667   ins_cost(0);
 4668 
 4669   size(0);
 4670   format %{ "!MEMBAR-acquire (CAS in prior FastLock so empty encoding)" %}
 4671   ins_encode( );
 4672   ins_pipe(empty);
 4673 %}
 4674 
 4675 instruct membar_release() %{
 4676   match(MemBarRelease);
 4677   match(StoreFence);
 4678   ins_cost(4*MEMORY_REF_COST);
 4679 
 4680   size(4);
 4681   format %{ "MEMBAR-release" %}
 4682   ins_encode %{
 4683     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), noreg);
 4684   %}
 4685   ins_pipe(long_memory_op);
 4686 %}
 4687 
 4688 instruct membar_release_lock() %{
 4689   match(MemBarReleaseLock);
 4690   ins_cost(0);
 4691 
 4692   size(0);
 4693   format %{ "!MEMBAR-release (CAS in succeeding FastUnlock so empty encoding)" %}
 4694   ins_encode( );
 4695   ins_pipe(empty);
 4696 %}
 4697 
 4698 instruct membar_volatile() %{
 4699   match(MemBarVolatile);
 4700   ins_cost(4*MEMORY_REF_COST);
 4701 
 4702   size(4);
 4703   format %{ "MEMBAR-volatile" %}
 4704   ins_encode %{
 4705     __ membar(MacroAssembler::StoreLoad, noreg);
 4706   %}
 4707   ins_pipe(long_memory_op);
 4708 %}
 4709 
 4710 instruct unnecessary_membar_volatile() %{
 4711   match(MemBarVolatile);
 4712   predicate(Matcher::post_store_load_barrier(n));
 4713   ins_cost(0);
 4714 
 4715   size(0);
 4716   format %{ "!MEMBAR-volatile (unnecessary so empty encoding)" %}
 4717   ins_encode( );
 4718   ins_pipe(empty);
 4719 %}
 4720 
 4721 //----------Register Move Instructions-----------------------------------------
 4722 // instruct roundDouble_nop(regD dst) %{
 4723 //   match(Set dst (RoundDouble dst));
 4724 //   ins_pipe(empty);
 4725 // %}
 4726 
 4727 
 4728 // instruct roundFloat_nop(regF dst) %{
 4729 //   match(Set dst (RoundFloat dst));
 4730 //   ins_pipe(empty);
 4731 // %}
 4732 
 4733 
 4734 
 4735 // Cast Index to Pointer for unsafe natives
 4736 instruct castX2P(iRegX src, iRegP dst) %{
 4737   match(Set dst (CastX2P src));
 4738 
 4739   format %{ "MOV    $dst,$src\t! IntX->Ptr if $dst != $src" %}
 4740   ins_encode %{
 4741     if ($dst$$Register !=  $src$$Register) {
 4742       __ mov($dst$$Register, $src$$Register);
 4743     }
 4744   %}
 4745   ins_pipe(ialu_reg);
 4746 %}
 4747 
 4748 // Cast Pointer to Index for unsafe natives
 4749 instruct castP2X(iRegP src, iRegX dst) %{
 4750   match(Set dst (CastP2X src));
 4751 
 4752   format %{ "MOV    $dst,$src\t! Ptr->IntX if $dst != $src" %}
 4753   ins_encode %{
 4754     if ($dst$$Register !=  $src$$Register) {
 4755       __ mov($dst$$Register, $src$$Register);
 4756     }
 4757   %}
 4758   ins_pipe(ialu_reg);
 4759 %}
 4760 
 4761 //----------Conditional Move---------------------------------------------------
 4762 // Conditional move
 4763 instruct cmovIP_reg(cmpOpP cmp, flagsRegP pcc, iRegI dst, iRegI src) %{
 4764   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
 4765   ins_cost(150);
 4766   size(4);
 4767   format %{ "MOV$cmp  $dst,$src\t! int" %}
 4768   ins_encode %{
 4769     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4770   %}
 4771   ins_pipe(ialu_reg);
 4772 %}
 4773 
 4774 
 4775 instruct cmovIP_immMov(cmpOpP cmp, flagsRegP pcc, iRegI dst, immIMov src) %{
 4776   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
 4777   ins_cost(140);
 4778   size(4);
 4779   format %{ "MOV$cmp  $dst,$src" %}
 4780   ins_encode %{
 4781     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4782   %}
 4783   ins_pipe(ialu_imm);
 4784 %}
 4785 
 4786 instruct cmovIP_imm16(cmpOpP cmp, flagsRegP pcc, iRegI dst, immI16 src) %{
 4787   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
 4788   ins_cost(140);
 4789   size(4);
 4790   format %{ "MOVw$cmp  $dst,$src" %}
 4791   ins_encode %{
 4792     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4793   %}
 4794   ins_pipe(ialu_imm);
 4795 %}
 4796 
 4797 instruct cmovI_reg(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src) %{
 4798   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4799   ins_cost(150);
 4800   size(4);
 4801   format %{ "MOV$cmp  $dst,$src" %}
 4802   ins_encode %{
 4803     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4804   %}
 4805   ins_pipe(ialu_reg);
 4806 %}
 4807 
 4808 
 4809 instruct cmovI_immMov(cmpOp cmp, flagsReg icc, iRegI dst, immIMov src) %{
 4810   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4811   ins_cost(140);
 4812   size(4);
 4813   format %{ "MOV$cmp  $dst,$src" %}
 4814   ins_encode %{
 4815     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4816   %}
 4817   ins_pipe(ialu_imm);
 4818 %}
 4819 
 4820 instruct cmovII_imm16(cmpOp cmp, flagsReg icc, iRegI dst, immI16 src) %{
 4821   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4822   ins_cost(140);
 4823   size(4);
 4824   format %{ "MOVw$cmp  $dst,$src" %}
 4825   ins_encode %{
 4826     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4827   %}
 4828   ins_pipe(ialu_imm);
 4829 %}
 4830 
 4831 instruct cmovII_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, iRegI src) %{
 4832   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4833   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4834             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4835             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4836             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4837   ins_cost(150);
 4838   size(4);
 4839   format %{ "MOV$cmp  $dst,$src" %}
 4840   ins_encode %{
 4841     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4842   %}
 4843   ins_pipe(ialu_reg);
 4844 %}
 4845 
 4846 instruct cmovII_immMov_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immIMov src) %{
 4847   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4848   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4849             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4850             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4851             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4852   ins_cost(140);
 4853   size(4);
 4854   format %{ "MOV$cmp  $dst,$src" %}
 4855   ins_encode %{
 4856     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4857   %}
 4858   ins_pipe(ialu_imm);
 4859 %}
 4860 
 4861 instruct cmovII_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immI16 src) %{
 4862   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4863   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4864             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4865             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4866             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4867   ins_cost(140);
 4868   size(4);
 4869   format %{ "MOVW$cmp  $dst,$src" %}
 4870   ins_encode %{
 4871     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4872   %}
 4873   ins_pipe(ialu_imm);
 4874 %}
 4875 
 4876 instruct cmovIIu_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
 4877   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4878   ins_cost(150);
 4879   size(4);
 4880   format %{ "MOV$cmp  $dst,$src" %}
 4881   ins_encode %{
 4882     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4883   %}
 4884   ins_pipe(ialu_reg);
 4885 %}
 4886 
 4887 instruct cmovIIu_immMov(cmpOpU cmp, flagsRegU icc, iRegI dst, immIMov src) %{
 4888   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4889   ins_cost(140);
 4890   size(4);
 4891   format %{ "MOV$cmp  $dst,$src" %}
 4892   ins_encode %{
 4893     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4894   %}
 4895   ins_pipe(ialu_imm);
 4896 %}
 4897 
 4898 instruct cmovIIu_imm16(cmpOpU cmp, flagsRegU icc, iRegI dst, immI16 src) %{
 4899   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
 4900   ins_cost(140);
 4901   size(4);
 4902   format %{ "MOVW$cmp  $dst,$src" %}
 4903   ins_encode %{
 4904     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4905   %}
 4906   ins_pipe(ialu_imm);
 4907 %}
 4908 
 4909 // Conditional move
 4910 instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{
 4911   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
 4912   ins_cost(150);
 4913   size(4);
 4914   format %{ "MOV$cmp  $dst,$src" %}
 4915   ins_encode %{
 4916     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4917   %}
 4918   ins_pipe(ialu_reg);
 4919 %}
 4920 
 4921 instruct cmovPP_imm(cmpOpP cmp, flagsRegP pcc, iRegP dst, immP0 src) %{
 4922   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
 4923   ins_cost(140);
 4924   size(4);
 4925   format %{ "MOV$cmp  $dst,$src" %}
 4926   ins_encode %{
 4927     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4928   %}
 4929   ins_pipe(ialu_imm);
 4930 %}
 4931 
 4932 // This instruction also works with CmpN so we don't need cmovPN_reg.
 4933 instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{
 4934   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4935   ins_cost(150);
 4936 
 4937   size(4);
 4938   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4939   ins_encode %{
 4940     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4941   %}
 4942   ins_pipe(ialu_reg);
 4943 %}
 4944 
 4945 instruct cmovPI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, iRegP src) %{
 4946   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4947   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4948             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4949             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4950             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4951   ins_cost(150);
 4952 
 4953   size(4);
 4954   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4955   ins_encode %{
 4956     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4957   %}
 4958   ins_pipe(ialu_reg);
 4959 %}
 4960 
 4961 instruct cmovPIu_reg(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src) %{
 4962   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4963   ins_cost(150);
 4964 
 4965   size(4);
 4966   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4967   ins_encode %{
 4968     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 4969   %}
 4970   ins_pipe(ialu_reg);
 4971 %}
 4972 
 4973 instruct cmovPI_imm(cmpOp cmp, flagsReg icc, iRegP dst, immP0 src) %{
 4974   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4975   ins_cost(140);
 4976 
 4977   size(4);
 4978   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4979   ins_encode %{
 4980     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4981   %}
 4982   ins_pipe(ialu_imm);
 4983 %}
 4984 
 4985 instruct cmovPI_imm_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, immP0 src) %{
 4986   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 4987   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 4988             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 4989             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 4990             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 4991   ins_cost(140);
 4992 
 4993   size(4);
 4994   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 4995   ins_encode %{
 4996     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 4997   %}
 4998   ins_pipe(ialu_imm);
 4999 %}
 5000 
 5001 instruct cmovPIu_imm(cmpOpU cmp, flagsRegU icc, iRegP dst, immP0 src) %{
 5002   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
 5003   ins_cost(140);
 5004 
 5005   size(4);
 5006   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
 5007   ins_encode %{
 5008     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5009   %}
 5010   ins_pipe(ialu_imm);
 5011 %}
 5012 
 5013 
 5014 // Conditional move
 5015 instruct cmovFP_reg(cmpOpP cmp, flagsRegP pcc, regF dst, regF src) %{
 5016   match(Set dst (CMoveF (Binary cmp pcc) (Binary dst src)));
 5017   ins_cost(150);
 5018   size(4);
 5019   format %{ "FCPYS$cmp $dst,$src" %}
 5020   ins_encode %{
 5021     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 5022   %}
 5023   ins_pipe(int_conditional_float_move);
 5024 %}
 5025 
 5026 instruct cmovFI_reg(cmpOp cmp, flagsReg icc, regF dst, regF src) %{
 5027   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
 5028   ins_cost(150);
 5029 
 5030   size(4);
 5031   format %{ "FCPYS$cmp $dst,$src" %}
 5032   ins_encode %{
 5033     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 5034   %}
 5035   ins_pipe(int_conditional_float_move);
 5036 %}
 5037 
 5038 instruct cmovFI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regF dst, regF src) %{
 5039   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
 5040   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 5041             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 5042             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 5043             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 5044   ins_cost(150);
 5045 
 5046   size(4);
 5047   format %{ "FCPYS$cmp $dst,$src" %}
 5048   ins_encode %{
 5049     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 5050   %}
 5051   ins_pipe(int_conditional_float_move);
 5052 %}
 5053 
 5054 instruct cmovFIu_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src) %{
 5055   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
 5056   ins_cost(150);
 5057 
 5058   size(4);
 5059   format %{ "FCPYS$cmp $dst,$src" %}
 5060   ins_encode %{
 5061     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 5062   %}
 5063   ins_pipe(int_conditional_float_move);
 5064 %}
 5065 
 5066 // Conditional move
 5067 instruct cmovDP_reg(cmpOpP cmp, flagsRegP pcc, regD dst, regD src) %{
 5068   match(Set dst (CMoveD (Binary cmp pcc) (Binary dst src)));
 5069   ins_cost(150);
 5070   size(4);
 5071   format %{ "FCPYD$cmp $dst,$src" %}
 5072   ins_encode %{
 5073     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 5074   %}
 5075   ins_pipe(int_conditional_double_move);
 5076 %}
 5077 
 5078 instruct cmovDI_reg(cmpOp cmp, flagsReg icc, regD dst, regD src) %{
 5079   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
 5080   ins_cost(150);
 5081 
 5082   size(4);
 5083   format %{ "FCPYD$cmp $dst,$src" %}
 5084   ins_encode %{
 5085     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 5086   %}
 5087   ins_pipe(int_conditional_double_move);
 5088 %}
 5089 
 5090 instruct cmovDI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regD dst, regD src) %{
 5091   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
 5092   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);
 5093   ins_cost(150);
 5094 
 5095   size(4);
 5096   format %{ "FCPYD$cmp $dst,$src" %}
 5097   ins_encode %{
 5098     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 5099   %}
 5100   ins_pipe(int_conditional_double_move);
 5101 %}
 5102 
 5103 instruct cmovDIu_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src) %{
 5104   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
 5105   ins_cost(150);
 5106 
 5107   size(4);
 5108   format %{ "FCPYD$cmp $dst,$src" %}
 5109   ins_encode %{
 5110     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 5111   %}
 5112   ins_pipe(int_conditional_double_move);
 5113 %}
 5114 
 5115 // Conditional move
 5116 instruct cmovLP_reg(cmpOpP cmp, flagsRegP pcc, iRegL dst, iRegL src) %{
 5117   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
 5118   ins_cost(150);
 5119 
 5120   size(8);
 5121   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 5122             "MOV$cmp  $dst.hi,$src.hi" %}
 5123   ins_encode %{
 5124     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 5125     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 5126   %}
 5127   ins_pipe(ialu_reg);
 5128 %}
 5129 
 5130 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5131 // (hi($con$$constant), lo($con$$constant)) becomes
 5132 instruct cmovLP_immRot(cmpOpP cmp, flagsRegP pcc, iRegL dst, immLlowRot src) %{
 5133   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
 5134   ins_cost(140);
 5135 
 5136   size(8);
 5137   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5138             "MOV$cmp  $dst.hi,0" %}
 5139   ins_encode %{
 5140     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5141     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5142   %}
 5143   ins_pipe(ialu_imm);
 5144 %}
 5145 
 5146 instruct cmovLP_imm16(cmpOpP cmp, flagsRegP pcc, iRegL dst, immL16 src) %{
 5147   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
 5148   ins_cost(140);
 5149 
 5150   size(8);
 5151   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5152             "MOV$cmp  $dst.hi,0" %}
 5153   ins_encode %{
 5154     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5155     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5156   %}
 5157   ins_pipe(ialu_imm);
 5158 %}
 5159 
 5160 instruct cmovLI_reg(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src) %{
 5161   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5162   ins_cost(150);
 5163 
 5164   size(8);
 5165   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 5166             "MOV$cmp  $dst.hi,$src.hi" %}
 5167   ins_encode %{
 5168     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 5169     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 5170   %}
 5171   ins_pipe(ialu_reg);
 5172 %}
 5173 
 5174 instruct cmovLI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, iRegL src) %{
 5175   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5176   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 5177             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 5178             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 5179             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 5180   ins_cost(150);
 5181 
 5182   size(8);
 5183   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 5184             "MOV$cmp  $dst.hi,$src.hi" %}
 5185   ins_encode %{
 5186     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 5187     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 5188   %}
 5189   ins_pipe(ialu_reg);
 5190 %}
 5191 
 5192 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5193 // (hi($con$$constant), lo($con$$constant)) becomes
 5194 instruct cmovLI_immRot(cmpOp cmp, flagsReg icc, iRegL dst, immLlowRot src) %{
 5195   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5196   ins_cost(140);
 5197 
 5198   size(8);
 5199   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5200             "MOV$cmp  $dst.hi,0" %}
 5201   ins_encode %{
 5202     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5203     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5204   %}
 5205   ins_pipe(ialu_imm);
 5206 %}
 5207 
 5208 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5209 // (hi($con$$constant), lo($con$$constant)) becomes
 5210 instruct cmovLI_immRot_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immLlowRot src) %{
 5211   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5212   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 5213             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 5214             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 5215             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 5216   ins_cost(140);
 5217 
 5218   size(8);
 5219   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5220             "MOV$cmp  $dst.hi,0" %}
 5221   ins_encode %{
 5222     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5223     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5224   %}
 5225   ins_pipe(ialu_imm);
 5226 %}
 5227 
 5228 instruct cmovLI_imm16(cmpOp cmp, flagsReg icc, iRegL dst, immL16 src) %{
 5229   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5230   ins_cost(140);
 5231 
 5232   size(8);
 5233   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5234             "MOV$cmp  $dst.hi,0" %}
 5235   ins_encode %{
 5236     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5237     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5238   %}
 5239   ins_pipe(ialu_imm);
 5240 %}
 5241 
 5242 instruct cmovLI_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immL16 src) %{
 5243   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5244   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
 5245             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
 5246             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
 5247             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 5248   ins_cost(140);
 5249 
 5250   size(8);
 5251   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
 5252             "MOV$cmp  $dst.hi,0" %}
 5253   ins_encode %{
 5254     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 5255     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 5256   %}
 5257   ins_pipe(ialu_imm);
 5258 %}
 5259 
 5260 instruct cmovLIu_reg(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src) %{
 5261   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
 5262   ins_cost(150);
 5263 
 5264   size(8);
 5265   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 5266             "MOV$cmp  $dst.hi,$src.hi" %}
 5267   ins_encode %{
 5268     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 5269     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 5270   %}
 5271   ins_pipe(ialu_reg);
 5272 %}
 5273 
 5274 
 5275 //----------OS and Locking Instructions----------------------------------------
 5276 
 5277 // This name is KNOWN by the ADLC and cannot be changed.
 5278 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
 5279 // for this guy.
 5280 instruct tlsLoadP(RthreadRegP dst) %{
 5281   match(Set dst (ThreadLocal));
 5282 
 5283   size(0);
 5284   ins_cost(0);
 5285   format %{ "! TLS is in $dst" %}
 5286   ins_encode( /*empty encoding*/ );
 5287   ins_pipe(ialu_none);
 5288 %}
 5289 
 5290 instruct checkCastPP( iRegP dst ) %{
 5291   match(Set dst (CheckCastPP dst));
 5292 
 5293   size(0);
 5294   format %{ "! checkcastPP of $dst" %}
 5295   ins_encode( /*empty encoding*/ );
 5296   ins_pipe(empty);
 5297 %}
 5298 
 5299 
 5300 instruct castPP( iRegP dst ) %{
 5301   match(Set dst (CastPP dst));
 5302   format %{ "! castPP of $dst" %}
 5303   ins_encode( /*empty encoding*/ );
 5304   ins_pipe(empty);
 5305 %}
 5306 
 5307 instruct castII( iRegI dst ) %{
 5308   match(Set dst (CastII dst));
 5309   format %{ "! castII of $dst" %}
 5310   ins_encode( /*empty encoding*/ );
 5311   ins_cost(0);
 5312   ins_pipe(empty);
 5313 %}
 5314 
 5315 //----------Arithmetic Instructions--------------------------------------------
 5316 // Addition Instructions
 5317 // Register Addition
 5318 instruct addI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 5319   match(Set dst (AddI src1 src2));
 5320 
 5321   size(4);
 5322   format %{ "add_32 $dst,$src1,$src2\t! int" %}
 5323   ins_encode %{
 5324     __ add_32($dst$$Register, $src1$$Register, $src2$$Register);
 5325   %}
 5326   ins_pipe(ialu_reg_reg);
 5327 %}
 5328 
 5329 instruct addshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5330   match(Set dst (AddI (LShiftI src1 src2) src3));
 5331 
 5332   size(4);
 5333   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
 5334   ins_encode %{
 5335     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 5336   %}
 5337   ins_pipe(ialu_reg_reg);
 5338 %}
 5339 
 5340 
 5341 instruct addshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5342   match(Set dst (AddI (LShiftI src1 src2) src3));
 5343 
 5344   size(4);
 5345   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
 5346   ins_encode %{
 5347     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
 5348   %}
 5349   ins_pipe(ialu_reg_reg);
 5350 %}
 5351 
 5352 instruct addsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5353   match(Set dst (AddI (RShiftI src1 src2) src3));
 5354 
 5355   size(4);
 5356   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
 5357   ins_encode %{
 5358     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
 5359   %}
 5360   ins_pipe(ialu_reg_reg);
 5361 %}
 5362 
 5363 instruct addsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5364   match(Set dst (AddI (RShiftI src1 src2) src3));
 5365 
 5366   size(4);
 5367   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
 5368   ins_encode %{
 5369     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
 5370   %}
 5371   ins_pipe(ialu_reg_reg);
 5372 %}
 5373 
 5374 instruct addshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5375   match(Set dst (AddI (URShiftI src1 src2) src3));
 5376 
 5377   size(4);
 5378   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
 5379   ins_encode %{
 5380     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 5381   %}
 5382   ins_pipe(ialu_reg_reg);
 5383 %}
 5384 
 5385 instruct addshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5386   match(Set dst (AddI (URShiftI src1 src2) src3));
 5387 
 5388   size(4);
 5389   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
 5390   ins_encode %{
 5391     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 5392   %}
 5393   ins_pipe(ialu_reg_reg);
 5394 %}
 5395 
 5396 // Immediate Addition
 5397 instruct addI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
 5398   match(Set dst (AddI src1 src2));
 5399 
 5400   size(4);
 5401   format %{ "add_32 $dst,$src1,$src2\t! int" %}
 5402   ins_encode %{
 5403     __ add_32($dst$$Register, $src1$$Register, $src2$$constant);
 5404   %}
 5405   ins_pipe(ialu_reg_imm);
 5406 %}
 5407 
 5408 // Pointer Register Addition
 5409 instruct addP_reg_reg(iRegP dst, iRegP src1, iRegX src2) %{
 5410   match(Set dst (AddP src1 src2));
 5411 
 5412   size(4);
 5413   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
 5414   ins_encode %{
 5415     __ add($dst$$Register, $src1$$Register, $src2$$Register);
 5416   %}
 5417   ins_pipe(ialu_reg_reg);
 5418 %}
 5419 
 5420 
 5421 // shifted iRegX operand
 5422 operand shiftedX(iRegX src2, shimmX src3) %{
 5423 //constraint(ALLOC_IN_RC(sp_ptr_reg));
 5424   match(LShiftX src2 src3);
 5425 
 5426   op_cost(1);
 5427   format %{ "$src2 << $src3" %}
 5428   interface(MEMORY_INTER) %{
 5429     base($src2);
 5430     index(0xff);
 5431     scale($src3);
 5432     disp(0x0);
 5433   %}
 5434 %}
 5435 
 5436 instruct addshlP_reg_reg_imm(iRegP dst, iRegP src1, shiftedX src2) %{
 5437   match(Set dst (AddP src1 src2));
 5438 
 5439   ins_cost(DEFAULT_COST * 3/2);
 5440   size(4);
 5441   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
 5442   ins_encode %{
 5443     Register base = reg_to_register_object($src2$$base);
 5444     __ add($dst$$Register, $src1$$Register, AsmOperand(base, lsl, $src2$$scale));
 5445   %}
 5446   ins_pipe(ialu_reg_reg);
 5447 %}
 5448 
 5449 // Pointer Immediate Addition
 5450 instruct addP_reg_aimmX(iRegP dst, iRegP src1, aimmX src2) %{
 5451   match(Set dst (AddP src1 src2));
 5452 
 5453   size(4);
 5454   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
 5455   ins_encode %{
 5456     __ add($dst$$Register, $src1$$Register, $src2$$constant);
 5457   %}
 5458   ins_pipe(ialu_reg_imm);
 5459 %}
 5460 
 5461 // Long Addition
 5462 instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg ccr) %{
 5463   match(Set dst (AddL src1 src2));
 5464   effect(KILL ccr);
 5465   size(8);
 5466   format %{ "ADDS    $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
 5467             "ADC     $dst.hi,$src1.hi,$src2.hi" %}
 5468   ins_encode %{
 5469     __ adds($dst$$Register, $src1$$Register, $src2$$Register);
 5470     __ adc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 5471   %}
 5472   ins_pipe(ialu_reg_reg);
 5473 %}
 5474 
 5475 // TODO
 5476 
 5477 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5478 // (hi($con$$constant), lo($con$$constant)) becomes
 5479 instruct addL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg ccr) %{
 5480   match(Set dst (AddL src1 con));
 5481   effect(KILL ccr);
 5482   size(8);
 5483   format %{ "ADDS    $dst.lo,$src1.lo,$con\t! long\n\t"
 5484             "ADC     $dst.hi,$src1.hi,0" %}
 5485   ins_encode %{
 5486     __ adds($dst$$Register, $src1$$Register, $con$$constant);
 5487     __ adc($dst$$Register->successor(), $src1$$Register->successor(), 0);
 5488   %}
 5489   ins_pipe(ialu_reg_imm);
 5490 %}
 5491 
 5492 //----------Conditional_store--------------------------------------------------
 5493 // Conditional-store of the updated heap-top.
 5494 // Used during allocation of the shared heap.
 5495 // Sets flags (EQ) on success.
 5496 
 5497 // LoadP-locked.
 5498 instruct loadPLocked(iRegP dst, memoryex mem) %{
 5499   match(Set dst (LoadPLocked mem));
 5500   size(4);
 5501   format %{ "LDREX  $dst,$mem" %}
 5502   ins_encode %{
 5503     __ ldrex($dst$$Register,$mem$$Address);
 5504   %}
 5505   ins_pipe(iload_mem);
 5506 %}
 5507 
 5508 instruct storePConditional( memoryex heap_top_ptr, iRegP oldval, iRegP newval, iRegI tmp, flagsRegP pcc ) %{
 5509   predicate(_kids[1]->_kids[0]->_leaf->Opcode() == Op_LoadPLocked); // only works in conjunction with a LoadPLocked node
 5510   match(Set pcc (StorePConditional heap_top_ptr (Binary oldval newval)));
 5511   effect( TEMP tmp );
 5512   size(8);
 5513   format %{ "STREX  $tmp,$newval,$heap_top_ptr\n\t"
 5514             "CMP    $tmp, 0" %}
 5515   ins_encode %{
 5516     __ strex($tmp$$Register, $newval$$Register, $heap_top_ptr$$Address);
 5517     __ cmp($tmp$$Register, 0);
 5518   %}
 5519   ins_pipe( long_memory_op );
 5520 %}
 5521 
 5522 // Conditional-store of an intx value.
 5523 instruct storeXConditional( memoryex mem, iRegX oldval, iRegX newval, iRegX tmp, flagsReg icc ) %{
 5524   match(Set icc (StoreIConditional mem (Binary oldval newval)));
 5525   effect( TEMP tmp );
 5526   size(28);
 5527   format %{ "loop: \n\t"
 5528             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem], DOESN'T set $newval=[$mem] in any case\n\t"
 5529             "XORS     $tmp,$tmp, $oldval\n\t"
 5530             "STREX.eq $tmp, $newval, $mem\n\t"
 5531             "CMP.eq   $tmp, 1 \n\t"
 5532             "B.eq     loop \n\t"
 5533             "TEQ      $tmp, 0\n\t"
 5534             "membar   LoadStore|LoadLoad" %}
 5535   ins_encode %{
 5536     Label loop;
 5537     __ bind(loop);
 5538     __ ldrex($tmp$$Register, $mem$$Address);
 5539     __ eors($tmp$$Register, $tmp$$Register, $oldval$$Register);
 5540     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5541     __ cmp($tmp$$Register, 1, eq);
 5542     __ b(loop, eq);
 5543     __ teq($tmp$$Register, 0);
 5544     // used by biased locking only. Requires a membar.
 5545     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadStore | MacroAssembler::LoadLoad), noreg);
 5546   %}
 5547   ins_pipe( long_memory_op );
 5548 %}
 5549 
 5550 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
 5551 
 5552 instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegLd newval, iRegI res, iRegLd tmp, flagsReg ccr ) %{
 5553   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
 5554   effect( KILL ccr, TEMP tmp);
 5555   size(32);
 5556   format %{ "loop: \n\t"
 5557             "LDREXD   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
 5558             "CMP      $tmp.lo, $oldval.lo\n\t"
 5559             "CMP.eq   $tmp.hi, $oldval.hi\n\t"
 5560             "STREXD.eq $tmp, $newval, $mem\n\t"
 5561             "MOV.ne   $tmp, 0 \n\t"
 5562             "XORS.eq  $tmp,$tmp, 1 \n\t"
 5563             "B.eq     loop \n\t"
 5564             "MOV      $res, $tmp" %}
 5565   ins_encode %{
 5566     Label loop;
 5567     __ bind(loop);
 5568     __ ldrexd($tmp$$Register, $mem$$Address);
 5569     __ cmp($tmp$$Register, $oldval$$Register);
 5570     __ cmp($tmp$$Register->successor(), $oldval$$Register->successor(), eq);
 5571     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5572     __ mov($tmp$$Register, 0, ne);
 5573     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
 5574     __ b(loop, eq);
 5575     __ mov($res$$Register, $tmp$$Register);
 5576   %}
 5577   ins_pipe( long_memory_op );
 5578 %}
 5579 
 5580 
 5581 instruct compareAndSwapI_bool(memoryex mem, iRegI oldval, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
 5582   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
 5583   effect( KILL ccr, TEMP tmp);
 5584   size(28);
 5585   format %{ "loop: \n\t"
 5586             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
 5587             "CMP      $tmp, $oldval\n\t"
 5588             "STREX.eq $tmp, $newval, $mem\n\t"
 5589             "MOV.ne   $tmp, 0 \n\t"
 5590             "XORS.eq  $tmp,$tmp, 1 \n\t"
 5591             "B.eq     loop \n\t"
 5592             "MOV      $res, $tmp" %}
 5593 
 5594   ins_encode %{
 5595     Label loop;
 5596     __ bind(loop);
 5597     __ ldrex($tmp$$Register,$mem$$Address);
 5598     __ cmp($tmp$$Register, $oldval$$Register);
 5599     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5600     __ mov($tmp$$Register, 0, ne);
 5601     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
 5602     __ b(loop, eq);
 5603     __ mov($res$$Register, $tmp$$Register);
 5604   %}
 5605   ins_pipe( long_memory_op );
 5606 %}
 5607 
 5608 instruct compareAndSwapP_bool(memoryex mem, iRegP oldval, iRegP newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
 5609   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
 5610   effect( KILL ccr, TEMP tmp);
 5611   size(28);
 5612   format %{ "loop: \n\t"
 5613             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
 5614             "CMP      $tmp, $oldval\n\t"
 5615             "STREX.eq $tmp, $newval, $mem\n\t"
 5616             "MOV.ne   $tmp, 0 \n\t"
 5617             "EORS.eq  $tmp,$tmp, 1 \n\t"
 5618             "B.eq     loop \n\t"
 5619             "MOV      $res, $tmp" %}
 5620 
 5621   ins_encode %{
 5622     Label loop;
 5623     __ bind(loop);
 5624     __ ldrex($tmp$$Register,$mem$$Address);
 5625     __ cmp($tmp$$Register, $oldval$$Register);
 5626     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
 5627     __ mov($tmp$$Register, 0, ne);
 5628     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
 5629     __ b(loop, eq);
 5630     __ mov($res$$Register, $tmp$$Register);
 5631   %}
 5632   ins_pipe( long_memory_op );
 5633 %}
 5634 
 5635 instruct xaddI_aimmI_no_res(memoryex mem, aimmI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5636   predicate(n->as_LoadStore()->result_not_used());
 5637   match(Set dummy (GetAndAddI mem add));
 5638   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
 5639   size(20);
 5640   format %{ "loop: \n\t"
 5641             "LDREX    $tmp1, $mem\n\t"
 5642             "ADD      $tmp1, $tmp1, $add\n\t"
 5643             "STREX    $tmp2, $tmp1, $mem\n\t"
 5644             "CMP      $tmp2, 0 \n\t"
 5645             "B.ne     loop \n\t" %}
 5646 
 5647   ins_encode %{
 5648     Label loop;
 5649     __ bind(loop);
 5650     __ ldrex($tmp1$$Register,$mem$$Address);
 5651     __ add($tmp1$$Register, $tmp1$$Register, $add$$constant);
 5652     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5653     __ cmp($tmp2$$Register, 0);
 5654     __ b(loop, ne);
 5655   %}
 5656   ins_pipe( long_memory_op );
 5657 %}
 5658 
 5659 instruct xaddI_reg_no_res(memoryex mem, iRegI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5660   predicate(n->as_LoadStore()->result_not_used());
 5661   match(Set dummy (GetAndAddI mem add));
 5662   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
 5663   size(20);
 5664   format %{ "loop: \n\t"
 5665             "LDREX    $tmp1, $mem\n\t"
 5666             "ADD      $tmp1, $tmp1, $add\n\t"
 5667             "STREX    $tmp2, $tmp1, $mem\n\t"
 5668             "CMP      $tmp2, 0 \n\t"
 5669             "B.ne     loop \n\t" %}
 5670 
 5671   ins_encode %{
 5672     Label loop;
 5673     __ bind(loop);
 5674     __ ldrex($tmp1$$Register,$mem$$Address);
 5675     __ add($tmp1$$Register, $tmp1$$Register, $add$$Register);
 5676     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5677     __ cmp($tmp2$$Register, 0);
 5678     __ b(loop, ne);
 5679   %}
 5680   ins_pipe( long_memory_op );
 5681 %}
 5682 
 5683 instruct xaddI_aimmI(memoryex mem, aimmI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5684   match(Set res (GetAndAddI mem add));
 5685   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5686   size(20);
 5687   format %{ "loop: \n\t"
 5688             "LDREX    $res, $mem\n\t"
 5689             "ADD      $tmp1, $res, $add\n\t"
 5690             "STREX    $tmp2, $tmp1, $mem\n\t"
 5691             "CMP      $tmp2, 0 \n\t"
 5692             "B.ne     loop \n\t" %}
 5693 
 5694   ins_encode %{
 5695     Label loop;
 5696     __ bind(loop);
 5697     __ ldrex($res$$Register,$mem$$Address);
 5698     __ add($tmp1$$Register, $res$$Register, $add$$constant);
 5699     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5700     __ cmp($tmp2$$Register, 0);
 5701     __ b(loop, ne);
 5702   %}
 5703   ins_pipe( long_memory_op );
 5704 %}
 5705 
 5706 instruct xaddI_reg(memoryex mem, iRegI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 5707   match(Set res (GetAndAddI mem add));
 5708   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5709   size(20);
 5710   format %{ "loop: \n\t"
 5711             "LDREX    $res, $mem\n\t"
 5712             "ADD      $tmp1, $res, $add\n\t"
 5713             "STREX    $tmp2, $tmp1, $mem\n\t"
 5714             "CMP      $tmp2, 0 \n\t"
 5715             "B.ne     loop \n\t" %}
 5716 
 5717   ins_encode %{
 5718     Label loop;
 5719     __ bind(loop);
 5720     __ ldrex($res$$Register,$mem$$Address);
 5721     __ add($tmp1$$Register, $res$$Register, $add$$Register);
 5722     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5723     __ cmp($tmp2$$Register, 0);
 5724     __ b(loop, ne);
 5725   %}
 5726   ins_pipe( long_memory_op );
 5727 %}
 5728 
 5729 instruct xaddL_reg_no_res(memoryex mem, iRegL add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5730   predicate(n->as_LoadStore()->result_not_used());
 5731   match(Set dummy (GetAndAddL mem add));
 5732   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
 5733   size(24);
 5734   format %{ "loop: \n\t"
 5735             "LDREXD   $tmp1, $mem\n\t"
 5736             "ADDS     $tmp1.lo, $tmp1.lo, $add.lo\n\t"
 5737             "ADC      $tmp1.hi, $tmp1.hi, $add.hi\n\t"
 5738             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5739             "CMP      $tmp2, 0 \n\t"
 5740             "B.ne     loop \n\t" %}
 5741 
 5742   ins_encode %{
 5743     Label loop;
 5744     __ bind(loop);
 5745     __ ldrexd($tmp1$$Register, $mem$$Address);
 5746     __ adds($tmp1$$Register, $tmp1$$Register, $add$$Register);
 5747     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), $add$$Register->successor());
 5748     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5749     __ cmp($tmp2$$Register, 0);
 5750     __ b(loop, ne);
 5751   %}
 5752   ins_pipe( long_memory_op );
 5753 %}
 5754 
 5755 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5756 // (hi($con$$constant), lo($con$$constant)) becomes
 5757 instruct xaddL_immRot_no_res(memoryex mem, immLlowRot add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5758   predicate(n->as_LoadStore()->result_not_used());
 5759   match(Set dummy (GetAndAddL mem add));
 5760   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
 5761   size(24);
 5762   format %{ "loop: \n\t"
 5763             "LDREXD   $tmp1, $mem\n\t"
 5764             "ADDS     $tmp1.lo, $tmp1.lo, $add\n\t"
 5765             "ADC      $tmp1.hi, $tmp1.hi, 0\n\t"
 5766             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5767             "CMP      $tmp2, 0 \n\t"
 5768             "B.ne     loop \n\t" %}
 5769 
 5770   ins_encode %{
 5771     Label loop;
 5772     __ bind(loop);
 5773     __ ldrexd($tmp1$$Register, $mem$$Address);
 5774     __ adds($tmp1$$Register, $tmp1$$Register, $add$$constant);
 5775     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), 0);
 5776     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5777     __ cmp($tmp2$$Register, 0);
 5778     __ b(loop, ne);
 5779   %}
 5780   ins_pipe( long_memory_op );
 5781 %}
 5782 
 5783 instruct xaddL_reg(memoryex mem, iRegL add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5784   match(Set res (GetAndAddL mem add));
 5785   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5786   size(24);
 5787   format %{ "loop: \n\t"
 5788             "LDREXD   $res, $mem\n\t"
 5789             "ADDS     $tmp1.lo, $res.lo, $add.lo\n\t"
 5790             "ADC      $tmp1.hi, $res.hi, $add.hi\n\t"
 5791             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5792             "CMP      $tmp2, 0 \n\t"
 5793             "B.ne     loop \n\t" %}
 5794 
 5795   ins_encode %{
 5796     Label loop;
 5797     __ bind(loop);
 5798     __ ldrexd($res$$Register, $mem$$Address);
 5799     __ adds($tmp1$$Register, $res$$Register, $add$$Register);
 5800     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), $add$$Register->successor());
 5801     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5802     __ cmp($tmp2$$Register, 0);
 5803     __ b(loop, ne);
 5804   %}
 5805   ins_pipe( long_memory_op );
 5806 %}
 5807 
 5808 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 5809 // (hi($con$$constant), lo($con$$constant)) becomes
 5810 instruct xaddL_immRot(memoryex mem, immLlowRot add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
 5811   match(Set res (GetAndAddL mem add));
 5812   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
 5813   size(24);
 5814   format %{ "loop: \n\t"
 5815             "LDREXD   $res, $mem\n\t"
 5816             "ADDS     $tmp1.lo, $res.lo, $add\n\t"
 5817             "ADC      $tmp1.hi, $res.hi, 0\n\t"
 5818             "STREXD   $tmp2, $tmp1, $mem\n\t"
 5819             "CMP      $tmp2, 0 \n\t"
 5820             "B.ne     loop \n\t" %}
 5821 
 5822   ins_encode %{
 5823     Label loop;
 5824     __ bind(loop);
 5825     __ ldrexd($res$$Register, $mem$$Address);
 5826     __ adds($tmp1$$Register, $res$$Register, $add$$constant);
 5827     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), 0);
 5828     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
 5829     __ cmp($tmp2$$Register, 0);
 5830     __ b(loop, ne);
 5831   %}
 5832   ins_pipe( long_memory_op );
 5833 %}
 5834 
 5835 instruct xchgI(memoryex mem, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr) %{
 5836   match(Set res (GetAndSetI mem newval));
 5837   effect(KILL ccr, TEMP tmp, TEMP res);
 5838   size(16);
 5839   format %{ "loop: \n\t"
 5840             "LDREX    $res, $mem\n\t"
 5841             "STREX    $tmp, $newval, $mem\n\t"
 5842             "CMP      $tmp, 0 \n\t"
 5843             "B.ne     loop \n\t" %}
 5844 
 5845   ins_encode %{
 5846     Label loop;
 5847     __ bind(loop);
 5848     __ ldrex($res$$Register,$mem$$Address);
 5849     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
 5850     __ cmp($tmp$$Register, 0);
 5851     __ b(loop, ne);
 5852   %}
 5853   ins_pipe( long_memory_op );
 5854 %}
 5855 
 5856 instruct xchgL(memoryex mem, iRegLd newval, iRegLd res, iRegI tmp, flagsReg ccr) %{
 5857   match(Set res (GetAndSetL mem newval));
 5858   effect( KILL ccr, TEMP tmp, TEMP res);
 5859   size(16);
 5860   format %{ "loop: \n\t"
 5861             "LDREXD   $res, $mem\n\t"
 5862             "STREXD   $tmp, $newval, $mem\n\t"
 5863             "CMP      $tmp, 0 \n\t"
 5864             "B.ne     loop \n\t" %}
 5865 
 5866   ins_encode %{
 5867     Label loop;
 5868     __ bind(loop);
 5869     __ ldrexd($res$$Register, $mem$$Address);
 5870     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address);
 5871     __ cmp($tmp$$Register, 0);
 5872     __ b(loop, ne);
 5873   %}
 5874   ins_pipe( long_memory_op );
 5875 %}
 5876 
 5877 instruct xchgP(memoryex mem, iRegP newval, iRegP res, iRegI tmp, flagsReg ccr) %{
 5878   match(Set res (GetAndSetP mem newval));
 5879   effect(KILL ccr, TEMP tmp, TEMP res);
 5880   size(16);
 5881   format %{ "loop: \n\t"
 5882             "LDREX    $res, $mem\n\t"
 5883             "STREX    $tmp, $newval, $mem\n\t"
 5884             "CMP      $tmp, 0 \n\t"
 5885             "B.ne     loop \n\t" %}
 5886 
 5887   ins_encode %{
 5888     Label loop;
 5889     __ bind(loop);
 5890     __ ldrex($res$$Register,$mem$$Address);
 5891     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
 5892     __ cmp($tmp$$Register, 0);
 5893     __ b(loop, ne);
 5894   %}
 5895   ins_pipe( long_memory_op );
 5896 %}
 5897 
 5898 //---------------------
 5899 // Subtraction Instructions
 5900 // Register Subtraction
 5901 instruct subI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 5902   match(Set dst (SubI src1 src2));
 5903 
 5904   size(4);
 5905   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
 5906   ins_encode %{
 5907     __ sub_32($dst$$Register, $src1$$Register, $src2$$Register);
 5908   %}
 5909   ins_pipe(ialu_reg_reg);
 5910 %}
 5911 
 5912 instruct subshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5913   match(Set dst (SubI src1 (LShiftI src2 src3)));
 5914 
 5915   size(4);
 5916   format %{ "SUB    $dst,$src1,$src2<<$src3" %}
 5917   ins_encode %{
 5918     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 5919   %}
 5920   ins_pipe(ialu_reg_reg);
 5921 %}
 5922 
 5923 instruct subshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 5924   match(Set dst (SubI src1 (LShiftI src2 src3)));
 5925 
 5926   size(4);
 5927   format %{ "sub_32 $dst,$src1,$src2<<$src3\t! int" %}
 5928   ins_encode %{
 5929     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 5930   %}
 5931   ins_pipe(ialu_reg_reg);
 5932 %}
 5933 
 5934 instruct subsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5935   match(Set dst (SubI src1 (RShiftI src2 src3)));
 5936 
 5937   size(4);
 5938   format %{ "SUB    $dst,$src1,$src2>>$src3" %}
 5939   ins_encode %{
 5940     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 5941   %}
 5942   ins_pipe(ialu_reg_reg);
 5943 %}
 5944 
 5945 instruct subsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 5946   match(Set dst (SubI src1 (RShiftI src2 src3)));
 5947 
 5948   size(4);
 5949   format %{ "sub_32 $dst,$src1,$src2>>$src3\t! int" %}
 5950   ins_encode %{
 5951     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 5952   %}
 5953   ins_pipe(ialu_reg_reg);
 5954 %}
 5955 
 5956 instruct subshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5957   match(Set dst (SubI src1 (URShiftI src2 src3)));
 5958 
 5959   size(4);
 5960   format %{ "SUB    $dst,$src1,$src2>>>$src3" %}
 5961   ins_encode %{
 5962     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 5963   %}
 5964   ins_pipe(ialu_reg_reg);
 5965 %}
 5966 
 5967 instruct subshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 5968   match(Set dst (SubI src1 (URShiftI src2 src3)));
 5969 
 5970   size(4);
 5971   format %{ "sub_32 $dst,$src1,$src2>>>$src3\t! int" %}
 5972   ins_encode %{
 5973     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 5974   %}
 5975   ins_pipe(ialu_reg_reg);
 5976 %}
 5977 
 5978 instruct rsbshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 5979   match(Set dst (SubI (LShiftI src1 src2) src3));
 5980 
 5981   size(4);
 5982   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
 5983   ins_encode %{
 5984     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 5985   %}
 5986   ins_pipe(ialu_reg_reg);
 5987 %}
 5988 
 5989 instruct rsbshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 5990   match(Set dst (SubI (LShiftI src1 src2) src3));
 5991 
 5992   size(4);
 5993   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
 5994   ins_encode %{
 5995     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
 5996   %}
 5997   ins_pipe(ialu_reg_reg);
 5998 %}
 5999 
 6000 instruct rsbsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6001   match(Set dst (SubI (RShiftI src1 src2) src3));
 6002 
 6003   size(4);
 6004   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
 6005   ins_encode %{
 6006     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
 6007   %}
 6008   ins_pipe(ialu_reg_reg);
 6009 %}
 6010 
 6011 instruct rsbsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 6012   match(Set dst (SubI (RShiftI src1 src2) src3));
 6013 
 6014   size(4);
 6015   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
 6016   ins_encode %{
 6017     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
 6018   %}
 6019   ins_pipe(ialu_reg_reg);
 6020 %}
 6021 
 6022 instruct rsbshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6023   match(Set dst (SubI (URShiftI src1 src2) src3));
 6024 
 6025   size(4);
 6026   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
 6027   ins_encode %{
 6028     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6029   %}
 6030   ins_pipe(ialu_reg_reg);
 6031 %}
 6032 
 6033 instruct rsbshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
 6034   match(Set dst (SubI (URShiftI src1 src2) src3));
 6035 
 6036   size(4);
 6037   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
 6038   ins_encode %{
 6039     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6040   %}
 6041   ins_pipe(ialu_reg_reg);
 6042 %}
 6043 
 6044 // Immediate Subtraction
 6045 instruct subI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
 6046   match(Set dst (SubI src1 src2));
 6047 
 6048   size(4);
 6049   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
 6050   ins_encode %{
 6051     __ sub_32($dst$$Register, $src1$$Register, $src2$$constant);
 6052   %}
 6053   ins_pipe(ialu_reg_imm);
 6054 %}
 6055 
 6056 instruct subI_reg_immRotneg(iRegI dst, iRegI src1, aimmIneg src2) %{
 6057   match(Set dst (AddI src1 src2));
 6058 
 6059   size(4);
 6060   format %{ "sub_32 $dst,$src1,-($src2)\t! int" %}
 6061   ins_encode %{
 6062     __ sub_32($dst$$Register, $src1$$Register, -$src2$$constant);
 6063   %}
 6064   ins_pipe(ialu_reg_imm);
 6065 %}
 6066 
 6067 instruct subI_immRot_reg(iRegI dst, immIRot src1, iRegI src2) %{
 6068   match(Set dst (SubI src1 src2));
 6069 
 6070   size(4);
 6071   format %{ "RSB    $dst,$src2,src1" %}
 6072   ins_encode %{
 6073     __ rsb($dst$$Register, $src2$$Register, $src1$$constant);
 6074   %}
 6075   ins_pipe(ialu_zero_reg);
 6076 %}
 6077 
 6078 // Register Subtraction
 6079 instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg icc ) %{
 6080   match(Set dst (SubL src1 src2));
 6081   effect (KILL icc);
 6082 
 6083   size(8);
 6084   format %{ "SUBS   $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
 6085             "SBC    $dst.hi,$src1.hi,$src2.hi" %}
 6086   ins_encode %{
 6087     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
 6088     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 6089   %}
 6090   ins_pipe(ialu_reg_reg);
 6091 %}
 6092 
 6093 // TODO
 6094 
 6095 // Immediate Subtraction
 6096 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 6097 // (hi($con$$constant), lo($con$$constant)) becomes
 6098 instruct subL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg icc) %{
 6099   match(Set dst (SubL src1 con));
 6100   effect (KILL icc);
 6101 
 6102   size(8);
 6103   format %{ "SUB    $dst.lo,$src1.lo,$con\t! long\n\t"
 6104             "SBC    $dst.hi,$src1.hi,0" %}
 6105   ins_encode %{
 6106     __ subs($dst$$Register, $src1$$Register, $con$$constant);
 6107     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), 0);
 6108   %}
 6109   ins_pipe(ialu_reg_imm);
 6110 %}
 6111 
 6112 // Long negation
 6113 instruct negL_reg_reg(iRegL dst, immL0 zero, iRegL src2, flagsReg icc) %{
 6114   match(Set dst (SubL zero src2));
 6115   effect (KILL icc);
 6116 
 6117   size(8);
 6118   format %{ "RSBS   $dst.lo,$src2.lo,0\t! long\n\t"
 6119             "RSC    $dst.hi,$src2.hi,0" %}
 6120   ins_encode %{
 6121     __ rsbs($dst$$Register, $src2$$Register, 0);
 6122     __ rsc($dst$$Register->successor(), $src2$$Register->successor(), 0);
 6123   %}
 6124   ins_pipe(ialu_zero_reg);
 6125 %}
 6126 
 6127 // Multiplication Instructions
 6128 // Integer Multiplication
 6129 // Register Multiplication
 6130 instruct mulI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6131   match(Set dst (MulI src1 src2));
 6132 
 6133   size(4);
 6134   format %{ "mul_32 $dst,$src1,$src2" %}
 6135   ins_encode %{
 6136     __ mul_32($dst$$Register, $src1$$Register, $src2$$Register);
 6137   %}
 6138   ins_pipe(imul_reg_reg);
 6139 %}
 6140 
 6141 instruct mulL_lo1_hi2(iRegL dst, iRegL src1, iRegL src2) %{
 6142   effect(DEF dst, USE src1, USE src2);
 6143   size(4);
 6144   format %{ "MUL  $dst.hi,$src1.lo,$src2.hi\t! long" %}
 6145   ins_encode %{
 6146     __ mul($dst$$Register->successor(), $src1$$Register, $src2$$Register->successor());
 6147   %}
 6148   ins_pipe(imul_reg_reg);
 6149 %}
 6150 
 6151 instruct mulL_hi1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
 6152   effect(USE_DEF dst, USE src1, USE src2);
 6153   size(8);
 6154   format %{ "MLA  $dst.hi,$src1.hi,$src2.lo,$dst.hi\t! long\n\t"
 6155             "MOV  $dst.lo, 0"%}
 6156   ins_encode %{
 6157     __ mla($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register, $dst$$Register->successor());
 6158     __ mov($dst$$Register, 0);
 6159   %}
 6160   ins_pipe(imul_reg_reg);
 6161 %}
 6162 
 6163 instruct mulL_lo1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
 6164   effect(USE_DEF dst, USE src1, USE src2);
 6165   size(4);
 6166   format %{ "UMLAL  $dst.lo,$dst.hi,$src1,$src2\t! long" %}
 6167   ins_encode %{
 6168     __ umlal($dst$$Register, $dst$$Register->successor(), $src1$$Register, $src2$$Register);
 6169   %}
 6170   ins_pipe(imul_reg_reg);
 6171 %}
 6172 
 6173 instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 6174   match(Set dst (MulL src1 src2));
 6175 
 6176   expand %{
 6177     mulL_lo1_hi2(dst, src1, src2);
 6178     mulL_hi1_lo2(dst, src1, src2);
 6179     mulL_lo1_lo2(dst, src1, src2);
 6180   %}
 6181 %}
 6182 
 6183 // Integer Division
 6184 // Register Division
 6185 instruct divI_reg_reg(R1RegI dst, R0RegI src1, R2RegI src2, LRRegP lr, flagsReg ccr) %{
 6186   match(Set dst (DivI src1 src2));
 6187   effect( KILL ccr, KILL src1, KILL src2, KILL lr);
 6188   ins_cost((2+71)*DEFAULT_COST);
 6189 
 6190   format %{ "DIV   $dst,$src1,$src2 ! call to StubRoutines::Arm::idiv_irem_entry()" %}
 6191   ins_encode %{
 6192     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
 6193   %}
 6194   ins_pipe(sdiv_reg_reg);
 6195 %}
 6196 
 6197 // Register Long Division
 6198 instruct divL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
 6199   match(Set dst (DivL src1 src2));
 6200   effect(CALL);
 6201   ins_cost(DEFAULT_COST*71);
 6202   format %{ "DIVL  $src1,$src2,$dst\t! long ! call to SharedRuntime::ldiv" %}
 6203   ins_encode %{
 6204     address target = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);
 6205     __ call(target, relocInfo::runtime_call_type);
 6206   %}
 6207   ins_pipe(divL_reg_reg);
 6208 %}
 6209 
 6210 // Integer Remainder
 6211 // Register Remainder
 6212 instruct modI_reg_reg(R0RegI dst, R0RegI src1, R2RegI src2, R1RegI temp, LRRegP lr, flagsReg ccr ) %{
 6213   match(Set dst (ModI src1 src2));
 6214   effect( KILL ccr, KILL temp, KILL src2, KILL lr);
 6215 
 6216   format %{ "MODI   $dst,$src1,$src2\t ! call to StubRoutines::Arm::idiv_irem_entry" %}
 6217   ins_encode %{
 6218     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
 6219   %}
 6220   ins_pipe(sdiv_reg_reg);
 6221 %}
 6222 
 6223 // Register Long Remainder
 6224 instruct modL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
 6225   match(Set dst (ModL src1 src2));
 6226   effect(CALL);
 6227   ins_cost(MEMORY_REF_COST); // FIXME
 6228   format %{ "modL    $dst,$src1,$src2\t ! call to SharedRuntime::lrem" %}
 6229   ins_encode %{
 6230     address target = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
 6231     __ call(target, relocInfo::runtime_call_type);
 6232   %}
 6233   ins_pipe(divL_reg_reg);
 6234 %}
 6235 
 6236 // Integer Shift Instructions
 6237 
 6238 // Register Shift Left
 6239 instruct shlI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6240   match(Set dst (LShiftI src1 src2));
 6241 
 6242   size(4);
 6243   format %{ "LSL  $dst,$src1,$src2 \n\t" %}
 6244   ins_encode %{
 6245     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 6246   %}
 6247   ins_pipe(ialu_reg_reg);
 6248 %}
 6249 
 6250 // Register Shift Left Immediate
 6251 instruct shlI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
 6252   match(Set dst (LShiftI src1 src2));
 6253 
 6254   size(4);
 6255   format %{ "LSL    $dst,$src1,$src2\t! int" %}
 6256   ins_encode %{
 6257     __ logical_shift_left($dst$$Register, $src1$$Register, $src2$$constant);
 6258   %}
 6259   ins_pipe(ialu_reg_imm);
 6260 %}
 6261 
 6262 instruct shlL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
 6263   effect(USE_DEF dst, USE src1, USE src2);
 6264   size(4);
 6265   format %{"OR  $dst.hi,$dst.hi,($src1.hi << $src2)"  %}
 6266   ins_encode %{
 6267     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$Register));
 6268   %}
 6269   ins_pipe(ialu_reg_reg);
 6270 %}
 6271 
 6272 instruct shlL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
 6273   effect(USE_DEF dst, USE src1, USE src2);
 6274   size(4);
 6275   format %{ "LSL  $dst.lo,$src1.lo,$src2 \n\t" %}
 6276   ins_encode %{
 6277     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
 6278   %}
 6279   ins_pipe(ialu_reg_reg);
 6280 %}
 6281 
 6282 instruct shlL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
 6283   effect(DEF dst, USE src1, USE src2, KILL ccr);
 6284   size(16);
 6285   format %{ "SUBS  $dst.hi,$src2,32 \n\t"
 6286             "LSLpl $dst.hi,$src1.lo,$dst.hi \n\t"
 6287             "RSBmi $dst.hi,$dst.hi,0 \n\t"
 6288             "LSRmi $dst.hi,$src1.lo,$dst.hi" %}
 6289 
 6290   ins_encode %{
 6291     // $src1$$Register and $dst$$Register->successor() can't be the same
 6292     __ subs($dst$$Register->successor(), $src2$$Register, 32);
 6293     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $dst$$Register->successor()), pl);
 6294     __ rsb($dst$$Register->successor(), $dst$$Register->successor(), 0, mi);
 6295     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsr, $dst$$Register->successor()), mi);
 6296   %}
 6297   ins_pipe(ialu_reg_reg);
 6298 %}
 6299 
 6300 instruct shlL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
 6301   match(Set dst (LShiftL src1 src2));
 6302 
 6303   expand %{
 6304     flagsReg ccr;
 6305     shlL_reg_reg_overlap(dst, src1, src2, ccr);
 6306     shlL_reg_reg_merge_hi(dst, src1, src2);
 6307     shlL_reg_reg_merge_lo(dst, src1, src2);
 6308   %}
 6309 %}
 6310 
 6311 // Register Shift Left Immediate
 6312 instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
 6313   match(Set dst (LShiftL src1 src2));
 6314 
 6315   size(8);
 6316   format %{ "LSL   $dst.hi,$src1.lo,$src2-32\t! or mov if $src2==32\n\t"
 6317             "MOV   $dst.lo, 0" %}
 6318   ins_encode %{
 6319     if ($src2$$constant == 32) {
 6320       __ mov($dst$$Register->successor(), $src1$$Register);
 6321     } else {
 6322       __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $src2$$constant-32));
 6323     }
 6324     __ mov($dst$$Register, 0);
 6325   %}
 6326   ins_pipe(ialu_reg_imm);
 6327 %}
 6328 
 6329 instruct shlL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
 6330   match(Set dst (LShiftL src1 src2));
 6331 
 6332   size(12);
 6333   format %{ "LSL   $dst.hi,$src1.lo,$src2\n\t"
 6334             "OR    $dst.hi, $dst.hi, $src1.lo >> 32-$src2\n\t"
 6335             "LSL   $dst.lo,$src1.lo,$src2" %}
 6336   ins_encode %{
 6337     // The order of the following 3 instructions matters: src1.lo and
 6338     // dst.hi can't overlap but src.hi and dst.hi can.
 6339     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$constant));
 6340     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register, lsr, 32-$src2$$constant));
 6341     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
 6342   %}
 6343   ins_pipe(ialu_reg_imm);
 6344 %}
 6345 
 6346 // Register Arithmetic Shift Right
 6347 instruct sarI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6348   match(Set dst (RShiftI src1 src2));
 6349   size(4);
 6350   format %{ "ASR    $dst,$src1,$src2\t! int" %}
 6351   ins_encode %{
 6352     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
 6353   %}
 6354   ins_pipe(ialu_reg_reg);
 6355 %}
 6356 
 6357 // Register Arithmetic Shift Right Immediate
 6358 instruct sarI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
 6359   match(Set dst (RShiftI src1 src2));
 6360 
 6361   size(4);
 6362   format %{ "ASR    $dst,$src1,$src2" %}
 6363   ins_encode %{
 6364     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
 6365   %}
 6366   ins_pipe(ialu_reg_imm);
 6367 %}
 6368 
 6369 // Register Shift Right Arithmetic Long
 6370 instruct sarL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
 6371   effect(USE_DEF dst, USE src1, USE src2);
 6372   size(4);
 6373   format %{ "OR  $dst.lo,$dst.lo,($src1.lo >> $src2)"  %}
 6374   ins_encode %{
 6375     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6376   %}
 6377   ins_pipe(ialu_reg_reg);
 6378 %}
 6379 
 6380 instruct sarL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
 6381   effect(USE_DEF dst, USE src1, USE src2);
 6382   size(4);
 6383   format %{ "ASR  $dst.hi,$src1.hi,$src2 \n\t" %}
 6384   ins_encode %{
 6385     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$Register));
 6386   %}
 6387   ins_pipe(ialu_reg_reg);
 6388 %}
 6389 
 6390 instruct sarL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
 6391   effect(DEF dst, USE src1, USE src2, KILL ccr);
 6392   size(16);
 6393   format %{ "SUBS  $dst.lo,$src2,32 \n\t"
 6394             "ASRpl $dst.lo,$src1.hi,$dst.lo \n\t"
 6395             "RSBmi $dst.lo,$dst.lo,0 \n\t"
 6396             "LSLmi $dst.lo,$src1.hi,$dst.lo" %}
 6397 
 6398   ins_encode %{
 6399     // $src1$$Register->successor() and $dst$$Register can't be the same
 6400     __ subs($dst$$Register, $src2$$Register, 32);
 6401     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $dst$$Register), pl);
 6402     __ rsb($dst$$Register, $dst$$Register, 0, mi);
 6403     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
 6404   %}
 6405   ins_pipe(ialu_reg_reg);
 6406 %}
 6407 
 6408 instruct sarL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
 6409   match(Set dst (RShiftL src1 src2));
 6410 
 6411   expand %{
 6412     flagsReg ccr;
 6413     sarL_reg_reg_overlap(dst, src1, src2, ccr);
 6414     sarL_reg_reg_merge_lo(dst, src1, src2);
 6415     sarL_reg_reg_merge_hi(dst, src1, src2);
 6416   %}
 6417 %}
 6418 
 6419 // Register Shift Left Immediate
 6420 instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
 6421   match(Set dst (RShiftL src1 src2));
 6422 
 6423   size(8);
 6424   format %{ "ASR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
 6425             "ASR   $dst.hi,$src1.hi, $src2" %}
 6426   ins_encode %{
 6427     if ($src2$$constant == 32) {
 6428       __ mov($dst$$Register, $src1$$Register->successor());
 6429     } else{
 6430       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $src2$$constant-32));
 6431     }
 6432     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, 0));
 6433   %}
 6434 
 6435   ins_pipe(ialu_reg_imm);
 6436 %}
 6437 
 6438 instruct sarL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
 6439   match(Set dst (RShiftL src1 src2));
 6440   size(12);
 6441   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
 6442             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
 6443             "ASR   $dst.hi,$src1.hi,$src2" %}
 6444   ins_encode %{
 6445     // The order of the following 3 instructions matters: src1.lo and
 6446     // dst.hi can't overlap but src.hi and dst.hi can.
 6447     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6448     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
 6449     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$constant));
 6450   %}
 6451   ins_pipe(ialu_reg_imm);
 6452 %}
 6453 
 6454 // Register Shift Right
 6455 instruct shrI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6456   match(Set dst (URShiftI src1 src2));
 6457   size(4);
 6458   format %{ "LSR    $dst,$src1,$src2\t! int" %}
 6459   ins_encode %{
 6460     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6461   %}
 6462   ins_pipe(ialu_reg_reg);
 6463 %}
 6464 
 6465 // Register Shift Right Immediate
 6466 instruct shrI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
 6467   match(Set dst (URShiftI src1 src2));
 6468 
 6469   size(4);
 6470   format %{ "LSR    $dst,$src1,$src2" %}
 6471   ins_encode %{
 6472     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6473   %}
 6474   ins_pipe(ialu_reg_imm);
 6475 %}
 6476 
 6477 // Register Shift Right
 6478 instruct shrL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
 6479   effect(USE_DEF dst, USE src1, USE src2);
 6480   size(4);
 6481   format %{ "OR   $dst.lo,$dst,($src1.lo >>> $src2)"  %}
 6482   ins_encode %{
 6483     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
 6484   %}
 6485   ins_pipe(ialu_reg_reg);
 6486 %}
 6487 
 6488 instruct shrL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
 6489   effect(USE_DEF dst, USE src1, USE src2);
 6490   size(4);
 6491   format %{ "LSR  $dst.hi,$src1.hi,$src2 \n\t" %}
 6492   ins_encode %{
 6493     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$Register));
 6494   %}
 6495   ins_pipe(ialu_reg_reg);
 6496 %}
 6497 
 6498 instruct shrL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
 6499   effect(DEF dst, USE src1, USE src2, KILL ccr);
 6500   size(16);
 6501   format %{ "SUBS  $dst,$src2,32 \n\t"
 6502             "LSRpl $dst,$src1.hi,$dst \n\t"
 6503             "RSBmi $dst,$dst,0 \n\t"
 6504             "LSLmi $dst,$src1.hi,$dst" %}
 6505 
 6506   ins_encode %{
 6507     // $src1$$Register->successor() and $dst$$Register can't be the same
 6508     __ subs($dst$$Register, $src2$$Register, 32);
 6509     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $dst$$Register), pl);
 6510     __ rsb($dst$$Register, $dst$$Register, 0, mi);
 6511     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
 6512   %}
 6513   ins_pipe(ialu_reg_reg);
 6514 %}
 6515 
 6516 instruct shrL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
 6517   match(Set dst (URShiftL src1 src2));
 6518 
 6519   expand %{
 6520     flagsReg ccr;
 6521     shrL_reg_reg_overlap(dst, src1, src2, ccr);
 6522     shrL_reg_reg_merge_lo(dst, src1, src2);
 6523     shrL_reg_reg_merge_hi(dst, src1, src2);
 6524   %}
 6525 %}
 6526 
 6527 // Register Shift Right Immediate
 6528 instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
 6529   match(Set dst (URShiftL src1 src2));
 6530 
 6531   size(8);
 6532   format %{ "LSR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
 6533             "MOV   $dst.hi, 0" %}
 6534   ins_encode %{
 6535     if ($src2$$constant == 32) {
 6536       __ mov($dst$$Register, $src1$$Register->successor());
 6537     } else {
 6538       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $src2$$constant-32));
 6539     }
 6540     __ mov($dst$$Register->successor(), 0);
 6541   %}
 6542 
 6543   ins_pipe(ialu_reg_imm);
 6544 %}
 6545 
 6546 instruct shrL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
 6547   match(Set dst (URShiftL src1 src2));
 6548 
 6549   size(12);
 6550   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
 6551             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
 6552             "LSR   $dst.hi,$src1.hi,$src2" %}
 6553   ins_encode %{
 6554     // The order of the following 3 instructions matters: src1.lo and
 6555     // dst.hi can't overlap but src.hi and dst.hi can.
 6556     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
 6557     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
 6558     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$constant));
 6559   %}
 6560   ins_pipe(ialu_reg_imm);
 6561 %}
 6562 
 6563 
 6564 instruct shrP_reg_imm5(iRegX dst, iRegP src1, immU5 src2) %{
 6565   match(Set dst (URShiftI (CastP2X src1) src2));
 6566   size(4);
 6567   format %{ "LSR    $dst,$src1,$src2\t! Cast ptr $src1 to int and shift" %}
 6568   ins_encode %{
 6569     __ logical_shift_right($dst$$Register, $src1$$Register, $src2$$constant);
 6570   %}
 6571   ins_pipe(ialu_reg_imm);
 6572 %}
 6573 
 6574 //----------Floating Point Arithmetic Instructions-----------------------------
 6575 
 6576 //  Add float single precision
 6577 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
 6578   match(Set dst (AddF src1 src2));
 6579 
 6580   size(4);
 6581   format %{ "FADDS  $dst,$src1,$src2" %}
 6582   ins_encode %{
 6583     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6584   %}
 6585 
 6586   ins_pipe(faddF_reg_reg);
 6587 %}
 6588 
 6589 //  Add float double precision
 6590 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
 6591   match(Set dst (AddD src1 src2));
 6592 
 6593   size(4);
 6594   format %{ "FADDD  $dst,$src1,$src2" %}
 6595   ins_encode %{
 6596     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6597   %}
 6598 
 6599   ins_pipe(faddD_reg_reg);
 6600 %}
 6601 
 6602 //  Sub float single precision
 6603 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
 6604   match(Set dst (SubF src1 src2));
 6605 
 6606   size(4);
 6607   format %{ "FSUBS  $dst,$src1,$src2" %}
 6608   ins_encode %{
 6609     __ sub_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6610   %}
 6611   ins_pipe(faddF_reg_reg);
 6612 %}
 6613 
 6614 //  Sub float double precision
 6615 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
 6616   match(Set dst (SubD src1 src2));
 6617 
 6618   size(4);
 6619   format %{ "FSUBD  $dst,$src1,$src2" %}
 6620   ins_encode %{
 6621     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6622   %}
 6623   ins_pipe(faddD_reg_reg);
 6624 %}
 6625 
 6626 //  Mul float single precision
 6627 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
 6628   match(Set dst (MulF src1 src2));
 6629 
 6630   size(4);
 6631   format %{ "FMULS  $dst,$src1,$src2" %}
 6632   ins_encode %{
 6633     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6634   %}
 6635 
 6636   ins_pipe(fmulF_reg_reg);
 6637 %}
 6638 
 6639 //  Mul float double precision
 6640 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
 6641   match(Set dst (MulD src1 src2));
 6642 
 6643   size(4);
 6644   format %{ "FMULD  $dst,$src1,$src2" %}
 6645   ins_encode %{
 6646     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6647   %}
 6648 
 6649   ins_pipe(fmulD_reg_reg);
 6650 %}
 6651 
 6652 //  Div float single precision
 6653 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
 6654   match(Set dst (DivF src1 src2));
 6655 
 6656   size(4);
 6657   format %{ "FDIVS  $dst,$src1,$src2" %}
 6658   ins_encode %{
 6659     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6660   %}
 6661 
 6662   ins_pipe(fdivF_reg_reg);
 6663 %}
 6664 
 6665 //  Div float double precision
 6666 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
 6667   match(Set dst (DivD src1 src2));
 6668 
 6669   size(4);
 6670   format %{ "FDIVD  $dst,$src1,$src2" %}
 6671   ins_encode %{
 6672     __ div_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 6673   %}
 6674 
 6675   ins_pipe(fdivD_reg_reg);
 6676 %}
 6677 
 6678 //  Absolute float double precision
 6679 instruct absD_reg(regD dst, regD src) %{
 6680   match(Set dst (AbsD src));
 6681 
 6682   size(4);
 6683   format %{ "FABSd  $dst,$src" %}
 6684   ins_encode %{
 6685     __ abs_double($dst$$FloatRegister, $src$$FloatRegister);
 6686   %}
 6687   ins_pipe(faddD_reg);
 6688 %}
 6689 
 6690 //  Absolute float single precision
 6691 instruct absF_reg(regF dst, regF src) %{
 6692   match(Set dst (AbsF src));
 6693   format %{ "FABSs  $dst,$src" %}
 6694   ins_encode %{
 6695     __ abs_float($dst$$FloatRegister, $src$$FloatRegister);
 6696   %}
 6697   ins_pipe(faddF_reg);
 6698 %}
 6699 
 6700 instruct negF_reg(regF dst, regF src) %{
 6701   match(Set dst (NegF src));
 6702 
 6703   size(4);
 6704   format %{ "FNEGs  $dst,$src" %}
 6705   ins_encode %{
 6706     __ neg_float($dst$$FloatRegister, $src$$FloatRegister);
 6707   %}
 6708   ins_pipe(faddF_reg);
 6709 %}
 6710 
 6711 instruct negD_reg(regD dst, regD src) %{
 6712   match(Set dst (NegD src));
 6713 
 6714   format %{ "FNEGd  $dst,$src" %}
 6715   ins_encode %{
 6716     __ neg_double($dst$$FloatRegister, $src$$FloatRegister);
 6717   %}
 6718   ins_pipe(faddD_reg);
 6719 %}
 6720 
 6721 //  Sqrt float double precision
 6722 instruct sqrtF_reg_reg(regF dst, regF src) %{
 6723   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
 6724 
 6725   size(4);
 6726   format %{ "FSQRTS $dst,$src" %}
 6727   ins_encode %{
 6728     __ sqrt_float($dst$$FloatRegister, $src$$FloatRegister);
 6729   %}
 6730   ins_pipe(fdivF_reg_reg);
 6731 %}
 6732 
 6733 //  Sqrt float double precision
 6734 instruct sqrtD_reg_reg(regD dst, regD src) %{
 6735   match(Set dst (SqrtD src));
 6736 
 6737   size(4);
 6738   format %{ "FSQRTD $dst,$src" %}
 6739   ins_encode %{
 6740     __ sqrt_double($dst$$FloatRegister, $src$$FloatRegister);
 6741   %}
 6742   ins_pipe(fdivD_reg_reg);
 6743 %}
 6744 
 6745 //----------Logical Instructions-----------------------------------------------
 6746 // And Instructions
 6747 // Register And
 6748 instruct andI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6749   match(Set dst (AndI src1 src2));
 6750 
 6751   size(4);
 6752   format %{ "and_32 $dst,$src1,$src2" %}
 6753   ins_encode %{
 6754     __ and_32($dst$$Register, $src1$$Register, $src2$$Register);
 6755   %}
 6756   ins_pipe(ialu_reg_reg);
 6757 %}
 6758 
 6759 instruct andshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6760   match(Set dst (AndI src1 (LShiftI src2 src3)));
 6761 
 6762   size(4);
 6763   format %{ "AND    $dst,$src1,$src2<<$src3" %}
 6764   ins_encode %{
 6765     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 6766   %}
 6767   ins_pipe(ialu_reg_reg);
 6768 %}
 6769 
 6770 instruct andshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6771   match(Set dst (AndI src1 (LShiftI src2 src3)));
 6772 
 6773   size(4);
 6774   format %{ "and_32 $dst,$src1,$src2<<$src3" %}
 6775   ins_encode %{
 6776     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 6777   %}
 6778   ins_pipe(ialu_reg_reg);
 6779 %}
 6780 
 6781 instruct andsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6782   match(Set dst (AndI src1 (RShiftI src2 src3)));
 6783 
 6784   size(4);
 6785   format %{ "AND    $dst,$src1,$src2>>$src3" %}
 6786   ins_encode %{
 6787     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 6788   %}
 6789   ins_pipe(ialu_reg_reg);
 6790 %}
 6791 
 6792 instruct andsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6793   match(Set dst (AndI src1 (RShiftI src2 src3)));
 6794 
 6795   size(4);
 6796   format %{ "and_32 $dst,$src1,$src2>>$src3" %}
 6797   ins_encode %{
 6798     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 6799   %}
 6800   ins_pipe(ialu_reg_reg);
 6801 %}
 6802 
 6803 instruct andshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6804   match(Set dst (AndI src1 (URShiftI src2 src3)));
 6805 
 6806   size(4);
 6807   format %{ "AND    $dst,$src1,$src2>>>$src3" %}
 6808   ins_encode %{
 6809     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 6810   %}
 6811   ins_pipe(ialu_reg_reg);
 6812 %}
 6813 
 6814 instruct andshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6815   match(Set dst (AndI src1 (URShiftI src2 src3)));
 6816 
 6817   size(4);
 6818   format %{ "and_32 $dst,$src1,$src2>>>$src3" %}
 6819   ins_encode %{
 6820     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 6821   %}
 6822   ins_pipe(ialu_reg_reg);
 6823 %}
 6824 
 6825 // Immediate And
 6826 instruct andI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
 6827   match(Set dst (AndI src1 src2));
 6828 
 6829   size(4);
 6830   format %{ "and_32 $dst,$src1,$src2\t! int" %}
 6831   ins_encode %{
 6832     __ and_32($dst$$Register, $src1$$Register, $src2$$constant);
 6833   %}
 6834   ins_pipe(ialu_reg_imm);
 6835 %}
 6836 
 6837 instruct andI_reg_limmn(iRegI dst, iRegI src1, limmIn src2) %{
 6838   match(Set dst (AndI src1 src2));
 6839 
 6840   size(4);
 6841   format %{ "bic    $dst,$src1,~$src2\t! int" %}
 6842   ins_encode %{
 6843     __ bic($dst$$Register, $src1$$Register, ~$src2$$constant);
 6844   %}
 6845   ins_pipe(ialu_reg_imm);
 6846 %}
 6847 
 6848 // Register And Long
 6849 instruct andL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 6850   match(Set dst (AndL src1 src2));
 6851 
 6852   ins_cost(DEFAULT_COST);
 6853   size(8);
 6854   format %{ "AND    $dst,$src1,$src2\t! long" %}
 6855   ins_encode %{
 6856     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
 6857     __ andr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 6858   %}
 6859   ins_pipe(ialu_reg_reg);
 6860 %}
 6861 
 6862 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 6863 // (hi($con$$constant), lo($con$$constant)) becomes
 6864 instruct andL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
 6865   match(Set dst (AndL src1 con));
 6866   ins_cost(DEFAULT_COST);
 6867   size(8);
 6868   format %{ "AND    $dst,$src1,$con\t! long" %}
 6869   ins_encode %{
 6870     __ andr($dst$$Register, $src1$$Register, $con$$constant);
 6871     __ andr($dst$$Register->successor(), $src1$$Register->successor(), 0);
 6872   %}
 6873   ins_pipe(ialu_reg_imm);
 6874 %}
 6875 
 6876 // Or Instructions
 6877 // Register Or
 6878 instruct orI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 6879   match(Set dst (OrI src1 src2));
 6880 
 6881   size(4);
 6882   format %{ "orr_32 $dst,$src1,$src2\t! int" %}
 6883   ins_encode %{
 6884     __ orr_32($dst$$Register, $src1$$Register, $src2$$Register);
 6885   %}
 6886   ins_pipe(ialu_reg_reg);
 6887 %}
 6888 
 6889 instruct orshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6890   match(Set dst (OrI src1 (LShiftI src2 src3)));
 6891 
 6892   size(4);
 6893   format %{ "OR    $dst,$src1,$src2<<$src3" %}
 6894   ins_encode %{
 6895     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 6896   %}
 6897   ins_pipe(ialu_reg_reg);
 6898 %}
 6899 
 6900 instruct orshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6901   match(Set dst (OrI src1 (LShiftI src2 src3)));
 6902 
 6903   size(4);
 6904   format %{ "orr_32 $dst,$src1,$src2<<$src3" %}
 6905   ins_encode %{
 6906     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 6907   %}
 6908   ins_pipe(ialu_reg_reg);
 6909 %}
 6910 
 6911 instruct orsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6912   match(Set dst (OrI src1 (RShiftI src2 src3)));
 6913 
 6914   size(4);
 6915   format %{ "OR    $dst,$src1,$src2>>$src3" %}
 6916   ins_encode %{
 6917     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 6918   %}
 6919   ins_pipe(ialu_reg_reg);
 6920 %}
 6921 
 6922 instruct orsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6923   match(Set dst (OrI src1 (RShiftI src2 src3)));
 6924 
 6925   size(4);
 6926   format %{ "orr_32 $dst,$src1,$src2>>$src3" %}
 6927   ins_encode %{
 6928     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 6929   %}
 6930   ins_pipe(ialu_reg_reg);
 6931 %}
 6932 
 6933 instruct orshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 6934   match(Set dst (OrI src1 (URShiftI src2 src3)));
 6935 
 6936   size(4);
 6937   format %{ "OR    $dst,$src1,$src2>>>$src3" %}
 6938   ins_encode %{
 6939     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 6940   %}
 6941   ins_pipe(ialu_reg_reg);
 6942 %}
 6943 
 6944 instruct orshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 6945   match(Set dst (OrI src1 (URShiftI src2 src3)));
 6946 
 6947   size(4);
 6948   format %{ "orr_32 $dst,$src1,$src2>>>$src3" %}
 6949   ins_encode %{
 6950     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 6951   %}
 6952   ins_pipe(ialu_reg_reg);
 6953 %}
 6954 
 6955 // Immediate Or
 6956 instruct orI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
 6957   match(Set dst (OrI src1 src2));
 6958 
 6959   size(4);
 6960   format %{ "orr_32  $dst,$src1,$src2" %}
 6961   ins_encode %{
 6962     __ orr_32($dst$$Register, $src1$$Register, $src2$$constant);
 6963   %}
 6964   ins_pipe(ialu_reg_imm);
 6965 %}
 6966 // TODO: orn_32 with limmIn
 6967 
 6968 // Register Or Long
 6969 instruct orL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 6970   match(Set dst (OrL src1 src2));
 6971 
 6972   ins_cost(DEFAULT_COST);
 6973   size(8);
 6974   format %{ "OR     $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
 6975             "OR     $dst.hi,$src1.hi,$src2.hi" %}
 6976   ins_encode %{
 6977     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
 6978     __ orr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 6979   %}
 6980   ins_pipe(ialu_reg_reg);
 6981 %}
 6982 
 6983 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 6984 // (hi($con$$constant), lo($con$$constant)) becomes
 6985 instruct orL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
 6986   match(Set dst (OrL src1 con));
 6987   ins_cost(DEFAULT_COST);
 6988   size(8);
 6989   format %{ "OR     $dst.lo,$src1.lo,$con\t! long\n\t"
 6990             "OR     $dst.hi,$src1.hi,$con" %}
 6991   ins_encode %{
 6992     __ orr($dst$$Register, $src1$$Register, $con$$constant);
 6993     __ orr($dst$$Register->successor(), $src1$$Register->successor(), 0);
 6994   %}
 6995   ins_pipe(ialu_reg_imm);
 6996 %}
 6997 
 6998 #ifdef TODO
 6999 // Use SPRegP to match Rthread (TLS register) without spilling.
 7000 // Use store_ptr_RegP to match Rthread (TLS register) without spilling.
 7001 // Use sp_ptr_RegP to match Rthread (TLS register) without spilling.
 7002 instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
 7003   match(Set dst (OrI src1 (CastP2X src2)));
 7004   size(4);
 7005   format %{ "OR     $dst,$src1,$src2" %}
 7006   ins_encode %{
 7007     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
 7008   %}
 7009   ins_pipe(ialu_reg_reg);
 7010 %}
 7011 #endif
 7012 
 7013 // Xor Instructions
 7014 // Register Xor
 7015 instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
 7016   match(Set dst (XorI src1 src2));
 7017 
 7018   size(4);
 7019   format %{ "eor_32 $dst,$src1,$src2" %}
 7020   ins_encode %{
 7021     __ eor_32($dst$$Register, $src1$$Register, $src2$$Register);
 7022   %}
 7023   ins_pipe(ialu_reg_reg);
 7024 %}
 7025 
 7026 instruct xorshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 7027   match(Set dst (XorI src1 (LShiftI src2 src3)));
 7028 
 7029   size(4);
 7030   format %{ "XOR    $dst,$src1,$src2<<$src3" %}
 7031   ins_encode %{
 7032     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
 7033   %}
 7034   ins_pipe(ialu_reg_reg);
 7035 %}
 7036 
 7037 instruct xorshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 7038   match(Set dst (XorI src1 (LShiftI src2 src3)));
 7039 
 7040   size(4);
 7041   format %{ "eor_32 $dst,$src1,$src2<<$src3" %}
 7042   ins_encode %{
 7043     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
 7044   %}
 7045   ins_pipe(ialu_reg_reg);
 7046 %}
 7047 
 7048 instruct xorsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 7049   match(Set dst (XorI src1 (RShiftI src2 src3)));
 7050 
 7051   size(4);
 7052   format %{ "XOR    $dst,$src1,$src2>>$src3" %}
 7053   ins_encode %{
 7054     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
 7055   %}
 7056   ins_pipe(ialu_reg_reg);
 7057 %}
 7058 
 7059 instruct xorsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 7060   match(Set dst (XorI src1 (RShiftI src2 src3)));
 7061 
 7062   size(4);
 7063   format %{ "eor_32 $dst,$src1,$src2>>$src3" %}
 7064   ins_encode %{
 7065     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
 7066   %}
 7067   ins_pipe(ialu_reg_reg);
 7068 %}
 7069 
 7070 instruct xorshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
 7071   match(Set dst (XorI src1 (URShiftI src2 src3)));
 7072 
 7073   size(4);
 7074   format %{ "XOR    $dst,$src1,$src2>>>$src3" %}
 7075   ins_encode %{
 7076     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
 7077   %}
 7078   ins_pipe(ialu_reg_reg);
 7079 %}
 7080 
 7081 instruct xorshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
 7082   match(Set dst (XorI src1 (URShiftI src2 src3)));
 7083 
 7084   size(4);
 7085   format %{ "eor_32 $dst,$src1,$src2>>>$src3" %}
 7086   ins_encode %{
 7087     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
 7088   %}
 7089   ins_pipe(ialu_reg_reg);
 7090 %}
 7091 
 7092 // Immediate Xor
 7093 instruct xorI_reg_imm(iRegI dst, iRegI src1, limmI src2) %{
 7094   match(Set dst (XorI src1 src2));
 7095 
 7096   size(4);
 7097   format %{ "eor_32 $dst,$src1,$src2" %}
 7098   ins_encode %{
 7099     __ eor_32($dst$$Register, $src1$$Register, $src2$$constant);
 7100   %}
 7101   ins_pipe(ialu_reg_imm);
 7102 %}
 7103 
 7104 // Register Xor Long
 7105 instruct xorL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
 7106   match(Set dst (XorL src1 src2));
 7107   ins_cost(DEFAULT_COST);
 7108   size(8);
 7109   format %{ "XOR     $dst.hi,$src1.hi,$src2.hi\t! long\n\t"
 7110             "XOR     $dst.lo,$src1.lo,$src2.lo\t! long" %}
 7111   ins_encode %{
 7112     __ eor($dst$$Register, $src1$$Register, $src2$$Register);
 7113     __ eor($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
 7114   %}
 7115   ins_pipe(ialu_reg_reg);
 7116 %}
 7117 
 7118 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7119 // (hi($con$$constant), lo($con$$constant)) becomes
 7120 instruct xorL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
 7121   match(Set dst (XorL src1 con));
 7122   ins_cost(DEFAULT_COST);
 7123   size(8);
 7124   format %{ "XOR     $dst.hi,$src1.hi,$con\t! long\n\t"
 7125             "XOR     $dst.lo,$src1.lo,0\t! long" %}
 7126   ins_encode %{
 7127     __ eor($dst$$Register, $src1$$Register, $con$$constant);
 7128     __ eor($dst$$Register->successor(), $src1$$Register->successor(), 0);
 7129   %}
 7130   ins_pipe(ialu_reg_imm);
 7131 %}
 7132 
 7133 //----------Convert to Boolean-------------------------------------------------
 7134 instruct convI2B( iRegI dst, iRegI src, flagsReg ccr ) %{
 7135   match(Set dst (Conv2B src));
 7136   effect(KILL ccr);
 7137   size(12);
 7138   ins_cost(DEFAULT_COST*2);
 7139   format %{ "TST    $src,$src \n\t"
 7140             "MOV    $dst, 0   \n\t"
 7141             "MOV.ne $dst, 1" %}
 7142   ins_encode %{ // FIXME: can do better?
 7143     __ tst($src$$Register, $src$$Register);
 7144     __ mov($dst$$Register, 0);
 7145     __ mov($dst$$Register, 1, ne);
 7146   %}
 7147   ins_pipe(ialu_reg_ialu);
 7148 %}
 7149 
 7150 instruct convP2B( iRegI dst, iRegP src, flagsReg ccr ) %{
 7151   match(Set dst (Conv2B src));
 7152   effect(KILL ccr);
 7153   size(12);
 7154   ins_cost(DEFAULT_COST*2);
 7155   format %{ "TST    $src,$src \n\t"
 7156             "MOV    $dst, 0   \n\t"
 7157             "MOV.ne $dst, 1" %}
 7158   ins_encode %{
 7159     __ tst($src$$Register, $src$$Register);
 7160     __ mov($dst$$Register, 0);
 7161     __ mov($dst$$Register, 1, ne);
 7162   %}
 7163   ins_pipe(ialu_reg_ialu);
 7164 %}
 7165 
 7166 instruct cmpLTMask_reg_reg( iRegI dst, iRegI p, iRegI q, flagsReg ccr ) %{
 7167   match(Set dst (CmpLTMask p q));
 7168   effect( KILL ccr );
 7169   ins_cost(DEFAULT_COST*3);
 7170   format %{ "CMP    $p,$q\n\t"
 7171             "MOV    $dst, #0\n\t"
 7172             "MOV.lt $dst, #-1" %}
 7173   ins_encode %{
 7174     __ cmp($p$$Register, $q$$Register);
 7175     __ mov($dst$$Register, 0);
 7176     __ mvn($dst$$Register, 0, lt);
 7177   %}
 7178   ins_pipe(ialu_reg_reg_ialu);
 7179 %}
 7180 
 7181 instruct cmpLTMask_reg_imm( iRegI dst, iRegI p, aimmI q, flagsReg ccr ) %{
 7182   match(Set dst (CmpLTMask p q));
 7183   effect( KILL ccr );
 7184   ins_cost(DEFAULT_COST*3);
 7185   format %{ "CMP    $p,$q\n\t"
 7186             "MOV    $dst, #0\n\t"
 7187             "MOV.lt $dst, #-1" %}
 7188   ins_encode %{
 7189     __ cmp($p$$Register, $q$$constant);
 7190     __ mov($dst$$Register, 0);
 7191     __ mvn($dst$$Register, 0, lt);
 7192   %}
 7193   ins_pipe(ialu_reg_reg_ialu);
 7194 %}
 7195 
 7196 instruct cadd_cmpLTMask3( iRegI p, iRegI q, iRegI y, iRegI z, flagsReg ccr ) %{
 7197   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
 7198   effect( KILL ccr );
 7199   ins_cost(DEFAULT_COST*2);
 7200   format %{ "CMP    $p,$q\n\t"
 7201             "ADD.lt $z,$y,$z" %}
 7202   ins_encode %{
 7203     __ cmp($p$$Register, $q$$Register);
 7204     __ add($z$$Register, $y$$Register, $z$$Register, lt);
 7205   %}
 7206   ins_pipe( cadd_cmpltmask );
 7207 %}
 7208 
 7209 // FIXME: remove unused "dst"
 7210 instruct cadd_cmpLTMask4( iRegI dst, iRegI p, aimmI q, iRegI y, iRegI z, flagsReg ccr ) %{
 7211   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
 7212   effect( KILL ccr );
 7213   ins_cost(DEFAULT_COST*2);
 7214   format %{ "CMP    $p,$q\n\t"
 7215             "ADD.lt $z,$y,$z" %}
 7216   ins_encode %{
 7217     __ cmp($p$$Register, $q$$constant);
 7218     __ add($z$$Register, $y$$Register, $z$$Register, lt);
 7219   %}
 7220   ins_pipe( cadd_cmpltmask );
 7221 %}
 7222 
 7223 instruct cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, flagsReg ccr ) %{
 7224   match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
 7225   effect( KILL ccr );
 7226   ins_cost(DEFAULT_COST*2);
 7227   format %{ "SUBS   $p,$p,$q\n\t"
 7228             "ADD.lt $p,$y,$p" %}
 7229   ins_encode %{
 7230     __ subs($p$$Register, $p$$Register, $q$$Register);
 7231     __ add($p$$Register, $y$$Register, $p$$Register, lt);
 7232   %}
 7233   ins_pipe( cadd_cmpltmask );
 7234 %}
 7235 
 7236 //----------Arithmetic Conversion Instructions---------------------------------
 7237 // The conversions operations are all Alpha sorted.  Please keep it that way!
 7238 
 7239 instruct convD2F_reg(regF dst, regD src) %{
 7240   match(Set dst (ConvD2F src));
 7241   size(4);
 7242   format %{ "FCVTSD  $dst,$src" %}
 7243   ins_encode %{
 7244     __ convert_d2f($dst$$FloatRegister, $src$$FloatRegister);
 7245   %}
 7246   ins_pipe(fcvtD2F);
 7247 %}
 7248 
 7249 // Convert a double to an int in a float register.
 7250 // If the double is a NAN, stuff a zero in instead.
 7251 
 7252 instruct convD2I_reg_reg(iRegI dst, regD src, regF tmp) %{
 7253   match(Set dst (ConvD2I src));
 7254   effect( TEMP tmp );
 7255   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
 7256   format %{ "FTOSIZD  $tmp,$src\n\t"
 7257             "FMRS     $dst, $tmp" %}
 7258   ins_encode %{
 7259     __ ftosizd($tmp$$FloatRegister, $src$$FloatRegister);
 7260     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 7261   %}
 7262   ins_pipe(fcvtD2I);
 7263 %}
 7264 
 7265 // Convert a double to a long in a double register.
 7266 // If the double is a NAN, stuff a zero in instead.
 7267 
 7268 // Double to Long conversion
 7269 instruct convD2L_reg(R0R1RegL dst, regD src) %{
 7270   match(Set dst (ConvD2L src));
 7271   effect(CALL);
 7272   ins_cost(MEMORY_REF_COST); // FIXME
 7273   format %{ "convD2L    $dst,$src\t ! call to SharedRuntime::d2l" %}
 7274   ins_encode %{
 7275 #ifndef __ABI_HARD__
 7276     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
 7277 #else
 7278     if ($src$$FloatRegister != D0) {
 7279       __ mov_double(D0, $src$$FloatRegister);
 7280     }
 7281 #endif
 7282     address target = CAST_FROM_FN_PTR(address, SharedRuntime::d2l);
 7283     __ call(target, relocInfo::runtime_call_type);
 7284   %}
 7285   ins_pipe(fcvtD2L);
 7286 %}
 7287 
 7288 instruct convF2D_reg(regD dst, regF src) %{
 7289   match(Set dst (ConvF2D src));
 7290   size(4);
 7291   format %{ "FCVTDS  $dst,$src" %}
 7292   ins_encode %{
 7293     __ convert_f2d($dst$$FloatRegister, $src$$FloatRegister);
 7294   %}
 7295   ins_pipe(fcvtF2D);
 7296 %}
 7297 
 7298 instruct convF2I_reg_reg(iRegI dst, regF src, regF tmp) %{
 7299   match(Set dst (ConvF2I src));
 7300   effect( TEMP tmp );
 7301   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
 7302   size(8);
 7303   format %{ "FTOSIZS  $tmp,$src\n\t"
 7304             "FMRS     $dst, $tmp" %}
 7305   ins_encode %{
 7306     __ ftosizs($tmp$$FloatRegister, $src$$FloatRegister);
 7307     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 7308   %}
 7309   ins_pipe(fcvtF2I);
 7310 %}
 7311 
 7312 // Float to Long conversion
 7313 instruct convF2L_reg(R0R1RegL dst, regF src, R0RegI arg1) %{
 7314   match(Set dst (ConvF2L src));
 7315   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
 7316   effect(CALL);
 7317   format %{ "convF2L  $dst,$src\t! call to SharedRuntime::f2l" %}
 7318   ins_encode %{
 7319 #ifndef __ABI_HARD__
 7320     __ fmrs($arg1$$Register, $src$$FloatRegister);
 7321 #else
 7322     if($src$$FloatRegister != S0) {
 7323       __ mov_float(S0, $src$$FloatRegister);
 7324     }
 7325 #endif
 7326     address target = CAST_FROM_FN_PTR(address, SharedRuntime::f2l);
 7327     __ call(target, relocInfo::runtime_call_type);
 7328   %}
 7329   ins_pipe(fcvtF2L);
 7330 %}
 7331 
 7332 instruct convI2D_reg_reg(iRegI src, regD_low dst) %{
 7333   match(Set dst (ConvI2D src));
 7334   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
 7335   size(8);
 7336   format %{ "FMSR     $dst,$src \n\t"
 7337             "FSITOD   $dst $dst"%}
 7338   ins_encode %{
 7339       __ fmsr($dst$$FloatRegister, $src$$Register);
 7340       __ fsitod($dst$$FloatRegister, $dst$$FloatRegister);
 7341   %}
 7342   ins_pipe(fcvtI2D);
 7343 %}
 7344 
 7345 instruct convI2F_reg_reg( regF dst, iRegI src ) %{
 7346   match(Set dst (ConvI2F src));
 7347   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
 7348   size(8);
 7349   format %{ "FMSR     $dst,$src \n\t"
 7350             "FSITOS   $dst, $dst"%}
 7351   ins_encode %{
 7352       __ fmsr($dst$$FloatRegister, $src$$Register);
 7353       __ fsitos($dst$$FloatRegister, $dst$$FloatRegister);
 7354   %}
 7355   ins_pipe(fcvtI2F);
 7356 %}
 7357 
 7358 instruct convI2L_reg(iRegL dst, iRegI src) %{
 7359   match(Set dst (ConvI2L src));
 7360   size(8);
 7361   format %{ "MOV    $dst.lo, $src \n\t"
 7362             "ASR    $dst.hi,$src,31\t! int->long" %}
 7363   ins_encode %{
 7364     __ mov($dst$$Register, $src$$Register);
 7365     __ mov($dst$$Register->successor(), AsmOperand($src$$Register, asr, 31));
 7366   %}
 7367   ins_pipe(ialu_reg_reg);
 7368 %}
 7369 
 7370 // Zero-extend convert int to long
 7371 instruct convI2L_reg_zex(iRegL dst, iRegI src, immL_32bits mask ) %{
 7372   match(Set dst (AndL (ConvI2L src) mask) );
 7373   size(8);
 7374   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend int to long\n\t"
 7375             "MOV    $dst.hi, 0"%}
 7376   ins_encode %{
 7377     __ mov($dst$$Register, $src$$Register);
 7378     __ mov($dst$$Register->successor(), 0);
 7379   %}
 7380   ins_pipe(ialu_reg_reg);
 7381 %}
 7382 
 7383 // Zero-extend long
 7384 instruct zerox_long(iRegL dst, iRegL src, immL_32bits mask ) %{
 7385   match(Set dst (AndL src mask) );
 7386   size(8);
 7387   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend long\n\t"
 7388             "MOV    $dst.hi, 0"%}
 7389   ins_encode %{
 7390     __ mov($dst$$Register, $src$$Register);
 7391     __ mov($dst$$Register->successor(), 0);
 7392   %}
 7393   ins_pipe(ialu_reg_reg);
 7394 %}
 7395 
 7396 instruct MoveF2I_reg_reg(iRegI dst, regF src) %{
 7397   match(Set dst (MoveF2I src));
 7398   effect(DEF dst, USE src);
 7399   ins_cost(MEMORY_REF_COST); // FIXME
 7400 
 7401   size(4);
 7402   format %{ "FMRS   $dst,$src\t! MoveF2I" %}
 7403   ins_encode %{
 7404     __ fmrs($dst$$Register, $src$$FloatRegister);
 7405   %}
 7406   ins_pipe(iload_mem); // FIXME
 7407 %}
 7408 
 7409 instruct MoveI2F_reg_reg(regF dst, iRegI src) %{
 7410   match(Set dst (MoveI2F src));
 7411   ins_cost(MEMORY_REF_COST); // FIXME
 7412 
 7413   size(4);
 7414   format %{ "FMSR   $dst,$src\t! MoveI2F" %}
 7415   ins_encode %{
 7416     __ fmsr($dst$$FloatRegister, $src$$Register);
 7417   %}
 7418   ins_pipe(iload_mem); // FIXME
 7419 %}
 7420 
 7421 instruct MoveD2L_reg_reg(iRegL dst, regD src) %{
 7422   match(Set dst (MoveD2L src));
 7423   effect(DEF dst, USE src);
 7424   ins_cost(MEMORY_REF_COST); // FIXME
 7425 
 7426   size(4);
 7427   format %{ "FMRRD    $dst,$src\t! MoveD2L" %}
 7428   ins_encode %{
 7429     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
 7430   %}
 7431   ins_pipe(iload_mem); // FIXME
 7432 %}
 7433 
 7434 instruct MoveL2D_reg_reg(regD dst, iRegL src) %{
 7435   match(Set dst (MoveL2D src));
 7436   effect(DEF dst, USE src);
 7437   ins_cost(MEMORY_REF_COST); // FIXME
 7438 
 7439   size(4);
 7440   format %{ "FMDRR   $dst,$src\t! MoveL2D" %}
 7441   ins_encode %{
 7442     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
 7443   %}
 7444   ins_pipe(ialu_reg_reg); // FIXME
 7445 %}
 7446 
 7447 //-----------
 7448 // Long to Double conversion
 7449 
 7450 // Magic constant, 0x43300000
 7451 instruct loadConI_x43300000(iRegI dst) %{
 7452   effect(DEF dst);
 7453   size(8);
 7454   format %{ "MOV_SLOW  $dst,0x43300000\t! 2^52" %}
 7455   ins_encode %{
 7456     __ mov_slow($dst$$Register, 0x43300000);
 7457   %}
 7458   ins_pipe(ialu_none);
 7459 %}
 7460 
 7461 // Magic constant, 0x41f00000
 7462 instruct loadConI_x41f00000(iRegI dst) %{
 7463   effect(DEF dst);
 7464   size(8);
 7465   format %{ "MOV_SLOW  $dst, 0x41f00000\t! 2^32" %}
 7466   ins_encode %{
 7467     __ mov_slow($dst$$Register, 0x41f00000);
 7468   %}
 7469   ins_pipe(ialu_none);
 7470 %}
 7471 
 7472 instruct loadConI_x0(iRegI dst) %{
 7473   effect(DEF dst);
 7474   size(4);
 7475   format %{ "MOV  $dst, 0x0\t! 0" %}
 7476   ins_encode %{
 7477     __ mov($dst$$Register, 0);
 7478   %}
 7479   ins_pipe(ialu_none);
 7480 %}
 7481 
 7482 // Construct a double from two float halves
 7483 instruct regDHi_regDLo_to_regD(regD_low dst, regD_low src1, regD_low src2) %{
 7484   effect(DEF dst, USE src1, USE src2);
 7485   size(8);
 7486   format %{ "FCPYS  $dst.hi,$src1.hi\n\t"
 7487             "FCPYS  $dst.lo,$src2.lo" %}
 7488   ins_encode %{
 7489     __ fcpys($dst$$FloatRegister->successor(), $src1$$FloatRegister->successor());
 7490     __ fcpys($dst$$FloatRegister, $src2$$FloatRegister);
 7491   %}
 7492   ins_pipe(faddD_reg_reg);
 7493 %}
 7494 
 7495 // Convert integer in high half of a double register (in the lower half of
 7496 // the double register file) to double
 7497 instruct convI2D_regDHi_regD(regD dst, regD_low src) %{
 7498   effect(DEF dst, USE src);
 7499   size(4);
 7500   format %{ "FSITOD  $dst,$src" %}
 7501   ins_encode %{
 7502     __ fsitod($dst$$FloatRegister, $src$$FloatRegister->successor());
 7503   %}
 7504   ins_pipe(fcvtLHi2D);
 7505 %}
 7506 
 7507 // Add float double precision
 7508 instruct addD_regD_regD(regD dst, regD src1, regD src2) %{
 7509   effect(DEF dst, USE src1, USE src2);
 7510   size(4);
 7511   format %{ "FADDD  $dst,$src1,$src2" %}
 7512   ins_encode %{
 7513     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 7514   %}
 7515   ins_pipe(faddD_reg_reg);
 7516 %}
 7517 
 7518 // Sub float double precision
 7519 instruct subD_regD_regD(regD dst, regD src1, regD src2) %{
 7520   effect(DEF dst, USE src1, USE src2);
 7521   size(4);
 7522   format %{ "FSUBD  $dst,$src1,$src2" %}
 7523   ins_encode %{
 7524     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 7525   %}
 7526   ins_pipe(faddD_reg_reg);
 7527 %}
 7528 
 7529 // Mul float double precision
 7530 instruct mulD_regD_regD(regD dst, regD src1, regD src2) %{
 7531   effect(DEF dst, USE src1, USE src2);
 7532   size(4);
 7533   format %{ "FMULD  $dst,$src1,$src2" %}
 7534   ins_encode %{
 7535     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 7536   %}
 7537   ins_pipe(fmulD_reg_reg);
 7538 %}
 7539 
 7540 instruct regL_to_regD(regD dst, iRegL src) %{
 7541   // No match rule to avoid chain rule match.
 7542   effect(DEF dst, USE src);
 7543   ins_cost(MEMORY_REF_COST);
 7544   size(4);
 7545   format %{ "FMDRR   $dst,$src\t! regL to regD" %}
 7546   ins_encode %{
 7547     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
 7548   %}
 7549   ins_pipe(ialu_reg_reg); // FIXME
 7550 %}
 7551 
 7552 instruct regI_regI_to_regD(regD dst, iRegI src1, iRegI src2) %{
 7553   // No match rule to avoid chain rule match.
 7554   effect(DEF dst, USE src1, USE src2);
 7555   ins_cost(MEMORY_REF_COST);
 7556   size(4);
 7557   format %{ "FMDRR   $dst,$src1,$src2\t! regI,regI to regD" %}
 7558   ins_encode %{
 7559     __ fmdrr($dst$$FloatRegister, $src1$$Register, $src2$$Register);
 7560   %}
 7561   ins_pipe(ialu_reg_reg); // FIXME
 7562 %}
 7563 
 7564 instruct convL2D_reg_slow_fxtof(regD dst, iRegL src) %{
 7565   match(Set dst (ConvL2D src));
 7566   ins_cost(DEFAULT_COST*8 + MEMORY_REF_COST*6); // FIXME
 7567 
 7568   expand %{
 7569     regD_low   tmpsrc;
 7570     iRegI      ix43300000;
 7571     iRegI      ix41f00000;
 7572     iRegI      ix0;
 7573     regD_low   dx43300000;
 7574     regD       dx41f00000;
 7575     regD       tmp1;
 7576     regD_low   tmp2;
 7577     regD       tmp3;
 7578     regD       tmp4;
 7579 
 7580     regL_to_regD(tmpsrc, src);
 7581 
 7582     loadConI_x43300000(ix43300000);
 7583     loadConI_x41f00000(ix41f00000);
 7584     loadConI_x0(ix0);
 7585 
 7586     regI_regI_to_regD(dx43300000, ix0, ix43300000);
 7587     regI_regI_to_regD(dx41f00000, ix0, ix41f00000);
 7588 
 7589     convI2D_regDHi_regD(tmp1, tmpsrc);
 7590     regDHi_regDLo_to_regD(tmp2, dx43300000, tmpsrc);
 7591     subD_regD_regD(tmp3, tmp2, dx43300000);
 7592     mulD_regD_regD(tmp4, tmp1, dx41f00000);
 7593     addD_regD_regD(dst, tmp3, tmp4);
 7594   %}
 7595 %}
 7596 
 7597 instruct convL2I_reg(iRegI dst, iRegL src) %{
 7598   match(Set dst (ConvL2I src));
 7599   size(4);
 7600   format %{ "MOV    $dst,$src.lo\t! long->int" %}
 7601   ins_encode %{
 7602     __ mov($dst$$Register, $src$$Register);
 7603   %}
 7604   ins_pipe(ialu_move_reg_I_to_L);
 7605 %}
 7606 
 7607 // Register Shift Right Immediate
 7608 instruct shrL_reg_imm6_L2I(iRegI dst, iRegL src, immI_32_63 cnt) %{
 7609   match(Set dst (ConvL2I (RShiftL src cnt)));
 7610   size(4);
 7611   format %{ "ASR    $dst,$src.hi,($cnt - 32)\t! long->int or mov if $cnt==32" %}
 7612   ins_encode %{
 7613     if ($cnt$$constant == 32) {
 7614       __ mov($dst$$Register, $src$$Register->successor());
 7615     } else {
 7616       __ mov($dst$$Register, AsmOperand($src$$Register->successor(), asr, $cnt$$constant - 32));
 7617     }
 7618   %}
 7619   ins_pipe(ialu_reg_imm);
 7620 %}
 7621 
 7622 
 7623 //----------Control Flow Instructions------------------------------------------
 7624 // Compare Instructions
 7625 // Compare Integers
 7626 instruct compI_iReg(flagsReg icc, iRegI op1, iRegI op2) %{
 7627   match(Set icc (CmpI op1 op2));
 7628   effect( DEF icc, USE op1, USE op2 );
 7629 
 7630   size(4);
 7631   format %{ "cmp_32 $op1,$op2\t! int" %}
 7632   ins_encode %{
 7633     __ cmp_32($op1$$Register, $op2$$Register);
 7634   %}
 7635   ins_pipe(ialu_cconly_reg_reg);
 7636 %}
 7637 
 7638 #ifdef _LP64
 7639 // Compare compressed pointers
 7640 instruct compN_reg2(flagsRegU icc, iRegN op1, iRegN op2) %{
 7641   match(Set icc (CmpN op1 op2));
 7642   effect( DEF icc, USE op1, USE op2 );
 7643 
 7644   size(4);
 7645   format %{ "cmp_32 $op1,$op2\t! int" %}
 7646   ins_encode %{
 7647     __ cmp_32($op1$$Register, $op2$$Register);
 7648   %}
 7649   ins_pipe(ialu_cconly_reg_reg);
 7650 %}
 7651 #endif
 7652 
 7653 instruct compU_iReg(flagsRegU icc, iRegI op1, iRegI op2) %{
 7654   match(Set icc (CmpU op1 op2));
 7655 
 7656   size(4);
 7657   format %{ "cmp_32 $op1,$op2\t! unsigned int" %}
 7658   ins_encode %{
 7659     __ cmp_32($op1$$Register, $op2$$Register);
 7660   %}
 7661   ins_pipe(ialu_cconly_reg_reg);
 7662 %}
 7663 
 7664 instruct compI_iReg_immneg(flagsReg icc, iRegI op1, aimmIneg op2) %{
 7665   match(Set icc (CmpI op1 op2));
 7666   effect( DEF icc, USE op1 );
 7667 
 7668   size(4);
 7669   format %{ "cmn_32 $op1,-$op2\t! int" %}
 7670   ins_encode %{
 7671     __ cmn_32($op1$$Register, -$op2$$constant);
 7672   %}
 7673   ins_pipe(ialu_cconly_reg_imm);
 7674 %}
 7675 
 7676 instruct compI_iReg_imm(flagsReg icc, iRegI op1, aimmI op2) %{
 7677   match(Set icc (CmpI op1 op2));
 7678   effect( DEF icc, USE op1 );
 7679 
 7680   size(4);
 7681   format %{ "cmp_32 $op1,$op2\t! int" %}
 7682   ins_encode %{
 7683     __ cmp_32($op1$$Register, $op2$$constant);
 7684   %}
 7685   ins_pipe(ialu_cconly_reg_imm);
 7686 %}
 7687 
 7688 instruct testI_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immI0 zero ) %{
 7689   match(Set icc (CmpI (AndI op1 op2) zero));
 7690   size(4);
 7691   format %{ "tst_32 $op2,$op1" %}
 7692 
 7693   ins_encode %{
 7694     __ tst_32($op1$$Register, $op2$$Register);
 7695   %}
 7696   ins_pipe(ialu_cconly_reg_reg_zero);
 7697 %}
 7698 
 7699 instruct testshlI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
 7700   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
 7701   size(4);
 7702   format %{ "TST   $op2,$op1<<$op3" %}
 7703 
 7704   ins_encode %{
 7705     __ tst($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$Register));
 7706   %}
 7707   ins_pipe(ialu_cconly_reg_reg_zero);
 7708 %}
 7709 
 7710 instruct testshlI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
 7711   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
 7712   size(4);
 7713   format %{ "tst_32 $op2,$op1<<$op3" %}
 7714 
 7715   ins_encode %{
 7716     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$constant));
 7717   %}
 7718   ins_pipe(ialu_cconly_reg_reg_zero);
 7719 %}
 7720 
 7721 instruct testsarI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
 7722   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
 7723   size(4);
 7724   format %{ "TST   $op2,$op1<<$op3" %}
 7725 
 7726   ins_encode %{
 7727     __ tst($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$Register));
 7728   %}
 7729   ins_pipe(ialu_cconly_reg_reg_zero);
 7730 %}
 7731 
 7732 instruct testsarI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
 7733   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
 7734   size(4);
 7735   format %{ "tst_32 $op2,$op1<<$op3" %}
 7736 
 7737   ins_encode %{
 7738     __ tst_32($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$constant));
 7739   %}
 7740   ins_pipe(ialu_cconly_reg_reg_zero);
 7741 %}
 7742 
 7743 instruct testshrI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
 7744   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
 7745   size(4);
 7746   format %{ "TST   $op2,$op1<<$op3" %}
 7747 
 7748   ins_encode %{
 7749     __ tst($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$Register));
 7750   %}
 7751   ins_pipe(ialu_cconly_reg_reg_zero);
 7752 %}
 7753 
 7754 instruct testshrI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
 7755   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
 7756   size(4);
 7757   format %{ "tst_32 $op2,$op1<<$op3" %}
 7758 
 7759   ins_encode %{
 7760     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$constant));
 7761   %}
 7762   ins_pipe(ialu_cconly_reg_reg_zero);
 7763 %}
 7764 
 7765 instruct testI_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, limmI op2, immI0 zero ) %{
 7766   match(Set icc (CmpI (AndI op1 op2) zero));
 7767   size(4);
 7768   format %{ "tst_32 $op2,$op1" %}
 7769 
 7770   ins_encode %{
 7771     __ tst_32($op1$$Register, $op2$$constant);
 7772   %}
 7773   ins_pipe(ialu_cconly_reg_imm_zero);
 7774 %}
 7775 
 7776 instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7777   match(Set xcc (CmpL op1 op2));
 7778   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
 7779 
 7780   size(8);
 7781   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! long\n\t"
 7782             "SBCS    $tmp,$op1.hi,$op2.hi" %}
 7783   ins_encode %{
 7784     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
 7785     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
 7786   %}
 7787   ins_pipe(ialu_cconly_reg_reg);
 7788 %}
 7789 
 7790 instruct compUL_reg_reg_LTGE(flagsRegUL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7791   match(Set xcc (CmpUL op1 op2));
 7792   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
 7793 
 7794   size(8);
 7795   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! unsigned long\n\t"
 7796             "SBCS    $tmp,$op1.hi,$op2.hi" %}
 7797   ins_encode %{
 7798     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
 7799     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
 7800   %}
 7801   ins_pipe(ialu_cconly_reg_reg);
 7802 %}
 7803 
 7804 instruct compL_reg_reg_EQNE(flagsRegL_EQNE xcc, iRegL op1, iRegL op2) %{
 7805   match(Set xcc (CmpL op1 op2));
 7806   effect( DEF xcc, USE op1, USE op2 );
 7807 
 7808   size(8);
 7809   format %{ "TEQ    $op1.hi,$op2.hi\t\t! long\n\t"
 7810             "TEQ.eq $op1.lo,$op2.lo" %}
 7811   ins_encode %{
 7812     __ teq($op1$$Register->successor(), $op2$$Register->successor());
 7813     __ teq($op1$$Register, $op2$$Register, eq);
 7814   %}
 7815   ins_pipe(ialu_cconly_reg_reg);
 7816 %}
 7817 
 7818 instruct compL_reg_reg_LEGT(flagsRegL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7819   match(Set xcc (CmpL op1 op2));
 7820   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
 7821 
 7822   size(8);
 7823   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! long\n\t"
 7824             "SBCS    $tmp,$op2.hi,$op1.hi" %}
 7825   ins_encode %{
 7826     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
 7827     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
 7828   %}
 7829   ins_pipe(ialu_cconly_reg_reg);
 7830 %}
 7831 
 7832 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7833 // (hi($con$$constant), lo($con$$constant)) becomes
 7834 instruct compL_reg_con_LTGE(flagsRegL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7835   match(Set xcc (CmpL op1 con));
 7836   effect( DEF xcc, USE op1, USE con, TEMP tmp );
 7837 
 7838   size(8);
 7839   format %{ "SUBS    $tmp,$op1.low,$con\t\t! long\n\t"
 7840             "SBCS    $tmp,$op1.hi,0" %}
 7841   ins_encode %{
 7842     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
 7843     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7844   %}
 7845 
 7846   ins_pipe(ialu_cconly_reg_reg);
 7847 %}
 7848 
 7849 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7850 // (hi($con$$constant), lo($con$$constant)) becomes
 7851 instruct compL_reg_con_EQNE(flagsRegL_EQNE xcc, iRegL op1, immLlowRot con) %{
 7852   match(Set xcc (CmpL op1 con));
 7853   effect( DEF xcc, USE op1, USE con );
 7854 
 7855   size(8);
 7856   format %{ "TEQ    $op1.hi,0\t\t! long\n\t"
 7857             "TEQ.eq $op1.lo,$con" %}
 7858   ins_encode %{
 7859     __ teq($op1$$Register->successor(), 0);
 7860     __ teq($op1$$Register, $con$$constant, eq);
 7861   %}
 7862 
 7863   ins_pipe(ialu_cconly_reg_reg);
 7864 %}
 7865 
 7866 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7867 // (hi($con$$constant), lo($con$$constant)) becomes
 7868 instruct compL_reg_con_LEGT(flagsRegL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7869   match(Set xcc (CmpL op1 con));
 7870   effect( DEF xcc, USE op1, USE con, TEMP tmp );
 7871 
 7872   size(8);
 7873   format %{ "RSBS    $tmp,$op1.low,$con\t\t! long\n\t"
 7874             "RSCS    $tmp,$op1.hi,0" %}
 7875   ins_encode %{
 7876     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
 7877     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7878   %}
 7879 
 7880   ins_pipe(ialu_cconly_reg_reg);
 7881 %}
 7882 
 7883 instruct compUL_reg_reg_EQNE(flagsRegUL_EQNE xcc, iRegL op1, iRegL op2) %{
 7884   match(Set xcc (CmpUL op1 op2));
 7885   effect(DEF xcc, USE op1, USE op2);
 7886 
 7887   size(8);
 7888   format %{ "TEQ    $op1.hi,$op2.hi\t\t! unsigned long\n\t"
 7889             "TEQ.eq $op1.lo,$op2.lo" %}
 7890   ins_encode %{
 7891     __ teq($op1$$Register->successor(), $op2$$Register->successor());
 7892     __ teq($op1$$Register, $op2$$Register, eq);
 7893   %}
 7894   ins_pipe(ialu_cconly_reg_reg);
 7895 %}
 7896 
 7897 instruct compUL_reg_reg_LEGT(flagsRegUL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
 7898   match(Set xcc (CmpUL op1 op2));
 7899   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
 7900 
 7901   size(8);
 7902   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! unsigned long\n\t"
 7903             "SBCS    $tmp,$op2.hi,$op1.hi" %}
 7904   ins_encode %{
 7905     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
 7906     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
 7907   %}
 7908   ins_pipe(ialu_cconly_reg_reg);
 7909 %}
 7910 
 7911 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7912 // (hi($con$$constant), lo($con$$constant)) becomes
 7913 instruct compUL_reg_con_LTGE(flagsRegUL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7914   match(Set xcc (CmpUL op1 con));
 7915   effect(DEF xcc, USE op1, USE con, TEMP tmp);
 7916 
 7917   size(8);
 7918   format %{ "SUBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
 7919             "SBCS    $tmp,$op1.hi,0" %}
 7920   ins_encode %{
 7921     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
 7922     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7923   %}
 7924 
 7925   ins_pipe(ialu_cconly_reg_reg);
 7926 %}
 7927 
 7928 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7929 // (hi($con$$constant), lo($con$$constant)) becomes
 7930 instruct compUL_reg_con_EQNE(flagsRegUL_EQNE xcc, iRegL op1, immLlowRot con) %{
 7931   match(Set xcc (CmpUL op1 con));
 7932   effect(DEF xcc, USE op1, USE con);
 7933 
 7934   size(8);
 7935   format %{ "TEQ    $op1.hi,0\t\t! unsigned long\n\t"
 7936             "TEQ.eq $op1.lo,$con" %}
 7937   ins_encode %{
 7938     __ teq($op1$$Register->successor(), 0);
 7939     __ teq($op1$$Register, $con$$constant, eq);
 7940   %}
 7941 
 7942   ins_pipe(ialu_cconly_reg_reg);
 7943 %}
 7944 
 7945 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
 7946 // (hi($con$$constant), lo($con$$constant)) becomes
 7947 instruct compUL_reg_con_LEGT(flagsRegUL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
 7948   match(Set xcc (CmpUL op1 con));
 7949   effect(DEF xcc, USE op1, USE con, TEMP tmp);
 7950 
 7951   size(8);
 7952   format %{ "RSBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
 7953             "RSCS    $tmp,$op1.hi,0" %}
 7954   ins_encode %{
 7955     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
 7956     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
 7957   %}
 7958 
 7959   ins_pipe(ialu_cconly_reg_reg);
 7960 %}
 7961 
 7962 /* instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ */
 7963 /*   match(Set xcc (CmpL (AndL op1 op2) zero)); */
 7964 /*   ins_encode %{ */
 7965 /*     __ stop("testL_reg_reg unimplemented"); */
 7966 /*   %} */
 7967 /*   ins_pipe(ialu_cconly_reg_reg); */
 7968 /* %} */
 7969 
 7970 /* // useful for checking the alignment of a pointer: */
 7971 /* instruct testL_reg_con(flagsRegL xcc, iRegL op1, immLlowRot con, immL0 zero) %{ */
 7972 /*   match(Set xcc (CmpL (AndL op1 con) zero)); */
 7973 /*   ins_encode %{ */
 7974 /*     __ stop("testL_reg_con unimplemented"); */
 7975 /*   %} */
 7976 /*   ins_pipe(ialu_cconly_reg_reg); */
 7977 /* %} */
 7978 
 7979 instruct compU_iReg_imm(flagsRegU icc, iRegI op1, aimmU31 op2 ) %{
 7980   match(Set icc (CmpU op1 op2));
 7981 
 7982   size(4);
 7983   format %{ "cmp_32 $op1,$op2\t! unsigned" %}
 7984   ins_encode %{
 7985     __ cmp_32($op1$$Register, $op2$$constant);
 7986   %}
 7987   ins_pipe(ialu_cconly_reg_imm);
 7988 %}
 7989 
 7990 // Compare Pointers
 7991 instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{
 7992   match(Set pcc (CmpP op1 op2));
 7993 
 7994   size(4);
 7995   format %{ "CMP    $op1,$op2\t! ptr" %}
 7996   ins_encode %{
 7997     __ cmp($op1$$Register, $op2$$Register);
 7998   %}
 7999   ins_pipe(ialu_cconly_reg_reg);
 8000 %}
 8001 
 8002 instruct compP_iRegP_imm(flagsRegP pcc, iRegP op1, aimmP op2 ) %{
 8003   match(Set pcc (CmpP op1 op2));
 8004 
 8005   size(4);
 8006   format %{ "CMP    $op1,$op2\t! ptr" %}
 8007   ins_encode %{
 8008     assert($op2$$constant == 0 || _opnds[2]->constant_reloc() == relocInfo::none, "reloc in cmp?");
 8009     __ cmp($op1$$Register, $op2$$constant);
 8010   %}
 8011   ins_pipe(ialu_cconly_reg_imm);
 8012 %}
 8013 
 8014 //----------Max and Min--------------------------------------------------------
 8015 // Min Instructions
 8016 // Conditional move for min
 8017 instruct cmovI_reg_lt( iRegI op2, iRegI op1, flagsReg icc ) %{
 8018   effect( USE_DEF op2, USE op1, USE icc );
 8019 
 8020   size(4);
 8021   format %{ "MOV.lt  $op2,$op1\t! min" %}
 8022   ins_encode %{
 8023     __ mov($op2$$Register, $op1$$Register, lt);
 8024   %}
 8025   ins_pipe(ialu_reg_flags);
 8026 %}
 8027 
 8028 // Min Register with Register.
 8029 instruct minI_eReg(iRegI op1, iRegI op2) %{
 8030   match(Set op2 (MinI op1 op2));
 8031   ins_cost(DEFAULT_COST*2);
 8032   expand %{
 8033     flagsReg icc;
 8034     compI_iReg(icc,op1,op2);
 8035     cmovI_reg_lt(op2,op1,icc);
 8036   %}
 8037 %}
 8038 
 8039 // Max Instructions
 8040 // Conditional move for max
 8041 instruct cmovI_reg_gt( iRegI op2, iRegI op1, flagsReg icc ) %{
 8042   effect( USE_DEF op2, USE op1, USE icc );
 8043   format %{ "MOV.gt  $op2,$op1\t! max" %}
 8044   ins_encode %{
 8045     __ mov($op2$$Register, $op1$$Register, gt);
 8046   %}
 8047   ins_pipe(ialu_reg_flags);
 8048 %}
 8049 
 8050 // Max Register with Register
 8051 instruct maxI_eReg(iRegI op1, iRegI op2) %{
 8052   match(Set op2 (MaxI op1 op2));
 8053   ins_cost(DEFAULT_COST*2);
 8054   expand %{
 8055     flagsReg icc;
 8056     compI_iReg(icc,op1,op2);
 8057     cmovI_reg_gt(op2,op1,icc);
 8058   %}
 8059 %}
 8060 
 8061 
 8062 //----------Float Compares----------------------------------------------------
 8063 // Compare floating, generate condition code
 8064 instruct cmpF_cc(flagsRegF fcc, flagsReg icc, regF src1, regF src2) %{
 8065   match(Set icc (CmpF src1 src2));
 8066   effect(KILL fcc);
 8067 
 8068   size(8);
 8069   format %{ "FCMPs  $src1,$src2\n\t"
 8070             "FMSTAT" %}
 8071   ins_encode %{
 8072     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
 8073     __ fmstat();
 8074   %}
 8075   ins_pipe(faddF_fcc_reg_reg_zero);
 8076 %}
 8077 
 8078 instruct cmpF0_cc(flagsRegF fcc, flagsReg icc, regF src1, immF0 src2) %{
 8079   match(Set icc (CmpF src1 src2));
 8080   effect(KILL fcc);
 8081 
 8082   size(8);
 8083   format %{ "FCMPs  $src1,$src2\n\t"
 8084             "FMSTAT" %}
 8085   ins_encode %{
 8086     __ fcmpzs($src1$$FloatRegister);
 8087     __ fmstat();
 8088   %}
 8089   ins_pipe(faddF_fcc_reg_reg_zero);
 8090 %}
 8091 
 8092 instruct cmpD_cc(flagsRegF fcc, flagsReg icc, regD src1, regD src2) %{
 8093   match(Set icc (CmpD src1 src2));
 8094   effect(KILL fcc);
 8095 
 8096   size(8);
 8097   format %{ "FCMPd  $src1,$src2 \n\t"
 8098             "FMSTAT" %}
 8099   ins_encode %{
 8100     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
 8101     __ fmstat();
 8102   %}
 8103   ins_pipe(faddD_fcc_reg_reg_zero);
 8104 %}
 8105 
 8106 instruct cmpD0_cc(flagsRegF fcc, flagsReg icc, regD src1, immD0 src2) %{
 8107   match(Set icc (CmpD src1 src2));
 8108   effect(KILL fcc);
 8109 
 8110   size(8);
 8111   format %{ "FCMPZd  $src1,$src2 \n\t"
 8112             "FMSTAT" %}
 8113   ins_encode %{
 8114     __ fcmpzd($src1$$FloatRegister);
 8115     __ fmstat();
 8116   %}
 8117   ins_pipe(faddD_fcc_reg_reg_zero);
 8118 %}
 8119 
 8120 // Compare floating, generate -1,0,1
 8121 instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsRegF fcc) %{
 8122   match(Set dst (CmpF3 src1 src2));
 8123   effect(KILL fcc);
 8124   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 8125   size(20);
 8126   // same number of instructions as code using conditional moves but
 8127   // doesn't kill integer condition register
 8128   format %{ "FCMPs  $dst,$src1,$src2 \n\t"
 8129             "VMRS   $dst, FPSCR \n\t"
 8130             "OR     $dst, $dst, 0x08000000 \n\t"
 8131             "EOR    $dst, $dst, $dst << 3 \n\t"
 8132             "MOV    $dst, $dst >> 30" %}
 8133   ins_encode %{
 8134     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
 8135     __ floating_cmp($dst$$Register);
 8136   %}
 8137   ins_pipe( floating_cmp );
 8138 %}
 8139 
 8140 instruct cmpF0_reg(iRegI dst, regF src1, immF0 src2, flagsRegF fcc) %{
 8141   match(Set dst (CmpF3 src1 src2));
 8142   effect(KILL fcc);
 8143   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 8144   size(20);
 8145   // same number of instructions as code using conditional moves but
 8146   // doesn't kill integer condition register
 8147   format %{ "FCMPZs $dst,$src1,$src2 \n\t"
 8148             "VMRS   $dst, FPSCR \n\t"
 8149             "OR     $dst, $dst, 0x08000000 \n\t"
 8150             "EOR    $dst, $dst, $dst << 3 \n\t"
 8151             "MOV    $dst, $dst >> 30" %}
 8152   ins_encode %{
 8153     __ fcmpzs($src1$$FloatRegister);
 8154     __ floating_cmp($dst$$Register);
 8155   %}
 8156   ins_pipe( floating_cmp );
 8157 %}
 8158 
 8159 instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsRegF fcc) %{
 8160   match(Set dst (CmpD3 src1 src2));
 8161   effect(KILL fcc);
 8162   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 8163   size(20);
 8164   // same number of instructions as code using conditional moves but
 8165   // doesn't kill integer condition register
 8166   format %{ "FCMPd  $dst,$src1,$src2 \n\t"
 8167             "VMRS   $dst, FPSCR \n\t"
 8168             "OR     $dst, $dst, 0x08000000 \n\t"
 8169             "EOR    $dst, $dst, $dst << 3 \n\t"
 8170             "MOV    $dst, $dst >> 30" %}
 8171   ins_encode %{
 8172     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
 8173     __ floating_cmp($dst$$Register);
 8174   %}
 8175   ins_pipe( floating_cmp );
 8176 %}
 8177 
 8178 instruct cmpD0_reg(iRegI dst, regD src1, immD0 src2, flagsRegF fcc) %{
 8179   match(Set dst (CmpD3 src1 src2));
 8180   effect(KILL fcc);
 8181   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
 8182   size(20);
 8183   // same number of instructions as code using conditional moves but
 8184   // doesn't kill integer condition register
 8185   format %{ "FCMPZd $dst,$src1,$src2 \n\t"
 8186             "VMRS   $dst, FPSCR \n\t"
 8187             "OR     $dst, $dst, 0x08000000 \n\t"
 8188             "EOR    $dst, $dst, $dst << 3 \n\t"
 8189             "MOV    $dst, $dst >> 30" %}
 8190   ins_encode %{
 8191     __ fcmpzd($src1$$FloatRegister);
 8192     __ floating_cmp($dst$$Register);
 8193   %}
 8194   ins_pipe( floating_cmp );
 8195 %}
 8196 
 8197 //----------Branches---------------------------------------------------------
 8198 // Jump
 8199 // (compare 'operand indIndex' and 'instruct addP_reg_reg' above)
 8200 // FIXME
 8201 instruct jumpXtnd(iRegX switch_val, iRegP tmp) %{
 8202   match(Jump switch_val);
 8203   effect(TEMP tmp);
 8204   ins_cost(350);
 8205   format %{  "ADD    $tmp, $constanttablebase, $switch_val\n\t"
 8206              "LDR    $tmp,[$tmp + $constantoffset]\n\t"
 8207              "BX     $tmp" %}
 8208   size(20);
 8209   ins_encode %{
 8210     Register table_reg;
 8211     Register label_reg = $tmp$$Register;
 8212     if (constant_offset() == 0) {
 8213       table_reg = $constanttablebase;
 8214       __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
 8215     } else {
 8216       table_reg = $tmp$$Register;
 8217       int offset = $constantoffset;
 8218       if (is_memoryP(offset)) {
 8219         __ add(table_reg, $constanttablebase, $switch_val$$Register);
 8220         __ ldr(label_reg, Address(table_reg, offset));
 8221       } else {
 8222         __ mov_slow(table_reg, $constantoffset);
 8223         __ add(table_reg, $constanttablebase, table_reg);
 8224         __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
 8225       }
 8226     }
 8227     __ jump(label_reg); // ldr + b better than ldr to PC for branch predictor?
 8228     //    __ ldr(PC, Address($table$$Register, $switch_val$$Register));
 8229   %}
 8230   ins_pipe(ialu_reg_reg);
 8231 %}
 8232 
 8233 // // Direct Branch.
 8234 instruct branch(label labl) %{
 8235   match(Goto);
 8236   effect(USE labl);
 8237 
 8238   size(4);
 8239   ins_cost(BRANCH_COST);
 8240   format %{ "B     $labl" %}
 8241   ins_encode %{
 8242     __ b(*($labl$$label));
 8243   %}
 8244   ins_pipe(br);
 8245 %}
 8246 
 8247 // Conditional Direct Branch
 8248 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{
 8249   match(If cmp icc);
 8250   effect(USE labl);
 8251 
 8252   size(4);
 8253   ins_cost(BRANCH_COST);
 8254   format %{ "B$cmp   $icc,$labl" %}
 8255   ins_encode %{
 8256     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8257   %}
 8258   ins_pipe(br_cc);
 8259 %}
 8260 
 8261 #ifdef ARM
 8262 instruct branchCon_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, label labl) %{
 8263   match(If cmp icc);
 8264   effect(USE labl);
 8265   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);
 8266 
 8267   size(4);
 8268   ins_cost(BRANCH_COST);
 8269   format %{ "B$cmp   $icc,$labl" %}
 8270   ins_encode %{
 8271     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8272   %}
 8273   ins_pipe(br_cc);
 8274 %}
 8275 #endif
 8276 
 8277 
 8278 instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{
 8279   match(If cmp icc);
 8280   effect(USE labl);
 8281 
 8282   size(4);
 8283   ins_cost(BRANCH_COST);
 8284   format %{ "B$cmp  $icc,$labl" %}
 8285   ins_encode %{
 8286     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8287   %}
 8288   ins_pipe(br_cc);
 8289 %}
 8290 
 8291 instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{
 8292   match(If cmp pcc);
 8293   effect(USE labl);
 8294 
 8295   size(4);
 8296   ins_cost(BRANCH_COST);
 8297   format %{ "B$cmp  $pcc,$labl" %}
 8298   ins_encode %{
 8299     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8300   %}
 8301   ins_pipe(br_cc);
 8302 %}
 8303 
 8304 instruct branchConL_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, label labl) %{
 8305   match(If cmp xcc);
 8306   effect(USE labl);
 8307   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8308 
 8309   size(4);
 8310   ins_cost(BRANCH_COST);
 8311   format %{ "B$cmp  $xcc,$labl" %}
 8312   ins_encode %{
 8313     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8314   %}
 8315   ins_pipe(br_cc);
 8316 %}
 8317 
 8318 instruct branchConL_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, label labl) %{
 8319   match(If cmp xcc);
 8320   effect(USE labl);
 8321   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8322 
 8323   size(4);
 8324   ins_cost(BRANCH_COST);
 8325   format %{ "B$cmp  $xcc,$labl" %}
 8326   ins_encode %{
 8327     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8328   %}
 8329   ins_pipe(br_cc);
 8330 %}
 8331 
 8332 instruct branchConL_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, label labl) %{
 8333   match(If cmp xcc);
 8334   effect(USE labl);
 8335   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le );
 8336 
 8337   size(4);
 8338   ins_cost(BRANCH_COST);
 8339   format %{ "B$cmp  $xcc,$labl" %}
 8340   ins_encode %{
 8341     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8342   %}
 8343   ins_pipe(br_cc);
 8344 %}
 8345 
 8346 instruct branchConUL_LTGE(cmpOpUL cmp, flagsRegUL_LTGE xcc, label labl) %{
 8347   match(If cmp xcc);
 8348   effect(USE labl);
 8349   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
 8350 
 8351   size(4);
 8352   ins_cost(BRANCH_COST);
 8353   format %{ "B$cmp  $xcc,$labl" %}
 8354   ins_encode %{
 8355     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8356   %}
 8357   ins_pipe(br_cc);
 8358 %}
 8359 
 8360 instruct branchConUL_EQNE(cmpOpUL cmp, flagsRegUL_EQNE xcc, label labl) %{
 8361   match(If cmp xcc);
 8362   effect(USE labl);
 8363   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
 8364 
 8365   size(4);
 8366   ins_cost(BRANCH_COST);
 8367   format %{ "B$cmp  $xcc,$labl" %}
 8368   ins_encode %{
 8369     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8370   %}
 8371   ins_pipe(br_cc);
 8372 %}
 8373 
 8374 instruct branchConUL_LEGT(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, label labl) %{
 8375   match(If cmp xcc);
 8376   effect(USE labl);
 8377   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le);
 8378 
 8379   size(4);
 8380   ins_cost(BRANCH_COST);
 8381   format %{ "B$cmp  $xcc,$labl" %}
 8382   ins_encode %{
 8383     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8384   %}
 8385   ins_pipe(br_cc);
 8386 %}
 8387 
 8388 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
 8389   match(CountedLoopEnd cmp icc);
 8390   effect(USE labl);
 8391 
 8392   size(4);
 8393   ins_cost(BRANCH_COST);
 8394   format %{ "B$cmp   $icc,$labl\t! Loop end" %}
 8395   ins_encode %{
 8396     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
 8397   %}
 8398   ins_pipe(br_cc);
 8399 %}
 8400 
 8401 // instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{
 8402 //   match(CountedLoopEnd cmp icc);
 8403 //   ins_pipe(br_cc);
 8404 // %}
 8405 
 8406 // ============================================================================
 8407 // Long Compare
 8408 //
 8409 // Currently we hold longs in 2 registers.  Comparing such values efficiently
 8410 // is tricky.  The flavor of compare used depends on whether we are testing
 8411 // for LT, LE, or EQ.  For a simple LT test we can check just the sign bit.
 8412 // The GE test is the negated LT test.  The LE test can be had by commuting
 8413 // the operands (yielding a GE test) and then negating; negate again for the
 8414 // GT test.  The EQ test is done by ORcc'ing the high and low halves, and the
 8415 // NE test is negated from that.
 8416 
 8417 // Due to a shortcoming in the ADLC, it mixes up expressions like:
 8418 // (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)).  Note the
 8419 // difference between 'Y' and '0L'.  The tree-matches for the CmpI sections
 8420 // are collapsed internally in the ADLC's dfa-gen code.  The match for
 8421 // (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the
 8422 // foo match ends up with the wrong leaf.  One fix is to not match both
 8423 // reg-reg and reg-zero forms of long-compare.  This is unfortunate because
 8424 // both forms beat the trinary form of long-compare and both are very useful
 8425 // on Intel which has so few registers.
 8426 
 8427 // instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{
 8428 //   match(If cmp xcc);
 8429 //   ins_pipe(br_cc);
 8430 // %}
 8431 
 8432 // Manifest a CmpL3 result in an integer register.  Very painful.
 8433 // This is the test to avoid.
 8434 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
 8435   match(Set dst (CmpL3 src1 src2) );
 8436   effect( KILL ccr );
 8437   ins_cost(6*DEFAULT_COST); // FIXME
 8438   size(32);
 8439   format %{
 8440       "CMP    $src1.hi, $src2.hi\t\t! long\n"
 8441     "\tMOV.gt $dst, 1\n"
 8442     "\tmvn.lt $dst, 0\n"
 8443     "\tB.ne   done\n"
 8444     "\tSUBS   $dst, $src1.lo, $src2.lo\n"
 8445     "\tMOV.hi $dst, 1\n"
 8446     "\tmvn.lo $dst, 0\n"
 8447     "done:"     %}
 8448   ins_encode %{
 8449     Label done;
 8450     __ cmp($src1$$Register->successor(), $src2$$Register->successor());
 8451     __ mov($dst$$Register, 1, gt);
 8452     __ mvn($dst$$Register, 0, lt);
 8453     __ b(done, ne);
 8454     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
 8455     __ mov($dst$$Register, 1, hi);
 8456     __ mvn($dst$$Register, 0, lo);
 8457     __ bind(done);
 8458   %}
 8459   ins_pipe(cmpL_reg);
 8460 %}
 8461 
 8462 // Conditional move
 8463 instruct cmovLL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, iRegL src) %{
 8464   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8465   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8466 
 8467   ins_cost(150);
 8468   size(8);
 8469   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8470             "MOV$cmp  $dst,$src.hi" %}
 8471   ins_encode %{
 8472     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8473     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8474   %}
 8475   ins_pipe(ialu_reg);
 8476 %}
 8477 
 8478 instruct cmovLL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, iRegL src) %{
 8479   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8480   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8481 
 8482   ins_cost(150);
 8483   size(8);
 8484   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8485             "MOV$cmp  $dst,$src.hi" %}
 8486   ins_encode %{
 8487     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8488     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8489   %}
 8490   ins_pipe(ialu_reg);
 8491 %}
 8492 
 8493 instruct cmovLL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, iRegL src) %{
 8494   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8495   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8496 
 8497   ins_cost(150);
 8498   size(8);
 8499   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
 8500             "MOV$cmp  $dst,$src.hi" %}
 8501   ins_encode %{
 8502     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8503     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
 8504   %}
 8505   ins_pipe(ialu_reg);
 8506 %}
 8507 
 8508 instruct cmovLL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, immL0 src) %{
 8509   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8510   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8511   ins_cost(140);
 8512   size(8);
 8513   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8514             "MOV$cmp  $dst,0" %}
 8515   ins_encode %{
 8516     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8517     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8518   %}
 8519   ins_pipe(ialu_imm);
 8520 %}
 8521 
 8522 instruct cmovLL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, immL0 src) %{
 8523   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8524   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8525   ins_cost(140);
 8526   size(8);
 8527   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8528             "MOV$cmp  $dst,0" %}
 8529   ins_encode %{
 8530     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8531     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8532   %}
 8533   ins_pipe(ialu_imm);
 8534 %}
 8535 
 8536 instruct cmovLL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, immL0 src) %{
 8537   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
 8538   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8539   ins_cost(140);
 8540   size(8);
 8541   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
 8542             "MOV$cmp  $dst,0" %}
 8543   ins_encode %{
 8544     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
 8545     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
 8546   %}
 8547   ins_pipe(ialu_imm);
 8548 %}
 8549 
 8550 instruct cmovIL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, iRegI src) %{
 8551   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8552   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8553 
 8554   ins_cost(150);
 8555   size(4);
 8556   format %{ "MOV$cmp  $dst,$src" %}
 8557   ins_encode %{
 8558     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8559   %}
 8560   ins_pipe(ialu_reg);
 8561 %}
 8562 
 8563 instruct cmovIL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, iRegI 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(150);
 8568   size(4);
 8569   format %{ "MOV$cmp  $dst,$src" %}
 8570   ins_encode %{
 8571     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8572   %}
 8573   ins_pipe(ialu_reg);
 8574 %}
 8575 
 8576 instruct cmovIL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, iRegI src) %{
 8577   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8578   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8579 
 8580   ins_cost(150);
 8581   size(4);
 8582   format %{ "MOV$cmp  $dst,$src" %}
 8583   ins_encode %{
 8584     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8585   %}
 8586   ins_pipe(ialu_reg);
 8587 %}
 8588 
 8589 instruct cmovIL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immI16 src) %{
 8590   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8591   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8592 
 8593   ins_cost(140);
 8594   format %{ "MOVW$cmp  $dst,$src" %}
 8595   ins_encode %{
 8596     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8597   %}
 8598   ins_pipe(ialu_imm);
 8599 %}
 8600 
 8601 instruct cmovIL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, immI16 src) %{
 8602   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
 8603   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8604 
 8605   ins_cost(140);
 8606   format %{ "MOVW$cmp  $dst,$src" %}
 8607   ins_encode %{
 8608     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8609   %}
 8610   ins_pipe(ialu_imm);
 8611 %}
 8612 
 8613 instruct cmovIL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immI16 src) %{
 8614   match(Set dst (CMoveI (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(140);
 8618   format %{ "MOVW$cmp  $dst,$src" %}
 8619   ins_encode %{
 8620     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8621   %}
 8622   ins_pipe(ialu_imm);
 8623 %}
 8624 
 8625 instruct cmovPL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, iRegP src) %{
 8626   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8627   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8628 
 8629   ins_cost(150);
 8630   size(4);
 8631   format %{ "MOV$cmp  $dst,$src" %}
 8632   ins_encode %{
 8633     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8634   %}
 8635   ins_pipe(ialu_reg);
 8636 %}
 8637 
 8638 instruct cmovPL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, iRegP 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(150);
 8643   size(4);
 8644   format %{ "MOV$cmp  $dst,$src" %}
 8645   ins_encode %{
 8646     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8647   %}
 8648   ins_pipe(ialu_reg);
 8649 %}
 8650 
 8651 instruct cmovPL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, iRegP src) %{
 8652   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8653   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8654 
 8655   ins_cost(150);
 8656   size(4);
 8657   format %{ "MOV$cmp  $dst,$src" %}
 8658   ins_encode %{
 8659     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
 8660   %}
 8661   ins_pipe(ialu_reg);
 8662 %}
 8663 
 8664 instruct cmovPL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, immP0 src) %{
 8665   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8666   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8667 
 8668   ins_cost(140);
 8669   format %{ "MOVW$cmp  $dst,$src" %}
 8670   ins_encode %{
 8671     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8672   %}
 8673   ins_pipe(ialu_imm);
 8674 %}
 8675 
 8676 instruct cmovPL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, immP0 src) %{
 8677   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8678   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8679 
 8680   ins_cost(140);
 8681   format %{ "MOVW$cmp  $dst,$src" %}
 8682   ins_encode %{
 8683     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8684   %}
 8685   ins_pipe(ialu_imm);
 8686 %}
 8687 
 8688 instruct cmovPL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, immP0 src) %{
 8689   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
 8690   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8691 
 8692   ins_cost(140);
 8693   format %{ "MOVW$cmp  $dst,$src" %}
 8694   ins_encode %{
 8695     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
 8696   %}
 8697   ins_pipe(ialu_imm);
 8698 %}
 8699 
 8700 instruct cmovFL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regF dst, regF src) %{
 8701   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
 8702   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8703   ins_cost(150);
 8704   size(4);
 8705   format %{ "FCPYS$cmp $dst,$src" %}
 8706   ins_encode %{
 8707     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8708   %}
 8709   ins_pipe(int_conditional_float_move);
 8710 %}
 8711 
 8712 instruct cmovFL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regF dst, regF src) %{
 8713   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
 8714   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8715   ins_cost(150);
 8716   size(4);
 8717   format %{ "FCPYS$cmp $dst,$src" %}
 8718   ins_encode %{
 8719     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8720   %}
 8721   ins_pipe(int_conditional_float_move);
 8722 %}
 8723 
 8724 instruct cmovFL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regF dst, regF src) %{
 8725   match(Set dst (CMoveF (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   ins_cost(150);
 8728   size(4);
 8729   format %{ "FCPYS$cmp $dst,$src" %}
 8730   ins_encode %{
 8731     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8732   %}
 8733   ins_pipe(int_conditional_float_move);
 8734 %}
 8735 
 8736 instruct cmovDL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regD dst, regD src) %{
 8737   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
 8738   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
 8739 
 8740   ins_cost(150);
 8741   size(4);
 8742   format %{ "FCPYD$cmp $dst,$src" %}
 8743   ins_encode %{
 8744     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8745   %}
 8746   ins_pipe(int_conditional_float_move);
 8747 %}
 8748 
 8749 instruct cmovDL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regD dst, regD src) %{
 8750   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
 8751   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
 8752 
 8753   ins_cost(150);
 8754   size(4);
 8755   format %{ "FCPYD$cmp $dst,$src" %}
 8756   ins_encode %{
 8757     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8758   %}
 8759   ins_pipe(int_conditional_float_move);
 8760 %}
 8761 
 8762 instruct cmovDL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regD dst, regD src) %{
 8763   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
 8764   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
 8765 
 8766   ins_cost(150);
 8767   size(4);
 8768   format %{ "FCPYD$cmp $dst,$src" %}
 8769   ins_encode %{
 8770     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
 8771   %}
 8772   ins_pipe(int_conditional_float_move);
 8773 %}
 8774 
 8775 // ============================================================================
 8776 // Safepoint Instruction
 8777 // rather than KILL R12, it would be better to use any reg as
 8778 // TEMP. Can't do that at this point because it crashes the compiler
 8779 instruct safePoint_poll(iRegP poll, R12RegI tmp, flagsReg icc) %{
 8780   match(SafePoint poll);
 8781   effect(USE poll, KILL tmp, KILL icc);
 8782 
 8783   size(4);
 8784   format %{ "LDR   $tmp,[$poll]\t! Safepoint: poll for GC" %}
 8785   ins_encode %{
 8786     __ relocate(relocInfo::poll_type);
 8787     __ ldr($tmp$$Register, Address($poll$$Register));
 8788   %}
 8789   ins_pipe(loadPollP);
 8790 %}
 8791 
 8792 
 8793 // ============================================================================
 8794 // Call Instructions
 8795 // Call Java Static Instruction
 8796 instruct CallStaticJavaDirect( method meth ) %{
 8797   match(CallStaticJava);
 8798   predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke());
 8799   effect(USE meth);
 8800 
 8801   ins_cost(CALL_COST);
 8802   format %{ "CALL,static ==> " %}
 8803   ins_encode( Java_Static_Call( meth ), call_epilog );
 8804   ins_pipe(simple_call);
 8805 %}
 8806 
 8807 // Call Java Static Instruction (method handle version)
 8808 instruct CallStaticJavaHandle( method meth ) %{
 8809   match(CallStaticJava);
 8810   predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke());
 8811   effect(USE meth);
 8812   // FP is saved by all callees (for interpreter stack correction).
 8813   // We use it here for a similar purpose, in {preserve,restore}_FP.
 8814 
 8815   ins_cost(CALL_COST);
 8816   format %{ "CALL,static/MethodHandle ==> " %}
 8817   ins_encode( preserve_SP, Java_Static_Call( meth ), restore_SP, call_epilog );
 8818   ins_pipe(simple_call);
 8819 %}
 8820 
 8821 // Call Java Dynamic Instruction
 8822 instruct CallDynamicJavaDirect( method meth ) %{
 8823   match(CallDynamicJava);
 8824   effect(USE meth);
 8825 
 8826   ins_cost(CALL_COST);
 8827   format %{ "MOV_OOP    (empty),R_R8\n\t"
 8828             "CALL,dynamic  ; NOP ==> " %}
 8829   ins_encode( Java_Dynamic_Call( meth ), call_epilog );
 8830   ins_pipe(call);
 8831 %}
 8832 
 8833 // Call Runtime Instruction
 8834 instruct CallRuntimeDirect(method meth) %{
 8835   match(CallRuntime);
 8836   effect(USE meth);
 8837   ins_cost(CALL_COST);
 8838   format %{ "CALL,runtime" %}
 8839   ins_encode( Java_To_Runtime( meth ),
 8840               call_epilog );
 8841   ins_pipe(simple_call);
 8842 %}
 8843 
 8844 // Call runtime without safepoint - same as CallRuntime
 8845 instruct CallLeafDirect(method meth) %{
 8846   match(CallLeaf);
 8847   effect(USE meth);
 8848   ins_cost(CALL_COST);
 8849   format %{ "CALL,runtime leaf" %}
 8850   // TODO: ned save_last_PC here?
 8851   ins_encode( Java_To_Runtime( meth ),
 8852               call_epilog );
 8853   ins_pipe(simple_call);
 8854 %}
 8855 
 8856 // Call runtime without safepoint - same as CallLeaf
 8857 instruct CallLeafNoFPDirect(method meth) %{
 8858   match(CallLeafNoFP);
 8859   effect(USE meth);
 8860   ins_cost(CALL_COST);
 8861   format %{ "CALL,runtime leaf nofp" %}
 8862   // TODO: ned save_last_PC here?
 8863   ins_encode( Java_To_Runtime( meth ),
 8864               call_epilog );
 8865   ins_pipe(simple_call);
 8866 %}
 8867 
 8868 // Tail Call; Jump from runtime stub to Java code.
 8869 // Also known as an 'interprocedural jump'.
 8870 // Target of jump will eventually return to caller.
 8871 // TailJump below removes the return address.
 8872 instruct TailCalljmpInd(IPRegP jump_target, inline_cache_regP method_ptr) %{
 8873   match(TailCall jump_target method_ptr);
 8874 
 8875   ins_cost(CALL_COST);
 8876   format %{ "MOV    Rexception_pc, LR\n\t"
 8877             "jump   $jump_target  \t! $method_ptr holds method" %}
 8878   ins_encode %{
 8879     __ mov(Rexception_pc, LR);   // this is used only to call
 8880                                  // StubRoutines::forward_exception_entry()
 8881                                  // which expects PC of exception in
 8882                                  // R5. FIXME?
 8883     __ jump($jump_target$$Register);
 8884   %}
 8885   ins_pipe(tail_call);
 8886 %}
 8887 
 8888 
 8889 // Return Instruction
 8890 instruct Ret() %{
 8891   match(Return);
 8892 
 8893   format %{ "ret LR" %}
 8894 
 8895   ins_encode %{
 8896     __ ret(LR);
 8897   %}
 8898 
 8899   ins_pipe(br);
 8900 %}
 8901 
 8902 
 8903 // Tail Jump; remove the return address; jump to target.
 8904 // TailCall above leaves the return address around.
 8905 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
 8906 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
 8907 // "restore" before this instruction (in Epilogue), we need to materialize it
 8908 // in %i0.
 8909 instruct tailjmpInd(IPRegP jump_target, RExceptionRegP ex_oop) %{
 8910   match( TailJump jump_target ex_oop );
 8911   ins_cost(CALL_COST);
 8912   format %{ "MOV    Rexception_pc, LR\n\t"
 8913             "jump   $jump_target \t! $ex_oop holds exc. oop" %}
 8914   ins_encode %{
 8915     __ mov(Rexception_pc, LR);
 8916     __ jump($jump_target$$Register);
 8917   %}
 8918   ins_pipe(tail_call);
 8919 %}
 8920 
 8921 // Create exception oop: created by stack-crawling runtime code.
 8922 // Created exception is now available to this handler, and is setup
 8923 // just prior to jumping to this handler.  No code emitted.
 8924 instruct CreateException( RExceptionRegP ex_oop )
 8925 %{
 8926   match(Set ex_oop (CreateEx));
 8927   ins_cost(0);
 8928 
 8929   size(0);
 8930   // use the following format syntax
 8931   format %{ "! exception oop is in Rexception_obj; no code emitted" %}
 8932   ins_encode();
 8933   ins_pipe(empty);
 8934 %}
 8935 
 8936 
 8937 // Rethrow exception:
 8938 // The exception oop will come in the first argument position.
 8939 // Then JUMP (not call) to the rethrow stub code.
 8940 instruct RethrowException()
 8941 %{
 8942   match(Rethrow);
 8943   ins_cost(CALL_COST);
 8944 
 8945   // use the following format syntax
 8946   format %{ "b    rethrow_stub" %}
 8947   ins_encode %{
 8948     Register scratch = R1_tmp;
 8949     assert_different_registers(scratch, c_rarg0, LR);
 8950     __ jump(OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type, scratch);
 8951   %}
 8952   ins_pipe(tail_call);
 8953 %}
 8954 
 8955 
 8956 // Die now
 8957 instruct ShouldNotReachHere( )
 8958 %{
 8959   match(Halt);
 8960   ins_cost(CALL_COST);
 8961 
 8962   // Use the following format syntax
 8963   format %{ "ShouldNotReachHere" %}
 8964   ins_encode %{
 8965     if (is_reachable()) {
 8966       __ stop(_halt_reason);
 8967     }
 8968   %}
 8969   ins_pipe(tail_call);
 8970 %}
 8971 
 8972 // ============================================================================
 8973 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
 8974 // array for an instance of the superklass.  Set a hidden internal cache on a
 8975 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
 8976 // not zero for a miss or zero for a hit.  The encoding ALSO sets flags.
 8977 instruct partialSubtypeCheck( R0RegP index, R1RegP sub, R2RegP super, flagsRegP pcc, LRRegP lr ) %{
 8978   match(Set index (PartialSubtypeCheck sub super));
 8979   effect( KILL pcc, KILL lr );
 8980   ins_cost(DEFAULT_COST*10);
 8981   format %{ "CALL   PartialSubtypeCheck" %}
 8982   ins_encode %{
 8983     __ call(StubRoutines::Arm::partial_subtype_check(), relocInfo::runtime_call_type);
 8984   %}
 8985   ins_pipe(partial_subtype_check_pipe);
 8986 %}
 8987 
 8988 /* instruct partialSubtypeCheck_vs_zero( flagsRegP pcc, o1RegP sub, o2RegP super, immP0 zero, o0RegP idx, o7RegP o7 ) %{ */
 8989 /*   match(Set pcc (CmpP (PartialSubtypeCheck sub super) zero)); */
 8990 /*   ins_pipe(partial_subtype_check_pipe); */
 8991 /* %} */
 8992 
 8993 
 8994 // ============================================================================
 8995 // inlined locking and unlocking
 8996 
 8997 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch )
 8998 %{
 8999   match(Set pcc (FastLock object box));
 9000   predicate(!(UseBiasedLocking && !UseOptoBiasInlining));
 9001 
 9002   effect(TEMP scratch, TEMP scratch2);
 9003   ins_cost(DEFAULT_COST*3);
 9004 
 9005   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2" %}
 9006   ins_encode %{
 9007     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
 9008   %}
 9009   ins_pipe(long_memory_op);
 9010 %}
 9011 
 9012 instruct cmpFastLock_noBiasInline(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2,
 9013                                   iRegP scratch, iRegP scratch3) %{
 9014   match(Set pcc (FastLock object box));
 9015   predicate(UseBiasedLocking && !UseOptoBiasInlining);
 9016 
 9017   effect(TEMP scratch, TEMP scratch2, TEMP scratch3);
 9018   ins_cost(DEFAULT_COST*5);
 9019 
 9020   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2, $scratch3" %}
 9021   ins_encode %{
 9022     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register, $scratch3$$Register);
 9023   %}
 9024   ins_pipe(long_memory_op);
 9025 %}
 9026 
 9027 
 9028 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch ) %{
 9029   match(Set pcc (FastUnlock object box));
 9030   effect(TEMP scratch, TEMP scratch2);
 9031   ins_cost(100);
 9032 
 9033   format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2" %}
 9034   ins_encode %{
 9035     __ fast_unlock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
 9036   %}
 9037   ins_pipe(long_memory_op);
 9038 %}
 9039 
 9040 // Count and Base registers are fixed because the allocator cannot
 9041 // kill unknown registers.  The encodings are generic.
 9042 instruct clear_array(iRegX cnt, iRegP base, iRegI temp, iRegX zero, Universe dummy, flagsReg cpsr) %{
 9043   match(Set dummy (ClearArray cnt base));
 9044   effect(TEMP temp, TEMP zero, KILL cpsr);
 9045   ins_cost(300);
 9046   format %{ "MOV    $zero,0\n"
 9047       "        MOV    $temp,$cnt\n"
 9048       "loop:   SUBS   $temp,$temp,4\t! Count down a dword of bytes\n"
 9049       "        STR.ge $zero,[$base+$temp]\t! delay slot"
 9050       "        B.gt   loop\t\t! Clearing loop\n" %}
 9051   ins_encode %{
 9052     __ mov($zero$$Register, 0);
 9053     __ mov($temp$$Register, $cnt$$Register);
 9054     Label(loop);
 9055     __ bind(loop);
 9056     __ subs($temp$$Register, $temp$$Register, 4);
 9057     __ str($zero$$Register, Address($base$$Register, $temp$$Register), ge);
 9058     __ b(loop, gt);
 9059   %}
 9060   ins_pipe(long_memory_op);
 9061 %}
 9062 
 9063 #ifdef XXX
 9064 // FIXME: Why R0/R1/R2/R3?
 9065 instruct string_compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result,
 9066                         iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
 9067   predicate(!CompactStrings);
 9068   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
 9069   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, TEMP tmp1, TEMP tmp2);
 9070   ins_cost(300);
 9071   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // TEMP $tmp1, $tmp2" %}
 9072   ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result, tmp1, tmp2) );
 9073 
 9074   ins_pipe(long_memory_op);
 9075 %}
 9076 
 9077 // FIXME: Why R0/R1/R2?
 9078 instruct string_equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2,
 9079                        flagsReg ccr) %{
 9080   predicate(!CompactStrings);
 9081   match(Set result (StrEquals (Binary str1 str2) cnt));
 9082   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp1, TEMP tmp2, TEMP result, KILL ccr);
 9083 
 9084   ins_cost(300);
 9085   format %{ "String Equals $str1,$str2,$cnt -> $result   // TEMP $tmp1, $tmp2" %}
 9086   ins_encode( enc_String_Equals(str1, str2, cnt, result, tmp1, tmp2) );
 9087   ins_pipe(long_memory_op);
 9088 %}
 9089 
 9090 // FIXME: Why R0/R1?
 9091 instruct array_equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result,
 9092                       flagsReg ccr) %{
 9093   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
 9094   match(Set result (AryEq ary1 ary2));
 9095   effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP result, KILL ccr);
 9096 
 9097   ins_cost(300);
 9098   format %{ "Array Equals $ary1,$ary2 -> $result   // TEMP $tmp1,$tmp2,$tmp3" %}
 9099   ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, result));
 9100   ins_pipe(long_memory_op);
 9101 %}
 9102 #endif
 9103 
 9104 //---------- Zeros Count Instructions ------------------------------------------
 9105 
 9106 instruct countLeadingZerosI(iRegI dst, iRegI src) %{
 9107   match(Set dst (CountLeadingZerosI src));
 9108   size(4);
 9109   format %{ "CLZ_32 $dst,$src" %}
 9110   ins_encode %{
 9111     __ clz_32($dst$$Register, $src$$Register);
 9112   %}
 9113   ins_pipe(ialu_reg);
 9114 %}
 9115 
 9116 instruct countLeadingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
 9117   match(Set dst (CountLeadingZerosL src));
 9118   effect(TEMP tmp, TEMP dst, KILL ccr);
 9119   size(16);
 9120   format %{ "CLZ    $dst,$src.hi\n\t"
 9121             "TEQ    $dst,32\n\t"
 9122             "CLZ.eq $tmp,$src.lo\n\t"
 9123             "ADD.eq $dst, $dst, $tmp\n\t" %}
 9124   ins_encode %{
 9125     __ clz($dst$$Register, $src$$Register->successor());
 9126     __ teq($dst$$Register, 32);
 9127     __ clz($tmp$$Register, $src$$Register, eq);
 9128     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
 9129   %}
 9130   ins_pipe(ialu_reg);
 9131 %}
 9132 
 9133 instruct countTrailingZerosI(iRegI dst, iRegI src, iRegI tmp) %{
 9134   match(Set dst (CountTrailingZerosI src));
 9135   effect(TEMP tmp);
 9136   size(8);
 9137   format %{ "RBIT_32 $tmp, $src\n\t"
 9138             "CLZ_32  $dst,$tmp" %}
 9139   ins_encode %{
 9140     __ rbit_32($tmp$$Register, $src$$Register);
 9141     __ clz_32($dst$$Register, $tmp$$Register);
 9142   %}
 9143   ins_pipe(ialu_reg);
 9144 %}
 9145 
 9146 instruct countTrailingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
 9147   match(Set dst (CountTrailingZerosL src));
 9148   effect(TEMP tmp, TEMP dst, KILL ccr);
 9149   size(24);
 9150   format %{ "RBIT   $tmp,$src.lo\n\t"
 9151             "CLZ    $dst,$tmp\n\t"
 9152             "TEQ    $dst,32\n\t"
 9153             "RBIT   $tmp,$src.hi\n\t"
 9154             "CLZ.eq $tmp,$tmp\n\t"
 9155             "ADD.eq $dst,$dst,$tmp\n\t" %}
 9156   ins_encode %{
 9157     __ rbit($tmp$$Register, $src$$Register);
 9158     __ clz($dst$$Register, $tmp$$Register);
 9159     __ teq($dst$$Register, 32);
 9160     __ rbit($tmp$$Register, $src$$Register->successor());
 9161     __ clz($tmp$$Register, $tmp$$Register, eq);
 9162     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
 9163   %}
 9164   ins_pipe(ialu_reg);
 9165 %}
 9166 
 9167 
 9168 //---------- Population Count Instructions -------------------------------------
 9169 
 9170 instruct popCountI(iRegI dst, iRegI src, regD_low tmp) %{
 9171   predicate(UsePopCountInstruction);
 9172   match(Set dst (PopCountI src));
 9173   effect(TEMP tmp);
 9174 
 9175   format %{ "FMSR       $tmp,$src\n\t"
 9176             "VCNT.8     $tmp,$tmp\n\t"
 9177             "VPADDL.U8  $tmp,$tmp\n\t"
 9178             "VPADDL.U16 $tmp,$tmp\n\t"
 9179             "FMRS       $dst,$tmp" %}
 9180   size(20);
 9181 
 9182   ins_encode %{
 9183     __ fmsr($tmp$$FloatRegister, $src$$Register);
 9184     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
 9185     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
 9186     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
 9187     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 9188   %}
 9189   ins_pipe(ialu_reg); // FIXME
 9190 %}
 9191 
 9192 // Note: Long.bitCount(long) returns an int.
 9193 instruct popCountL(iRegI dst, iRegL src, regD_low tmp) %{
 9194   predicate(UsePopCountInstruction);
 9195   match(Set dst (PopCountL src));
 9196   effect(TEMP tmp);
 9197 
 9198   format %{ "FMDRR       $tmp,$src.lo,$src.hi\n\t"
 9199             "VCNT.8      $tmp,$tmp\n\t"
 9200             "VPADDL.U8   $tmp,$tmp\n\t"
 9201             "VPADDL.U16  $tmp,$tmp\n\t"
 9202             "VPADDL.U32  $tmp,$tmp\n\t"
 9203             "FMRS        $dst,$tmp" %}
 9204 
 9205   size(32);
 9206 
 9207   ins_encode %{
 9208     __ fmdrr($tmp$$FloatRegister, $src$$Register, $src$$Register->successor());
 9209     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
 9210     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
 9211     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
 9212     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 32, 0);
 9213     __ fmrs($dst$$Register, $tmp$$FloatRegister);
 9214   %}
 9215   ins_pipe(ialu_reg);
 9216 %}
 9217 
 9218 
 9219 // ============================================================================
 9220 //------------Bytes reverse--------------------------------------------------
 9221 
 9222 instruct bytes_reverse_int(iRegI dst, iRegI src) %{
 9223   match(Set dst (ReverseBytesI src));
 9224 
 9225   size(4);
 9226   format %{ "REV32 $dst,$src" %}
 9227   ins_encode %{
 9228     __ rev($dst$$Register, $src$$Register);
 9229   %}
 9230   ins_pipe( iload_mem ); // FIXME
 9231 %}
 9232 
 9233 instruct bytes_reverse_long(iRegL dst, iRegL src) %{
 9234   match(Set dst (ReverseBytesL src));
 9235   effect(TEMP dst);
 9236   size(8);
 9237   format %{ "REV $dst.lo,$src.lo\n\t"
 9238             "REV $dst.hi,$src.hi" %}
 9239   ins_encode %{
 9240     __ rev($dst$$Register, $src$$Register->successor());
 9241     __ rev($dst$$Register->successor(), $src$$Register);
 9242   %}
 9243   ins_pipe( iload_mem ); // FIXME
 9244 %}
 9245 
 9246 instruct bytes_reverse_unsigned_short(iRegI dst, iRegI src) %{
 9247   match(Set dst (ReverseBytesUS src));
 9248   size(4);
 9249   format %{ "REV16 $dst,$src" %}
 9250   ins_encode %{
 9251     __ rev16($dst$$Register, $src$$Register);
 9252   %}
 9253   ins_pipe( iload_mem ); // FIXME
 9254 %}
 9255 
 9256 instruct bytes_reverse_short(iRegI dst, iRegI src) %{
 9257   match(Set dst (ReverseBytesS src));
 9258   size(4);
 9259   format %{ "REVSH $dst,$src" %}
 9260   ins_encode %{
 9261     __ revsh($dst$$Register, $src$$Register);
 9262   %}
 9263   ins_pipe( iload_mem ); // FIXME
 9264 %}
 9265 
 9266 
 9267 // ====================VECTOR INSTRUCTIONS=====================================
 9268 
 9269 // Load Aligned Packed values into a Double Register
 9270 instruct loadV8(vecD dst, memoryD mem) %{
 9271   predicate(n->as_LoadVector()->memory_size() == 8);
 9272   match(Set dst (LoadVector mem));
 9273   ins_cost(MEMORY_REF_COST);
 9274   size(4);
 9275   format %{ "FLDD   $mem,$dst\t! load vector (8 bytes)" %}
 9276   ins_encode %{
 9277     __ ldr_double($dst$$FloatRegister, $mem$$Address);
 9278   %}
 9279   ins_pipe(floadD_mem);
 9280 %}
 9281 
 9282 // Load Aligned Packed values into a Double Register Pair
 9283 instruct loadV16(vecX dst, memoryvld mem) %{
 9284   predicate(n->as_LoadVector()->memory_size() == 16);
 9285   match(Set dst (LoadVector mem));
 9286   ins_cost(MEMORY_REF_COST);
 9287   size(4);
 9288   format %{ "VLD1   $mem,$dst.Q\t! load vector (16 bytes)" %}
 9289   ins_encode %{
 9290     __ vld1($dst$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
 9291   %}
 9292   ins_pipe(floadD_mem); // FIXME
 9293 %}
 9294 
 9295 // Store Vector in Double register to memory
 9296 instruct storeV8(memoryD mem, vecD src) %{
 9297   predicate(n->as_StoreVector()->memory_size() == 8);
 9298   match(Set mem (StoreVector mem src));
 9299   ins_cost(MEMORY_REF_COST);
 9300   size(4);
 9301   format %{ "FSTD   $src,$mem\t! store vector (8 bytes)" %}
 9302   ins_encode %{
 9303     __ str_double($src$$FloatRegister, $mem$$Address);
 9304   %}
 9305   ins_pipe(fstoreD_mem_reg);
 9306 %}
 9307 
 9308 // Store Vector in Double Register Pair to memory
 9309 instruct storeV16(memoryvld mem, vecX src) %{
 9310   predicate(n->as_StoreVector()->memory_size() == 16);
 9311   match(Set mem (StoreVector mem src));
 9312   ins_cost(MEMORY_REF_COST);
 9313   size(4);
 9314   format %{ "VST1   $src,$mem\t! store vector (16 bytes)" %}
 9315   ins_encode %{
 9316     __ vst1($src$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
 9317   %}
 9318   ins_pipe(fstoreD_mem_reg); // FIXME
 9319 %}
 9320 
 9321 // Replicate scalar to packed byte values in Double register
 9322 instruct Repl8B_reg(vecD dst, iRegI src, iRegI tmp) %{
 9323   predicate(n->as_Vector()->length() == 8);
 9324   match(Set dst (ReplicateB src));
 9325   ins_cost(DEFAULT_COST*4);
 9326   effect(TEMP tmp);
 9327   size(16);
 9328 
 9329   // FIXME: could use PKH instruction instead?
 9330   format %{ "LSL      $tmp, $src, 24 \n\t"
 9331             "OR       $tmp, $tmp, ($tmp >> 8) \n\t"
 9332             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
 9333             "FMDRR    $dst,$tmp,$tmp\t" %}
 9334   ins_encode %{
 9335     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 24));
 9336     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 8));
 9337     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
 9338     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 9339   %}
 9340   ins_pipe(ialu_reg); // FIXME
 9341 %}
 9342 
 9343 // Replicate scalar to packed byte values in Double register
 9344 instruct Repl8B_reg_simd(vecD dst, iRegI src) %{
 9345   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9346   match(Set dst (ReplicateB src));
 9347   size(4);
 9348 
 9349   format %{ "VDUP.8 $dst,$src\t" %}
 9350   ins_encode %{
 9351     bool quad = false;
 9352     __ vdupI($dst$$FloatRegister, $src$$Register,
 9353              MacroAssembler::VELEM_SIZE_8, quad);
 9354   %}
 9355   ins_pipe(ialu_reg); // FIXME
 9356 %}
 9357 
 9358 // Replicate scalar to packed byte values in Double register pair
 9359 instruct Repl16B_reg(vecX dst, iRegI src) %{
 9360   predicate(n->as_Vector()->length_in_bytes() == 16);
 9361   match(Set dst (ReplicateB src));
 9362   size(4);
 9363 
 9364   format %{ "VDUP.8 $dst.Q,$src\t" %}
 9365   ins_encode %{
 9366     bool quad = true;
 9367     __ vdupI($dst$$FloatRegister, $src$$Register,
 9368              MacroAssembler::VELEM_SIZE_8, quad);
 9369   %}
 9370   ins_pipe(ialu_reg); // FIXME
 9371 %}
 9372 
 9373 // Replicate scalar constant to packed byte values in Double register
 9374 instruct Repl8B_immI(vecD dst, immI src, iRegI tmp) %{
 9375   predicate(n->as_Vector()->length() == 8);
 9376   match(Set dst (ReplicateB src));
 9377   ins_cost(DEFAULT_COST*2);
 9378   effect(TEMP tmp);
 9379   size(12);
 9380 
 9381   format %{ "MOV      $tmp, Repl4($src))\n\t"
 9382             "FMDRR    $dst,$tmp,$tmp\t" %}
 9383   ins_encode( LdReplImmI(src, dst, tmp, (4), (1)) );
 9384   ins_pipe(loadConFD); // FIXME
 9385 %}
 9386 
 9387 // Replicate scalar constant to packed byte values in Double register
 9388 // TODO: support negative constants with MVNI?
 9389 instruct Repl8B_immU8(vecD dst, immU8 src) %{
 9390   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9391   match(Set dst (ReplicateB src));
 9392   size(4);
 9393 
 9394   format %{ "VMOV.U8  $dst,$src" %}
 9395   ins_encode %{
 9396     bool quad = false;
 9397     __ vmovI($dst$$FloatRegister, $src$$constant,
 9398              MacroAssembler::VELEM_SIZE_8, quad);
 9399   %}
 9400   ins_pipe(loadConFD); // FIXME
 9401 %}
 9402 
 9403 // Replicate scalar constant to packed byte values in Double register pair
 9404 instruct Repl16B_immU8(vecX dst, immU8 src) %{
 9405   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
 9406   match(Set dst (ReplicateB src));
 9407   size(4);
 9408 
 9409   format %{ "VMOV.U8  $dst.Q,$src" %}
 9410   ins_encode %{
 9411     bool quad = true;
 9412     __ vmovI($dst$$FloatRegister, $src$$constant,
 9413              MacroAssembler::VELEM_SIZE_8, quad);
 9414   %}
 9415   ins_pipe(loadConFD); // FIXME
 9416 %}
 9417 
 9418 // Replicate scalar to packed short/char values into Double register
 9419 instruct Repl4S_reg(vecD dst, iRegI src, iRegI tmp) %{
 9420   predicate(n->as_Vector()->length() == 4);
 9421   match(Set dst (ReplicateS src));
 9422   ins_cost(DEFAULT_COST*3);
 9423   effect(TEMP tmp);
 9424   size(12);
 9425 
 9426   // FIXME: could use PKH instruction instead?
 9427   format %{ "LSL      $tmp, $src, 16 \n\t"
 9428             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
 9429             "FMDRR    $dst,$tmp,$tmp\t" %}
 9430   ins_encode %{
 9431     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 16));
 9432     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
 9433     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 9434   %}
 9435   ins_pipe(ialu_reg); // FIXME
 9436 %}
 9437 
 9438 // Replicate scalar to packed byte values in Double register
 9439 instruct Repl4S_reg_simd(vecD dst, iRegI src) %{
 9440   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9441   match(Set dst (ReplicateS src));
 9442   size(4);
 9443 
 9444   format %{ "VDUP.16 $dst,$src\t" %}
 9445   ins_encode %{
 9446     bool quad = false;
 9447     __ vdupI($dst$$FloatRegister, $src$$Register,
 9448              MacroAssembler::VELEM_SIZE_16, quad);
 9449   %}
 9450   ins_pipe(ialu_reg); // FIXME
 9451 %}
 9452 
 9453 // Replicate scalar to packed byte values in Double register pair
 9454 instruct Repl8S_reg(vecX dst, iRegI src) %{
 9455   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
 9456   match(Set dst (ReplicateS src));
 9457   size(4);
 9458 
 9459   format %{ "VDUP.16 $dst.Q,$src\t" %}
 9460   ins_encode %{
 9461     bool quad = true;
 9462     __ vdupI($dst$$FloatRegister, $src$$Register,
 9463              MacroAssembler::VELEM_SIZE_16, quad);
 9464   %}
 9465   ins_pipe(ialu_reg); // FIXME
 9466 %}
 9467 
 9468 
 9469 // Replicate scalar constant to packed short/char values in Double register
 9470 instruct Repl4S_immI(vecD dst, immI src, iRegP tmp) %{
 9471   predicate(n->as_Vector()->length() == 4);
 9472   match(Set dst (ReplicateS src));
 9473   effect(TEMP tmp);
 9474   size(12);
 9475   ins_cost(DEFAULT_COST*4); // FIXME
 9476 
 9477   format %{ "MOV      $tmp, Repl2($src))\n\t"
 9478             "FMDRR    $dst,$tmp,$tmp\t" %}
 9479   ins_encode( LdReplImmI(src, dst, tmp, (2), (2)) );
 9480   ins_pipe(loadConFD); // FIXME
 9481 %}
 9482 
 9483 // Replicate scalar constant to packed byte values in Double register
 9484 instruct Repl4S_immU8(vecD dst, immU8 src) %{
 9485   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9486   match(Set dst (ReplicateS src));
 9487   size(4);
 9488 
 9489   format %{ "VMOV.U16  $dst,$src" %}
 9490   ins_encode %{
 9491     bool quad = false;
 9492     __ vmovI($dst$$FloatRegister, $src$$constant,
 9493              MacroAssembler::VELEM_SIZE_16, quad);
 9494   %}
 9495   ins_pipe(loadConFD); // FIXME
 9496 %}
 9497 
 9498 // Replicate scalar constant to packed byte values in Double register pair
 9499 instruct Repl8S_immU8(vecX dst, immU8 src) %{
 9500   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
 9501   match(Set dst (ReplicateS src));
 9502   size(4);
 9503 
 9504   format %{ "VMOV.U16  $dst.Q,$src" %}
 9505   ins_encode %{
 9506     bool quad = true;
 9507     __ vmovI($dst$$FloatRegister, $src$$constant,
 9508              MacroAssembler::VELEM_SIZE_16, quad);
 9509   %}
 9510   ins_pipe(loadConFD); // FIXME
 9511 %}
 9512 
 9513 // Replicate scalar to packed int values in Double register
 9514 instruct Repl2I_reg(vecD dst, iRegI src) %{
 9515   predicate(n->as_Vector()->length() == 2);
 9516   match(Set dst (ReplicateI src));
 9517   size(4);
 9518 
 9519   format %{ "FMDRR    $dst,$src,$src\t" %}
 9520   ins_encode %{
 9521     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
 9522   %}
 9523   ins_pipe(ialu_reg); // FIXME
 9524 %}
 9525 
 9526 // Replicate scalar to packed int values in Double register pair
 9527 instruct Repl4I_reg(vecX dst, iRegI src) %{
 9528   predicate(n->as_Vector()->length() == 4);
 9529   match(Set dst (ReplicateI src));
 9530   ins_cost(DEFAULT_COST*2);
 9531   size(8);
 9532 
 9533   format %{ "FMDRR    $dst.lo,$src,$src\n\t"
 9534             "FMDRR    $dst.hi,$src,$src" %}
 9535 
 9536   ins_encode %{
 9537     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
 9538     __ fmdrr($dst$$FloatRegister->successor()->successor(),
 9539              $src$$Register, $src$$Register);
 9540   %}
 9541   ins_pipe(ialu_reg); // FIXME
 9542 %}
 9543 
 9544 // Replicate scalar to packed int values in Double register
 9545 instruct Repl2I_reg_simd(vecD dst, iRegI src) %{
 9546   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9547   match(Set dst (ReplicateI src));
 9548   size(4);
 9549 
 9550   format %{ "VDUP.32 $dst.D,$src\t" %}
 9551   ins_encode %{
 9552     bool quad = false;
 9553     __ vdupI($dst$$FloatRegister, $src$$Register,
 9554              MacroAssembler::VELEM_SIZE_32, quad);
 9555   %}
 9556   ins_pipe(ialu_reg); // FIXME
 9557 %}
 9558 
 9559 // Replicate scalar to packed int values in Double register pair
 9560 instruct Repl4I_reg_simd(vecX dst, iRegI src) %{
 9561   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
 9562   match(Set dst (ReplicateI src));
 9563   size(4);
 9564 
 9565   format %{ "VDUP.32 $dst.Q,$src\t" %}
 9566   ins_encode %{
 9567     bool quad = true;
 9568     __ vdupI($dst$$FloatRegister, $src$$Register,
 9569              MacroAssembler::VELEM_SIZE_32, quad);
 9570   %}
 9571   ins_pipe(ialu_reg); // FIXME
 9572 %}
 9573 
 9574 
 9575 // Replicate scalar zero constant to packed int values in Double register
 9576 instruct Repl2I_immI(vecD dst, immI src, iRegI tmp) %{
 9577   predicate(n->as_Vector()->length() == 2);
 9578   match(Set dst (ReplicateI src));
 9579   effect(TEMP tmp);
 9580   size(12);
 9581   ins_cost(DEFAULT_COST*4); // FIXME
 9582 
 9583   format %{ "MOV      $tmp, Repl1($src))\n\t"
 9584             "FMDRR    $dst,$tmp,$tmp\t" %}
 9585   ins_encode( LdReplImmI(src, dst, tmp, (1), (4)) );
 9586   ins_pipe(loadConFD); // FIXME
 9587 %}
 9588 
 9589 // Replicate scalar constant to packed byte values in Double register
 9590 instruct Repl2I_immU8(vecD dst, immU8 src) %{
 9591   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9592   match(Set dst (ReplicateI src));
 9593   size(4);
 9594 
 9595   format %{ "VMOV.I32  $dst.D,$src" %}
 9596   ins_encode %{
 9597     bool quad = false;
 9598     __ vmovI($dst$$FloatRegister, $src$$constant,
 9599              MacroAssembler::VELEM_SIZE_32, quad);
 9600   %}
 9601   ins_pipe(loadConFD); // FIXME
 9602 %}
 9603 
 9604 // Replicate scalar constant to packed byte values in Double register pair
 9605 instruct Repl4I_immU8(vecX dst, immU8 src) %{
 9606   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
 9607   match(Set dst (ReplicateI src));
 9608   size(4);
 9609 
 9610   format %{ "VMOV.I32  $dst.Q,$src" %}
 9611   ins_encode %{
 9612     bool quad = true;
 9613     __ vmovI($dst$$FloatRegister, $src$$constant,
 9614              MacroAssembler::VELEM_SIZE_32, quad);
 9615   %}
 9616   ins_pipe(loadConFD); // FIXME
 9617 %}
 9618 
 9619 // Replicate scalar to packed byte values in Double register pair
 9620 instruct Repl2L_reg(vecX dst, iRegL src) %{
 9621   predicate(n->as_Vector()->length() == 2);
 9622   match(Set dst (ReplicateL src));
 9623   size(8);
 9624   ins_cost(DEFAULT_COST*2); // FIXME
 9625 
 9626   format %{ "FMDRR $dst.D,$src.lo,$src.hi\t\n"
 9627             "FMDRR $dst.D.next,$src.lo,$src.hi" %}
 9628   ins_encode %{
 9629     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
 9630     __ fmdrr($dst$$FloatRegister->successor()->successor(),
 9631              $src$$Register, $src$$Register->successor());
 9632   %}
 9633   ins_pipe(ialu_reg); // FIXME
 9634 %}
 9635 
 9636 
 9637 // Replicate scalar to packed float values in Double register
 9638 instruct Repl2F_regI(vecD dst, iRegI src) %{
 9639   predicate(n->as_Vector()->length() == 2);
 9640   match(Set dst (ReplicateF src));
 9641   size(4);
 9642 
 9643   format %{ "FMDRR    $dst.D,$src,$src\t" %}
 9644   ins_encode %{
 9645     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
 9646   %}
 9647   ins_pipe(ialu_reg); // FIXME
 9648 %}
 9649 
 9650 // Replicate scalar to packed float values in Double register
 9651 instruct Repl2F_reg_vfp(vecD dst, regF src) %{
 9652   predicate(n->as_Vector()->length() == 2);
 9653   match(Set dst (ReplicateF src));
 9654   size(4*2);
 9655   ins_cost(DEFAULT_COST*2); // FIXME
 9656 
 9657   expand %{
 9658     iRegI tmp;
 9659     MoveF2I_reg_reg(tmp, src);
 9660     Repl2F_regI(dst,tmp);
 9661   %}
 9662 %}
 9663 
 9664 // Replicate scalar to packed float values in Double register
 9665 instruct Repl2F_reg_simd(vecD dst, regF src) %{
 9666   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
 9667   match(Set dst (ReplicateF src));
 9668   size(4);
 9669   ins_cost(DEFAULT_COST); // FIXME
 9670 
 9671   format %{ "VDUP.32  $dst.D,$src.D\t" %}
 9672   ins_encode %{
 9673     bool quad = false;
 9674     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
 9675   %}
 9676   ins_pipe(ialu_reg); // FIXME
 9677 %}
 9678 
 9679 // Replicate scalar to packed float values in Double register pair
 9680 instruct Repl4F_reg(vecX dst, regF src, iRegI tmp) %{
 9681   predicate(n->as_Vector()->length() == 4);
 9682   match(Set dst (ReplicateF src));
 9683   effect(TEMP tmp);
 9684   size(4*3);
 9685   ins_cost(DEFAULT_COST*3); // FIXME
 9686 
 9687   format %{ "FMRS     $tmp,$src\n\t"
 9688             "FMDRR    $dst.D,$tmp,$tmp\n\t"
 9689             "FMDRR    $dst.D.next,$tmp,$tmp\t" %}
 9690   ins_encode %{
 9691     __ fmrs($tmp$$Register, $src$$FloatRegister);
 9692     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
 9693     __ fmdrr($dst$$FloatRegister->successor()->successor(),
 9694              $tmp$$Register, $tmp$$Register);
 9695   %}
 9696   ins_pipe(ialu_reg); // FIXME
 9697 %}
 9698 
 9699 // Replicate scalar to packed float values in Double register pair
 9700 instruct Repl4F_reg_simd(vecX dst, regF src) %{
 9701   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
 9702   match(Set dst (ReplicateF src));
 9703   size(4);
 9704   ins_cost(DEFAULT_COST); // FIXME
 9705 
 9706   format %{ "VDUP.32  $dst.Q,$src.D\t" %}
 9707   ins_encode %{
 9708     bool quad = true;
 9709     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
 9710   %}
 9711   ins_pipe(ialu_reg); // FIXME
 9712 %}
 9713 
 9714 // Replicate scalar zero constant to packed float values in Double register
 9715 instruct Repl2F_immI(vecD dst, immF src, iRegI tmp) %{
 9716   predicate(n->as_Vector()->length() == 2);
 9717   match(Set dst (ReplicateF src));
 9718   effect(TEMP tmp);
 9719   size(12);
 9720   ins_cost(DEFAULT_COST*4); // FIXME
 9721 
 9722   format %{ "MOV      $tmp, Repl1($src))\n\t"
 9723             "FMDRR    $dst,$tmp,$tmp\t" %}
 9724   ins_encode( LdReplImmF(src, dst, tmp) );
 9725   ins_pipe(loadConFD); // FIXME
 9726 %}
 9727 
 9728 // Replicate scalar to packed double float values in Double register pair
 9729 instruct Repl2D_reg(vecX dst, regD src) %{
 9730   predicate(n->as_Vector()->length() == 2);
 9731   match(Set dst (ReplicateD src));
 9732   size(4*2);
 9733   ins_cost(DEFAULT_COST*2); // FIXME
 9734 
 9735   format %{ "FCPYD    $dst.D.a,$src\n\t"
 9736             "FCPYD    $dst.D.b,$src\t" %}
 9737   ins_encode %{
 9738     FloatRegister dsta = $dst$$FloatRegister;
 9739     FloatRegister src = $src$$FloatRegister;
 9740     __ fcpyd(dsta, src);
 9741     FloatRegister dstb = dsta->successor()->successor();
 9742     __ fcpyd(dstb, src);
 9743   %}
 9744   ins_pipe(ialu_reg); // FIXME
 9745 %}
 9746 
 9747 // ====================VECTOR ARITHMETIC=======================================
 9748 
 9749 // --------------------------------- ADD --------------------------------------
 9750 
 9751 // Bytes vector add
 9752 instruct vadd8B_reg(vecD dst, vecD src1, vecD src2) %{
 9753   predicate(n->as_Vector()->length() == 8);
 9754   match(Set dst (AddVB src1 src2));
 9755   format %{ "VADD.I8 $dst,$src1,$src2\t! add packed8B" %}
 9756   size(4);
 9757   ins_encode %{
 9758     bool quad = false;
 9759     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9760              MacroAssembler::VELEM_SIZE_8, quad);
 9761   %}
 9762   ins_pipe( ialu_reg_reg ); // FIXME
 9763 %}
 9764 
 9765 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
 9766   predicate(n->as_Vector()->length() == 16);
 9767   match(Set dst (AddVB src1 src2));
 9768   size(4);
 9769   format %{ "VADD.I8 $dst.Q,$src1.Q,$src2.Q\t! add packed16B" %}
 9770   ins_encode %{
 9771     bool quad = true;
 9772     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9773              MacroAssembler::VELEM_SIZE_8, quad);
 9774   %}
 9775   ins_pipe( ialu_reg_reg ); // FIXME
 9776 %}
 9777 
 9778 // Shorts/Chars vector add
 9779 instruct vadd4S_reg(vecD dst, vecD src1, vecD src2) %{
 9780   predicate(n->as_Vector()->length() == 4);
 9781   match(Set dst (AddVS src1 src2));
 9782   size(4);
 9783   format %{ "VADD.I16 $dst,$src1,$src2\t! add packed4S" %}
 9784   ins_encode %{
 9785     bool quad = false;
 9786     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9787              MacroAssembler::VELEM_SIZE_16, quad);
 9788   %}
 9789   ins_pipe( ialu_reg_reg ); // FIXME
 9790 %}
 9791 
 9792 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
 9793   predicate(n->as_Vector()->length() == 8);
 9794   match(Set dst (AddVS src1 src2));
 9795   size(4);
 9796   format %{ "VADD.I16 $dst.Q,$src1.Q,$src2.Q\t! add packed8S" %}
 9797   ins_encode %{
 9798     bool quad = true;
 9799     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9800              MacroAssembler::VELEM_SIZE_16, quad);
 9801   %}
 9802   ins_pipe( ialu_reg_reg ); // FIXME
 9803 %}
 9804 
 9805 // Integers vector add
 9806 instruct vadd2I_reg(vecD dst, vecD src1, vecD src2) %{
 9807   predicate(n->as_Vector()->length() == 2);
 9808   match(Set dst (AddVI src1 src2));
 9809   size(4);
 9810   format %{ "VADD.I32 $dst.D,$src1.D,$src2.D\t! add packed2I" %}
 9811   ins_encode %{
 9812     bool quad = false;
 9813     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9814              MacroAssembler::VELEM_SIZE_32, quad);
 9815   %}
 9816   ins_pipe( ialu_reg_reg ); // FIXME
 9817 %}
 9818 
 9819 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
 9820   predicate(n->as_Vector()->length() == 4);
 9821   match(Set dst (AddVI src1 src2));
 9822   size(4);
 9823   format %{ "VADD.I32 $dst.Q,$src1.Q,$src2.Q\t! add packed4I" %}
 9824   ins_encode %{
 9825     bool quad = true;
 9826     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9827              MacroAssembler::VELEM_SIZE_32, quad);
 9828   %}
 9829   ins_pipe( ialu_reg_reg ); // FIXME
 9830 %}
 9831 
 9832 // Longs vector add
 9833 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
 9834   predicate(n->as_Vector()->length() == 2);
 9835   match(Set dst (AddVL src1 src2));
 9836   size(4);
 9837   format %{ "VADD.I64 $dst.Q,$src1.Q,$src2.Q\t! add packed2L" %}
 9838   ins_encode %{
 9839     bool quad = true;
 9840     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9841              MacroAssembler::VELEM_SIZE_64, quad);
 9842   %}
 9843   ins_pipe( ialu_reg_reg ); // FIXME
 9844 %}
 9845 
 9846 // Floats vector add
 9847 instruct vadd2F_reg(vecD dst, vecD src1, vecD src2) %{
 9848   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
 9849   match(Set dst (AddVF src1 src2));
 9850   size(4);
 9851   format %{ "VADD.F32 $dst,$src1,$src2\t! add packed2F" %}
 9852   ins_encode %{
 9853     bool quad = false;
 9854     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9855              MacroAssembler::VFA_SIZE_F32, quad);
 9856   %}
 9857   ins_pipe( faddD_reg_reg ); // FIXME
 9858 %}
 9859 
 9860 instruct vadd2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
 9861   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
 9862   match(Set dst (AddVF src1 src2));
 9863   ins_cost(DEFAULT_COST*2); // FIXME
 9864 
 9865   size(4*2);
 9866   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
 9867             "FADDS  $dst.b,$src1.b,$src2.b" %}
 9868   ins_encode %{
 9869     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 9870     __ add_float($dst$$FloatRegister->successor(),
 9871              $src1$$FloatRegister->successor(),
 9872              $src2$$FloatRegister->successor());
 9873   %}
 9874 
 9875   ins_pipe(faddF_reg_reg); // FIXME
 9876 %}
 9877 
 9878 instruct vadd4F_reg_simd(vecX dst, vecX src1, vecX src2) %{
 9879   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
 9880   match(Set dst (AddVF src1 src2));
 9881   size(4);
 9882   format %{ "VADD.F32 $dst.Q,$src1.Q,$src2.Q\t! add packed4F" %}
 9883   ins_encode %{
 9884     bool quad = true;
 9885     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9886              MacroAssembler::VFA_SIZE_F32, quad);
 9887   %}
 9888   ins_pipe( faddD_reg_reg ); // FIXME
 9889 %}
 9890 
 9891 instruct vadd4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
 9892   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
 9893   match(Set dst (AddVF src1 src2));
 9894   size(4*4);
 9895   ins_cost(DEFAULT_COST*4); // FIXME
 9896 
 9897   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
 9898             "FADDS  $dst.b,$src1.b,$src2.b\n\t"
 9899             "FADDS  $dst.c,$src1.c,$src2.c\n\t"
 9900             "FADDS  $dst.d,$src1.d,$src2.d" %}
 9901 
 9902   ins_encode %{
 9903     FloatRegister dsta = $dst$$FloatRegister;
 9904     FloatRegister src1a = $src1$$FloatRegister;
 9905     FloatRegister src2a = $src2$$FloatRegister;
 9906     __ add_float(dsta, src1a, src2a);
 9907     FloatRegister dstb = dsta->successor();
 9908     FloatRegister src1b = src1a->successor();
 9909     FloatRegister src2b = src2a->successor();
 9910     __ add_float(dstb, src1b, src2b);
 9911     FloatRegister dstc = dstb->successor();
 9912     FloatRegister src1c = src1b->successor();
 9913     FloatRegister src2c = src2b->successor();
 9914     __ add_float(dstc, src1c, src2c);
 9915     FloatRegister dstd = dstc->successor();
 9916     FloatRegister src1d = src1c->successor();
 9917     FloatRegister src2d = src2c->successor();
 9918     __ add_float(dstd, src1d, src2d);
 9919   %}
 9920 
 9921   ins_pipe(faddF_reg_reg); // FIXME
 9922 %}
 9923 
 9924 instruct vadd2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
 9925   predicate(n->as_Vector()->length() == 2);
 9926   match(Set dst (AddVD src1 src2));
 9927   size(4*2);
 9928   ins_cost(DEFAULT_COST*2); // FIXME
 9929 
 9930   format %{ "FADDD  $dst.a,$src1.a,$src2.a\n\t"
 9931             "FADDD  $dst.b,$src1.b,$src2.b" %}
 9932 
 9933   ins_encode %{
 9934     FloatRegister dsta = $dst$$FloatRegister;
 9935     FloatRegister src1a = $src1$$FloatRegister;
 9936     FloatRegister src2a = $src2$$FloatRegister;
 9937     __ add_double(dsta, src1a, src2a);
 9938     FloatRegister dstb = dsta->successor()->successor();
 9939     FloatRegister src1b = src1a->successor()->successor();
 9940     FloatRegister src2b = src2a->successor()->successor();
 9941     __ add_double(dstb, src1b, src2b);
 9942   %}
 9943 
 9944   ins_pipe(faddF_reg_reg); // FIXME
 9945 %}
 9946 
 9947 
 9948 // Bytes vector sub
 9949 instruct vsub8B_reg(vecD dst, vecD src1, vecD src2) %{
 9950   predicate(n->as_Vector()->length() == 8);
 9951   match(Set dst (SubVB src1 src2));
 9952   size(4);
 9953   format %{ "VSUB.I8 $dst,$src1,$src2\t! sub packed8B" %}
 9954   ins_encode %{
 9955     bool quad = false;
 9956     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9957              MacroAssembler::VELEM_SIZE_8, quad);
 9958   %}
 9959   ins_pipe( ialu_reg_reg ); // FIXME
 9960 %}
 9961 
 9962 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
 9963   predicate(n->as_Vector()->length() == 16);
 9964   match(Set dst (SubVB src1 src2));
 9965   size(4);
 9966   format %{ "VSUB.I8 $dst.Q,$src1.Q,$src2.Q\t! sub packed16B" %}
 9967   ins_encode %{
 9968     bool quad = true;
 9969     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9970              MacroAssembler::VELEM_SIZE_8, quad);
 9971   %}
 9972   ins_pipe( ialu_reg_reg ); // FIXME
 9973 %}
 9974 
 9975 // Shorts/Chars vector sub
 9976 instruct vsub4S_reg(vecD dst, vecD src1, vecD src2) %{
 9977   predicate(n->as_Vector()->length() == 4);
 9978   match(Set dst (SubVS src1 src2));
 9979   size(4);
 9980   format %{ "VSUB.I16 $dst,$src1,$src2\t! sub packed4S" %}
 9981   ins_encode %{
 9982     bool quad = false;
 9983     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9984              MacroAssembler::VELEM_SIZE_16, quad);
 9985   %}
 9986   ins_pipe( ialu_reg_reg ); // FIXME
 9987 %}
 9988 
 9989 instruct vsub16S_reg(vecX dst, vecX src1, vecX src2) %{
 9990   predicate(n->as_Vector()->length() == 8);
 9991   match(Set dst (SubVS src1 src2));
 9992   size(4);
 9993   format %{ "VSUB.I16 $dst.Q,$src1.Q,$src2.Q\t! sub packed8S" %}
 9994   ins_encode %{
 9995     bool quad = true;
 9996     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
 9997              MacroAssembler::VELEM_SIZE_16, quad);
 9998   %}
 9999   ins_pipe( ialu_reg_reg ); // FIXME
10000 %}
10001 
10002 // Integers vector sub
10003 instruct vsub2I_reg(vecD dst, vecD src1, vecD src2) %{
10004   predicate(n->as_Vector()->length() == 2);
10005   match(Set dst (SubVI src1 src2));
10006   size(4);
10007   format %{ "VSUB.I32 $dst,$src1,$src2\t! sub packed2I" %}
10008   ins_encode %{
10009     bool quad = false;
10010     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10011              MacroAssembler::VELEM_SIZE_32, quad);
10012   %}
10013   ins_pipe( ialu_reg_reg ); // FIXME
10014 %}
10015 
10016 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
10017   predicate(n->as_Vector()->length() == 4);
10018   match(Set dst (SubVI src1 src2));
10019   size(4);
10020   format %{ "VSUB.I32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4I" %}
10021   ins_encode %{
10022     bool quad = true;
10023     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10024              MacroAssembler::VELEM_SIZE_32, quad);
10025   %}
10026   ins_pipe( ialu_reg_reg ); // FIXME
10027 %}
10028 
10029 // Longs vector sub
10030 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
10031   predicate(n->as_Vector()->length() == 2);
10032   match(Set dst (SubVL src1 src2));
10033   size(4);
10034   format %{ "VSUB.I64 $dst.Q,$src1.Q,$src2.Q\t! sub packed2L" %}
10035   ins_encode %{
10036     bool quad = true;
10037     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10038              MacroAssembler::VELEM_SIZE_64, quad);
10039   %}
10040   ins_pipe( ialu_reg_reg ); // FIXME
10041 %}
10042 
10043 // Floats vector sub
10044 instruct vsub2F_reg(vecD dst, vecD src1, vecD src2) %{
10045   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
10046   match(Set dst (SubVF src1 src2));
10047   size(4);
10048   format %{ "VSUB.F32 $dst,$src1,$src2\t! sub packed2F" %}
10049   ins_encode %{
10050     bool quad = false;
10051     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10052              MacroAssembler::VFA_SIZE_F32, quad);
10053   %}
10054   ins_pipe( faddF_reg_reg ); // FIXME
10055 %}
10056 
10057 instruct vsub2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10058   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
10059   match(Set dst (SubVF src1 src2));
10060   size(4*2);
10061   ins_cost(DEFAULT_COST*2); // FIXME
10062 
10063   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10064             "FSUBS  $dst.b,$src1.b,$src2.b" %}
10065 
10066   ins_encode %{
10067     FloatRegister dsta = $dst$$FloatRegister;
10068     FloatRegister src1a = $src1$$FloatRegister;
10069     FloatRegister src2a = $src2$$FloatRegister;
10070     __ sub_float(dsta, src1a, src2a);
10071     FloatRegister dstb = dsta->successor();
10072     FloatRegister src1b = src1a->successor();
10073     FloatRegister src2b = src2a->successor();
10074     __ sub_float(dstb, src1b, src2b);
10075   %}
10076 
10077   ins_pipe(faddF_reg_reg); // FIXME
10078 %}
10079 
10080 
10081 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
10082   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
10083   match(Set dst (SubVF src1 src2));
10084   size(4);
10085   format %{ "VSUB.F32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4F" %}
10086   ins_encode %{
10087     bool quad = true;
10088     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10089              MacroAssembler::VFA_SIZE_F32, quad);
10090   %}
10091   ins_pipe( faddF_reg_reg ); // FIXME
10092 %}
10093 
10094 instruct vsub4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10095   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
10096   match(Set dst (SubVF src1 src2));
10097   size(4*4);
10098   ins_cost(DEFAULT_COST*4); // FIXME
10099 
10100   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10101             "FSUBS  $dst.b,$src1.b,$src2.b\n\t"
10102             "FSUBS  $dst.c,$src1.c,$src2.c\n\t"
10103             "FSUBS  $dst.d,$src1.d,$src2.d" %}
10104 
10105   ins_encode %{
10106     FloatRegister dsta = $dst$$FloatRegister;
10107     FloatRegister src1a = $src1$$FloatRegister;
10108     FloatRegister src2a = $src2$$FloatRegister;
10109     __ sub_float(dsta, src1a, src2a);
10110     FloatRegister dstb = dsta->successor();
10111     FloatRegister src1b = src1a->successor();
10112     FloatRegister src2b = src2a->successor();
10113     __ sub_float(dstb, src1b, src2b);
10114     FloatRegister dstc = dstb->successor();
10115     FloatRegister src1c = src1b->successor();
10116     FloatRegister src2c = src2b->successor();
10117     __ sub_float(dstc, src1c, src2c);
10118     FloatRegister dstd = dstc->successor();
10119     FloatRegister src1d = src1c->successor();
10120     FloatRegister src2d = src2c->successor();
10121     __ sub_float(dstd, src1d, src2d);
10122   %}
10123 
10124   ins_pipe(faddF_reg_reg); // FIXME
10125 %}
10126 
10127 instruct vsub2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10128   predicate(n->as_Vector()->length() == 2);
10129   match(Set dst (SubVD src1 src2));
10130   size(4*2);
10131   ins_cost(DEFAULT_COST*2); // FIXME
10132 
10133   format %{ "FSUBD  $dst.a,$src1.a,$src2.a\n\t"
10134             "FSUBD  $dst.b,$src1.b,$src2.b" %}
10135 
10136   ins_encode %{
10137     FloatRegister dsta = $dst$$FloatRegister;
10138     FloatRegister src1a = $src1$$FloatRegister;
10139     FloatRegister src2a = $src2$$FloatRegister;
10140     __ sub_double(dsta, src1a, src2a);
10141     FloatRegister dstb = dsta->successor()->successor();
10142     FloatRegister src1b = src1a->successor()->successor();
10143     FloatRegister src2b = src2a->successor()->successor();
10144     __ sub_double(dstb, src1b, src2b);
10145   %}
10146 
10147   ins_pipe(faddF_reg_reg); // FIXME
10148 %}
10149 
10150 // Shorts/Chars vector mul
10151 instruct vmul4S_reg(vecD dst, vecD src1, vecD src2) %{
10152   predicate(n->as_Vector()->length() == 4);
10153   match(Set dst (MulVS src1 src2));
10154   size(4);
10155   format %{ "VMUL.I16 $dst,$src1,$src2\t! mul packed4S" %}
10156   ins_encode %{
10157     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10158              MacroAssembler::VELEM_SIZE_16, 0);
10159   %}
10160   ins_pipe( ialu_reg_reg ); // FIXME
10161 %}
10162 
10163 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2) %{
10164   predicate(n->as_Vector()->length() == 8);
10165   match(Set dst (MulVS src1 src2));
10166   size(4);
10167   format %{ "VMUL.I16 $dst.Q,$src1.Q,$src2.Q\t! mul packed8S" %}
10168   ins_encode %{
10169     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10170              MacroAssembler::VELEM_SIZE_16, 1);
10171   %}
10172   ins_pipe( ialu_reg_reg ); // FIXME
10173 %}
10174 
10175 // Integers vector mul
10176 instruct vmul2I_reg(vecD dst, vecD src1, vecD src2) %{
10177   predicate(n->as_Vector()->length() == 2);
10178   match(Set dst (MulVI src1 src2));
10179   size(4);
10180   format %{ "VMUL.I32 $dst,$src1,$src2\t! mul packed2I" %}
10181   ins_encode %{
10182     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10183              MacroAssembler::VELEM_SIZE_32, 0);
10184   %}
10185   ins_pipe( ialu_reg_reg ); // FIXME
10186 %}
10187 
10188 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
10189   predicate(n->as_Vector()->length() == 4);
10190   match(Set dst (MulVI src1 src2));
10191   size(4);
10192   format %{ "VMUL.I32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4I" %}
10193   ins_encode %{
10194     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10195              MacroAssembler::VELEM_SIZE_32, 1);
10196   %}
10197   ins_pipe( ialu_reg_reg ); // FIXME
10198 %}
10199 
10200 // Floats vector mul
10201 instruct vmul2F_reg(vecD dst, vecD src1, vecD src2) %{
10202   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
10203   match(Set dst (MulVF src1 src2));
10204   size(4);
10205   format %{ "VMUL.F32 $dst,$src1,$src2\t! mul packed2F" %}
10206   ins_encode %{
10207     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10208              MacroAssembler::VFA_SIZE_F32, 0);
10209   %}
10210   ins_pipe( fmulF_reg_reg ); // FIXME
10211 %}
10212 
10213 instruct vmul2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10214   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
10215   match(Set dst (MulVF src1 src2));
10216   size(4*2);
10217   ins_cost(DEFAULT_COST*2); // FIXME
10218 
10219   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10220             "FMULS  $dst.b,$src1.b,$src2.b" %}
10221   ins_encode %{
10222     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10223     __ mul_float($dst$$FloatRegister->successor(),
10224              $src1$$FloatRegister->successor(),
10225              $src2$$FloatRegister->successor());
10226   %}
10227 
10228   ins_pipe(fmulF_reg_reg); // FIXME
10229 %}
10230 
10231 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
10232   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
10233   match(Set dst (MulVF src1 src2));
10234   size(4);
10235   format %{ "VMUL.F32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4F" %}
10236   ins_encode %{
10237     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10238              MacroAssembler::VFA_SIZE_F32, 1);
10239   %}
10240   ins_pipe( fmulF_reg_reg ); // FIXME
10241 %}
10242 
10243 instruct vmul4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10244   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
10245   match(Set dst (MulVF src1 src2));
10246   size(4*4);
10247   ins_cost(DEFAULT_COST*4); // FIXME
10248 
10249   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10250             "FMULS  $dst.b,$src1.b,$src2.b\n\t"
10251             "FMULS  $dst.c,$src1.c,$src2.c\n\t"
10252             "FMULS  $dst.d,$src1.d,$src2.d" %}
10253 
10254   ins_encode %{
10255     FloatRegister dsta = $dst$$FloatRegister;
10256     FloatRegister src1a = $src1$$FloatRegister;
10257     FloatRegister src2a = $src2$$FloatRegister;
10258     __ mul_float(dsta, src1a, src2a);
10259     FloatRegister dstb = dsta->successor();
10260     FloatRegister src1b = src1a->successor();
10261     FloatRegister src2b = src2a->successor();
10262     __ mul_float(dstb, src1b, src2b);
10263     FloatRegister dstc = dstb->successor();
10264     FloatRegister src1c = src1b->successor();
10265     FloatRegister src2c = src2b->successor();
10266     __ mul_float(dstc, src1c, src2c);
10267     FloatRegister dstd = dstc->successor();
10268     FloatRegister src1d = src1c->successor();
10269     FloatRegister src2d = src2c->successor();
10270     __ mul_float(dstd, src1d, src2d);
10271   %}
10272 
10273   ins_pipe(fmulF_reg_reg); // FIXME
10274 %}
10275 
10276 instruct vmul2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10277   predicate(n->as_Vector()->length() == 2);
10278   match(Set dst (MulVD src1 src2));
10279   size(4*2);
10280   ins_cost(DEFAULT_COST*2); // FIXME
10281 
10282   format %{ "FMULD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10283             "FMULD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10284   ins_encode %{
10285     FloatRegister dsta = $dst$$FloatRegister;
10286     FloatRegister src1a = $src1$$FloatRegister;
10287     FloatRegister src2a = $src2$$FloatRegister;
10288     __ mul_double(dsta, src1a, src2a);
10289     FloatRegister dstb = dsta->successor()->successor();
10290     FloatRegister src1b = src1a->successor()->successor();
10291     FloatRegister src2b = src2a->successor()->successor();
10292     __ mul_double(dstb, src1b, src2b);
10293   %}
10294 
10295   ins_pipe(fmulD_reg_reg); // FIXME
10296 %}
10297 
10298 
10299 // Floats vector div
10300 instruct vdiv2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10301   predicate(n->as_Vector()->length() == 2);
10302   match(Set dst (DivVF src1 src2));
10303   size(4*2);
10304   ins_cost(DEFAULT_COST*2); // FIXME
10305 
10306   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10307             "FDIVS  $dst.b,$src1.b,$src2.b" %}
10308   ins_encode %{
10309     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10310     __ div_float($dst$$FloatRegister->successor(),
10311              $src1$$FloatRegister->successor(),
10312              $src2$$FloatRegister->successor());
10313   %}
10314 
10315   ins_pipe(fdivF_reg_reg); // FIXME
10316 %}
10317 
10318 instruct vdiv4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10319   predicate(n->as_Vector()->length() == 4);
10320   match(Set dst (DivVF src1 src2));
10321   size(4*4);
10322   ins_cost(DEFAULT_COST*4); // FIXME
10323 
10324   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10325             "FDIVS  $dst.b,$src1.b,$src2.b\n\t"
10326             "FDIVS  $dst.c,$src1.c,$src2.c\n\t"
10327             "FDIVS  $dst.d,$src1.d,$src2.d" %}
10328 
10329   ins_encode %{
10330     FloatRegister dsta = $dst$$FloatRegister;
10331     FloatRegister src1a = $src1$$FloatRegister;
10332     FloatRegister src2a = $src2$$FloatRegister;
10333     __ div_float(dsta, src1a, src2a);
10334     FloatRegister dstb = dsta->successor();
10335     FloatRegister src1b = src1a->successor();
10336     FloatRegister src2b = src2a->successor();
10337     __ div_float(dstb, src1b, src2b);
10338     FloatRegister dstc = dstb->successor();
10339     FloatRegister src1c = src1b->successor();
10340     FloatRegister src2c = src2b->successor();
10341     __ div_float(dstc, src1c, src2c);
10342     FloatRegister dstd = dstc->successor();
10343     FloatRegister src1d = src1c->successor();
10344     FloatRegister src2d = src2c->successor();
10345     __ div_float(dstd, src1d, src2d);
10346   %}
10347 
10348   ins_pipe(fdivF_reg_reg); // FIXME
10349 %}
10350 
10351 instruct vdiv2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10352   predicate(n->as_Vector()->length() == 2);
10353   match(Set dst (DivVD src1 src2));
10354   size(4*2);
10355   ins_cost(DEFAULT_COST*2); // FIXME
10356 
10357   format %{ "FDIVD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10358             "FDIVD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10359   ins_encode %{
10360     FloatRegister dsta = $dst$$FloatRegister;
10361     FloatRegister src1a = $src1$$FloatRegister;
10362     FloatRegister src2a = $src2$$FloatRegister;
10363     __ div_double(dsta, src1a, src2a);
10364     FloatRegister dstb = dsta->successor()->successor();
10365     FloatRegister src1b = src1a->successor()->successor();
10366     FloatRegister src2b = src2a->successor()->successor();
10367     __ div_double(dstb, src1b, src2b);
10368   %}
10369 
10370   ins_pipe(fdivD_reg_reg); // FIXME
10371 %}
10372 
10373 // --------------------------------- NEG --------------------------------------
10374 
10375 instruct vneg8B_reg(vecD dst, vecD src) %{
10376   predicate(n->as_Vector()->length_in_bytes() == 8);
10377   effect(DEF dst, USE src);
10378   size(4);
10379   ins_cost(DEFAULT_COST); // FIXME
10380   format %{ "VNEG.S8 $dst.D,$src.D\t! neg packed8B" %}
10381   ins_encode %{
10382     bool quad = false;
10383     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
10384               MacroAssembler::VELEM_SIZE_8, quad);
10385   %}
10386   ins_pipe( ialu_reg_reg ); // FIXME
10387 %}
10388 
10389 instruct vneg16B_reg(vecX dst, vecX src) %{
10390   predicate(n->as_Vector()->length_in_bytes() == 16);
10391   effect(DEF dst, USE src);
10392   size(4);
10393   ins_cost(DEFAULT_COST); // FIXME
10394   format %{ "VNEG.S8 $dst.Q,$src.Q\t! neg0 packed16B" %}
10395   ins_encode %{
10396     bool _float = false;
10397     bool quad = true;
10398     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
10399               MacroAssembler::VELEM_SIZE_8, quad);
10400   %}
10401   ins_pipe( ialu_reg_reg ); // FIXME
10402 %}
10403 
10404 // ------------------------------ Shift ---------------------------------------
10405 
10406 instruct vslcntD(vecD dst, iRegI cnt) %{
10407   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
10408   match(Set dst (LShiftCntV cnt));
10409   size(4);
10410   ins_cost(DEFAULT_COST); // FIXME
10411   expand %{
10412     Repl8B_reg_simd(dst, cnt);
10413   %}
10414 %}
10415 
10416 instruct vslcntX(vecX dst, iRegI cnt) %{
10417   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
10418   match(Set dst (LShiftCntV cnt));
10419   size(4);
10420   ins_cost(DEFAULT_COST); // FIXME
10421   expand %{
10422     Repl16B_reg(dst, cnt);
10423   %}
10424 %}
10425 
10426 // Low bits of vector "shift" elements are used, so it
10427 // doesn't matter if we treat it as ints or bytes here.
10428 instruct vsrcntD(vecD dst, iRegI cnt) %{
10429   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
10430   match(Set dst (RShiftCntV cnt));
10431   size(4*2);
10432   ins_cost(DEFAULT_COST*2); // FIXME
10433 
10434   format %{ "VDUP.8 $dst.D,$cnt\n\t"
10435             "VNEG.S8 $dst.D,$dst.D\t! neg packed8B" %}
10436   ins_encode %{
10437     bool quad = false;
10438     __ vdupI($dst$$FloatRegister, $cnt$$Register,
10439              MacroAssembler::VELEM_SIZE_8, quad);
10440     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
10441               MacroAssembler::VELEM_SIZE_8, quad);
10442   %}
10443   ins_pipe( ialu_reg_reg ); // FIXME
10444 %}
10445 
10446 instruct vsrcntX(vecX dst, iRegI cnt) %{
10447   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
10448   match(Set dst (RShiftCntV cnt));
10449   size(4*2);
10450   ins_cost(DEFAULT_COST*2); // FIXME
10451   format %{ "VDUP.8 $dst.Q,$cnt\n\t"
10452             "VNEG.S8 $dst.Q,$dst.Q\t! neg packed16B" %}
10453   ins_encode %{
10454     bool quad = true;
10455     __ vdupI($dst$$FloatRegister, $cnt$$Register,
10456              MacroAssembler::VELEM_SIZE_8, quad);
10457     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
10458               MacroAssembler::VELEM_SIZE_8, quad);
10459   %}
10460   ins_pipe( ialu_reg_reg ); // FIXME
10461 %}
10462 
10463 // Byte vector logical left/right shift based on sign
10464 instruct vsh8B_reg(vecD dst, vecD src, vecD shift) %{
10465   predicate(n->as_Vector()->length() == 8);
10466   effect(DEF dst, USE src, USE shift);
10467   size(4);
10468   ins_cost(DEFAULT_COST); // FIXME
10469   format %{
10470     "VSHL.U8 $dst.D,$src.D,$shift.D\t! logical left/right shift packed8B"
10471   %}
10472   ins_encode %{
10473     bool quad = false;
10474     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10475               MacroAssembler::VELEM_SIZE_8, quad);
10476   %}
10477   ins_pipe( ialu_reg_reg ); // FIXME
10478 %}
10479 
10480 instruct vsh16B_reg(vecX dst, vecX src, vecX shift) %{
10481   predicate(n->as_Vector()->length() == 16);
10482   effect(DEF dst, USE src, USE shift);
10483   size(4);
10484   ins_cost(DEFAULT_COST); // FIXME
10485   format %{
10486     "VSHL.U8 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed16B"
10487   %}
10488   ins_encode %{
10489     bool quad = true;
10490     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10491               MacroAssembler::VELEM_SIZE_8, quad);
10492   %}
10493   ins_pipe( ialu_reg_reg ); // FIXME
10494 %}
10495 
10496 // Shorts/Char vector logical left/right shift based on sign
10497 instruct vsh4S_reg(vecD dst, vecD src, vecD shift) %{
10498   predicate(n->as_Vector()->length() == 4);
10499   effect(DEF dst, USE src, USE shift);
10500   size(4);
10501   ins_cost(DEFAULT_COST); // FIXME
10502   format %{
10503     "VSHL.U16 $dst.D,$src.D,$shift.D\t! logical left/right shift packed4S"
10504   %}
10505   ins_encode %{
10506     bool quad = false;
10507     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10508               MacroAssembler::VELEM_SIZE_16, quad);
10509   %}
10510   ins_pipe( ialu_reg_reg ); // FIXME
10511 %}
10512 
10513 instruct vsh8S_reg(vecX dst, vecX src, vecX shift) %{
10514   predicate(n->as_Vector()->length() == 8);
10515   effect(DEF dst, USE src, USE shift);
10516   size(4);
10517   ins_cost(DEFAULT_COST); // FIXME
10518   format %{
10519     "VSHL.U16 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed8S"
10520   %}
10521   ins_encode %{
10522     bool quad = true;
10523     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10524               MacroAssembler::VELEM_SIZE_16, quad);
10525   %}
10526   ins_pipe( ialu_reg_reg ); // FIXME
10527 %}
10528 
10529 // Integers vector logical left/right shift based on sign
10530 instruct vsh2I_reg(vecD dst, vecD src, vecD shift) %{
10531   predicate(n->as_Vector()->length() == 2);
10532   effect(DEF dst, USE src, USE shift);
10533   size(4);
10534   ins_cost(DEFAULT_COST); // FIXME
10535   format %{
10536     "VSHL.U32 $dst.D,$src.D,$shift.D\t! logical left/right shift packed2I"
10537   %}
10538   ins_encode %{
10539     bool quad = false;
10540     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10541               MacroAssembler::VELEM_SIZE_32, quad);
10542   %}
10543   ins_pipe( ialu_reg_reg ); // FIXME
10544 %}
10545 
10546 instruct vsh4I_reg(vecX dst, vecX src, vecX shift) %{
10547   predicate(n->as_Vector()->length() == 4);
10548   effect(DEF dst, USE src, USE shift);
10549   size(4);
10550   ins_cost(DEFAULT_COST); // FIXME
10551   format %{
10552     "VSHL.U32 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed4I"
10553   %}
10554   ins_encode %{
10555     bool quad = true;
10556     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10557               MacroAssembler::VELEM_SIZE_32, quad);
10558   %}
10559   ins_pipe( ialu_reg_reg ); // FIXME
10560 %}
10561 
10562 // Longs vector logical left/right shift based on sign
10563 instruct vsh2L_reg(vecX dst, vecX src, vecX shift) %{
10564   predicate(n->as_Vector()->length() == 2);
10565   effect(DEF dst, USE src, USE shift);
10566   size(4);
10567   ins_cost(DEFAULT_COST); // FIXME
10568   format %{
10569     "VSHL.U64 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed2L"
10570   %}
10571   ins_encode %{
10572     bool quad = true;
10573     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10574               MacroAssembler::VELEM_SIZE_64, quad);
10575   %}
10576   ins_pipe( ialu_reg_reg ); // FIXME
10577 %}
10578 
10579 // ------------------------------ LeftShift -----------------------------------
10580 
10581 // Byte vector left shift
10582 instruct vsl8B_reg(vecD dst, vecD src, vecD shift) %{
10583   predicate(n->as_Vector()->length() == 8);
10584   match(Set dst (LShiftVB src shift));
10585   size(4*1);
10586   ins_cost(DEFAULT_COST*1); // FIXME
10587   expand %{
10588     vsh8B_reg(dst, src, shift);
10589   %}
10590 %}
10591 
10592 instruct vsl16B_reg(vecX dst, vecX src, vecX shift) %{
10593   predicate(n->as_Vector()->length() == 16);
10594   match(Set dst (LShiftVB src shift));
10595   size(4*1);
10596   ins_cost(DEFAULT_COST*1); // FIXME
10597   expand %{
10598     vsh16B_reg(dst, src, shift);
10599   %}
10600 %}
10601 
10602 instruct vsl8B_immI(vecD dst, vecD src, immI shift) %{
10603   predicate(n->as_Vector()->length() == 8);
10604   match(Set dst (LShiftVB src (LShiftCntV shift)));
10605   size(4);
10606   ins_cost(DEFAULT_COST); // FIXME
10607   format %{
10608     "VSHL.I8 $dst.D,$src.D,$shift\t! logical left shift packed8B"
10609   %}
10610   ins_encode %{
10611     bool quad = false;
10612     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10613              quad);
10614   %}
10615   ins_pipe( ialu_reg_reg ); // FIXME
10616 %}
10617 
10618 instruct vsl16B_immI(vecX dst, vecX src, immI shift) %{
10619   predicate(n->as_Vector()->length() == 16);
10620   match(Set dst (LShiftVB src (LShiftCntV shift)));
10621   size(4);
10622   ins_cost(DEFAULT_COST); // FIXME
10623   format %{
10624     "VSHL.I8 $dst.Q,$src.Q,$shift\t! logical left shift packed16B"
10625   %}
10626   ins_encode %{
10627     bool quad = true;
10628     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10629              quad);
10630   %}
10631   ins_pipe( ialu_reg_reg ); // FIXME
10632 %}
10633 
10634 // Shorts/Chars vector logical left/right shift
10635 instruct vsl4S_reg(vecD dst, vecD src, vecD shift) %{
10636   predicate(n->as_Vector()->length() == 4);
10637   match(Set dst (LShiftVS src shift));
10638   match(Set dst (URShiftVS src shift));
10639   size(4*1);
10640   ins_cost(DEFAULT_COST*1); // FIXME
10641   expand %{
10642     vsh4S_reg(dst, src, shift);
10643   %}
10644 %}
10645 
10646 instruct vsl8S_reg(vecX dst, vecX src, vecX shift) %{
10647   predicate(n->as_Vector()->length() == 8);
10648   match(Set dst (LShiftVS src shift));
10649   match(Set dst (URShiftVS src shift));
10650   size(4*1);
10651   ins_cost(DEFAULT_COST*1); // FIXME
10652   expand %{
10653     vsh8S_reg(dst, src, shift);
10654   %}
10655 %}
10656 
10657 instruct vsl4S_immI(vecD dst, vecD src, immI shift) %{
10658   predicate(n->as_Vector()->length() == 4);
10659   match(Set dst (LShiftVS src (LShiftCntV shift)));
10660   size(4);
10661   ins_cost(DEFAULT_COST); // FIXME
10662   format %{
10663     "VSHL.I16 $dst.D,$src.D,$shift\t! logical left shift packed4S"
10664   %}
10665   ins_encode %{
10666     bool quad = false;
10667     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10668              quad);
10669   %}
10670   ins_pipe( ialu_reg_reg ); // FIXME
10671 %}
10672 
10673 instruct vsl8S_immI(vecX dst, vecX src, immI shift) %{
10674   predicate(n->as_Vector()->length() == 8);
10675   match(Set dst (LShiftVS src shift));
10676   size(4);
10677   ins_cost(DEFAULT_COST); // FIXME
10678   format %{
10679     "VSHL.I16 $dst.Q,$src.Q,$shift\t! logical left shift packed8S"
10680   %}
10681   ins_encode %{
10682     bool quad = true;
10683     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10684              quad);
10685   %}
10686   ins_pipe( ialu_reg_reg ); // FIXME
10687 %}
10688 
10689 // Integers vector logical left/right shift
10690 instruct vsl2I_reg(vecD dst, vecD src, vecD shift) %{
10691   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10692   match(Set dst (LShiftVI src shift));
10693   match(Set dst (URShiftVI src shift));
10694   size(4*1);
10695   ins_cost(DEFAULT_COST*1); // FIXME
10696   expand %{
10697     vsh2I_reg(dst, src, shift);
10698   %}
10699 %}
10700 
10701 instruct vsl4I_reg(vecX dst, vecX src, vecX shift) %{
10702   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10703   match(Set dst (LShiftVI src shift));
10704   match(Set dst (URShiftVI src shift));
10705   size(4*1);
10706   ins_cost(DEFAULT_COST*1); // FIXME
10707   expand %{
10708     vsh4I_reg(dst, src, shift);
10709   %}
10710 %}
10711 
10712 instruct vsl2I_immI(vecD dst, vecD src, immI shift) %{
10713   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10714   match(Set dst (LShiftVI src (LShiftCntV shift)));
10715   size(4);
10716   ins_cost(DEFAULT_COST); // FIXME
10717   format %{
10718     "VSHL.I32 $dst.D,$src.D,$shift\t! logical left shift packed2I"
10719   %}
10720   ins_encode %{
10721     bool quad = false;
10722     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10723              quad);
10724   %}
10725   ins_pipe( ialu_reg_reg ); // FIXME
10726 %}
10727 
10728 instruct vsl4I_immI(vecX dst, vecX src, immI shift) %{
10729   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10730   match(Set dst (LShiftVI src (LShiftCntV shift)));
10731   size(4);
10732   ins_cost(DEFAULT_COST); // FIXME
10733   format %{
10734     "VSHL.I32 $dst.Q,$src.Q,$shift\t! logical left shift packed4I"
10735   %}
10736   ins_encode %{
10737     bool quad = true;
10738     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10739              quad);
10740   %}
10741   ins_pipe( ialu_reg_reg ); // FIXME
10742 %}
10743 
10744 // Longs vector logical left/right shift
10745 instruct vsl2L_reg(vecX dst, vecX src, vecX shift) %{
10746   predicate(n->as_Vector()->length() == 2);
10747   match(Set dst (LShiftVL src shift));
10748   match(Set dst (URShiftVL src shift));
10749   size(4*1);
10750   ins_cost(DEFAULT_COST*1); // FIXME
10751   expand %{
10752     vsh2L_reg(dst, src, shift);
10753   %}
10754 %}
10755 
10756 instruct vsl2L_immI(vecX dst, vecX src, immI shift) %{
10757   predicate(n->as_Vector()->length() == 2);
10758   match(Set dst (LShiftVL src (LShiftCntV shift)));
10759   size(4);
10760   ins_cost(DEFAULT_COST); // FIXME
10761   format %{
10762     "VSHL.I64 $dst.Q,$src.Q,$shift\t! logical left shift packed2L"
10763   %}
10764   ins_encode %{
10765     bool quad = true;
10766     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
10767              quad);
10768   %}
10769   ins_pipe( ialu_reg_reg ); // FIXME
10770 %}
10771 
10772 // ----------------------- LogicalRightShift -----------------------------------
10773 
10774 // Bytes/Shorts vector logical right shift produces incorrect Java result
10775 // for negative data because java code convert short value into int with
10776 // sign extension before a shift.
10777 
10778 // Chars vector logical right shift
10779 instruct vsrl4S_immI(vecD dst, vecD src, immI shift) %{
10780   predicate(n->as_Vector()->length() == 4);
10781   match(Set dst (URShiftVS src (RShiftCntV shift)));
10782   size(4);
10783   ins_cost(DEFAULT_COST); // FIXME
10784   format %{
10785     "VSHR.U16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
10786   %}
10787   ins_encode %{
10788     bool quad = false;
10789     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10790              quad);
10791   %}
10792   ins_pipe( ialu_reg_reg ); // FIXME
10793 %}
10794 
10795 instruct vsrl8S_immI(vecX dst, vecX src, immI shift) %{
10796   predicate(n->as_Vector()->length() == 8);
10797   match(Set dst (URShiftVS src (RShiftCntV shift)));
10798   size(4);
10799   ins_cost(DEFAULT_COST); // FIXME
10800   format %{
10801     "VSHR.U16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
10802   %}
10803   ins_encode %{
10804     bool quad = true;
10805     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10806              quad);
10807   %}
10808   ins_pipe( ialu_reg_reg ); // FIXME
10809 %}
10810 
10811 // Integers vector logical right shift
10812 instruct vsrl2I_immI(vecD dst, vecD src, immI shift) %{
10813   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10814   match(Set dst (URShiftVI src (RShiftCntV shift)));
10815   size(4);
10816   ins_cost(DEFAULT_COST); // FIXME
10817   format %{
10818     "VSHR.U32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
10819   %}
10820   ins_encode %{
10821     bool quad = false;
10822     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10823              quad);
10824   %}
10825   ins_pipe( ialu_reg_reg ); // FIXME
10826 %}
10827 
10828 instruct vsrl4I_immI(vecX dst, vecX src, immI shift) %{
10829   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10830   match(Set dst (URShiftVI src (RShiftCntV shift)));
10831   size(4);
10832   ins_cost(DEFAULT_COST); // FIXME
10833   format %{
10834     "VSHR.U32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
10835   %}
10836   ins_encode %{
10837     bool quad = true;
10838     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10839              quad);
10840   %}
10841   ins_pipe( ialu_reg_reg ); // FIXME
10842 %}
10843 
10844 // Longs vector logical right shift
10845 instruct vsrl2L_immI(vecX dst, vecX src, immI shift) %{
10846   predicate(n->as_Vector()->length() == 2);
10847   match(Set dst (URShiftVL src (RShiftCntV shift)));
10848   size(4);
10849   ins_cost(DEFAULT_COST); // FIXME
10850   format %{
10851     "VSHR.U64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
10852   %}
10853   ins_encode %{
10854     bool quad = true;
10855     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
10856              quad);
10857   %}
10858   ins_pipe( ialu_reg_reg ); // FIXME
10859 %}
10860 
10861 // ------------------- ArithmeticRightShift -----------------------------------
10862 
10863 // Bytes vector arithmetic left/right shift based on sign
10864 instruct vsha8B_reg(vecD dst, vecD src, vecD shift) %{
10865   predicate(n->as_Vector()->length() == 8);
10866   effect(DEF dst, USE src, USE shift);
10867   size(4);
10868   ins_cost(DEFAULT_COST); // FIXME
10869   format %{
10870     "VSHL.S8 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed8B"
10871   %}
10872   ins_encode %{
10873     bool quad = false;
10874     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10875               MacroAssembler::VELEM_SIZE_8, quad);
10876   %}
10877   ins_pipe( ialu_reg_reg ); // FIXME
10878 %}
10879 
10880 instruct vsha16B_reg(vecX dst, vecX src, vecX shift) %{
10881   predicate(n->as_Vector()->length() == 16);
10882   effect(DEF dst, USE src, USE shift);
10883   size(4);
10884   ins_cost(DEFAULT_COST); // FIXME
10885   format %{
10886     "VSHL.S8 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed16B"
10887   %}
10888   ins_encode %{
10889     bool quad = true;
10890     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10891               MacroAssembler::VELEM_SIZE_8, quad);
10892   %}
10893   ins_pipe( ialu_reg_reg ); // FIXME
10894 %}
10895 
10896 // Shorts vector arithmetic left/right shift based on sign
10897 instruct vsha4S_reg(vecD dst, vecD src, vecD shift) %{
10898   predicate(n->as_Vector()->length() == 4);
10899   effect(DEF dst, USE src, USE shift);
10900   size(4);
10901   ins_cost(DEFAULT_COST); // FIXME
10902   format %{
10903     "VSHL.S16 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed4S"
10904   %}
10905   ins_encode %{
10906     bool quad = false;
10907     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10908               MacroAssembler::VELEM_SIZE_16, quad);
10909   %}
10910   ins_pipe( ialu_reg_reg ); // FIXME
10911 %}
10912 
10913 instruct vsha8S_reg(vecX dst, vecX src, vecX shift) %{
10914   predicate(n->as_Vector()->length() == 8);
10915   effect(DEF dst, USE src, USE shift);
10916   size(4);
10917   ins_cost(DEFAULT_COST); // FIXME
10918   format %{
10919     "VSHL.S16 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed8S"
10920   %}
10921   ins_encode %{
10922     bool quad = true;
10923     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10924               MacroAssembler::VELEM_SIZE_16, quad);
10925   %}
10926   ins_pipe( ialu_reg_reg ); // FIXME
10927 %}
10928 
10929 // Integers vector arithmetic left/right shift based on sign
10930 instruct vsha2I_reg(vecD dst, vecD src, vecD shift) %{
10931   predicate(n->as_Vector()->length() == 2);
10932   effect(DEF dst, USE src, USE shift);
10933   size(4);
10934   ins_cost(DEFAULT_COST); // FIXME
10935   format %{
10936     "VSHL.S32 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed2I"
10937   %}
10938   ins_encode %{
10939     bool quad = false;
10940     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10941               MacroAssembler::VELEM_SIZE_32, quad);
10942   %}
10943   ins_pipe( ialu_reg_reg ); // FIXME
10944 %}
10945 
10946 instruct vsha4I_reg(vecX dst, vecX src, vecX shift) %{
10947   predicate(n->as_Vector()->length() == 4);
10948   effect(DEF dst, USE src, USE shift);
10949   size(4);
10950   ins_cost(DEFAULT_COST); // FIXME
10951   format %{
10952     "VSHL.S32 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed4I"
10953   %}
10954   ins_encode %{
10955     bool quad = true;
10956     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10957               MacroAssembler::VELEM_SIZE_32, quad);
10958   %}
10959   ins_pipe( ialu_reg_reg ); // FIXME
10960 %}
10961 
10962 // Longs vector arithmetic left/right shift based on sign
10963 instruct vsha2L_reg(vecX dst, vecX src, vecX shift) %{
10964   predicate(n->as_Vector()->length() == 2);
10965   effect(DEF dst, USE src, USE shift);
10966   size(4);
10967   ins_cost(DEFAULT_COST); // FIXME
10968   format %{
10969     "VSHL.S64 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed2L"
10970   %}
10971   ins_encode %{
10972     bool quad = true;
10973     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10974               MacroAssembler::VELEM_SIZE_64, quad);
10975   %}
10976   ins_pipe( ialu_reg_reg ); // FIXME
10977 %}
10978 
10979 // Byte vector arithmetic right shift
10980 
10981 instruct vsra8B_reg(vecD dst, vecD src, vecD shift) %{
10982   predicate(n->as_Vector()->length() == 8);
10983   match(Set dst (RShiftVB src shift));
10984   size(4);
10985   ins_cost(DEFAULT_COST); // FIXME
10986   expand %{
10987     vsha8B_reg(dst, src, shift);
10988   %}
10989 %}
10990 
10991 instruct vsrl16B_reg(vecX dst, vecX src, vecX shift) %{
10992   predicate(n->as_Vector()->length() == 16);
10993   match(Set dst (RShiftVB src shift));
10994   size(4);
10995   ins_cost(DEFAULT_COST); // FIXME
10996   expand %{
10997     vsha16B_reg(dst, src, shift);
10998   %}
10999 %}
11000 
11001 instruct vsrl8B_immI(vecD dst, vecD src, immI shift) %{
11002   predicate(n->as_Vector()->length() == 8);
11003   match(Set dst (RShiftVB src shift));
11004   size(4);
11005   ins_cost(DEFAULT_COST); // FIXME
11006   format %{
11007     "VSHR.S8 $dst.D,$src.D,$shift\t! logical right shift packed8B"
11008   %}
11009   ins_encode %{
11010     bool quad = false;
11011     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
11012              quad);
11013   %}
11014   ins_pipe( ialu_reg_reg ); // FIXME
11015 %}
11016 
11017 instruct vsrl16B_immI(vecX dst, vecX src, immI shift) %{
11018   predicate(n->as_Vector()->length() == 16);
11019   match(Set dst (RShiftVB src shift));
11020   size(4);
11021   ins_cost(DEFAULT_COST); // FIXME
11022   format %{
11023     "VSHR.S8 $dst.Q,$src.Q,$shift\t! logical right shift packed16B"
11024   %}
11025   ins_encode %{
11026     bool quad = true;
11027     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
11028              quad);
11029   %}
11030   ins_pipe( ialu_reg_reg ); // FIXME
11031 %}
11032 
11033 // Shorts vector arithmetic right shift
11034 instruct vsra4S_reg(vecD dst, vecD src, vecD shift) %{
11035   predicate(n->as_Vector()->length() == 4);
11036   match(Set dst (RShiftVS src shift));
11037   size(4);
11038   ins_cost(DEFAULT_COST); // FIXME
11039   expand %{
11040     vsha4S_reg(dst, src, shift);
11041   %}
11042 %}
11043 
11044 instruct vsra8S_reg(vecX dst, vecX src, vecX shift) %{
11045   predicate(n->as_Vector()->length() == 8);
11046   match(Set dst (RShiftVS src shift));
11047   size(4);
11048   ins_cost(DEFAULT_COST); // FIXME
11049   expand %{
11050     vsha8S_reg(dst, src, shift);
11051   %}
11052 %}
11053 
11054 instruct vsra4S_immI(vecD dst, vecD src, immI shift) %{
11055   predicate(n->as_Vector()->length() == 4);
11056   match(Set dst (RShiftVS src shift));
11057   size(4);
11058   ins_cost(DEFAULT_COST); // FIXME
11059   format %{
11060     "VSHR.S16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
11061   %}
11062   ins_encode %{
11063     bool quad = false;
11064     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
11065              quad);
11066   %}
11067   ins_pipe( ialu_reg_reg ); // FIXME
11068 %}
11069 
11070 instruct vsra8S_immI(vecX dst, vecX src, immI shift) %{
11071   predicate(n->as_Vector()->length() == 8);
11072   match(Set dst (RShiftVS src shift));
11073   size(4);
11074   ins_cost(DEFAULT_COST); // FIXME
11075   format %{
11076     "VSHR.S16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
11077   %}
11078   ins_encode %{
11079     bool quad = true;
11080     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
11081              quad);
11082   %}
11083   ins_pipe( ialu_reg_reg ); // FIXME
11084 %}
11085 
11086 // Integers vector arithmetic right shift
11087 instruct vsra2I_reg(vecD dst, vecD src, vecD shift) %{
11088   predicate(n->as_Vector()->length() == 2);
11089   match(Set dst (RShiftVI src shift));
11090   size(4);
11091   ins_cost(DEFAULT_COST); // FIXME
11092   expand %{
11093     vsha2I_reg(dst, src, shift);
11094   %}
11095 %}
11096 
11097 instruct vsra4I_reg(vecX dst, vecX src, vecX shift) %{
11098   predicate(n->as_Vector()->length() == 4);
11099   match(Set dst (RShiftVI src shift));
11100   size(4);
11101   ins_cost(DEFAULT_COST); // FIXME
11102   expand %{
11103     vsha4I_reg(dst, src, shift);
11104   %}
11105 %}
11106 
11107 instruct vsra2I_immI(vecD dst, vecD src, immI shift) %{
11108   predicate(n->as_Vector()->length() == 2);
11109   match(Set dst (RShiftVI src shift));
11110   size(4);
11111   ins_cost(DEFAULT_COST); // FIXME
11112   format %{
11113     "VSHR.S32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
11114   %}
11115   ins_encode %{
11116     bool quad = false;
11117     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11118              quad);
11119   %}
11120   ins_pipe( ialu_reg_reg ); // FIXME
11121 %}
11122 
11123 instruct vsra4I_immI(vecX dst, vecX src, immI shift) %{
11124   predicate(n->as_Vector()->length() == 4);
11125   match(Set dst (RShiftVI src shift));
11126   size(4);
11127   ins_cost(DEFAULT_COST); // FIXME
11128   format %{
11129     "VSHR.S32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
11130   %}
11131   ins_encode %{
11132     bool quad = true;
11133     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11134              quad);
11135   %}
11136   ins_pipe( ialu_reg_reg ); // FIXME
11137 %}
11138 
11139 // Longs vector arithmetic right shift
11140 instruct vsra2L_reg(vecX dst, vecX src, vecX shift) %{
11141   predicate(n->as_Vector()->length() == 2);
11142   match(Set dst (RShiftVL src shift));
11143   size(4);
11144   ins_cost(DEFAULT_COST); // FIXME
11145   expand %{
11146     vsha2L_reg(dst, src, shift);
11147   %}
11148 %}
11149 
11150 instruct vsra2L_immI(vecX dst, vecX src, immI shift) %{
11151   predicate(n->as_Vector()->length() == 2);
11152   match(Set dst (RShiftVL src shift));
11153   size(4);
11154   ins_cost(DEFAULT_COST); // FIXME
11155   format %{
11156     "VSHR.S64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
11157   %}
11158   ins_encode %{
11159     bool quad = true;
11160     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
11161              quad);
11162   %}
11163   ins_pipe( ialu_reg_reg ); // FIXME
11164 %}
11165 
11166 // --------------------------------- AND --------------------------------------
11167 
11168 instruct vandD(vecD dst, vecD src1, vecD src2) %{
11169   predicate(n->as_Vector()->length_in_bytes() == 8);
11170   match(Set dst (AndV src1 src2));
11171   format %{ "VAND    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11172   ins_encode %{
11173     bool quad = false;
11174     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11175              quad);
11176   %}
11177   ins_pipe( ialu_reg_reg ); // FIXME
11178 %}
11179 
11180 instruct vandX(vecX dst, vecX src1, vecX src2) %{
11181   predicate(n->as_Vector()->length_in_bytes() == 16);
11182   match(Set dst (AndV src1 src2));
11183   format %{ "VAND    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11184   ins_encode %{
11185     bool quad = true;
11186     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11187              quad);
11188   %}
11189   ins_pipe( ialu_reg_reg ); // FIXME
11190 %}
11191 
11192 // --------------------------------- OR ---------------------------------------
11193 
11194 instruct vorD(vecD dst, vecD src1, vecD src2) %{
11195   predicate(n->as_Vector()->length_in_bytes() == 8);
11196   match(Set dst (OrV src1 src2));
11197   format %{ "VOR     $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11198   ins_encode %{
11199     bool quad = false;
11200     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11201             quad);
11202   %}
11203   ins_pipe( ialu_reg_reg ); // FIXME
11204 %}
11205 
11206 instruct vorX(vecX dst, vecX src1, vecX src2) %{
11207   predicate(n->as_Vector()->length_in_bytes() == 16);
11208   match(Set dst (OrV src1 src2));
11209   format %{ "VOR     $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11210   ins_encode %{
11211     bool quad = true;
11212     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11213             quad);
11214   %}
11215   ins_pipe( ialu_reg_reg ); // FIXME
11216 %}
11217 
11218 // --------------------------------- XOR --------------------------------------
11219 
11220 instruct vxorD(vecD dst, vecD src1, vecD src2) %{
11221   predicate(n->as_Vector()->length_in_bytes() == 8);
11222   match(Set dst (XorV src1 src2));
11223   format %{ "VXOR    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11224   ins_encode %{
11225     bool quad = false;
11226     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11227              quad);
11228   %}
11229   ins_pipe( ialu_reg_reg ); // FIXME
11230 %}
11231 
11232 instruct vxorX(vecX dst, vecX src1, vecX src2) %{
11233   predicate(n->as_Vector()->length_in_bytes() == 16);
11234   match(Set dst (XorV src1 src2));
11235   format %{ "VXOR    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11236   ins_encode %{
11237     bool quad = true;
11238     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11239              quad);
11240   %}
11241   ins_pipe( ialu_reg_reg ); // FIXME
11242 %}
11243 
11244 
11245 //----------PEEPHOLE RULES-----------------------------------------------------
11246 // These must follow all instruction definitions as they use the names
11247 // defined in the instructions definitions.
11248 //
11249 // peepmatch ( root_instr_name [preceding_instruction]* );
11250 //
11251 // peepconstraint %{
11252 // (instruction_number.operand_name relational_op instruction_number.operand_name
11253 //  [, ...] );
11254 // // instruction numbers are zero-based using left to right order in peepmatch
11255 //
11256 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
11257 // // provide an instruction_number.operand_name for each operand that appears
11258 // // in the replacement instruction's match rule
11259 //
11260 // ---------VM FLAGS---------------------------------------------------------
11261 //
11262 // All peephole optimizations can be turned off using -XX:-OptoPeephole
11263 //
11264 // Each peephole rule is given an identifying number starting with zero and
11265 // increasing by one in the order seen by the parser.  An individual peephole
11266 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
11267 // on the command-line.
11268 //
11269 // ---------CURRENT LIMITATIONS----------------------------------------------
11270 //
11271 // Only match adjacent instructions in same basic block
11272 // Only equality constraints
11273 // Only constraints between operands, not (0.dest_reg == EAX_enc)
11274 // Only one replacement instruction
11275 //
11276 // ---------EXAMPLE----------------------------------------------------------
11277 //
11278 // // pertinent parts of existing instructions in architecture description
11279 // instruct movI(eRegI dst, eRegI src) %{
11280 //   match(Set dst (CopyI src));
11281 // %}
11282 //
11283 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
11284 //   match(Set dst (AddI dst src));
11285 //   effect(KILL cr);
11286 // %}
11287 //
11288 // // Change (inc mov) to lea
11289 // peephole %{
11290 //   // increment preceeded by register-register move
11291 //   peepmatch ( incI_eReg movI );
11292 //   // require that the destination register of the increment
11293 //   // match the destination register of the move
11294 //   peepconstraint ( 0.dst == 1.dst );
11295 //   // construct a replacement instruction that sets
11296 //   // the destination to ( move's source register + one )
11297 //   peepreplace ( incI_eReg_immI1( 0.dst 1.src 0.src ) );
11298 // %}
11299 //
11300 
11301 // // Change load of spilled value to only a spill
11302 // instruct storeI(memory mem, eRegI src) %{
11303 //   match(Set mem (StoreI mem src));
11304 // %}
11305 //
11306 // instruct loadI(eRegI dst, memory mem) %{
11307 //   match(Set dst (LoadI mem));
11308 // %}
11309 //
11310 // peephole %{
11311 //   peepmatch ( loadI storeI );
11312 //   peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
11313 //   peepreplace ( storeI( 1.mem 1.mem 1.src ) );
11314 // %}
11315 
11316 //----------SMARTSPILL RULES---------------------------------------------------
11317 // These must follow all instruction definitions as they use the names
11318 // defined in the instructions definitions.
11319 //
11320 // ARM will probably not have any of these rules due to RISC instruction set.
11321 
11322 //----------PIPELINE-----------------------------------------------------------
11323 // Rules which define the behavior of the target architectures pipeline.