hotspot/src/cpu/arm/vm/arm.ad
changeset 42664 29142a56c193
child 45965 e29c1363af9a
child 46378 4ccca1fdf627
equal deleted inserted replaced
42663:2335df372367 42664:29142a56c193
       
     1 //
       
     2 // Copyright (c) 2008, 2015, 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 #ifdef AARCH64
       
    71 #define ldr_32 ldr_w
       
    72 #define str_32 str_w
       
    73 #else
       
    74 #define ldr_32 ldr
       
    75 #define str_32 str
       
    76 #define tst_32 tst
       
    77 #define teq_32 teq
       
    78 #endif
       
    79 #if 1
       
    80 extern bool PrintOptoAssembly;
       
    81 #endif
       
    82 
       
    83 class c2 {
       
    84 public:
       
    85   static OptoRegPair return_value(int ideal_reg);
       
    86 };
       
    87 
       
    88 class CallStubImpl {
       
    89 
       
    90   //--------------------------------------------------------------
       
    91   //---<  Used for optimization in Compile::Shorten_branches  >---
       
    92   //--------------------------------------------------------------
       
    93 
       
    94  public:
       
    95   // Size of call trampoline stub.
       
    96   static uint size_call_trampoline() {
       
    97     return 0; // no call trampolines on this platform
       
    98   }
       
    99 
       
   100   // number of relocations needed by a call trampoline stub
       
   101   static uint reloc_call_trampoline() {
       
   102     return 0; // no call trampolines on this platform
       
   103   }
       
   104 };
       
   105 
       
   106 class HandlerImpl {
       
   107 
       
   108  public:
       
   109 
       
   110   static int emit_exception_handler(CodeBuffer &cbuf);
       
   111   static int emit_deopt_handler(CodeBuffer& cbuf);
       
   112 
       
   113   static uint size_exception_handler() {
       
   114 #ifdef AARCH64
       
   115     // ldr_literal; br; (pad); <literal>
       
   116     return 3 * Assembler::InstructionSize + wordSize;
       
   117 #else
       
   118     return ( 3 * 4 );
       
   119 #endif
       
   120   }
       
   121 
       
   122 
       
   123   static uint size_deopt_handler() {
       
   124     return ( 9 * 4 );
       
   125   }
       
   126 
       
   127 };
       
   128 
       
   129 %}
       
   130 
       
   131 source %{
       
   132 #define __ _masm.
       
   133 
       
   134 static FloatRegister reg_to_FloatRegister_object(int register_encoding);
       
   135 static Register reg_to_register_object(int register_encoding);
       
   136 
       
   137 
       
   138 // ****************************************************************************
       
   139 
       
   140 // REQUIRED FUNCTIONALITY
       
   141 
       
   142 // Indicate if the safepoint node needs the polling page as an input.
       
   143 // Since ARM does not have absolute addressing, it does.
       
   144 bool SafePointNode::needs_polling_address_input() {
       
   145   return true;
       
   146 }
       
   147 
       
   148 // emit an interrupt that is caught by the debugger (for debugging compiler)
       
   149 void emit_break(CodeBuffer &cbuf) {
       
   150   MacroAssembler _masm(&cbuf);
       
   151   __ breakpoint();
       
   152 }
       
   153 
       
   154 #ifndef PRODUCT
       
   155 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream *st ) const {
       
   156   st->print("TA");
       
   157 }
       
   158 #endif
       
   159 
       
   160 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
       
   161   emit_break(cbuf);
       
   162 }
       
   163 
       
   164 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
       
   165   return MachNode::size(ra_);
       
   166 }
       
   167 
       
   168 
       
   169 void emit_nop(CodeBuffer &cbuf) {
       
   170   MacroAssembler _masm(&cbuf);
       
   171   __ nop();
       
   172 }
       
   173 
       
   174 
       
   175 void emit_call_reloc(CodeBuffer &cbuf, const MachCallNode *n, MachOper *m, RelocationHolder const& rspec) {
       
   176   int ret_addr_offset0 = n->as_MachCall()->ret_addr_offset();
       
   177   int call_site_offset = cbuf.insts()->mark_off();
       
   178   MacroAssembler _masm(&cbuf);
       
   179   __ set_inst_mark(); // needed in emit_to_interp_stub() to locate the call
       
   180   address target = (address)m->method();
       
   181   assert(n->as_MachCall()->entry_point() == target, "sanity");
       
   182   assert(maybe_far_call(n) == !__ reachable_from_cache(target), "sanity");
       
   183   assert(cache_reachable() == __ cache_fully_reachable(), "sanity");
       
   184 
       
   185   assert(target != NULL, "need real address");
       
   186 
       
   187   int ret_addr_offset = -1;
       
   188   if (rspec.type() == relocInfo::runtime_call_type) {
       
   189     __ call(target, rspec);
       
   190     ret_addr_offset = __ offset();
       
   191   } else {
       
   192     // scratches Rtemp
       
   193     ret_addr_offset = __ patchable_call(target, rspec, true);
       
   194   }
       
   195   assert(ret_addr_offset - call_site_offset == ret_addr_offset0, "fix ret_addr_offset()");
       
   196 }
       
   197 
       
   198 //=============================================================================
       
   199 // REQUIRED FUNCTIONALITY for encoding
       
   200 void emit_lo(CodeBuffer &cbuf, int val) {  }
       
   201 void emit_hi(CodeBuffer &cbuf, int val) {  }
       
   202 
       
   203 
       
   204 //=============================================================================
       
   205 const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask();
       
   206 
       
   207 int Compile::ConstantTable::calculate_table_base_offset() const {
       
   208 #ifdef AARCH64
       
   209   return 0;
       
   210 #else
       
   211   int offset = -(size() / 2);
       
   212   // flds, fldd: 8-bit  offset multiplied by 4: +/- 1024
       
   213   // ldr, ldrb : 12-bit offset:                 +/- 4096
       
   214   if (!Assembler::is_simm10(offset)) {
       
   215     offset = Assembler::min_simm10();
       
   216   }
       
   217   return offset;
       
   218 #endif
       
   219 }
       
   220 
       
   221 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
       
   222 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
       
   223   ShouldNotReachHere();
       
   224 }
       
   225 
       
   226 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
       
   227   Compile* C = ra_->C;
       
   228   Compile::ConstantTable& constant_table = C->constant_table();
       
   229   MacroAssembler _masm(&cbuf);
       
   230 
       
   231   Register r = as_Register(ra_->get_encode(this));
       
   232   CodeSection* consts_section = __ code()->consts();
       
   233   int consts_size = consts_section->align_at_start(consts_section->size());
       
   234   assert(constant_table.size() == consts_size, "must be: %d == %d", constant_table.size(), consts_size);
       
   235 
       
   236   // Materialize the constant table base.
       
   237   address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
       
   238   RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
       
   239   __ mov_address(r, baseaddr, rspec);
       
   240 }
       
   241 
       
   242 uint MachConstantBaseNode::size(PhaseRegAlloc*) const {
       
   243 #ifdef AARCH64
       
   244   return 5 * Assembler::InstructionSize;
       
   245 #else
       
   246   return 8;
       
   247 #endif
       
   248 }
       
   249 
       
   250 #ifndef PRODUCT
       
   251 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
       
   252   char reg[128];
       
   253   ra_->dump_register(this, reg);
       
   254   st->print("MOV_SLOW    &constanttable,%s\t! constant table base", reg);
       
   255 }
       
   256 #endif
       
   257 
       
   258 #ifndef PRODUCT
       
   259 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
       
   260   Compile* C = ra_->C;
       
   261 
       
   262   for (int i = 0; i < OptoPrologueNops; i++) {
       
   263     st->print_cr("NOP"); st->print("\t");
       
   264   }
       
   265 #ifdef AARCH64
       
   266   if (OptoPrologueNops <= 0) {
       
   267     st->print_cr("NOP\t! required for safe patching");
       
   268     st->print("\t");
       
   269   }
       
   270 #endif
       
   271 
       
   272   size_t framesize = C->frame_size_in_bytes();
       
   273   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
       
   274   int bangsize = C->bang_size_in_bytes();
       
   275   // Remove two words for return addr and rbp,
       
   276   framesize -= 2*wordSize;
       
   277   bangsize -= 2*wordSize;
       
   278 
       
   279   // Calls to C2R adapters often do not accept exceptional returns.
       
   280   // We require that their callers must bang for them.  But be careful, because
       
   281   // some VM calls (such as call site linkage) can use several kilobytes of
       
   282   // stack.  But the stack safety zone should account for that.
       
   283   // See bugs 4446381, 4468289, 4497237.
       
   284   if (C->need_stack_bang(bangsize)) {
       
   285     st->print_cr("! stack bang (%d bytes)", bangsize); st->print("\t");
       
   286   }
       
   287   st->print_cr("PUSH   R_FP|R_LR_LR"); st->print("\t");
       
   288   if (framesize != 0) {
       
   289     st->print   ("SUB    R_SP, R_SP, " SIZE_FORMAT,framesize);
       
   290   }
       
   291 }
       
   292 #endif
       
   293 
       
   294 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
       
   295   Compile* C = ra_->C;
       
   296   MacroAssembler _masm(&cbuf);
       
   297 
       
   298   for (int i = 0; i < OptoPrologueNops; i++) {
       
   299     __ nop();
       
   300   }
       
   301 #ifdef AARCH64
       
   302   if (OptoPrologueNops <= 0) {
       
   303     __ nop(); // required for safe patching by patch_verified_entry()
       
   304   }
       
   305 #endif
       
   306 
       
   307   size_t framesize = C->frame_size_in_bytes();
       
   308   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
       
   309   int bangsize = C->bang_size_in_bytes();
       
   310   // Remove two words for return addr and fp,
       
   311   framesize -= 2*wordSize;
       
   312   bangsize -= 2*wordSize;
       
   313 
       
   314   // Calls to C2R adapters often do not accept exceptional returns.
       
   315   // We require that their callers must bang for them.  But be careful, because
       
   316   // some VM calls (such as call site linkage) can use several kilobytes of
       
   317   // stack.  But the stack safety zone should account for that.
       
   318   // See bugs 4446381, 4468289, 4497237.
       
   319   if (C->need_stack_bang(bangsize)) {
       
   320     __ arm_stack_overflow_check(bangsize, Rtemp);
       
   321   }
       
   322 
       
   323   __ raw_push(FP, LR);
       
   324   if (framesize != 0) {
       
   325     __ sub_slow(SP, SP, framesize);
       
   326   }
       
   327 
       
   328   // offset from scratch buffer is not valid
       
   329   if (strcmp(cbuf.name(), "Compile::Fill_buffer") == 0) {
       
   330     C->set_frame_complete( __ offset() );
       
   331   }
       
   332 
       
   333   if (C->has_mach_constant_base_node()) {
       
   334     // NOTE: We set the table base offset here because users might be
       
   335     // emitted before MachConstantBaseNode.
       
   336     Compile::ConstantTable& constant_table = C->constant_table();
       
   337     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
       
   338   }
       
   339 }
       
   340 
       
   341 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
       
   342   return MachNode::size(ra_);
       
   343 }
       
   344 
       
   345 int MachPrologNode::reloc() const {
       
   346   return 10; // a large enough number
       
   347 }
       
   348 
       
   349 //=============================================================================
       
   350 #ifndef PRODUCT
       
   351 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
       
   352   Compile* C = ra_->C;
       
   353 
       
   354   size_t framesize = C->frame_size_in_bytes();
       
   355   framesize -= 2*wordSize;
       
   356 
       
   357   if (framesize != 0) {
       
   358     st->print("ADD    R_SP, R_SP, " SIZE_FORMAT "\n\t",framesize);
       
   359   }
       
   360   st->print("POP    R_FP|R_LR_LR");
       
   361 
       
   362   if (do_polling() && ra_->C->is_method_compilation()) {
       
   363     st->print("\n\t");
       
   364 #ifdef AARCH64
       
   365     if (MacroAssembler::page_reachable_from_cache(os::get_polling_page())) {
       
   366       st->print("ADRP     Rtemp, #PollAddr\t! Load Polling address\n\t");
       
   367       st->print("LDR      ZR,[Rtemp + #PollAddr & 0xfff]\t!Poll for Safepointing");
       
   368     } else {
       
   369       st->print("mov_slow Rtemp, #PollAddr\t! Load Polling address\n\t");
       
   370       st->print("LDR      ZR,[Rtemp]\t!Poll for Safepointing");
       
   371     }
       
   372 #else
       
   373     st->print("MOV    Rtemp, #PollAddr\t! Load Polling address\n\t");
       
   374     st->print("LDR    Rtemp,[Rtemp]\t!Poll for Safepointing");
       
   375 #endif
       
   376   }
       
   377 }
       
   378 #endif
       
   379 
       
   380 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
       
   381   MacroAssembler _masm(&cbuf);
       
   382   Compile* C = ra_->C;
       
   383 
       
   384   size_t framesize = C->frame_size_in_bytes();
       
   385   framesize -= 2*wordSize;
       
   386   if (framesize != 0) {
       
   387     __ add_slow(SP, SP, framesize);
       
   388   }
       
   389   __ raw_pop(FP, LR);
       
   390 
       
   391   // If this does safepoint polling, then do it here
       
   392   if (do_polling() && ra_->C->is_method_compilation()) {
       
   393 #ifdef AARCH64
       
   394     if (false && MacroAssembler::page_reachable_from_cache(os::get_polling_page())) {
       
   395 /* FIXME: TODO
       
   396       __ relocate(relocInfo::xxx);
       
   397       __ adrp(Rtemp, (intptr_t)os::get_polling_page());
       
   398       __ relocate(relocInfo::poll_return_type);
       
   399       int offset = os::get_polling_page() & 0xfff;
       
   400       __ ldr(ZR, Address(Rtemp + offset));
       
   401 */
       
   402     } else {
       
   403       __ mov_address(Rtemp, (address)os::get_polling_page(), symbolic_Relocation::polling_page_reference);
       
   404       __ relocate(relocInfo::poll_return_type);
       
   405       __ ldr(ZR, Address(Rtemp));
       
   406     }
       
   407 #else
       
   408     // mov_slow here is usually one or two instruction
       
   409     __ mov_address(Rtemp, (address)os::get_polling_page(), symbolic_Relocation::polling_page_reference);
       
   410     __ relocate(relocInfo::poll_return_type);
       
   411     __ ldr(Rtemp, Address(Rtemp));
       
   412 #endif
       
   413   }
       
   414 }
       
   415 
       
   416 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
       
   417 #ifdef AARCH64
       
   418   // allow for added alignment nop from mov_address bind_literal
       
   419   return MachNode::size(ra_) + 1 * Assembler::InstructionSize;
       
   420 #else
       
   421   return MachNode::size(ra_);
       
   422 #endif
       
   423 }
       
   424 
       
   425 int MachEpilogNode::reloc() const {
       
   426   return 16; // a large enough number
       
   427 }
       
   428 
       
   429 const Pipeline * MachEpilogNode::pipeline() const {
       
   430   return MachNode::pipeline_class();
       
   431 }
       
   432 
       
   433 int MachEpilogNode::safepoint_offset() const {
       
   434   assert( do_polling(), "no return for this epilog node");
       
   435   //  return MacroAssembler::size_of_sethi(os::get_polling_page());
       
   436   Unimplemented();
       
   437   return 0;
       
   438 }
       
   439 
       
   440 //=============================================================================
       
   441 
       
   442 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
       
   443 enum RC { rc_bad, rc_int, rc_float, rc_stack };
       
   444 static enum RC rc_class( OptoReg::Name reg ) {
       
   445   if (!OptoReg::is_valid(reg)) return rc_bad;
       
   446   if (OptoReg::is_stack(reg)) return rc_stack;
       
   447   VMReg r = OptoReg::as_VMReg(reg);
       
   448   if (r->is_Register()) return rc_int;
       
   449   assert(r->is_FloatRegister(), "must be");
       
   450   return rc_float;
       
   451 }
       
   452 
       
   453 static inline bool is_iRegLd_memhd(OptoReg::Name src_first, OptoReg::Name src_second, int offset) {
       
   454 #ifdef AARCH64
       
   455   return is_memoryHD(offset);
       
   456 #else
       
   457   int rlo = Matcher::_regEncode[src_first];
       
   458   int rhi = Matcher::_regEncode[src_second];
       
   459   if (!((rlo&1)==0 && (rlo+1 == rhi))) {
       
   460     tty->print_cr("CAUGHT BAD LDRD/STRD");
       
   461   }
       
   462   return (rlo&1)==0 && (rlo+1 == rhi) && is_memoryHD(offset);
       
   463 #endif
       
   464 }
       
   465 
       
   466 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
       
   467                                         PhaseRegAlloc *ra_,
       
   468                                         bool do_size,
       
   469                                         outputStream* st ) const {
       
   470   // Get registers to move
       
   471   OptoReg::Name src_second = ra_->get_reg_second(in(1));
       
   472   OptoReg::Name src_first = ra_->get_reg_first(in(1));
       
   473   OptoReg::Name dst_second = ra_->get_reg_second(this );
       
   474   OptoReg::Name dst_first = ra_->get_reg_first(this );
       
   475 
       
   476   enum RC src_second_rc = rc_class(src_second);
       
   477   enum RC src_first_rc = rc_class(src_first);
       
   478   enum RC dst_second_rc = rc_class(dst_second);
       
   479   enum RC dst_first_rc = rc_class(dst_first);
       
   480 
       
   481   assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
       
   482 
       
   483   // Generate spill code!
       
   484   int size = 0;
       
   485 
       
   486   if (src_first == dst_first && src_second == dst_second)
       
   487     return size;            // Self copy, no move
       
   488 
       
   489 #ifdef TODO
       
   490   if (bottom_type()->isa_vect() != NULL) {
       
   491   }
       
   492 #endif
       
   493 
       
   494   // Shared code does not expect instruction set capability based bailouts here.
       
   495   // Handle offset unreachable bailout with minimal change in shared code.
       
   496   // Bailout only for real instruction emit.
       
   497   // This requires a single comment change in shared code. ( see output.cpp "Normal" instruction case )
       
   498 
       
   499   MacroAssembler _masm(cbuf);
       
   500 
       
   501   // --------------------------------------
       
   502   // Check for mem-mem move.  Load into unused float registers and fall into
       
   503   // the float-store case.
       
   504   if (src_first_rc == rc_stack && dst_first_rc == rc_stack) {
       
   505     int offset = ra_->reg2offset(src_first);
       
   506     if (cbuf && !is_memoryfp(offset)) {
       
   507       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
       
   508       return 0;
       
   509     } else {
       
   510       if (src_second_rc != rc_bad) {
       
   511         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
       
   512         src_first     = OptoReg::Name(R_mem_copy_lo_num);
       
   513         src_second    = OptoReg::Name(R_mem_copy_hi_num);
       
   514         src_first_rc  = rc_float;
       
   515         src_second_rc = rc_float;
       
   516         if (cbuf) {
       
   517           __ ldr_double(Rmemcopy, Address(SP, offset));
       
   518         } else if (!do_size) {
       
   519           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
       
   520         }
       
   521       } else {
       
   522         src_first     = OptoReg::Name(R_mem_copy_lo_num);
       
   523         src_first_rc  = rc_float;
       
   524         if (cbuf) {
       
   525           __ ldr_float(Rmemcopy, Address(SP, offset));
       
   526         } else if (!do_size) {
       
   527           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
       
   528         }
       
   529       }
       
   530       size += 4;
       
   531     }
       
   532   }
       
   533 
       
   534   if (src_second_rc == rc_stack && dst_second_rc == rc_stack) {
       
   535     Unimplemented();
       
   536   }
       
   537 
       
   538   // --------------------------------------
       
   539   // Check for integer reg-reg copy
       
   540   if (src_first_rc == rc_int && dst_first_rc == rc_int) {
       
   541     // Else normal reg-reg copy
       
   542     assert( src_second != dst_first, "smashed second before evacuating it" );
       
   543     if (cbuf) {
       
   544       __ mov(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
       
   545 #ifndef PRODUCT
       
   546     } else if (!do_size) {
       
   547       st->print("MOV    R_%s, R_%s\t# spill",
       
   548                 Matcher::regName[dst_first],
       
   549                 Matcher::regName[src_first]);
       
   550 #endif
       
   551     }
       
   552 #ifdef AARCH64
       
   553     if (src_first+1 == src_second && dst_first+1 == dst_second) {
       
   554       return size + 4;
       
   555     }
       
   556 #endif
       
   557     size += 4;
       
   558   }
       
   559 
       
   560   // Check for integer store
       
   561   if (src_first_rc == rc_int && dst_first_rc == rc_stack) {
       
   562     int offset = ra_->reg2offset(dst_first);
       
   563     if (cbuf && !is_memoryI(offset)) {
       
   564       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
       
   565       return 0;
       
   566     } else {
       
   567       if (src_second_rc != rc_bad && is_iRegLd_memhd(src_first, src_second, offset)) {
       
   568         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
       
   569         if (cbuf) {
       
   570           __ str_64(reg_to_register_object(Matcher::_regEncode[src_first]), Address(SP, offset));
       
   571 #ifndef PRODUCT
       
   572         } else if (!do_size) {
       
   573           if (size != 0) st->print("\n\t");
       
   574           st->print(STR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
       
   575 #endif
       
   576         }
       
   577         return size + 4;
       
   578       } else {
       
   579         if (cbuf) {
       
   580           __ str_32(reg_to_register_object(Matcher::_regEncode[src_first]), Address(SP, offset));
       
   581 #ifndef PRODUCT
       
   582         } else if (!do_size) {
       
   583           if (size != 0) st->print("\n\t");
       
   584           st->print(STR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
       
   585 #endif
       
   586         }
       
   587       }
       
   588     }
       
   589     size += 4;
       
   590   }
       
   591 
       
   592   // Check for integer load
       
   593   if (dst_first_rc == rc_int && src_first_rc == rc_stack) {
       
   594     int offset = ra_->reg2offset(src_first);
       
   595     if (cbuf && !is_memoryI(offset)) {
       
   596       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
       
   597       return 0;
       
   598     } else {
       
   599       if (src_second_rc != rc_bad && is_iRegLd_memhd(dst_first, dst_second, offset)) {
       
   600         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
       
   601         if (cbuf) {
       
   602           __ ldr_64(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
       
   603 #ifndef PRODUCT
       
   604         } else if (!do_size) {
       
   605           if (size != 0) st->print("\n\t");
       
   606           st->print(LDR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
       
   607 #endif
       
   608         }
       
   609         return size + 4;
       
   610       } else {
       
   611         if (cbuf) {
       
   612           __ ldr_32(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
       
   613 #ifndef PRODUCT
       
   614         } else if (!do_size) {
       
   615           if (size != 0) st->print("\n\t");
       
   616           st->print(LDR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
       
   617 #endif
       
   618         }
       
   619       }
       
   620     }
       
   621     size += 4;
       
   622   }
       
   623 
       
   624   // Check for float reg-reg copy
       
   625   if (src_first_rc == rc_float && dst_first_rc == rc_float) {
       
   626     if (src_second_rc != rc_bad) {
       
   627       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");
       
   628       if (cbuf) {
       
   629       __ mov_double(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
       
   630 #ifndef PRODUCT
       
   631       } else if (!do_size) {
       
   632         st->print(MOV_DOUBLE "    R_%s, R_%s\t# spill",
       
   633                   Matcher::regName[dst_first],
       
   634                   Matcher::regName[src_first]);
       
   635 #endif
       
   636       }
       
   637       return 4;
       
   638     }
       
   639     if (cbuf) {
       
   640       __ mov_float(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
       
   641 #ifndef PRODUCT
       
   642     } else if (!do_size) {
       
   643       st->print(MOV_FLOAT "    R_%s, R_%s\t# spill",
       
   644                 Matcher::regName[dst_first],
       
   645                 Matcher::regName[src_first]);
       
   646 #endif
       
   647     }
       
   648     size = 4;
       
   649   }
       
   650 
       
   651   // Check for float store
       
   652   if (src_first_rc == rc_float && dst_first_rc == rc_stack) {
       
   653     int offset = ra_->reg2offset(dst_first);
       
   654     if (cbuf && !is_memoryfp(offset)) {
       
   655       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
       
   656       return 0;
       
   657     } else {
       
   658       // Further check for aligned-adjacent pair, so we can use a double store
       
   659       if (src_second_rc != rc_bad) {
       
   660         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");
       
   661         if (cbuf) {
       
   662           __ str_double(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(SP, offset));
       
   663 #ifndef PRODUCT
       
   664         } else if (!do_size) {
       
   665           if (size != 0) st->print("\n\t");
       
   666           st->print(STR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
       
   667 #endif
       
   668         }
       
   669         return size + 4;
       
   670       } else {
       
   671         if (cbuf) {
       
   672           __ str_float(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(SP, offset));
       
   673 #ifndef PRODUCT
       
   674         } else if (!do_size) {
       
   675           if (size != 0) st->print("\n\t");
       
   676           st->print(STR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
       
   677 #endif
       
   678         }
       
   679       }
       
   680     }
       
   681     size += 4;
       
   682   }
       
   683 
       
   684   // Check for float load
       
   685   if (dst_first_rc == rc_float && src_first_rc == rc_stack) {
       
   686     int offset = ra_->reg2offset(src_first);
       
   687     if (cbuf && !is_memoryfp(offset)) {
       
   688       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
       
   689       return 0;
       
   690     } else {
       
   691       // Further check for aligned-adjacent pair, so we can use a double store
       
   692       if (src_second_rc != rc_bad) {
       
   693         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");
       
   694         if (cbuf) {
       
   695           __ ldr_double(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
       
   696 #ifndef PRODUCT
       
   697         } else if (!do_size) {
       
   698           if (size != 0) st->print("\n\t");
       
   699           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
       
   700 #endif
       
   701         }
       
   702         return size + 4;
       
   703       } else {
       
   704         if (cbuf) {
       
   705           __ ldr_float(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
       
   706 #ifndef PRODUCT
       
   707         } else if (!do_size) {
       
   708           if (size != 0) st->print("\n\t");
       
   709           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
       
   710 #endif
       
   711         }
       
   712       }
       
   713     }
       
   714     size += 4;
       
   715   }
       
   716 
       
   717   // check for int reg -> float reg move
       
   718   if (src_first_rc == rc_int && dst_first_rc == rc_float) {
       
   719     // Further check for aligned-adjacent pair, so we can use a single instruction
       
   720     if (src_second_rc != rc_bad) {
       
   721       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
       
   722       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
       
   723       assert(src_second_rc == rc_int && dst_second_rc == rc_float, "unsupported");
       
   724       if (cbuf) {
       
   725 #ifdef AARCH64
       
   726         __ fmov_dx(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
       
   727 #else
       
   728         __ 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]));
       
   729 #endif
       
   730 #ifndef PRODUCT
       
   731       } else if (!do_size) {
       
   732         if (size != 0) st->print("\n\t");
       
   733 #ifdef AARCH64
       
   734         st->print("FMOV_DX   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
       
   735 #else
       
   736         st->print("FMDRR   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first), OptoReg::regname(src_second));
       
   737 #endif
       
   738 #endif
       
   739       }
       
   740       return size + 4;
       
   741     } else {
       
   742       if (cbuf) {
       
   743         __ fmsr(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
       
   744 #ifndef PRODUCT
       
   745       } else if (!do_size) {
       
   746         if (size != 0) st->print("\n\t");
       
   747         st->print(FMSR "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
       
   748 #endif
       
   749       }
       
   750       size += 4;
       
   751     }
       
   752   }
       
   753 
       
   754   // check for float reg -> int reg move
       
   755   if (src_first_rc == rc_float && dst_first_rc == rc_int) {
       
   756     // Further check for aligned-adjacent pair, so we can use a single instruction
       
   757     if (src_second_rc != rc_bad) {
       
   758       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
       
   759       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
       
   760       assert(src_second_rc == rc_float && dst_second_rc == rc_int, "unsupported");
       
   761       if (cbuf) {
       
   762 #ifdef AARCH64
       
   763         __ fmov_xd(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
       
   764 #else
       
   765         __ 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]));
       
   766 #endif
       
   767 #ifndef PRODUCT
       
   768       } else if (!do_size) {
       
   769         if (size != 0) st->print("\n\t");
       
   770 #ifdef AARCH64
       
   771         st->print("FMOV_XD R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
       
   772 #else
       
   773         st->print("FMRRD   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(dst_second), OptoReg::regname(src_first));
       
   774 #endif
       
   775 #endif
       
   776       }
       
   777       return size + 4;
       
   778     } else {
       
   779       if (cbuf) {
       
   780         __ fmrs(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
       
   781 #ifndef PRODUCT
       
   782       } else if (!do_size) {
       
   783         if (size != 0) st->print("\n\t");
       
   784         st->print(FMRS "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
       
   785 #endif
       
   786       }
       
   787       size += 4;
       
   788     }
       
   789   }
       
   790 
       
   791   // --------------------------------------------------------------------
       
   792   // Check for hi bits still needing moving.  Only happens for misaligned
       
   793   // arguments to native calls.
       
   794   if (src_second == dst_second)
       
   795     return size;               // Self copy; no move
       
   796   assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" );
       
   797 
       
   798 #ifndef AARCH64
       
   799   // Check for integer reg-reg copy.  Hi bits are stuck up in the top
       
   800   // 32-bits of a 64-bit register, but are needed in low bits of another
       
   801   // register (else it's a hi-bits-to-hi-bits copy which should have
       
   802   // happened already as part of a 64-bit move)
       
   803   if (src_second_rc == rc_int && dst_second_rc == rc_int) {
       
   804     if (cbuf) {
       
   805       __ mov(reg_to_register_object(Matcher::_regEncode[dst_second]), reg_to_register_object(Matcher::_regEncode[src_second]));
       
   806 #ifndef PRODUCT
       
   807     } else if (!do_size) {
       
   808       if (size != 0) st->print("\n\t");
       
   809       st->print("MOV    R_%s, R_%s\t# spill high",
       
   810                 Matcher::regName[dst_second],
       
   811                 Matcher::regName[src_second]);
       
   812 #endif
       
   813     }
       
   814     return size+4;
       
   815   }
       
   816 
       
   817   // Check for high word integer store
       
   818   if (src_second_rc == rc_int && dst_second_rc == rc_stack) {
       
   819     int offset = ra_->reg2offset(dst_second);
       
   820 
       
   821     if (cbuf && !is_memoryP(offset)) {
       
   822       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
       
   823       return 0;
       
   824     } else {
       
   825       if (cbuf) {
       
   826         __ str(reg_to_register_object(Matcher::_regEncode[src_second]), Address(SP, offset));
       
   827 #ifndef PRODUCT
       
   828       } else if (!do_size) {
       
   829         if (size != 0) st->print("\n\t");
       
   830         st->print("STR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_second), offset);
       
   831 #endif
       
   832       }
       
   833     }
       
   834     return size + 4;
       
   835   }
       
   836 
       
   837   // Check for high word integer load
       
   838   if (dst_second_rc == rc_int && src_second_rc == rc_stack) {
       
   839     int offset = ra_->reg2offset(src_second);
       
   840     if (cbuf && !is_memoryP(offset)) {
       
   841       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
       
   842       return 0;
       
   843     } else {
       
   844       if (cbuf) {
       
   845         __ ldr(reg_to_register_object(Matcher::_regEncode[dst_second]), Address(SP, offset));
       
   846 #ifndef PRODUCT
       
   847       } else if (!do_size) {
       
   848         if (size != 0) st->print("\n\t");
       
   849         st->print("LDR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_second), offset);
       
   850 #endif
       
   851       }
       
   852     }
       
   853     return size + 4;
       
   854   }
       
   855 #endif
       
   856 
       
   857   Unimplemented();
       
   858   return 0; // Mute compiler
       
   859 }
       
   860 
       
   861 #ifndef PRODUCT
       
   862 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
       
   863   implementation( NULL, ra_, false, st );
       
   864 }
       
   865 #endif
       
   866 
       
   867 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
       
   868   implementation( &cbuf, ra_, false, NULL );
       
   869 }
       
   870 
       
   871 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
       
   872   return implementation( NULL, ra_, true, NULL );
       
   873 }
       
   874 
       
   875 //=============================================================================
       
   876 #ifndef PRODUCT
       
   877 void MachNopNode::format( PhaseRegAlloc *, outputStream *st ) const {
       
   878   st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
       
   879 }
       
   880 #endif
       
   881 
       
   882 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
       
   883   MacroAssembler _masm(&cbuf);
       
   884   for(int i = 0; i < _count; i += 1) {
       
   885     __ nop();
       
   886   }
       
   887 }
       
   888 
       
   889 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
       
   890   return 4 * _count;
       
   891 }
       
   892 
       
   893 
       
   894 //=============================================================================
       
   895 #ifndef PRODUCT
       
   896 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
       
   897   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
       
   898   int reg = ra_->get_reg_first(this);
       
   899   st->print("ADD    %s,R_SP+#%d",Matcher::regName[reg], offset);
       
   900 }
       
   901 #endif
       
   902 
       
   903 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
       
   904   MacroAssembler _masm(&cbuf);
       
   905   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
       
   906   int reg = ra_->get_encode(this);
       
   907   Register dst = reg_to_register_object(reg);
       
   908 
       
   909   if (is_aimm(offset)) {
       
   910     __ add(dst, SP, offset);
       
   911   } else {
       
   912     __ mov_slow(dst, offset);
       
   913 #ifdef AARCH64
       
   914     __ add(dst, SP, dst, ex_lsl);
       
   915 #else
       
   916     __ add(dst, SP, dst);
       
   917 #endif
       
   918   }
       
   919 }
       
   920 
       
   921 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
       
   922   // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_)
       
   923   assert(ra_ == ra_->C->regalloc(), "sanity");
       
   924   return ra_->C->scratch_emit_size(this);
       
   925 }
       
   926 
       
   927 //=============================================================================
       
   928 #ifndef PRODUCT
       
   929 #ifdef AARCH64
       
   930 #define R_RTEMP "R_R16"
       
   931 #else
       
   932 #define R_RTEMP "R_R12"
       
   933 #endif
       
   934 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
       
   935   st->print_cr("\nUEP:");
       
   936   if (UseCompressedClassPointers) {
       
   937     st->print_cr("\tLDR_w " R_RTEMP ",[R_R0 + oopDesc::klass_offset_in_bytes]\t! Inline cache check");
       
   938     st->print_cr("\tdecode_klass " R_RTEMP);
       
   939   } else {
       
   940     st->print_cr("\tLDR   " R_RTEMP ",[R_R0 + oopDesc::klass_offset_in_bytes]\t! Inline cache check");
       
   941   }
       
   942   st->print_cr("\tCMP   " R_RTEMP ",R_R8" );
       
   943   st->print   ("\tB.NE  SharedRuntime::handle_ic_miss_stub");
       
   944 }
       
   945 #endif
       
   946 
       
   947 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
       
   948   MacroAssembler _masm(&cbuf);
       
   949   Register iCache  = reg_to_register_object(Matcher::inline_cache_reg_encode());
       
   950   assert(iCache == Ricklass, "should be");
       
   951   Register receiver = R0;
       
   952 
       
   953   __ load_klass(Rtemp, receiver);
       
   954   __ cmp(Rtemp, iCache);
       
   955 #ifdef AARCH64
       
   956   Label match;
       
   957   __ b(match, eq);
       
   958   __ jump(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type, Rtemp);
       
   959   __ bind(match);
       
   960 #else
       
   961   __ jump(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type, noreg, ne);
       
   962 #endif
       
   963 }
       
   964 
       
   965 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
       
   966   return MachNode::size(ra_);
       
   967 }
       
   968 
       
   969 
       
   970 //=============================================================================
       
   971 
       
   972 // Emit exception handler code.
       
   973 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) {
       
   974   MacroAssembler _masm(&cbuf);
       
   975 
       
   976   address base = __ start_a_stub(size_exception_handler());
       
   977   if (base == NULL) {
       
   978     ciEnv::current()->record_failure("CodeCache is full");
       
   979     return 0;  // CodeBuffer::expand failed
       
   980   }
       
   981 
       
   982   int offset = __ offset();
       
   983 
       
   984   // OK to trash LR, because exception blob will kill it
       
   985   __ jump(OptoRuntime::exception_blob()->entry_point(), relocInfo::runtime_call_type, LR_tmp);
       
   986 
       
   987   assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
       
   988 
       
   989   __ end_a_stub();
       
   990 
       
   991   return offset;
       
   992 }
       
   993 
       
   994 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
       
   995   // Can't use any of the current frame's registers as we may have deopted
       
   996   // at a poll and everything can be live.
       
   997   MacroAssembler _masm(&cbuf);
       
   998 
       
   999   address base = __ start_a_stub(size_deopt_handler());
       
  1000   if (base == NULL) {
       
  1001     ciEnv::current()->record_failure("CodeCache is full");
       
  1002     return 0;  // CodeBuffer::expand failed
       
  1003   }
       
  1004 
       
  1005   int offset = __ offset();
       
  1006   address deopt_pc = __ pc();
       
  1007 
       
  1008 #ifdef AARCH64
       
  1009   // See LR saved by caller in sharedRuntime_arm.cpp
       
  1010   // see also hse1 ws
       
  1011   // see also LIR_Assembler::emit_deopt_handler
       
  1012 
       
  1013   __ raw_push(LR, LR); // preserve LR in both slots
       
  1014   __ mov_relative_address(LR, deopt_pc);
       
  1015   __ str(LR, Address(SP, 1 * wordSize)); // save deopt PC
       
  1016   // OK to kill LR, because deopt blob will restore it from SP[0]
       
  1017   __ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, LR_tmp);
       
  1018 #else
       
  1019   __ sub(SP, SP, wordSize); // make room for saved PC
       
  1020   __ push(LR); // save LR that may be live when we get here
       
  1021   __ mov_relative_address(LR, deopt_pc);
       
  1022   __ str(LR, Address(SP, wordSize)); // save deopt PC
       
  1023   __ pop(LR); // restore LR
       
  1024   __ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, noreg);
       
  1025 #endif
       
  1026 
       
  1027   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
       
  1028 
       
  1029   __ end_a_stub();
       
  1030   return offset;
       
  1031 }
       
  1032 
       
  1033 const bool Matcher::match_rule_supported(int opcode) {
       
  1034   if (!has_match_rule(opcode))
       
  1035     return false;
       
  1036 
       
  1037   switch (opcode) {
       
  1038   case Op_PopCountI:
       
  1039   case Op_PopCountL:
       
  1040     if (!UsePopCountInstruction)
       
  1041       return false;
       
  1042     break;
       
  1043   case Op_LShiftCntV:
       
  1044   case Op_RShiftCntV:
       
  1045   case Op_AddVB:
       
  1046   case Op_AddVS:
       
  1047   case Op_AddVI:
       
  1048   case Op_AddVL:
       
  1049   case Op_SubVB:
       
  1050   case Op_SubVS:
       
  1051   case Op_SubVI:
       
  1052   case Op_SubVL:
       
  1053   case Op_MulVS:
       
  1054   case Op_MulVI:
       
  1055   case Op_LShiftVB:
       
  1056   case Op_LShiftVS:
       
  1057   case Op_LShiftVI:
       
  1058   case Op_LShiftVL:
       
  1059   case Op_RShiftVB:
       
  1060   case Op_RShiftVS:
       
  1061   case Op_RShiftVI:
       
  1062   case Op_RShiftVL:
       
  1063   case Op_URShiftVB:
       
  1064   case Op_URShiftVS:
       
  1065   case Op_URShiftVI:
       
  1066   case Op_URShiftVL:
       
  1067   case Op_AndV:
       
  1068   case Op_OrV:
       
  1069   case Op_XorV:
       
  1070     return VM_Version::has_simd();
       
  1071   case Op_LoadVector:
       
  1072   case Op_StoreVector:
       
  1073   case Op_AddVF:
       
  1074   case Op_SubVF:
       
  1075   case Op_MulVF:
       
  1076 #ifdef AARCH64
       
  1077     return VM_Version::has_simd();
       
  1078 #else
       
  1079     return VM_Version::has_vfp() || VM_Version::has_simd();
       
  1080 #endif
       
  1081   case Op_AddVD:
       
  1082   case Op_SubVD:
       
  1083   case Op_MulVD:
       
  1084   case Op_DivVF:
       
  1085   case Op_DivVD:
       
  1086 #ifdef AARCH64
       
  1087     return VM_Version::has_simd();
       
  1088 #else
       
  1089     return VM_Version::has_vfp();
       
  1090 #endif
       
  1091   }
       
  1092 
       
  1093   return true;  // Per default match rules are supported.
       
  1094 }
       
  1095 
       
  1096 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) {
       
  1097 
       
  1098   // TODO
       
  1099   // identify extra cases that we might want to provide match rules for
       
  1100   // e.g. Op_ vector nodes and other intrinsics while guarding with vlen
       
  1101   bool ret_value = match_rule_supported(opcode);
       
  1102   // Add rules here.
       
  1103 
       
  1104   return ret_value;  // Per default match rules are supported.
       
  1105 }
       
  1106 
       
  1107 const bool Matcher::has_predicated_vectors(void) {
       
  1108   return false;
       
  1109 }
       
  1110 
       
  1111 const int Matcher::float_pressure(int default_pressure_threshold) {
       
  1112   return default_pressure_threshold;
       
  1113 }
       
  1114 
       
  1115 int Matcher::regnum_to_fpu_offset(int regnum) {
       
  1116   return regnum - 32; // The FP registers are in the second chunk
       
  1117 }
       
  1118 
       
  1119 // Vector width in bytes
       
  1120 const int Matcher::vector_width_in_bytes(BasicType bt) {
       
  1121   return MaxVectorSize;
       
  1122 }
       
  1123 
       
  1124 // Vector ideal reg corresponding to specified size in bytes
       
  1125 const int Matcher::vector_ideal_reg(int size) {
       
  1126   assert(MaxVectorSize >= size, "");
       
  1127   switch(size) {
       
  1128     case  8: return Op_VecD;
       
  1129     case 16: return Op_VecX;
       
  1130   }
       
  1131   ShouldNotReachHere();
       
  1132   return 0;
       
  1133 }
       
  1134 
       
  1135 const int Matcher::vector_shift_count_ideal_reg(int size) {
       
  1136   return vector_ideal_reg(size);
       
  1137 }
       
  1138 
       
  1139 // Limits on vector size (number of elements) loaded into vector.
       
  1140 const int Matcher::max_vector_size(const BasicType bt) {
       
  1141   assert(is_java_primitive(bt), "only primitive type vectors");
       
  1142   return vector_width_in_bytes(bt)/type2aelembytes(bt);
       
  1143 }
       
  1144 
       
  1145 const int Matcher::min_vector_size(const BasicType bt) {
       
  1146   assert(is_java_primitive(bt), "only primitive type vectors");
       
  1147   return 8/type2aelembytes(bt);
       
  1148 }
       
  1149 
       
  1150 // ARM doesn't support misaligned vectors store/load.
       
  1151 const bool Matcher::misaligned_vectors_ok() {
       
  1152   return false;
       
  1153 }
       
  1154 
       
  1155 // ARM doesn't support AES intrinsics
       
  1156 const bool Matcher::pass_original_key_for_aes() {
       
  1157   return false;
       
  1158 }
       
  1159 
       
  1160 const bool Matcher::convL2FSupported(void) {
       
  1161 #ifdef AARCH64
       
  1162   return true;
       
  1163 #else
       
  1164   return false;
       
  1165 #endif
       
  1166 }
       
  1167 
       
  1168 // Is this branch offset short enough that a short branch can be used?
       
  1169 //
       
  1170 // NOTE: If the platform does not provide any short branch variants, then
       
  1171 //       this method should return false for offset 0.
       
  1172 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
       
  1173   // The passed offset is relative to address of the branch.
       
  1174   // On ARM a branch displacement is calculated relative to address
       
  1175   // of the branch + 8.
       
  1176   //
       
  1177   // offset -= 8;
       
  1178   // return (Assembler::is_simm24(offset));
       
  1179   return false;
       
  1180 }
       
  1181 
       
  1182 const bool Matcher::isSimpleConstant64(jlong value) {
       
  1183   // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
       
  1184 #ifdef AARCH64
       
  1185   return (value == 0);
       
  1186 #else
       
  1187   return false;
       
  1188 #endif
       
  1189 }
       
  1190 
       
  1191 // No scaling for the parameter the ClearArray node.
       
  1192 const bool Matcher::init_array_count_is_in_bytes = true;
       
  1193 
       
  1194 #ifdef AARCH64
       
  1195 const int Matcher::long_cmove_cost() { return 1; }
       
  1196 #else
       
  1197 // Needs 2 CMOV's for longs.
       
  1198 const int Matcher::long_cmove_cost() { return 2; }
       
  1199 #endif
       
  1200 
       
  1201 #ifdef AARCH64
       
  1202 const int Matcher::float_cmove_cost() { return 1; }
       
  1203 #else
       
  1204 // CMOVF/CMOVD are expensive on ARM.
       
  1205 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
       
  1206 #endif
       
  1207 
       
  1208 // Does the CPU require late expand (see block.cpp for description of late expand)?
       
  1209 const bool Matcher::require_postalloc_expand = false;
       
  1210 
       
  1211 // Do we need to mask the count passed to shift instructions or does
       
  1212 // the cpu only look at the lower 5/6 bits anyway?
       
  1213 // FIXME: does this handle vector shifts as well?
       
  1214 #ifdef AARCH64
       
  1215 const bool Matcher::need_masked_shift_count = false;
       
  1216 #else
       
  1217 const bool Matcher::need_masked_shift_count = true;
       
  1218 #endif
       
  1219 
       
  1220 const bool Matcher::convi2l_type_required = true;
       
  1221 
       
  1222 // Should the Matcher clone shifts on addressing modes, expecting them
       
  1223 // to be subsumed into complex addressing expressions or compute them
       
  1224 // into registers?
       
  1225 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
       
  1226   return clone_base_plus_offset_address(m, mstack, address_visited);
       
  1227 }
       
  1228 
       
  1229 void Compile::reshape_address(AddPNode* addp) {
       
  1230 }
       
  1231 
       
  1232 bool Matcher::narrow_oop_use_complex_address() {
       
  1233   NOT_LP64(ShouldNotCallThis());
       
  1234   assert(UseCompressedOops, "only for compressed oops code");
       
  1235   return false;
       
  1236 }
       
  1237 
       
  1238 bool Matcher::narrow_klass_use_complex_address() {
       
  1239   NOT_LP64(ShouldNotCallThis());
       
  1240   assert(UseCompressedClassPointers, "only for compressed klass code");
       
  1241   return false;
       
  1242 }
       
  1243 
       
  1244 bool Matcher::const_oop_prefer_decode() {
       
  1245   NOT_LP64(ShouldNotCallThis());
       
  1246   return true;
       
  1247 }
       
  1248 
       
  1249 bool Matcher::const_klass_prefer_decode() {
       
  1250   NOT_LP64(ShouldNotCallThis());
       
  1251   return true;
       
  1252 }
       
  1253 
       
  1254 // Is it better to copy float constants, or load them directly from memory?
       
  1255 // Intel can load a float constant from a direct address, requiring no
       
  1256 // extra registers.  Most RISCs will have to materialize an address into a
       
  1257 // register first, so they would do better to copy the constant from stack.
       
  1258 const bool Matcher::rematerialize_float_constants = false;
       
  1259 
       
  1260 // If CPU can load and store mis-aligned doubles directly then no fixup is
       
  1261 // needed.  Else we split the double into 2 integer pieces and move it
       
  1262 // piece-by-piece.  Only happens when passing doubles into C code as the
       
  1263 // Java calling convention forces doubles to be aligned.
       
  1264 #ifdef AARCH64
       
  1265 // On stack replacement support:
       
  1266 // We don't need Load[DL]_unaligned support, because interpreter stack
       
  1267 // has correct alignment
       
  1268 const bool Matcher::misaligned_doubles_ok = true;
       
  1269 #else
       
  1270 const bool Matcher::misaligned_doubles_ok = false;
       
  1271 #endif
       
  1272 
       
  1273 // No-op on ARM.
       
  1274 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {
       
  1275 }
       
  1276 
       
  1277 // Advertise here if the CPU requires explicit rounding operations
       
  1278 // to implement the UseStrictFP mode.
       
  1279 const bool Matcher::strict_fp_requires_explicit_rounding = false;
       
  1280 
       
  1281 // Are floats converted to double when stored to stack during deoptimization?
       
  1282 // ARM does not handle callee-save floats.
       
  1283 bool Matcher::float_in_double() {
       
  1284   return false;
       
  1285 }
       
  1286 
       
  1287 // Do ints take an entire long register or just half?
       
  1288 // Note that we if-def off of _LP64.
       
  1289 // The relevant question is how the int is callee-saved.  In _LP64
       
  1290 // the whole long is written but de-opt'ing will have to extract
       
  1291 // the relevant 32 bits, in not-_LP64 only the low 32 bits is written.
       
  1292 #ifdef _LP64
       
  1293 const bool Matcher::int_in_long = true;
       
  1294 #else
       
  1295 const bool Matcher::int_in_long = false;
       
  1296 #endif
       
  1297 
       
  1298 // Return whether or not this register is ever used as an argument.  This
       
  1299 // function is used on startup to build the trampoline stubs in generateOptoStub.
       
  1300 // Registers not mentioned will be killed by the VM call in the trampoline, and
       
  1301 // arguments in those registers not be available to the callee.
       
  1302 bool Matcher::can_be_java_arg( int reg ) {
       
  1303 #ifdef AARCH64
       
  1304   if (reg >= R_R0_num && reg < R_R8_num) return true;
       
  1305   if (reg >= R_V0_num && reg <= R_V7b_num && ((reg & 3) < 2)) return true;
       
  1306 #else
       
  1307   if (reg == R_R0_num ||
       
  1308       reg == R_R1_num ||
       
  1309       reg == R_R2_num ||
       
  1310       reg == R_R3_num) return true;
       
  1311 
       
  1312   if (reg >= R_S0_num &&
       
  1313       reg <= R_S13_num) return true;
       
  1314 #endif
       
  1315   return false;
       
  1316 }
       
  1317 
       
  1318 bool Matcher::is_spillable_arg( int reg ) {
       
  1319   return can_be_java_arg(reg);
       
  1320 }
       
  1321 
       
  1322 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
       
  1323   return false;
       
  1324 }
       
  1325 
       
  1326 // Register for DIVI projection of divmodI
       
  1327 RegMask Matcher::divI_proj_mask() {
       
  1328   ShouldNotReachHere();
       
  1329   return RegMask();
       
  1330 }
       
  1331 
       
  1332 // Register for MODI projection of divmodI
       
  1333 RegMask Matcher::modI_proj_mask() {
       
  1334   ShouldNotReachHere();
       
  1335   return RegMask();
       
  1336 }
       
  1337 
       
  1338 // Register for DIVL projection of divmodL
       
  1339 RegMask Matcher::divL_proj_mask() {
       
  1340   ShouldNotReachHere();
       
  1341   return RegMask();
       
  1342 }
       
  1343 
       
  1344 // Register for MODL projection of divmodL
       
  1345 RegMask Matcher::modL_proj_mask() {
       
  1346   ShouldNotReachHere();
       
  1347   return RegMask();
       
  1348 }
       
  1349 
       
  1350 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
       
  1351   return FP_REGP_mask();
       
  1352 }
       
  1353 
       
  1354 bool maybe_far_call(const CallNode *n) {
       
  1355   return !MacroAssembler::_reachable_from_cache(n->as_Call()->entry_point());
       
  1356 }
       
  1357 
       
  1358 bool maybe_far_call(const MachCallNode *n) {
       
  1359   return !MacroAssembler::_reachable_from_cache(n->as_MachCall()->entry_point());
       
  1360 }
       
  1361 
       
  1362 %}
       
  1363 
       
  1364 //----------ENCODING BLOCK-----------------------------------------------------
       
  1365 // This block specifies the encoding classes used by the compiler to output
       
  1366 // byte streams.  Encoding classes are parameterized macros used by
       
  1367 // Machine Instruction Nodes in order to generate the bit encoding of the
       
  1368 // instruction.  Operands specify their base encoding interface with the
       
  1369 // interface keyword.  There are currently supported four interfaces,
       
  1370 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
       
  1371 // operand to generate a function which returns its register number when
       
  1372 // queried.   CONST_INTER causes an operand to generate a function which
       
  1373 // returns the value of the constant when queried.  MEMORY_INTER causes an
       
  1374 // operand to generate four functions which return the Base Register, the
       
  1375 // Index Register, the Scale Value, and the Offset Value of the operand when
       
  1376 // queried.  COND_INTER causes an operand to generate six functions which
       
  1377 // return the encoding code (ie - encoding bits for the instruction)
       
  1378 // associated with each basic boolean condition for a conditional instruction.
       
  1379 //
       
  1380 // Instructions specify two basic values for encoding.  Again, a function
       
  1381 // is available to check if the constant displacement is an oop. They use the
       
  1382 // ins_encode keyword to specify their encoding classes (which must be
       
  1383 // a sequence of enc_class names, and their parameters, specified in
       
  1384 // the encoding block), and they use the
       
  1385 // opcode keyword to specify, in order, their primary, secondary, and
       
  1386 // tertiary opcode.  Only the opcode sections which a particular instruction
       
  1387 // needs for encoding need to be specified.
       
  1388 encode %{
       
  1389   enc_class call_epilog %{
       
  1390     // nothing
       
  1391   %}
       
  1392 
       
  1393   enc_class Java_To_Runtime (method meth) %{
       
  1394     // CALL directly to the runtime
       
  1395     emit_call_reloc(cbuf, as_MachCall(), $meth, runtime_call_Relocation::spec());
       
  1396   %}
       
  1397 
       
  1398   enc_class Java_Static_Call (method meth) %{
       
  1399     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
       
  1400     // who we intended to call.
       
  1401 
       
  1402     if ( !_method) {
       
  1403       emit_call_reloc(cbuf, as_MachCall(), $meth, runtime_call_Relocation::spec());
       
  1404     } else {
       
  1405       int method_index = resolved_method_index(cbuf);
       
  1406       RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
       
  1407                                                   : static_call_Relocation::spec(method_index);
       
  1408       emit_call_reloc(cbuf, as_MachCall(), $meth, rspec);
       
  1409 
       
  1410       // Emit stubs for static call.
       
  1411       address stub = CompiledStaticCall::emit_to_interp_stub(cbuf);
       
  1412       if (stub == NULL) {
       
  1413         ciEnv::current()->record_failure("CodeCache is full");
       
  1414         return;
       
  1415       }
       
  1416     }
       
  1417   %}
       
  1418 
       
  1419   enc_class save_last_PC %{
       
  1420     // preserve mark
       
  1421     address mark = cbuf.insts()->mark();
       
  1422     debug_only(int off0 = cbuf.insts_size());
       
  1423     MacroAssembler _masm(&cbuf);
       
  1424     int ret_addr_offset = as_MachCall()->ret_addr_offset();
       
  1425     __ adr(LR, mark + ret_addr_offset);
       
  1426     __ str(LR, Address(Rthread, JavaThread::last_Java_pc_offset()));
       
  1427     debug_only(int off1 = cbuf.insts_size());
       
  1428     assert(off1 - off0 == 2 * Assembler::InstructionSize, "correct size prediction");
       
  1429     // restore mark
       
  1430     cbuf.insts()->set_mark(mark);
       
  1431   %}
       
  1432 
       
  1433   enc_class preserve_SP %{
       
  1434     // preserve mark
       
  1435     address mark = cbuf.insts()->mark();
       
  1436     debug_only(int off0 = cbuf.insts_size());
       
  1437     MacroAssembler _masm(&cbuf);
       
  1438     // FP is preserved across all calls, even compiled calls.
       
  1439     // Use it to preserve SP in places where the callee might change the SP.
       
  1440     __ mov(Rmh_SP_save, SP);
       
  1441     debug_only(int off1 = cbuf.insts_size());
       
  1442     assert(off1 - off0 == 4, "correct size prediction");
       
  1443     // restore mark
       
  1444     cbuf.insts()->set_mark(mark);
       
  1445   %}
       
  1446 
       
  1447   enc_class restore_SP %{
       
  1448     MacroAssembler _masm(&cbuf);
       
  1449     __ mov(SP, Rmh_SP_save);
       
  1450   %}
       
  1451 
       
  1452   enc_class Java_Dynamic_Call (method meth) %{
       
  1453     MacroAssembler _masm(&cbuf);
       
  1454     Register R8_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode());
       
  1455     assert(R8_ic_reg == Ricklass, "should be");
       
  1456     __ set_inst_mark();
       
  1457 #ifdef AARCH64
       
  1458 // TODO: see C1 LIR_Assembler::ic_call()
       
  1459     InlinedAddress oop_literal((address)Universe::non_oop_word());
       
  1460     int offset = __ offset();
       
  1461     int fixed_size = mov_oop_size * 4;
       
  1462     if (VM_Version::prefer_moves_over_load_literal()) {
       
  1463       uintptr_t val = (uintptr_t)Universe::non_oop_word();
       
  1464       __ movz(R8_ic_reg, (val >>  0) & 0xffff,  0);
       
  1465       __ movk(R8_ic_reg, (val >> 16) & 0xffff, 16);
       
  1466       __ movk(R8_ic_reg, (val >> 32) & 0xffff, 32);
       
  1467       __ movk(R8_ic_reg, (val >> 48) & 0xffff, 48);
       
  1468     } else {
       
  1469       __ ldr_literal(R8_ic_reg, oop_literal);
       
  1470     }
       
  1471     assert(__ offset() - offset == fixed_size, "bad mov_oop size");
       
  1472 #else
       
  1473     __ movw(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) & 0xffff);
       
  1474     __ movt(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) >> 16);
       
  1475 #endif
       
  1476     address  virtual_call_oop_addr = __ inst_mark();
       
  1477     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
       
  1478     // who we intended to call.
       
  1479     int method_index = resolved_method_index(cbuf);
       
  1480     __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index));
       
  1481     emit_call_reloc(cbuf, as_MachCall(), $meth, RelocationHolder::none);
       
  1482 #ifdef AARCH64
       
  1483     if (!VM_Version::prefer_moves_over_load_literal()) {
       
  1484       Label skip_literal;
       
  1485       __ b(skip_literal);
       
  1486       int off2 = __ offset();
       
  1487       __ bind_literal(oop_literal);
       
  1488       if (__ offset() - off2 == wordSize) {
       
  1489         // no padding, so insert nop for worst-case sizing
       
  1490         __ nop();
       
  1491       }
       
  1492       __ bind(skip_literal);
       
  1493     }
       
  1494 #endif
       
  1495   %}
       
  1496 
       
  1497   enc_class LdReplImmI(immI src, regD dst, iRegI tmp, int cnt, int wth) %{
       
  1498     // FIXME: load from constant table?
       
  1499     // Load a constant replicated "count" times with width "width"
       
  1500     int count = $cnt$$constant;
       
  1501     int width = $wth$$constant;
       
  1502     assert(count*width == 4, "sanity");
       
  1503     int val = $src$$constant;
       
  1504     if (width < 4) {
       
  1505       int bit_width = width * 8;
       
  1506       val &= (((int)1) << bit_width) - 1; // mask off sign bits
       
  1507       for (int i = 0; i < count - 1; i++) {
       
  1508         val |= (val << bit_width);
       
  1509       }
       
  1510     }
       
  1511     MacroAssembler _masm(&cbuf);
       
  1512 
       
  1513     if (val == -1) {
       
  1514       __ mvn($tmp$$Register, 0);
       
  1515     } else if (val == 0) {
       
  1516       __ mov($tmp$$Register, 0);
       
  1517     } else {
       
  1518       __ movw($tmp$$Register, val & 0xffff);
       
  1519       __ movt($tmp$$Register, (unsigned int)val >> 16);
       
  1520     }
       
  1521     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
       
  1522   %}
       
  1523 
       
  1524   enc_class LdReplImmF(immF src, regD dst, iRegI tmp) %{
       
  1525     // Replicate float con 2 times and pack into vector (8 bytes) in regD.
       
  1526     float fval = $src$$constant;
       
  1527     int val = *((int*)&fval);
       
  1528     MacroAssembler _masm(&cbuf);
       
  1529 
       
  1530     if (val == -1) {
       
  1531       __ mvn($tmp$$Register, 0);
       
  1532     } else if (val == 0) {
       
  1533       __ mov($tmp$$Register, 0);
       
  1534     } else {
       
  1535       __ movw($tmp$$Register, val & 0xffff);
       
  1536       __ movt($tmp$$Register, (unsigned int)val >> 16);
       
  1537     }
       
  1538     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
       
  1539   %}
       
  1540 
       
  1541   enc_class enc_String_Compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result, iRegI tmp1, iRegI tmp2) %{
       
  1542     Label Ldone, Lloop;
       
  1543     MacroAssembler _masm(&cbuf);
       
  1544 
       
  1545     Register   str1_reg = $str1$$Register;
       
  1546     Register   str2_reg = $str2$$Register;
       
  1547     Register   cnt1_reg = $cnt1$$Register; // int
       
  1548     Register   cnt2_reg = $cnt2$$Register; // int
       
  1549     Register   tmp1_reg = $tmp1$$Register;
       
  1550     Register   tmp2_reg = $tmp2$$Register;
       
  1551     Register result_reg = $result$$Register;
       
  1552 
       
  1553     assert_different_registers(str1_reg, str2_reg, cnt1_reg, cnt2_reg, tmp1_reg, tmp2_reg);
       
  1554 
       
  1555     // Compute the minimum of the string lengths(str1_reg) and the
       
  1556     // difference of the string lengths (stack)
       
  1557 
       
  1558     // See if the lengths are different, and calculate min in str1_reg.
       
  1559     // Stash diff in tmp2 in case we need it for a tie-breaker.
       
  1560     __ subs_32(tmp2_reg, cnt1_reg, cnt2_reg);
       
  1561 #ifdef AARCH64
       
  1562     Label Lskip;
       
  1563     __ _lsl_w(cnt1_reg, cnt1_reg, exact_log2(sizeof(jchar))); // scale the limit
       
  1564     __ b(Lskip, mi);
       
  1565     __ _lsl_w(cnt1_reg, cnt2_reg, exact_log2(sizeof(jchar))); // scale the limit
       
  1566     __ bind(Lskip);
       
  1567 #else
       
  1568     __ mov(cnt1_reg, AsmOperand(cnt1_reg, lsl, exact_log2(sizeof(jchar)))); // scale the limit
       
  1569     __ mov(cnt1_reg, AsmOperand(cnt2_reg, lsl, exact_log2(sizeof(jchar))), pl); // scale the limit
       
  1570 #endif
       
  1571 
       
  1572     // reallocate cnt1_reg, cnt2_reg, result_reg
       
  1573     // Note:  limit_reg holds the string length pre-scaled by 2
       
  1574     Register limit_reg = cnt1_reg;
       
  1575     Register  chr2_reg = cnt2_reg;
       
  1576     Register  chr1_reg = tmp1_reg;
       
  1577     // str{12} are the base pointers
       
  1578 
       
  1579     // Is the minimum length zero?
       
  1580     __ cmp_32(limit_reg, 0);
       
  1581     if (result_reg != tmp2_reg) {
       
  1582       __ mov(result_reg, tmp2_reg, eq);
       
  1583     }
       
  1584     __ b(Ldone, eq);
       
  1585 
       
  1586     // Load first characters
       
  1587     __ ldrh(chr1_reg, Address(str1_reg, 0));
       
  1588     __ ldrh(chr2_reg, Address(str2_reg, 0));
       
  1589 
       
  1590     // Compare first characters
       
  1591     __ subs(chr1_reg, chr1_reg, chr2_reg);
       
  1592     if (result_reg != chr1_reg) {
       
  1593       __ mov(result_reg, chr1_reg, ne);
       
  1594     }
       
  1595     __ b(Ldone, ne);
       
  1596 
       
  1597     {
       
  1598       // Check after comparing first character to see if strings are equivalent
       
  1599       // Check if the strings start at same location
       
  1600       __ cmp(str1_reg, str2_reg);
       
  1601       // Check if the length difference is zero
       
  1602       __ cond_cmp(tmp2_reg, 0, eq);
       
  1603       __ mov(result_reg, 0, eq); // result is zero
       
  1604       __ b(Ldone, eq);
       
  1605       // Strings might not be equal
       
  1606     }
       
  1607 
       
  1608     __ subs(chr1_reg, limit_reg, 1 * sizeof(jchar));
       
  1609     if (result_reg != tmp2_reg) {
       
  1610       __ mov(result_reg, tmp2_reg, eq);
       
  1611     }
       
  1612     __ b(Ldone, eq);
       
  1613 
       
  1614     // Shift str1_reg and str2_reg to the end of the arrays, negate limit
       
  1615     __ add(str1_reg, str1_reg, limit_reg);
       
  1616     __ add(str2_reg, str2_reg, limit_reg);
       
  1617     __ neg(limit_reg, chr1_reg);  // limit = -(limit-2)
       
  1618 
       
  1619     // Compare the rest of the characters
       
  1620     __ bind(Lloop);
       
  1621     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
       
  1622     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
       
  1623     __ subs(chr1_reg, chr1_reg, chr2_reg);
       
  1624     if (result_reg != chr1_reg) {
       
  1625       __ mov(result_reg, chr1_reg, ne);
       
  1626     }
       
  1627     __ b(Ldone, ne);
       
  1628 
       
  1629     __ adds(limit_reg, limit_reg, sizeof(jchar));
       
  1630     __ b(Lloop, ne);
       
  1631 
       
  1632     // If strings are equal up to min length, return the length difference.
       
  1633     if (result_reg != tmp2_reg) {
       
  1634       __ mov(result_reg, tmp2_reg);
       
  1635     }
       
  1636 
       
  1637     // Otherwise, return the difference between the first mismatched chars.
       
  1638     __ bind(Ldone);
       
  1639   %}
       
  1640 
       
  1641   enc_class enc_String_Equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2) %{
       
  1642     Label Lword_loop, Lpost_word, Lchar, Lchar_loop, Ldone, Lequal;
       
  1643     MacroAssembler _masm(&cbuf);
       
  1644 
       
  1645     Register   str1_reg = $str1$$Register;
       
  1646     Register   str2_reg = $str2$$Register;
       
  1647     Register    cnt_reg = $cnt$$Register; // int
       
  1648     Register   tmp1_reg = $tmp1$$Register;
       
  1649     Register   tmp2_reg = $tmp2$$Register;
       
  1650     Register result_reg = $result$$Register;
       
  1651 
       
  1652     assert_different_registers(str1_reg, str2_reg, cnt_reg, tmp1_reg, tmp2_reg, result_reg);
       
  1653 
       
  1654     __ cmp(str1_reg, str2_reg); //same char[] ?
       
  1655     __ b(Lequal, eq);
       
  1656 
       
  1657     __ cbz_32(cnt_reg, Lequal); // count == 0
       
  1658 
       
  1659     //rename registers
       
  1660     Register limit_reg = cnt_reg;
       
  1661     Register  chr1_reg = tmp1_reg;
       
  1662     Register  chr2_reg = tmp2_reg;
       
  1663 
       
  1664     __ logical_shift_left(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
       
  1665 
       
  1666     //check for alignment and position the pointers to the ends
       
  1667     __ orr(chr1_reg, str1_reg, str2_reg);
       
  1668     __ tst(chr1_reg, 0x3);
       
  1669 
       
  1670     // notZero means at least one not 4-byte aligned.
       
  1671     // We could optimize the case when both arrays are not aligned
       
  1672     // but it is not frequent case and it requires additional checks.
       
  1673     __ b(Lchar, ne);
       
  1674 
       
  1675     // Compare char[] arrays aligned to 4 bytes.
       
  1676     __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg,
       
  1677                           chr1_reg, chr2_reg, Ldone);
       
  1678 
       
  1679     __ b(Lequal); // equal
       
  1680 
       
  1681     // char by char compare
       
  1682     __ bind(Lchar);
       
  1683     __ mov(result_reg, 0);
       
  1684     __ add(str1_reg, limit_reg, str1_reg);
       
  1685     __ add(str2_reg, limit_reg, str2_reg);
       
  1686     __ neg(limit_reg, limit_reg); //negate count
       
  1687 
       
  1688     // Lchar_loop
       
  1689     __ bind(Lchar_loop);
       
  1690     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
       
  1691     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
       
  1692     __ cmp(chr1_reg, chr2_reg);
       
  1693     __ b(Ldone, ne);
       
  1694     __ adds(limit_reg, limit_reg, sizeof(jchar));
       
  1695     __ b(Lchar_loop, ne);
       
  1696 
       
  1697     __ bind(Lequal);
       
  1698     __ mov(result_reg, 1);  //equal
       
  1699 
       
  1700     __ bind(Ldone);
       
  1701   %}
       
  1702 
       
  1703   enc_class enc_Array_Equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result) %{
       
  1704     Label Lvector, Ldone, Lloop, Lequal;
       
  1705     MacroAssembler _masm(&cbuf);
       
  1706 
       
  1707     Register   ary1_reg = $ary1$$Register;
       
  1708     Register   ary2_reg = $ary2$$Register;
       
  1709     Register   tmp1_reg = $tmp1$$Register;
       
  1710     Register   tmp2_reg = $tmp2$$Register;
       
  1711     Register   tmp3_reg = $tmp3$$Register;
       
  1712     Register result_reg = $result$$Register;
       
  1713 
       
  1714     assert_different_registers(ary1_reg, ary2_reg, tmp1_reg, tmp2_reg, tmp3_reg, result_reg);
       
  1715 
       
  1716     int length_offset  = arrayOopDesc::length_offset_in_bytes();
       
  1717     int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
       
  1718 
       
  1719     // return true if the same array
       
  1720 #ifdef AARCH64
       
  1721     __ cmp(ary1_reg, ary2_reg);
       
  1722     __ b(Lequal, eq);
       
  1723 
       
  1724     __ mov(result_reg, 0);
       
  1725 
       
  1726     __ cbz(ary1_reg, Ldone); // not equal
       
  1727 
       
  1728     __ cbz(ary2_reg, Ldone); // not equal
       
  1729 #else
       
  1730     __ teq(ary1_reg, ary2_reg);
       
  1731     __ mov(result_reg, 1, eq);
       
  1732     __ b(Ldone, eq); // equal
       
  1733 
       
  1734     __ tst(ary1_reg, ary1_reg);
       
  1735     __ mov(result_reg, 0, eq);
       
  1736     __ b(Ldone, eq);    // not equal
       
  1737 
       
  1738     __ tst(ary2_reg, ary2_reg);
       
  1739     __ mov(result_reg, 0, eq);
       
  1740     __ b(Ldone, eq);    // not equal
       
  1741 #endif
       
  1742 
       
  1743     //load the lengths of arrays
       
  1744     __ ldr_s32(tmp1_reg, Address(ary1_reg, length_offset)); // int
       
  1745     __ ldr_s32(tmp2_reg, Address(ary2_reg, length_offset)); // int
       
  1746 
       
  1747     // return false if the two arrays are not equal length
       
  1748 #ifdef AARCH64
       
  1749     __ cmp_w(tmp1_reg, tmp2_reg);
       
  1750     __ b(Ldone, ne);    // not equal
       
  1751 
       
  1752     __ cbz_w(tmp1_reg, Lequal); // zero-length arrays are equal
       
  1753 #else
       
  1754     __ teq_32(tmp1_reg, tmp2_reg);
       
  1755     __ mov(result_reg, 0, ne);
       
  1756     __ b(Ldone, ne);    // not equal
       
  1757 
       
  1758     __ tst(tmp1_reg, tmp1_reg);
       
  1759     __ mov(result_reg, 1, eq);
       
  1760     __ b(Ldone, eq);    // zero-length arrays are equal
       
  1761 #endif
       
  1762 
       
  1763     // load array addresses
       
  1764     __ add(ary1_reg, ary1_reg, base_offset);
       
  1765     __ add(ary2_reg, ary2_reg, base_offset);
       
  1766 
       
  1767     // renaming registers
       
  1768     Register chr1_reg  =  tmp3_reg;   // for characters in ary1
       
  1769     Register chr2_reg  =  tmp2_reg;   // for characters in ary2
       
  1770     Register limit_reg =  tmp1_reg;   // length
       
  1771 
       
  1772     // set byte count
       
  1773     __ logical_shift_left_32(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
       
  1774 
       
  1775     // Compare char[] arrays aligned to 4 bytes.
       
  1776     __ char_arrays_equals(ary1_reg, ary2_reg, limit_reg, result_reg,
       
  1777                           chr1_reg, chr2_reg, Ldone);
       
  1778     __ bind(Lequal);
       
  1779     __ mov(result_reg, 1);  //equal
       
  1780 
       
  1781     __ bind(Ldone);
       
  1782     %}
       
  1783 %}
       
  1784 
       
  1785 //----------FRAME--------------------------------------------------------------
       
  1786 // Definition of frame structure and management information.
       
  1787 //
       
  1788 //  S T A C K   L A Y O U T    Allocators stack-slot number
       
  1789 //                             |   (to get allocators register number
       
  1790 //  G  Owned by    |        |  v    add VMRegImpl::stack0)
       
  1791 //  r   CALLER     |        |
       
  1792 //  o     |        +--------+      pad to even-align allocators stack-slot
       
  1793 //  w     V        |  pad0  |        numbers; owned by CALLER
       
  1794 //  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
       
  1795 //  h     ^        |   in   |  5
       
  1796 //        |        |  args  |  4   Holes in incoming args owned by SELF
       
  1797 //  |     |        |        |  3
       
  1798 //  |     |        +--------+
       
  1799 //  V     |        | old out|      Empty on Intel, window on Sparc
       
  1800 //        |    old |preserve|      Must be even aligned.
       
  1801 //        |     SP-+--------+----> Matcher::_old_SP, 8 (or 16 in LP64)-byte aligned
       
  1802 //        |        |   in   |  3   area for Intel ret address
       
  1803 //     Owned by    |preserve|      Empty on Sparc.
       
  1804 //       SELF      +--------+
       
  1805 //        |        |  pad2  |  2   pad to align old SP
       
  1806 //        |        +--------+  1
       
  1807 //        |        | locks  |  0
       
  1808 //        |        +--------+----> VMRegImpl::stack0, 8 (or 16 in LP64)-byte aligned
       
  1809 //        |        |  pad1  | 11   pad to align new SP
       
  1810 //        |        +--------+
       
  1811 //        |        |        | 10
       
  1812 //        |        | spills |  9   spills
       
  1813 //        V        |        |  8   (pad0 slot for callee)
       
  1814 //      -----------+--------+----> Matcher::_out_arg_limit, unaligned
       
  1815 //        ^        |  out   |  7
       
  1816 //        |        |  args  |  6   Holes in outgoing args owned by CALLEE
       
  1817 //     Owned by    +--------+
       
  1818 //      CALLEE     | new out|  6   Empty on Intel, window on Sparc
       
  1819 //        |    new |preserve|      Must be even-aligned.
       
  1820 //        |     SP-+--------+----> Matcher::_new_SP, even aligned
       
  1821 //        |        |        |
       
  1822 //
       
  1823 // Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
       
  1824 //         known from SELF's arguments and the Java calling convention.
       
  1825 //         Region 6-7 is determined per call site.
       
  1826 // Note 2: If the calling convention leaves holes in the incoming argument
       
  1827 //         area, those holes are owned by SELF.  Holes in the outgoing area
       
  1828 //         are owned by the CALLEE.  Holes should not be nessecary in the
       
  1829 //         incoming area, as the Java calling convention is completely under
       
  1830 //         the control of the AD file.  Doubles can be sorted and packed to
       
  1831 //         avoid holes.  Holes in the outgoing arguments may be nessecary for
       
  1832 //         varargs C calling conventions.
       
  1833 // Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
       
  1834 //         even aligned with pad0 as needed.
       
  1835 //         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
       
  1836 //         region 6-11 is even aligned; it may be padded out more so that
       
  1837 //         the region from SP to FP meets the minimum stack alignment.
       
  1838 
       
  1839 frame %{
       
  1840   // What direction does stack grow in (assumed to be same for native & Java)
       
  1841   stack_direction(TOWARDS_LOW);
       
  1842 
       
  1843   // These two registers define part of the calling convention
       
  1844   // between compiled code and the interpreter.
       
  1845   inline_cache_reg(R_Ricklass);          // Inline Cache Register or Method* for I2C
       
  1846   interpreter_method_oop_reg(R_Rmethod); // Method Oop Register when calling interpreter
       
  1847 
       
  1848   // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
       
  1849   cisc_spilling_operand_name(indOffset);
       
  1850 
       
  1851   // Number of stack slots consumed by a Monitor enter
       
  1852   sync_stack_slots(1 * VMRegImpl::slots_per_word);
       
  1853 
       
  1854   // Compiled code's Frame Pointer
       
  1855 #ifdef AARCH64
       
  1856   frame_pointer(R_SP);
       
  1857 #else
       
  1858   frame_pointer(R_R13);
       
  1859 #endif
       
  1860 
       
  1861   // Stack alignment requirement
       
  1862   stack_alignment(StackAlignmentInBytes);
       
  1863   //  LP64: Alignment size in bytes (128-bit -> 16 bytes)
       
  1864   // !LP64: Alignment size in bytes (64-bit  ->  8 bytes)
       
  1865 
       
  1866   // Number of stack slots between incoming argument block and the start of
       
  1867   // a new frame.  The PROLOG must add this many slots to the stack.  The
       
  1868   // EPILOG must remove this many slots.
       
  1869   // FP + LR
       
  1870   in_preserve_stack_slots(2 * VMRegImpl::slots_per_word);
       
  1871 
       
  1872   // Number of outgoing stack slots killed above the out_preserve_stack_slots
       
  1873   // for calls to C.  Supports the var-args backing area for register parms.
       
  1874   // ADLC doesn't support parsing expressions, so I folded the math by hand.
       
  1875   varargs_C_out_slots_killed( 0);
       
  1876 
       
  1877   // The after-PROLOG location of the return address.  Location of
       
  1878   // return address specifies a type (REG or STACK) and a number
       
  1879   // representing the register number (i.e. - use a register name) or
       
  1880   // stack slot.
       
  1881   // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
       
  1882   // Otherwise, it is above the locks and verification slot and alignment word
       
  1883   return_addr(STACK - 1*VMRegImpl::slots_per_word +
       
  1884               round_to((Compile::current()->in_preserve_stack_slots() +
       
  1885                         Compile::current()->fixed_slots()),
       
  1886                        stack_alignment_in_slots()));
       
  1887 
       
  1888   // Body of function which returns an OptoRegs array locating
       
  1889   // arguments either in registers or in stack slots for calling
       
  1890   // java
       
  1891   calling_convention %{
       
  1892     (void) SharedRuntime::java_calling_convention(sig_bt, regs, length, is_outgoing);
       
  1893 
       
  1894   %}
       
  1895 
       
  1896   // Body of function which returns an OptoRegs array locating
       
  1897   // arguments either in registers or in stack slots for callin
       
  1898   // C.
       
  1899   c_calling_convention %{
       
  1900     // This is obviously always outgoing
       
  1901     (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
       
  1902   %}
       
  1903 
       
  1904   // Location of compiled Java return values.  Same as C
       
  1905   return_value %{
       
  1906     return c2::return_value(ideal_reg);
       
  1907   %}
       
  1908 
       
  1909 %}
       
  1910 
       
  1911 //----------ATTRIBUTES---------------------------------------------------------
       
  1912 //----------Instruction Attributes---------------------------------------------
       
  1913 ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute
       
  1914 ins_attrib ins_size(32);           // Required size attribute (in bits)
       
  1915 ins_attrib ins_short_branch(0);    // Required flag: is this instruction a
       
  1916                                    // non-matching short branch variant of some
       
  1917                                                             // long branch?
       
  1918 
       
  1919 //----------OPERANDS-----------------------------------------------------------
       
  1920 // Operand definitions must precede instruction definitions for correct parsing
       
  1921 // in the ADLC because operands constitute user defined types which are used in
       
  1922 // instruction definitions.
       
  1923 
       
  1924 //----------Simple Operands----------------------------------------------------
       
  1925 // Immediate Operands
       
  1926 // Integer Immediate: 32-bit
       
  1927 operand immI() %{
       
  1928   match(ConI);
       
  1929 
       
  1930   op_cost(0);
       
  1931   // formats are generated automatically for constants and base registers
       
  1932   format %{ %}
       
  1933   interface(CONST_INTER);
       
  1934 %}
       
  1935 
       
  1936 // Integer Immediate: 8-bit unsigned - for VMOV
       
  1937 operand immU8() %{
       
  1938   predicate(0 <= n->get_int() && (n->get_int() <= 255));
       
  1939   match(ConI);
       
  1940   op_cost(0);
       
  1941 
       
  1942   format %{ %}
       
  1943   interface(CONST_INTER);
       
  1944 %}
       
  1945 
       
  1946 // Integer Immediate: 16-bit
       
  1947 operand immI16() %{
       
  1948   predicate((n->get_int() >> 16) == 0 && VM_Version::supports_movw());
       
  1949   match(ConI);
       
  1950   op_cost(0);
       
  1951 
       
  1952   format %{ %}
       
  1953   interface(CONST_INTER);
       
  1954 %}
       
  1955 
       
  1956 #ifndef AARCH64
       
  1957 // Integer Immediate: offset for half and double word loads and stores
       
  1958 operand immIHD() %{
       
  1959   predicate(is_memoryHD(n->get_int()));
       
  1960   match(ConI);
       
  1961   op_cost(0);
       
  1962   format %{ %}
       
  1963   interface(CONST_INTER);
       
  1964 %}
       
  1965 
       
  1966 // Integer Immediate: offset for fp loads and stores
       
  1967 operand immIFP() %{
       
  1968   predicate(is_memoryfp(n->get_int()) && ((n->get_int() & 3) == 0));
       
  1969   match(ConI);
       
  1970   op_cost(0);
       
  1971 
       
  1972   format %{ %}
       
  1973   interface(CONST_INTER);
       
  1974 %}
       
  1975 #endif
       
  1976 
       
  1977 // Valid scale values for addressing modes and shifts
       
  1978 operand immU5() %{
       
  1979   predicate(0 <= n->get_int() && (n->get_int() <= 31));
       
  1980   match(ConI);
       
  1981   op_cost(0);
       
  1982 
       
  1983   format %{ %}
       
  1984   interface(CONST_INTER);
       
  1985 %}
       
  1986 
       
  1987 // Integer Immediate: 6-bit
       
  1988 operand immU6Big() %{
       
  1989   predicate(n->get_int() >= 32 && n->get_int() <= 63);
       
  1990   match(ConI);
       
  1991   op_cost(0);
       
  1992   format %{ %}
       
  1993   interface(CONST_INTER);
       
  1994 %}
       
  1995 
       
  1996 // Integer Immediate: 0-bit
       
  1997 operand immI0() %{
       
  1998   predicate(n->get_int() == 0);
       
  1999   match(ConI);
       
  2000   op_cost(0);
       
  2001 
       
  2002   format %{ %}
       
  2003   interface(CONST_INTER);
       
  2004 %}
       
  2005 
       
  2006 // Integer Immediate: the value 1
       
  2007 operand immI_1() %{
       
  2008   predicate(n->get_int() == 1);
       
  2009   match(ConI);
       
  2010   op_cost(0);
       
  2011 
       
  2012   format %{ %}
       
  2013   interface(CONST_INTER);
       
  2014 %}
       
  2015 
       
  2016 // Integer Immediate: the value 2
       
  2017 operand immI_2() %{
       
  2018   predicate(n->get_int() == 2);
       
  2019   match(ConI);
       
  2020   op_cost(0);
       
  2021 
       
  2022   format %{ %}
       
  2023   interface(CONST_INTER);
       
  2024 %}
       
  2025 
       
  2026 // Integer Immediate: the value 3
       
  2027 operand immI_3() %{
       
  2028   predicate(n->get_int() == 3);
       
  2029   match(ConI);
       
  2030   op_cost(0);
       
  2031 
       
  2032   format %{ %}
       
  2033   interface(CONST_INTER);
       
  2034 %}
       
  2035 
       
  2036 // Integer Immediate: the value 4
       
  2037 operand immI_4() %{
       
  2038   predicate(n->get_int() == 4);
       
  2039   match(ConI);
       
  2040   op_cost(0);
       
  2041 
       
  2042   format %{ %}
       
  2043   interface(CONST_INTER);
       
  2044 %}
       
  2045 
       
  2046 // Integer Immediate: the value 8
       
  2047 operand immI_8() %{
       
  2048   predicate(n->get_int() == 8);
       
  2049   match(ConI);
       
  2050   op_cost(0);
       
  2051 
       
  2052   format %{ %}
       
  2053   interface(CONST_INTER);
       
  2054 %}
       
  2055 
       
  2056 // Int Immediate non-negative
       
  2057 operand immU31()
       
  2058 %{
       
  2059   predicate(n->get_int() >= 0);
       
  2060   match(ConI);
       
  2061 
       
  2062   op_cost(0);
       
  2063   format %{ %}
       
  2064   interface(CONST_INTER);
       
  2065 %}
       
  2066 
       
  2067 // Integer Immediate: the values 32-63
       
  2068 operand immI_32_63() %{
       
  2069   predicate(n->get_int() >= 32 && n->get_int() <= 63);
       
  2070   match(ConI);
       
  2071   op_cost(0);
       
  2072 
       
  2073   format %{ %}
       
  2074   interface(CONST_INTER);
       
  2075 %}
       
  2076 
       
  2077 // Immediates for special shifts (sign extend)
       
  2078 
       
  2079 // Integer Immediate: the value 16
       
  2080 operand immI_16() %{
       
  2081   predicate(n->get_int() == 16);
       
  2082   match(ConI);
       
  2083   op_cost(0);
       
  2084 
       
  2085   format %{ %}
       
  2086   interface(CONST_INTER);
       
  2087 %}
       
  2088 
       
  2089 // Integer Immediate: the value 24
       
  2090 operand immI_24() %{
       
  2091   predicate(n->get_int() == 24);
       
  2092   match(ConI);
       
  2093   op_cost(0);
       
  2094 
       
  2095   format %{ %}
       
  2096   interface(CONST_INTER);
       
  2097 %}
       
  2098 
       
  2099 // Integer Immediate: the value 255
       
  2100 operand immI_255() %{
       
  2101   predicate( n->get_int() == 255 );
       
  2102   match(ConI);
       
  2103   op_cost(0);
       
  2104 
       
  2105   format %{ %}
       
  2106   interface(CONST_INTER);
       
  2107 %}
       
  2108 
       
  2109 // Integer Immediate: the value 65535
       
  2110 operand immI_65535() %{
       
  2111   predicate(n->get_int() == 65535);
       
  2112   match(ConI);
       
  2113   op_cost(0);
       
  2114 
       
  2115   format %{ %}
       
  2116   interface(CONST_INTER);
       
  2117 %}
       
  2118 
       
  2119 // Integer Immediates for arithmetic instructions
       
  2120 
       
  2121 operand aimmI() %{
       
  2122   predicate(is_aimm(n->get_int()));
       
  2123   match(ConI);
       
  2124   op_cost(0);
       
  2125 
       
  2126   format %{ %}
       
  2127   interface(CONST_INTER);
       
  2128 %}
       
  2129 
       
  2130 operand aimmIneg() %{
       
  2131   predicate(is_aimm(-n->get_int()));
       
  2132   match(ConI);
       
  2133   op_cost(0);
       
  2134 
       
  2135   format %{ %}
       
  2136   interface(CONST_INTER);
       
  2137 %}
       
  2138 
       
  2139 operand aimmU31() %{
       
  2140   predicate((0 <= n->get_int()) && is_aimm(n->get_int()));
       
  2141   match(ConI);
       
  2142   op_cost(0);
       
  2143 
       
  2144   format %{ %}
       
  2145   interface(CONST_INTER);
       
  2146 %}
       
  2147 
       
  2148 // Integer Immediates for logical instructions
       
  2149 
       
  2150 operand limmI() %{
       
  2151   predicate(is_limmI(n->get_int()));
       
  2152   match(ConI);
       
  2153   op_cost(0);
       
  2154 
       
  2155   format %{ %}
       
  2156   interface(CONST_INTER);
       
  2157 %}
       
  2158 
       
  2159 operand limmIlow8() %{
       
  2160   predicate(is_limmI_low(n->get_int(), 8));
       
  2161   match(ConI);
       
  2162   op_cost(0);
       
  2163 
       
  2164   format %{ %}
       
  2165   interface(CONST_INTER);
       
  2166 %}
       
  2167 
       
  2168 operand limmU31() %{
       
  2169   predicate(0 <= n->get_int() && is_limmI(n->get_int()));
       
  2170   match(ConI);
       
  2171   op_cost(0);
       
  2172 
       
  2173   format %{ %}
       
  2174   interface(CONST_INTER);
       
  2175 %}
       
  2176 
       
  2177 operand limmIn() %{
       
  2178   predicate(is_limmI(~n->get_int()));
       
  2179   match(ConI);
       
  2180   op_cost(0);
       
  2181 
       
  2182   format %{ %}
       
  2183   interface(CONST_INTER);
       
  2184 %}
       
  2185 
       
  2186 #ifdef AARCH64
       
  2187 // Long Immediate: for logical instruction
       
  2188 operand limmL() %{
       
  2189   predicate(is_limmL(n->get_long()));
       
  2190   match(ConL);
       
  2191   op_cost(0);
       
  2192 
       
  2193   format %{ %}
       
  2194   interface(CONST_INTER);
       
  2195 %}
       
  2196 
       
  2197 operand limmLn() %{
       
  2198   predicate(is_limmL(~n->get_long()));
       
  2199   match(ConL);
       
  2200   op_cost(0);
       
  2201 
       
  2202   format %{ %}
       
  2203   interface(CONST_INTER);
       
  2204 %}
       
  2205 
       
  2206 // Long Immediate: for arithmetic instruction
       
  2207 operand aimmL() %{
       
  2208   predicate(is_aimm(n->get_long()));
       
  2209   match(ConL);
       
  2210   op_cost(0);
       
  2211 
       
  2212   format %{ %}
       
  2213   interface(CONST_INTER);
       
  2214 %}
       
  2215 
       
  2216 operand aimmLneg() %{
       
  2217   predicate(is_aimm(-n->get_long()));
       
  2218   match(ConL);
       
  2219   op_cost(0);
       
  2220 
       
  2221   format %{ %}
       
  2222   interface(CONST_INTER);
       
  2223 %}
       
  2224 #endif // AARCH64
       
  2225 
       
  2226 // Long Immediate: the value FF
       
  2227 operand immL_FF() %{
       
  2228   predicate( n->get_long() == 0xFFL );
       
  2229   match(ConL);
       
  2230   op_cost(0);
       
  2231 
       
  2232   format %{ %}
       
  2233   interface(CONST_INTER);
       
  2234 %}
       
  2235 
       
  2236 // Long Immediate: the value FFFF
       
  2237 operand immL_FFFF() %{
       
  2238   predicate( n->get_long() == 0xFFFFL );
       
  2239   match(ConL);
       
  2240   op_cost(0);
       
  2241 
       
  2242   format %{ %}
       
  2243   interface(CONST_INTER);
       
  2244 %}
       
  2245 
       
  2246 // Pointer Immediate: 32 or 64-bit
       
  2247 operand immP() %{
       
  2248   match(ConP);
       
  2249 
       
  2250   op_cost(5);
       
  2251   // formats are generated automatically for constants and base registers
       
  2252   format %{ %}
       
  2253   interface(CONST_INTER);
       
  2254 %}
       
  2255 
       
  2256 operand immP0() %{
       
  2257   predicate(n->get_ptr() == 0);
       
  2258   match(ConP);
       
  2259   op_cost(0);
       
  2260 
       
  2261   format %{ %}
       
  2262   interface(CONST_INTER);
       
  2263 %}
       
  2264 
       
  2265 operand immP_poll() %{
       
  2266   predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
       
  2267   match(ConP);
       
  2268 
       
  2269   // formats are generated automatically for constants and base registers
       
  2270   format %{ %}
       
  2271   interface(CONST_INTER);
       
  2272 %}
       
  2273 
       
  2274 // Pointer Immediate
       
  2275 operand immN()
       
  2276 %{
       
  2277   match(ConN);
       
  2278 
       
  2279   op_cost(10);
       
  2280   format %{ %}
       
  2281   interface(CONST_INTER);
       
  2282 %}
       
  2283 
       
  2284 operand immNKlass()
       
  2285 %{
       
  2286   match(ConNKlass);
       
  2287 
       
  2288   op_cost(10);
       
  2289   format %{ %}
       
  2290   interface(CONST_INTER);
       
  2291 %}
       
  2292 
       
  2293 // NULL Pointer Immediate
       
  2294 operand immN0()
       
  2295 %{
       
  2296   predicate(n->get_narrowcon() == 0);
       
  2297   match(ConN);
       
  2298 
       
  2299   op_cost(0);
       
  2300   format %{ %}
       
  2301   interface(CONST_INTER);
       
  2302 %}
       
  2303 
       
  2304 operand immL() %{
       
  2305   match(ConL);
       
  2306   op_cost(40);
       
  2307   // formats are generated automatically for constants and base registers
       
  2308   format %{ %}
       
  2309   interface(CONST_INTER);
       
  2310 %}
       
  2311 
       
  2312 operand immL0() %{
       
  2313   predicate(n->get_long() == 0L);
       
  2314   match(ConL);
       
  2315   op_cost(0);
       
  2316   // formats are generated automatically for constants and base registers
       
  2317   format %{ %}
       
  2318   interface(CONST_INTER);
       
  2319 %}
       
  2320 
       
  2321 // Long Immediate: 16-bit
       
  2322 operand immL16() %{
       
  2323   predicate(n->get_long() >= 0 && n->get_long() < (1<<16)  && VM_Version::supports_movw());
       
  2324   match(ConL);
       
  2325   op_cost(0);
       
  2326 
       
  2327   format %{ %}
       
  2328   interface(CONST_INTER);
       
  2329 %}
       
  2330 
       
  2331 // Long Immediate: low 32-bit mask
       
  2332 operand immL_32bits() %{
       
  2333   predicate(n->get_long() == 0xFFFFFFFFL);
       
  2334   match(ConL);
       
  2335   op_cost(0);
       
  2336 
       
  2337   format %{ %}
       
  2338   interface(CONST_INTER);
       
  2339 %}
       
  2340 
       
  2341 // Double Immediate
       
  2342 operand immD() %{
       
  2343   match(ConD);
       
  2344 
       
  2345   op_cost(40);
       
  2346   format %{ %}
       
  2347   interface(CONST_INTER);
       
  2348 %}
       
  2349 
       
  2350 // Double Immediate: +0.0d.
       
  2351 operand immD0() %{
       
  2352   predicate(jlong_cast(n->getd()) == 0);
       
  2353 
       
  2354   match(ConD);
       
  2355   op_cost(0);
       
  2356   format %{ %}
       
  2357   interface(CONST_INTER);
       
  2358 %}
       
  2359 
       
  2360 operand imm8D() %{
       
  2361   predicate(Assembler::double_num(n->getd()).can_be_imm8());
       
  2362   match(ConD);
       
  2363 
       
  2364   op_cost(0);
       
  2365   format %{ %}
       
  2366   interface(CONST_INTER);
       
  2367 %}
       
  2368 
       
  2369 // Float Immediate
       
  2370 operand immF() %{
       
  2371   match(ConF);
       
  2372 
       
  2373   op_cost(20);
       
  2374   format %{ %}
       
  2375   interface(CONST_INTER);
       
  2376 %}
       
  2377 
       
  2378 // Float Immediate: +0.0f
       
  2379 operand immF0() %{
       
  2380   predicate(jint_cast(n->getf()) == 0);
       
  2381   match(ConF);
       
  2382 
       
  2383   op_cost(0);
       
  2384   format %{ %}
       
  2385   interface(CONST_INTER);
       
  2386 %}
       
  2387 
       
  2388 // Float Immediate: encoded as 8 bits
       
  2389 operand imm8F() %{
       
  2390   predicate(Assembler::float_num(n->getf()).can_be_imm8());
       
  2391   match(ConF);
       
  2392 
       
  2393   op_cost(0);
       
  2394   format %{ %}
       
  2395   interface(CONST_INTER);
       
  2396 %}
       
  2397 
       
  2398 // Integer Register Operands
       
  2399 // Integer Register
       
  2400 operand iRegI() %{
       
  2401   constraint(ALLOC_IN_RC(int_reg));
       
  2402   match(RegI);
       
  2403   match(R0RegI);
       
  2404   match(R1RegI);
       
  2405   match(R2RegI);
       
  2406   match(R3RegI);
       
  2407 #ifdef AARCH64
       
  2408   match(ZRRegI);
       
  2409 #else
       
  2410   match(R12RegI);
       
  2411 #endif
       
  2412 
       
  2413   format %{ %}
       
  2414   interface(REG_INTER);
       
  2415 %}
       
  2416 
       
  2417 // Pointer Register
       
  2418 operand iRegP() %{
       
  2419   constraint(ALLOC_IN_RC(ptr_reg));
       
  2420   match(RegP);
       
  2421   match(R0RegP);
       
  2422   match(R1RegP);
       
  2423   match(R2RegP);
       
  2424   match(RExceptionRegP);
       
  2425   match(R8RegP);
       
  2426   match(R9RegP);
       
  2427   match(RthreadRegP); // FIXME: move to sp_ptr_RegP?
       
  2428   match(R12RegP);
       
  2429   match(LRRegP);
       
  2430 
       
  2431   match(sp_ptr_RegP);
       
  2432   match(store_ptr_RegP);
       
  2433 
       
  2434   format %{ %}
       
  2435   interface(REG_INTER);
       
  2436 %}
       
  2437 
       
  2438 // GPRs + Rthread + SP
       
  2439 operand sp_ptr_RegP() %{
       
  2440   constraint(ALLOC_IN_RC(sp_ptr_reg));
       
  2441   match(RegP);
       
  2442   match(iRegP);
       
  2443   match(SPRegP); // FIXME: check cost
       
  2444 
       
  2445   format %{ %}
       
  2446   interface(REG_INTER);
       
  2447 %}
       
  2448 
       
  2449 #ifdef AARCH64
       
  2450 // Like sp_ptr_reg, but exclude regs (Aarch64 SP) that can't be
       
  2451 // stored directly.  Includes ZR, so can't be used as a destination.
       
  2452 operand store_ptr_RegP() %{
       
  2453   constraint(ALLOC_IN_RC(store_ptr_reg));
       
  2454   match(RegP);
       
  2455   match(iRegP);
       
  2456   match(ZRRegP);
       
  2457 
       
  2458   format %{ %}
       
  2459   interface(REG_INTER);
       
  2460 %}
       
  2461 
       
  2462 operand store_RegI() %{
       
  2463   constraint(ALLOC_IN_RC(store_reg));
       
  2464   match(RegI);
       
  2465   match(iRegI);
       
  2466   match(ZRRegI);
       
  2467 
       
  2468   format %{ %}
       
  2469   interface(REG_INTER);
       
  2470 %}
       
  2471 
       
  2472 operand store_RegL() %{
       
  2473   constraint(ALLOC_IN_RC(store_ptr_reg));
       
  2474   match(RegL);
       
  2475   match(iRegL);
       
  2476   match(ZRRegL);
       
  2477 
       
  2478   format %{ %}
       
  2479   interface(REG_INTER);
       
  2480 %}
       
  2481 
       
  2482 operand store_RegN() %{
       
  2483   constraint(ALLOC_IN_RC(store_reg));
       
  2484   match(RegN);
       
  2485   match(iRegN);
       
  2486   match(ZRRegN);
       
  2487 
       
  2488   format %{ %}
       
  2489   interface(REG_INTER);
       
  2490 %}
       
  2491 #endif
       
  2492 
       
  2493 operand R0RegP() %{
       
  2494   constraint(ALLOC_IN_RC(R0_regP));
       
  2495   match(iRegP);
       
  2496 
       
  2497   format %{ %}
       
  2498   interface(REG_INTER);
       
  2499 %}
       
  2500 
       
  2501 operand R1RegP() %{
       
  2502   constraint(ALLOC_IN_RC(R1_regP));
       
  2503   match(iRegP);
       
  2504 
       
  2505   format %{ %}
       
  2506   interface(REG_INTER);
       
  2507 %}
       
  2508 
       
  2509 operand R2RegP() %{
       
  2510   constraint(ALLOC_IN_RC(R2_regP));
       
  2511   match(iRegP);
       
  2512 
       
  2513   format %{ %}
       
  2514   interface(REG_INTER);
       
  2515 %}
       
  2516 
       
  2517 operand RExceptionRegP() %{
       
  2518   constraint(ALLOC_IN_RC(Rexception_regP));
       
  2519   match(iRegP);
       
  2520 
       
  2521   format %{ %}
       
  2522   interface(REG_INTER);
       
  2523 %}
       
  2524 
       
  2525 operand RthreadRegP() %{
       
  2526   constraint(ALLOC_IN_RC(Rthread_regP));
       
  2527   match(iRegP);
       
  2528 
       
  2529   format %{ %}
       
  2530   interface(REG_INTER);
       
  2531 %}
       
  2532 
       
  2533 operand IPRegP() %{
       
  2534   constraint(ALLOC_IN_RC(IP_regP));
       
  2535   match(iRegP);
       
  2536 
       
  2537   format %{ %}
       
  2538   interface(REG_INTER);
       
  2539 %}
       
  2540 
       
  2541 operand LRRegP() %{
       
  2542   constraint(ALLOC_IN_RC(LR_regP));
       
  2543   match(iRegP);
       
  2544 
       
  2545   format %{ %}
       
  2546   interface(REG_INTER);
       
  2547 %}
       
  2548 
       
  2549 operand R0RegI() %{
       
  2550   constraint(ALLOC_IN_RC(R0_regI));
       
  2551   match(iRegI);
       
  2552 
       
  2553   format %{ %}
       
  2554   interface(REG_INTER);
       
  2555 %}
       
  2556 
       
  2557 operand R1RegI() %{
       
  2558   constraint(ALLOC_IN_RC(R1_regI));
       
  2559   match(iRegI);
       
  2560 
       
  2561   format %{ %}
       
  2562   interface(REG_INTER);
       
  2563 %}
       
  2564 
       
  2565 operand R2RegI() %{
       
  2566   constraint(ALLOC_IN_RC(R2_regI));
       
  2567   match(iRegI);
       
  2568 
       
  2569   format %{ %}
       
  2570   interface(REG_INTER);
       
  2571 %}
       
  2572 
       
  2573 operand R3RegI() %{
       
  2574   constraint(ALLOC_IN_RC(R3_regI));
       
  2575   match(iRegI);
       
  2576 
       
  2577   format %{ %}
       
  2578   interface(REG_INTER);
       
  2579 %}
       
  2580 
       
  2581 #ifndef AARCH64
       
  2582 operand R12RegI() %{
       
  2583   constraint(ALLOC_IN_RC(R12_regI));
       
  2584   match(iRegI);
       
  2585 
       
  2586   format %{ %}
       
  2587   interface(REG_INTER);
       
  2588 %}
       
  2589 #endif
       
  2590 
       
  2591 // Long Register
       
  2592 operand iRegL() %{
       
  2593   constraint(ALLOC_IN_RC(long_reg));
       
  2594   match(RegL);
       
  2595 #ifdef AARCH64
       
  2596   match(iRegLd);
       
  2597 #else
       
  2598   match(R0R1RegL);
       
  2599   match(R2R3RegL);
       
  2600 #endif
       
  2601 //match(iRegLex);
       
  2602 
       
  2603   format %{ %}
       
  2604   interface(REG_INTER);
       
  2605 %}
       
  2606 
       
  2607 operand iRegLd() %{
       
  2608   constraint(ALLOC_IN_RC(long_reg_align));
       
  2609   match(iRegL); // FIXME: allows unaligned R11/R12?
       
  2610 
       
  2611   format %{ %}
       
  2612   interface(REG_INTER);
       
  2613 %}
       
  2614 
       
  2615 #ifndef AARCH64
       
  2616 // first long arg, or return value
       
  2617 operand R0R1RegL() %{
       
  2618   constraint(ALLOC_IN_RC(R0R1_regL));
       
  2619   match(iRegL);
       
  2620 
       
  2621   format %{ %}
       
  2622   interface(REG_INTER);
       
  2623 %}
       
  2624 
       
  2625 operand R2R3RegL() %{
       
  2626   constraint(ALLOC_IN_RC(R2R3_regL));
       
  2627   match(iRegL);
       
  2628 
       
  2629   format %{ %}
       
  2630   interface(REG_INTER);
       
  2631 %}
       
  2632 #endif
       
  2633 
       
  2634 // Condition Code Flag Register
       
  2635 operand flagsReg() %{
       
  2636   constraint(ALLOC_IN_RC(int_flags));
       
  2637   match(RegFlags);
       
  2638 
       
  2639   format %{ "apsr" %}
       
  2640   interface(REG_INTER);
       
  2641 %}
       
  2642 
       
  2643 // Result of compare to 0 (TST)
       
  2644 operand flagsReg_EQNELTGE() %{
       
  2645   constraint(ALLOC_IN_RC(int_flags));
       
  2646   match(RegFlags);
       
  2647 
       
  2648   format %{ "apsr_EQNELTGE" %}
       
  2649   interface(REG_INTER);
       
  2650 %}
       
  2651 
       
  2652 // Condition Code Register, unsigned comparisons.
       
  2653 operand flagsRegU() %{
       
  2654   constraint(ALLOC_IN_RC(int_flags));
       
  2655   match(RegFlags);
       
  2656 #ifdef TODO
       
  2657   match(RegFlagsP);
       
  2658 #endif
       
  2659 
       
  2660   format %{ "apsr_U" %}
       
  2661   interface(REG_INTER);
       
  2662 %}
       
  2663 
       
  2664 // Condition Code Register, pointer comparisons.
       
  2665 operand flagsRegP() %{
       
  2666   constraint(ALLOC_IN_RC(int_flags));
       
  2667   match(RegFlags);
       
  2668 
       
  2669   format %{ "apsr_P" %}
       
  2670   interface(REG_INTER);
       
  2671 %}
       
  2672 
       
  2673 // Condition Code Register, long comparisons.
       
  2674 #ifndef AARCH64
       
  2675 operand flagsRegL_LTGE() %{
       
  2676   constraint(ALLOC_IN_RC(int_flags));
       
  2677   match(RegFlags);
       
  2678 
       
  2679   format %{ "apsr_L_LTGE" %}
       
  2680   interface(REG_INTER);
       
  2681 %}
       
  2682 
       
  2683 operand flagsRegL_EQNE() %{
       
  2684   constraint(ALLOC_IN_RC(int_flags));
       
  2685   match(RegFlags);
       
  2686 
       
  2687   format %{ "apsr_L_EQNE" %}
       
  2688   interface(REG_INTER);
       
  2689 %}
       
  2690 
       
  2691 operand flagsRegL_LEGT() %{
       
  2692   constraint(ALLOC_IN_RC(int_flags));
       
  2693   match(RegFlags);
       
  2694 
       
  2695   format %{ "apsr_L_LEGT" %}
       
  2696   interface(REG_INTER);
       
  2697 %}
       
  2698 #endif
       
  2699 
       
  2700 // Condition Code Register, floating comparisons, unordered same as "less".
       
  2701 operand flagsRegF() %{
       
  2702   constraint(ALLOC_IN_RC(float_flags));
       
  2703   match(RegFlags);
       
  2704 
       
  2705   format %{ "fpscr_F" %}
       
  2706   interface(REG_INTER);
       
  2707 %}
       
  2708 
       
  2709 // Vectors
       
  2710 operand vecD() %{
       
  2711   constraint(ALLOC_IN_RC(actual_dflt_reg));
       
  2712   match(VecD);
       
  2713 
       
  2714   format %{ %}
       
  2715   interface(REG_INTER);
       
  2716 %}
       
  2717 
       
  2718 operand vecX() %{
       
  2719   constraint(ALLOC_IN_RC(vectorx_reg));
       
  2720   match(VecX);
       
  2721 
       
  2722   format %{ %}
       
  2723   interface(REG_INTER);
       
  2724 %}
       
  2725 
       
  2726 operand regD() %{
       
  2727   constraint(ALLOC_IN_RC(actual_dflt_reg));
       
  2728   match(RegD);
       
  2729   match(regD_low);
       
  2730 
       
  2731   format %{ %}
       
  2732   interface(REG_INTER);
       
  2733 %}
       
  2734 
       
  2735 operand regF() %{
       
  2736   constraint(ALLOC_IN_RC(sflt_reg));
       
  2737   match(RegF);
       
  2738 
       
  2739   format %{ %}
       
  2740   interface(REG_INTER);
       
  2741 %}
       
  2742 
       
  2743 operand regD_low() %{
       
  2744   constraint(ALLOC_IN_RC(dflt_low_reg));
       
  2745   match(RegD);
       
  2746 
       
  2747   format %{ %}
       
  2748   interface(REG_INTER);
       
  2749 %}
       
  2750 
       
  2751 // Special Registers
       
  2752 
       
  2753 // Method Register
       
  2754 operand inline_cache_regP(iRegP reg) %{
       
  2755   constraint(ALLOC_IN_RC(Ricklass_regP));
       
  2756   match(reg);
       
  2757   format %{ %}
       
  2758   interface(REG_INTER);
       
  2759 %}
       
  2760 
       
  2761 operand interpreter_method_oop_regP(iRegP reg) %{
       
  2762   constraint(ALLOC_IN_RC(Rmethod_regP));
       
  2763   match(reg);
       
  2764   format %{ %}
       
  2765   interface(REG_INTER);
       
  2766 %}
       
  2767 
       
  2768 
       
  2769 //----------Complex Operands---------------------------------------------------
       
  2770 // Indirect Memory Reference
       
  2771 operand indirect(sp_ptr_RegP reg) %{
       
  2772   constraint(ALLOC_IN_RC(sp_ptr_reg));
       
  2773   match(reg);
       
  2774 
       
  2775   op_cost(100);
       
  2776   format %{ "[$reg]" %}
       
  2777   interface(MEMORY_INTER) %{
       
  2778     base($reg);
       
  2779 #ifdef AARCH64
       
  2780     index(0xff); // 0xff => no index
       
  2781 #else
       
  2782     index(0xf); // PC => no index
       
  2783 #endif
       
  2784     scale(0x0);
       
  2785     disp(0x0);
       
  2786   %}
       
  2787 %}
       
  2788 
       
  2789 #ifdef AARCH64
       
  2790 // Indirect with scaled*1 uimm12 offset
       
  2791 operand indOffsetU12ScaleB(sp_ptr_RegP reg, immUL12 offset) %{
       
  2792   constraint(ALLOC_IN_RC(sp_ptr_reg));
       
  2793   match(AddP reg offset);
       
  2794 
       
  2795   op_cost(100);
       
  2796   format %{ "[$reg + $offset]" %}
       
  2797   interface(MEMORY_INTER) %{
       
  2798     base($reg);
       
  2799 #ifdef AARCH64
       
  2800     index(0xff); // 0xff => no index
       
  2801 #else
       
  2802     index(0xf); // PC => no index
       
  2803 #endif
       
  2804     scale(0x0);
       
  2805     disp($offset);
       
  2806   %}
       
  2807 %}
       
  2808 
       
  2809 // Indirect with scaled*2 uimm12 offset
       
  2810 operand indOffsetU12ScaleS(sp_ptr_RegP reg, immUL12x2 offset) %{
       
  2811   constraint(ALLOC_IN_RC(sp_ptr_reg));
       
  2812   match(AddP reg offset);
       
  2813 
       
  2814   op_cost(100);
       
  2815   format %{ "[$reg + $offset]" %}
       
  2816   interface(MEMORY_INTER) %{
       
  2817     base($reg);
       
  2818 #ifdef AARCH64
       
  2819     index(0xff); // 0xff => no index
       
  2820 #else
       
  2821     index(0xf); // PC => no index
       
  2822 #endif
       
  2823     scale(0x0);
       
  2824     disp($offset);
       
  2825   %}
       
  2826 %}
       
  2827 
       
  2828 // Indirect with scaled*4 uimm12 offset
       
  2829 operand indOffsetU12ScaleI(sp_ptr_RegP reg, immUL12x4 offset) %{
       
  2830   constraint(ALLOC_IN_RC(sp_ptr_reg));
       
  2831   match(AddP reg offset);
       
  2832 
       
  2833   op_cost(100);
       
  2834   format %{ "[$reg + $offset]" %}
       
  2835   interface(MEMORY_INTER) %{
       
  2836     base($reg);
       
  2837 #ifdef AARCH64
       
  2838     index(0xff); // 0xff => no index
       
  2839 #else
       
  2840     index(0xf); // PC => no index
       
  2841 #endif
       
  2842     scale(0x0);
       
  2843     disp($offset);
       
  2844   %}
       
  2845 %}
       
  2846 
       
  2847 // Indirect with scaled*8 uimm12 offset
       
  2848 operand indOffsetU12ScaleL(sp_ptr_RegP reg, immUL12x8 offset) %{
       
  2849   constraint(ALLOC_IN_RC(sp_ptr_reg));
       
  2850   match(AddP reg offset);
       
  2851 
       
  2852   op_cost(100);
       
  2853   format %{ "[$reg + $offset]" %}
       
  2854   interface(MEMORY_INTER) %{
       
  2855     base($reg);
       
  2856 #ifdef AARCH64
       
  2857     index(0xff); // 0xff => no index
       
  2858 #else
       
  2859     index(0xf); // PC => no index
       
  2860 #endif
       
  2861     scale(0x0);
       
  2862     disp($offset);
       
  2863   %}
       
  2864 %}
       
  2865 
       
  2866 // Indirect with scaled*16 uimm12 offset
       
  2867 operand indOffsetU12ScaleQ(sp_ptr_RegP reg, immUL12x16 offset) %{
       
  2868   constraint(ALLOC_IN_RC(sp_ptr_reg));
       
  2869   match(AddP reg offset);
       
  2870 
       
  2871   op_cost(100);
       
  2872   format %{ "[$reg + $offset]" %}
       
  2873   interface(MEMORY_INTER) %{
       
  2874     base($reg);
       
  2875 #ifdef AARCH64
       
  2876     index(0xff); // 0xff => no index
       
  2877 #else
       
  2878     index(0xf); // PC => no index
       
  2879 #endif
       
  2880     scale(0x0);
       
  2881     disp($offset);
       
  2882   %}
       
  2883 %}
       
  2884 
       
  2885 #else // ! AARCH64
       
  2886 
       
  2887 // Indirect with Offset in ]-4096, 4096[
       
  2888 operand indOffset12(sp_ptr_RegP reg, immI12 offset) %{
       
  2889   constraint(ALLOC_IN_RC(sp_ptr_reg));
       
  2890   match(AddP reg offset);
       
  2891 
       
  2892   op_cost(100);
       
  2893   format %{ "[$reg + $offset]" %}
       
  2894   interface(MEMORY_INTER) %{
       
  2895     base($reg);
       
  2896 #ifdef AARCH64
       
  2897     index(0xff); // 0xff => no index
       
  2898 #else
       
  2899     index(0xf); // PC => no index
       
  2900 #endif
       
  2901     scale(0x0);
       
  2902     disp($offset);
       
  2903   %}
       
  2904 %}
       
  2905 
       
  2906 // Indirect with offset for float load/store
       
  2907 operand indOffsetFP(sp_ptr_RegP reg, immIFP offset) %{
       
  2908   constraint(ALLOC_IN_RC(sp_ptr_reg));
       
  2909   match(AddP reg offset);
       
  2910 
       
  2911   op_cost(100);
       
  2912   format %{ "[$reg + $offset]" %}
       
  2913   interface(MEMORY_INTER) %{
       
  2914     base($reg);
       
  2915 #ifdef AARCH64
       
  2916     index(0xff); // 0xff => no index
       
  2917 #else
       
  2918     index(0xf); // PC => no index
       
  2919 #endif
       
  2920     scale(0x0);
       
  2921     disp($offset);
       
  2922   %}
       
  2923 %}
       
  2924 
       
  2925 // Indirect with Offset for half and double words
       
  2926 operand indOffsetHD(sp_ptr_RegP reg, immIHD offset) %{
       
  2927   constraint(ALLOC_IN_RC(sp_ptr_reg));
       
  2928   match(AddP reg offset);
       
  2929 
       
  2930   op_cost(100);
       
  2931   format %{ "[$reg + $offset]" %}
       
  2932   interface(MEMORY_INTER) %{
       
  2933     base($reg);
       
  2934 #ifdef AARCH64
       
  2935     index(0xff); // 0xff => no index
       
  2936 #else
       
  2937     index(0xf); // PC => no index
       
  2938 #endif
       
  2939     scale(0x0);
       
  2940     disp($offset);
       
  2941   %}
       
  2942 %}
       
  2943 
       
  2944 // Indirect with Offset and Offset+4 in ]-1024, 1024[
       
  2945 operand indOffsetFPx2(sp_ptr_RegP reg, immX10x2 offset) %{
       
  2946   constraint(ALLOC_IN_RC(sp_ptr_reg));
       
  2947   match(AddP reg offset);
       
  2948 
       
  2949   op_cost(100);
       
  2950   format %{ "[$reg + $offset]" %}
       
  2951   interface(MEMORY_INTER) %{
       
  2952     base($reg);
       
  2953 #ifdef AARCH64
       
  2954     index(0xff); // 0xff => no index
       
  2955 #else
       
  2956     index(0xf); // PC => no index
       
  2957 #endif
       
  2958     scale(0x0);
       
  2959     disp($offset);
       
  2960   %}
       
  2961 %}
       
  2962 
       
  2963 // Indirect with Offset and Offset+4 in ]-4096, 4096[
       
  2964 operand indOffset12x2(sp_ptr_RegP reg, immI12x2 offset) %{
       
  2965   constraint(ALLOC_IN_RC(sp_ptr_reg));
       
  2966   match(AddP reg offset);
       
  2967 
       
  2968   op_cost(100);
       
  2969   format %{ "[$reg + $offset]" %}
       
  2970   interface(MEMORY_INTER) %{
       
  2971     base($reg);
       
  2972 #ifdef AARCH64
       
  2973     index(0xff); // 0xff => no index
       
  2974 #else
       
  2975     index(0xf); // PC => no index
       
  2976 #endif
       
  2977     scale(0x0);
       
  2978     disp($offset);
       
  2979   %}
       
  2980 %}
       
  2981 #endif // !AARCH64
       
  2982 
       
  2983 // Indirect with Register Index
       
  2984 operand indIndex(iRegP addr, iRegX index) %{
       
  2985   constraint(ALLOC_IN_RC(ptr_reg));
       
  2986   match(AddP addr index);
       
  2987 
       
  2988   op_cost(100);
       
  2989   format %{ "[$addr + $index]" %}
       
  2990   interface(MEMORY_INTER) %{
       
  2991     base($addr);
       
  2992     index($index);
       
  2993     scale(0x0);
       
  2994     disp(0x0);
       
  2995   %}
       
  2996 %}
       
  2997 
       
  2998 #ifdef AARCH64
       
  2999 // Indirect Memory Times Scale Plus Index Register
       
  3000 operand indIndexScaleS(iRegP addr, iRegX index, immI_1 scale) %{
       
  3001   constraint(ALLOC_IN_RC(ptr_reg));
       
  3002   match(AddP addr (LShiftX index scale));
       
  3003 
       
  3004   op_cost(100);
       
  3005   format %{"[$addr + $index << $scale]" %}
       
  3006   interface(MEMORY_INTER) %{
       
  3007     base($addr);
       
  3008     index($index);
       
  3009     scale($scale);
       
  3010     disp(0x0);
       
  3011   %}
       
  3012 %}
       
  3013 
       
  3014 // Indirect Memory Times Scale Plus 32-bit Index Register
       
  3015 operand indIndexIScaleS(iRegP addr, iRegI index, immI_1 scale) %{
       
  3016   constraint(ALLOC_IN_RC(ptr_reg));
       
  3017   match(AddP addr (LShiftX (ConvI2L index) scale));
       
  3018 
       
  3019   op_cost(100);
       
  3020   format %{"[$addr + $index.w << $scale]" %}
       
  3021   interface(MEMORY_INTER) %{
       
  3022     base($addr);
       
  3023     index($index);
       
  3024     scale($scale);
       
  3025     disp(0x7fffffff); // sxtw
       
  3026   %}
       
  3027 %}
       
  3028 
       
  3029 // Indirect Memory Times Scale Plus Index Register
       
  3030 operand indIndexScaleI(iRegP addr, iRegX index, immI_2 scale) %{
       
  3031   constraint(ALLOC_IN_RC(ptr_reg));
       
  3032   match(AddP addr (LShiftX index scale));
       
  3033 
       
  3034   op_cost(100);
       
  3035   format %{"[$addr + $index << $scale]" %}
       
  3036   interface(MEMORY_INTER) %{
       
  3037     base($addr);
       
  3038     index($index);
       
  3039     scale($scale);
       
  3040     disp(0x0);
       
  3041   %}
       
  3042 %}
       
  3043 
       
  3044 // Indirect Memory Times Scale Plus 32-bit Index Register
       
  3045 operand indIndexIScaleI(iRegP addr, iRegI index, immI_2 scale) %{
       
  3046   constraint(ALLOC_IN_RC(ptr_reg));
       
  3047   match(AddP addr (LShiftX (ConvI2L index) scale));
       
  3048 
       
  3049   op_cost(100);
       
  3050   format %{"[$addr + $index.w << $scale]" %}
       
  3051   interface(MEMORY_INTER) %{
       
  3052     base($addr);
       
  3053     index($index);
       
  3054     scale($scale);
       
  3055     disp(0x7fffffff); // sxtw
       
  3056   %}
       
  3057 %}
       
  3058 
       
  3059 // Indirect Memory Times Scale Plus Index Register
       
  3060 operand indIndexScaleL(iRegP addr, iRegX index, immI_3 scale) %{
       
  3061   constraint(ALLOC_IN_RC(ptr_reg));
       
  3062   match(AddP addr (LShiftX index scale));
       
  3063 
       
  3064   op_cost(100);
       
  3065   format %{"[$addr + $index << $scale]" %}
       
  3066   interface(MEMORY_INTER) %{
       
  3067     base($addr);
       
  3068     index($index);
       
  3069     scale($scale);
       
  3070     disp(0x0);
       
  3071   %}
       
  3072 %}
       
  3073 
       
  3074 // Indirect Memory Times Scale Plus 32-bit Index Register
       
  3075 operand indIndexIScaleL(iRegP addr, iRegI index, immI_3 scale) %{
       
  3076   constraint(ALLOC_IN_RC(ptr_reg));
       
  3077   match(AddP addr (LShiftX (ConvI2L index) scale));
       
  3078 
       
  3079   op_cost(100);
       
  3080   format %{"[$addr + $index.w << $scale]" %}
       
  3081   interface(MEMORY_INTER) %{
       
  3082     base($addr);
       
  3083     index($index);
       
  3084     scale($scale);
       
  3085     disp(0x7fffffff); // sxtw
       
  3086   %}
       
  3087 %}
       
  3088 
       
  3089 // Indirect Memory Times Scale Plus Index Register
       
  3090 operand indIndexScaleQ(iRegP addr, iRegX index, immI_4 scale) %{
       
  3091   constraint(ALLOC_IN_RC(ptr_reg));
       
  3092   match(AddP addr (LShiftX index scale));
       
  3093 
       
  3094   op_cost(100);
       
  3095   format %{"[$addr + $index << $scale]" %}
       
  3096   interface(MEMORY_INTER) %{
       
  3097     base($addr);
       
  3098     index($index);
       
  3099     scale($scale);
       
  3100     disp(0x0);
       
  3101   %}
       
  3102 %}
       
  3103 
       
  3104 // Indirect Memory Times Scale Plus 32-bit Index Register
       
  3105 operand indIndexIScaleQ(iRegP addr, iRegI index, immI_4 scale) %{
       
  3106   constraint(ALLOC_IN_RC(ptr_reg));
       
  3107   match(AddP addr (LShiftX (ConvI2L index) scale));
       
  3108 
       
  3109   op_cost(100);
       
  3110   format %{"[$addr + $index.w << $scale]" %}
       
  3111   interface(MEMORY_INTER) %{
       
  3112     base($addr);
       
  3113     index($index);
       
  3114     scale($scale);
       
  3115     disp(0x7fffffff); // sxtw
       
  3116   %}
       
  3117 %}
       
  3118 #else
       
  3119 // Indirect Memory Times Scale Plus Index Register
       
  3120 operand indIndexScale(iRegP addr, iRegX index, immU5 scale) %{
       
  3121   constraint(ALLOC_IN_RC(ptr_reg));
       
  3122   match(AddP addr (LShiftX index scale));
       
  3123 
       
  3124   op_cost(100);
       
  3125   format %{"[$addr + $index << $scale]" %}
       
  3126   interface(MEMORY_INTER) %{
       
  3127     base($addr);
       
  3128     index($index);
       
  3129     scale($scale);
       
  3130     disp(0x0);
       
  3131   %}
       
  3132 %}
       
  3133 #endif
       
  3134 
       
  3135 // Operands for expressing Control Flow
       
  3136 // NOTE:  Label is a predefined operand which should not be redefined in
       
  3137 //        the AD file.  It is generically handled within the ADLC.
       
  3138 
       
  3139 //----------Conditional Branch Operands----------------------------------------
       
  3140 // Comparison Op  - This is the operation of the comparison, and is limited to
       
  3141 //                  the following set of codes:
       
  3142 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
       
  3143 //
       
  3144 // Other attributes of the comparison, such as unsignedness, are specified
       
  3145 // by the comparison instruction that sets a condition code flags register.
       
  3146 // That result is represented by a flags operand whose subtype is appropriate
       
  3147 // to the unsignedness (etc.) of the comparison.
       
  3148 //
       
  3149 // Later, the instruction which matches both the Comparison Op (a Bool) and
       
  3150 // the flags (produced by the Cmp) specifies the coding of the comparison op
       
  3151 // by matching a specific subtype of Bool operand below, such as cmpOpU.
       
  3152 
       
  3153 operand cmpOp() %{
       
  3154   match(Bool);
       
  3155 
       
  3156   format %{ "" %}
       
  3157   interface(COND_INTER) %{
       
  3158     equal(0x0);
       
  3159     not_equal(0x1);
       
  3160     less(0xb);
       
  3161     greater_equal(0xa);
       
  3162     less_equal(0xd);
       
  3163     greater(0xc);
       
  3164     overflow(0x0); // unsupported/unimplemented
       
  3165     no_overflow(0x0); // unsupported/unimplemented
       
  3166   %}
       
  3167 %}
       
  3168 
       
  3169 // integer comparison with 0, signed
       
  3170 operand cmpOp0() %{
       
  3171   match(Bool);
       
  3172 
       
  3173   format %{ "" %}
       
  3174   interface(COND_INTER) %{
       
  3175     equal(0x0);
       
  3176     not_equal(0x1);
       
  3177     less(0x4);
       
  3178     greater_equal(0x5);
       
  3179     less_equal(0xd); // unsupported
       
  3180     greater(0xc); // unsupported
       
  3181     overflow(0x0); // unsupported/unimplemented
       
  3182     no_overflow(0x0); // unsupported/unimplemented
       
  3183   %}
       
  3184 %}
       
  3185 
       
  3186 // Comparison Op, unsigned
       
  3187 operand cmpOpU() %{
       
  3188   match(Bool);
       
  3189 
       
  3190   format %{ "u" %}
       
  3191   interface(COND_INTER) %{
       
  3192     equal(0x0);
       
  3193     not_equal(0x1);
       
  3194     less(0x3);
       
  3195     greater_equal(0x2);
       
  3196     less_equal(0x9);
       
  3197     greater(0x8);
       
  3198     overflow(0x0); // unsupported/unimplemented
       
  3199     no_overflow(0x0); // unsupported/unimplemented
       
  3200   %}
       
  3201 %}
       
  3202 
       
  3203 // Comparison Op, pointer (same as unsigned)
       
  3204 operand cmpOpP() %{
       
  3205   match(Bool);
       
  3206 
       
  3207   format %{ "p" %}
       
  3208   interface(COND_INTER) %{
       
  3209     equal(0x0);
       
  3210     not_equal(0x1);
       
  3211     less(0x3);
       
  3212     greater_equal(0x2);
       
  3213     less_equal(0x9);
       
  3214     greater(0x8);
       
  3215     overflow(0x0); // unsupported/unimplemented
       
  3216     no_overflow(0x0); // unsupported/unimplemented
       
  3217   %}
       
  3218 %}
       
  3219 
       
  3220 operand cmpOpL() %{
       
  3221   match(Bool);
       
  3222 
       
  3223   format %{ "L" %}
       
  3224   interface(COND_INTER) %{
       
  3225     equal(0x0);
       
  3226     not_equal(0x1);
       
  3227     less(0xb);
       
  3228     greater_equal(0xa);
       
  3229     less_equal(0xd);
       
  3230     greater(0xc);
       
  3231     overflow(0x0); // unsupported/unimplemented
       
  3232     no_overflow(0x0); // unsupported/unimplemented
       
  3233   %}
       
  3234 %}
       
  3235 
       
  3236 operand cmpOpL_commute() %{
       
  3237   match(Bool);
       
  3238 
       
  3239   format %{ "L" %}
       
  3240   interface(COND_INTER) %{
       
  3241     equal(0x0);
       
  3242     not_equal(0x1);
       
  3243     less(0xc);
       
  3244     greater_equal(0xd);
       
  3245     less_equal(0xa);
       
  3246     greater(0xb);
       
  3247     overflow(0x0); // unsupported/unimplemented
       
  3248     no_overflow(0x0); // unsupported/unimplemented
       
  3249   %}
       
  3250 %}
       
  3251 
       
  3252 //----------OPERAND CLASSES----------------------------------------------------
       
  3253 // Operand Classes are groups of operands that are used to simplify
       
  3254 // instruction definitions by not requiring the AD writer to specify separate
       
  3255 // instructions for every form of operand when the instruction accepts
       
  3256 // multiple operand types with the same basic encoding and format.  The classic
       
  3257 // case of this is memory operands.
       
  3258 #ifdef AARCH64
       
  3259 opclass memoryB(indirect, indIndex, indOffsetU12ScaleB);
       
  3260 opclass memoryS(indirect, indIndex, indIndexScaleS, indIndexIScaleS, indOffsetU12ScaleS);
       
  3261 opclass memoryI(indirect, indIndex, indIndexScaleI, indIndexIScaleI, indOffsetU12ScaleI);
       
  3262 opclass memoryL(indirect, indIndex, indIndexScaleL, indIndexIScaleL, indOffsetU12ScaleL);
       
  3263 opclass memoryP(indirect, indIndex, indIndexScaleL, indIndexIScaleL, indOffsetU12ScaleL);
       
  3264 opclass memoryQ(indirect, indIndex, indIndexScaleQ, indIndexIScaleQ, indOffsetU12ScaleQ);
       
  3265 opclass memoryF(indirect, indIndex, indIndexScaleI, indIndexIScaleI, indOffsetU12ScaleI);
       
  3266 opclass memoryD(indirect, indIndex, indIndexScaleL, indIndexIScaleL, indOffsetU12ScaleL);
       
  3267 
       
  3268 opclass memoryScaledS(indIndexScaleS, indIndexIScaleS);
       
  3269 opclass memoryScaledI(indIndexScaleI, indIndexIScaleI);
       
  3270 opclass memoryScaledL(indIndexScaleL, indIndexIScaleL);
       
  3271 opclass memoryScaledP(indIndexScaleL, indIndexIScaleL);
       
  3272 opclass memoryScaledQ(indIndexScaleQ, indIndexIScaleQ);
       
  3273 opclass memoryScaledF(indIndexScaleI, indIndexIScaleI);
       
  3274 opclass memoryScaledD(indIndexScaleL, indIndexIScaleL);
       
  3275 // when ldrex/strex is used:
       
  3276 opclass memoryex ( indirect );
       
  3277 opclass indIndexMemory( indIndex );
       
  3278 opclass memoryvld ( indirect /* , write back mode not implemented */ );
       
  3279 
       
  3280 #else
       
  3281 
       
  3282 opclass memoryI ( indirect, indOffset12, indIndex, indIndexScale );
       
  3283 opclass memoryP ( indirect, indOffset12, indIndex, indIndexScale );
       
  3284 opclass memoryF ( indirect, indOffsetFP );
       
  3285 opclass memoryF2 ( indirect, indOffsetFPx2 );
       
  3286 opclass memoryD ( indirect, indOffsetFP );
       
  3287 opclass memoryfp( indirect, indOffsetFP );
       
  3288 opclass memoryB ( indirect, indIndex, indOffsetHD );
       
  3289 opclass memoryS ( indirect, indIndex, indOffsetHD );
       
  3290 opclass memoryL ( indirect, indIndex, indOffsetHD );
       
  3291 
       
  3292 opclass memoryScaledI(indIndexScale);
       
  3293 opclass memoryScaledP(indIndexScale);
       
  3294 
       
  3295 // when ldrex/strex is used:
       
  3296 opclass memoryex ( indirect );
       
  3297 opclass indIndexMemory( indIndex );
       
  3298 opclass memorylong ( indirect, indOffset12x2 );
       
  3299 opclass memoryvld ( indirect /* , write back mode not implemented */ );
       
  3300 #endif
       
  3301 
       
  3302 //----------PIPELINE-----------------------------------------------------------
       
  3303 pipeline %{
       
  3304 
       
  3305 //----------ATTRIBUTES---------------------------------------------------------
       
  3306 attributes %{
       
  3307   fixed_size_instructions;           // Fixed size instructions
       
  3308   max_instructions_per_bundle = 4;   // Up to 4 instructions per bundle
       
  3309   instruction_unit_size = 4;         // An instruction is 4 bytes long
       
  3310   instruction_fetch_unit_size = 16;  // The processor fetches one line
       
  3311   instruction_fetch_units = 1;       // of 16 bytes
       
  3312 
       
  3313   // List of nop instructions
       
  3314   nops( Nop_A0, Nop_A1, Nop_MS, Nop_FA, Nop_BR );
       
  3315 %}
       
  3316 
       
  3317 //----------RESOURCES----------------------------------------------------------
       
  3318 // Resources are the functional units available to the machine
       
  3319 resources(A0, A1, MS, BR, FA, FM, IDIV, FDIV, IALU = A0 | A1);
       
  3320 
       
  3321 //----------PIPELINE DESCRIPTION-----------------------------------------------
       
  3322 // Pipeline Description specifies the stages in the machine's pipeline
       
  3323 
       
  3324 pipe_desc(A, P, F, B, I, J, S, R, E, C, M, W, X, T, D);
       
  3325 
       
  3326 //----------PIPELINE CLASSES---------------------------------------------------
       
  3327 // Pipeline Classes describe the stages in which input and output are
       
  3328 // referenced by the hardware pipeline.
       
  3329 
       
  3330 // Integer ALU reg-reg operation
       
  3331 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
       
  3332     single_instruction;
       
  3333     dst   : E(write);
       
  3334     src1  : R(read);
       
  3335     src2  : R(read);
       
  3336     IALU  : R;
       
  3337 %}
       
  3338 
       
  3339 // Integer ALU reg-reg long operation
       
  3340 pipe_class ialu_reg_reg_2(iRegL dst, iRegL src1, iRegL src2) %{
       
  3341     instruction_count(2);
       
  3342     dst   : E(write);
       
  3343     src1  : R(read);
       
  3344     src2  : R(read);
       
  3345     IALU  : R;
       
  3346     IALU  : R;
       
  3347 %}
       
  3348 
       
  3349 // Integer ALU reg-reg long dependent operation
       
  3350 pipe_class ialu_reg_reg_2_dep(iRegL dst, iRegL src1, iRegL src2, flagsReg cr) %{
       
  3351     instruction_count(1); multiple_bundles;
       
  3352     dst   : E(write);
       
  3353     src1  : R(read);
       
  3354     src2  : R(read);
       
  3355     cr    : E(write);
       
  3356     IALU  : R(2);
       
  3357 %}
       
  3358 
       
  3359 // Integer ALU reg-imm operaion
       
  3360 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) %{
       
  3361     single_instruction;
       
  3362     dst   : E(write);
       
  3363     src1  : R(read);
       
  3364     IALU  : R;
       
  3365 %}
       
  3366 
       
  3367 // Integer ALU reg-reg operation with condition code
       
  3368 pipe_class ialu_cc_reg_reg(iRegI dst, iRegI src1, iRegI src2, flagsReg cr) %{
       
  3369     single_instruction;
       
  3370     dst   : E(write);
       
  3371     cr    : E(write);
       
  3372     src1  : R(read);
       
  3373     src2  : R(read);
       
  3374     IALU  : R;
       
  3375 %}
       
  3376 
       
  3377 // Integer ALU zero-reg operation
       
  3378 pipe_class ialu_zero_reg(iRegI dst, immI0 zero, iRegI src2) %{
       
  3379     single_instruction;
       
  3380     dst   : E(write);
       
  3381     src2  : R(read);
       
  3382     IALU  : R;
       
  3383 %}
       
  3384 
       
  3385 // Integer ALU zero-reg operation with condition code only
       
  3386 pipe_class ialu_cconly_zero_reg(flagsReg cr, iRegI src) %{
       
  3387     single_instruction;
       
  3388     cr    : E(write);
       
  3389     src   : R(read);
       
  3390     IALU  : R;
       
  3391 %}
       
  3392 
       
  3393 // Integer ALU reg-reg operation with condition code only
       
  3394 pipe_class ialu_cconly_reg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
       
  3395     single_instruction;
       
  3396     cr    : E(write);
       
  3397     src1  : R(read);
       
  3398     src2  : R(read);
       
  3399     IALU  : R;
       
  3400 %}
       
  3401 
       
  3402 // Integer ALU reg-imm operation with condition code only
       
  3403 pipe_class ialu_cconly_reg_imm(flagsReg cr, iRegI src1) %{
       
  3404     single_instruction;
       
  3405     cr    : E(write);
       
  3406     src1  : R(read);
       
  3407     IALU  : R;
       
  3408 %}
       
  3409 
       
  3410 // Integer ALU reg-reg-zero operation with condition code only
       
  3411 pipe_class ialu_cconly_reg_reg_zero(flagsReg cr, iRegI src1, iRegI src2, immI0 zero) %{
       
  3412     single_instruction;
       
  3413     cr    : E(write);
       
  3414     src1  : R(read);
       
  3415     src2  : R(read);
       
  3416     IALU  : R;
       
  3417 %}
       
  3418 
       
  3419 // Integer ALU reg-imm-zero operation with condition code only
       
  3420 pipe_class ialu_cconly_reg_imm_zero(flagsReg cr, iRegI src1, immI0 zero) %{
       
  3421     single_instruction;
       
  3422     cr    : E(write);
       
  3423     src1  : R(read);
       
  3424     IALU  : R;
       
  3425 %}
       
  3426 
       
  3427 // Integer ALU reg-reg operation with condition code, src1 modified
       
  3428 pipe_class ialu_cc_rwreg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
       
  3429     single_instruction;
       
  3430     cr    : E(write);
       
  3431     src1  : E(write);
       
  3432     src1  : R(read);
       
  3433     src2  : R(read);
       
  3434     IALU  : R;
       
  3435 %}
       
  3436 
       
  3437 pipe_class cmpL_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg cr ) %{
       
  3438     multiple_bundles;
       
  3439     dst   : E(write)+4;
       
  3440     cr    : E(write);
       
  3441     src1  : R(read);
       
  3442     src2  : R(read);
       
  3443     IALU  : R(3);
       
  3444     BR    : R(2);
       
  3445 %}
       
  3446 
       
  3447 // Integer ALU operation
       
  3448 pipe_class ialu_none(iRegI dst) %{
       
  3449     single_instruction;
       
  3450     dst   : E(write);
       
  3451     IALU  : R;
       
  3452 %}
       
  3453 
       
  3454 // Integer ALU reg operation
       
  3455 pipe_class ialu_reg(iRegI dst, iRegI src) %{
       
  3456     single_instruction; may_have_no_code;
       
  3457     dst   : E(write);
       
  3458     src   : R(read);
       
  3459     IALU  : R;
       
  3460 %}
       
  3461 
       
  3462 // Integer ALU reg conditional operation
       
  3463 // This instruction has a 1 cycle stall, and cannot execute
       
  3464 // in the same cycle as the instruction setting the condition
       
  3465 // code. We kludge this by pretending to read the condition code
       
  3466 // 1 cycle earlier, and by marking the functional units as busy
       
  3467 // for 2 cycles with the result available 1 cycle later than
       
  3468 // is really the case.
       
  3469 pipe_class ialu_reg_flags( iRegI op2_out, iRegI op2_in, iRegI op1, flagsReg cr ) %{
       
  3470     single_instruction;
       
  3471     op2_out : C(write);
       
  3472     op1     : R(read);
       
  3473     cr      : R(read);       // This is really E, with a 1 cycle stall
       
  3474     BR      : R(2);
       
  3475     MS      : R(2);
       
  3476 %}
       
  3477 
       
  3478 // Integer ALU reg operation
       
  3479 pipe_class ialu_move_reg_L_to_I(iRegI dst, iRegL src) %{
       
  3480     single_instruction; may_have_no_code;
       
  3481     dst   : E(write);
       
  3482     src   : R(read);
       
  3483     IALU  : R;
       
  3484 %}
       
  3485 pipe_class ialu_move_reg_I_to_L(iRegL dst, iRegI src) %{
       
  3486     single_instruction; may_have_no_code;
       
  3487     dst   : E(write);
       
  3488     src   : R(read);
       
  3489     IALU  : R;
       
  3490 %}
       
  3491 
       
  3492 // Two integer ALU reg operations
       
  3493 pipe_class ialu_reg_2(iRegL dst, iRegL src) %{
       
  3494     instruction_count(2);
       
  3495     dst   : E(write);
       
  3496     src   : R(read);
       
  3497     A0    : R;
       
  3498     A1    : R;
       
  3499 %}
       
  3500 
       
  3501 // Two integer ALU reg operations
       
  3502 pipe_class ialu_move_reg_L_to_L(iRegL dst, iRegL src) %{
       
  3503     instruction_count(2); may_have_no_code;
       
  3504     dst   : E(write);
       
  3505     src   : R(read);
       
  3506     A0    : R;
       
  3507     A1    : R;
       
  3508 %}
       
  3509 
       
  3510 // Integer ALU imm operation
       
  3511 pipe_class ialu_imm(iRegI dst) %{
       
  3512     single_instruction;
       
  3513     dst   : E(write);
       
  3514     IALU  : R;
       
  3515 %}
       
  3516 
       
  3517 pipe_class ialu_imm_n(iRegI dst) %{
       
  3518     single_instruction;
       
  3519     dst   : E(write);
       
  3520     IALU  : R;
       
  3521 %}
       
  3522 
       
  3523 // Integer ALU reg-reg with carry operation
       
  3524 pipe_class ialu_reg_reg_cy(iRegI dst, iRegI src1, iRegI src2, iRegI cy) %{
       
  3525     single_instruction;
       
  3526     dst   : E(write);
       
  3527     src1  : R(read);
       
  3528     src2  : R(read);
       
  3529     IALU  : R;
       
  3530 %}
       
  3531 
       
  3532 // Integer ALU cc operation
       
  3533 pipe_class ialu_cc(iRegI dst, flagsReg cc) %{
       
  3534     single_instruction;
       
  3535     dst   : E(write);
       
  3536     cc    : R(read);
       
  3537     IALU  : R;
       
  3538 %}
       
  3539 
       
  3540 // Integer ALU cc / second IALU operation
       
  3541 pipe_class ialu_reg_ialu( iRegI dst, iRegI src ) %{
       
  3542     instruction_count(1); multiple_bundles;
       
  3543     dst   : E(write)+1;
       
  3544     src   : R(read);
       
  3545     IALU  : R;
       
  3546 %}
       
  3547 
       
  3548 // Integer ALU cc / second IALU operation
       
  3549 pipe_class ialu_reg_reg_ialu( iRegI dst, iRegI p, iRegI q ) %{
       
  3550     instruction_count(1); multiple_bundles;
       
  3551     dst   : E(write)+1;
       
  3552     p     : R(read);
       
  3553     q     : R(read);
       
  3554     IALU  : R;
       
  3555 %}
       
  3556 
       
  3557 // Integer ALU hi-lo-reg operation
       
  3558 pipe_class ialu_hi_lo_reg(iRegI dst, immI src) %{
       
  3559     instruction_count(1); multiple_bundles;
       
  3560     dst   : E(write)+1;
       
  3561     IALU  : R(2);
       
  3562 %}
       
  3563 
       
  3564 // Long Constant
       
  3565 pipe_class loadConL( iRegL dst, immL src ) %{
       
  3566     instruction_count(2); multiple_bundles;
       
  3567     dst   : E(write)+1;
       
  3568     IALU  : R(2);
       
  3569     IALU  : R(2);
       
  3570 %}
       
  3571 
       
  3572 // Pointer Constant
       
  3573 pipe_class loadConP( iRegP dst, immP src ) %{
       
  3574     instruction_count(0); multiple_bundles;
       
  3575     fixed_latency(6);
       
  3576 %}
       
  3577 
       
  3578 // Polling Address
       
  3579 pipe_class loadConP_poll( iRegP dst, immP_poll src ) %{
       
  3580     dst   : E(write);
       
  3581     IALU  : R;
       
  3582 %}
       
  3583 
       
  3584 // Long Constant small
       
  3585 pipe_class loadConLlo( iRegL dst, immL src ) %{
       
  3586     instruction_count(2);
       
  3587     dst   : E(write);
       
  3588     IALU  : R;
       
  3589     IALU  : R;
       
  3590 %}
       
  3591 
       
  3592 // [PHH] This is wrong for 64-bit.  See LdImmF/D.
       
  3593 pipe_class loadConFD(regF dst, immF src, iRegP tmp) %{
       
  3594     instruction_count(1); multiple_bundles;
       
  3595     src   : R(read);
       
  3596     dst   : M(write)+1;
       
  3597     IALU  : R;
       
  3598     MS    : E;
       
  3599 %}
       
  3600 
       
  3601 // Integer ALU nop operation
       
  3602 pipe_class ialu_nop() %{
       
  3603     single_instruction;
       
  3604     IALU  : R;
       
  3605 %}
       
  3606 
       
  3607 // Integer ALU nop operation
       
  3608 pipe_class ialu_nop_A0() %{
       
  3609     single_instruction;
       
  3610     A0    : R;
       
  3611 %}
       
  3612 
       
  3613 // Integer ALU nop operation
       
  3614 pipe_class ialu_nop_A1() %{
       
  3615     single_instruction;
       
  3616     A1    : R;
       
  3617 %}
       
  3618 
       
  3619 // Integer Multiply reg-reg operation
       
  3620 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
       
  3621     single_instruction;
       
  3622     dst   : E(write);
       
  3623     src1  : R(read);
       
  3624     src2  : R(read);
       
  3625     MS    : R(5);
       
  3626 %}
       
  3627 
       
  3628 pipe_class mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
       
  3629     single_instruction;
       
  3630     dst   : E(write)+4;
       
  3631     src1  : R(read);
       
  3632     src2  : R(read);
       
  3633     MS    : R(6);
       
  3634 %}
       
  3635 
       
  3636 // Integer Divide reg-reg
       
  3637 pipe_class sdiv_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI temp, flagsReg cr) %{
       
  3638     instruction_count(1); multiple_bundles;
       
  3639     dst   : E(write);
       
  3640     temp  : E(write);
       
  3641     src1  : R(read);
       
  3642     src2  : R(read);
       
  3643     temp  : R(read);
       
  3644     MS    : R(38);
       
  3645 %}
       
  3646 
       
  3647 // Long Divide
       
  3648 pipe_class divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
       
  3649     dst  : E(write)+71;
       
  3650     src1 : R(read);
       
  3651     src2 : R(read)+1;
       
  3652     MS   : R(70);
       
  3653 %}
       
  3654 
       
  3655 // Floating Point Add Float
       
  3656 pipe_class faddF_reg_reg(regF dst, regF src1, regF src2) %{
       
  3657     single_instruction;
       
  3658     dst   : X(write);
       
  3659     src1  : E(read);
       
  3660     src2  : E(read);
       
  3661     FA    : R;
       
  3662 %}
       
  3663 
       
  3664 // Floating Point Add Double
       
  3665 pipe_class faddD_reg_reg(regD dst, regD src1, regD src2) %{
       
  3666     single_instruction;
       
  3667     dst   : X(write);
       
  3668     src1  : E(read);
       
  3669     src2  : E(read);
       
  3670     FA    : R;
       
  3671 %}
       
  3672 
       
  3673 // Floating Point Conditional Move based on integer flags
       
  3674 pipe_class int_conditional_float_move (cmpOp cmp, flagsReg cr, regF dst, regF src) %{
       
  3675     single_instruction;
       
  3676     dst   : X(write);
       
  3677     src   : E(read);
       
  3678     cr    : R(read);
       
  3679     FA    : R(2);
       
  3680     BR    : R(2);
       
  3681 %}
       
  3682 
       
  3683 // Floating Point Conditional Move based on integer flags
       
  3684 pipe_class int_conditional_double_move (cmpOp cmp, flagsReg cr, regD dst, regD src) %{
       
  3685     single_instruction;
       
  3686     dst   : X(write);
       
  3687     src   : E(read);
       
  3688     cr    : R(read);
       
  3689     FA    : R(2);
       
  3690     BR    : R(2);
       
  3691 %}
       
  3692 
       
  3693 // Floating Point Multiply Float
       
  3694 pipe_class fmulF_reg_reg(regF dst, regF src1, regF src2) %{
       
  3695     single_instruction;
       
  3696     dst   : X(write);
       
  3697     src1  : E(read);
       
  3698     src2  : E(read);
       
  3699     FM    : R;
       
  3700 %}
       
  3701 
       
  3702 // Floating Point Multiply Double
       
  3703 pipe_class fmulD_reg_reg(regD dst, regD src1, regD src2) %{
       
  3704     single_instruction;
       
  3705     dst   : X(write);
       
  3706     src1  : E(read);
       
  3707     src2  : E(read);
       
  3708     FM    : R;
       
  3709 %}
       
  3710 
       
  3711 // Floating Point Divide Float
       
  3712 pipe_class fdivF_reg_reg(regF dst, regF src1, regF src2) %{
       
  3713     single_instruction;
       
  3714     dst   : X(write);
       
  3715     src1  : E(read);
       
  3716     src2  : E(read);
       
  3717     FM    : R;
       
  3718     FDIV  : C(14);
       
  3719 %}
       
  3720 
       
  3721 // Floating Point Divide Double
       
  3722 pipe_class fdivD_reg_reg(regD dst, regD src1, regD src2) %{
       
  3723     single_instruction;
       
  3724     dst   : X(write);
       
  3725     src1  : E(read);
       
  3726     src2  : E(read);
       
  3727     FM    : R;
       
  3728     FDIV  : C(17);
       
  3729 %}
       
  3730 
       
  3731 // Floating Point Move/Negate/Abs Float
       
  3732 pipe_class faddF_reg(regF dst, regF src) %{
       
  3733     single_instruction;
       
  3734     dst   : W(write);
       
  3735     src   : E(read);
       
  3736     FA    : R(1);
       
  3737 %}
       
  3738 
       
  3739 // Floating Point Move/Negate/Abs Double
       
  3740 pipe_class faddD_reg(regD dst, regD src) %{
       
  3741     single_instruction;
       
  3742     dst   : W(write);
       
  3743     src   : E(read);
       
  3744     FA    : R;
       
  3745 %}
       
  3746 
       
  3747 // Floating Point Convert F->D
       
  3748 pipe_class fcvtF2D(regD dst, regF src) %{
       
  3749     single_instruction;
       
  3750     dst   : X(write);
       
  3751     src   : E(read);
       
  3752     FA    : R;
       
  3753 %}
       
  3754 
       
  3755 // Floating Point Convert I->D
       
  3756 pipe_class fcvtI2D(regD dst, regF src) %{
       
  3757     single_instruction;
       
  3758     dst   : X(write);
       
  3759     src   : E(read);
       
  3760     FA    : R;
       
  3761 %}
       
  3762 
       
  3763 // Floating Point Convert LHi->D
       
  3764 pipe_class fcvtLHi2D(regD dst, regD src) %{
       
  3765     single_instruction;
       
  3766     dst   : X(write);
       
  3767     src   : E(read);
       
  3768     FA    : R;
       
  3769 %}
       
  3770 
       
  3771 // Floating Point Convert L->D
       
  3772 pipe_class fcvtL2D(regD dst, iRegL src) %{
       
  3773     single_instruction;
       
  3774     dst   : X(write);
       
  3775     src   : E(read);
       
  3776     FA    : R;
       
  3777 %}
       
  3778 
       
  3779 // Floating Point Convert L->F
       
  3780 pipe_class fcvtL2F(regF dst, iRegL src) %{
       
  3781     single_instruction;
       
  3782     dst   : X(write);
       
  3783     src   : E(read);
       
  3784     FA    : R;
       
  3785 %}
       
  3786 
       
  3787 // Floating Point Convert D->F
       
  3788 pipe_class fcvtD2F(regD dst, regF src) %{
       
  3789     single_instruction;
       
  3790     dst   : X(write);
       
  3791     src   : E(read);
       
  3792     FA    : R;
       
  3793 %}
       
  3794 
       
  3795 // Floating Point Convert I->L
       
  3796 pipe_class fcvtI2L(regD dst, regF src) %{
       
  3797     single_instruction;
       
  3798     dst   : X(write);
       
  3799     src   : E(read);
       
  3800     FA    : R;
       
  3801 %}
       
  3802 
       
  3803 // Floating Point Convert D->F
       
  3804 pipe_class fcvtD2I(iRegI dst, regD src, flagsReg cr) %{
       
  3805     instruction_count(1); multiple_bundles;
       
  3806     dst   : X(write)+6;
       
  3807     src   : E(read);
       
  3808     FA    : R;
       
  3809 %}
       
  3810 
       
  3811 // Floating Point Convert D->L
       
  3812 pipe_class fcvtD2L(regD dst, regD src, flagsReg cr) %{
       
  3813     instruction_count(1); multiple_bundles;
       
  3814     dst   : X(write)+6;
       
  3815     src   : E(read);
       
  3816     FA    : R;
       
  3817 %}
       
  3818 
       
  3819 // Floating Point Convert F->I
       
  3820 pipe_class fcvtF2I(regF dst, regF src, flagsReg cr) %{
       
  3821     instruction_count(1); multiple_bundles;
       
  3822     dst   : X(write)+6;
       
  3823     src   : E(read);
       
  3824     FA    : R;
       
  3825 %}
       
  3826 
       
  3827 // Floating Point Convert F->L
       
  3828 pipe_class fcvtF2L(regD dst, regF src, flagsReg cr) %{
       
  3829     instruction_count(1); multiple_bundles;
       
  3830     dst   : X(write)+6;
       
  3831     src   : E(read);
       
  3832     FA    : R;
       
  3833 %}
       
  3834 
       
  3835 // Floating Point Convert I->F
       
  3836 pipe_class fcvtI2F(regF dst, regF src) %{
       
  3837     single_instruction;
       
  3838     dst   : X(write);
       
  3839     src   : E(read);
       
  3840     FA    : R;
       
  3841 %}
       
  3842 
       
  3843 // Floating Point Compare
       
  3844 pipe_class faddF_fcc_reg_reg_zero(flagsRegF cr, regF src1, regF src2, immI0 zero) %{
       
  3845     single_instruction;
       
  3846     cr    : X(write);
       
  3847     src1  : E(read);
       
  3848     src2  : E(read);
       
  3849     FA    : R;
       
  3850 %}
       
  3851 
       
  3852 // Floating Point Compare
       
  3853 pipe_class faddD_fcc_reg_reg_zero(flagsRegF cr, regD src1, regD src2, immI0 zero) %{
       
  3854     single_instruction;
       
  3855     cr    : X(write);
       
  3856     src1  : E(read);
       
  3857     src2  : E(read);
       
  3858     FA    : R;
       
  3859 %}
       
  3860 
       
  3861 // Floating Add Nop
       
  3862 pipe_class fadd_nop() %{
       
  3863     single_instruction;
       
  3864     FA  : R;
       
  3865 %}
       
  3866 
       
  3867 // Integer Store to Memory
       
  3868 pipe_class istore_mem_reg(memoryI mem, iRegI src) %{
       
  3869     single_instruction;
       
  3870     mem   : R(read);
       
  3871     src   : C(read);
       
  3872     MS    : R;
       
  3873 %}
       
  3874 
       
  3875 // Integer Store to Memory
       
  3876 pipe_class istore_mem_spORreg(memoryI mem, sp_ptr_RegP src) %{
       
  3877     single_instruction;
       
  3878     mem   : R(read);
       
  3879     src   : C(read);
       
  3880     MS    : R;
       
  3881 %}
       
  3882 
       
  3883 // Float Store
       
  3884 pipe_class fstoreF_mem_reg(memoryF mem, RegF src) %{
       
  3885     single_instruction;
       
  3886     mem : R(read);
       
  3887     src : C(read);
       
  3888     MS  : R;
       
  3889 %}
       
  3890 
       
  3891 // Float Store
       
  3892 pipe_class fstoreF_mem_zero(memoryF mem, immF0 src) %{
       
  3893     single_instruction;
       
  3894     mem : R(read);
       
  3895     MS  : R;
       
  3896 %}
       
  3897 
       
  3898 // Double Store
       
  3899 pipe_class fstoreD_mem_reg(memoryD mem, RegD src) %{
       
  3900     instruction_count(1);
       
  3901     mem : R(read);
       
  3902     src : C(read);
       
  3903     MS  : R;
       
  3904 %}
       
  3905 
       
  3906 // Double Store
       
  3907 pipe_class fstoreD_mem_zero(memoryD mem, immD0 src) %{
       
  3908     single_instruction;
       
  3909     mem : R(read);
       
  3910     MS  : R;
       
  3911 %}
       
  3912 
       
  3913 // Integer Load (when sign bit propagation not needed)
       
  3914 pipe_class iload_mem(iRegI dst, memoryI mem) %{
       
  3915     single_instruction;
       
  3916     mem : R(read);
       
  3917     dst : C(write);
       
  3918     MS  : R;
       
  3919 %}
       
  3920 
       
  3921 // Integer Load (when sign bit propagation or masking is needed)
       
  3922 pipe_class iload_mask_mem(iRegI dst, memoryI mem) %{
       
  3923     single_instruction;
       
  3924     mem : R(read);
       
  3925     dst : M(write);
       
  3926     MS  : R;
       
  3927 %}
       
  3928 
       
  3929 // Float Load
       
  3930 pipe_class floadF_mem(regF dst, memoryF mem) %{
       
  3931     single_instruction;
       
  3932     mem : R(read);
       
  3933     dst : M(write);
       
  3934     MS  : R;
       
  3935 %}
       
  3936 
       
  3937 // Float Load
       
  3938 pipe_class floadD_mem(regD dst, memoryD mem) %{
       
  3939     instruction_count(1); multiple_bundles; // Again, unaligned argument is only multiple case
       
  3940     mem : R(read);
       
  3941     dst : M(write);
       
  3942     MS  : R;
       
  3943 %}
       
  3944 
       
  3945 // Memory Nop
       
  3946 pipe_class mem_nop() %{
       
  3947     single_instruction;
       
  3948     MS  : R;
       
  3949 %}
       
  3950 
       
  3951 pipe_class sethi(iRegP dst, immI src) %{
       
  3952     single_instruction;
       
  3953     dst  : E(write);
       
  3954     IALU : R;
       
  3955 %}
       
  3956 
       
  3957 pipe_class loadPollP(iRegP poll) %{
       
  3958     single_instruction;
       
  3959     poll : R(read);
       
  3960     MS   : R;
       
  3961 %}
       
  3962 
       
  3963 pipe_class br(Universe br, label labl) %{
       
  3964     single_instruction_with_delay_slot;
       
  3965     BR  : R;
       
  3966 %}
       
  3967 
       
  3968 pipe_class br_cc(Universe br, cmpOp cmp, flagsReg cr, label labl) %{
       
  3969     single_instruction_with_delay_slot;
       
  3970     cr    : E(read);
       
  3971     BR    : R;
       
  3972 %}
       
  3973 
       
  3974 pipe_class br_reg(Universe br, cmpOp cmp, iRegI op1, label labl) %{
       
  3975     single_instruction_with_delay_slot;
       
  3976     op1 : E(read);
       
  3977     BR  : R;
       
  3978     MS  : R;
       
  3979 %}
       
  3980 
       
  3981 pipe_class br_nop() %{
       
  3982     single_instruction;
       
  3983     BR  : R;
       
  3984 %}
       
  3985 
       
  3986 pipe_class simple_call(method meth) %{
       
  3987     instruction_count(2); multiple_bundles; force_serialization;
       
  3988     fixed_latency(100);
       
  3989     BR  : R(1);
       
  3990     MS  : R(1);
       
  3991     A0  : R(1);
       
  3992 %}
       
  3993 
       
  3994 pipe_class compiled_call(method meth) %{
       
  3995     instruction_count(1); multiple_bundles; force_serialization;
       
  3996     fixed_latency(100);
       
  3997     MS  : R(1);
       
  3998 %}
       
  3999 
       
  4000 pipe_class call(method meth) %{
       
  4001     instruction_count(0); multiple_bundles; force_serialization;
       
  4002     fixed_latency(100);
       
  4003 %}
       
  4004 
       
  4005 pipe_class tail_call(Universe ignore, label labl) %{
       
  4006     single_instruction; has_delay_slot;
       
  4007     fixed_latency(100);
       
  4008     BR  : R(1);
       
  4009     MS  : R(1);
       
  4010 %}
       
  4011 
       
  4012 pipe_class ret(Universe ignore) %{
       
  4013     single_instruction; has_delay_slot;
       
  4014     BR  : R(1);
       
  4015     MS  : R(1);
       
  4016 %}
       
  4017 
       
  4018 // The real do-nothing guy
       
  4019 pipe_class empty( ) %{
       
  4020     instruction_count(0);
       
  4021 %}
       
  4022 
       
  4023 pipe_class long_memory_op() %{
       
  4024     instruction_count(0); multiple_bundles; force_serialization;
       
  4025     fixed_latency(25);
       
  4026     MS  : R(1);
       
  4027 %}
       
  4028 
       
  4029 // Check-cast
       
  4030 pipe_class partial_subtype_check_pipe(Universe ignore, iRegP array, iRegP match ) %{
       
  4031     array : R(read);
       
  4032     match  : R(read);
       
  4033     IALU   : R(2);
       
  4034     BR     : R(2);
       
  4035     MS     : R;
       
  4036 %}
       
  4037 
       
  4038 // Convert FPU flags into +1,0,-1
       
  4039 pipe_class floating_cmp( iRegI dst, regF src1, regF src2 ) %{
       
  4040     src1  : E(read);
       
  4041     src2  : E(read);
       
  4042     dst   : E(write);
       
  4043     FA    : R;
       
  4044     MS    : R(2);
       
  4045     BR    : R(2);
       
  4046 %}
       
  4047 
       
  4048 // Compare for p < q, and conditionally add y
       
  4049 pipe_class cadd_cmpltmask( iRegI p, iRegI q, iRegI y ) %{
       
  4050     p     : E(read);
       
  4051     q     : E(read);
       
  4052     y     : E(read);
       
  4053     IALU  : R(3)
       
  4054 %}
       
  4055 
       
  4056 // Perform a compare, then move conditionally in a branch delay slot.
       
  4057 pipe_class min_max( iRegI src2, iRegI srcdst ) %{
       
  4058     src2   : E(read);
       
  4059     srcdst : E(read);
       
  4060     IALU   : R;
       
  4061     BR     : R;
       
  4062 %}
       
  4063 
       
  4064 // Define the class for the Nop node
       
  4065 define %{
       
  4066    MachNop = ialu_nop;
       
  4067 %}
       
  4068 
       
  4069 %}
       
  4070 
       
  4071 //----------INSTRUCTIONS-------------------------------------------------------
       
  4072 
       
  4073 //------------Special Nop instructions for bundling - no match rules-----------
       
  4074 // Nop using the A0 functional unit
       
  4075 instruct Nop_A0() %{
       
  4076   ins_pipe(ialu_nop_A0);
       
  4077 %}
       
  4078 
       
  4079 // Nop using the A1 functional unit
       
  4080 instruct Nop_A1( ) %{
       
  4081   ins_pipe(ialu_nop_A1);
       
  4082 %}
       
  4083 
       
  4084 // Nop using the memory functional unit
       
  4085 instruct Nop_MS( ) %{
       
  4086   ins_pipe(mem_nop);
       
  4087 %}
       
  4088 
       
  4089 // Nop using the floating add functional unit
       
  4090 instruct Nop_FA( ) %{
       
  4091   ins_pipe(fadd_nop);
       
  4092 %}
       
  4093 
       
  4094 // Nop using the branch functional unit
       
  4095 instruct Nop_BR( ) %{
       
  4096   ins_pipe(br_nop);
       
  4097 %}
       
  4098 
       
  4099 //----------Load/Store/Move Instructions---------------------------------------
       
  4100 //----------Load Instructions--------------------------------------------------
       
  4101 // Load Byte (8bit signed)
       
  4102 instruct loadB(iRegI dst, memoryB mem) %{
       
  4103   match(Set dst (LoadB mem));
       
  4104   ins_cost(MEMORY_REF_COST);
       
  4105 
       
  4106   size(4);
       
  4107   format %{ "LDRSB   $dst,$mem\t! byte -> int" %}
       
  4108   ins_encode %{
       
  4109     // High 32 bits are harmlessly set on Aarch64
       
  4110     __ ldrsb($dst$$Register, $mem$$Address);
       
  4111   %}
       
  4112   ins_pipe(iload_mask_mem);
       
  4113 %}
       
  4114 
       
  4115 // Load Byte (8bit signed) into a Long Register
       
  4116 instruct loadB2L(iRegL dst, memoryB mem) %{
       
  4117   match(Set dst (ConvI2L (LoadB mem)));
       
  4118   ins_cost(MEMORY_REF_COST);
       
  4119 
       
  4120 #ifdef AARCH64
       
  4121   size(4);
       
  4122   format %{ "LDRSB $dst,$mem\t! byte -> long"  %}
       
  4123   ins_encode %{
       
  4124     __ ldrsb($dst$$Register, $mem$$Address);
       
  4125   %}
       
  4126 #else
       
  4127   size(8);
       
  4128   format %{ "LDRSB $dst.lo,$mem\t! byte -> long\n\t"
       
  4129             "ASR   $dst.hi,$dst.lo,31" %}
       
  4130   ins_encode %{
       
  4131     __ ldrsb($dst$$Register, $mem$$Address);
       
  4132     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
       
  4133   %}
       
  4134 #endif
       
  4135   ins_pipe(iload_mask_mem);
       
  4136 %}
       
  4137 
       
  4138 // Load Unsigned Byte (8bit UNsigned) into an int reg
       
  4139 instruct loadUB(iRegI dst, memoryB mem) %{
       
  4140   match(Set dst (LoadUB mem));
       
  4141   ins_cost(MEMORY_REF_COST);
       
  4142 
       
  4143   size(4);
       
  4144   format %{ "LDRB   $dst,$mem\t! ubyte -> int" %}
       
  4145   ins_encode %{
       
  4146     __ ldrb($dst$$Register, $mem$$Address);
       
  4147   %}
       
  4148   ins_pipe(iload_mem);
       
  4149 %}
       
  4150 
       
  4151 // Load Unsigned Byte (8bit UNsigned) into a Long Register
       
  4152 instruct loadUB2L(iRegL dst, memoryB mem) %{
       
  4153   match(Set dst (ConvI2L (LoadUB mem)));
       
  4154   ins_cost(MEMORY_REF_COST);
       
  4155 
       
  4156 #ifdef AARCH64
       
  4157   size(4);
       
  4158   format %{ "LDRB  $dst,$mem\t! ubyte -> long"  %}
       
  4159   ins_encode %{
       
  4160     __ ldrb($dst$$Register, $mem$$Address);
       
  4161   %}
       
  4162 #else
       
  4163   size(8);
       
  4164   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
       
  4165             "MOV   $dst.hi,0" %}
       
  4166   ins_encode %{
       
  4167     __ ldrb($dst$$Register, $mem$$Address);
       
  4168     __ mov($dst$$Register->successor(), 0);
       
  4169   %}
       
  4170 #endif
       
  4171   ins_pipe(iload_mem);
       
  4172 %}
       
  4173 
       
  4174 // Load Unsigned Byte (8 bit UNsigned) with immediate mask into Long Register
       
  4175 instruct loadUB2L_limmI(iRegL dst, memoryB mem, limmIlow8 mask) %{
       
  4176   match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
       
  4177 
       
  4178 #ifdef AARCH64
       
  4179   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
       
  4180   size(8);
       
  4181   format %{ "LDRB  $dst,$mem\t! ubyte -> long\n\t"
       
  4182             "AND  $dst,$dst,$mask" %}
       
  4183   ins_encode %{
       
  4184     __ ldrb($dst$$Register, $mem$$Address);
       
  4185     __ andr($dst$$Register, $dst$$Register, limmI_low($mask$$constant, 8));
       
  4186   %}
       
  4187 #else
       
  4188   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
       
  4189   size(12);
       
  4190   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
       
  4191             "MOV   $dst.hi,0\n\t"
       
  4192             "AND  $dst.lo,$dst.lo,$mask" %}
       
  4193   ins_encode %{
       
  4194     __ ldrb($dst$$Register, $mem$$Address);
       
  4195     __ mov($dst$$Register->successor(), 0);
       
  4196     __ andr($dst$$Register, $dst$$Register, limmI_low($mask$$constant, 8));
       
  4197   %}
       
  4198 #endif
       
  4199   ins_pipe(iload_mem);
       
  4200 %}
       
  4201 
       
  4202 // Load Short (16bit signed)
       
  4203 #ifdef AARCH64
       
  4204 // XXX This variant shouldn't be necessary if 6217251 is implemented
       
  4205 instruct loadSoff(iRegI dst, memoryScaledS mem, aimmX off, iRegP tmp) %{
       
  4206   match(Set dst (LoadS (AddP mem off)));
       
  4207   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
       
  4208   effect(TEMP tmp);
       
  4209   size(4 * 2);
       
  4210 
       
  4211   format %{ "LDRSH   $dst,$mem+$off\t! short temp=$tmp" %}
       
  4212   ins_encode %{
       
  4213     Register base = reg_to_register_object($mem$$base);
       
  4214     __ add($tmp$$Register, base, $off$$constant);
       
  4215     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  4216     __ ldrsh($dst$$Register, nmem);
       
  4217   %}
       
  4218   ins_pipe(iload_mask_mem);
       
  4219 %}
       
  4220 #endif
       
  4221 
       
  4222 instruct loadS(iRegI dst, memoryS mem) %{
       
  4223   match(Set dst (LoadS mem));
       
  4224   ins_cost(MEMORY_REF_COST);
       
  4225 
       
  4226   size(4);
       
  4227   format %{ "LDRSH   $dst,$mem\t! short" %}
       
  4228   ins_encode %{
       
  4229     __ ldrsh($dst$$Register, $mem$$Address);
       
  4230   %}
       
  4231   ins_pipe(iload_mask_mem);
       
  4232 %}
       
  4233 
       
  4234 // Load Short (16 bit signed) to Byte (8 bit signed)
       
  4235 instruct loadS2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
       
  4236   match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
       
  4237   ins_cost(MEMORY_REF_COST);
       
  4238 
       
  4239   size(4);
       
  4240 
       
  4241   format %{ "LDRSB   $dst,$mem\t! short -> byte" %}
       
  4242   ins_encode %{
       
  4243     // High 32 bits are harmlessly set on Aarch64
       
  4244     __ ldrsb($dst$$Register, $mem$$Address);
       
  4245   %}
       
  4246   ins_pipe(iload_mask_mem);
       
  4247 %}
       
  4248 
       
  4249 // Load Short (16bit signed) into a Long Register
       
  4250 instruct loadS2L(iRegL dst, memoryS mem) %{
       
  4251   match(Set dst (ConvI2L (LoadS mem)));
       
  4252   ins_cost(MEMORY_REF_COST);
       
  4253 
       
  4254 #ifdef AARCH64
       
  4255   size(4);
       
  4256   format %{ "LDRSH $dst,$mem\t! short -> long"  %}
       
  4257   ins_encode %{
       
  4258     __ ldrsh($dst$$Register, $mem$$Address);
       
  4259   %}
       
  4260 #else
       
  4261   size(8);
       
  4262   format %{ "LDRSH $dst.lo,$mem\t! short -> long\n\t"
       
  4263             "ASR   $dst.hi,$dst.lo,31" %}
       
  4264   ins_encode %{
       
  4265     __ ldrsh($dst$$Register, $mem$$Address);
       
  4266     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
       
  4267   %}
       
  4268 #endif
       
  4269   ins_pipe(iload_mask_mem);
       
  4270 %}
       
  4271 
       
  4272 // Load Unsigned Short/Char (16bit UNsigned)
       
  4273 
       
  4274 #ifdef AARCH64
       
  4275 // XXX This variant shouldn't be necessary if 6217251 is implemented
       
  4276 instruct loadUSoff(iRegI dst, memoryScaledS mem, aimmX off, iRegP tmp) %{
       
  4277   match(Set dst (LoadUS (AddP mem off)));
       
  4278   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
       
  4279   effect(TEMP tmp);
       
  4280   size(4 * 2);
       
  4281 
       
  4282   format %{ "LDRH   $dst,$mem+$off\t! ushort/char temp=$tmp" %}
       
  4283   ins_encode %{
       
  4284     Register base = reg_to_register_object($mem$$base);
       
  4285     __ add($tmp$$Register, base, $off$$constant);
       
  4286     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  4287     __ ldrh($dst$$Register, nmem);
       
  4288   %}
       
  4289   ins_pipe(iload_mem);
       
  4290 %}
       
  4291 #endif
       
  4292 
       
  4293 instruct loadUS(iRegI dst, memoryS mem) %{
       
  4294   match(Set dst (LoadUS mem));
       
  4295   ins_cost(MEMORY_REF_COST);
       
  4296 
       
  4297   size(4);
       
  4298   format %{ "LDRH   $dst,$mem\t! ushort/char" %}
       
  4299   ins_encode %{
       
  4300     __ ldrh($dst$$Register, $mem$$Address);
       
  4301   %}
       
  4302   ins_pipe(iload_mem);
       
  4303 %}
       
  4304 
       
  4305 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
       
  4306 instruct loadUS2B(iRegI dst, memoryB mem, immI_24 twentyfour) %{
       
  4307   match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
       
  4308   ins_cost(MEMORY_REF_COST);
       
  4309 
       
  4310   size(4);
       
  4311   format %{ "LDRSB   $dst,$mem\t! ushort -> byte" %}
       
  4312   ins_encode %{
       
  4313     __ ldrsb($dst$$Register, $mem$$Address);
       
  4314   %}
       
  4315   ins_pipe(iload_mask_mem);
       
  4316 %}
       
  4317 
       
  4318 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register
       
  4319 instruct loadUS2L(iRegL dst, memoryS mem) %{
       
  4320   match(Set dst (ConvI2L (LoadUS mem)));
       
  4321   ins_cost(MEMORY_REF_COST);
       
  4322 
       
  4323 #ifdef AARCH64
       
  4324   size(4);
       
  4325   format %{ "LDRH  $dst,$mem\t! short -> long"  %}
       
  4326   ins_encode %{
       
  4327     __ ldrh($dst$$Register, $mem$$Address);
       
  4328   %}
       
  4329 #else
       
  4330   size(8);
       
  4331   format %{ "LDRH  $dst.lo,$mem\t! short -> long\n\t"
       
  4332             "MOV   $dst.hi, 0" %}
       
  4333   ins_encode %{
       
  4334     __ ldrh($dst$$Register, $mem$$Address);
       
  4335     __ mov($dst$$Register->successor(), 0);
       
  4336   %}
       
  4337 #endif
       
  4338   ins_pipe(iload_mem);
       
  4339 %}
       
  4340 
       
  4341 // Load Unsigned Short/Char (16bit UNsigned) with mask 0xFF into a Long Register
       
  4342 instruct loadUS2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
       
  4343   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
       
  4344   ins_cost(MEMORY_REF_COST);
       
  4345 
       
  4346 #ifdef AARCH64
       
  4347   size(4);
       
  4348   format %{ "LDRB  $dst,$mem"  %}
       
  4349   ins_encode %{
       
  4350     __ ldrb($dst$$Register, $mem$$Address);
       
  4351   %}
       
  4352 #else
       
  4353   size(8);
       
  4354   format %{ "LDRB  $dst.lo,$mem\t! \n\t"
       
  4355             "MOV   $dst.hi, 0" %}
       
  4356   ins_encode %{
       
  4357     __ ldrb($dst$$Register, $mem$$Address);
       
  4358     __ mov($dst$$Register->successor(), 0);
       
  4359   %}
       
  4360 #endif
       
  4361   ins_pipe(iload_mem);
       
  4362 %}
       
  4363 
       
  4364 // Load Unsigned Short/Char (16bit UNsigned) with a immediate mask into a Long Register
       
  4365 instruct loadUS2L_limmI(iRegL dst, memoryS mem, limmI mask) %{
       
  4366   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
       
  4367 #ifdef AARCH64
       
  4368   ins_cost(MEMORY_REF_COST + 1*DEFAULT_COST);
       
  4369 
       
  4370   size(8);
       
  4371   format %{ "LDRH   $dst,$mem\t! ushort/char & mask -> long\n\t"
       
  4372             "AND    $dst,$dst,$mask" %}
       
  4373   ins_encode %{
       
  4374     __ ldrh($dst$$Register, $mem$$Address);
       
  4375     __ andr($dst$$Register, $dst$$Register, (uintx)$mask$$constant);
       
  4376   %}
       
  4377 #else
       
  4378   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
       
  4379 
       
  4380   size(12);
       
  4381   format %{ "LDRH   $dst,$mem\t! ushort/char & mask -> long\n\t"
       
  4382             "MOV    $dst.hi, 0\n\t"
       
  4383             "AND    $dst,$dst,$mask" %}
       
  4384   ins_encode %{
       
  4385     __ ldrh($dst$$Register, $mem$$Address);
       
  4386     __ mov($dst$$Register->successor(), 0);
       
  4387     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
       
  4388   %}
       
  4389 #endif
       
  4390   ins_pipe(iload_mem);
       
  4391 %}
       
  4392 
       
  4393 // Load Integer
       
  4394 
       
  4395 #ifdef AARCH64
       
  4396 // XXX This variant shouldn't be necessary if 6217251 is implemented
       
  4397 instruct loadIoff(iRegI dst, memoryScaledI mem, aimmX off, iRegP tmp) %{
       
  4398   match(Set dst (LoadI (AddP mem off)));
       
  4399   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
       
  4400   effect(TEMP tmp);
       
  4401   size(4 * 2);
       
  4402 
       
  4403   format %{ "ldr_s32 $dst,$mem+$off\t! int temp=$tmp" %}
       
  4404   ins_encode %{
       
  4405     Register base = reg_to_register_object($mem$$base);
       
  4406     __ add($tmp$$Register, base, $off$$constant);
       
  4407     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  4408     __ ldr_s32($dst$$Register, nmem);
       
  4409   %}
       
  4410   ins_pipe(iload_mem);
       
  4411 %}
       
  4412 #endif
       
  4413 
       
  4414 instruct loadI(iRegI dst, memoryI mem) %{
       
  4415   match(Set dst (LoadI mem));
       
  4416   ins_cost(MEMORY_REF_COST);
       
  4417 
       
  4418   size(4);
       
  4419   format %{ "ldr_s32 $dst,$mem\t! int" %}
       
  4420   ins_encode %{
       
  4421     __ ldr_s32($dst$$Register, $mem$$Address);
       
  4422   %}
       
  4423   ins_pipe(iload_mem);
       
  4424 %}
       
  4425 
       
  4426 // Load Integer to Byte (8 bit signed)
       
  4427 instruct loadI2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
       
  4428   match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
       
  4429   ins_cost(MEMORY_REF_COST);
       
  4430 
       
  4431   size(4);
       
  4432 
       
  4433   format %{ "LDRSB   $dst,$mem\t! int -> byte" %}
       
  4434   ins_encode %{
       
  4435     __ ldrsb($dst$$Register, $mem$$Address);
       
  4436   %}
       
  4437   ins_pipe(iload_mask_mem);
       
  4438 %}
       
  4439 
       
  4440 // Load Integer to Unsigned Byte (8 bit UNsigned)
       
  4441 instruct loadI2UB(iRegI dst, memoryB mem, immI_255 mask) %{
       
  4442   match(Set dst (AndI (LoadI mem) mask));
       
  4443   ins_cost(MEMORY_REF_COST);
       
  4444 
       
  4445   size(4);
       
  4446 
       
  4447   format %{ "LDRB   $dst,$mem\t! int -> ubyte" %}
       
  4448   ins_encode %{
       
  4449     __ ldrb($dst$$Register, $mem$$Address);
       
  4450   %}
       
  4451   ins_pipe(iload_mask_mem);
       
  4452 %}
       
  4453 
       
  4454 // Load Integer to Short (16 bit signed)
       
  4455 instruct loadI2S(iRegI dst, memoryS mem, immI_16 sixteen) %{
       
  4456   match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
       
  4457   ins_cost(MEMORY_REF_COST);
       
  4458 
       
  4459   size(4);
       
  4460   format %{ "LDRSH   $dst,$mem\t! int -> short" %}
       
  4461   ins_encode %{
       
  4462     __ ldrsh($dst$$Register, $mem$$Address);
       
  4463   %}
       
  4464   ins_pipe(iload_mask_mem);
       
  4465 %}
       
  4466 
       
  4467 // Load Integer to Unsigned Short (16 bit UNsigned)
       
  4468 instruct loadI2US(iRegI dst, memoryS mem, immI_65535 mask) %{
       
  4469   match(Set dst (AndI (LoadI mem) mask));
       
  4470   ins_cost(MEMORY_REF_COST);
       
  4471 
       
  4472   size(4);
       
  4473   format %{ "LDRH   $dst,$mem\t! int -> ushort/char" %}
       
  4474   ins_encode %{
       
  4475     __ ldrh($dst$$Register, $mem$$Address);
       
  4476   %}
       
  4477   ins_pipe(iload_mask_mem);
       
  4478 %}
       
  4479 
       
  4480 // Load Integer into a Long Register
       
  4481 instruct loadI2L(iRegL dst, memoryI mem) %{
       
  4482   match(Set dst (ConvI2L (LoadI mem)));
       
  4483 #ifdef AARCH64
       
  4484   ins_cost(MEMORY_REF_COST);
       
  4485 
       
  4486   size(4);
       
  4487   format %{ "LDRSW $dst.lo,$mem\t! int -> long"  %}
       
  4488   ins_encode %{
       
  4489     __ ldr_s32($dst$$Register, $mem$$Address);
       
  4490   %}
       
  4491 #else
       
  4492   ins_cost(MEMORY_REF_COST);
       
  4493 
       
  4494   size(8);
       
  4495   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
       
  4496             "ASR   $dst.hi,$dst.lo,31\t! int->long" %}
       
  4497   ins_encode %{
       
  4498     __ ldr($dst$$Register, $mem$$Address);
       
  4499     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
       
  4500   %}
       
  4501 #endif
       
  4502   ins_pipe(iload_mask_mem);
       
  4503 %}
       
  4504 
       
  4505 // Load Integer with mask 0xFF into a Long Register
       
  4506 instruct loadI2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
       
  4507   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
       
  4508 #ifdef AARCH64
       
  4509   ins_cost(MEMORY_REF_COST);
       
  4510 
       
  4511   size(4);
       
  4512   format %{ "LDRB   $dst.lo,$mem\t! int & 0xFF -> long"  %}
       
  4513   ins_encode %{
       
  4514     __ ldrb($dst$$Register, $mem$$Address);
       
  4515   %}
       
  4516 #else
       
  4517   ins_cost(MEMORY_REF_COST);
       
  4518 
       
  4519   size(8);
       
  4520   format %{ "LDRB   $dst.lo,$mem\t! int & 0xFF -> long\n\t"
       
  4521             "MOV    $dst.hi, 0" %}
       
  4522   ins_encode %{
       
  4523     __ ldrb($dst$$Register, $mem$$Address);
       
  4524     __ mov($dst$$Register->successor(), 0);
       
  4525   %}
       
  4526 #endif
       
  4527   ins_pipe(iload_mem);
       
  4528 %}
       
  4529 
       
  4530 // Load Integer with mask 0xFFFF into a Long Register
       
  4531 instruct loadI2L_immI_65535(iRegL dst, memoryS mem, immI_65535 mask) %{
       
  4532   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
       
  4533   ins_cost(MEMORY_REF_COST);
       
  4534 
       
  4535 #ifdef AARCH64
       
  4536   size(4);
       
  4537   format %{ "LDRH   $dst,$mem\t! int & 0xFFFF -> long" %}
       
  4538   ins_encode %{
       
  4539     __ ldrh($dst$$Register, $mem$$Address);
       
  4540   %}
       
  4541 #else
       
  4542   size(8);
       
  4543   format %{ "LDRH   $dst,$mem\t! int & 0xFFFF -> long\n\t"
       
  4544             "MOV    $dst.hi, 0" %}
       
  4545   ins_encode %{
       
  4546     __ ldrh($dst$$Register, $mem$$Address);
       
  4547     __ mov($dst$$Register->successor(), 0);
       
  4548   %}
       
  4549 #endif
       
  4550   ins_pipe(iload_mask_mem);
       
  4551 %}
       
  4552 
       
  4553 #ifdef AARCH64
       
  4554 // Load Integer with an immediate mask into a Long Register
       
  4555 instruct loadI2L_limmI(iRegL dst, memoryI mem, limmI mask) %{
       
  4556   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
       
  4557   ins_cost(MEMORY_REF_COST + 1*DEFAULT_COST);
       
  4558 
       
  4559   size(8);
       
  4560   format %{ "LDRSW $dst,$mem\t! int -> long\n\t"
       
  4561             "AND   $dst,$dst,$mask" %}
       
  4562 
       
  4563   ins_encode %{
       
  4564     __ ldr_s32($dst$$Register, $mem$$Address);
       
  4565     __ andr($dst$$Register, $dst$$Register, (uintx)$mask$$constant);
       
  4566   %}
       
  4567   ins_pipe(iload_mem);
       
  4568 %}
       
  4569 #else
       
  4570 // Load Integer with a 31-bit immediate mask into a Long Register
       
  4571 instruct loadI2L_limmU31(iRegL dst, memoryI mem, limmU31 mask) %{
       
  4572   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
       
  4573   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
       
  4574 
       
  4575   size(12);
       
  4576   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
       
  4577             "MOV    $dst.hi, 0\n\t"
       
  4578             "AND   $dst,$dst,$mask" %}
       
  4579 
       
  4580   ins_encode %{
       
  4581     __ ldr($dst$$Register, $mem$$Address);
       
  4582     __ mov($dst$$Register->successor(), 0);
       
  4583     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
       
  4584   %}
       
  4585   ins_pipe(iload_mem);
       
  4586 %}
       
  4587 #endif
       
  4588 
       
  4589 #ifdef AARCH64
       
  4590 // Load Integer with mask into a Long Register
       
  4591 // FIXME: use signedRegI mask, remove tmp?
       
  4592 instruct loadI2L_immI(iRegL dst, memoryI mem, immI mask, iRegI tmp) %{
       
  4593   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
       
  4594   effect(TEMP dst, TEMP tmp);
       
  4595 
       
  4596   ins_cost(MEMORY_REF_COST + 3*DEFAULT_COST);
       
  4597   format %{ "LDRSW    $mem,$dst\t! int & 31-bit mask -> long\n\t"
       
  4598             "MOV_SLOW $tmp,$mask\n\t"
       
  4599             "AND      $dst,$tmp,$dst" %}
       
  4600   ins_encode %{
       
  4601     __ ldrsw($dst$$Register, $mem$$Address);
       
  4602     __ mov_slow($tmp$$Register, $mask$$constant);
       
  4603     __ andr($dst$$Register, $dst$$Register, $tmp$$Register);
       
  4604   %}
       
  4605   ins_pipe(iload_mem);
       
  4606 %}
       
  4607 #else
       
  4608 // Load Integer with a 31-bit mask into a Long Register
       
  4609 // FIXME: use iRegI mask, remove tmp?
       
  4610 instruct loadI2L_immU31(iRegL dst, memoryI mem, immU31 mask, iRegI tmp) %{
       
  4611   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
       
  4612   effect(TEMP dst, TEMP tmp);
       
  4613 
       
  4614   ins_cost(MEMORY_REF_COST + 4*DEFAULT_COST);
       
  4615   size(20);
       
  4616   format %{ "LDR      $mem,$dst\t! int & 31-bit mask -> long\n\t"
       
  4617             "MOV      $dst.hi, 0\n\t"
       
  4618             "MOV_SLOW $tmp,$mask\n\t"
       
  4619             "AND      $dst,$tmp,$dst" %}
       
  4620   ins_encode %{
       
  4621     __ ldr($dst$$Register, $mem$$Address);
       
  4622     __ mov($dst$$Register->successor(), 0);
       
  4623     __ mov_slow($tmp$$Register, $mask$$constant);
       
  4624     __ andr($dst$$Register, $dst$$Register, $tmp$$Register);
       
  4625   %}
       
  4626   ins_pipe(iload_mem);
       
  4627 %}
       
  4628 #endif
       
  4629 
       
  4630 // Load Unsigned Integer into a Long Register
       
  4631 instruct loadUI2L(iRegL dst, memoryI mem, immL_32bits mask) %{
       
  4632   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
       
  4633   ins_cost(MEMORY_REF_COST);
       
  4634 
       
  4635 #ifdef AARCH64
       
  4636 //size(4);
       
  4637   format %{ "LDR_w $dst,$mem\t! uint -> long" %}
       
  4638   ins_encode %{
       
  4639     __ ldr_w($dst$$Register, $mem$$Address);
       
  4640   %}
       
  4641 #else
       
  4642   size(8);
       
  4643   format %{ "LDR   $dst.lo,$mem\t! uint -> long\n\t"
       
  4644             "MOV   $dst.hi,0" %}
       
  4645   ins_encode %{
       
  4646     __ ldr($dst$$Register, $mem$$Address);
       
  4647     __ mov($dst$$Register->successor(), 0);
       
  4648   %}
       
  4649 #endif
       
  4650   ins_pipe(iload_mem);
       
  4651 %}
       
  4652 
       
  4653 // Load Long
       
  4654 
       
  4655 #ifdef AARCH64
       
  4656 // XXX This variant shouldn't be necessary if 6217251 is implemented
       
  4657 instruct loadLoff(iRegLd dst, memoryScaledL mem, aimmX off, iRegP tmp) %{
       
  4658   match(Set dst (LoadL (AddP mem off)));
       
  4659   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
       
  4660   effect(TEMP tmp);
       
  4661   size(4 * 2);
       
  4662 
       
  4663   format %{ "LDR    $dst,$mem+$off\t! long temp=$tmp" %}
       
  4664   ins_encode %{
       
  4665     Register base = reg_to_register_object($mem$$base);
       
  4666     __ add($tmp$$Register, base, $off$$constant);
       
  4667     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  4668     __ ldr($dst$$Register, nmem);
       
  4669   %}
       
  4670   ins_pipe(iload_mem);
       
  4671 %}
       
  4672 #endif
       
  4673 
       
  4674 instruct loadL(iRegLd dst, memoryL mem ) %{
       
  4675 #ifdef AARCH64
       
  4676   // already atomic for Aarch64
       
  4677 #else
       
  4678   predicate(!((LoadLNode*)n)->require_atomic_access());
       
  4679 #endif
       
  4680   match(Set dst (LoadL mem));
       
  4681   effect(TEMP dst);
       
  4682   ins_cost(MEMORY_REF_COST);
       
  4683 
       
  4684   size(4);
       
  4685   format %{ "ldr_64  $dst,$mem\t! long" %}
       
  4686   ins_encode %{
       
  4687     __ ldr_64($dst$$Register, $mem$$Address);
       
  4688   %}
       
  4689   ins_pipe(iload_mem);
       
  4690 %}
       
  4691 
       
  4692 #ifndef AARCH64
       
  4693 instruct loadL_2instr(iRegL dst, memorylong mem ) %{
       
  4694   predicate(!((LoadLNode*)n)->require_atomic_access());
       
  4695   match(Set dst (LoadL mem));
       
  4696   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
       
  4697 
       
  4698   size(8);
       
  4699   format %{ "LDR    $dst.lo,$mem \t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
       
  4700             "LDR    $dst.hi,$mem+4 or $mem" %}
       
  4701   ins_encode %{
       
  4702     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  4703     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
       
  4704 
       
  4705     if ($dst$$Register == reg_to_register_object($mem$$base)) {
       
  4706       __ ldr($dst$$Register->successor(), Amemhi);
       
  4707       __ ldr($dst$$Register, Amemlo);
       
  4708     } else {
       
  4709       __ ldr($dst$$Register, Amemlo);
       
  4710       __ ldr($dst$$Register->successor(), Amemhi);
       
  4711     }
       
  4712   %}
       
  4713   ins_pipe(iload_mem);
       
  4714 %}
       
  4715 
       
  4716 instruct loadL_volatile(iRegL dst, indirect mem ) %{
       
  4717   predicate(((LoadLNode*)n)->require_atomic_access());
       
  4718   match(Set dst (LoadL mem));
       
  4719   ins_cost(MEMORY_REF_COST);
       
  4720 
       
  4721   size(4);
       
  4722   format %{ "LDMIA    $dst,$mem\t! long" %}
       
  4723   ins_encode %{
       
  4724     // FIXME: why is ldmia considered atomic?  Should be ldrexd
       
  4725     RegisterSet set($dst$$Register);
       
  4726     set = set | reg_to_register_object($dst$$reg + 1);
       
  4727     __ ldmia(reg_to_register_object($mem$$base), set);
       
  4728   %}
       
  4729   ins_pipe(iload_mem);
       
  4730 %}
       
  4731 
       
  4732 instruct loadL_volatile_fp(iRegL dst, memoryD mem ) %{
       
  4733   predicate(((LoadLNode*)n)->require_atomic_access());
       
  4734   match(Set dst (LoadL mem));
       
  4735   ins_cost(MEMORY_REF_COST);
       
  4736 
       
  4737   size(8);
       
  4738   format %{ "FLDD      S14, $mem"
       
  4739             "FMRRD    $dst, S14\t! long \n't" %}
       
  4740   ins_encode %{
       
  4741     __ fldd(S14, $mem$$Address);
       
  4742     __ fmrrd($dst$$Register, $dst$$Register->successor(), S14);
       
  4743   %}
       
  4744   ins_pipe(iload_mem);
       
  4745 %}
       
  4746 
       
  4747 instruct loadL_unaligned(iRegL dst, memorylong mem ) %{
       
  4748   match(Set dst (LoadL_unaligned mem));
       
  4749   ins_cost(MEMORY_REF_COST);
       
  4750 
       
  4751   size(8);
       
  4752   format %{ "LDR    $dst.lo,$mem\t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
       
  4753             "LDR    $dst.hi,$mem+4" %}
       
  4754   ins_encode %{
       
  4755     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  4756     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
       
  4757 
       
  4758     if ($dst$$Register == reg_to_register_object($mem$$base)) {
       
  4759       __ ldr($dst$$Register->successor(), Amemhi);
       
  4760       __ ldr($dst$$Register, Amemlo);
       
  4761     } else {
       
  4762       __ ldr($dst$$Register, Amemlo);
       
  4763       __ ldr($dst$$Register->successor(), Amemhi);
       
  4764     }
       
  4765   %}
       
  4766   ins_pipe(iload_mem);
       
  4767 %}
       
  4768 #endif // !AARCH64
       
  4769 
       
  4770 // Load Range
       
  4771 instruct loadRange(iRegI dst, memoryI mem) %{
       
  4772   match(Set dst (LoadRange mem));
       
  4773   ins_cost(MEMORY_REF_COST);
       
  4774 
       
  4775   size(4);
       
  4776   format %{ "LDR_u32 $dst,$mem\t! range" %}
       
  4777   ins_encode %{
       
  4778     __ ldr_u32($dst$$Register, $mem$$Address);
       
  4779   %}
       
  4780   ins_pipe(iload_mem);
       
  4781 %}
       
  4782 
       
  4783 // Load Pointer
       
  4784 
       
  4785 #ifdef AARCH64
       
  4786 // XXX This variant shouldn't be necessary if 6217251 is implemented
       
  4787 instruct loadPoff(iRegP dst, memoryScaledP mem, aimmX off, iRegP tmp) %{
       
  4788   match(Set dst (LoadP (AddP mem off)));
       
  4789   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
       
  4790   effect(TEMP tmp);
       
  4791   size(4 * 2);
       
  4792 
       
  4793   format %{ "LDR    $dst,$mem+$off\t! ptr temp=$tmp" %}
       
  4794   ins_encode %{
       
  4795     Register base = reg_to_register_object($mem$$base);
       
  4796     __ add($tmp$$Register, base, $off$$constant);
       
  4797     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  4798     __ ldr($dst$$Register, nmem);
       
  4799   %}
       
  4800   ins_pipe(iload_mem);
       
  4801 %}
       
  4802 #endif
       
  4803 
       
  4804 instruct loadP(iRegP dst, memoryP mem) %{
       
  4805   match(Set dst (LoadP mem));
       
  4806   ins_cost(MEMORY_REF_COST);
       
  4807   size(4);
       
  4808 
       
  4809   format %{ "LDR   $dst,$mem\t! ptr" %}
       
  4810   ins_encode %{
       
  4811     __ ldr($dst$$Register, $mem$$Address);
       
  4812   %}
       
  4813   ins_pipe(iload_mem);
       
  4814 %}
       
  4815 
       
  4816 #ifdef XXX
       
  4817 // FIXME XXXX
       
  4818 //instruct loadSP(iRegP dst, memoryP mem) %{
       
  4819 instruct loadSP(SPRegP dst, memoryP mem, iRegP tmp) %{
       
  4820   match(Set dst (LoadP mem));
       
  4821   effect(TEMP tmp);
       
  4822   ins_cost(MEMORY_REF_COST+1);
       
  4823   size(8);
       
  4824 
       
  4825   format %{ "LDR   $tmp,$mem\t! ptr\n\t"
       
  4826             "MOV   $dst,$tmp\t! ptr" %}
       
  4827   ins_encode %{
       
  4828     __ ldr($tmp$$Register, $mem$$Address);
       
  4829     __ mov($dst$$Register, $tmp$$Register);
       
  4830   %}
       
  4831   ins_pipe(iload_mem);
       
  4832 %}
       
  4833 #endif
       
  4834 
       
  4835 #ifdef _LP64
       
  4836 // Load Compressed Pointer
       
  4837 
       
  4838 // XXX This variant shouldn't be necessary if 6217251 is implemented
       
  4839 instruct loadNoff(iRegN dst, memoryScaledI mem, aimmX off, iRegP tmp) %{
       
  4840   match(Set dst (LoadN (AddP mem off)));
       
  4841   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
       
  4842   effect(TEMP tmp);
       
  4843   size(4 * 2);
       
  4844 
       
  4845   format %{ "ldr_u32 $dst,$mem+$off\t! compressed ptr temp=$tmp" %}
       
  4846   ins_encode %{
       
  4847     Register base = reg_to_register_object($mem$$base);
       
  4848     __ add($tmp$$Register, base, $off$$constant);
       
  4849     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  4850     __ ldr_u32($dst$$Register, nmem);
       
  4851   %}
       
  4852   ins_pipe(iload_mem);
       
  4853 %}
       
  4854 
       
  4855 instruct loadN(iRegN dst, memoryI mem) %{
       
  4856   match(Set dst (LoadN mem));
       
  4857   ins_cost(MEMORY_REF_COST);
       
  4858   size(4);
       
  4859 
       
  4860   format %{ "ldr_u32 $dst,$mem\t! compressed ptr" %}
       
  4861   ins_encode %{
       
  4862     __ ldr_u32($dst$$Register, $mem$$Address);
       
  4863   %}
       
  4864   ins_pipe(iload_mem);
       
  4865 %}
       
  4866 #endif
       
  4867 
       
  4868 // Load Klass Pointer
       
  4869 instruct loadKlass(iRegP dst, memoryI mem) %{
       
  4870   match(Set dst (LoadKlass mem));
       
  4871   ins_cost(MEMORY_REF_COST);
       
  4872   size(4);
       
  4873 
       
  4874   format %{ "LDR   $dst,$mem\t! klass ptr" %}
       
  4875   ins_encode %{
       
  4876     __ ldr($dst$$Register, $mem$$Address);
       
  4877   %}
       
  4878   ins_pipe(iload_mem);
       
  4879 %}
       
  4880 
       
  4881 #ifdef _LP64
       
  4882 // Load narrow Klass Pointer
       
  4883 instruct loadNKlass(iRegN dst, memoryI mem) %{
       
  4884   match(Set dst (LoadNKlass mem));
       
  4885   ins_cost(MEMORY_REF_COST);
       
  4886   size(4);
       
  4887 
       
  4888   format %{ "ldr_u32 $dst,$mem\t! compressed klass ptr" %}
       
  4889   ins_encode %{
       
  4890     __ ldr_u32($dst$$Register, $mem$$Address);
       
  4891   %}
       
  4892   ins_pipe(iload_mem);
       
  4893 %}
       
  4894 #endif
       
  4895 
       
  4896 #ifdef AARCH64
       
  4897 // XXX This variant shouldn't be necessary if 6217251 is implemented
       
  4898 instruct loadDoff(regD dst, memoryScaledD mem, aimmX off, iRegP tmp) %{
       
  4899   match(Set dst (LoadD (AddP mem off)));
       
  4900   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
       
  4901   effect(TEMP tmp);
       
  4902   size(4 * 2);
       
  4903 
       
  4904   format %{ "ldr    $dst,$mem+$off\t! double temp=$tmp" %}
       
  4905   ins_encode %{
       
  4906     Register base = reg_to_register_object($mem$$base);
       
  4907     __ add($tmp$$Register, base, $off$$constant);
       
  4908     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  4909     __ ldr_d($dst$$FloatRegister, nmem);
       
  4910   %}
       
  4911   ins_pipe(floadD_mem);
       
  4912 %}
       
  4913 #endif
       
  4914 
       
  4915 instruct loadD(regD dst, memoryD mem) %{
       
  4916   match(Set dst (LoadD mem));
       
  4917   ins_cost(MEMORY_REF_COST);
       
  4918 
       
  4919   size(4);
       
  4920   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
       
  4921   // only LDREXD and STREXD are 64-bit single-copy atomic
       
  4922   format %{ "FLDD   $dst,$mem" %}
       
  4923   ins_encode %{
       
  4924     __ ldr_double($dst$$FloatRegister, $mem$$Address);
       
  4925   %}
       
  4926   ins_pipe(floadD_mem);
       
  4927 %}
       
  4928 
       
  4929 #ifndef AARCH64
       
  4930 // Load Double - UNaligned
       
  4931 instruct loadD_unaligned(regD_low dst, memoryF2 mem ) %{
       
  4932   match(Set dst (LoadD_unaligned mem));
       
  4933   ins_cost(MEMORY_REF_COST*2+DEFAULT_COST);
       
  4934   size(8);
       
  4935   format %{ "FLDS    $dst.lo,$mem\t! misaligned double\n"
       
  4936           "\tFLDS    $dst.hi,$mem+4\t!" %}
       
  4937   ins_encode %{
       
  4938     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  4939     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
       
  4940       __ flds($dst$$FloatRegister, Amemlo);
       
  4941       __ flds($dst$$FloatRegister->successor(), Amemhi);
       
  4942   %}
       
  4943   ins_pipe(iload_mem);
       
  4944 %}
       
  4945 #endif
       
  4946 
       
  4947 #ifdef AARCH64
       
  4948 // XXX This variant shouldn't be necessary if 6217251 is implemented
       
  4949 instruct loadFoff(regF dst, memoryScaledF mem, aimmX off, iRegP tmp) %{
       
  4950   match(Set dst (LoadF (AddP mem off)));
       
  4951   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
       
  4952   effect(TEMP tmp);
       
  4953   size(4 * 2);
       
  4954 
       
  4955   format %{ "ldr    $dst,$mem+$off\t! float temp=$tmp" %}
       
  4956   ins_encode %{
       
  4957     Register base = reg_to_register_object($mem$$base);
       
  4958     __ add($tmp$$Register, base, $off$$constant);
       
  4959     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  4960     __ ldr_s($dst$$FloatRegister, nmem);
       
  4961   %}
       
  4962   ins_pipe(floadF_mem);
       
  4963 %}
       
  4964 #endif
       
  4965 
       
  4966 instruct loadF(regF dst, memoryF mem) %{
       
  4967   match(Set dst (LoadF mem));
       
  4968 
       
  4969   ins_cost(MEMORY_REF_COST);
       
  4970   size(4);
       
  4971   format %{ "FLDS    $dst,$mem" %}
       
  4972   ins_encode %{
       
  4973     __ ldr_float($dst$$FloatRegister, $mem$$Address);
       
  4974   %}
       
  4975   ins_pipe(floadF_mem);
       
  4976 %}
       
  4977 
       
  4978 #ifdef AARCH64
       
  4979 instruct load_limmI(iRegI dst, limmI src) %{
       
  4980   match(Set dst src);
       
  4981   ins_cost(DEFAULT_COST + 1); // + 1 because MOV is preferred
       
  4982   format %{ "ORR_w  $dst, ZR, $src\t! int"  %}
       
  4983   ins_encode %{
       
  4984     __ orr_w($dst$$Register, ZR, (uintx)$src$$constant);
       
  4985   %}
       
  4986   ins_pipe(ialu_imm);
       
  4987 %}
       
  4988 #endif
       
  4989 
       
  4990 // // Load Constant
       
  4991 instruct loadConI( iRegI dst, immI src ) %{
       
  4992   match(Set dst src);
       
  4993   ins_cost(DEFAULT_COST * 3/2);
       
  4994   format %{ "MOV_SLOW    $dst, $src" %}
       
  4995   ins_encode %{
       
  4996     __ mov_slow($dst$$Register, $src$$constant);
       
  4997   %}
       
  4998   ins_pipe(ialu_hi_lo_reg);
       
  4999 %}
       
  5000 
       
  5001 instruct loadConIMov( iRegI dst, immIMov src ) %{
       
  5002   match(Set dst src);
       
  5003   size(4);
       
  5004   format %{ "MOV    $dst, $src" %}
       
  5005   ins_encode %{
       
  5006     __ mov($dst$$Register, $src$$constant);
       
  5007   %}
       
  5008   ins_pipe(ialu_imm);
       
  5009 %}
       
  5010 
       
  5011 #ifndef AARCH64
       
  5012 instruct loadConIMovn( iRegI dst, immIRotn src ) %{
       
  5013   match(Set dst src);
       
  5014   size(4);
       
  5015   format %{ "MVN    $dst, ~$src" %}
       
  5016   ins_encode %{
       
  5017     __ mvn($dst$$Register, ~$src$$constant);
       
  5018   %}
       
  5019   ins_pipe(ialu_imm_n);
       
  5020 %}
       
  5021 #endif
       
  5022 
       
  5023 instruct loadConI16( iRegI dst, immI16 src ) %{
       
  5024   match(Set dst src);
       
  5025   size(4);
       
  5026 #ifdef AARCH64
       
  5027   format %{ "MOVZ_w  $dst, $src" %}
       
  5028 #else
       
  5029   format %{ "MOVW    $dst, $src" %}
       
  5030 #endif
       
  5031   ins_encode %{
       
  5032 #ifdef AARCH64
       
  5033     __ mov_w($dst$$Register, $src$$constant);
       
  5034 #else
       
  5035     __ movw($dst$$Register, $src$$constant);
       
  5036 #endif
       
  5037   %}
       
  5038   ins_pipe(ialu_imm_n);
       
  5039 %}
       
  5040 
       
  5041 instruct loadConP(iRegP dst, immP src) %{
       
  5042   match(Set dst src);
       
  5043   ins_cost(DEFAULT_COST * 3/2);
       
  5044   format %{ "MOV_SLOW    $dst,$src\t!ptr" %}
       
  5045   ins_encode %{
       
  5046     relocInfo::relocType constant_reloc = _opnds[1]->constant_reloc();
       
  5047     intptr_t val = $src$$constant;
       
  5048     if (constant_reloc == relocInfo::oop_type) {
       
  5049       __ mov_oop($dst$$Register, (jobject)val);
       
  5050     } else if (constant_reloc == relocInfo::metadata_type) {
       
  5051       __ mov_metadata($dst$$Register, (Metadata*)val);
       
  5052     } else {
       
  5053       __ mov_slow($dst$$Register, val);
       
  5054     }
       
  5055   %}
       
  5056   ins_pipe(loadConP);
       
  5057 %}
       
  5058 
       
  5059 
       
  5060 instruct loadConP_poll(iRegP dst, immP_poll src) %{
       
  5061   match(Set dst src);
       
  5062   ins_cost(DEFAULT_COST);
       
  5063   format %{ "MOV_SLOW    $dst,$src\t!ptr" %}
       
  5064   ins_encode %{
       
  5065       __ mov_slow($dst$$Register, $src$$constant);
       
  5066   %}
       
  5067   ins_pipe(loadConP_poll);
       
  5068 %}
       
  5069 
       
  5070 #ifdef AARCH64
       
  5071 instruct loadConP0(iRegP dst, immP0 src) %{
       
  5072   match(Set dst src);
       
  5073   ins_cost(DEFAULT_COST);
       
  5074   format %{ "MOV    $dst,ZR\t!ptr" %}
       
  5075   ins_encode %{
       
  5076     __ mov($dst$$Register, ZR);
       
  5077   %}
       
  5078   ins_pipe(ialu_none);
       
  5079 %}
       
  5080 
       
  5081 instruct loadConN(iRegN dst, immN src) %{
       
  5082   match(Set dst src);
       
  5083   ins_cost(DEFAULT_COST * 3/2);
       
  5084   format %{ "SET    $dst,$src\t! compressed ptr" %}
       
  5085   ins_encode %{
       
  5086     Register dst = $dst$$Register;
       
  5087     // FIXME: use $constanttablebase?
       
  5088     __ set_narrow_oop(dst, (jobject)$src$$constant);
       
  5089   %}
       
  5090   ins_pipe(ialu_hi_lo_reg);
       
  5091 %}
       
  5092 
       
  5093 instruct loadConN0(iRegN dst, immN0 src) %{
       
  5094   match(Set dst src);
       
  5095   ins_cost(DEFAULT_COST);
       
  5096   format %{ "MOV    $dst,ZR\t! compressed ptr" %}
       
  5097   ins_encode %{
       
  5098     __ mov($dst$$Register, ZR);
       
  5099   %}
       
  5100   ins_pipe(ialu_none);
       
  5101 %}
       
  5102 
       
  5103 instruct loadConNKlass(iRegN dst, immNKlass src) %{
       
  5104   match(Set dst src);
       
  5105   ins_cost(DEFAULT_COST * 3/2);
       
  5106   format %{ "SET    $dst,$src\t! compressed klass ptr" %}
       
  5107   ins_encode %{
       
  5108     Register dst = $dst$$Register;
       
  5109     // FIXME: use $constanttablebase?
       
  5110     __ set_narrow_klass(dst, (Klass*)$src$$constant);
       
  5111   %}
       
  5112   ins_pipe(ialu_hi_lo_reg);
       
  5113 %}
       
  5114 
       
  5115 instruct load_limmL(iRegL dst, limmL src) %{
       
  5116   match(Set dst src);
       
  5117   ins_cost(DEFAULT_COST);
       
  5118   format %{ "ORR    $dst, ZR, $src\t! long"  %}
       
  5119   ins_encode %{
       
  5120     __ orr($dst$$Register, ZR, (uintx)$src$$constant);
       
  5121   %}
       
  5122   ins_pipe(loadConL);
       
  5123 %}
       
  5124 instruct load_immLMov(iRegL dst, immLMov src) %{
       
  5125   match(Set dst src);
       
  5126   ins_cost(DEFAULT_COST);
       
  5127   format %{ "MOV    $dst, $src\t! long"  %}
       
  5128   ins_encode %{
       
  5129     __ mov($dst$$Register, $src$$constant);
       
  5130   %}
       
  5131   ins_pipe(loadConL);
       
  5132 %}
       
  5133 instruct loadConL(iRegL dst, immL src) %{
       
  5134   match(Set dst src);
       
  5135   ins_cost(DEFAULT_COST * 4); // worst case
       
  5136   format %{ "mov_slow   $dst, $src\t! long"  %}
       
  5137   ins_encode %{
       
  5138     // FIXME: use $constanttablebase?
       
  5139     __ mov_slow($dst$$Register, $src$$constant);
       
  5140   %}
       
  5141   ins_pipe(loadConL);
       
  5142 %}
       
  5143 #else
       
  5144 instruct loadConL(iRegL dst, immL src) %{
       
  5145   match(Set dst src);
       
  5146   ins_cost(DEFAULT_COST * 4);
       
  5147   format %{ "MOV_SLOW   $dst.lo, $src & 0x0FFFFFFFFL \t! long\n\t"
       
  5148             "MOV_SLOW   $dst.hi, $src >> 32" %}
       
  5149   ins_encode %{
       
  5150     __ mov_slow(reg_to_register_object($dst$$reg), $src$$constant & 0x0FFFFFFFFL);
       
  5151     __ mov_slow(reg_to_register_object($dst$$reg + 1), ((julong)($src$$constant)) >> 32);
       
  5152   %}
       
  5153   ins_pipe(loadConL);
       
  5154 %}
       
  5155 
       
  5156 instruct loadConL16( iRegL dst, immL16 src ) %{
       
  5157   match(Set dst src);
       
  5158   ins_cost(DEFAULT_COST * 2);
       
  5159 
       
  5160   size(8);
       
  5161   format %{ "MOVW    $dst.lo, $src \n\t"
       
  5162             "MOVW    $dst.hi, 0 \n\t" %}
       
  5163   ins_encode %{
       
  5164     __ movw($dst$$Register, $src$$constant);
       
  5165     __ movw($dst$$Register->successor(), 0);
       
  5166   %}
       
  5167   ins_pipe(ialu_imm);
       
  5168 %}
       
  5169 #endif
       
  5170 
       
  5171 instruct loadConF_imm8(regF dst, imm8F src) %{
       
  5172   match(Set dst src);
       
  5173   ins_cost(DEFAULT_COST);
       
  5174   size(4);
       
  5175 
       
  5176   format %{ "FCONSTS      $dst, $src"%}
       
  5177 
       
  5178   ins_encode %{
       
  5179     __ fconsts($dst$$FloatRegister, Assembler::float_num($src$$constant).imm8());
       
  5180   %}
       
  5181   ins_pipe(loadConFD); // FIXME
       
  5182 %}
       
  5183 
       
  5184 #ifdef AARCH64
       
  5185 instruct loadIConF(iRegI dst, immF src) %{
       
  5186   match(Set dst src);
       
  5187   ins_cost(DEFAULT_COST * 2);
       
  5188 
       
  5189   format %{ "MOV_SLOW  $dst, $src\t! loadIConF"  %}
       
  5190 
       
  5191   ins_encode %{
       
  5192     // FIXME revisit once 6961697 is in
       
  5193     union {
       
  5194       jfloat f;
       
  5195       int i;
       
  5196     } v;
       
  5197     v.f = $src$$constant;
       
  5198     __ mov_slow($dst$$Register, v.i);
       
  5199   %}
       
  5200   ins_pipe(ialu_imm);
       
  5201 %}
       
  5202 #endif
       
  5203 
       
  5204 instruct loadConF(regF dst, immF src, iRegI tmp) %{
       
  5205   match(Set dst src);
       
  5206   ins_cost(DEFAULT_COST * 2);
       
  5207   effect(TEMP tmp);
       
  5208   size(3*4);
       
  5209 
       
  5210   format %{ "MOV_SLOW  $tmp, $src\n\t"
       
  5211             "FMSR      $dst, $tmp"%}
       
  5212 
       
  5213   ins_encode %{
       
  5214     // FIXME revisit once 6961697 is in
       
  5215     union {
       
  5216       jfloat f;
       
  5217       int i;
       
  5218     } v;
       
  5219     v.f = $src$$constant;
       
  5220     __ mov_slow($tmp$$Register, v.i);
       
  5221     __ fmsr($dst$$FloatRegister, $tmp$$Register);
       
  5222   %}
       
  5223   ins_pipe(loadConFD); // FIXME
       
  5224 %}
       
  5225 
       
  5226 instruct loadConD_imm8(regD dst, imm8D src) %{
       
  5227   match(Set dst src);
       
  5228   ins_cost(DEFAULT_COST);
       
  5229   size(4);
       
  5230 
       
  5231   format %{ "FCONSTD      $dst, $src"%}
       
  5232 
       
  5233   ins_encode %{
       
  5234     __ fconstd($dst$$FloatRegister, Assembler::double_num($src$$constant).imm8());
       
  5235   %}
       
  5236   ins_pipe(loadConFD); // FIXME
       
  5237 %}
       
  5238 
       
  5239 instruct loadConD(regD dst, immD src, iRegP tmp) %{
       
  5240   match(Set dst src);
       
  5241   effect(TEMP tmp);
       
  5242   ins_cost(MEMORY_REF_COST);
       
  5243   format %{ "FLDD  $dst, [$constanttablebase + $constantoffset]\t! load from constant table: double=$src" %}
       
  5244 
       
  5245   ins_encode %{
       
  5246     Register r = $constanttablebase;
       
  5247     int offset  = $constantoffset($src);
       
  5248     if (!is_memoryD(offset)) {                // can't use a predicate
       
  5249                                               // in load constant instructs
       
  5250       __ add_slow($tmp$$Register, r, offset);
       
  5251       r = $tmp$$Register;
       
  5252       offset = 0;
       
  5253     }
       
  5254     __ ldr_double($dst$$FloatRegister, Address(r, offset));
       
  5255   %}
       
  5256   ins_pipe(loadConFD);
       
  5257 %}
       
  5258 
       
  5259 // Prefetch instructions.
       
  5260 // Must be safe to execute with invalid address (cannot fault).
       
  5261 
       
  5262 instruct prefetchAlloc_mp( memoryP mem ) %{
       
  5263   predicate(os::is_MP());
       
  5264   match( PrefetchAllocation mem );
       
  5265   ins_cost(MEMORY_REF_COST);
       
  5266   size(4);
       
  5267 
       
  5268   format %{ "PLDW $mem\t! Prefetch allocation" %}
       
  5269   ins_encode %{
       
  5270 #ifdef AARCH64
       
  5271     __ prfm(pstl1keep, $mem$$Address);
       
  5272 #else
       
  5273     __ pldw($mem$$Address);
       
  5274 #endif
       
  5275   %}
       
  5276   ins_pipe(iload_mem);
       
  5277 %}
       
  5278 
       
  5279 instruct prefetchAlloc_sp( memoryP mem ) %{
       
  5280   predicate(!os::is_MP());
       
  5281   match( PrefetchAllocation mem );
       
  5282   ins_cost(MEMORY_REF_COST);
       
  5283   size(4);
       
  5284 
       
  5285   format %{ "PLD $mem\t! Prefetch allocation" %}
       
  5286   ins_encode %{
       
  5287 #ifdef AARCH64
       
  5288     __ prfm(pstl1keep, $mem$$Address);
       
  5289 #else
       
  5290     __ pld($mem$$Address);
       
  5291 #endif
       
  5292   %}
       
  5293   ins_pipe(iload_mem);
       
  5294 %}
       
  5295 
       
  5296 //----------Store Instructions-------------------------------------------------
       
  5297 // Store Byte
       
  5298 instruct storeB(memoryB mem, store_RegI src) %{
       
  5299   match(Set mem (StoreB mem src));
       
  5300   ins_cost(MEMORY_REF_COST);
       
  5301 
       
  5302   size(4);
       
  5303   format %{ "STRB    $src,$mem\t! byte" %}
       
  5304   ins_encode %{
       
  5305     __ strb($src$$Register, $mem$$Address);
       
  5306   %}
       
  5307   ins_pipe(istore_mem_reg);
       
  5308 %}
       
  5309 
       
  5310 instruct storeCM(memoryB mem, store_RegI src) %{
       
  5311   match(Set mem (StoreCM mem src));
       
  5312   ins_cost(MEMORY_REF_COST);
       
  5313 
       
  5314   size(4);
       
  5315   format %{ "STRB    $src,$mem\t! CMS card-mark byte" %}
       
  5316   ins_encode %{
       
  5317     __ strb($src$$Register, $mem$$Address);
       
  5318   %}
       
  5319   ins_pipe(istore_mem_reg);
       
  5320 %}
       
  5321 
       
  5322 // Store Char/Short
       
  5323 
       
  5324 #ifdef AARCH64
       
  5325 // XXX This variant shouldn't be necessary if 6217251 is implemented
       
  5326 instruct storeCoff(store_RegI src, memoryScaledS mem, aimmX off, iRegP tmp) %{
       
  5327   match(Set mem (StoreC (AddP mem off) src));
       
  5328   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
       
  5329   effect(TEMP tmp);
       
  5330   size(4 * 2);
       
  5331 
       
  5332   format %{ "STRH    $src,$mem+$off\t! short temp=$tmp" %}
       
  5333   ins_encode %{
       
  5334     Register base = reg_to_register_object($mem$$base);
       
  5335     __ add($tmp$$Register, base, $off$$constant);
       
  5336     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  5337     __ strh($src$$Register, nmem);
       
  5338   %}
       
  5339   ins_pipe(istore_mem_reg);
       
  5340 %}
       
  5341 #endif
       
  5342 
       
  5343 instruct storeC(memoryS mem, store_RegI src) %{
       
  5344   match(Set mem (StoreC mem src));
       
  5345   ins_cost(MEMORY_REF_COST);
       
  5346 
       
  5347   size(4);
       
  5348   format %{ "STRH    $src,$mem\t! short" %}
       
  5349   ins_encode %{
       
  5350     __ strh($src$$Register, $mem$$Address);
       
  5351   %}
       
  5352   ins_pipe(istore_mem_reg);
       
  5353 %}
       
  5354 
       
  5355 // Store Integer
       
  5356 
       
  5357 #ifdef AARCH64
       
  5358 // XXX This variant shouldn't be necessary if 6217251 is implemented
       
  5359 instruct storeIoff(store_RegI src, memoryScaledI mem, aimmX off, iRegP tmp) %{
       
  5360   match(Set mem (StoreI (AddP mem off) src));
       
  5361   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
       
  5362   effect(TEMP tmp);
       
  5363   size(4 * 2);
       
  5364 
       
  5365   format %{ "str_32 $src,$mem+$off\t! int temp=$tmp" %}
       
  5366   ins_encode %{
       
  5367     Register base = reg_to_register_object($mem$$base);
       
  5368     __ add($tmp$$Register, base, $off$$constant);
       
  5369     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  5370     __ str_32($src$$Register, nmem);
       
  5371   %}
       
  5372   ins_pipe(istore_mem_reg);
       
  5373 %}
       
  5374 #endif
       
  5375 
       
  5376 instruct storeI(memoryI mem, store_RegI src) %{
       
  5377   match(Set mem (StoreI mem src));
       
  5378   ins_cost(MEMORY_REF_COST);
       
  5379 
       
  5380   size(4);
       
  5381   format %{ "str_32 $src,$mem" %}
       
  5382   ins_encode %{
       
  5383     __ str_32($src$$Register, $mem$$Address);
       
  5384   %}
       
  5385   ins_pipe(istore_mem_reg);
       
  5386 %}
       
  5387 
       
  5388 // Store Long
       
  5389 
       
  5390 #ifdef AARCH64
       
  5391 // XXX This variant shouldn't be necessary if 6217251 is implemented
       
  5392 instruct storeLoff(store_RegLd src, memoryScaledL mem, aimmX off, iRegP tmp) %{
       
  5393   match(Set mem (StoreL (AddP mem off) src));
       
  5394   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
       
  5395   effect(TEMP tmp);
       
  5396   size(4 * 2);
       
  5397 
       
  5398   format %{ "str_64 $src,$mem+$off\t! long temp=$tmp" %}
       
  5399   ins_encode %{
       
  5400     Register base = reg_to_register_object($mem$$base);
       
  5401     __ add($tmp$$Register, base, $off$$constant);
       
  5402     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  5403     __ str_64($src$$Register, nmem);
       
  5404   %}
       
  5405   ins_pipe(istore_mem_reg);
       
  5406 %}
       
  5407 #endif
       
  5408 
       
  5409 instruct storeL(memoryL mem, store_RegLd src) %{
       
  5410 #ifdef AARCH64
       
  5411   // already atomic for Aarch64
       
  5412 #else
       
  5413   predicate(!((StoreLNode*)n)->require_atomic_access());
       
  5414 #endif
       
  5415   match(Set mem (StoreL mem src));
       
  5416   ins_cost(MEMORY_REF_COST);
       
  5417 
       
  5418   size(4);
       
  5419   format %{ "str_64  $src,$mem\t! long\n\t" %}
       
  5420 
       
  5421   ins_encode %{
       
  5422     __ str_64($src$$Register, $mem$$Address);
       
  5423   %}
       
  5424   ins_pipe(istore_mem_reg);
       
  5425 %}
       
  5426 
       
  5427 #ifndef AARCH64
       
  5428 instruct storeL_2instr(memorylong mem, iRegL src) %{
       
  5429   predicate(!((StoreLNode*)n)->require_atomic_access());
       
  5430   match(Set mem (StoreL mem src));
       
  5431   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
       
  5432 
       
  5433   size(8);
       
  5434   format %{ "STR    $src.lo,$mem\t! long\n\t"
       
  5435             "STR    $src.hi,$mem+4" %}
       
  5436 
       
  5437   ins_encode %{
       
  5438     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  5439     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
       
  5440     __ str($src$$Register, Amemlo);
       
  5441     __ str($src$$Register->successor(), Amemhi);
       
  5442   %}
       
  5443   ins_pipe(istore_mem_reg);
       
  5444 %}
       
  5445 
       
  5446 instruct storeL_volatile(indirect mem, iRegL src) %{
       
  5447   predicate(((StoreLNode*)n)->require_atomic_access());
       
  5448   match(Set mem (StoreL mem src));
       
  5449   ins_cost(MEMORY_REF_COST);
       
  5450   size(4);
       
  5451   format %{ "STMIA    $src,$mem\t! long" %}
       
  5452   ins_encode %{
       
  5453     // FIXME: why is stmia considered atomic?  Should be strexd
       
  5454     RegisterSet set($src$$Register);
       
  5455     set = set | reg_to_register_object($src$$reg + 1);
       
  5456     __ stmia(reg_to_register_object($mem$$base), set);
       
  5457   %}
       
  5458   ins_pipe(istore_mem_reg);
       
  5459 %}
       
  5460 #endif // !AARCH64
       
  5461 
       
  5462 #ifndef AARCH64
       
  5463 instruct storeL_volatile_fp(memoryD mem, iRegL src) %{
       
  5464   predicate(((StoreLNode*)n)->require_atomic_access());
       
  5465   match(Set mem (StoreL mem src));
       
  5466   ins_cost(MEMORY_REF_COST);
       
  5467   size(8);
       
  5468   format %{ "FMDRR    S14, $src\t! long \n\t"
       
  5469             "FSTD     S14, $mem" %}
       
  5470   ins_encode %{
       
  5471     __ fmdrr(S14, $src$$Register, $src$$Register->successor());
       
  5472     __ fstd(S14, $mem$$Address);
       
  5473   %}
       
  5474   ins_pipe(istore_mem_reg);
       
  5475 %}
       
  5476 #endif
       
  5477 
       
  5478 #ifdef XXX
       
  5479 // Move SP Pointer
       
  5480 //instruct movSP(sp_ptr_RegP dst, SPRegP src) %{
       
  5481 //instruct movSP(iRegP dst, SPRegP src) %{
       
  5482 instruct movSP(store_ptr_RegP dst, SPRegP src) %{
       
  5483   match(Set dst src);
       
  5484 //predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con == TypeFunc::FramePtr);
       
  5485   ins_cost(MEMORY_REF_COST);
       
  5486   size(4);
       
  5487 
       
  5488   format %{ "MOV    $dst,$src\t! SP ptr\n\t" %}
       
  5489   ins_encode %{
       
  5490     assert(false, "XXX1 got here");
       
  5491     __ mov($dst$$Register, SP);
       
  5492     __ mov($dst$$Register, $src$$Register);
       
  5493   %}
       
  5494   ins_pipe(ialu_reg);
       
  5495 %}
       
  5496 #endif
       
  5497 
       
  5498 #ifdef AARCH64
       
  5499 // FIXME
       
  5500 // Store SP Pointer
       
  5501 instruct storeSP(memoryP mem, SPRegP src, iRegP tmp) %{
       
  5502   match(Set mem (StoreP mem src));
       
  5503   predicate(_kids[1]->_leaf->is_Proj() && _kids[1]->_leaf->as_Proj()->_con == TypeFunc::FramePtr);
       
  5504   // Multiple StoreP rules, different only in register mask.
       
  5505   // Matcher makes the last always valid.  The others will
       
  5506   // only be valid if they cost less than the last valid
       
  5507   // rule.  So cost(rule1) < cost(rule2) < cost(last)
       
  5508   // Unlike immediates, register constraints are not checked
       
  5509   // at match time.
       
  5510   ins_cost(MEMORY_REF_COST+DEFAULT_COST+4);
       
  5511   effect(TEMP tmp);
       
  5512   size(8);
       
  5513 
       
  5514   format %{ "MOV    $tmp,$src\t! SP ptr\n\t"
       
  5515             "STR    $tmp,$mem\t! SP ptr" %}
       
  5516   ins_encode %{
       
  5517     assert($src$$Register == SP, "SP expected");
       
  5518     __ mov($tmp$$Register, $src$$Register);
       
  5519     __ str($tmp$$Register, $mem$$Address);
       
  5520   %}
       
  5521   ins_pipe(istore_mem_spORreg); // FIXME
       
  5522 %}
       
  5523 #endif // AARCH64
       
  5524 
       
  5525 // Store Pointer
       
  5526 
       
  5527 #ifdef AARCH64
       
  5528 // XXX This variant shouldn't be necessary if 6217251 is implemented
       
  5529 instruct storePoff(store_ptr_RegP src, memoryScaledP mem, aimmX off, iRegP tmp) %{
       
  5530   predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con != TypeFunc::FramePtr);
       
  5531   match(Set mem (StoreP (AddP mem off) src));
       
  5532   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
       
  5533   effect(TEMP tmp);
       
  5534   size(4 * 2);
       
  5535 
       
  5536   format %{ "STR    $src,$mem+$off\t! ptr temp=$tmp" %}
       
  5537   ins_encode %{
       
  5538     Register base = reg_to_register_object($mem$$base);
       
  5539     __ add($tmp$$Register, base, $off$$constant);
       
  5540     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  5541     __ str($src$$Register, nmem);
       
  5542   %}
       
  5543   ins_pipe(istore_mem_reg);
       
  5544 %}
       
  5545 #endif
       
  5546 
       
  5547 instruct storeP(memoryP mem, store_ptr_RegP src) %{
       
  5548   match(Set mem (StoreP mem src));
       
  5549 #ifdef AARCH64
       
  5550   predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con != TypeFunc::FramePtr);
       
  5551 #endif
       
  5552   ins_cost(MEMORY_REF_COST);
       
  5553   size(4);
       
  5554 
       
  5555   format %{ "STR    $src,$mem\t! ptr" %}
       
  5556   ins_encode %{
       
  5557     __ str($src$$Register, $mem$$Address);
       
  5558   %}
       
  5559   ins_pipe(istore_mem_spORreg);
       
  5560 %}
       
  5561 
       
  5562 #ifdef AARCH64
       
  5563 // Store NULL Pointer
       
  5564 instruct storeP0(memoryP mem, immP0 src) %{
       
  5565   match(Set mem (StoreP mem src));
       
  5566   ins_cost(MEMORY_REF_COST);
       
  5567   size(4);
       
  5568 
       
  5569   format %{ "STR    ZR,$mem\t! ptr" %}
       
  5570   ins_encode %{
       
  5571     __ str(ZR, $mem$$Address);
       
  5572   %}
       
  5573   ins_pipe(istore_mem_spORreg);
       
  5574 %}
       
  5575 #endif // AARCH64
       
  5576 
       
  5577 #ifdef _LP64
       
  5578 // Store Compressed Pointer
       
  5579 
       
  5580 #ifdef AARCH64
       
  5581 // XXX This variant shouldn't be necessary if 6217251 is implemented
       
  5582 instruct storeNoff(store_RegN src, memoryScaledI mem, aimmX off, iRegP tmp) %{
       
  5583   match(Set mem (StoreN (AddP mem off) src));
       
  5584   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
       
  5585   effect(TEMP tmp);
       
  5586   size(4 * 2);
       
  5587 
       
  5588   format %{ "str_32 $src,$mem+$off\t! compressed ptr temp=$tmp" %}
       
  5589   ins_encode %{
       
  5590     Register base = reg_to_register_object($mem$$base);
       
  5591     __ add($tmp$$Register, base, $off$$constant);
       
  5592     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  5593     __ str_32($src$$Register, nmem);
       
  5594   %}
       
  5595   ins_pipe(istore_mem_reg);
       
  5596 %}
       
  5597 #endif
       
  5598 
       
  5599 instruct storeN(memoryI mem, store_RegN src) %{
       
  5600   match(Set mem (StoreN mem src));
       
  5601   ins_cost(MEMORY_REF_COST);
       
  5602   size(4);
       
  5603 
       
  5604   format %{ "str_32 $src,$mem\t! compressed ptr" %}
       
  5605   ins_encode %{
       
  5606     __ str_32($src$$Register, $mem$$Address);
       
  5607   %}
       
  5608   ins_pipe(istore_mem_reg);
       
  5609 %}
       
  5610 
       
  5611 #ifdef AARCH64
       
  5612 // Store NULL Pointer
       
  5613 instruct storeN0(memoryI mem, immN0 src) %{
       
  5614   match(Set mem (StoreN mem src));
       
  5615   ins_cost(MEMORY_REF_COST);
       
  5616   size(4);
       
  5617 
       
  5618   format %{ "str_32 ZR,$mem\t! compressed ptr" %}
       
  5619   ins_encode %{
       
  5620     __ str_32(ZR, $mem$$Address);
       
  5621   %}
       
  5622   ins_pipe(istore_mem_reg);
       
  5623 %}
       
  5624 #endif
       
  5625 
       
  5626 // Store Compressed Klass Pointer
       
  5627 instruct storeNKlass(memoryI mem, store_RegN src) %{
       
  5628   match(Set mem (StoreNKlass mem src));
       
  5629   ins_cost(MEMORY_REF_COST);
       
  5630   size(4);
       
  5631 
       
  5632   format %{ "str_32 $src,$mem\t! compressed klass ptr" %}
       
  5633   ins_encode %{
       
  5634     __ str_32($src$$Register, $mem$$Address);
       
  5635   %}
       
  5636   ins_pipe(istore_mem_reg);
       
  5637 %}
       
  5638 #endif
       
  5639 
       
  5640 // Store Double
       
  5641 
       
  5642 #ifdef AARCH64
       
  5643 // XXX This variant shouldn't be necessary if 6217251 is implemented
       
  5644 instruct storeDoff(regD src, memoryScaledD mem, aimmX off, iRegP tmp) %{
       
  5645   match(Set mem (StoreD (AddP mem off) src));
       
  5646   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
       
  5647   effect(TEMP tmp);
       
  5648   size(4 * 2);
       
  5649 
       
  5650   format %{ "STR    $src,$mem+$off\t! double temp=$tmp" %}
       
  5651   ins_encode %{
       
  5652     Register base = reg_to_register_object($mem$$base);
       
  5653     __ add($tmp$$Register, base, $off$$constant);
       
  5654     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  5655     __ str_d($src$$FloatRegister, nmem);
       
  5656   %}
       
  5657   ins_pipe(fstoreD_mem_reg);
       
  5658 %}
       
  5659 #endif
       
  5660 
       
  5661 instruct storeD(memoryD mem, regD src) %{
       
  5662   match(Set mem (StoreD mem src));
       
  5663   ins_cost(MEMORY_REF_COST);
       
  5664 
       
  5665   size(4);
       
  5666   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
       
  5667   // only LDREXD and STREXD are 64-bit single-copy atomic
       
  5668   format %{ "FSTD   $src,$mem" %}
       
  5669   ins_encode %{
       
  5670     __ str_double($src$$FloatRegister, $mem$$Address);
       
  5671   %}
       
  5672   ins_pipe(fstoreD_mem_reg);
       
  5673 %}
       
  5674 
       
  5675 #ifdef AARCH64
       
  5676 instruct movI2F(regF dst, iRegI src) %{
       
  5677   match(Set dst src);
       
  5678   size(4);
       
  5679 
       
  5680   format %{ "FMOV_sw $dst,$src\t! movI2F" %}
       
  5681   ins_encode %{
       
  5682     __ fmov_sw($dst$$FloatRegister, $src$$Register);
       
  5683   %}
       
  5684   ins_pipe(ialu_reg); // FIXME
       
  5685 %}
       
  5686 
       
  5687 instruct movF2I(iRegI dst, regF src) %{
       
  5688   match(Set dst src);
       
  5689   size(4);
       
  5690 
       
  5691   format %{ "FMOV_ws $dst,$src\t! movF2I" %}
       
  5692   ins_encode %{
       
  5693     __ fmov_ws($dst$$Register, $src$$FloatRegister);
       
  5694   %}
       
  5695   ins_pipe(ialu_reg); // FIXME
       
  5696 %}
       
  5697 #endif
       
  5698 
       
  5699 // Store Float
       
  5700 
       
  5701 #ifdef AARCH64
       
  5702 // XXX This variant shouldn't be necessary if 6217251 is implemented
       
  5703 instruct storeFoff(regF src, memoryScaledF mem, aimmX off, iRegP tmp) %{
       
  5704   match(Set mem (StoreF (AddP mem off) src));
       
  5705   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
       
  5706   effect(TEMP tmp);
       
  5707   size(4 * 2);
       
  5708 
       
  5709   format %{ "str_s  $src,$mem+$off\t! float temp=$tmp" %}
       
  5710   ins_encode %{
       
  5711     Register base = reg_to_register_object($mem$$base);
       
  5712     __ add($tmp$$Register, base, $off$$constant);
       
  5713     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
       
  5714     __ str_s($src$$FloatRegister, nmem);
       
  5715   %}
       
  5716   ins_pipe(fstoreF_mem_reg);
       
  5717 %}
       
  5718 #endif
       
  5719 
       
  5720 instruct storeF( memoryF mem, regF src) %{
       
  5721   match(Set mem (StoreF mem src));
       
  5722   ins_cost(MEMORY_REF_COST);
       
  5723 
       
  5724   size(4);
       
  5725   format %{ "FSTS    $src,$mem" %}
       
  5726   ins_encode %{
       
  5727     __ str_float($src$$FloatRegister, $mem$$Address);
       
  5728   %}
       
  5729   ins_pipe(fstoreF_mem_reg);
       
  5730 %}
       
  5731 
       
  5732 #ifdef AARCH64
       
  5733 // Convert oop pointer into compressed form
       
  5734 instruct encodeHeapOop(iRegN dst, iRegP src, flagsReg ccr) %{
       
  5735   predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
       
  5736   match(Set dst (EncodeP src));
       
  5737   effect(KILL ccr);
       
  5738   format %{ "encode_heap_oop $dst, $src" %}
       
  5739   ins_encode %{
       
  5740     __ encode_heap_oop($dst$$Register, $src$$Register);
       
  5741   %}
       
  5742   ins_pipe(ialu_reg);
       
  5743 %}
       
  5744 
       
  5745 instruct encodeHeapOop_not_null(iRegN dst, iRegP src) %{
       
  5746   predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
       
  5747   match(Set dst (EncodeP src));
       
  5748   format %{ "encode_heap_oop_not_null $dst, $src" %}
       
  5749   ins_encode %{
       
  5750     __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
       
  5751   %}
       
  5752   ins_pipe(ialu_reg);
       
  5753 %}
       
  5754 
       
  5755 instruct decodeHeapOop(iRegP dst, iRegN src, flagsReg ccr) %{
       
  5756   predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
       
  5757             n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant);
       
  5758   match(Set dst (DecodeN src));
       
  5759   effect(KILL ccr);
       
  5760   format %{ "decode_heap_oop $dst, $src" %}
       
  5761   ins_encode %{
       
  5762     __ decode_heap_oop($dst$$Register, $src$$Register);
       
  5763   %}
       
  5764   ins_pipe(ialu_reg);
       
  5765 %}
       
  5766 
       
  5767 instruct decodeHeapOop_not_null(iRegP dst, iRegN src) %{
       
  5768   predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
       
  5769             n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant);
       
  5770   match(Set dst (DecodeN src));
       
  5771   format %{ "decode_heap_oop_not_null $dst, $src" %}
       
  5772   ins_encode %{
       
  5773     __ decode_heap_oop_not_null($dst$$Register, $src$$Register);
       
  5774   %}
       
  5775   ins_pipe(ialu_reg);
       
  5776 %}
       
  5777 
       
  5778 instruct encodeKlass_not_null(iRegN dst, iRegP src) %{
       
  5779   match(Set dst (EncodePKlass src));
       
  5780   format %{ "encode_klass_not_null $dst, $src" %}
       
  5781   ins_encode %{
       
  5782     __ encode_klass_not_null($dst$$Register, $src$$Register);
       
  5783   %}
       
  5784   ins_pipe(ialu_reg);
       
  5785 %}
       
  5786 
       
  5787 instruct decodeKlass_not_null(iRegP dst, iRegN src) %{
       
  5788   match(Set dst (DecodeNKlass src));
       
  5789   format %{ "decode_klass_not_null $dst, $src" %}
       
  5790   ins_encode %{
       
  5791     __ decode_klass_not_null($dst$$Register, $src$$Register);
       
  5792   %}
       
  5793   ins_pipe(ialu_reg);
       
  5794 %}
       
  5795 #endif // AARCH64
       
  5796 
       
  5797 //----------MemBar Instructions-----------------------------------------------
       
  5798 // Memory barrier flavors
       
  5799 
       
  5800 // TODO: take advantage of Aarch64 load-acquire, store-release, etc
       
  5801 // pattern-match out unnecessary membars
       
  5802 instruct membar_storestore() %{
       
  5803   match(MemBarStoreStore);
       
  5804   ins_cost(4*MEMORY_REF_COST);
       
  5805 
       
  5806   size(4);
       
  5807   format %{ "MEMBAR-storestore" %}
       
  5808   ins_encode %{
       
  5809     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore), noreg);
       
  5810   %}
       
  5811   ins_pipe(long_memory_op);
       
  5812 %}
       
  5813 
       
  5814 instruct membar_acquire() %{
       
  5815   match(MemBarAcquire);
       
  5816   match(LoadFence);
       
  5817   ins_cost(4*MEMORY_REF_COST);
       
  5818 
       
  5819   size(4);
       
  5820   format %{ "MEMBAR-acquire" %}
       
  5821   ins_encode %{
       
  5822     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), noreg);
       
  5823   %}
       
  5824   ins_pipe(long_memory_op);
       
  5825 %}
       
  5826 
       
  5827 instruct membar_acquire_lock() %{
       
  5828   match(MemBarAcquireLock);
       
  5829   ins_cost(0);
       
  5830 
       
  5831   size(0);
       
  5832   format %{ "!MEMBAR-acquire (CAS in prior FastLock so empty encoding)" %}
       
  5833   ins_encode( );
       
  5834   ins_pipe(empty);
       
  5835 %}
       
  5836 
       
  5837 instruct membar_release() %{
       
  5838   match(MemBarRelease);
       
  5839   match(StoreFence);
       
  5840   ins_cost(4*MEMORY_REF_COST);
       
  5841 
       
  5842   size(4);
       
  5843   format %{ "MEMBAR-release" %}
       
  5844   ins_encode %{
       
  5845     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), noreg);
       
  5846   %}
       
  5847   ins_pipe(long_memory_op);
       
  5848 %}
       
  5849 
       
  5850 instruct membar_release_lock() %{
       
  5851   match(MemBarReleaseLock);
       
  5852   ins_cost(0);
       
  5853 
       
  5854   size(0);
       
  5855   format %{ "!MEMBAR-release (CAS in succeeding FastUnlock so empty encoding)" %}
       
  5856   ins_encode( );
       
  5857   ins_pipe(empty);
       
  5858 %}
       
  5859 
       
  5860 instruct membar_volatile() %{
       
  5861   match(MemBarVolatile);
       
  5862   ins_cost(4*MEMORY_REF_COST);
       
  5863 
       
  5864   size(4);
       
  5865   format %{ "MEMBAR-volatile" %}
       
  5866   ins_encode %{
       
  5867     __ membar(MacroAssembler::StoreLoad, noreg);
       
  5868   %}
       
  5869   ins_pipe(long_memory_op);
       
  5870 %}
       
  5871 
       
  5872 instruct unnecessary_membar_volatile() %{
       
  5873   match(MemBarVolatile);
       
  5874   predicate(Matcher::post_store_load_barrier(n));
       
  5875   ins_cost(0);
       
  5876 
       
  5877   size(0);
       
  5878   format %{ "!MEMBAR-volatile (unnecessary so empty encoding)" %}
       
  5879   ins_encode( );
       
  5880   ins_pipe(empty);
       
  5881 %}
       
  5882 
       
  5883 //----------Register Move Instructions-----------------------------------------
       
  5884 // instruct roundDouble_nop(regD dst) %{
       
  5885 //   match(Set dst (RoundDouble dst));
       
  5886 //   ins_pipe(empty);
       
  5887 // %}
       
  5888 
       
  5889 
       
  5890 // instruct roundFloat_nop(regF dst) %{
       
  5891 //   match(Set dst (RoundFloat dst));
       
  5892 //   ins_pipe(empty);
       
  5893 // %}
       
  5894 
       
  5895 
       
  5896 #ifdef AARCH64
       
  5897 // 0 constant in register
       
  5898 instruct zrImmI0(ZRRegI dst, immI0 imm) %{
       
  5899   match(Set dst imm);
       
  5900   size(0);
       
  5901   ins_cost(0);
       
  5902 
       
  5903   format %{ "! ZR (int 0)" %}
       
  5904   ins_encode( /*empty encoding*/ );
       
  5905   ins_pipe(ialu_none);
       
  5906 %}
       
  5907 
       
  5908 // 0 constant in register
       
  5909 instruct zrImmL0(ZRRegL dst, immL0 imm) %{
       
  5910   match(Set dst imm);
       
  5911   size(0);
       
  5912   ins_cost(0);
       
  5913 
       
  5914   format %{ "! ZR (long 0)" %}
       
  5915   ins_encode( /*empty encoding*/ );
       
  5916   ins_pipe(ialu_none);
       
  5917 %}
       
  5918 
       
  5919 #ifdef XXX
       
  5920 // 0 constant in register
       
  5921 instruct zrImmN0(ZRRegN dst, immN0 imm) %{
       
  5922   match(Set dst imm);
       
  5923   size(0);
       
  5924   ins_cost(0);
       
  5925 
       
  5926   format %{ "! ZR (compressed pointer NULL)" %}
       
  5927   ins_encode( /*empty encoding*/ );
       
  5928   ins_pipe(ialu_none);
       
  5929 %}
       
  5930 
       
  5931 // 0 constant in register
       
  5932 instruct zrImmP0(ZRRegP dst, immP0 imm) %{
       
  5933   match(Set dst imm);
       
  5934   size(0);
       
  5935   ins_cost(0);
       
  5936 
       
  5937   format %{ "! ZR (NULL)" %}
       
  5938   ins_encode( /*empty encoding*/ );
       
  5939   ins_pipe(ialu_none);
       
  5940 %}
       
  5941 #endif
       
  5942 #endif // AARCH64
       
  5943 
       
  5944 // Cast Index to Pointer for unsafe natives
       
  5945 instruct castX2P(iRegX src, iRegP dst) %{
       
  5946   match(Set dst (CastX2P src));
       
  5947 
       
  5948   format %{ "MOV    $dst,$src\t! IntX->Ptr if $dst != $src" %}
       
  5949   ins_encode %{
       
  5950     if ($dst$$Register !=  $src$$Register) {
       
  5951       __ mov($dst$$Register, $src$$Register);
       
  5952     }
       
  5953   %}
       
  5954   ins_pipe(ialu_reg);
       
  5955 %}
       
  5956 
       
  5957 // Cast Pointer to Index for unsafe natives
       
  5958 instruct castP2X(iRegP src, iRegX dst) %{
       
  5959   match(Set dst (CastP2X src));
       
  5960 
       
  5961   format %{ "MOV    $dst,$src\t! Ptr->IntX if $dst != $src" %}
       
  5962   ins_encode %{
       
  5963     if ($dst$$Register !=  $src$$Register) {
       
  5964       __ mov($dst$$Register, $src$$Register);
       
  5965     }
       
  5966   %}
       
  5967   ins_pipe(ialu_reg);
       
  5968 %}
       
  5969 
       
  5970 #ifndef AARCH64
       
  5971 //----------Conditional Move---------------------------------------------------
       
  5972 // Conditional move
       
  5973 instruct cmovIP_reg(cmpOpP cmp, flagsRegP pcc, iRegI dst, iRegI src) %{
       
  5974   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
       
  5975   ins_cost(150);
       
  5976   size(4);
       
  5977   format %{ "MOV$cmp  $dst,$src\t! int" %}
       
  5978   ins_encode %{
       
  5979     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
  5980   %}
       
  5981   ins_pipe(ialu_reg);
       
  5982 %}
       
  5983 #endif
       
  5984 
       
  5985 #ifdef AARCH64
       
  5986 instruct cmovI_reg3(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src1, iRegI src2) %{
       
  5987   match(Set dst (CMoveI (Binary cmp icc) (Binary src2 src1)));
       
  5988   ins_cost(150);
       
  5989   size(4);
       
  5990   format %{ "CSEL $dst,$src1,$src2,$cmp\t! int" %}
       
  5991   ins_encode %{
       
  5992     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
       
  5993   %}
       
  5994   ins_pipe(ialu_reg);
       
  5995 %}
       
  5996 
       
  5997 instruct cmovL_reg3(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src1, iRegL src2) %{
       
  5998   match(Set dst (CMoveL (Binary cmp icc) (Binary src2 src1)));
       
  5999   ins_cost(150);
       
  6000   size(4);
       
  6001   format %{ "CSEL $dst,$src1,$src2,$cmp\t! long" %}
       
  6002   ins_encode %{
       
  6003     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6004   %}
       
  6005   ins_pipe(ialu_reg);
       
  6006 %}
       
  6007 
       
  6008 instruct cmovP_reg3(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src1, iRegP src2) %{
       
  6009   match(Set dst (CMoveP (Binary cmp icc) (Binary src2 src1)));
       
  6010   ins_cost(150);
       
  6011   size(4);
       
  6012   format %{ "CSEL $dst,$src1,$src2,$cmp\t! ptr" %}
       
  6013   ins_encode %{
       
  6014     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6015   %}
       
  6016   ins_pipe(ialu_reg);
       
  6017 %}
       
  6018 
       
  6019 instruct cmovN_reg3(cmpOp cmp, flagsReg icc, iRegN dst, iRegN src1, iRegN src2) %{
       
  6020   match(Set dst (CMoveN (Binary cmp icc) (Binary src2 src1)));
       
  6021   ins_cost(150);
       
  6022   size(4);
       
  6023   format %{ "CSEL $dst,$src1,$src2,$cmp\t! compressed ptr" %}
       
  6024   ins_encode %{
       
  6025     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6026   %}
       
  6027   ins_pipe(ialu_reg);
       
  6028 %}
       
  6029 
       
  6030 instruct cmovIP_reg3(cmpOpP cmp, flagsRegP icc, iRegI dst, iRegI src1, iRegI src2) %{
       
  6031   match(Set dst (CMoveI (Binary cmp icc) (Binary src2 src1)));
       
  6032   ins_cost(150);
       
  6033   size(4);
       
  6034   format %{ "CSEL $dst,$src1,$src2,$cmp\t! int" %}
       
  6035   ins_encode %{
       
  6036     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6037   %}
       
  6038   ins_pipe(ialu_reg);
       
  6039 %}
       
  6040 
       
  6041 instruct cmovLP_reg3(cmpOpP cmp, flagsRegP icc, iRegL dst, iRegL src1, iRegL src2) %{
       
  6042   match(Set dst (CMoveL (Binary cmp icc) (Binary src2 src1)));
       
  6043   ins_cost(150);
       
  6044   size(4);
       
  6045   format %{ "CSEL $dst,$src1,$src2,$cmp\t! long" %}
       
  6046   ins_encode %{
       
  6047     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6048   %}
       
  6049   ins_pipe(ialu_reg);
       
  6050 %}
       
  6051 
       
  6052 instruct cmovPP_reg3(cmpOpP cmp, flagsRegP icc, iRegP dst, iRegP src1, iRegP src2) %{
       
  6053   match(Set dst (CMoveP (Binary cmp icc) (Binary src2 src1)));
       
  6054   ins_cost(150);
       
  6055   size(4);
       
  6056   format %{ "CSEL $dst,$src1,$src2,$cmp\t! ptr" %}
       
  6057   ins_encode %{
       
  6058     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6059   %}
       
  6060   ins_pipe(ialu_reg);
       
  6061 %}
       
  6062 
       
  6063 instruct cmovNP_reg3(cmpOpP cmp, flagsRegP icc, iRegN dst, iRegN src1, iRegN src2) %{
       
  6064   match(Set dst (CMoveN (Binary cmp icc) (Binary src2 src1)));
       
  6065   ins_cost(150);
       
  6066   size(4);
       
  6067   format %{ "CSEL $dst,$src1,$src2,$cmp\t! compressed ptr" %}
       
  6068   ins_encode %{
       
  6069     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6070   %}
       
  6071   ins_pipe(ialu_reg);
       
  6072 %}
       
  6073 
       
  6074 instruct cmovIU_reg3(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src1, iRegI src2) %{
       
  6075   match(Set dst (CMoveI (Binary cmp icc) (Binary src2 src1)));
       
  6076   ins_cost(150);
       
  6077   size(4);
       
  6078   format %{ "CSEL $dst,$src1,$src2,$cmp\t! int" %}
       
  6079   ins_encode %{
       
  6080     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6081   %}
       
  6082   ins_pipe(ialu_reg);
       
  6083 %}
       
  6084 
       
  6085 instruct cmovLU_reg3(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src1, iRegL src2) %{
       
  6086   match(Set dst (CMoveL (Binary cmp icc) (Binary src2 src1)));
       
  6087   ins_cost(150);
       
  6088   size(4);
       
  6089   format %{ "CSEL $dst,$src1,$src2,$cmp\t! long" %}
       
  6090   ins_encode %{
       
  6091     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6092   %}
       
  6093   ins_pipe(ialu_reg);
       
  6094 %}
       
  6095 
       
  6096 instruct cmovPU_reg3(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src1, iRegP src2) %{
       
  6097   match(Set dst (CMoveP (Binary cmp icc) (Binary src2 src1)));
       
  6098   ins_cost(150);
       
  6099   size(4);
       
  6100   format %{ "CSEL $dst,$src1,$src2,$cmp\t! ptr" %}
       
  6101   ins_encode %{
       
  6102     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6103   %}
       
  6104   ins_pipe(ialu_reg);
       
  6105 %}
       
  6106 
       
  6107 instruct cmovNU_reg3(cmpOpU cmp, flagsRegU icc, iRegN dst, iRegN src1, iRegN src2) %{
       
  6108   match(Set dst (CMoveN (Binary cmp icc) (Binary src2 src1)));
       
  6109   ins_cost(150);
       
  6110   size(4);
       
  6111   format %{ "CSEL $dst,$src1,$src2,$cmp\t! compressed ptr" %}
       
  6112   ins_encode %{
       
  6113     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6114   %}
       
  6115   ins_pipe(ialu_reg);
       
  6116 %}
       
  6117 
       
  6118 instruct cmovIZ_reg3(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, iRegI src1, iRegI src2) %{
       
  6119   match(Set dst (CMoveI (Binary cmp icc) (Binary src2 src1)));
       
  6120   ins_cost(150);
       
  6121   size(4);
       
  6122   format %{ "CSEL $dst,$src1,$src2,$cmp\t! int" %}
       
  6123   ins_encode %{
       
  6124     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6125   %}
       
  6126   ins_pipe(ialu_reg);
       
  6127 %}
       
  6128 
       
  6129 instruct cmovLZ_reg3(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, iRegL src1, iRegL src2) %{
       
  6130   match(Set dst (CMoveL (Binary cmp icc) (Binary src2 src1)));
       
  6131   ins_cost(150);
       
  6132   size(4);
       
  6133   format %{ "CSEL $dst,$src1,$src2,$cmp\t! long" %}
       
  6134   ins_encode %{
       
  6135     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6136   %}
       
  6137   ins_pipe(ialu_reg);
       
  6138 %}
       
  6139 
       
  6140 instruct cmovPZ_reg3(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, iRegP src1, iRegP src2) %{
       
  6141   match(Set dst (CMoveP (Binary cmp icc) (Binary src2 src1)));
       
  6142   ins_cost(150);
       
  6143   size(4);
       
  6144   format %{ "CSEL $dst,$src1,$src2,$cmp\t! ptr" %}
       
  6145   ins_encode %{
       
  6146     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6147   %}
       
  6148   ins_pipe(ialu_reg);
       
  6149 %}
       
  6150 
       
  6151 instruct cmovNZ_reg3(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegN dst, iRegN src1, iRegN src2) %{
       
  6152   match(Set dst (CMoveN (Binary cmp icc) (Binary src2 src1)));
       
  6153   ins_cost(150);
       
  6154   size(4);
       
  6155   format %{ "CSEL $dst,$src1,$src2,$cmp\t! compressed ptr" %}
       
  6156   ins_encode %{
       
  6157     __ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6158   %}
       
  6159   ins_pipe(ialu_reg);
       
  6160 %}
       
  6161 #endif // AARCH64
       
  6162 
       
  6163 #ifndef AARCH64
       
  6164 instruct cmovIP_immMov(cmpOpP cmp, flagsRegP pcc, iRegI dst, immIMov src) %{
       
  6165   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
       
  6166   ins_cost(140);
       
  6167   size(4);
       
  6168   format %{ "MOV$cmp  $dst,$src" %}
       
  6169   ins_encode %{
       
  6170     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
  6171   %}
       
  6172   ins_pipe(ialu_imm);
       
  6173 %}
       
  6174 
       
  6175 instruct cmovIP_imm16(cmpOpP cmp, flagsRegP pcc, iRegI dst, immI16 src) %{
       
  6176   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
       
  6177   ins_cost(140);
       
  6178   size(4);
       
  6179   format %{ "MOVw$cmp  $dst,$src" %}
       
  6180   ins_encode %{
       
  6181     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
  6182   %}
       
  6183   ins_pipe(ialu_imm);
       
  6184 %}
       
  6185 #endif
       
  6186 
       
  6187 instruct cmovI_reg(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src) %{
       
  6188   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
       
  6189   ins_cost(150);
       
  6190   size(4);
       
  6191   format %{ "MOV$cmp  $dst,$src" %}
       
  6192   ins_encode %{
       
  6193     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6194   %}
       
  6195   ins_pipe(ialu_reg);
       
  6196 %}
       
  6197 
       
  6198 #ifdef AARCH64
       
  6199 instruct cmovL_reg(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src) %{
       
  6200   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
       
  6201   ins_cost(150);
       
  6202   size(4);
       
  6203   format %{ "MOV$cmp  $dst,$src\t! long" %}
       
  6204   ins_encode %{
       
  6205     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6206   %}
       
  6207   ins_pipe(ialu_reg);
       
  6208 %}
       
  6209 #endif
       
  6210 
       
  6211 #ifndef AARCH64
       
  6212 instruct cmovI_immMov(cmpOp cmp, flagsReg icc, iRegI dst, immIMov src) %{
       
  6213   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
       
  6214   ins_cost(140);
       
  6215   size(4);
       
  6216   format %{ "MOV$cmp  $dst,$src" %}
       
  6217   ins_encode %{
       
  6218     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
  6219   %}
       
  6220   ins_pipe(ialu_imm);
       
  6221 %}
       
  6222 
       
  6223 instruct cmovII_imm16(cmpOp cmp, flagsReg icc, iRegI dst, immI16 src) %{
       
  6224   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
       
  6225   ins_cost(140);
       
  6226   size(4);
       
  6227   format %{ "MOVw$cmp  $dst,$src" %}
       
  6228   ins_encode %{
       
  6229     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
  6230   %}
       
  6231   ins_pipe(ialu_imm);
       
  6232 %}
       
  6233 #endif
       
  6234 
       
  6235 instruct cmovII_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, iRegI src) %{
       
  6236   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
       
  6237   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
       
  6238             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
       
  6239             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
       
  6240             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
       
  6241   ins_cost(150);
       
  6242   size(4);
       
  6243   format %{ "MOV$cmp  $dst,$src" %}
       
  6244   ins_encode %{
       
  6245     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6246   %}
       
  6247   ins_pipe(ialu_reg);
       
  6248 %}
       
  6249 
       
  6250 #ifndef AARCH64
       
  6251 instruct cmovII_immMov_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immIMov src) %{
       
  6252   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
       
  6253   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
       
  6254             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
       
  6255             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
       
  6256             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
       
  6257   ins_cost(140);
       
  6258   size(4);
       
  6259   format %{ "MOV$cmp  $dst,$src" %}
       
  6260   ins_encode %{
       
  6261     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
  6262   %}
       
  6263   ins_pipe(ialu_imm);
       
  6264 %}
       
  6265 
       
  6266 instruct cmovII_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immI16 src) %{
       
  6267   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
       
  6268   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
       
  6269             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
       
  6270             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
       
  6271             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
       
  6272   ins_cost(140);
       
  6273   size(4);
       
  6274   format %{ "MOVW$cmp  $dst,$src" %}
       
  6275   ins_encode %{
       
  6276     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
  6277   %}
       
  6278   ins_pipe(ialu_imm);
       
  6279 %}
       
  6280 #endif
       
  6281 
       
  6282 instruct cmovIIu_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
       
  6283   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
       
  6284   ins_cost(150);
       
  6285   size(4);
       
  6286   format %{ "MOV$cmp  $dst,$src" %}
       
  6287   ins_encode %{
       
  6288     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6289   %}
       
  6290   ins_pipe(ialu_reg);
       
  6291 %}
       
  6292 
       
  6293 #ifndef AARCH64
       
  6294 instruct cmovIIu_immMov(cmpOpU cmp, flagsRegU icc, iRegI dst, immIMov src) %{
       
  6295   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
       
  6296   ins_cost(140);
       
  6297   size(4);
       
  6298   format %{ "MOV$cmp  $dst,$src" %}
       
  6299   ins_encode %{
       
  6300     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
  6301   %}
       
  6302   ins_pipe(ialu_imm);
       
  6303 %}
       
  6304 
       
  6305 instruct cmovIIu_imm16(cmpOpU cmp, flagsRegU icc, iRegI dst, immI16 src) %{
       
  6306   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
       
  6307   ins_cost(140);
       
  6308   size(4);
       
  6309   format %{ "MOVW$cmp  $dst,$src" %}
       
  6310   ins_encode %{
       
  6311     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
  6312   %}
       
  6313   ins_pipe(ialu_imm);
       
  6314 %}
       
  6315 #endif
       
  6316 
       
  6317 // Conditional move
       
  6318 instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{
       
  6319   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
       
  6320   ins_cost(150);
       
  6321   size(4);
       
  6322   format %{ "MOV$cmp  $dst,$src" %}
       
  6323   ins_encode %{
       
  6324     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6325   %}
       
  6326   ins_pipe(ialu_reg);
       
  6327 %}
       
  6328 
       
  6329 instruct cmovPP_imm(cmpOpP cmp, flagsRegP pcc, iRegP dst, immP0 src) %{
       
  6330   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
       
  6331   ins_cost(140);
       
  6332   size(4);
       
  6333 #ifdef AARCH64
       
  6334   format %{ "MOV$cmp  $dst,ZR" %}
       
  6335 #else
       
  6336   format %{ "MOV$cmp  $dst,$src" %}
       
  6337 #endif
       
  6338   ins_encode %{
       
  6339 #ifdef AARCH64
       
  6340     __ mov($dst$$Register,             ZR, (AsmCondition)($cmp$$cmpcode));
       
  6341 #else
       
  6342     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
  6343 #endif
       
  6344   %}
       
  6345   ins_pipe(ialu_imm);
       
  6346 %}
       
  6347 
       
  6348 // This instruction also works with CmpN so we don't need cmovPN_reg.
       
  6349 instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{
       
  6350   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
       
  6351   ins_cost(150);
       
  6352 
       
  6353   size(4);
       
  6354   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
       
  6355   ins_encode %{
       
  6356     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6357   %}
       
  6358   ins_pipe(ialu_reg);
       
  6359 %}
       
  6360 
       
  6361 instruct cmovPI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, iRegP src) %{
       
  6362   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
       
  6363   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
       
  6364             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
       
  6365             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
       
  6366             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
       
  6367   ins_cost(150);
       
  6368 
       
  6369   size(4);
       
  6370   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
       
  6371   ins_encode %{
       
  6372     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6373   %}
       
  6374   ins_pipe(ialu_reg);
       
  6375 %}
       
  6376 
       
  6377 instruct cmovPIu_reg(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src) %{
       
  6378   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
       
  6379   ins_cost(150);
       
  6380 
       
  6381   size(4);
       
  6382   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
       
  6383   ins_encode %{
       
  6384     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6385   %}
       
  6386   ins_pipe(ialu_reg);
       
  6387 %}
       
  6388 
       
  6389 instruct cmovPI_imm(cmpOp cmp, flagsReg icc, iRegP dst, immP0 src) %{
       
  6390   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
       
  6391   ins_cost(140);
       
  6392 
       
  6393   size(4);
       
  6394 #ifdef AARCH64
       
  6395   format %{ "MOV$cmp  $dst,ZR\t! ptr" %}
       
  6396 #else
       
  6397   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
       
  6398 #endif
       
  6399   ins_encode %{
       
  6400 #ifdef AARCH64
       
  6401     __ mov($dst$$Register,             ZR, (AsmCondition)($cmp$$cmpcode));
       
  6402 #else
       
  6403     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
  6404 #endif
       
  6405   %}
       
  6406   ins_pipe(ialu_imm);
       
  6407 %}
       
  6408 
       
  6409 instruct cmovPI_imm_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, immP0 src) %{
       
  6410   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
       
  6411   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
       
  6412             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
       
  6413             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
       
  6414             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
       
  6415   ins_cost(140);
       
  6416 
       
  6417   size(4);
       
  6418 #ifdef AARCH64
       
  6419   format %{ "MOV$cmp  $dst,ZR\t! ptr" %}
       
  6420 #else
       
  6421   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
       
  6422 #endif
       
  6423   ins_encode %{
       
  6424 #ifdef AARCH64
       
  6425     __ mov($dst$$Register,             ZR, (AsmCondition)($cmp$$cmpcode));
       
  6426 #else
       
  6427     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
  6428 #endif
       
  6429   %}
       
  6430   ins_pipe(ialu_imm);
       
  6431 %}
       
  6432 
       
  6433 instruct cmovPIu_imm(cmpOpU cmp, flagsRegU icc, iRegP dst, immP0 src) %{
       
  6434   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
       
  6435   ins_cost(140);
       
  6436 
       
  6437   size(4);
       
  6438 #ifdef AARCH64
       
  6439   format %{ "MOV$cmp  $dst,ZR\t! ptr" %}
       
  6440 #else
       
  6441   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
       
  6442 #endif
       
  6443   ins_encode %{
       
  6444 #ifdef AARCH64
       
  6445     __ mov($dst$$Register,             ZR, (AsmCondition)($cmp$$cmpcode));
       
  6446 #else
       
  6447     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
  6448 #endif
       
  6449   %}
       
  6450   ins_pipe(ialu_imm);
       
  6451 %}
       
  6452 
       
  6453 #ifdef AARCH64
       
  6454 // Conditional move
       
  6455 instruct cmovF_reg(cmpOp cmp, flagsReg icc, regF dst, regF src1, regF src2) %{
       
  6456   match(Set dst (CMoveF (Binary cmp icc) (Binary src2 src1)));
       
  6457   ins_cost(150);
       
  6458   size(4);
       
  6459   format %{ "FCSEL_s $dst,$src1,$src2,$cmp" %}
       
  6460   ins_encode %{
       
  6461     __ fcsel_s($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
  6462   %}
       
  6463   ins_pipe(int_conditional_float_move);
       
  6464 %}
       
  6465 
       
  6466 instruct cmovD_reg(cmpOp cmp, flagsReg icc, regD dst, regD src1, regD src2) %{
       
  6467   match(Set dst (CMoveD (Binary cmp icc) (Binary src2 src1)));
       
  6468   ins_cost(150);
       
  6469   size(4);
       
  6470   format %{ "FCSEL_d $dst,$src1,$src2,$cmp" %}
       
  6471   ins_encode %{
       
  6472     __ fcsel_d($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
  6473   %}
       
  6474   ins_pipe(int_conditional_float_move);
       
  6475 %}
       
  6476 
       
  6477 instruct cmovFP_reg(cmpOpP cmp, flagsRegP icc, regF dst, regF src1, regF src2) %{
       
  6478   match(Set dst (CMoveF (Binary cmp icc) (Binary src2 src1)));
       
  6479   ins_cost(150);
       
  6480   size(4);
       
  6481   format %{ "FCSEL_s $dst,$src1,$src2,$cmp" %}
       
  6482   ins_encode %{
       
  6483     __ fcsel_s($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
  6484   %}
       
  6485   ins_pipe(int_conditional_float_move);
       
  6486 %}
       
  6487 
       
  6488 instruct cmovDP_reg(cmpOpP cmp, flagsRegP icc, regD dst, regD src1, regD src2) %{
       
  6489   match(Set dst (CMoveD (Binary cmp icc) (Binary src2 src1)));
       
  6490   ins_cost(150);
       
  6491   size(4);
       
  6492   format %{ "FCSEL_d $dst,$src1,$src2,$cmp" %}
       
  6493   ins_encode %{
       
  6494     __ fcsel_d($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
  6495   %}
       
  6496   ins_pipe(int_conditional_float_move);
       
  6497 %}
       
  6498 
       
  6499 instruct cmovFU_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src1, regF src2) %{
       
  6500   match(Set dst (CMoveF (Binary cmp icc) (Binary src2 src1)));
       
  6501   ins_cost(150);
       
  6502   size(4);
       
  6503   format %{ "FCSEL_s $dst,$src1,$src2,$cmp" %}
       
  6504   ins_encode %{
       
  6505     __ fcsel_s($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
  6506   %}
       
  6507   ins_pipe(int_conditional_float_move);
       
  6508 %}
       
  6509 
       
  6510 instruct cmovDU_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src1, regD src2) %{
       
  6511   match(Set dst (CMoveD (Binary cmp icc) (Binary src2 src1)));
       
  6512   ins_cost(150);
       
  6513   size(4);
       
  6514   format %{ "FCSEL_d $dst,$src1,$src2,$cmp" %}
       
  6515   ins_encode %{
       
  6516     __ fcsel_d($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
  6517   %}
       
  6518   ins_pipe(int_conditional_float_move);
       
  6519 %}
       
  6520 
       
  6521 instruct cmovFZ_reg(cmpOp0 cmp, flagsReg_EQNELTGE icc, regF dst, regF src1, regF src2) %{
       
  6522   match(Set dst (CMoveF (Binary cmp icc) (Binary src2 src1)));
       
  6523   ins_cost(150);
       
  6524   size(4);
       
  6525   format %{ "FCSEL_s $dst,$src1,$src2,$cmp" %}
       
  6526   ins_encode %{
       
  6527     __ fcsel_s($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
  6528   %}
       
  6529   ins_pipe(int_conditional_float_move);
       
  6530 %}
       
  6531 
       
  6532 instruct cmovDZ_reg(cmpOp0 cmp, flagsReg_EQNELTGE icc, regD dst, regD src1, regD src2) %{
       
  6533   match(Set dst (CMoveD (Binary cmp icc) (Binary src2 src1)));
       
  6534   ins_cost(150);
       
  6535   size(4);
       
  6536   format %{ "FCSEL_d $dst,$src1,$src2,$cmp" %}
       
  6537   ins_encode %{
       
  6538     __ fcsel_d($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
  6539   %}
       
  6540   ins_pipe(int_conditional_float_move);
       
  6541 %}
       
  6542 
       
  6543 #else // !AARCH64
       
  6544 
       
  6545 // Conditional move
       
  6546 instruct cmovFP_reg(cmpOpP cmp, flagsRegP pcc, regF dst, regF src) %{
       
  6547   match(Set dst (CMoveF (Binary cmp pcc) (Binary dst src)));
       
  6548   ins_cost(150);
       
  6549   size(4);
       
  6550   format %{ "FCPYS$cmp $dst,$src" %}
       
  6551   ins_encode %{
       
  6552     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
  6553   %}
       
  6554   ins_pipe(int_conditional_float_move);
       
  6555 %}
       
  6556 
       
  6557 instruct cmovFI_reg(cmpOp cmp, flagsReg icc, regF dst, regF src) %{
       
  6558   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
       
  6559   ins_cost(150);
       
  6560 
       
  6561   size(4);
       
  6562   format %{ "FCPYS$cmp $dst,$src" %}
       
  6563   ins_encode %{
       
  6564     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
  6565   %}
       
  6566   ins_pipe(int_conditional_float_move);
       
  6567 %}
       
  6568 
       
  6569 instruct cmovFI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regF dst, regF src) %{
       
  6570   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
       
  6571   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
       
  6572             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
       
  6573             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
       
  6574             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
       
  6575   ins_cost(150);
       
  6576 
       
  6577   size(4);
       
  6578   format %{ "FCPYS$cmp $dst,$src" %}
       
  6579   ins_encode %{
       
  6580     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
  6581   %}
       
  6582   ins_pipe(int_conditional_float_move);
       
  6583 %}
       
  6584 
       
  6585 instruct cmovFIu_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src) %{
       
  6586   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
       
  6587   ins_cost(150);
       
  6588 
       
  6589   size(4);
       
  6590   format %{ "FCPYS$cmp $dst,$src" %}
       
  6591   ins_encode %{
       
  6592     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
  6593   %}
       
  6594   ins_pipe(int_conditional_float_move);
       
  6595 %}
       
  6596 
       
  6597 // Conditional move
       
  6598 instruct cmovDP_reg(cmpOpP cmp, flagsRegP pcc, regD dst, regD src) %{
       
  6599   match(Set dst (CMoveD (Binary cmp pcc) (Binary dst src)));
       
  6600   ins_cost(150);
       
  6601   size(4);
       
  6602   format %{ "FCPYD$cmp $dst,$src" %}
       
  6603   ins_encode %{
       
  6604     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
  6605   %}
       
  6606   ins_pipe(int_conditional_double_move);
       
  6607 %}
       
  6608 
       
  6609 instruct cmovDI_reg(cmpOp cmp, flagsReg icc, regD dst, regD src) %{
       
  6610   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
       
  6611   ins_cost(150);
       
  6612 
       
  6613   size(4);
       
  6614   format %{ "FCPYD$cmp $dst,$src" %}
       
  6615   ins_encode %{
       
  6616     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
  6617   %}
       
  6618   ins_pipe(int_conditional_double_move);
       
  6619 %}
       
  6620 
       
  6621 instruct cmovDI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regD dst, regD src) %{
       
  6622   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
       
  6623   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);
       
  6624   ins_cost(150);
       
  6625 
       
  6626   size(4);
       
  6627   format %{ "FCPYD$cmp $dst,$src" %}
       
  6628   ins_encode %{
       
  6629     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
  6630   %}
       
  6631   ins_pipe(int_conditional_double_move);
       
  6632 %}
       
  6633 
       
  6634 instruct cmovDIu_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src) %{
       
  6635   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
       
  6636   ins_cost(150);
       
  6637 
       
  6638   size(4);
       
  6639   format %{ "FCPYD$cmp $dst,$src" %}
       
  6640   ins_encode %{
       
  6641     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
  6642   %}
       
  6643   ins_pipe(int_conditional_double_move);
       
  6644 %}
       
  6645 
       
  6646 // Conditional move
       
  6647 instruct cmovLP_reg(cmpOpP cmp, flagsRegP pcc, iRegL dst, iRegL src) %{
       
  6648   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
       
  6649   ins_cost(150);
       
  6650 
       
  6651   size(8);
       
  6652   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
       
  6653             "MOV$cmp  $dst.hi,$src.hi" %}
       
  6654   ins_encode %{
       
  6655     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6656     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
       
  6657   %}
       
  6658   ins_pipe(ialu_reg);
       
  6659 %}
       
  6660 
       
  6661 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
       
  6662 // (hi($con$$constant), lo($con$$constant)) becomes
       
  6663 instruct cmovLP_immRot(cmpOpP cmp, flagsRegP pcc, iRegL dst, immLlowRot src) %{
       
  6664   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
       
  6665   ins_cost(140);
       
  6666 
       
  6667   size(8);
       
  6668   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
       
  6669             "MOV$cmp  $dst.hi,0" %}
       
  6670   ins_encode %{
       
  6671     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
  6672     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
       
  6673   %}
       
  6674   ins_pipe(ialu_imm);
       
  6675 %}
       
  6676 
       
  6677 instruct cmovLP_imm16(cmpOpP cmp, flagsRegP pcc, iRegL dst, immL16 src) %{
       
  6678   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
       
  6679   ins_cost(140);
       
  6680 
       
  6681   size(8);
       
  6682   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
       
  6683             "MOV$cmp  $dst.hi,0" %}
       
  6684   ins_encode %{
       
  6685     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
  6686     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
       
  6687   %}
       
  6688   ins_pipe(ialu_imm);
       
  6689 %}
       
  6690 
       
  6691 instruct cmovLI_reg(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src) %{
       
  6692   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
       
  6693   ins_cost(150);
       
  6694 
       
  6695   size(8);
       
  6696   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
       
  6697             "MOV$cmp  $dst.hi,$src.hi" %}
       
  6698   ins_encode %{
       
  6699     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6700     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
       
  6701   %}
       
  6702   ins_pipe(ialu_reg);
       
  6703 %}
       
  6704 
       
  6705 instruct cmovLI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, iRegL src) %{
       
  6706   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
       
  6707   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
       
  6708             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
       
  6709             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
       
  6710             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
       
  6711   ins_cost(150);
       
  6712 
       
  6713   size(8);
       
  6714   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
       
  6715             "MOV$cmp  $dst.hi,$src.hi" %}
       
  6716   ins_encode %{
       
  6717     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6718     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
       
  6719   %}
       
  6720   ins_pipe(ialu_reg);
       
  6721 %}
       
  6722 
       
  6723 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
       
  6724 // (hi($con$$constant), lo($con$$constant)) becomes
       
  6725 instruct cmovLI_immRot(cmpOp cmp, flagsReg icc, iRegL dst, immLlowRot src) %{
       
  6726   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
       
  6727   ins_cost(140);
       
  6728 
       
  6729   size(8);
       
  6730   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
       
  6731             "MOV$cmp  $dst.hi,0" %}
       
  6732   ins_encode %{
       
  6733     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
  6734     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
       
  6735   %}
       
  6736   ins_pipe(ialu_imm);
       
  6737 %}
       
  6738 
       
  6739 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
       
  6740 // (hi($con$$constant), lo($con$$constant)) becomes
       
  6741 instruct cmovLI_immRot_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immLlowRot src) %{
       
  6742   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
       
  6743   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
       
  6744             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
       
  6745             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
       
  6746             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
       
  6747   ins_cost(140);
       
  6748 
       
  6749   size(8);
       
  6750   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
       
  6751             "MOV$cmp  $dst.hi,0" %}
       
  6752   ins_encode %{
       
  6753     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
  6754     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
       
  6755   %}
       
  6756   ins_pipe(ialu_imm);
       
  6757 %}
       
  6758 
       
  6759 instruct cmovLI_imm16(cmpOp cmp, flagsReg icc, iRegL dst, immL16 src) %{
       
  6760   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
       
  6761   ins_cost(140);
       
  6762 
       
  6763   size(8);
       
  6764   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
       
  6765             "MOV$cmp  $dst.hi,0" %}
       
  6766   ins_encode %{
       
  6767     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
  6768     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
       
  6769   %}
       
  6770   ins_pipe(ialu_imm);
       
  6771 %}
       
  6772 
       
  6773 instruct cmovLI_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immL16 src) %{
       
  6774   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
       
  6775   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
       
  6776             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
       
  6777             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
       
  6778             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
       
  6779   ins_cost(140);
       
  6780 
       
  6781   size(8);
       
  6782   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
       
  6783             "MOV$cmp  $dst.hi,0" %}
       
  6784   ins_encode %{
       
  6785     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
  6786     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
       
  6787   %}
       
  6788   ins_pipe(ialu_imm);
       
  6789 %}
       
  6790 
       
  6791 instruct cmovLIu_reg(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src) %{
       
  6792   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
       
  6793   ins_cost(150);
       
  6794 
       
  6795   size(8);
       
  6796   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
       
  6797             "MOV$cmp  $dst.hi,$src.hi" %}
       
  6798   ins_encode %{
       
  6799     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
  6800     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
       
  6801   %}
       
  6802   ins_pipe(ialu_reg);
       
  6803 %}
       
  6804 #endif // !AARCH64
       
  6805 
       
  6806 
       
  6807 //----------OS and Locking Instructions----------------------------------------
       
  6808 
       
  6809 // This name is KNOWN by the ADLC and cannot be changed.
       
  6810 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
       
  6811 // for this guy.
       
  6812 instruct tlsLoadP(RthreadRegP dst) %{
       
  6813   match(Set dst (ThreadLocal));
       
  6814 
       
  6815   size(0);
       
  6816   ins_cost(0);
       
  6817   format %{ "! TLS is in $dst" %}
       
  6818   ins_encode( /*empty encoding*/ );
       
  6819   ins_pipe(ialu_none);
       
  6820 %}
       
  6821 
       
  6822 instruct checkCastPP( iRegP dst ) %{
       
  6823   match(Set dst (CheckCastPP dst));
       
  6824 
       
  6825   size(0);
       
  6826   format %{ "! checkcastPP of $dst" %}
       
  6827   ins_encode( /*empty encoding*/ );
       
  6828   ins_pipe(empty);
       
  6829 %}
       
  6830 
       
  6831 
       
  6832 instruct castPP( iRegP dst ) %{
       
  6833   match(Set dst (CastPP dst));
       
  6834   format %{ "! castPP of $dst" %}
       
  6835   ins_encode( /*empty encoding*/ );
       
  6836   ins_pipe(empty);
       
  6837 %}
       
  6838 
       
  6839 instruct castII( iRegI dst ) %{
       
  6840   match(Set dst (CastII dst));
       
  6841   format %{ "! castII of $dst" %}
       
  6842   ins_encode( /*empty encoding*/ );
       
  6843   ins_cost(0);
       
  6844   ins_pipe(empty);
       
  6845 %}
       
  6846 
       
  6847 //----------Arithmetic Instructions--------------------------------------------
       
  6848 // Addition Instructions
       
  6849 // Register Addition
       
  6850 instruct addI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
       
  6851   match(Set dst (AddI src1 src2));
       
  6852 
       
  6853   size(4);
       
  6854   format %{ "add_32 $dst,$src1,$src2\t! int" %}
       
  6855   ins_encode %{
       
  6856     __ add_32($dst$$Register, $src1$$Register, $src2$$Register);
       
  6857   %}
       
  6858   ins_pipe(ialu_reg_reg);
       
  6859 %}
       
  6860 
       
  6861 #ifndef AARCH64
       
  6862 instruct addshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  6863   match(Set dst (AddI (LShiftI src1 src2) src3));
       
  6864 
       
  6865   size(4);
       
  6866   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
       
  6867   ins_encode %{
       
  6868     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
       
  6869   %}
       
  6870   ins_pipe(ialu_reg_reg);
       
  6871 %}
       
  6872 #endif
       
  6873 
       
  6874 #ifdef AARCH64
       
  6875 #ifdef TODO
       
  6876 instruct addshlL_reg_imm_reg(iRegL dst, iRegL src1, immU6 src2, iRegL src3) %{
       
  6877   match(Set dst (AddL (LShiftL src1 src2) src3));
       
  6878 
       
  6879   size(4);
       
  6880   format %{ "ADD    $dst,$src3,$src1<<$src2\t! long" %}
       
  6881   ins_encode %{
       
  6882     __ add($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
       
  6883   %}
       
  6884   ins_pipe(ialu_reg_reg);
       
  6885 %}
       
  6886 #endif
       
  6887 #endif
       
  6888 
       
  6889 instruct addshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
       
  6890   match(Set dst (AddI (LShiftI src1 src2) src3));
       
  6891 
       
  6892   size(4);
       
  6893   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
       
  6894   ins_encode %{
       
  6895     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
       
  6896   %}
       
  6897   ins_pipe(ialu_reg_reg);
       
  6898 %}
       
  6899 
       
  6900 #ifndef AARCH64
       
  6901 instruct addsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  6902   match(Set dst (AddI (RShiftI src1 src2) src3));
       
  6903 
       
  6904   size(4);
       
  6905   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
       
  6906   ins_encode %{
       
  6907     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
       
  6908   %}
       
  6909   ins_pipe(ialu_reg_reg);
       
  6910 %}
       
  6911 #endif
       
  6912 
       
  6913 instruct addsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
       
  6914   match(Set dst (AddI (RShiftI src1 src2) src3));
       
  6915 
       
  6916   size(4);
       
  6917   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
       
  6918   ins_encode %{
       
  6919     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
       
  6920   %}
       
  6921   ins_pipe(ialu_reg_reg);
       
  6922 %}
       
  6923 
       
  6924 #ifndef AARCH64
       
  6925 instruct addshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  6926   match(Set dst (AddI (URShiftI src1 src2) src3));
       
  6927 
       
  6928   size(4);
       
  6929   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
       
  6930   ins_encode %{
       
  6931     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
       
  6932   %}
       
  6933   ins_pipe(ialu_reg_reg);
       
  6934 %}
       
  6935 #endif
       
  6936 
       
  6937 instruct addshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
       
  6938   match(Set dst (AddI (URShiftI src1 src2) src3));
       
  6939 
       
  6940   size(4);
       
  6941   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
       
  6942   ins_encode %{
       
  6943     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
       
  6944   %}
       
  6945   ins_pipe(ialu_reg_reg);
       
  6946 %}
       
  6947 
       
  6948 // Immediate Addition
       
  6949 instruct addI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
       
  6950   match(Set dst (AddI src1 src2));
       
  6951 
       
  6952   size(4);
       
  6953   format %{ "add_32 $dst,$src1,$src2\t! int" %}
       
  6954   ins_encode %{
       
  6955     __ add_32($dst$$Register, $src1$$Register, $src2$$constant);
       
  6956   %}
       
  6957   ins_pipe(ialu_reg_imm);
       
  6958 %}
       
  6959 
       
  6960 // Pointer Register Addition
       
  6961 instruct addP_reg_reg(iRegP dst, iRegP src1, iRegX src2) %{
       
  6962   match(Set dst (AddP src1 src2));
       
  6963 
       
  6964   size(4);
       
  6965   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
       
  6966   ins_encode %{
       
  6967     __ add($dst$$Register, $src1$$Register, $src2$$Register);
       
  6968   %}
       
  6969   ins_pipe(ialu_reg_reg);
       
  6970 %}
       
  6971 
       
  6972 #ifdef AARCH64
       
  6973 // unshifted I2L operand
       
  6974 operand unshiftedI2L(iRegI src2) %{
       
  6975 //constraint(ALLOC_IN_RC(sp_ptr_reg));
       
  6976   match(ConvI2L src2);
       
  6977 
       
  6978   op_cost(1);
       
  6979   format %{ "$src2.w" %}
       
  6980   interface(MEMORY_INTER) %{
       
  6981     base($src2);
       
  6982     index(0xff);
       
  6983     scale(0x0);
       
  6984     disp(0x0);
       
  6985   %}
       
  6986 %}
       
  6987 
       
  6988 // shifted I2L operand
       
  6989 operand shiftedI2L(iRegI src2, immI_0_4 src3) %{
       
  6990 //constraint(ALLOC_IN_RC(sp_ptr_reg));
       
  6991   match(LShiftX (ConvI2L src2) src3);
       
  6992 
       
  6993   op_cost(1);
       
  6994   format %{ "$src2.w << $src3" %}
       
  6995   interface(MEMORY_INTER) %{
       
  6996     base($src2);
       
  6997     index(0xff);
       
  6998     scale($src3);
       
  6999     disp(0x0);
       
  7000   %}
       
  7001 %}
       
  7002 
       
  7003 opclass shiftedRegI(shiftedI2L, unshiftedI2L);
       
  7004 
       
  7005 instruct shlL_reg_regI(iRegL dst, iRegI src1, immU6 src2) %{
       
  7006   match(Set dst (LShiftL (ConvI2L src1) src2));
       
  7007 
       
  7008   size(4);
       
  7009   format %{ "LSL    $dst,$src1.w,$src2\t! ptr" %}
       
  7010   ins_encode %{
       
  7011     int c = $src2$$constant;
       
  7012     int r = 64 - c;
       
  7013     int s = 31;
       
  7014     if (s >= r) {
       
  7015       s = r - 1;
       
  7016     }
       
  7017     __ sbfm($dst$$Register, $src1$$Register, r, s);
       
  7018   %}
       
  7019   ins_pipe(ialu_reg_reg);
       
  7020 %}
       
  7021 
       
  7022 instruct addP_reg_regI(iRegP dst, iRegP src1, shiftedRegI src2) %{
       
  7023   match(Set dst (AddP src1 src2));
       
  7024 
       
  7025   ins_cost(DEFAULT_COST * 3/2);
       
  7026   size(4);
       
  7027   format %{ "ADD    $dst,$src1,$src2, sxtw\t! ptr" %}
       
  7028   ins_encode %{
       
  7029     Register base = reg_to_register_object($src2$$base);
       
  7030     __ add($dst$$Register, $src1$$Register, base, ex_sxtw, $src2$$scale);
       
  7031   %}
       
  7032   ins_pipe(ialu_reg_reg);
       
  7033 %}
       
  7034 #endif
       
  7035 
       
  7036 // shifted iRegX operand
       
  7037 operand shiftedX(iRegX src2, shimmX src3) %{
       
  7038 //constraint(ALLOC_IN_RC(sp_ptr_reg));
       
  7039   match(LShiftX src2 src3);
       
  7040 
       
  7041   op_cost(1);
       
  7042   format %{ "$src2 << $src3" %}
       
  7043   interface(MEMORY_INTER) %{
       
  7044     base($src2);
       
  7045     index(0xff);
       
  7046     scale($src3);
       
  7047     disp(0x0);
       
  7048   %}
       
  7049 %}
       
  7050 
       
  7051 instruct addshlP_reg_reg_imm(iRegP dst, iRegP src1, shiftedX src2) %{
       
  7052   match(Set dst (AddP src1 src2));
       
  7053 
       
  7054   ins_cost(DEFAULT_COST * 3/2);
       
  7055   size(4);
       
  7056   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
       
  7057   ins_encode %{
       
  7058     Register base = reg_to_register_object($src2$$base);
       
  7059     __ add($dst$$Register, $src1$$Register, AsmOperand(base, lsl, $src2$$scale));
       
  7060   %}
       
  7061   ins_pipe(ialu_reg_reg);
       
  7062 %}
       
  7063 
       
  7064 // Pointer Immediate Addition
       
  7065 instruct addP_reg_aimmX(iRegP dst, iRegP src1, aimmX src2) %{
       
  7066   match(Set dst (AddP src1 src2));
       
  7067 
       
  7068   size(4);
       
  7069   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
       
  7070   ins_encode %{
       
  7071     __ add($dst$$Register, $src1$$Register, $src2$$constant);
       
  7072   %}
       
  7073   ins_pipe(ialu_reg_imm);
       
  7074 %}
       
  7075 
       
  7076 // Long Addition
       
  7077 #ifdef AARCH64
       
  7078 instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
       
  7079   match(Set dst (AddL src1 src2));
       
  7080   size(4);
       
  7081   format %{ "ADD     $dst,$src1,$src2\t! long" %}
       
  7082   ins_encode %{
       
  7083     __ add($dst$$Register, $src1$$Register, $src2$$Register);
       
  7084   %}
       
  7085   ins_pipe(ialu_reg_reg);
       
  7086 %}
       
  7087 
       
  7088 instruct addL_reg_regI(iRegL dst, iRegL src1, shiftedRegI src2) %{
       
  7089   match(Set dst (AddL src1 src2));
       
  7090 
       
  7091   ins_cost(DEFAULT_COST * 3/2);
       
  7092   size(4);
       
  7093   format %{ "ADD    $dst,$src1,$src2, sxtw\t! long" %}
       
  7094   ins_encode %{
       
  7095     Register base = reg_to_register_object($src2$$base);
       
  7096     __ add($dst$$Register, $src1$$Register, base, ex_sxtw, $src2$$scale);
       
  7097   %}
       
  7098   ins_pipe(ialu_reg_reg);
       
  7099 %}
       
  7100 #else
       
  7101 instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg ccr) %{
       
  7102   match(Set dst (AddL src1 src2));
       
  7103   effect(KILL ccr);
       
  7104   size(8);
       
  7105   format %{ "ADDS    $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
       
  7106             "ADC     $dst.hi,$src1.hi,$src2.hi" %}
       
  7107   ins_encode %{
       
  7108     __ adds($dst$$Register, $src1$$Register, $src2$$Register);
       
  7109     __ adc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
       
  7110   %}
       
  7111   ins_pipe(ialu_reg_reg);
       
  7112 %}
       
  7113 #endif
       
  7114 
       
  7115 #ifdef AARCH64
       
  7116 // Immediate Addition
       
  7117 instruct addL_reg_aimm(iRegL dst, iRegL src1, aimmL src2) %{
       
  7118   match(Set dst (AddL src1 src2));
       
  7119 
       
  7120   size(4);
       
  7121   format %{ "ADD    $dst,$src1,$src2\t! long" %}
       
  7122   ins_encode %{
       
  7123     __ add($dst$$Register, $src1$$Register, $src2$$constant);
       
  7124   %}
       
  7125   ins_pipe(ialu_reg_imm);
       
  7126 %}
       
  7127 
       
  7128 instruct addL_reg_immLneg(iRegL dst, iRegL src1, aimmLneg src2) %{
       
  7129   match(Set dst (SubL src1 src2));
       
  7130 
       
  7131   size(4);
       
  7132   format %{ "ADD    $dst,$src1,-($src2)\t! long" %}
       
  7133   ins_encode %{
       
  7134     __ add($dst$$Register, $src1$$Register, -$src2$$constant);
       
  7135   %}
       
  7136   ins_pipe(ialu_reg_imm);
       
  7137 %}
       
  7138 #else
       
  7139 // TODO
       
  7140 #endif
       
  7141 
       
  7142 #ifndef AARCH64
       
  7143 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
       
  7144 // (hi($con$$constant), lo($con$$constant)) becomes
       
  7145 instruct addL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg ccr) %{
       
  7146   match(Set dst (AddL src1 con));
       
  7147   effect(KILL ccr);
       
  7148   size(8);
       
  7149   format %{ "ADDS    $dst.lo,$src1.lo,$con\t! long\n\t"
       
  7150             "ADC     $dst.hi,$src1.hi,0" %}
       
  7151   ins_encode %{
       
  7152     __ adds($dst$$Register, $src1$$Register, $con$$constant);
       
  7153     __ adc($dst$$Register->successor(), $src1$$Register->successor(), 0);
       
  7154   %}
       
  7155   ins_pipe(ialu_reg_imm);
       
  7156 %}
       
  7157 #endif
       
  7158 
       
  7159 //----------Conditional_store--------------------------------------------------
       
  7160 // Conditional-store of the updated heap-top.
       
  7161 // Used during allocation of the shared heap.
       
  7162 // Sets flags (EQ) on success.
       
  7163 
       
  7164 // TODO: optimize out barriers with AArch64 load-acquire/store-release
       
  7165 // LoadP-locked.
       
  7166 instruct loadPLocked(iRegP dst, memoryex mem) %{
       
  7167   match(Set dst (LoadPLocked mem));
       
  7168   size(4);
       
  7169   format %{ "LDREX  $dst,$mem" %}
       
  7170   ins_encode %{
       
  7171 #ifdef AARCH64
       
  7172     Register base = reg_to_register_object($mem$$base);
       
  7173     __ ldxr($dst$$Register, base);
       
  7174 #else
       
  7175     __ ldrex($dst$$Register,$mem$$Address);
       
  7176 #endif
       
  7177   %}
       
  7178   ins_pipe(iload_mem);
       
  7179 %}
       
  7180 
       
  7181 instruct storePConditional( memoryex heap_top_ptr, iRegP oldval, iRegP newval, iRegI tmp, flagsRegP pcc ) %{
       
  7182   predicate(_kids[1]->_kids[0]->_leaf->Opcode() == Op_LoadPLocked); // only works in conjunction with a LoadPLocked node
       
  7183   match(Set pcc (StorePConditional heap_top_ptr (Binary oldval newval)));
       
  7184   effect( TEMP tmp );
       
  7185   size(8);
       
  7186   format %{ "STREX  $tmp,$newval,$heap_top_ptr\n\t"
       
  7187             "CMP    $tmp, 0" %}
       
  7188   ins_encode %{
       
  7189 #ifdef AARCH64
       
  7190     Register base = reg_to_register_object($heap_top_ptr$$base);
       
  7191     __ stxr($tmp$$Register, $newval$$Register, base);
       
  7192 #else
       
  7193     __ strex($tmp$$Register, $newval$$Register, $heap_top_ptr$$Address);
       
  7194 #endif
       
  7195     __ cmp($tmp$$Register, 0);
       
  7196   %}
       
  7197   ins_pipe( long_memory_op );
       
  7198 %}
       
  7199 
       
  7200 // Conditional-store of an intx value.
       
  7201 instruct storeXConditional( memoryex mem, iRegX oldval, iRegX newval, iRegX tmp, flagsReg icc ) %{
       
  7202 #ifdef AARCH64
       
  7203   match(Set icc (StoreLConditional mem (Binary oldval newval)));
       
  7204   effect( TEMP tmp );
       
  7205   size(28);
       
  7206   format %{ "loop:\n\t"
       
  7207             "LDXR     $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem], DOESN'T set $newval=[$mem] in any case\n\t"
       
  7208             "SUBS     $tmp, $tmp, $oldval\n\t"
       
  7209             "B.ne     done\n\t"
       
  7210             "STXR     $tmp, $newval, $mem\n\t"
       
  7211             "CBNZ_w   $tmp, loop\n\t"
       
  7212             "CMP      $tmp, 0\n\t"
       
  7213             "done:\n\t"
       
  7214             "membar   LoadStore|LoadLoad" %}
       
  7215 #else
       
  7216   match(Set icc (StoreIConditional mem (Binary oldval newval)));
       
  7217   effect( TEMP tmp );
       
  7218   size(28);
       
  7219   format %{ "loop: \n\t"
       
  7220             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem], DOESN'T set $newval=[$mem] in any case\n\t"
       
  7221             "XORS     $tmp,$tmp, $oldval\n\t"
       
  7222             "STREX.eq $tmp, $newval, $mem\n\t"
       
  7223             "CMP.eq   $tmp, 1 \n\t"
       
  7224             "B.eq     loop \n\t"
       
  7225             "TEQ      $tmp, 0\n\t"
       
  7226             "membar   LoadStore|LoadLoad" %}
       
  7227 #endif
       
  7228   ins_encode %{
       
  7229     Label loop;
       
  7230     __ bind(loop);
       
  7231 #ifdef AARCH64
       
  7232 // FIXME: use load-acquire/store-release, remove membar?
       
  7233     Label done;
       
  7234     Register base = reg_to_register_object($mem$$base);
       
  7235     __ ldxr($tmp$$Register, base);
       
  7236     __ subs($tmp$$Register, $tmp$$Register, $oldval$$Register);
       
  7237     __ b(done, ne);
       
  7238     __ stxr($tmp$$Register, $newval$$Register, base);
       
  7239     __ cbnz_w($tmp$$Register, loop);
       
  7240     __ cmp($tmp$$Register, 0);
       
  7241     __ bind(done);
       
  7242 #else
       
  7243     __ ldrex($tmp$$Register, $mem$$Address);
       
  7244     __ eors($tmp$$Register, $tmp$$Register, $oldval$$Register);
       
  7245     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
       
  7246     __ cmp($tmp$$Register, 1, eq);
       
  7247     __ b(loop, eq);
       
  7248     __ teq($tmp$$Register, 0);
       
  7249 #endif
       
  7250     // used by biased locking only. Requires a membar.
       
  7251     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadStore | MacroAssembler::LoadLoad), noreg);
       
  7252   %}
       
  7253   ins_pipe( long_memory_op );
       
  7254 %}
       
  7255 
       
  7256 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
       
  7257 
       
  7258 #ifdef AARCH64
       
  7259 // TODO: if combined with membar, elide membar and use
       
  7260 // load-acquire/store-release if appropriate
       
  7261 instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegL newval, iRegI res, iRegI tmp, flagsReg ccr) %{
       
  7262   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
       
  7263   effect( KILL ccr, TEMP tmp);
       
  7264   size(24);
       
  7265   format %{ "loop:\n\t"
       
  7266             "LDXR     $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
       
  7267             "CMP      $tmp, $oldval\n\t"
       
  7268             "B.ne     done\n\t"
       
  7269             "STXR     $tmp, $newval, $mem\n\t"
       
  7270             "CBNZ_w   $tmp, loop\n\t"
       
  7271             "done:\n\t"
       
  7272             "CSET_w   $res, eq" %}
       
  7273   ins_encode %{
       
  7274     Register base = reg_to_register_object($mem$$base);
       
  7275     Label loop, done;
       
  7276     __ bind(loop);
       
  7277     __ ldxr($tmp$$Register, base);
       
  7278     __ cmp($tmp$$Register, $oldval$$Register);
       
  7279     __ b(done, ne);
       
  7280     __ stxr($tmp$$Register, $newval$$Register, base);
       
  7281     __ cbnz_w($tmp$$Register, loop);
       
  7282     __ bind(done);
       
  7283     __ cset_w($res$$Register, eq);
       
  7284   %}
       
  7285   ins_pipe( long_memory_op );
       
  7286 %}
       
  7287 
       
  7288 instruct compareAndSwapI_bool(memoryex mem, iRegI oldval, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr) %{
       
  7289   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
       
  7290   effect( KILL ccr, TEMP tmp);
       
  7291   size(24);
       
  7292   format %{ "loop:\n\t"
       
  7293             "LDXR_w   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
       
  7294             "CMP_w    $tmp, $oldval\n\t"
       
  7295             "B.ne     done\n\t"
       
  7296             "STXR_w   $tmp, $newval, $mem\n\t"
       
  7297             "CBNZ_w   $tmp, loop\n\t"
       
  7298             "done:\n\t"
       
  7299             "CSET_w   $res, eq" %}
       
  7300   ins_encode %{
       
  7301     Register base = reg_to_register_object($mem$$base);
       
  7302     Label loop, done;
       
  7303     __ bind(loop);
       
  7304     __ ldxr_w($tmp$$Register, base);
       
  7305     __ cmp_w($tmp$$Register, $oldval$$Register);
       
  7306     __ b(done, ne);
       
  7307     __ stxr_w($tmp$$Register, $newval$$Register,  base);
       
  7308     __ cbnz_w($tmp$$Register, loop);
       
  7309     __ bind(done);
       
  7310     __ cset_w($res$$Register, eq);
       
  7311   %}
       
  7312   ins_pipe( long_memory_op );
       
  7313 %}
       
  7314 
       
  7315 // tmp must use iRegI instead of iRegN until 8051805 is fixed.
       
  7316 instruct compareAndSwapN_bool(memoryex mem, iRegN oldval, iRegN newval, iRegI res, iRegI tmp, flagsReg ccr) %{
       
  7317   match(Set res (CompareAndSwapN mem (Binary oldval newval)));
       
  7318   effect( KILL ccr, TEMP tmp);
       
  7319   size(24);
       
  7320   format %{ "loop:\n\t"
       
  7321             "LDXR_w   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
       
  7322             "CMP_w    $tmp, $oldval\n\t"
       
  7323             "B.ne     done\n\t"
       
  7324             "STXR_w   $tmp, $newval, $mem\n\t"
       
  7325             "CBNZ_w   $tmp, loop\n\t"
       
  7326             "done:\n\t"
       
  7327             "CSET_w   $res, eq" %}
       
  7328   ins_encode %{
       
  7329     Register base = reg_to_register_object($mem$$base);
       
  7330     Label loop, done;
       
  7331     __ bind(loop);
       
  7332     __ ldxr_w($tmp$$Register, base);
       
  7333     __ cmp_w($tmp$$Register, $oldval$$Register);
       
  7334     __ b(done, ne);
       
  7335     __ stxr_w($tmp$$Register, $newval$$Register,  base);
       
  7336     __ cbnz_w($tmp$$Register, loop);
       
  7337     __ bind(done);
       
  7338     __ cset_w($res$$Register, eq);
       
  7339   %}
       
  7340   ins_pipe( long_memory_op );
       
  7341 %}
       
  7342 
       
  7343 instruct compareAndSwapP_bool(memoryex mem, iRegP oldval, iRegP newval, iRegI res, iRegI tmp, flagsReg ccr) %{
       
  7344   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
       
  7345   effect( KILL ccr, TEMP tmp);
       
  7346   size(24);
       
  7347   format %{ "loop:\n\t"
       
  7348             "LDXR     $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
       
  7349             "CMP      $tmp, $oldval\n\t"
       
  7350             "B.ne     done\n\t"
       
  7351             "STXR     $tmp, $newval, $mem\n\t"
       
  7352             "CBNZ_w   $tmp, loop\n\t"
       
  7353             "done:\n\t"
       
  7354             "CSET_w   $res, eq" %}
       
  7355   ins_encode %{
       
  7356     Register base = reg_to_register_object($mem$$base);
       
  7357     Label loop, done;
       
  7358     __ bind(loop);
       
  7359     __ ldxr($tmp$$Register, base);
       
  7360     __ cmp($tmp$$Register, $oldval$$Register);
       
  7361     __ b(done, ne);
       
  7362     __ stxr($tmp$$Register, $newval$$Register,  base);
       
  7363     __ cbnz_w($tmp$$Register, loop);
       
  7364     __ bind(done);
       
  7365     __ cset_w($res$$Register, eq);
       
  7366   %}
       
  7367   ins_pipe( long_memory_op );
       
  7368 %}
       
  7369 #else // !AARCH64
       
  7370 instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegLd newval, iRegI res, iRegLd tmp, flagsReg ccr ) %{
       
  7371   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
       
  7372   effect( KILL ccr, TEMP tmp);
       
  7373   size(32);
       
  7374   format %{ "loop: \n\t"
       
  7375             "LDREXD   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
       
  7376             "CMP      $tmp.lo, $oldval.lo\n\t"
       
  7377             "CMP.eq   $tmp.hi, $oldval.hi\n\t"
       
  7378             "STREXD.eq $tmp, $newval, $mem\n\t"
       
  7379             "MOV.ne   $tmp, 0 \n\t"
       
  7380             "XORS.eq  $tmp,$tmp, 1 \n\t"
       
  7381             "B.eq     loop \n\t"
       
  7382             "MOV      $res, $tmp" %}
       
  7383   ins_encode %{
       
  7384     Label loop;
       
  7385     __ bind(loop);
       
  7386     __ ldrexd($tmp$$Register, $mem$$Address);
       
  7387     __ cmp($tmp$$Register, $oldval$$Register);
       
  7388     __ cmp($tmp$$Register->successor(), $oldval$$Register->successor(), eq);
       
  7389     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address, eq);
       
  7390     __ mov($tmp$$Register, 0, ne);
       
  7391     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
       
  7392     __ b(loop, eq);
       
  7393     __ mov($res$$Register, $tmp$$Register);
       
  7394   %}
       
  7395   ins_pipe( long_memory_op );
       
  7396 %}
       
  7397 
       
  7398 
       
  7399 instruct compareAndSwapI_bool(memoryex mem, iRegI oldval, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
       
  7400   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
       
  7401   effect( KILL ccr, TEMP tmp);
       
  7402   size(28);
       
  7403   format %{ "loop: \n\t"
       
  7404             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
       
  7405             "CMP      $tmp, $oldval\n\t"
       
  7406             "STREX.eq $tmp, $newval, $mem\n\t"
       
  7407             "MOV.ne   $tmp, 0 \n\t"
       
  7408             "XORS.eq  $tmp,$tmp, 1 \n\t"
       
  7409             "B.eq     loop \n\t"
       
  7410             "MOV      $res, $tmp" %}
       
  7411 
       
  7412   ins_encode %{
       
  7413     Label loop;
       
  7414     __ bind(loop);
       
  7415     __ ldrex($tmp$$Register,$mem$$Address);
       
  7416     __ cmp($tmp$$Register, $oldval$$Register);
       
  7417     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
       
  7418     __ mov($tmp$$Register, 0, ne);
       
  7419     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
       
  7420     __ b(loop, eq);
       
  7421     __ mov($res$$Register, $tmp$$Register);
       
  7422   %}
       
  7423   ins_pipe( long_memory_op );
       
  7424 %}
       
  7425 
       
  7426 instruct compareAndSwapP_bool(memoryex mem, iRegP oldval, iRegP newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
       
  7427   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
       
  7428   effect( KILL ccr, TEMP tmp);
       
  7429   size(28);
       
  7430   format %{ "loop: \n\t"
       
  7431             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
       
  7432             "CMP      $tmp, $oldval\n\t"
       
  7433             "STREX.eq $tmp, $newval, $mem\n\t"
       
  7434             "MOV.ne   $tmp, 0 \n\t"
       
  7435             "EORS.eq  $tmp,$tmp, 1 \n\t"
       
  7436             "B.eq     loop \n\t"
       
  7437             "MOV      $res, $tmp" %}
       
  7438 
       
  7439   ins_encode %{
       
  7440     Label loop;
       
  7441     __ bind(loop);
       
  7442     __ ldrex($tmp$$Register,$mem$$Address);
       
  7443     __ cmp($tmp$$Register, $oldval$$Register);
       
  7444     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
       
  7445     __ mov($tmp$$Register, 0, ne);
       
  7446     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
       
  7447     __ b(loop, eq);
       
  7448     __ mov($res$$Register, $tmp$$Register);
       
  7449   %}
       
  7450   ins_pipe( long_memory_op );
       
  7451 %}
       
  7452 #endif // !AARCH64
       
  7453 
       
  7454 #ifdef AARCH64
       
  7455 instruct xaddI_aimmI_no_res(memoryex mem, aimmI add, Universe dummy, iRegI tmp1, iRegI tmp2) %{
       
  7456   predicate(n->as_LoadStore()->result_not_used());
       
  7457   match(Set dummy (GetAndAddI mem add));
       
  7458   effect(TEMP tmp1, TEMP tmp2);
       
  7459   size(16);
       
  7460   format %{ "loop:\n\t"
       
  7461             "LDXR_w   $tmp1, $mem\n\t"
       
  7462             "ADD_w    $tmp1, $tmp1, $add\n\t"
       
  7463             "STXR_w   $tmp2, $tmp1, $mem\n\t"
       
  7464             "CBNZ_w   $tmp2, loop" %}
       
  7465 
       
  7466   ins_encode %{
       
  7467     Label loop;
       
  7468     Register base = reg_to_register_object($mem$$base);
       
  7469     __ bind(loop);
       
  7470     __ ldxr_w($tmp1$$Register, base);
       
  7471     __ add_w($tmp1$$Register, $tmp1$$Register, $add$$constant);
       
  7472     __ stxr_w($tmp2$$Register, $tmp1$$Register, base);
       
  7473     __ cbnz_w($tmp2$$Register, loop);
       
  7474   %}
       
  7475   ins_pipe( long_memory_op );
       
  7476 %}
       
  7477 #else
       
  7478 instruct xaddI_aimmI_no_res(memoryex mem, aimmI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
       
  7479   predicate(n->as_LoadStore()->result_not_used());
       
  7480   match(Set dummy (GetAndAddI mem add));
       
  7481   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
       
  7482   size(20);
       
  7483   format %{ "loop: \n\t"
       
  7484             "LDREX    $tmp1, $mem\n\t"
       
  7485             "ADD      $tmp1, $tmp1, $add\n\t"
       
  7486             "STREX    $tmp2, $tmp1, $mem\n\t"
       
  7487             "CMP      $tmp2, 0 \n\t"
       
  7488             "B.ne     loop \n\t" %}
       
  7489 
       
  7490   ins_encode %{
       
  7491     Label loop;
       
  7492     __ bind(loop);
       
  7493     __ ldrex($tmp1$$Register,$mem$$Address);
       
  7494     __ add($tmp1$$Register, $tmp1$$Register, $add$$constant);
       
  7495     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
       
  7496     __ cmp($tmp2$$Register, 0);
       
  7497     __ b(loop, ne);
       
  7498   %}
       
  7499   ins_pipe( long_memory_op );
       
  7500 %}
       
  7501 #endif
       
  7502 
       
  7503 #ifdef AARCH64
       
  7504 instruct xaddI_reg_no_res(memoryex mem, iRegI add, Universe dummy, iRegI tmp1, iRegI tmp2) %{
       
  7505   predicate(n->as_LoadStore()->result_not_used());
       
  7506   match(Set dummy (GetAndAddI mem add));
       
  7507   effect(TEMP tmp1, TEMP tmp2);
       
  7508   size(16);
       
  7509   format %{ "loop:\n\t"
       
  7510             "LDXR_w   $tmp1, $mem\n\t"
       
  7511             "ADD_w    $tmp1, $tmp1, $add\n\t"
       
  7512             "STXR_w   $tmp2, $tmp1, $mem\n\t"
       
  7513             "CBNZ_w   $tmp2, loop" %}
       
  7514 
       
  7515   ins_encode %{
       
  7516     Label loop;
       
  7517     Register base = reg_to_register_object($mem$$base);
       
  7518     __ bind(loop);
       
  7519     __ ldxr_w($tmp1$$Register, base);
       
  7520     __ add_w($tmp1$$Register, $tmp1$$Register, $add$$Register);
       
  7521     __ stxr_w($tmp2$$Register, $tmp1$$Register, base);
       
  7522     __ cbnz_w($tmp2$$Register, loop);
       
  7523   %}
       
  7524   ins_pipe( long_memory_op );
       
  7525 %}
       
  7526 #else
       
  7527 instruct xaddI_reg_no_res(memoryex mem, iRegI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
       
  7528   predicate(n->as_LoadStore()->result_not_used());
       
  7529   match(Set dummy (GetAndAddI mem add));
       
  7530   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
       
  7531   size(20);
       
  7532   format %{ "loop: \n\t"
       
  7533             "LDREX    $tmp1, $mem\n\t"
       
  7534             "ADD      $tmp1, $tmp1, $add\n\t"
       
  7535             "STREX    $tmp2, $tmp1, $mem\n\t"
       
  7536             "CMP      $tmp2, 0 \n\t"
       
  7537             "B.ne     loop \n\t" %}
       
  7538 
       
  7539   ins_encode %{
       
  7540     Label loop;
       
  7541     __ bind(loop);
       
  7542     __ ldrex($tmp1$$Register,$mem$$Address);
       
  7543     __ add($tmp1$$Register, $tmp1$$Register, $add$$Register);
       
  7544     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
       
  7545     __ cmp($tmp2$$Register, 0);
       
  7546     __ b(loop, ne);
       
  7547   %}
       
  7548   ins_pipe( long_memory_op );
       
  7549 %}
       
  7550 #endif
       
  7551 
       
  7552 #ifdef AARCH64
       
  7553 instruct xaddI_aimmI(memoryex mem, aimmI add, iRegI res, iRegI tmp1, iRegI tmp2) %{
       
  7554   match(Set res (GetAndAddI mem add));
       
  7555   effect(TEMP tmp1, TEMP tmp2, TEMP res);
       
  7556   size(16);
       
  7557   format %{ "loop:\n\t"
       
  7558             "LDXR_w   $res, $mem\n\t"
       
  7559             "ADD_w    $tmp1, $res, $add\n\t"
       
  7560             "STXR_w   $tmp2, $tmp1, $mem\n\t"
       
  7561             "CBNZ_w   $tmp2, loop" %}
       
  7562 
       
  7563   ins_encode %{
       
  7564     Label loop;
       
  7565     Register base = reg_to_register_object($mem$$base);
       
  7566     __ bind(loop);
       
  7567     __ ldxr_w($res$$Register, base);
       
  7568     __ add_w($tmp1$$Register, $res$$Register, $add$$constant);
       
  7569     __ stxr_w($tmp2$$Register, $tmp1$$Register, base);
       
  7570     __ cbnz_w($tmp2$$Register, loop);
       
  7571   %}
       
  7572   ins_pipe( long_memory_op );
       
  7573 %}
       
  7574 #else
       
  7575 instruct xaddI_aimmI(memoryex mem, aimmI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
       
  7576   match(Set res (GetAndAddI mem add));
       
  7577   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
       
  7578   size(20);
       
  7579   format %{ "loop: \n\t"
       
  7580             "LDREX    $res, $mem\n\t"
       
  7581             "ADD      $tmp1, $res, $add\n\t"
       
  7582             "STREX    $tmp2, $tmp1, $mem\n\t"
       
  7583             "CMP      $tmp2, 0 \n\t"
       
  7584             "B.ne     loop \n\t" %}
       
  7585 
       
  7586   ins_encode %{
       
  7587     Label loop;
       
  7588     __ bind(loop);
       
  7589     __ ldrex($res$$Register,$mem$$Address);
       
  7590     __ add($tmp1$$Register, $res$$Register, $add$$constant);
       
  7591     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
       
  7592     __ cmp($tmp2$$Register, 0);
       
  7593     __ b(loop, ne);
       
  7594   %}
       
  7595   ins_pipe( long_memory_op );
       
  7596 %}
       
  7597 #endif
       
  7598 
       
  7599 #ifdef AARCH64
       
  7600 instruct xaddI_reg(memoryex mem, iRegI add, iRegI res, iRegI tmp1, iRegI tmp2) %{
       
  7601   match(Set res (GetAndAddI mem add));
       
  7602   effect(TEMP tmp1, TEMP tmp2, TEMP res);
       
  7603   size(16);
       
  7604   format %{ "loop:\n\t"
       
  7605             "LDXR_w   $res, $mem\n\t"
       
  7606             "ADD_w    $tmp1, $res, $add\n\t"
       
  7607             "STXR_w   $tmp2, $tmp1, $mem\n\t"
       
  7608             "CBNZ_w   $tmp2, loop" %}
       
  7609 
       
  7610   ins_encode %{
       
  7611     Label loop;
       
  7612     Register base = reg_to_register_object($mem$$base);
       
  7613     __ bind(loop);
       
  7614     __ ldxr_w($res$$Register, base);
       
  7615     __ add_w($tmp1$$Register, $res$$Register, $add$$Register);
       
  7616     __ stxr_w($tmp2$$Register, $tmp1$$Register, base);
       
  7617     __ cbnz_w($tmp2$$Register, loop);
       
  7618   %}
       
  7619   ins_pipe( long_memory_op );
       
  7620 %}
       
  7621 #else
       
  7622 instruct xaddI_reg(memoryex mem, iRegI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
       
  7623   match(Set res (GetAndAddI mem add));
       
  7624   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
       
  7625   size(20);
       
  7626   format %{ "loop: \n\t"
       
  7627             "LDREX    $res, $mem\n\t"
       
  7628             "ADD      $tmp1, $res, $add\n\t"
       
  7629             "STREX    $tmp2, $tmp1, $mem\n\t"
       
  7630             "CMP      $tmp2, 0 \n\t"
       
  7631             "B.ne     loop \n\t" %}
       
  7632 
       
  7633   ins_encode %{
       
  7634     Label loop;
       
  7635     __ bind(loop);
       
  7636     __ ldrex($res$$Register,$mem$$Address);
       
  7637     __ add($tmp1$$Register, $res$$Register, $add$$Register);
       
  7638     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
       
  7639     __ cmp($tmp2$$Register, 0);
       
  7640     __ b(loop, ne);
       
  7641   %}
       
  7642   ins_pipe( long_memory_op );
       
  7643 %}
       
  7644 #endif
       
  7645 
       
  7646 #ifdef AARCH64
       
  7647 instruct xaddL_reg_no_res(memoryex mem, iRegL add, Universe dummy, iRegL tmp1, iRegI tmp2) %{
       
  7648   predicate(n->as_LoadStore()->result_not_used());
       
  7649   match(Set dummy (GetAndAddL mem add));
       
  7650   effect(TEMP tmp1, TEMP tmp2);
       
  7651   size(16);
       
  7652   format %{ "loop:\n\t"
       
  7653             "LDXR     $tmp1, $mem\n\t"
       
  7654             "ADD      $tmp1, $tmp1, $add\n\t"
       
  7655             "STXR     $tmp2, $tmp1, $mem\n\t"
       
  7656             "CBNZ_w   $tmp2, loop" %}
       
  7657 
       
  7658   ins_encode %{
       
  7659     Label loop;
       
  7660     Register base = reg_to_register_object($mem$$base);
       
  7661     __ bind(loop);
       
  7662     __ ldxr($tmp1$$Register, base);
       
  7663     __ add($tmp1$$Register, $tmp1$$Register, $add$$Register);
       
  7664     __ stxr($tmp2$$Register, $tmp1$$Register, base);
       
  7665     __ cbnz_w($tmp2$$Register, loop);
       
  7666   %}
       
  7667   ins_pipe( long_memory_op );
       
  7668 %}
       
  7669 #else
       
  7670 instruct xaddL_reg_no_res(memoryex mem, iRegL add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
       
  7671   predicate(n->as_LoadStore()->result_not_used());
       
  7672   match(Set dummy (GetAndAddL mem add));
       
  7673   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
       
  7674   size(24);
       
  7675   format %{ "loop: \n\t"
       
  7676             "LDREXD   $tmp1, $mem\n\t"
       
  7677             "ADDS     $tmp1.lo, $tmp1.lo, $add.lo\n\t"
       
  7678             "ADC      $tmp1.hi, $tmp1.hi, $add.hi\n\t"
       
  7679             "STREXD   $tmp2, $tmp1, $mem\n\t"
       
  7680             "CMP      $tmp2, 0 \n\t"
       
  7681             "B.ne     loop \n\t" %}
       
  7682 
       
  7683   ins_encode %{
       
  7684     Label loop;
       
  7685     __ bind(loop);
       
  7686     __ ldrexd($tmp1$$Register, $mem$$Address);
       
  7687     __ adds($tmp1$$Register, $tmp1$$Register, $add$$Register);
       
  7688     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), $add$$Register->successor());
       
  7689     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
       
  7690     __ cmp($tmp2$$Register, 0);
       
  7691     __ b(loop, ne);
       
  7692   %}
       
  7693   ins_pipe( long_memory_op );
       
  7694 %}
       
  7695 #endif
       
  7696 
       
  7697 #ifdef AARCH64
       
  7698 instruct xaddL_imm_no_res(memoryex mem, aimmL add, Universe dummy, iRegL tmp1, iRegI tmp2) %{
       
  7699   predicate(n->as_LoadStore()->result_not_used());
       
  7700   match(Set dummy (GetAndAddL mem add));
       
  7701   effect(TEMP tmp1, TEMP tmp2);
       
  7702   size(16);
       
  7703   format %{ "loop:\n\t"
       
  7704             "LDXR     $tmp1, $mem\n\t"
       
  7705             "ADD      $tmp1, $tmp1, $add\n\t"
       
  7706             "STXR     $tmp2, $tmp1, $mem\n\t"
       
  7707             "CBNZ_w   $tmp2, loop" %}
       
  7708 
       
  7709   ins_encode %{
       
  7710     Label loop;
       
  7711     Register base = reg_to_register_object($mem$$base);
       
  7712     __ bind(loop);
       
  7713     __ ldxr($tmp1$$Register, base);
       
  7714     __ add($tmp1$$Register, $tmp1$$Register, $add$$constant);
       
  7715     __ stxr($tmp2$$Register, $tmp1$$Register, base);
       
  7716     __ cbnz_w($tmp2$$Register, loop);
       
  7717   %}
       
  7718   ins_pipe( long_memory_op );
       
  7719 %}
       
  7720 #else
       
  7721 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
       
  7722 // (hi($con$$constant), lo($con$$constant)) becomes
       
  7723 instruct xaddL_immRot_no_res(memoryex mem, immLlowRot add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
       
  7724   predicate(n->as_LoadStore()->result_not_used());
       
  7725   match(Set dummy (GetAndAddL mem add));
       
  7726   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
       
  7727   size(24);
       
  7728   format %{ "loop: \n\t"
       
  7729             "LDREXD   $tmp1, $mem\n\t"
       
  7730             "ADDS     $tmp1.lo, $tmp1.lo, $add\n\t"
       
  7731             "ADC      $tmp1.hi, $tmp1.hi, 0\n\t"
       
  7732             "STREXD   $tmp2, $tmp1, $mem\n\t"
       
  7733             "CMP      $tmp2, 0 \n\t"
       
  7734             "B.ne     loop \n\t" %}
       
  7735 
       
  7736   ins_encode %{
       
  7737     Label loop;
       
  7738     __ bind(loop);
       
  7739     __ ldrexd($tmp1$$Register, $mem$$Address);
       
  7740     __ adds($tmp1$$Register, $tmp1$$Register, $add$$constant);
       
  7741     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), 0);
       
  7742     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
       
  7743     __ cmp($tmp2$$Register, 0);
       
  7744     __ b(loop, ne);
       
  7745   %}
       
  7746   ins_pipe( long_memory_op );
       
  7747 %}
       
  7748 #endif
       
  7749 
       
  7750 #ifdef AARCH64
       
  7751 instruct xaddL_reg(memoryex mem, iRegL add, iRegL res, iRegL tmp1, iRegI tmp2) %{
       
  7752   match(Set res (GetAndAddL mem add));
       
  7753   effect(TEMP tmp1, TEMP tmp2, TEMP res);
       
  7754   size(16);
       
  7755   format %{ "loop:\n\t"
       
  7756             "LDXR     $res, $mem\n\t"
       
  7757             "ADD      $tmp1, $res, $add\n\t"
       
  7758             "STXR     $tmp2, $tmp1, $mem\n\t"
       
  7759             "CBNZ_w   $tmp2, loop" %}
       
  7760 
       
  7761   ins_encode %{
       
  7762     Label loop;
       
  7763     Register base = reg_to_register_object($mem$$base);
       
  7764     __ bind(loop);
       
  7765     __ ldxr($res$$Register, base);
       
  7766     __ add($tmp1$$Register, $res$$Register, $add$$Register);
       
  7767     __ stxr($tmp2$$Register, $tmp1$$Register, base);
       
  7768     __ cbnz_w($tmp2$$Register, loop);
       
  7769   %}
       
  7770   ins_pipe( long_memory_op );
       
  7771 %}
       
  7772 #else
       
  7773 instruct xaddL_reg(memoryex mem, iRegL add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
       
  7774   match(Set res (GetAndAddL mem add));
       
  7775   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
       
  7776   size(24);
       
  7777   format %{ "loop: \n\t"
       
  7778             "LDREXD   $res, $mem\n\t"
       
  7779             "ADDS     $tmp1.lo, $res.lo, $add.lo\n\t"
       
  7780             "ADC      $tmp1.hi, $res.hi, $add.hi\n\t"
       
  7781             "STREXD   $tmp2, $tmp1, $mem\n\t"
       
  7782             "CMP      $tmp2, 0 \n\t"
       
  7783             "B.ne     loop \n\t" %}
       
  7784 
       
  7785   ins_encode %{
       
  7786     Label loop;
       
  7787     __ bind(loop);
       
  7788     __ ldrexd($res$$Register, $mem$$Address);
       
  7789     __ adds($tmp1$$Register, $res$$Register, $add$$Register);
       
  7790     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), $add$$Register->successor());
       
  7791     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
       
  7792     __ cmp($tmp2$$Register, 0);
       
  7793     __ b(loop, ne);
       
  7794   %}
       
  7795   ins_pipe( long_memory_op );
       
  7796 %}
       
  7797 #endif
       
  7798 
       
  7799 #ifdef AARCH64
       
  7800 instruct xaddL_imm(memoryex mem, aimmL add, iRegL res, iRegL tmp1, iRegI tmp2) %{
       
  7801   match(Set res (GetAndAddL mem add));
       
  7802   effect(TEMP tmp1, TEMP tmp2, TEMP res);
       
  7803   size(16);
       
  7804   format %{ "loop:\n\t"
       
  7805             "LDXR     $res, $mem\n\t"
       
  7806             "ADD      $tmp1, $res, $add\n\t"
       
  7807             "STXR     $tmp2, $tmp1, $mem\n\t"
       
  7808             "CBNZ_w   $tmp2, loop" %}
       
  7809 
       
  7810   ins_encode %{
       
  7811     Label loop;
       
  7812     Register base = reg_to_register_object($mem$$base);
       
  7813     __ bind(loop);
       
  7814     __ ldxr($res$$Register, base);
       
  7815     __ add($tmp1$$Register, $res$$Register, $add$$constant);
       
  7816     __ stxr($tmp2$$Register, $tmp1$$Register, base);
       
  7817     __ cbnz_w($tmp2$$Register, loop);
       
  7818   %}
       
  7819   ins_pipe( long_memory_op );
       
  7820 %}
       
  7821 #else
       
  7822 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
       
  7823 // (hi($con$$constant), lo($con$$constant)) becomes
       
  7824 instruct xaddL_immRot(memoryex mem, immLlowRot add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
       
  7825   match(Set res (GetAndAddL mem add));
       
  7826   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
       
  7827   size(24);
       
  7828   format %{ "loop: \n\t"
       
  7829             "LDREXD   $res, $mem\n\t"
       
  7830             "ADDS     $tmp1.lo, $res.lo, $add\n\t"
       
  7831             "ADC      $tmp1.hi, $res.hi, 0\n\t"
       
  7832             "STREXD   $tmp2, $tmp1, $mem\n\t"
       
  7833             "CMP      $tmp2, 0 \n\t"
       
  7834             "B.ne     loop \n\t" %}
       
  7835 
       
  7836   ins_encode %{
       
  7837     Label loop;
       
  7838     __ bind(loop);
       
  7839     __ ldrexd($res$$Register, $mem$$Address);
       
  7840     __ adds($tmp1$$Register, $res$$Register, $add$$constant);
       
  7841     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), 0);
       
  7842     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
       
  7843     __ cmp($tmp2$$Register, 0);
       
  7844     __ b(loop, ne);
       
  7845   %}
       
  7846   ins_pipe( long_memory_op );
       
  7847 %}
       
  7848 #endif
       
  7849 
       
  7850 #ifdef AARCH64
       
  7851 instruct xchgI(memoryex mem, iRegI newval, iRegI res, iRegI tmp) %{
       
  7852   match(Set res (GetAndSetI mem newval));
       
  7853   effect(TEMP tmp, TEMP res);
       
  7854   size(12);
       
  7855   format %{ "loop:\n\t"
       
  7856             "LDXR_w   $res, $mem\n\t"
       
  7857             "STXR_w   $tmp, $newval, $mem\n\t"
       
  7858             "CBNZ_w   $tmp, loop" %}
       
  7859 
       
  7860   ins_encode %{
       
  7861     Label loop;
       
  7862     Register base = reg_to_register_object($mem$$base);
       
  7863     __ bind(loop);
       
  7864     __ ldxr_w($res$$Register, base);
       
  7865     __ stxr_w($tmp$$Register, $newval$$Register, base);
       
  7866     __ cbnz_w($tmp$$Register, loop);
       
  7867   %}
       
  7868   ins_pipe( long_memory_op );
       
  7869 %}
       
  7870 
       
  7871 #ifdef XXX
       
  7872 // Disabled until 8051805 is fixed.
       
  7873 instruct xchgN(memoryex mem, iRegN newval, iRegN res, iRegN tmp) %{
       
  7874   match(Set res (GetAndSetN mem newval));
       
  7875   effect(TEMP tmp, TEMP res);
       
  7876   size(12);
       
  7877   format %{ "loop:\n\t"
       
  7878             "LDXR_w   $res, $mem\n\t"
       
  7879             "STXR_w   $tmp, $newval, $mem\n\t"
       
  7880             "CBNZ_w   $tmp, loop" %}
       
  7881 
       
  7882   ins_encode %{
       
  7883     Label loop;
       
  7884     Register base = reg_to_register_object($mem$$base);
       
  7885     __ bind(loop);
       
  7886     __ ldxr_w($res$$Register, base);
       
  7887     __ stxr_w($tmp$$Register, $newval$$Register, base);
       
  7888     __ cbnz_w($tmp$$Register, loop);
       
  7889   %}
       
  7890   ins_pipe( long_memory_op );
       
  7891 %}
       
  7892 #endif
       
  7893 #else
       
  7894 instruct xchgI(memoryex mem, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr) %{
       
  7895   match(Set res (GetAndSetI mem newval));
       
  7896   effect(KILL ccr, TEMP tmp, TEMP res);
       
  7897   size(16);
       
  7898   format %{ "loop: \n\t"
       
  7899             "LDREX    $res, $mem\n\t"
       
  7900             "STREX    $tmp, $newval, $mem\n\t"
       
  7901             "CMP      $tmp, 0 \n\t"
       
  7902             "B.ne     loop \n\t" %}
       
  7903 
       
  7904   ins_encode %{
       
  7905     Label loop;
       
  7906     __ bind(loop);
       
  7907     __ ldrex($res$$Register,$mem$$Address);
       
  7908     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
       
  7909     __ cmp($tmp$$Register, 0);
       
  7910     __ b(loop, ne);
       
  7911   %}
       
  7912   ins_pipe( long_memory_op );
       
  7913 %}
       
  7914 #endif
       
  7915 
       
  7916 #ifdef AARCH64
       
  7917 instruct xchgL(memoryex mem, iRegL newval, iRegL res, iRegI tmp) %{
       
  7918   match(Set res (GetAndSetL mem newval));
       
  7919   effect(TEMP tmp, TEMP res);
       
  7920   size(12);
       
  7921   format %{ "loop:\n\t"
       
  7922             "LDXR     $res, $mem\n\t"
       
  7923             "STXR     $tmp, $newval, $mem\n\t"
       
  7924             "CBNZ_w   $tmp, loop" %}
       
  7925 
       
  7926   ins_encode %{
       
  7927     Label loop;
       
  7928     Register base = reg_to_register_object($mem$$base);
       
  7929     __ bind(loop);
       
  7930     __ ldxr($res$$Register, base);
       
  7931     __ stxr($tmp$$Register, $newval$$Register, base);
       
  7932     __ cbnz_w($tmp$$Register, loop);
       
  7933   %}
       
  7934   ins_pipe( long_memory_op );
       
  7935 %}
       
  7936 #else
       
  7937 instruct xchgL(memoryex mem, iRegLd newval, iRegLd res, iRegI tmp, flagsReg ccr) %{
       
  7938   match(Set res (GetAndSetL mem newval));
       
  7939   effect( KILL ccr, TEMP tmp, TEMP res);
       
  7940   size(16);
       
  7941   format %{ "loop: \n\t"
       
  7942             "LDREXD   $res, $mem\n\t"
       
  7943             "STREXD   $tmp, $newval, $mem\n\t"
       
  7944             "CMP      $tmp, 0 \n\t"
       
  7945             "B.ne     loop \n\t" %}
       
  7946 
       
  7947   ins_encode %{
       
  7948     Label loop;
       
  7949     __ bind(loop);
       
  7950     __ ldrexd($res$$Register, $mem$$Address);
       
  7951     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address);
       
  7952     __ cmp($tmp$$Register, 0);
       
  7953     __ b(loop, ne);
       
  7954   %}
       
  7955   ins_pipe( long_memory_op );
       
  7956 %}
       
  7957 #endif // !AARCH64
       
  7958 
       
  7959 #ifdef AARCH64
       
  7960 instruct xchgP(memoryex mem, iRegP newval, iRegP res, iRegI tmp) %{
       
  7961   match(Set res (GetAndSetP mem newval));
       
  7962   effect(TEMP tmp, TEMP res);
       
  7963   size(12);
       
  7964   format %{ "loop:\n\t"
       
  7965             "LDREX    $res, $mem\n\t"
       
  7966             "STREX    $tmp, $newval, $mem\n\t"
       
  7967             "CBNZ_w   $tmp, loop" %}
       
  7968 
       
  7969   ins_encode %{
       
  7970     Label loop;
       
  7971     Register base = reg_to_register_object($mem$$base);
       
  7972     __ bind(loop);
       
  7973     __ ldrex($res$$Register, base);
       
  7974     __ strex($tmp$$Register, $newval$$Register, base);
       
  7975     __ cbnz_w($tmp$$Register, loop);
       
  7976   %}
       
  7977   ins_pipe( long_memory_op );
       
  7978 %}
       
  7979 #else
       
  7980 instruct xchgP(memoryex mem, iRegP newval, iRegP res, iRegI tmp, flagsReg ccr) %{
       
  7981   match(Set res (GetAndSetP mem newval));
       
  7982   effect(KILL ccr, TEMP tmp, TEMP res);
       
  7983   size(16);
       
  7984   format %{ "loop: \n\t"
       
  7985             "LDREX    $res, $mem\n\t"
       
  7986             "STREX    $tmp, $newval, $mem\n\t"
       
  7987             "CMP      $tmp, 0 \n\t"
       
  7988             "B.ne     loop \n\t" %}
       
  7989 
       
  7990   ins_encode %{
       
  7991     Label loop;
       
  7992     __ bind(loop);
       
  7993     __ ldrex($res$$Register,$mem$$Address);
       
  7994     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
       
  7995     __ cmp($tmp$$Register, 0);
       
  7996     __ b(loop, ne);
       
  7997   %}
       
  7998   ins_pipe( long_memory_op );
       
  7999 %}
       
  8000 #endif // !AARCH64
       
  8001 
       
  8002 //---------------------
       
  8003 // Subtraction Instructions
       
  8004 // Register Subtraction
       
  8005 instruct subI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
       
  8006   match(Set dst (SubI src1 src2));
       
  8007 
       
  8008   size(4);
       
  8009   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
       
  8010   ins_encode %{
       
  8011     __ sub_32($dst$$Register, $src1$$Register, $src2$$Register);
       
  8012   %}
       
  8013   ins_pipe(ialu_reg_reg);
       
  8014 %}
       
  8015 
       
  8016 #ifndef AARCH64
       
  8017 instruct subshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  8018   match(Set dst (SubI src1 (LShiftI src2 src3)));
       
  8019 
       
  8020   size(4);
       
  8021   format %{ "SUB    $dst,$src1,$src2<<$src3" %}
       
  8022   ins_encode %{
       
  8023     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
       
  8024   %}
       
  8025   ins_pipe(ialu_reg_reg);
       
  8026 %}
       
  8027 #endif
       
  8028 
       
  8029 instruct subshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
       
  8030   match(Set dst (SubI src1 (LShiftI src2 src3)));
       
  8031 
       
  8032   size(4);
       
  8033   format %{ "sub_32 $dst,$src1,$src2<<$src3\t! int" %}
       
  8034   ins_encode %{
       
  8035     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
       
  8036   %}
       
  8037   ins_pipe(ialu_reg_reg);
       
  8038 %}
       
  8039 
       
  8040 #ifndef AARCH64
       
  8041 instruct subsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  8042   match(Set dst (SubI src1 (RShiftI src2 src3)));
       
  8043 
       
  8044   size(4);
       
  8045   format %{ "SUB    $dst,$src1,$src2>>$src3" %}
       
  8046   ins_encode %{
       
  8047     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
       
  8048   %}
       
  8049   ins_pipe(ialu_reg_reg);
       
  8050 %}
       
  8051 #endif
       
  8052 
       
  8053 instruct subsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
       
  8054   match(Set dst (SubI src1 (RShiftI src2 src3)));
       
  8055 
       
  8056   size(4);
       
  8057   format %{ "sub_32 $dst,$src1,$src2>>$src3\t! int" %}
       
  8058   ins_encode %{
       
  8059     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
       
  8060   %}
       
  8061   ins_pipe(ialu_reg_reg);
       
  8062 %}
       
  8063 
       
  8064 #ifndef AARCH64
       
  8065 instruct subshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  8066   match(Set dst (SubI src1 (URShiftI src2 src3)));
       
  8067 
       
  8068   size(4);
       
  8069   format %{ "SUB    $dst,$src1,$src2>>>$src3" %}
       
  8070   ins_encode %{
       
  8071     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
       
  8072   %}
       
  8073   ins_pipe(ialu_reg_reg);
       
  8074 %}
       
  8075 #endif
       
  8076 
       
  8077 instruct subshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
       
  8078   match(Set dst (SubI src1 (URShiftI src2 src3)));
       
  8079 
       
  8080   size(4);
       
  8081   format %{ "sub_32 $dst,$src1,$src2>>>$src3\t! int" %}
       
  8082   ins_encode %{
       
  8083     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
       
  8084   %}
       
  8085   ins_pipe(ialu_reg_reg);
       
  8086 %}
       
  8087 
       
  8088 #ifndef AARCH64
       
  8089 instruct rsbshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  8090   match(Set dst (SubI (LShiftI src1 src2) src3));
       
  8091 
       
  8092   size(4);
       
  8093   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
       
  8094   ins_encode %{
       
  8095     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
       
  8096   %}
       
  8097   ins_pipe(ialu_reg_reg);
       
  8098 %}
       
  8099 
       
  8100 instruct rsbshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
       
  8101   match(Set dst (SubI (LShiftI src1 src2) src3));
       
  8102 
       
  8103   size(4);
       
  8104   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
       
  8105   ins_encode %{
       
  8106     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
       
  8107   %}
       
  8108   ins_pipe(ialu_reg_reg);
       
  8109 %}
       
  8110 
       
  8111 instruct rsbsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  8112   match(Set dst (SubI (RShiftI src1 src2) src3));
       
  8113 
       
  8114   size(4);
       
  8115   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
       
  8116   ins_encode %{
       
  8117     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
       
  8118   %}
       
  8119   ins_pipe(ialu_reg_reg);
       
  8120 %}
       
  8121 
       
  8122 instruct rsbsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
       
  8123   match(Set dst (SubI (RShiftI src1 src2) src3));
       
  8124 
       
  8125   size(4);
       
  8126   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
       
  8127   ins_encode %{
       
  8128     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
       
  8129   %}
       
  8130   ins_pipe(ialu_reg_reg);
       
  8131 %}
       
  8132 
       
  8133 instruct rsbshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  8134   match(Set dst (SubI (URShiftI src1 src2) src3));
       
  8135 
       
  8136   size(4);
       
  8137   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
       
  8138   ins_encode %{
       
  8139     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
       
  8140   %}
       
  8141   ins_pipe(ialu_reg_reg);
       
  8142 %}
       
  8143 
       
  8144 instruct rsbshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
       
  8145   match(Set dst (SubI (URShiftI src1 src2) src3));
       
  8146 
       
  8147   size(4);
       
  8148   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
       
  8149   ins_encode %{
       
  8150     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
       
  8151   %}
       
  8152   ins_pipe(ialu_reg_reg);
       
  8153 %}
       
  8154 #endif
       
  8155 
       
  8156 // Immediate Subtraction
       
  8157 instruct subI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
       
  8158   match(Set dst (SubI src1 src2));
       
  8159 
       
  8160   size(4);
       
  8161   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
       
  8162   ins_encode %{
       
  8163     __ sub_32($dst$$Register, $src1$$Register, $src2$$constant);
       
  8164   %}
       
  8165   ins_pipe(ialu_reg_imm);
       
  8166 %}
       
  8167 
       
  8168 instruct subI_reg_immRotneg(iRegI dst, iRegI src1, aimmIneg src2) %{
       
  8169   match(Set dst (AddI src1 src2));
       
  8170 
       
  8171   size(4);
       
  8172   format %{ "sub_32 $dst,$src1,-($src2)\t! int" %}
       
  8173   ins_encode %{
       
  8174     __ sub_32($dst$$Register, $src1$$Register, -$src2$$constant);
       
  8175   %}
       
  8176   ins_pipe(ialu_reg_imm);
       
  8177 %}
       
  8178 
       
  8179 #ifndef AARCH64
       
  8180 instruct subI_immRot_reg(iRegI dst, immIRot src1, iRegI src2) %{
       
  8181   match(Set dst (SubI src1 src2));
       
  8182 
       
  8183   size(4);
       
  8184   format %{ "RSB    $dst,$src2,src1" %}
       
  8185   ins_encode %{
       
  8186     __ rsb($dst$$Register, $src2$$Register, $src1$$constant);
       
  8187   %}
       
  8188   ins_pipe(ialu_zero_reg);
       
  8189 %}
       
  8190 #endif
       
  8191 
       
  8192 // Register Subtraction
       
  8193 #ifdef AARCH64
       
  8194 instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
       
  8195   match(Set dst (SubL src1 src2));
       
  8196 
       
  8197   size(4);
       
  8198   format %{ "SUB    $dst,$src1,$src2\t! long" %}
       
  8199   ins_encode %{
       
  8200     __ sub($dst$$Register, $src1$$Register, $src2$$Register);
       
  8201   %}
       
  8202   ins_pipe(ialu_reg_reg);
       
  8203 %}
       
  8204 #else
       
  8205 instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg icc ) %{
       
  8206   match(Set dst (SubL src1 src2));
       
  8207   effect (KILL icc);
       
  8208 
       
  8209   size(8);
       
  8210   format %{ "SUBS   $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
       
  8211             "SBC    $dst.hi,$src1.hi,$src2.hi" %}
       
  8212   ins_encode %{
       
  8213     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
       
  8214     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
       
  8215   %}
       
  8216   ins_pipe(ialu_reg_reg);
       
  8217 %}
       
  8218 #endif
       
  8219 
       
  8220 #ifdef AARCH64
       
  8221 // Immediate Subtraction
       
  8222 instruct subL_reg_aimm(iRegL dst, iRegL src1, aimmL src2) %{
       
  8223   match(Set dst (SubL src1 src2));
       
  8224 
       
  8225   size(4);
       
  8226   format %{ "SUB    $dst,$src1,$src2\t! long" %}
       
  8227   ins_encode %{
       
  8228     __ sub($dst$$Register, $src1$$Register, $src2$$constant);
       
  8229   %}
       
  8230   ins_pipe(ialu_reg_imm);
       
  8231 %}
       
  8232 
       
  8233 instruct subL_reg_immLneg(iRegL dst, iRegL src1, aimmLneg src2) %{
       
  8234   match(Set dst (AddL src1 src2));
       
  8235 
       
  8236   size(4);
       
  8237   format %{ "SUB    $dst,$src1,-($src2)\t! long" %}
       
  8238   ins_encode %{
       
  8239     __ sub($dst$$Register, $src1$$Register, -$src2$$constant);
       
  8240   %}
       
  8241   ins_pipe(ialu_reg_imm);
       
  8242 %}
       
  8243 #else
       
  8244 // TODO
       
  8245 #endif
       
  8246 
       
  8247 #ifndef AARCH64
       
  8248 // Immediate Subtraction
       
  8249 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
       
  8250 // (hi($con$$constant), lo($con$$constant)) becomes
       
  8251 instruct subL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg icc) %{
       
  8252   match(Set dst (SubL src1 con));
       
  8253   effect (KILL icc);
       
  8254 
       
  8255   size(8);
       
  8256   format %{ "SUB    $dst.lo,$src1.lo,$con\t! long\n\t"
       
  8257             "SBC    $dst.hi,$src1.hi,0" %}
       
  8258   ins_encode %{
       
  8259     __ subs($dst$$Register, $src1$$Register, $con$$constant);
       
  8260     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), 0);
       
  8261   %}
       
  8262   ins_pipe(ialu_reg_imm);
       
  8263 %}
       
  8264 
       
  8265 // Long negation
       
  8266 instruct negL_reg_reg(iRegL dst, immL0 zero, iRegL src2, flagsReg icc) %{
       
  8267   match(Set dst (SubL zero src2));
       
  8268   effect (KILL icc);
       
  8269 
       
  8270   size(8);
       
  8271   format %{ "RSBS   $dst.lo,$src2.lo,0\t! long\n\t"
       
  8272             "RSC    $dst.hi,$src2.hi,0" %}
       
  8273   ins_encode %{
       
  8274     __ rsbs($dst$$Register, $src2$$Register, 0);
       
  8275     __ rsc($dst$$Register->successor(), $src2$$Register->successor(), 0);
       
  8276   %}
       
  8277   ins_pipe(ialu_zero_reg);
       
  8278 %}
       
  8279 #endif // !AARCH64
       
  8280 
       
  8281 // Multiplication Instructions
       
  8282 // Integer Multiplication
       
  8283 // Register Multiplication
       
  8284 instruct mulI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
       
  8285   match(Set dst (MulI src1 src2));
       
  8286 
       
  8287   size(4);
       
  8288   format %{ "mul_32 $dst,$src1,$src2" %}
       
  8289   ins_encode %{
       
  8290     __ mul_32($dst$$Register, $src1$$Register, $src2$$Register);
       
  8291   %}
       
  8292   ins_pipe(imul_reg_reg);
       
  8293 %}
       
  8294 
       
  8295 #ifdef AARCH64
       
  8296 instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
       
  8297   match(Set dst (MulL src1 src2));
       
  8298   size(4);
       
  8299   format %{ "MUL  $dst,$src1,$src2\t! long" %}
       
  8300   ins_encode %{
       
  8301     __ mul($dst$$Register, $src1$$Register, $src2$$Register);
       
  8302   %}
       
  8303   ins_pipe(imul_reg_reg);
       
  8304 %}
       
  8305 #else
       
  8306 instruct mulL_lo1_hi2(iRegL dst, iRegL src1, iRegL src2) %{
       
  8307   effect(DEF dst, USE src1, USE src2);
       
  8308   size(4);
       
  8309   format %{ "MUL  $dst.hi,$src1.lo,$src2.hi\t! long" %}
       
  8310   ins_encode %{
       
  8311     __ mul($dst$$Register->successor(), $src1$$Register, $src2$$Register->successor());
       
  8312   %}
       
  8313   ins_pipe(imul_reg_reg);
       
  8314 %}
       
  8315 
       
  8316 instruct mulL_hi1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
       
  8317   effect(USE_DEF dst, USE src1, USE src2);
       
  8318   size(8);
       
  8319   format %{ "MLA  $dst.hi,$src1.hi,$src2.lo,$dst.hi\t! long\n\t"
       
  8320             "MOV  $dst.lo, 0"%}
       
  8321   ins_encode %{
       
  8322     __ mla($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register, $dst$$Register->successor());
       
  8323     __ mov($dst$$Register, 0);
       
  8324   %}
       
  8325   ins_pipe(imul_reg_reg);
       
  8326 %}
       
  8327 
       
  8328 instruct mulL_lo1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
       
  8329   effect(USE_DEF dst, USE src1, USE src2);
       
  8330   size(4);
       
  8331   format %{ "UMLAL  $dst.lo,$dst.hi,$src1,$src2\t! long" %}
       
  8332   ins_encode %{
       
  8333     __ umlal($dst$$Register, $dst$$Register->successor(), $src1$$Register, $src2$$Register);
       
  8334   %}
       
  8335   ins_pipe(imul_reg_reg);
       
  8336 %}
       
  8337 
       
  8338 instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
       
  8339   match(Set dst (MulL src1 src2));
       
  8340 
       
  8341   expand %{
       
  8342     mulL_lo1_hi2(dst, src1, src2);
       
  8343     mulL_hi1_lo2(dst, src1, src2);
       
  8344     mulL_lo1_lo2(dst, src1, src2);
       
  8345   %}
       
  8346 %}
       
  8347 #endif // !AARCH64
       
  8348 
       
  8349 // Integer Division
       
  8350 // Register Division
       
  8351 #ifdef AARCH64
       
  8352 instruct divI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
       
  8353   match(Set dst (DivI src1 src2));
       
  8354 
       
  8355   size(4);
       
  8356   format %{ "SDIV    $dst,$src1,$src2\t! 32-bit" %}
       
  8357   ins_encode %{
       
  8358     __ sdiv_w($dst$$Register, $src1$$Register, $src2$$Register);
       
  8359   %}
       
  8360   ins_pipe(ialu_reg_reg); // FIXME
       
  8361 %}
       
  8362 #else
       
  8363 instruct divI_reg_reg(R1RegI dst, R0RegI src1, R2RegI src2, LRRegP lr, flagsReg ccr) %{
       
  8364   match(Set dst (DivI src1 src2));
       
  8365   effect( KILL ccr, KILL src1, KILL src2, KILL lr);
       
  8366   ins_cost((2+71)*DEFAULT_COST);
       
  8367 
       
  8368   format %{ "DIV   $dst,$src1,$src2 ! call to StubRoutines::Arm::idiv_irem_entry()" %}
       
  8369   ins_encode %{
       
  8370     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
       
  8371   %}
       
  8372   ins_pipe(sdiv_reg_reg);
       
  8373 %}
       
  8374 #endif
       
  8375 
       
  8376 // Register Long Division
       
  8377 #ifdef AARCH64
       
  8378 instruct divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
       
  8379   match(Set dst (DivL src1 src2));
       
  8380 
       
  8381   size(4);
       
  8382   format %{ "SDIV    $dst,$src1,$src2" %}
       
  8383   ins_encode %{
       
  8384     __ sdiv($dst$$Register, $src1$$Register, $src2$$Register);
       
  8385   %}
       
  8386   ins_pipe(ialu_reg_reg); // FIXME
       
  8387 %}
       
  8388 #else
       
  8389 instruct divL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
       
  8390   match(Set dst (DivL src1 src2));
       
  8391   effect(CALL);
       
  8392   ins_cost(DEFAULT_COST*71);
       
  8393   format %{ "DIVL  $src1,$src2,$dst\t! long ! call to SharedRuntime::ldiv" %}
       
  8394   ins_encode %{
       
  8395     address target = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);
       
  8396     __ call(target, relocInfo::runtime_call_type);
       
  8397   %}
       
  8398   ins_pipe(divL_reg_reg);
       
  8399 %}
       
  8400 #endif
       
  8401 
       
  8402 // Integer Remainder
       
  8403 // Register Remainder
       
  8404 #ifdef AARCH64
       
  8405 #ifdef TODO
       
  8406 instruct msubI_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  8407   match(Set dst (SubI src1 (MulI src2 src3)));
       
  8408 
       
  8409   size(4);
       
  8410   format %{ "MSUB    $dst,$src2,$src3,$src1\t! 32-bit\n\t" %}
       
  8411   ins_encode %{
       
  8412     __ msub_w($dst$$Register, $src2$$Register, $src3$$Register, $src1$$Register);
       
  8413   %}
       
  8414   ins_pipe(ialu_reg_reg); // FIXME
       
  8415 %}
       
  8416 #endif
       
  8417 
       
  8418 instruct modI_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI temp) %{
       
  8419   match(Set dst (ModI src1 src2));
       
  8420   effect(TEMP temp);
       
  8421 
       
  8422   size(8);
       
  8423   format %{ "SDIV    $temp,$src1,$src2\t! 32-bit\n\t"
       
  8424             "MSUB    $dst,$src2,$temp,$src1\t! 32-bit\n\t" %}
       
  8425   ins_encode %{
       
  8426     __ sdiv_w($temp$$Register, $src1$$Register, $src2$$Register);
       
  8427     __ msub_w($dst$$Register, $src2$$Register, $temp$$Register, $src1$$Register);
       
  8428   %}
       
  8429   ins_pipe(ialu_reg_reg); // FIXME
       
  8430 %}
       
  8431 #else
       
  8432 instruct modI_reg_reg(R0RegI dst, R0RegI src1, R2RegI src2, R1RegI temp, LRRegP lr, flagsReg ccr ) %{
       
  8433   match(Set dst (ModI src1 src2));
       
  8434   effect( KILL ccr, KILL temp, KILL src2, KILL lr);
       
  8435 
       
  8436   format %{ "MODI   $dst,$src1,$src2\t ! call to StubRoutines::Arm::idiv_irem_entry" %}
       
  8437   ins_encode %{
       
  8438     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
       
  8439   %}
       
  8440   ins_pipe(sdiv_reg_reg);
       
  8441 %}
       
  8442 #endif
       
  8443 
       
  8444 // Register Long Remainder
       
  8445 #ifdef AARCH64
       
  8446 instruct modL_reg_reg(iRegL dst, iRegL src1, iRegL src2, iRegL temp) %{
       
  8447   match(Set dst (ModL src1 src2));
       
  8448   effect(TEMP temp);
       
  8449 
       
  8450   size(8);
       
  8451   format %{ "SDIV    $temp,$src1,$src2\n\t"
       
  8452             "MSUB    $dst,$src2,$temp,$src1" %}
       
  8453   ins_encode %{
       
  8454     __ sdiv($temp$$Register, $src1$$Register, $src2$$Register);
       
  8455     __ msub($dst$$Register, $src2$$Register, $temp$$Register, $src1$$Register);
       
  8456   %}
       
  8457   ins_pipe(ialu_reg_reg); // FIXME
       
  8458 %}
       
  8459 #else
       
  8460 instruct modL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
       
  8461   match(Set dst (ModL src1 src2));
       
  8462   effect(CALL);
       
  8463   ins_cost(MEMORY_REF_COST); // FIXME
       
  8464   format %{ "modL    $dst,$src1,$src2\t ! call to SharedRuntime::lrem" %}
       
  8465   ins_encode %{
       
  8466     address target = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
       
  8467     __ call(target, relocInfo::runtime_call_type);
       
  8468   %}
       
  8469   ins_pipe(divL_reg_reg);
       
  8470 %}
       
  8471 #endif
       
  8472 
       
  8473 // Integer Shift Instructions
       
  8474 
       
  8475 // Register Shift Left
       
  8476 instruct shlI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
       
  8477   match(Set dst (LShiftI src1 src2));
       
  8478 
       
  8479   size(4);
       
  8480 #ifdef AARCH64
       
  8481   format %{ "LSLV   $dst,$src1,$src2\t! int" %}
       
  8482   ins_encode %{
       
  8483     __ lslv_w($dst$$Register, $src1$$Register, $src2$$Register);
       
  8484   %}
       
  8485 #else
       
  8486   format %{ "LSL  $dst,$src1,$src2 \n\t" %}
       
  8487   ins_encode %{
       
  8488     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
       
  8489   %}
       
  8490 #endif
       
  8491   ins_pipe(ialu_reg_reg);
       
  8492 %}
       
  8493 
       
  8494 // Register Shift Left Immediate
       
  8495 instruct shlI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
       
  8496   match(Set dst (LShiftI src1 src2));
       
  8497 
       
  8498   size(4);
       
  8499 #ifdef AARCH64
       
  8500   format %{ "LSL_w  $dst,$src1,$src2\t! int" %}
       
  8501   ins_encode %{
       
  8502     __ _lsl($dst$$Register, $src1$$Register, $src2$$constant);
       
  8503   %}
       
  8504 #else
       
  8505   format %{ "LSL    $dst,$src1,$src2\t! int" %}
       
  8506   ins_encode %{
       
  8507     __ logical_shift_left($dst$$Register, $src1$$Register, $src2$$constant);
       
  8508   %}
       
  8509 #endif
       
  8510   ins_pipe(ialu_reg_imm);
       
  8511 %}
       
  8512 
       
  8513 #ifndef AARCH64
       
  8514 instruct shlL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
       
  8515   effect(USE_DEF dst, USE src1, USE src2);
       
  8516   size(4);
       
  8517   format %{"OR  $dst.hi,$dst.hi,($src1.hi << $src2)"  %}
       
  8518   ins_encode %{
       
  8519     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$Register));
       
  8520   %}
       
  8521   ins_pipe(ialu_reg_reg);
       
  8522 %}
       
  8523 
       
  8524 instruct shlL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
       
  8525   effect(USE_DEF dst, USE src1, USE src2);
       
  8526   size(4);
       
  8527   format %{ "LSL  $dst.lo,$src1.lo,$src2 \n\t" %}
       
  8528   ins_encode %{
       
  8529     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
       
  8530   %}
       
  8531   ins_pipe(ialu_reg_reg);
       
  8532 %}
       
  8533 
       
  8534 instruct shlL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
       
  8535   effect(DEF dst, USE src1, USE src2, KILL ccr);
       
  8536   size(16);
       
  8537   format %{ "SUBS  $dst.hi,$src2,32 \n\t"
       
  8538             "LSLpl $dst.hi,$src1.lo,$dst.hi \n\t"
       
  8539             "RSBmi $dst.hi,$dst.hi,0 \n\t"
       
  8540             "LSRmi $dst.hi,$src1.lo,$dst.hi" %}
       
  8541 
       
  8542   ins_encode %{
       
  8543     // $src1$$Register and $dst$$Register->successor() can't be the same
       
  8544     __ subs($dst$$Register->successor(), $src2$$Register, 32);
       
  8545     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $dst$$Register->successor()), pl);
       
  8546     __ rsb($dst$$Register->successor(), $dst$$Register->successor(), 0, mi);
       
  8547     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsr, $dst$$Register->successor()), mi);
       
  8548   %}
       
  8549   ins_pipe(ialu_reg_reg);
       
  8550 %}
       
  8551 #endif // !AARCH64
       
  8552 
       
  8553 instruct shlL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
       
  8554   match(Set dst (LShiftL src1 src2));
       
  8555 
       
  8556 #ifdef AARCH64
       
  8557   size(4);
       
  8558   format %{ "LSLV  $dst,$src1,$src2\t! long" %}
       
  8559   ins_encode %{
       
  8560     __ lslv($dst$$Register, $src1$$Register, $src2$$Register);
       
  8561   %}
       
  8562   ins_pipe(ialu_reg_reg);
       
  8563 #else
       
  8564   expand %{
       
  8565     flagsReg ccr;
       
  8566     shlL_reg_reg_overlap(dst, src1, src2, ccr);
       
  8567     shlL_reg_reg_merge_hi(dst, src1, src2);
       
  8568     shlL_reg_reg_merge_lo(dst, src1, src2);
       
  8569   %}
       
  8570 #endif
       
  8571 %}
       
  8572 
       
  8573 #ifdef AARCH64
       
  8574 instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6 src2) %{
       
  8575   match(Set dst (LShiftL src1 src2));
       
  8576 
       
  8577   size(4);
       
  8578   format %{ "LSL    $dst,$src1,$src2\t! long" %}
       
  8579   ins_encode %{
       
  8580     __ logical_shift_left($dst$$Register, $src1$$Register, $src2$$constant);
       
  8581   %}
       
  8582   ins_pipe(ialu_reg_imm);
       
  8583 %}
       
  8584 #else
       
  8585 // Register Shift Left Immediate
       
  8586 instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
       
  8587   match(Set dst (LShiftL src1 src2));
       
  8588 
       
  8589   size(8);
       
  8590   format %{ "LSL   $dst.hi,$src1.lo,$src2-32\t! or mov if $src2==32\n\t"
       
  8591             "MOV   $dst.lo, 0" %}
       
  8592   ins_encode %{
       
  8593     if ($src2$$constant == 32) {
       
  8594       __ mov($dst$$Register->successor(), $src1$$Register);
       
  8595     } else {
       
  8596       __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $src2$$constant-32));
       
  8597     }
       
  8598     __ mov($dst$$Register, 0);
       
  8599   %}
       
  8600   ins_pipe(ialu_reg_imm);
       
  8601 %}
       
  8602 
       
  8603 instruct shlL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
       
  8604   match(Set dst (LShiftL src1 src2));
       
  8605 
       
  8606   size(12);
       
  8607   format %{ "LSL   $dst.hi,$src1.lo,$src2\n\t"
       
  8608             "OR    $dst.hi, $dst.hi, $src1.lo >> 32-$src2\n\t"
       
  8609             "LSL   $dst.lo,$src1.lo,$src2" %}
       
  8610   ins_encode %{
       
  8611     // The order of the following 3 instructions matters: src1.lo and
       
  8612     // dst.hi can't overlap but src.hi and dst.hi can.
       
  8613     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$constant));
       
  8614     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register, lsr, 32-$src2$$constant));
       
  8615     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
       
  8616   %}
       
  8617   ins_pipe(ialu_reg_imm);
       
  8618 %}
       
  8619 #endif // !AARCH64
       
  8620 
       
  8621 // Register Arithmetic Shift Right
       
  8622 instruct sarI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
       
  8623   match(Set dst (RShiftI src1 src2));
       
  8624   size(4);
       
  8625 #ifdef AARCH64
       
  8626   format %{ "ASRV   $dst,$src1,$src2\t! int" %}
       
  8627   ins_encode %{
       
  8628     __ asrv_w($dst$$Register, $src1$$Register, $src2$$Register);
       
  8629   %}
       
  8630 #else
       
  8631   format %{ "ASR    $dst,$src1,$src2\t! int" %}
       
  8632   ins_encode %{
       
  8633     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
       
  8634   %}
       
  8635 #endif
       
  8636   ins_pipe(ialu_reg_reg);
       
  8637 %}
       
  8638 
       
  8639 // Register Arithmetic Shift Right Immediate
       
  8640 instruct sarI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
       
  8641   match(Set dst (RShiftI src1 src2));
       
  8642 
       
  8643   size(4);
       
  8644 #ifdef AARCH64
       
  8645   format %{ "ASR_w  $dst,$src1,$src2" %}
       
  8646   ins_encode %{
       
  8647     __ _asr_w($dst$$Register, $src1$$Register, $src2$$constant);
       
  8648   %}
       
  8649 #else
       
  8650   format %{ "ASR    $dst,$src1,$src2" %}
       
  8651   ins_encode %{
       
  8652     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
       
  8653   %}
       
  8654 #endif
       
  8655   ins_pipe(ialu_reg_imm);
       
  8656 %}
       
  8657 
       
  8658 #ifndef AARCH64
       
  8659 // Register Shift Right Arithmetic Long
       
  8660 instruct sarL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
       
  8661   effect(USE_DEF dst, USE src1, USE src2);
       
  8662   size(4);
       
  8663   format %{ "OR  $dst.lo,$dst.lo,($src1.lo >> $src2)"  %}
       
  8664   ins_encode %{
       
  8665     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
       
  8666   %}
       
  8667   ins_pipe(ialu_reg_reg);
       
  8668 %}
       
  8669 
       
  8670 instruct sarL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
       
  8671   effect(USE_DEF dst, USE src1, USE src2);
       
  8672   size(4);
       
  8673   format %{ "ASR  $dst.hi,$src1.hi,$src2 \n\t" %}
       
  8674   ins_encode %{
       
  8675     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$Register));
       
  8676   %}
       
  8677   ins_pipe(ialu_reg_reg);
       
  8678 %}
       
  8679 
       
  8680 instruct sarL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
       
  8681   effect(DEF dst, USE src1, USE src2, KILL ccr);
       
  8682   size(16);
       
  8683   format %{ "SUBS  $dst.lo,$src2,32 \n\t"
       
  8684             "ASRpl $dst.lo,$src1.hi,$dst.lo \n\t"
       
  8685             "RSBmi $dst.lo,$dst.lo,0 \n\t"
       
  8686             "LSLmi $dst.lo,$src1.hi,$dst.lo" %}
       
  8687 
       
  8688   ins_encode %{
       
  8689     // $src1$$Register->successor() and $dst$$Register can't be the same
       
  8690     __ subs($dst$$Register, $src2$$Register, 32);
       
  8691     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $dst$$Register), pl);
       
  8692     __ rsb($dst$$Register, $dst$$Register, 0, mi);
       
  8693     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
       
  8694   %}
       
  8695   ins_pipe(ialu_reg_reg);
       
  8696 %}
       
  8697 #endif // !AARCH64
       
  8698 
       
  8699 instruct sarL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
       
  8700   match(Set dst (RShiftL src1 src2));
       
  8701 
       
  8702 #ifdef AARCH64
       
  8703   size(4);
       
  8704   format %{ "ASRV  $dst,$src1,$src2\t! long" %}
       
  8705   ins_encode %{
       
  8706     __ asrv($dst$$Register, $src1$$Register, $src2$$Register);
       
  8707   %}
       
  8708   ins_pipe(ialu_reg_reg);
       
  8709 #else
       
  8710   expand %{
       
  8711     flagsReg ccr;
       
  8712     sarL_reg_reg_overlap(dst, src1, src2, ccr);
       
  8713     sarL_reg_reg_merge_lo(dst, src1, src2);
       
  8714     sarL_reg_reg_merge_hi(dst, src1, src2);
       
  8715   %}
       
  8716 #endif
       
  8717 %}
       
  8718 
       
  8719 // Register Shift Left Immediate
       
  8720 #ifdef AARCH64
       
  8721 instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6 src2) %{
       
  8722   match(Set dst (RShiftL src1 src2));
       
  8723 
       
  8724   size(4);
       
  8725   format %{ "ASR    $dst,$src1,$src2\t! long" %}
       
  8726   ins_encode %{
       
  8727     __ _asr($dst$$Register, $src1$$Register, $src2$$constant);
       
  8728   %}
       
  8729   ins_pipe(ialu_reg_imm);
       
  8730 %}
       
  8731 #else
       
  8732 instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
       
  8733   match(Set dst (RShiftL src1 src2));
       
  8734 
       
  8735   size(8);
       
  8736   format %{ "ASR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
       
  8737             "ASR   $dst.hi,$src1.hi, $src2" %}
       
  8738   ins_encode %{
       
  8739     if ($src2$$constant == 32) {
       
  8740       __ mov($dst$$Register, $src1$$Register->successor());
       
  8741     } else{
       
  8742       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $src2$$constant-32));
       
  8743     }
       
  8744     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, 0));
       
  8745   %}
       
  8746 
       
  8747   ins_pipe(ialu_reg_imm);
       
  8748 %}
       
  8749 
       
  8750 instruct sarL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
       
  8751   match(Set dst (RShiftL src1 src2));
       
  8752   size(12);
       
  8753   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
       
  8754             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
       
  8755             "ASR   $dst.hi,$src1.hi,$src2" %}
       
  8756   ins_encode %{
       
  8757     // The order of the following 3 instructions matters: src1.lo and
       
  8758     // dst.hi can't overlap but src.hi and dst.hi can.
       
  8759     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
       
  8760     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
       
  8761     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$constant));
       
  8762   %}
       
  8763   ins_pipe(ialu_reg_imm);
       
  8764 %}
       
  8765 #endif
       
  8766 
       
  8767 // Register Shift Right
       
  8768 instruct shrI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
       
  8769   match(Set dst (URShiftI src1 src2));
       
  8770   size(4);
       
  8771 #ifdef AARCH64
       
  8772   format %{ "LSRV   $dst,$src1,$src2\t! int" %}
       
  8773   ins_encode %{
       
  8774     __ lsrv_w($dst$$Register, $src1$$Register, $src2$$Register);
       
  8775   %}
       
  8776 #else
       
  8777   format %{ "LSR    $dst,$src1,$src2\t! int" %}
       
  8778   ins_encode %{
       
  8779     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
       
  8780   %}
       
  8781 #endif
       
  8782   ins_pipe(ialu_reg_reg);
       
  8783 %}
       
  8784 
       
  8785 // Register Shift Right Immediate
       
  8786 instruct shrI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
       
  8787   match(Set dst (URShiftI src1 src2));
       
  8788 
       
  8789   size(4);
       
  8790 #ifdef AARCH64
       
  8791   format %{ "LSR_w  $dst,$src1,$src2" %}
       
  8792   ins_encode %{
       
  8793     __ _lsr_w($dst$$Register, $src1$$Register, $src2$$constant);
       
  8794   %}
       
  8795 #else
       
  8796   format %{ "LSR    $dst,$src1,$src2" %}
       
  8797   ins_encode %{
       
  8798     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
       
  8799   %}
       
  8800 #endif
       
  8801   ins_pipe(ialu_reg_imm);
       
  8802 %}
       
  8803 
       
  8804 #ifndef AARCH64
       
  8805 // Register Shift Right
       
  8806 instruct shrL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
       
  8807   effect(USE_DEF dst, USE src1, USE src2);
       
  8808   size(4);
       
  8809   format %{ "OR   $dst.lo,$dst,($src1.lo >>> $src2)"  %}
       
  8810   ins_encode %{
       
  8811     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
       
  8812   %}
       
  8813   ins_pipe(ialu_reg_reg);
       
  8814 %}
       
  8815 
       
  8816 instruct shrL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
       
  8817   effect(USE_DEF dst, USE src1, USE src2);
       
  8818   size(4);
       
  8819   format %{ "LSR  $dst.hi,$src1.hi,$src2 \n\t" %}
       
  8820   ins_encode %{
       
  8821     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$Register));
       
  8822   %}
       
  8823   ins_pipe(ialu_reg_reg);
       
  8824 %}
       
  8825 
       
  8826 instruct shrL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
       
  8827   effect(DEF dst, USE src1, USE src2, KILL ccr);
       
  8828   size(16);
       
  8829   format %{ "SUBS  $dst,$src2,32 \n\t"
       
  8830             "LSRpl $dst,$src1.hi,$dst \n\t"
       
  8831             "RSBmi $dst,$dst,0 \n\t"
       
  8832             "LSLmi $dst,$src1.hi,$dst" %}
       
  8833 
       
  8834   ins_encode %{
       
  8835     // $src1$$Register->successor() and $dst$$Register can't be the same
       
  8836     __ subs($dst$$Register, $src2$$Register, 32);
       
  8837     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $dst$$Register), pl);
       
  8838     __ rsb($dst$$Register, $dst$$Register, 0, mi);
       
  8839     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
       
  8840   %}
       
  8841   ins_pipe(ialu_reg_reg);
       
  8842 %}
       
  8843 #endif // !AARCH64
       
  8844 
       
  8845 instruct shrL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
       
  8846   match(Set dst (URShiftL src1 src2));
       
  8847 
       
  8848 #ifdef AARCH64
       
  8849   size(4);
       
  8850   format %{ "LSRV  $dst,$src1,$src2\t! long" %}
       
  8851   ins_encode %{
       
  8852     __ lsrv($dst$$Register, $src1$$Register, $src2$$Register);
       
  8853   %}
       
  8854   ins_pipe(ialu_reg_reg);
       
  8855 #else
       
  8856   expand %{
       
  8857     flagsReg ccr;
       
  8858     shrL_reg_reg_overlap(dst, src1, src2, ccr);
       
  8859     shrL_reg_reg_merge_lo(dst, src1, src2);
       
  8860     shrL_reg_reg_merge_hi(dst, src1, src2);
       
  8861   %}
       
  8862 #endif
       
  8863 %}
       
  8864 
       
  8865 // Register Shift Right Immediate
       
  8866 #ifdef AARCH64
       
  8867 instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6 src2) %{
       
  8868   match(Set dst (URShiftL src1 src2));
       
  8869 
       
  8870   size(4);
       
  8871   format %{ "LSR    $dst,$src1,$src2" %}
       
  8872   ins_encode %{
       
  8873     __ _lsr($dst$$Register, $src1$$Register, $src2$$constant);
       
  8874   %}
       
  8875   ins_pipe(ialu_reg_imm);
       
  8876 %}
       
  8877 #else
       
  8878 instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
       
  8879   match(Set dst (URShiftL src1 src2));
       
  8880 
       
  8881   size(8);
       
  8882   format %{ "LSR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
       
  8883             "MOV   $dst.hi, 0" %}
       
  8884   ins_encode %{
       
  8885     if ($src2$$constant == 32) {
       
  8886       __ mov($dst$$Register, $src1$$Register->successor());
       
  8887     } else {
       
  8888       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $src2$$constant-32));
       
  8889     }
       
  8890     __ mov($dst$$Register->successor(), 0);
       
  8891   %}
       
  8892 
       
  8893   ins_pipe(ialu_reg_imm);
       
  8894 %}
       
  8895 
       
  8896 instruct shrL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
       
  8897   match(Set dst (URShiftL src1 src2));
       
  8898 
       
  8899   size(12);
       
  8900   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
       
  8901             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
       
  8902             "LSR   $dst.hi,$src1.hi,$src2" %}
       
  8903   ins_encode %{
       
  8904     // The order of the following 3 instructions matters: src1.lo and
       
  8905     // dst.hi can't overlap but src.hi and dst.hi can.
       
  8906     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
       
  8907     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
       
  8908     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$constant));
       
  8909   %}
       
  8910   ins_pipe(ialu_reg_imm);
       
  8911 %}
       
  8912 #endif // !AARCH64
       
  8913 
       
  8914 
       
  8915 instruct shrP_reg_imm5(iRegX dst, iRegP src1, immU5 src2) %{
       
  8916   match(Set dst (URShiftI (CastP2X src1) src2));
       
  8917   size(4);
       
  8918   format %{ "LSR    $dst,$src1,$src2\t! Cast ptr $src1 to int and shift" %}
       
  8919   ins_encode %{
       
  8920     __ logical_shift_right($dst$$Register, $src1$$Register, $src2$$constant);
       
  8921   %}
       
  8922   ins_pipe(ialu_reg_imm);
       
  8923 %}
       
  8924 
       
  8925 //----------Floating Point Arithmetic Instructions-----------------------------
       
  8926 
       
  8927 //  Add float single precision
       
  8928 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
       
  8929   match(Set dst (AddF src1 src2));
       
  8930 
       
  8931   size(4);
       
  8932   format %{ "FADDS  $dst,$src1,$src2" %}
       
  8933   ins_encode %{
       
  8934     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
       
  8935   %}
       
  8936 
       
  8937   ins_pipe(faddF_reg_reg);
       
  8938 %}
       
  8939 
       
  8940 //  Add float double precision
       
  8941 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
       
  8942   match(Set dst (AddD src1 src2));
       
  8943 
       
  8944   size(4);
       
  8945   format %{ "FADDD  $dst,$src1,$src2" %}
       
  8946   ins_encode %{
       
  8947     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
       
  8948   %}
       
  8949 
       
  8950   ins_pipe(faddD_reg_reg);
       
  8951 %}
       
  8952 
       
  8953 //  Sub float single precision
       
  8954 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
       
  8955   match(Set dst (SubF src1 src2));
       
  8956 
       
  8957   size(4);
       
  8958   format %{ "FSUBS  $dst,$src1,$src2" %}
       
  8959   ins_encode %{
       
  8960     __ sub_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
       
  8961   %}
       
  8962   ins_pipe(faddF_reg_reg);
       
  8963 %}
       
  8964 
       
  8965 //  Sub float double precision
       
  8966 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
       
  8967   match(Set dst (SubD src1 src2));
       
  8968 
       
  8969   size(4);
       
  8970   format %{ "FSUBD  $dst,$src1,$src2" %}
       
  8971   ins_encode %{
       
  8972     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
       
  8973   %}
       
  8974   ins_pipe(faddD_reg_reg);
       
  8975 %}
       
  8976 
       
  8977 //  Mul float single precision
       
  8978 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
       
  8979   match(Set dst (MulF src1 src2));
       
  8980 
       
  8981   size(4);
       
  8982   format %{ "FMULS  $dst,$src1,$src2" %}
       
  8983   ins_encode %{
       
  8984     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
       
  8985   %}
       
  8986 
       
  8987   ins_pipe(fmulF_reg_reg);
       
  8988 %}
       
  8989 
       
  8990 //  Mul float double precision
       
  8991 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
       
  8992   match(Set dst (MulD src1 src2));
       
  8993 
       
  8994   size(4);
       
  8995   format %{ "FMULD  $dst,$src1,$src2" %}
       
  8996   ins_encode %{
       
  8997     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
       
  8998   %}
       
  8999 
       
  9000   ins_pipe(fmulD_reg_reg);
       
  9001 %}
       
  9002 
       
  9003 //  Div float single precision
       
  9004 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
       
  9005   match(Set dst (DivF src1 src2));
       
  9006 
       
  9007   size(4);
       
  9008   format %{ "FDIVS  $dst,$src1,$src2" %}
       
  9009   ins_encode %{
       
  9010     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
       
  9011   %}
       
  9012 
       
  9013   ins_pipe(fdivF_reg_reg);
       
  9014 %}
       
  9015 
       
  9016 //  Div float double precision
       
  9017 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
       
  9018   match(Set dst (DivD src1 src2));
       
  9019 
       
  9020   size(4);
       
  9021   format %{ "FDIVD  $dst,$src1,$src2" %}
       
  9022   ins_encode %{
       
  9023     __ div_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
       
  9024   %}
       
  9025 
       
  9026   ins_pipe(fdivD_reg_reg);
       
  9027 %}
       
  9028 
       
  9029 //  Absolute float double precision
       
  9030 instruct absD_reg(regD dst, regD src) %{
       
  9031   match(Set dst (AbsD src));
       
  9032 
       
  9033   size(4);
       
  9034   format %{ "FABSd  $dst,$src" %}
       
  9035   ins_encode %{
       
  9036     __ abs_double($dst$$FloatRegister, $src$$FloatRegister);
       
  9037   %}
       
  9038   ins_pipe(faddD_reg);
       
  9039 %}
       
  9040 
       
  9041 //  Absolute float single precision
       
  9042 instruct absF_reg(regF dst, regF src) %{
       
  9043   match(Set dst (AbsF src));
       
  9044   format %{ "FABSs  $dst,$src" %}
       
  9045   ins_encode %{
       
  9046     __ abs_float($dst$$FloatRegister, $src$$FloatRegister);
       
  9047   %}
       
  9048   ins_pipe(faddF_reg);
       
  9049 %}
       
  9050 
       
  9051 instruct negF_reg(regF dst, regF src) %{
       
  9052   match(Set dst (NegF src));
       
  9053 
       
  9054   size(4);
       
  9055   format %{ "FNEGs  $dst,$src" %}
       
  9056   ins_encode %{
       
  9057     __ neg_float($dst$$FloatRegister, $src$$FloatRegister);
       
  9058   %}
       
  9059   ins_pipe(faddF_reg);
       
  9060 %}
       
  9061 
       
  9062 instruct negD_reg(regD dst, regD src) %{
       
  9063   match(Set dst (NegD src));
       
  9064 
       
  9065   format %{ "FNEGd  $dst,$src" %}
       
  9066   ins_encode %{
       
  9067     __ neg_double($dst$$FloatRegister, $src$$FloatRegister);
       
  9068   %}
       
  9069   ins_pipe(faddD_reg);
       
  9070 %}
       
  9071 
       
  9072 //  Sqrt float double precision
       
  9073 instruct sqrtF_reg_reg(regF dst, regF src) %{
       
  9074   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
       
  9075 
       
  9076   size(4);
       
  9077   format %{ "FSQRTS $dst,$src" %}
       
  9078   ins_encode %{
       
  9079     __ sqrt_float($dst$$FloatRegister, $src$$FloatRegister);
       
  9080   %}
       
  9081   ins_pipe(fdivF_reg_reg);
       
  9082 %}
       
  9083 
       
  9084 //  Sqrt float double precision
       
  9085 instruct sqrtD_reg_reg(regD dst, regD src) %{
       
  9086   match(Set dst (SqrtD src));
       
  9087 
       
  9088   size(4);
       
  9089   format %{ "FSQRTD $dst,$src" %}
       
  9090   ins_encode %{
       
  9091     __ sqrt_double($dst$$FloatRegister, $src$$FloatRegister);
       
  9092   %}
       
  9093   ins_pipe(fdivD_reg_reg);
       
  9094 %}
       
  9095 
       
  9096 //----------Logical Instructions-----------------------------------------------
       
  9097 // And Instructions
       
  9098 // Register And
       
  9099 instruct andI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
       
  9100   match(Set dst (AndI src1 src2));
       
  9101 
       
  9102   size(4);
       
  9103   format %{ "and_32 $dst,$src1,$src2" %}
       
  9104   ins_encode %{
       
  9105     __ and_32($dst$$Register, $src1$$Register, $src2$$Register);
       
  9106   %}
       
  9107   ins_pipe(ialu_reg_reg);
       
  9108 %}
       
  9109 
       
  9110 #ifndef AARCH64
       
  9111 instruct andshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  9112   match(Set dst (AndI src1 (LShiftI src2 src3)));
       
  9113 
       
  9114   size(4);
       
  9115   format %{ "AND    $dst,$src1,$src2<<$src3" %}
       
  9116   ins_encode %{
       
  9117     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
       
  9118   %}
       
  9119   ins_pipe(ialu_reg_reg);
       
  9120 %}
       
  9121 #endif
       
  9122 
       
  9123 instruct andshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
       
  9124   match(Set dst (AndI src1 (LShiftI src2 src3)));
       
  9125 
       
  9126   size(4);
       
  9127   format %{ "and_32 $dst,$src1,$src2<<$src3" %}
       
  9128   ins_encode %{
       
  9129     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
       
  9130   %}
       
  9131   ins_pipe(ialu_reg_reg);
       
  9132 %}
       
  9133 
       
  9134 #ifndef AARCH64
       
  9135 instruct andsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  9136   match(Set dst (AndI src1 (RShiftI src2 src3)));
       
  9137 
       
  9138   size(4);
       
  9139   format %{ "AND    $dst,$src1,$src2>>$src3" %}
       
  9140   ins_encode %{
       
  9141     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
       
  9142   %}
       
  9143   ins_pipe(ialu_reg_reg);
       
  9144 %}
       
  9145 #endif
       
  9146 
       
  9147 instruct andsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
       
  9148   match(Set dst (AndI src1 (RShiftI src2 src3)));
       
  9149 
       
  9150   size(4);
       
  9151   format %{ "and_32 $dst,$src1,$src2>>$src3" %}
       
  9152   ins_encode %{
       
  9153     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
       
  9154   %}
       
  9155   ins_pipe(ialu_reg_reg);
       
  9156 %}
       
  9157 
       
  9158 #ifndef AARCH64
       
  9159 instruct andshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  9160   match(Set dst (AndI src1 (URShiftI src2 src3)));
       
  9161 
       
  9162   size(4);
       
  9163   format %{ "AND    $dst,$src1,$src2>>>$src3" %}
       
  9164   ins_encode %{
       
  9165     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
       
  9166   %}
       
  9167   ins_pipe(ialu_reg_reg);
       
  9168 %}
       
  9169 #endif
       
  9170 
       
  9171 instruct andshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
       
  9172   match(Set dst (AndI src1 (URShiftI src2 src3)));
       
  9173 
       
  9174   size(4);
       
  9175   format %{ "and_32 $dst,$src1,$src2>>>$src3" %}
       
  9176   ins_encode %{
       
  9177     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
       
  9178   %}
       
  9179   ins_pipe(ialu_reg_reg);
       
  9180 %}
       
  9181 
       
  9182 // Immediate And
       
  9183 instruct andI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
       
  9184   match(Set dst (AndI src1 src2));
       
  9185 
       
  9186   size(4);
       
  9187   format %{ "and_32 $dst,$src1,$src2\t! int" %}
       
  9188   ins_encode %{
       
  9189     __ and_32($dst$$Register, $src1$$Register, $src2$$constant);
       
  9190   %}
       
  9191   ins_pipe(ialu_reg_imm);
       
  9192 %}
       
  9193 
       
  9194 #ifndef AARCH64
       
  9195 instruct andI_reg_limmn(iRegI dst, iRegI src1, limmIn src2) %{
       
  9196   match(Set dst (AndI src1 src2));
       
  9197 
       
  9198   size(4);
       
  9199   format %{ "bic    $dst,$src1,~$src2\t! int" %}
       
  9200   ins_encode %{
       
  9201     __ bic($dst$$Register, $src1$$Register, ~$src2$$constant);
       
  9202   %}
       
  9203   ins_pipe(ialu_reg_imm);
       
  9204 %}
       
  9205 #endif
       
  9206 
       
  9207 // Register And Long
       
  9208 instruct andL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
       
  9209   match(Set dst (AndL src1 src2));
       
  9210 
       
  9211   ins_cost(DEFAULT_COST);
       
  9212 #ifdef AARCH64
       
  9213   size(4);
       
  9214   format %{ "AND    $dst,$src1,$src2\t! long" %}
       
  9215   ins_encode %{
       
  9216     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
       
  9217   %}
       
  9218 #else
       
  9219   size(8);
       
  9220   format %{ "AND    $dst,$src1,$src2\t! long" %}
       
  9221   ins_encode %{
       
  9222     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
       
  9223     __ andr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
       
  9224   %}
       
  9225 #endif
       
  9226   ins_pipe(ialu_reg_reg);
       
  9227 %}
       
  9228 
       
  9229 #ifdef AARCH64
       
  9230 // Immediate And
       
  9231 instruct andL_reg_limm(iRegL dst, iRegL src1, limmL src2) %{
       
  9232   match(Set dst (AndL src1 src2));
       
  9233 
       
  9234   size(4);
       
  9235   format %{ "AND    $dst,$src1,$src2\t! long" %}
       
  9236   ins_encode %{
       
  9237     __ andr($dst$$Register, $src1$$Register, (uintx)$src2$$constant);
       
  9238   %}
       
  9239   ins_pipe(ialu_reg_imm);
       
  9240 %}
       
  9241 #else
       
  9242 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
       
  9243 // (hi($con$$constant), lo($con$$constant)) becomes
       
  9244 instruct andL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
       
  9245   match(Set dst (AndL src1 con));
       
  9246   ins_cost(DEFAULT_COST);
       
  9247   size(8);
       
  9248   format %{ "AND    $dst,$src1,$con\t! long" %}
       
  9249   ins_encode %{
       
  9250     __ andr($dst$$Register, $src1$$Register, $con$$constant);
       
  9251     __ andr($dst$$Register->successor(), $src1$$Register->successor(), 0);
       
  9252   %}
       
  9253   ins_pipe(ialu_reg_imm);
       
  9254 %}
       
  9255 #endif
       
  9256 
       
  9257 // Or Instructions
       
  9258 // Register Or
       
  9259 instruct orI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
       
  9260   match(Set dst (OrI src1 src2));
       
  9261 
       
  9262   size(4);
       
  9263   format %{ "orr_32 $dst,$src1,$src2\t! int" %}
       
  9264   ins_encode %{
       
  9265     __ orr_32($dst$$Register, $src1$$Register, $src2$$Register);
       
  9266   %}
       
  9267   ins_pipe(ialu_reg_reg);
       
  9268 %}
       
  9269 
       
  9270 #ifndef AARCH64
       
  9271 instruct orshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  9272   match(Set dst (OrI src1 (LShiftI src2 src3)));
       
  9273 
       
  9274   size(4);
       
  9275   format %{ "OR    $dst,$src1,$src2<<$src3" %}
       
  9276   ins_encode %{
       
  9277     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
       
  9278   %}
       
  9279   ins_pipe(ialu_reg_reg);
       
  9280 %}
       
  9281 #endif
       
  9282 
       
  9283 instruct orshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
       
  9284   match(Set dst (OrI src1 (LShiftI src2 src3)));
       
  9285 
       
  9286   size(4);
       
  9287   format %{ "orr_32 $dst,$src1,$src2<<$src3" %}
       
  9288   ins_encode %{
       
  9289     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
       
  9290   %}
       
  9291   ins_pipe(ialu_reg_reg);
       
  9292 %}
       
  9293 
       
  9294 #ifndef AARCH64
       
  9295 instruct orsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  9296   match(Set dst (OrI src1 (RShiftI src2 src3)));
       
  9297 
       
  9298   size(4);
       
  9299   format %{ "OR    $dst,$src1,$src2>>$src3" %}
       
  9300   ins_encode %{
       
  9301     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
       
  9302   %}
       
  9303   ins_pipe(ialu_reg_reg);
       
  9304 %}
       
  9305 #endif
       
  9306 
       
  9307 instruct orsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
       
  9308   match(Set dst (OrI src1 (RShiftI src2 src3)));
       
  9309 
       
  9310   size(4);
       
  9311   format %{ "orr_32 $dst,$src1,$src2>>$src3" %}
       
  9312   ins_encode %{
       
  9313     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
       
  9314   %}
       
  9315   ins_pipe(ialu_reg_reg);
       
  9316 %}
       
  9317 
       
  9318 #ifndef AARCH64
       
  9319 instruct orshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  9320   match(Set dst (OrI src1 (URShiftI src2 src3)));
       
  9321 
       
  9322   size(4);
       
  9323   format %{ "OR    $dst,$src1,$src2>>>$src3" %}
       
  9324   ins_encode %{
       
  9325     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
       
  9326   %}
       
  9327   ins_pipe(ialu_reg_reg);
       
  9328 %}
       
  9329 #endif
       
  9330 
       
  9331 instruct orshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
       
  9332   match(Set dst (OrI src1 (URShiftI src2 src3)));
       
  9333 
       
  9334   size(4);
       
  9335   format %{ "orr_32 $dst,$src1,$src2>>>$src3" %}
       
  9336   ins_encode %{
       
  9337     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
       
  9338   %}
       
  9339   ins_pipe(ialu_reg_reg);
       
  9340 %}
       
  9341 
       
  9342 // Immediate Or
       
  9343 instruct orI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
       
  9344   match(Set dst (OrI src1 src2));
       
  9345 
       
  9346   size(4);
       
  9347   format %{ "orr_32  $dst,$src1,$src2" %}
       
  9348   ins_encode %{
       
  9349     __ orr_32($dst$$Register, $src1$$Register, $src2$$constant);
       
  9350   %}
       
  9351   ins_pipe(ialu_reg_imm);
       
  9352 %}
       
  9353 // TODO: orn_32 with limmIn
       
  9354 
       
  9355 // Register Or Long
       
  9356 instruct orL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
       
  9357   match(Set dst (OrL src1 src2));
       
  9358 
       
  9359   ins_cost(DEFAULT_COST);
       
  9360 #ifdef AARCH64
       
  9361   size(4);
       
  9362   format %{ "OR     $dst,$src1,$src2\t! long" %}
       
  9363   ins_encode %{
       
  9364     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
       
  9365   %}
       
  9366 #else
       
  9367   size(8);
       
  9368   format %{ "OR     $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
       
  9369             "OR     $dst.hi,$src1.hi,$src2.hi" %}
       
  9370   ins_encode %{
       
  9371     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
       
  9372     __ orr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
       
  9373   %}
       
  9374 #endif
       
  9375   ins_pipe(ialu_reg_reg);
       
  9376 %}
       
  9377 
       
  9378 #ifdef AARCH64
       
  9379 instruct orL_reg_limm(iRegL dst, iRegL src1, limmL src2) %{
       
  9380   match(Set dst (OrL src1 src2));
       
  9381 
       
  9382   size(4);
       
  9383   format %{ "ORR    $dst,$src1,$src2\t! long" %}
       
  9384   ins_encode %{
       
  9385     __ orr($dst$$Register, $src1$$Register, (uintx)$src2$$constant);
       
  9386   %}
       
  9387   ins_pipe(ialu_reg_imm);
       
  9388 %}
       
  9389 #else
       
  9390 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
       
  9391 // (hi($con$$constant), lo($con$$constant)) becomes
       
  9392 instruct orL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
       
  9393   match(Set dst (OrL src1 con));
       
  9394   ins_cost(DEFAULT_COST);
       
  9395   size(8);
       
  9396   format %{ "OR     $dst.lo,$src1.lo,$con\t! long\n\t"
       
  9397             "OR     $dst.hi,$src1.hi,$con" %}
       
  9398   ins_encode %{
       
  9399     __ orr($dst$$Register, $src1$$Register, $con$$constant);
       
  9400     __ orr($dst$$Register->successor(), $src1$$Register->successor(), 0);
       
  9401   %}
       
  9402   ins_pipe(ialu_reg_imm);
       
  9403 %}
       
  9404 #endif
       
  9405 
       
  9406 #ifdef TODO
       
  9407 // Use SPRegP to match Rthread (TLS register) without spilling.
       
  9408 // Use store_ptr_RegP to match Rthread (TLS register) without spilling.
       
  9409 // Use sp_ptr_RegP to match Rthread (TLS register) without spilling.
       
  9410 instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
       
  9411   match(Set dst (OrI src1 (CastP2X src2)));
       
  9412   size(4);
       
  9413   format %{ "OR     $dst,$src1,$src2" %}
       
  9414   ins_encode %{
       
  9415     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
       
  9416   %}
       
  9417   ins_pipe(ialu_reg_reg);
       
  9418 %}
       
  9419 #endif
       
  9420 
       
  9421 // Xor Instructions
       
  9422 // Register Xor
       
  9423 instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
       
  9424   match(Set dst (XorI src1 src2));
       
  9425 
       
  9426   size(4);
       
  9427   format %{ "eor_32 $dst,$src1,$src2" %}
       
  9428   ins_encode %{
       
  9429     __ eor_32($dst$$Register, $src1$$Register, $src2$$Register);
       
  9430   %}
       
  9431   ins_pipe(ialu_reg_reg);
       
  9432 %}
       
  9433 
       
  9434 #ifndef AARCH64
       
  9435 instruct xorshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  9436   match(Set dst (XorI src1 (LShiftI src2 src3)));
       
  9437 
       
  9438   size(4);
       
  9439   format %{ "XOR    $dst,$src1,$src2<<$src3" %}
       
  9440   ins_encode %{
       
  9441     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
       
  9442   %}
       
  9443   ins_pipe(ialu_reg_reg);
       
  9444 %}
       
  9445 #endif
       
  9446 
       
  9447 instruct xorshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
       
  9448   match(Set dst (XorI src1 (LShiftI src2 src3)));
       
  9449 
       
  9450   size(4);
       
  9451   format %{ "eor_32 $dst,$src1,$src2<<$src3" %}
       
  9452   ins_encode %{
       
  9453     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
       
  9454   %}
       
  9455   ins_pipe(ialu_reg_reg);
       
  9456 %}
       
  9457 
       
  9458 #ifndef AARCH64
       
  9459 instruct xorsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  9460   match(Set dst (XorI src1 (RShiftI src2 src3)));
       
  9461 
       
  9462   size(4);
       
  9463   format %{ "XOR    $dst,$src1,$src2>>$src3" %}
       
  9464   ins_encode %{
       
  9465     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
       
  9466   %}
       
  9467   ins_pipe(ialu_reg_reg);
       
  9468 %}
       
  9469 #endif
       
  9470 
       
  9471 instruct xorsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
       
  9472   match(Set dst (XorI src1 (RShiftI src2 src3)));
       
  9473 
       
  9474   size(4);
       
  9475   format %{ "eor_32 $dst,$src1,$src2>>$src3" %}
       
  9476   ins_encode %{
       
  9477     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
       
  9478   %}
       
  9479   ins_pipe(ialu_reg_reg);
       
  9480 %}
       
  9481 
       
  9482 #ifndef AARCH64
       
  9483 instruct xorshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
       
  9484   match(Set dst (XorI src1 (URShiftI src2 src3)));
       
  9485 
       
  9486   size(4);
       
  9487   format %{ "XOR    $dst,$src1,$src2>>>$src3" %}
       
  9488   ins_encode %{
       
  9489     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
       
  9490   %}
       
  9491   ins_pipe(ialu_reg_reg);
       
  9492 %}
       
  9493 #endif
       
  9494 
       
  9495 instruct xorshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
       
  9496   match(Set dst (XorI src1 (URShiftI src2 src3)));
       
  9497 
       
  9498   size(4);
       
  9499   format %{ "eor_32 $dst,$src1,$src2>>>$src3" %}
       
  9500   ins_encode %{
       
  9501     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
       
  9502   %}
       
  9503   ins_pipe(ialu_reg_reg);
       
  9504 %}
       
  9505 
       
  9506 // Immediate Xor
       
  9507 instruct xorI_reg_imm(iRegI dst, iRegI src1, limmI src2) %{
       
  9508   match(Set dst (XorI src1 src2));
       
  9509 
       
  9510   size(4);
       
  9511   format %{ "eor_32 $dst,$src1,$src2" %}
       
  9512   ins_encode %{
       
  9513     __ eor_32($dst$$Register, $src1$$Register, $src2$$constant);
       
  9514   %}
       
  9515   ins_pipe(ialu_reg_imm);
       
  9516 %}
       
  9517 
       
  9518 // Register Xor Long
       
  9519 instruct xorL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
       
  9520   match(Set dst (XorL src1 src2));
       
  9521   ins_cost(DEFAULT_COST);
       
  9522 #ifdef AARCH64
       
  9523   size(4);
       
  9524   format %{ "XOR     $dst,$src1,$src2\t! long" %}
       
  9525   ins_encode %{
       
  9526     __ eor($dst$$Register, $src1$$Register, $src2$$Register);
       
  9527   %}
       
  9528 #else
       
  9529   size(8);
       
  9530   format %{ "XOR     $dst.hi,$src1.hi,$src2.hi\t! long\n\t"
       
  9531             "XOR     $dst.lo,$src1.lo,$src2.lo\t! long" %}
       
  9532   ins_encode %{
       
  9533     __ eor($dst$$Register, $src1$$Register, $src2$$Register);
       
  9534     __ eor($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
       
  9535   %}
       
  9536 #endif
       
  9537   ins_pipe(ialu_reg_reg);
       
  9538 %}
       
  9539 
       
  9540 #ifdef AARCH64
       
  9541 instruct xorL_reg_limmL(iRegL dst, iRegL src1, limmL con) %{
       
  9542   match(Set dst (XorL src1 con));
       
  9543   ins_cost(DEFAULT_COST);
       
  9544   size(4);
       
  9545   format %{ "EOR     $dst,$src1,$con\t! long" %}
       
  9546   ins_encode %{
       
  9547     __ eor($dst$$Register, $src1$$Register, (uintx)$con$$constant);
       
  9548   %}
       
  9549   ins_pipe(ialu_reg_imm);
       
  9550 %}
       
  9551 #else
       
  9552 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
       
  9553 // (hi($con$$constant), lo($con$$constant)) becomes
       
  9554 instruct xorL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
       
  9555   match(Set dst (XorL src1 con));
       
  9556   ins_cost(DEFAULT_COST);
       
  9557   size(8);
       
  9558   format %{ "XOR     $dst.hi,$src1.hi,$con\t! long\n\t"
       
  9559             "XOR     $dst.lo,$src1.lo,0\t! long" %}
       
  9560   ins_encode %{
       
  9561     __ eor($dst$$Register, $src1$$Register, $con$$constant);
       
  9562     __ eor($dst$$Register->successor(), $src1$$Register->successor(), 0);
       
  9563   %}
       
  9564   ins_pipe(ialu_reg_imm);
       
  9565 %}
       
  9566 #endif // AARCH64
       
  9567 
       
  9568 //----------Convert to Boolean-------------------------------------------------
       
  9569 instruct convI2B( iRegI dst, iRegI src, flagsReg ccr ) %{
       
  9570   match(Set dst (Conv2B src));
       
  9571   effect(KILL ccr);
       
  9572 #ifdef AARCH64
       
  9573   size(8);
       
  9574   ins_cost(DEFAULT_COST*2);
       
  9575   format %{ "cmp_32 $src,ZR\n\t"
       
  9576             "cset_w $dst, ne" %}
       
  9577   ins_encode %{
       
  9578     __ cmp_32($src$$Register, ZR);
       
  9579     __ cset_w($dst$$Register, ne);
       
  9580   %}
       
  9581 #else
       
  9582   size(12);
       
  9583   ins_cost(DEFAULT_COST*2);
       
  9584   format %{ "TST    $src,$src \n\t"
       
  9585             "MOV    $dst, 0   \n\t"
       
  9586             "MOV.ne $dst, 1" %}
       
  9587   ins_encode %{ // FIXME: can do better?
       
  9588     __ tst($src$$Register, $src$$Register);
       
  9589     __ mov($dst$$Register, 0);
       
  9590     __ mov($dst$$Register, 1, ne);
       
  9591   %}
       
  9592 #endif
       
  9593   ins_pipe(ialu_reg_ialu);
       
  9594 %}
       
  9595 
       
  9596 instruct convP2B( iRegI dst, iRegP src, flagsReg ccr ) %{
       
  9597   match(Set dst (Conv2B src));
       
  9598   effect(KILL ccr);
       
  9599 #ifdef AARCH64
       
  9600   size(8);
       
  9601   ins_cost(DEFAULT_COST*2);
       
  9602   format %{ "CMP    $src,ZR\n\t"
       
  9603             "cset   $dst, ne" %}
       
  9604   ins_encode %{
       
  9605     __ cmp($src$$Register, ZR);
       
  9606     __ cset($dst$$Register, ne);
       
  9607   %}
       
  9608 #else
       
  9609   size(12);
       
  9610   ins_cost(DEFAULT_COST*2);
       
  9611   format %{ "TST    $src,$src \n\t"
       
  9612             "MOV    $dst, 0   \n\t"
       
  9613             "MOV.ne $dst, 1" %}
       
  9614   ins_encode %{
       
  9615     __ tst($src$$Register, $src$$Register);
       
  9616     __ mov($dst$$Register, 0);
       
  9617     __ mov($dst$$Register, 1, ne);
       
  9618   %}
       
  9619 #endif
       
  9620   ins_pipe(ialu_reg_ialu);
       
  9621 %}
       
  9622 
       
  9623 instruct cmpLTMask_reg_reg( iRegI dst, iRegI p, iRegI q, flagsReg ccr ) %{
       
  9624   match(Set dst (CmpLTMask p q));
       
  9625   effect( KILL ccr );
       
  9626 #ifdef AARCH64
       
  9627   size(8);
       
  9628   ins_cost(DEFAULT_COST*2);
       
  9629   format %{ "CMP_w   $p,$q\n\t"
       
  9630             "CSETM_w $dst, lt" %}
       
  9631   ins_encode %{
       
  9632     __ cmp_w($p$$Register, $q$$Register);
       
  9633     __ csetm_w($dst$$Register, lt);
       
  9634   %}
       
  9635 #else
       
  9636   ins_cost(DEFAULT_COST*3);
       
  9637   format %{ "CMP    $p,$q\n\t"
       
  9638             "MOV    $dst, #0\n\t"
       
  9639             "MOV.lt $dst, #-1" %}
       
  9640   ins_encode %{
       
  9641     __ cmp($p$$Register, $q$$Register);
       
  9642     __ mov($dst$$Register, 0);
       
  9643     __ mvn($dst$$Register, 0, lt);
       
  9644   %}
       
  9645 #endif
       
  9646   ins_pipe(ialu_reg_reg_ialu);
       
  9647 %}
       
  9648 
       
  9649 instruct cmpLTMask_reg_imm( iRegI dst, iRegI p, aimmI q, flagsReg ccr ) %{
       
  9650   match(Set dst (CmpLTMask p q));
       
  9651   effect( KILL ccr );
       
  9652 #ifdef AARCH64
       
  9653   size(8);
       
  9654   ins_cost(DEFAULT_COST*2);
       
  9655   format %{ "CMP_w   $p,$q\n\t"
       
  9656             "CSETM_w $dst, lt" %}
       
  9657   ins_encode %{
       
  9658     __ cmp_w($p$$Register, $q$$constant);
       
  9659     __ csetm_w($dst$$Register, lt);
       
  9660   %}
       
  9661 #else
       
  9662   ins_cost(DEFAULT_COST*3);
       
  9663   format %{ "CMP    $p,$q\n\t"
       
  9664             "MOV    $dst, #0\n\t"
       
  9665             "MOV.lt $dst, #-1" %}
       
  9666   ins_encode %{
       
  9667     __ cmp($p$$Register, $q$$constant);
       
  9668     __ mov($dst$$Register, 0);
       
  9669     __ mvn($dst$$Register, 0, lt);
       
  9670   %}
       
  9671 #endif
       
  9672   ins_pipe(ialu_reg_reg_ialu);
       
  9673 %}
       
  9674 
       
  9675 #ifdef AARCH64
       
  9676 instruct cadd_cmpLTMask3( iRegI dst, iRegI p, iRegI q, iRegI y, iRegI x, flagsReg ccr ) %{
       
  9677   match(Set dst (AddI (AndI (CmpLTMask p q) y) x));
       
  9678   effect( TEMP dst, KILL ccr );
       
  9679   size(12);
       
  9680   ins_cost(DEFAULT_COST*3);
       
  9681   format %{ "CMP_w  $p,$q\n\t"
       
  9682             "ADD_w  $dst,$y,$x\n\t"
       
  9683             "CSEL_w $dst,$dst,$x,lt" %}
       
  9684   ins_encode %{
       
  9685     __ cmp_w($p$$Register, $q$$Register);
       
  9686     __ add_w($dst$$Register, $y$$Register, $x$$Register);
       
  9687     __ csel_w($dst$$Register, $dst$$Register, $x$$Register, lt);
       
  9688   %}
       
  9689   ins_pipe( cadd_cmpltmask );
       
  9690 %}
       
  9691 #else
       
  9692 instruct cadd_cmpLTMask3( iRegI p, iRegI q, iRegI y, iRegI z, flagsReg ccr ) %{
       
  9693   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
       
  9694   effect( KILL ccr );
       
  9695   ins_cost(DEFAULT_COST*2);
       
  9696   format %{ "CMP    $p,$q\n\t"
       
  9697             "ADD.lt $z,$y,$z" %}
       
  9698   ins_encode %{
       
  9699     __ cmp($p$$Register, $q$$Register);
       
  9700     __ add($z$$Register, $y$$Register, $z$$Register, lt);
       
  9701   %}
       
  9702   ins_pipe( cadd_cmpltmask );
       
  9703 %}
       
  9704 #endif
       
  9705 
       
  9706 #ifdef AARCH64
       
  9707 instruct cadd_cmpLTMask4( iRegI dst, iRegI p, aimmI q, iRegI y, iRegI x, flagsReg ccr ) %{
       
  9708   match(Set dst (AddI (AndI (CmpLTMask p q) y) x));
       
  9709   effect( TEMP dst, KILL ccr );
       
  9710   size(12);
       
  9711   ins_cost(DEFAULT_COST*3);
       
  9712   format %{ "CMP_w  $p,$q\n\t"
       
  9713             "ADD_w  $dst,$y,$x\n\t"
       
  9714             "CSEL_w $dst,$dst,$x,lt" %}
       
  9715   ins_encode %{
       
  9716     __ cmp_w($p$$Register, $q$$constant);
       
  9717     __ add_w($dst$$Register, $y$$Register, $x$$Register);
       
  9718     __ csel_w($dst$$Register, $dst$$Register, $x$$Register, lt);
       
  9719   %}
       
  9720   ins_pipe( cadd_cmpltmask );
       
  9721 %}
       
  9722 #else
       
  9723 // FIXME: remove unused "dst"
       
  9724 instruct cadd_cmpLTMask4( iRegI dst, iRegI p, aimmI q, iRegI y, iRegI z, flagsReg ccr ) %{
       
  9725   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
       
  9726   effect( KILL ccr );
       
  9727   ins_cost(DEFAULT_COST*2);
       
  9728   format %{ "CMP    $p,$q\n\t"
       
  9729             "ADD.lt $z,$y,$z" %}
       
  9730   ins_encode %{
       
  9731     __ cmp($p$$Register, $q$$constant);
       
  9732     __ add($z$$Register, $y$$Register, $z$$Register, lt);
       
  9733   %}
       
  9734   ins_pipe( cadd_cmpltmask );
       
  9735 %}
       
  9736 #endif // !AARCH64
       
  9737 
       
  9738 #ifdef AARCH64
       
  9739 instruct cadd_cmpLTMask( iRegI dst, iRegI p, iRegI q, iRegI y, flagsReg ccr ) %{
       
  9740   match(Set dst (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
       
  9741   effect( TEMP dst, KILL ccr );
       
  9742   size(12);
       
  9743   ins_cost(DEFAULT_COST*3);
       
  9744   format %{ "SUBS_w $p,$p,$q\n\t"
       
  9745             "ADD_w  $dst,$y,$p\n\t"
       
  9746             "CSEL_w $dst,$dst,$p,lt" %}
       
  9747   ins_encode %{
       
  9748     __ subs_w($p$$Register, $p$$Register, $q$$Register);
       
  9749     __ add_w($dst$$Register, $y$$Register, $p$$Register);
       
  9750     __ csel_w($dst$$Register, $dst$$Register, $p$$Register, lt);
       
  9751   %}
       
  9752   ins_pipe( cadd_cmpltmask ); // FIXME
       
  9753 %}
       
  9754 #else
       
  9755 instruct cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, flagsReg ccr ) %{
       
  9756   match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
       
  9757   effect( KILL ccr );
       
  9758   ins_cost(DEFAULT_COST*2);
       
  9759   format %{ "SUBS   $p,$p,$q\n\t"
       
  9760             "ADD.lt $p,$y,$p" %}
       
  9761   ins_encode %{
       
  9762     __ subs($p$$Register, $p$$Register, $q$$Register);
       
  9763     __ add($p$$Register, $y$$Register, $p$$Register, lt);
       
  9764   %}
       
  9765   ins_pipe( cadd_cmpltmask );
       
  9766 %}
       
  9767 #endif
       
  9768 
       
  9769 //----------Arithmetic Conversion Instructions---------------------------------
       
  9770 // The conversions operations are all Alpha sorted.  Please keep it that way!
       
  9771 
       
  9772 instruct convD2F_reg(regF dst, regD src) %{
       
  9773   match(Set dst (ConvD2F src));
       
  9774   size(4);
       
  9775   format %{ "FCVTSD  $dst,$src" %}
       
  9776   ins_encode %{
       
  9777     __ convert_d2f($dst$$FloatRegister, $src$$FloatRegister);
       
  9778   %}
       
  9779   ins_pipe(fcvtD2F);
       
  9780 %}
       
  9781 
       
  9782 // Convert a double to an int in a float register.
       
  9783 // If the double is a NAN, stuff a zero in instead.
       
  9784 
       
  9785 #ifdef AARCH64
       
  9786 instruct convD2I_reg_reg(iRegI dst, regD src) %{
       
  9787   match(Set dst (ConvD2I src));
       
  9788   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
       
  9789   format %{ "FCVTZS_wd $dst, $src" %}
       
  9790   ins_encode %{
       
  9791     __ fcvtzs_wd($dst$$Register, $src$$FloatRegister);
       
  9792   %}
       
  9793   ins_pipe(fcvtD2I);
       
  9794 %}
       
  9795 
       
  9796 instruct convD2L_reg_reg(iRegL dst, regD src) %{
       
  9797   match(Set dst (ConvD2L src));
       
  9798   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
       
  9799   format %{ "FCVTZS_xd $dst, $src" %}
       
  9800   ins_encode %{
       
  9801     __ fcvtzs_xd($dst$$Register, $src$$FloatRegister);
       
  9802   %}
       
  9803   ins_pipe(fcvtD2L);
       
  9804 %}
       
  9805 #else
       
  9806 instruct convD2I_reg_reg(iRegI dst, regD src, regF tmp) %{
       
  9807   match(Set dst (ConvD2I src));
       
  9808   effect( TEMP tmp );
       
  9809   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
       
  9810   format %{ "FTOSIZD  $tmp,$src\n\t"
       
  9811             "FMRS     $dst, $tmp" %}
       
  9812   ins_encode %{
       
  9813     __ ftosizd($tmp$$FloatRegister, $src$$FloatRegister);
       
  9814     __ fmrs($dst$$Register, $tmp$$FloatRegister);
       
  9815   %}
       
  9816   ins_pipe(fcvtD2I);
       
  9817 %}
       
  9818 #endif
       
  9819 
       
  9820 // Convert a double to a long in a double register.
       
  9821 // If the double is a NAN, stuff a zero in instead.
       
  9822 
       
  9823 #ifndef AARCH64
       
  9824 // Double to Long conversion
       
  9825 instruct convD2L_reg(R0R1RegL dst, regD src) %{
       
  9826   match(Set dst (ConvD2L src));
       
  9827   effect(CALL);
       
  9828   ins_cost(MEMORY_REF_COST); // FIXME
       
  9829   format %{ "convD2L    $dst,$src\t ! call to SharedRuntime::d2l" %}
       
  9830   ins_encode %{
       
  9831 #ifndef __ABI_HARD__
       
  9832     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
       
  9833 #else
       
  9834     if ($src$$FloatRegister != D0) {
       
  9835       __ mov_double(D0, $src$$FloatRegister);
       
  9836     }
       
  9837 #endif
       
  9838     address target = CAST_FROM_FN_PTR(address, SharedRuntime::d2l);
       
  9839     __ call(target, relocInfo::runtime_call_type);
       
  9840   %}
       
  9841   ins_pipe(fcvtD2L);
       
  9842 %}
       
  9843 #endif
       
  9844 
       
  9845 instruct convF2D_reg(regD dst, regF src) %{
       
  9846   match(Set dst (ConvF2D src));
       
  9847   size(4);
       
  9848   format %{ "FCVTDS  $dst,$src" %}
       
  9849   ins_encode %{
       
  9850     __ convert_f2d($dst$$FloatRegister, $src$$FloatRegister);
       
  9851   %}
       
  9852   ins_pipe(fcvtF2D);
       
  9853 %}
       
  9854 
       
  9855 #ifdef AARCH64
       
  9856 instruct convF2I_reg_reg(iRegI dst, regF src) %{
       
  9857   match(Set dst (ConvF2I src));
       
  9858   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
       
  9859   size(4);
       
  9860   format %{ "FCVTZS_ws $dst, $src" %}
       
  9861   ins_encode %{
       
  9862     __ fcvtzs_ws($dst$$Register, $src$$FloatRegister);
       
  9863   %}
       
  9864   ins_pipe(fcvtF2I);
       
  9865 %}
       
  9866 
       
  9867 instruct convF2L_reg_reg(iRegL dst, regF src) %{
       
  9868   match(Set dst (ConvF2L src));
       
  9869   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
       
  9870   size(4);
       
  9871   format %{ "FCVTZS_xs $dst, $src" %}
       
  9872   ins_encode %{
       
  9873     __ fcvtzs_xs($dst$$Register, $src$$FloatRegister);
       
  9874   %}
       
  9875   ins_pipe(fcvtF2L);
       
  9876 %}
       
  9877 #else
       
  9878 instruct convF2I_reg_reg(iRegI dst, regF src, regF tmp) %{
       
  9879   match(Set dst (ConvF2I src));
       
  9880   effect( TEMP tmp );
       
  9881   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
       
  9882   size(8);
       
  9883   format %{ "FTOSIZS  $tmp,$src\n\t"
       
  9884             "FMRS     $dst, $tmp" %}
       
  9885   ins_encode %{
       
  9886     __ ftosizs($tmp$$FloatRegister, $src$$FloatRegister);
       
  9887     __ fmrs($dst$$Register, $tmp$$FloatRegister);
       
  9888   %}
       
  9889   ins_pipe(fcvtF2I);
       
  9890 %}
       
  9891 
       
  9892 // Float to Long conversion
       
  9893 instruct convF2L_reg(R0R1RegL dst, regF src, R0RegI arg1) %{
       
  9894   match(Set dst (ConvF2L src));
       
  9895   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
       
  9896   effect(CALL);
       
  9897   format %{ "convF2L  $dst,$src\t! call to SharedRuntime::f2l" %}
       
  9898   ins_encode %{
       
  9899 #ifndef __ABI_HARD__
       
  9900     __ fmrs($arg1$$Register, $src$$FloatRegister);
       
  9901 #else
       
  9902     if($src$$FloatRegister != S0) {
       
  9903       __ mov_float(S0, $src$$FloatRegister);
       
  9904     }
       
  9905 #endif
       
  9906     address target = CAST_FROM_FN_PTR(address, SharedRuntime::f2l);
       
  9907     __ call(target, relocInfo::runtime_call_type);
       
  9908   %}
       
  9909   ins_pipe(fcvtF2L);
       
  9910 %}
       
  9911 #endif
       
  9912 
       
  9913 #ifdef AARCH64
       
  9914 instruct convI2D_reg_reg(iRegI src, regD dst) %{
       
  9915   match(Set dst (ConvI2D src));
       
  9916   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
       
  9917   size(4);
       
  9918   format %{ "SCVTF_dw $dst,$src" %}
       
  9919   ins_encode %{
       
  9920       __ scvtf_dw($dst$$FloatRegister, $src$$Register);
       
  9921   %}
       
  9922   ins_pipe(fcvtI2D);
       
  9923 %}
       
  9924 #else
       
  9925 instruct convI2D_reg_reg(iRegI src, regD_low dst) %{
       
  9926   match(Set dst (ConvI2D src));
       
  9927   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
       
  9928   size(8);
       
  9929   format %{ "FMSR     $dst,$src \n\t"
       
  9930             "FSITOD   $dst $dst"%}
       
  9931   ins_encode %{
       
  9932       __ fmsr($dst$$FloatRegister, $src$$Register);
       
  9933       __ fsitod($dst$$FloatRegister, $dst$$FloatRegister);
       
  9934   %}
       
  9935   ins_pipe(fcvtI2D);
       
  9936 %}
       
  9937 #endif
       
  9938 
       
  9939 instruct convI2F_reg_reg( regF dst, iRegI src ) %{
       
  9940   match(Set dst (ConvI2F src));
       
  9941   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
       
  9942 #ifdef AARCH64
       
  9943   size(4);
       
  9944   format %{ "SCVTF_sw $dst,$src" %}
       
  9945   ins_encode %{
       
  9946       __ scvtf_sw($dst$$FloatRegister, $src$$Register);
       
  9947   %}
       
  9948 #else
       
  9949   size(8);
       
  9950   format %{ "FMSR     $dst,$src \n\t"
       
  9951             "FSITOS   $dst, $dst"%}
       
  9952   ins_encode %{
       
  9953       __ fmsr($dst$$FloatRegister, $src$$Register);
       
  9954       __ fsitos($dst$$FloatRegister, $dst$$FloatRegister);
       
  9955   %}
       
  9956 #endif
       
  9957   ins_pipe(fcvtI2F);
       
  9958 %}
       
  9959 
       
  9960 instruct convI2L_reg(iRegL dst, iRegI src) %{
       
  9961   match(Set dst (ConvI2L src));
       
  9962 #ifdef AARCH64
       
  9963   size(4);
       
  9964   format %{ "SXTW   $dst,$src\t! int->long" %}
       
  9965   ins_encode %{
       
  9966     __ sxtw($dst$$Register, $src$$Register);
       
  9967   %}
       
  9968 #else
       
  9969   size(8);
       
  9970   format %{ "MOV    $dst.lo, $src \n\t"
       
  9971             "ASR    $dst.hi,$src,31\t! int->long" %}
       
  9972   ins_encode %{
       
  9973     __ mov($dst$$Register, $src$$Register);
       
  9974     __ mov($dst$$Register->successor(), AsmOperand($src$$Register, asr, 31));
       
  9975   %}
       
  9976 #endif
       
  9977   ins_pipe(ialu_reg_reg);
       
  9978 %}
       
  9979 
       
  9980 // Zero-extend convert int to long
       
  9981 instruct convI2L_reg_zex(iRegL dst, iRegI src, immL_32bits mask ) %{
       
  9982   match(Set dst (AndL (ConvI2L src) mask) );
       
  9983 #ifdef AARCH64
       
  9984   size(4);
       
  9985   format %{ "mov_w  $dst,$src\t! zero-extend int to long"  %}
       
  9986   ins_encode %{
       
  9987     __ mov_w($dst$$Register, $src$$Register);
       
  9988   %}
       
  9989 #else
       
  9990   size(8);
       
  9991   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend int to long\n\t"
       
  9992             "MOV    $dst.hi, 0"%}
       
  9993   ins_encode %{
       
  9994     __ mov($dst$$Register, $src$$Register);
       
  9995     __ mov($dst$$Register->successor(), 0);
       
  9996   %}
       
  9997 #endif
       
  9998   ins_pipe(ialu_reg_reg);
       
  9999 %}
       
 10000 
       
 10001 // Zero-extend long
       
 10002 instruct zerox_long(iRegL dst, iRegL src, immL_32bits mask ) %{
       
 10003   match(Set dst (AndL src mask) );
       
 10004 #ifdef AARCH64
       
 10005   size(4);
       
 10006   format %{ "mov_w  $dst,$src\t! zero-extend long"  %}
       
 10007   ins_encode %{
       
 10008     __ mov_w($dst$$Register, $src$$Register);
       
 10009   %}
       
 10010 #else
       
 10011   size(8);
       
 10012   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend long\n\t"
       
 10013             "MOV    $dst.hi, 0"%}
       
 10014   ins_encode %{
       
 10015     __ mov($dst$$Register, $src$$Register);
       
 10016     __ mov($dst$$Register->successor(), 0);
       
 10017   %}
       
 10018 #endif
       
 10019   ins_pipe(ialu_reg_reg);
       
 10020 %}
       
 10021 
       
 10022 instruct MoveF2I_reg_reg(iRegI dst, regF src) %{
       
 10023   match(Set dst (MoveF2I src));
       
 10024   effect(DEF dst, USE src);
       
 10025   ins_cost(MEMORY_REF_COST); // FIXME
       
 10026 
       
 10027   size(4);
       
 10028   format %{ "FMRS   $dst,$src\t! MoveF2I" %}
       
 10029   ins_encode %{
       
 10030     __ fmrs($dst$$Register, $src$$FloatRegister);
       
 10031   %}
       
 10032   ins_pipe(iload_mem); // FIXME
       
 10033 %}
       
 10034 
       
 10035 instruct MoveI2F_reg_reg(regF dst, iRegI src) %{
       
 10036   match(Set dst (MoveI2F src));
       
 10037   ins_cost(MEMORY_REF_COST); // FIXME
       
 10038 
       
 10039   size(4);
       
 10040   format %{ "FMSR   $dst,$src\t! MoveI2F" %}
       
 10041   ins_encode %{
       
 10042     __ fmsr($dst$$FloatRegister, $src$$Register);
       
 10043   %}
       
 10044   ins_pipe(iload_mem); // FIXME
       
 10045 %}
       
 10046 
       
 10047 instruct MoveD2L_reg_reg(iRegL dst, regD src) %{
       
 10048   match(Set dst (MoveD2L src));
       
 10049   effect(DEF dst, USE src);
       
 10050   ins_cost(MEMORY_REF_COST); // FIXME
       
 10051 
       
 10052   size(4);
       
 10053 #ifdef AARCH64
       
 10054   format %{ "FMOV_xd  $dst,$src\t! MoveD2L" %}
       
 10055   ins_encode %{
       
 10056     __ fmov_xd($dst$$Register, $src$$FloatRegister);
       
 10057   %}
       
 10058 #else
       
 10059   format %{ "FMRRD    $dst,$src\t! MoveD2L" %}
       
 10060   ins_encode %{
       
 10061     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
       
 10062   %}
       
 10063 #endif
       
 10064   ins_pipe(iload_mem); // FIXME
       
 10065 %}
       
 10066 
       
 10067 instruct MoveL2D_reg_reg(regD dst, iRegL src) %{
       
 10068   match(Set dst (MoveL2D src));
       
 10069   effect(DEF dst, USE src);
       
 10070   ins_cost(MEMORY_REF_COST); // FIXME
       
 10071 
       
 10072   size(4);
       
 10073 #ifdef AARCH64
       
 10074   format %{ "FMOV_dx $dst,$src\t! MoveL2D" %}
       
 10075   ins_encode %{
       
 10076     __ fmov_dx($dst$$FloatRegister, $src$$Register);
       
 10077   %}
       
 10078 #else
       
 10079   format %{ "FMDRR   $dst,$src\t! MoveL2D" %}
       
 10080   ins_encode %{
       
 10081     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
       
 10082   %}
       
 10083 #endif
       
 10084   ins_pipe(ialu_reg_reg); // FIXME
       
 10085 %}
       
 10086 
       
 10087 //-----------
       
 10088 // Long to Double conversion
       
 10089 
       
 10090 #ifdef AARCH64
       
 10091 instruct convL2D(regD dst, iRegL src) %{
       
 10092   match(Set dst (ConvL2D src));
       
 10093   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
       
 10094   size(4);
       
 10095   format %{ "SCVTF_dx $dst, $src" %}
       
 10096   ins_encode %{
       
 10097     __ scvtf_dx($dst$$FloatRegister, $src$$Register);
       
 10098   %}
       
 10099   ins_pipe(fcvtL2D);
       
 10100 %}
       
 10101 
       
 10102 instruct convL2F(regF dst, iRegL src) %{
       
 10103   match(Set dst (ConvL2F src));
       
 10104   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
       
 10105   size(4);
       
 10106   format %{ "SCVTF_sx $dst, $src" %}
       
 10107   ins_encode %{
       
 10108     __ scvtf_sx($dst$$FloatRegister, $src$$Register);
       
 10109   %}
       
 10110   ins_pipe(fcvtL2F);
       
 10111 %}
       
 10112 #else
       
 10113 // Magic constant, 0x43300000
       
 10114 instruct loadConI_x43300000(iRegI dst) %{
       
 10115   effect(DEF dst);
       
 10116   size(8);
       
 10117   format %{ "MOV_SLOW  $dst,0x43300000\t! 2^52" %}
       
 10118   ins_encode %{
       
 10119     __ mov_slow($dst$$Register, 0x43300000);
       
 10120   %}
       
 10121   ins_pipe(ialu_none);
       
 10122 %}
       
 10123 
       
 10124 // Magic constant, 0x41f00000
       
 10125 instruct loadConI_x41f00000(iRegI dst) %{
       
 10126   effect(DEF dst);
       
 10127   size(8);
       
 10128   format %{ "MOV_SLOW  $dst, 0x41f00000\t! 2^32" %}
       
 10129   ins_encode %{
       
 10130     __ mov_slow($dst$$Register, 0x41f00000);
       
 10131   %}
       
 10132   ins_pipe(ialu_none);
       
 10133 %}
       
 10134 
       
 10135 instruct loadConI_x0(iRegI dst) %{
       
 10136   effect(DEF dst);
       
 10137   size(4);
       
 10138   format %{ "MOV  $dst, 0x0\t! 0" %}
       
 10139   ins_encode %{
       
 10140     __ mov($dst$$Register, 0);
       
 10141   %}
       
 10142   ins_pipe(ialu_none);
       
 10143 %}
       
 10144 
       
 10145 // Construct a double from two float halves
       
 10146 instruct regDHi_regDLo_to_regD(regD_low dst, regD_low src1, regD_low src2) %{
       
 10147   effect(DEF dst, USE src1, USE src2);
       
 10148   size(8);
       
 10149   format %{ "FCPYS  $dst.hi,$src1.hi\n\t"
       
 10150             "FCPYS  $dst.lo,$src2.lo" %}
       
 10151   ins_encode %{
       
 10152     __ fcpys($dst$$FloatRegister->successor(), $src1$$FloatRegister->successor());
       
 10153     __ fcpys($dst$$FloatRegister, $src2$$FloatRegister);
       
 10154   %}
       
 10155   ins_pipe(faddD_reg_reg);
       
 10156 %}
       
 10157 
       
 10158 #ifndef AARCH64
       
 10159 // Convert integer in high half of a double register (in the lower half of
       
 10160 // the double register file) to double
       
 10161 instruct convI2D_regDHi_regD(regD dst, regD_low src) %{
       
 10162   effect(DEF dst, USE src);
       
 10163   size(4);
       
 10164   format %{ "FSITOD  $dst,$src" %}
       
 10165   ins_encode %{
       
 10166     __ fsitod($dst$$FloatRegister, $src$$FloatRegister->successor());
       
 10167   %}
       
 10168   ins_pipe(fcvtLHi2D);
       
 10169 %}
       
 10170 #endif
       
 10171 
       
 10172 // Add float double precision
       
 10173 instruct addD_regD_regD(regD dst, regD src1, regD src2) %{
       
 10174   effect(DEF dst, USE src1, USE src2);
       
 10175   size(4);
       
 10176   format %{ "FADDD  $dst,$src1,$src2" %}
       
 10177   ins_encode %{
       
 10178     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
       
 10179   %}
       
 10180   ins_pipe(faddD_reg_reg);
       
 10181 %}
       
 10182 
       
 10183 // Sub float double precision
       
 10184 instruct subD_regD_regD(regD dst, regD src1, regD src2) %{
       
 10185   effect(DEF dst, USE src1, USE src2);
       
 10186   size(4);
       
 10187   format %{ "FSUBD  $dst,$src1,$src2" %}
       
 10188   ins_encode %{
       
 10189     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
       
 10190   %}
       
 10191   ins_pipe(faddD_reg_reg);
       
 10192 %}
       
 10193 
       
 10194 // Mul float double precision
       
 10195 instruct mulD_regD_regD(regD dst, regD src1, regD src2) %{
       
 10196   effect(DEF dst, USE src1, USE src2);
       
 10197   size(4);
       
 10198   format %{ "FMULD  $dst,$src1,$src2" %}
       
 10199   ins_encode %{
       
 10200     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
       
 10201   %}
       
 10202   ins_pipe(fmulD_reg_reg);
       
 10203 %}
       
 10204 
       
 10205 instruct regL_to_regD(regD dst, iRegL src) %{
       
 10206   // No match rule to avoid chain rule match.
       
 10207   effect(DEF dst, USE src);
       
 10208   ins_cost(MEMORY_REF_COST);
       
 10209   size(4);
       
 10210   format %{ "FMDRR   $dst,$src\t! regL to regD" %}
       
 10211   ins_encode %{
       
 10212     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
       
 10213   %}
       
 10214   ins_pipe(ialu_reg_reg); // FIXME
       
 10215 %}
       
 10216 
       
 10217 instruct regI_regI_to_regD(regD dst, iRegI src1, iRegI src2) %{
       
 10218   // No match rule to avoid chain rule match.
       
 10219   effect(DEF dst, USE src1, USE src2);
       
 10220   ins_cost(MEMORY_REF_COST);
       
 10221   size(4);
       
 10222   format %{ "FMDRR   $dst,$src1,$src2\t! regI,regI to regD" %}
       
 10223   ins_encode %{
       
 10224     __ fmdrr($dst$$FloatRegister, $src1$$Register, $src2$$Register);
       
 10225   %}
       
 10226   ins_pipe(ialu_reg_reg); // FIXME
       
 10227 %}
       
 10228 
       
 10229 instruct convL2D_reg_slow_fxtof(regD dst, iRegL src) %{
       
 10230   match(Set dst (ConvL2D src));
       
 10231   ins_cost(DEFAULT_COST*8 + MEMORY_REF_COST*6); // FIXME
       
 10232 
       
 10233   expand %{
       
 10234     regD_low   tmpsrc;
       
 10235     iRegI      ix43300000;
       
 10236     iRegI      ix41f00000;
       
 10237     iRegI      ix0;
       
 10238     regD_low   dx43300000;
       
 10239     regD       dx41f00000;
       
 10240     regD       tmp1;
       
 10241     regD_low   tmp2;
       
 10242     regD       tmp3;
       
 10243     regD       tmp4;
       
 10244 
       
 10245     regL_to_regD(tmpsrc, src);
       
 10246 
       
 10247     loadConI_x43300000(ix43300000);
       
 10248     loadConI_x41f00000(ix41f00000);
       
 10249     loadConI_x0(ix0);
       
 10250 
       
 10251     regI_regI_to_regD(dx43300000, ix0, ix43300000);
       
 10252     regI_regI_to_regD(dx41f00000, ix0, ix41f00000);
       
 10253 
       
 10254     convI2D_regDHi_regD(tmp1, tmpsrc);
       
 10255     regDHi_regDLo_to_regD(tmp2, dx43300000, tmpsrc);
       
 10256     subD_regD_regD(tmp3, tmp2, dx43300000);
       
 10257     mulD_regD_regD(tmp4, tmp1, dx41f00000);
       
 10258     addD_regD_regD(dst, tmp3, tmp4);
       
 10259   %}
       
 10260 %}
       
 10261 #endif // !AARCH64
       
 10262 
       
 10263 instruct convL2I_reg(iRegI dst, iRegL src) %{
       
 10264   match(Set dst (ConvL2I src));
       
 10265   size(4);
       
 10266 #ifdef AARCH64
       
 10267   format %{ "MOV_w  $dst,$src\t! long->int" %}
       
 10268   ins_encode %{
       
 10269     __ mov_w($dst$$Register, $src$$Register);
       
 10270   %}
       
 10271 #else
       
 10272   format %{ "MOV    $dst,$src.lo\t! long->int" %}
       
 10273   ins_encode %{
       
 10274     __ mov($dst$$Register, $src$$Register);
       
 10275   %}
       
 10276 #endif
       
 10277   ins_pipe(ialu_move_reg_I_to_L);
       
 10278 %}
       
 10279 
       
 10280 #ifndef AARCH64
       
 10281 // Register Shift Right Immediate
       
 10282 instruct shrL_reg_imm6_L2I(iRegI dst, iRegL src, immI_32_63 cnt) %{
       
 10283   match(Set dst (ConvL2I (RShiftL src cnt)));
       
 10284   size(4);
       
 10285   format %{ "ASR    $dst,$src.hi,($cnt - 32)\t! long->int or mov if $cnt==32" %}
       
 10286   ins_encode %{
       
 10287     if ($cnt$$constant == 32) {
       
 10288       __ mov($dst$$Register, $src$$Register->successor());
       
 10289     } else {
       
 10290       __ mov($dst$$Register, AsmOperand($src$$Register->successor(), asr, $cnt$$constant - 32));
       
 10291     }
       
 10292   %}
       
 10293   ins_pipe(ialu_reg_imm);
       
 10294 %}
       
 10295 #endif
       
 10296 
       
 10297 
       
 10298 //----------Control Flow Instructions------------------------------------------
       
 10299 // Compare Instructions
       
 10300 // Compare Integers
       
 10301 instruct compI_iReg(flagsReg icc, iRegI op1, iRegI op2) %{
       
 10302   match(Set icc (CmpI op1 op2));
       
 10303   effect( DEF icc, USE op1, USE op2 );
       
 10304 
       
 10305   size(4);
       
 10306   format %{ "cmp_32 $op1,$op2\t! int" %}
       
 10307   ins_encode %{
       
 10308     __ cmp_32($op1$$Register, $op2$$Register);
       
 10309   %}
       
 10310   ins_pipe(ialu_cconly_reg_reg);
       
 10311 %}
       
 10312 
       
 10313 #ifdef _LP64
       
 10314 // Compare compressed pointers
       
 10315 instruct compN_reg2(flagsRegU icc, iRegN op1, iRegN op2) %{
       
 10316   match(Set icc (CmpN op1 op2));
       
 10317   effect( DEF icc, USE op1, USE op2 );
       
 10318 
       
 10319   size(4);
       
 10320   format %{ "cmp_32 $op1,$op2\t! int" %}
       
 10321   ins_encode %{
       
 10322     __ cmp_32($op1$$Register, $op2$$Register);
       
 10323   %}
       
 10324   ins_pipe(ialu_cconly_reg_reg);
       
 10325 %}
       
 10326 #endif
       
 10327 
       
 10328 instruct compU_iReg(flagsRegU icc, iRegI op1, iRegI op2) %{
       
 10329   match(Set icc (CmpU op1 op2));
       
 10330 
       
 10331   size(4);
       
 10332   format %{ "cmp_32 $op1,$op2\t! unsigned int" %}
       
 10333   ins_encode %{
       
 10334     __ cmp_32($op1$$Register, $op2$$Register);
       
 10335   %}
       
 10336   ins_pipe(ialu_cconly_reg_reg);
       
 10337 %}
       
 10338 
       
 10339 instruct compI_iReg_immneg(flagsReg icc, iRegI op1, aimmIneg op2) %{
       
 10340   match(Set icc (CmpI op1 op2));
       
 10341   effect( DEF icc, USE op1 );
       
 10342 
       
 10343   size(4);
       
 10344   format %{ "cmn_32 $op1,-$op2\t! int" %}
       
 10345   ins_encode %{
       
 10346     __ cmn_32($op1$$Register, -$op2$$constant);
       
 10347   %}
       
 10348   ins_pipe(ialu_cconly_reg_imm);
       
 10349 %}
       
 10350 
       
 10351 instruct compI_iReg_imm(flagsReg icc, iRegI op1, aimmI op2) %{
       
 10352   match(Set icc (CmpI op1 op2));
       
 10353   effect( DEF icc, USE op1 );
       
 10354 
       
 10355   size(4);
       
 10356   format %{ "cmp_32 $op1,$op2\t! int" %}
       
 10357   ins_encode %{
       
 10358     __ cmp_32($op1$$Register, $op2$$constant);
       
 10359   %}
       
 10360   ins_pipe(ialu_cconly_reg_imm);
       
 10361 %}
       
 10362 
       
 10363 instruct testI_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immI0 zero ) %{
       
 10364   match(Set icc (CmpI (AndI op1 op2) zero));
       
 10365   size(4);
       
 10366   format %{ "tst_32 $op2,$op1" %}
       
 10367 
       
 10368   ins_encode %{
       
 10369     __ tst_32($op1$$Register, $op2$$Register);
       
 10370   %}
       
 10371   ins_pipe(ialu_cconly_reg_reg_zero);
       
 10372 %}
       
 10373 
       
 10374 #ifndef AARCH64
       
 10375 instruct testshlI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
       
 10376   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
       
 10377   size(4);
       
 10378   format %{ "TST   $op2,$op1<<$op3" %}
       
 10379 
       
 10380   ins_encode %{
       
 10381     __ tst($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$Register));
       
 10382   %}
       
 10383   ins_pipe(ialu_cconly_reg_reg_zero);
       
 10384 %}
       
 10385 #endif
       
 10386 
       
 10387 instruct testshlI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
       
 10388   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
       
 10389   size(4);
       
 10390   format %{ "tst_32 $op2,$op1<<$op3" %}
       
 10391 
       
 10392   ins_encode %{
       
 10393     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$constant));
       
 10394   %}
       
 10395   ins_pipe(ialu_cconly_reg_reg_zero);
       
 10396 %}
       
 10397 
       
 10398 #ifndef AARCH64
       
 10399 instruct testsarI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
       
 10400   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
       
 10401   size(4);
       
 10402   format %{ "TST   $op2,$op1<<$op3" %}
       
 10403 
       
 10404   ins_encode %{
       
 10405     __ tst($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$Register));
       
 10406   %}
       
 10407   ins_pipe(ialu_cconly_reg_reg_zero);
       
 10408 %}
       
 10409 #endif
       
 10410 
       
 10411 instruct testsarI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
       
 10412   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
       
 10413   size(4);
       
 10414   format %{ "tst_32 $op2,$op1<<$op3" %}
       
 10415 
       
 10416   ins_encode %{
       
 10417     __ tst_32($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$constant));
       
 10418   %}
       
 10419   ins_pipe(ialu_cconly_reg_reg_zero);
       
 10420 %}
       
 10421 
       
 10422 #ifndef AARCH64
       
 10423 instruct testshrI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
       
 10424   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
       
 10425   size(4);
       
 10426   format %{ "TST   $op2,$op1<<$op3" %}
       
 10427 
       
 10428   ins_encode %{
       
 10429     __ tst($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$Register));
       
 10430   %}
       
 10431   ins_pipe(ialu_cconly_reg_reg_zero);
       
 10432 %}
       
 10433 #endif
       
 10434 
       
 10435 instruct testshrI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
       
 10436   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
       
 10437   size(4);
       
 10438   format %{ "tst_32 $op2,$op1<<$op3" %}
       
 10439 
       
 10440   ins_encode %{
       
 10441     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$constant));
       
 10442   %}
       
 10443   ins_pipe(ialu_cconly_reg_reg_zero);
       
 10444 %}
       
 10445 
       
 10446 instruct testI_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, limmI op2, immI0 zero ) %{
       
 10447   match(Set icc (CmpI (AndI op1 op2) zero));
       
 10448   size(4);
       
 10449   format %{ "tst_32 $op2,$op1" %}
       
 10450 
       
 10451   ins_encode %{
       
 10452     __ tst_32($op1$$Register, $op2$$constant);
       
 10453   %}
       
 10454   ins_pipe(ialu_cconly_reg_imm_zero);
       
 10455 %}
       
 10456 
       
 10457 #ifdef AARCH64
       
 10458 instruct compL_reg_reg(flagsReg xcc, iRegL op1, iRegL op2)
       
 10459 %{
       
 10460   match(Set xcc (CmpL op1 op2));
       
 10461   effect( DEF xcc, USE op1, USE op2 );
       
 10462 
       
 10463   size(4);
       
 10464   format %{ "CMP     $op1,$op2\t! long" %}
       
 10465   ins_encode %{
       
 10466     __ cmp($op1$$Register, $op2$$Register);
       
 10467   %}
       
 10468   ins_pipe(ialu_cconly_reg_reg);
       
 10469 %}
       
 10470 #else
       
 10471 instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
       
 10472   match(Set xcc (CmpL op1 op2));
       
 10473   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
       
 10474 
       
 10475   size(8);
       
 10476   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! long\n\t"
       
 10477             "SBCS    $tmp,$op1.hi,$op2.hi" %}
       
 10478   ins_encode %{
       
 10479     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
       
 10480     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
       
 10481   %}
       
 10482   ins_pipe(ialu_cconly_reg_reg);
       
 10483 %}
       
 10484 #endif
       
 10485 
       
 10486 #ifdef AARCH64
       
 10487 instruct compL_reg_con(flagsReg xcc, iRegL op1, aimmL con) %{
       
 10488   match(Set xcc (CmpL op1 con));
       
 10489   effect( DEF xcc, USE op1, USE con );
       
 10490 
       
 10491   size(8);
       
 10492   format %{ "CMP     $op1,$con\t\t! long"  %}
       
 10493   ins_encode %{
       
 10494     __ cmp($op1$$Register, $con$$constant);
       
 10495   %}
       
 10496 
       
 10497   ins_pipe(ialu_cconly_reg_imm);
       
 10498 %}
       
 10499 #else
       
 10500 instruct compL_reg_reg_EQNE(flagsRegL_EQNE xcc, iRegL op1, iRegL op2) %{
       
 10501   match(Set xcc (CmpL op1 op2));
       
 10502   effect( DEF xcc, USE op1, USE op2 );
       
 10503 
       
 10504   size(8);
       
 10505   format %{ "TEQ    $op1.hi,$op2.hi\t\t! long\n\t"
       
 10506             "TEQ.eq $op1.lo,$op2.lo" %}
       
 10507   ins_encode %{
       
 10508     __ teq($op1$$Register->successor(), $op2$$Register->successor());
       
 10509     __ teq($op1$$Register, $op2$$Register, eq);
       
 10510   %}
       
 10511   ins_pipe(ialu_cconly_reg_reg);
       
 10512 %}
       
 10513 
       
 10514 instruct compL_reg_reg_LEGT(flagsRegL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
       
 10515   match(Set xcc (CmpL op1 op2));
       
 10516   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
       
 10517 
       
 10518   size(8);
       
 10519   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! long\n\t"
       
 10520             "SBCS    $tmp,$op2.hi,$op1.hi" %}
       
 10521   ins_encode %{
       
 10522     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
       
 10523     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
       
 10524   %}
       
 10525   ins_pipe(ialu_cconly_reg_reg);
       
 10526 %}
       
 10527 
       
 10528 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
       
 10529 // (hi($con$$constant), lo($con$$constant)) becomes
       
 10530 instruct compL_reg_con_LTGE(flagsRegL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
       
 10531   match(Set xcc (CmpL op1 con));
       
 10532   effect( DEF xcc, USE op1, USE con, TEMP tmp );
       
 10533 
       
 10534   size(8);
       
 10535   format %{ "SUBS    $tmp,$op1.low,$con\t\t! long\n\t"
       
 10536             "SBCS    $tmp,$op1.hi,0" %}
       
 10537   ins_encode %{
       
 10538     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
       
 10539     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
       
 10540   %}
       
 10541 
       
 10542   ins_pipe(ialu_cconly_reg_reg);
       
 10543 %}
       
 10544 
       
 10545 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
       
 10546 // (hi($con$$constant), lo($con$$constant)) becomes
       
 10547 instruct compL_reg_con_EQNE(flagsRegL_EQNE xcc, iRegL op1, immLlowRot con) %{
       
 10548   match(Set xcc (CmpL op1 con));
       
 10549   effect( DEF xcc, USE op1, USE con );
       
 10550 
       
 10551   size(8);
       
 10552   format %{ "TEQ    $op1.hi,0\t\t! long\n\t"
       
 10553             "TEQ.eq $op1.lo,$con" %}
       
 10554   ins_encode %{
       
 10555     __ teq($op1$$Register->successor(), 0);
       
 10556     __ teq($op1$$Register, $con$$constant, eq);
       
 10557   %}
       
 10558 
       
 10559   ins_pipe(ialu_cconly_reg_reg);
       
 10560 %}
       
 10561 
       
 10562 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
       
 10563 // (hi($con$$constant), lo($con$$constant)) becomes
       
 10564 instruct compL_reg_con_LEGT(flagsRegL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
       
 10565   match(Set xcc (CmpL op1 con));
       
 10566   effect( DEF xcc, USE op1, USE con, TEMP tmp );
       
 10567 
       
 10568   size(8);
       
 10569   format %{ "RSBS    $tmp,$op1.low,$con\t\t! long\n\t"
       
 10570             "RSCS    $tmp,$op1.hi,0" %}
       
 10571   ins_encode %{
       
 10572     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
       
 10573     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
       
 10574   %}
       
 10575 
       
 10576   ins_pipe(ialu_cconly_reg_reg);
       
 10577 %}
       
 10578 #endif
       
 10579 
       
 10580 /* instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ */
       
 10581 /*   match(Set xcc (CmpL (AndL op1 op2) zero)); */
       
 10582 /*   ins_encode %{ */
       
 10583 /*     __ stop("testL_reg_reg unimplemented"); */
       
 10584 /*   %} */
       
 10585 /*   ins_pipe(ialu_cconly_reg_reg); */
       
 10586 /* %} */
       
 10587 
       
 10588 /* // useful for checking the alignment of a pointer: */
       
 10589 /* instruct testL_reg_con(flagsRegL xcc, iRegL op1, immLlowRot con, immL0 zero) %{ */
       
 10590 /*   match(Set xcc (CmpL (AndL op1 con) zero)); */
       
 10591 /*   ins_encode %{ */
       
 10592 /*     __ stop("testL_reg_con unimplemented"); */
       
 10593 /*   %} */
       
 10594 /*   ins_pipe(ialu_cconly_reg_reg); */
       
 10595 /* %} */
       
 10596 
       
 10597 instruct compU_iReg_imm(flagsRegU icc, iRegI op1, aimmU31 op2 ) %{
       
 10598   match(Set icc (CmpU op1 op2));
       
 10599 
       
 10600   size(4);
       
 10601   format %{ "cmp_32 $op1,$op2\t! unsigned" %}
       
 10602   ins_encode %{
       
 10603     __ cmp_32($op1$$Register, $op2$$constant);
       
 10604   %}
       
 10605   ins_pipe(ialu_cconly_reg_imm);
       
 10606 %}
       
 10607 
       
 10608 // Compare Pointers
       
 10609 instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{
       
 10610   match(Set pcc (CmpP op1 op2));
       
 10611 
       
 10612   size(4);
       
 10613   format %{ "CMP    $op1,$op2\t! ptr" %}
       
 10614   ins_encode %{
       
 10615     __ cmp($op1$$Register, $op2$$Register);
       
 10616   %}
       
 10617   ins_pipe(ialu_cconly_reg_reg);
       
 10618 %}
       
 10619 
       
 10620 instruct compP_iRegP_imm(flagsRegP pcc, iRegP op1, aimmP op2 ) %{
       
 10621   match(Set pcc (CmpP op1 op2));
       
 10622 
       
 10623   size(4);
       
 10624   format %{ "CMP    $op1,$op2\t! ptr" %}
       
 10625   ins_encode %{
       
 10626     assert($op2$$constant == 0 || _opnds[2]->constant_reloc() == relocInfo::none, "reloc in cmp?");
       
 10627     __ cmp($op1$$Register, $op2$$constant);
       
 10628   %}
       
 10629   ins_pipe(ialu_cconly_reg_imm);
       
 10630 %}
       
 10631 
       
 10632 //----------Max and Min--------------------------------------------------------
       
 10633 // Min Instructions
       
 10634 // Conditional move for min
       
 10635 instruct cmovI_reg_lt( iRegI op2, iRegI op1, flagsReg icc ) %{
       
 10636   effect( USE_DEF op2, USE op1, USE icc );
       
 10637 
       
 10638   size(4);
       
 10639   format %{ "MOV.lt  $op2,$op1\t! min" %}
       
 10640   ins_encode %{
       
 10641     __ mov($op2$$Register, $op1$$Register, lt);
       
 10642   %}
       
 10643   ins_pipe(ialu_reg_flags);
       
 10644 %}
       
 10645 
       
 10646 // Min Register with Register.
       
 10647 instruct minI_eReg(iRegI op1, iRegI op2) %{
       
 10648   match(Set op2 (MinI op1 op2));
       
 10649   ins_cost(DEFAULT_COST*2);
       
 10650   expand %{
       
 10651     flagsReg icc;
       
 10652     compI_iReg(icc,op1,op2);
       
 10653     cmovI_reg_lt(op2,op1,icc);
       
 10654   %}
       
 10655 %}
       
 10656 
       
 10657 // Max Instructions
       
 10658 // Conditional move for max
       
 10659 instruct cmovI_reg_gt( iRegI op2, iRegI op1, flagsReg icc ) %{
       
 10660   effect( USE_DEF op2, USE op1, USE icc );
       
 10661   format %{ "MOV.gt  $op2,$op1\t! max" %}
       
 10662   ins_encode %{
       
 10663     __ mov($op2$$Register, $op1$$Register, gt);
       
 10664   %}
       
 10665   ins_pipe(ialu_reg_flags);
       
 10666 %}
       
 10667 
       
 10668 // Max Register with Register
       
 10669 instruct maxI_eReg(iRegI op1, iRegI op2) %{
       
 10670   match(Set op2 (MaxI op1 op2));
       
 10671   ins_cost(DEFAULT_COST*2);
       
 10672   expand %{
       
 10673     flagsReg icc;
       
 10674     compI_iReg(icc,op1,op2);
       
 10675     cmovI_reg_gt(op2,op1,icc);
       
 10676   %}
       
 10677 %}
       
 10678 
       
 10679 
       
 10680 //----------Float Compares----------------------------------------------------
       
 10681 // Compare floating, generate condition code
       
 10682 instruct cmpF_cc(flagsRegF fcc, flagsReg icc, regF src1, regF src2) %{
       
 10683   match(Set icc (CmpF src1 src2));
       
 10684   effect(KILL fcc);
       
 10685 
       
 10686 #ifdef AARCH64
       
 10687   size(4);
       
 10688   format %{ "FCMP_s  $src1,$src2" %}
       
 10689   ins_encode %{
       
 10690     __ fcmp_s($src1$$FloatRegister, $src2$$FloatRegister);
       
 10691   %}
       
 10692 #else
       
 10693   size(8);
       
 10694   format %{ "FCMPs  $src1,$src2\n\t"
       
 10695             "FMSTAT" %}
       
 10696   ins_encode %{
       
 10697     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
       
 10698     __ fmstat();
       
 10699   %}
       
 10700 #endif
       
 10701   ins_pipe(faddF_fcc_reg_reg_zero);
       
 10702 %}
       
 10703 
       
 10704 instruct cmpF0_cc(flagsRegF fcc, flagsReg icc, regF src1, immF0 src2) %{
       
 10705   match(Set icc (CmpF src1 src2));
       
 10706   effect(KILL fcc);
       
 10707 
       
 10708 #ifdef AARCH64
       
 10709   size(4);
       
 10710   format %{ "FCMP0_s $src1" %}
       
 10711   ins_encode %{
       
 10712     __ fcmp0_s($src1$$FloatRegister);
       
 10713   %}
       
 10714 #else
       
 10715   size(8);
       
 10716   format %{ "FCMPs  $src1,$src2\n\t"
       
 10717             "FMSTAT" %}
       
 10718   ins_encode %{
       
 10719     __ fcmpzs($src1$$FloatRegister);
       
 10720     __ fmstat();
       
 10721   %}
       
 10722 #endif
       
 10723   ins_pipe(faddF_fcc_reg_reg_zero);
       
 10724 %}
       
 10725 
       
 10726 instruct cmpD_cc(flagsRegF fcc, flagsReg icc, regD src1, regD src2) %{
       
 10727   match(Set icc (CmpD src1 src2));
       
 10728   effect(KILL fcc);
       
 10729 
       
 10730 #ifdef AARCH64
       
 10731   size(4);
       
 10732   format %{ "FCMP_d $src1,$src2" %}
       
 10733   ins_encode %{
       
 10734     __ fcmp_d($src1$$FloatRegister, $src2$$FloatRegister);
       
 10735   %}
       
 10736 #else
       
 10737   size(8);
       
 10738   format %{ "FCMPd  $src1,$src2 \n\t"
       
 10739             "FMSTAT" %}
       
 10740   ins_encode %{
       
 10741     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
       
 10742     __ fmstat();
       
 10743   %}
       
 10744 #endif
       
 10745   ins_pipe(faddD_fcc_reg_reg_zero);
       
 10746 %}
       
 10747 
       
 10748 instruct cmpD0_cc(flagsRegF fcc, flagsReg icc, regD src1, immD0 src2) %{
       
 10749   match(Set icc (CmpD src1 src2));
       
 10750   effect(KILL fcc);
       
 10751 
       
 10752 #ifdef AARCH64
       
 10753   size(8);
       
 10754   format %{ "FCMP0_d $src1" %}
       
 10755   ins_encode %{
       
 10756     __ fcmp0_d($src1$$FloatRegister);
       
 10757   %}
       
 10758 #else
       
 10759   size(8);
       
 10760   format %{ "FCMPZd  $src1,$src2 \n\t"
       
 10761             "FMSTAT" %}
       
 10762   ins_encode %{
       
 10763     __ fcmpzd($src1$$FloatRegister);
       
 10764     __ fmstat();
       
 10765   %}
       
 10766 #endif
       
 10767   ins_pipe(faddD_fcc_reg_reg_zero);
       
 10768 %}
       
 10769 
       
 10770 #ifdef AARCH64
       
 10771 // Compare floating, generate -1,0,1
       
 10772 instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsReg icc) %{
       
 10773   match(Set dst (CmpF3 src1 src2));
       
 10774   // effect(KILL fcc); // nobody cares if flagsRegF is killed
       
 10775   effect(KILL icc);
       
 10776   ins_cost(DEFAULT_COST*3); // FIXME
       
 10777   size(12);
       
 10778   format %{ "FCMP_s $src1,$src2\n\t"
       
 10779             "CSET   $dst, gt\n\t"
       
 10780             "CSINV  $dst, $dst, ZR, ge" %}
       
 10781   ins_encode %{
       
 10782     Register dst = $dst$$Register;
       
 10783     __ fcmp_s($src1$$FloatRegister, $src2$$FloatRegister);
       
 10784     __ cset(dst, gt);            // 1 if '>', else 0
       
 10785     __ csinv(dst, dst, ZR, ge);  // previous value if '>=', else -1
       
 10786   %}
       
 10787   ins_pipe( floating_cmp ); // FIXME
       
 10788 %}
       
 10789 
       
 10790 // Compare floating, generate -1,0,1
       
 10791 instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsReg icc) %{
       
 10792   match(Set dst (CmpD3 src1 src2));
       
 10793   // effect(KILL fcc); // nobody cares if flagsRegF is killed
       
 10794   effect(KILL icc);
       
 10795   ins_cost(DEFAULT_COST*3); // FIXME
       
 10796   size(12);
       
 10797   format %{ "FCMP_d $src1,$src2\n\t"
       
 10798             "CSET   $dst, gt\n\t"
       
 10799             "CSINV  $dst, $dst, ZR, ge" %}
       
 10800   ins_encode %{
       
 10801     Register dst = $dst$$Register;
       
 10802     __ fcmp_d($src1$$FloatRegister, $src2$$FloatRegister);
       
 10803     __ cset(dst, gt);            // 1 if '>', else 0
       
 10804     __ csinv(dst, dst, ZR, ge);  // previous value if '>=', else -1
       
 10805   %}
       
 10806   ins_pipe( floating_cmp ); // FIXME
       
 10807 %}
       
 10808 
       
 10809 // Compare floating, generate -1,0,1
       
 10810 instruct cmpF0_reg(iRegI dst, regF src1, immF0 src2, flagsReg icc) %{
       
 10811   match(Set dst (CmpF3 src1 src2));
       
 10812   // effect(KILL fcc); // nobody cares if flagsRegF is killed
       
 10813   effect(KILL icc);
       
 10814   ins_cost(DEFAULT_COST*3); // FIXME
       
 10815   size(12);
       
 10816   format %{ "FCMP0_s $src1\n\t"
       
 10817             "CSET   $dst, gt\n\t"
       
 10818             "CSINV  $dst, $dst, ZR, ge" %}
       
 10819   ins_encode %{
       
 10820     Register dst = $dst$$Register;
       
 10821     __ fcmp0_s($src1$$FloatRegister);
       
 10822     __ cset(dst, gt);            // 1 if '>', else 0
       
 10823     __ csinv(dst, dst, ZR, ge);  // previous value if '>=', else -1
       
 10824   %}
       
 10825   ins_pipe( floating_cmp ); // FIXME
       
 10826 %}
       
 10827 
       
 10828 // Compare floating, generate -1,0,1
       
 10829 instruct cmpD0_reg(iRegI dst, regD src1, immD0 src2, flagsReg icc) %{
       
 10830   match(Set dst (CmpD3 src1 src2));
       
 10831   // effect(KILL fcc); // nobody cares if flagsRegF is killed
       
 10832   effect(KILL icc);
       
 10833   ins_cost(DEFAULT_COST*3); // FIXME
       
 10834   size(12);
       
 10835   format %{ "FCMP0_d $src1\n\t"
       
 10836             "CSET   $dst, gt\n\t"
       
 10837             "CSINV  $dst, $dst, ZR, ge" %}
       
 10838   ins_encode %{
       
 10839     Register dst = $dst$$Register;
       
 10840     __ fcmp0_d($src1$$FloatRegister);
       
 10841     __ cset(dst, gt);            // 1 if '>', else 0
       
 10842     __ csinv(dst, dst, ZR, ge);  // previous value if '>=', else -1
       
 10843   %}
       
 10844   ins_pipe( floating_cmp ); // FIXME
       
 10845 %}
       
 10846 #else
       
 10847 // Compare floating, generate -1,0,1
       
 10848 instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsRegF fcc) %{
       
 10849   match(Set dst (CmpF3 src1 src2));
       
 10850   effect(KILL fcc);
       
 10851   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
       
 10852   size(20);
       
 10853   // same number of instructions as code using conditional moves but
       
 10854   // doesn't kill integer condition register
       
 10855   format %{ "FCMPs  $dst,$src1,$src2 \n\t"
       
 10856             "VMRS   $dst, FPSCR \n\t"
       
 10857             "OR     $dst, $dst, 0x08000000 \n\t"
       
 10858             "EOR    $dst, $dst, $dst << 3 \n\t"
       
 10859             "MOV    $dst, $dst >> 30" %}
       
 10860   ins_encode %{
       
 10861     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
       
 10862     __ floating_cmp($dst$$Register);
       
 10863   %}
       
 10864   ins_pipe( floating_cmp );
       
 10865 %}
       
 10866 
       
 10867 instruct cmpF0_reg(iRegI dst, regF src1, immF0 src2, flagsRegF fcc) %{
       
 10868   match(Set dst (CmpF3 src1 src2));
       
 10869   effect(KILL fcc);
       
 10870   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
       
 10871   size(20);
       
 10872   // same number of instructions as code using conditional moves but
       
 10873   // doesn't kill integer condition register
       
 10874   format %{ "FCMPZs $dst,$src1,$src2 \n\t"
       
 10875             "VMRS   $dst, FPSCR \n\t"
       
 10876             "OR     $dst, $dst, 0x08000000 \n\t"
       
 10877             "EOR    $dst, $dst, $dst << 3 \n\t"
       
 10878             "MOV    $dst, $dst >> 30" %}
       
 10879   ins_encode %{
       
 10880     __ fcmpzs($src1$$FloatRegister);
       
 10881     __ floating_cmp($dst$$Register);
       
 10882   %}
       
 10883   ins_pipe( floating_cmp );
       
 10884 %}
       
 10885 
       
 10886 instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsRegF fcc) %{
       
 10887   match(Set dst (CmpD3 src1 src2));
       
 10888   effect(KILL fcc);
       
 10889   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
       
 10890   size(20);
       
 10891   // same number of instructions as code using conditional moves but
       
 10892   // doesn't kill integer condition register
       
 10893   format %{ "FCMPd  $dst,$src1,$src2 \n\t"
       
 10894             "VMRS   $dst, FPSCR \n\t"
       
 10895             "OR     $dst, $dst, 0x08000000 \n\t"
       
 10896             "EOR    $dst, $dst, $dst << 3 \n\t"
       
 10897             "MOV    $dst, $dst >> 30" %}
       
 10898   ins_encode %{
       
 10899     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
       
 10900     __ floating_cmp($dst$$Register);
       
 10901   %}
       
 10902   ins_pipe( floating_cmp );
       
 10903 %}
       
 10904 
       
 10905 instruct cmpD0_reg(iRegI dst, regD src1, immD0 src2, flagsRegF fcc) %{
       
 10906   match(Set dst (CmpD3 src1 src2));
       
 10907   effect(KILL fcc);
       
 10908   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
       
 10909   size(20);
       
 10910   // same number of instructions as code using conditional moves but
       
 10911   // doesn't kill integer condition register
       
 10912   format %{ "FCMPZd $dst,$src1,$src2 \n\t"
       
 10913             "VMRS   $dst, FPSCR \n\t"
       
 10914             "OR     $dst, $dst, 0x08000000 \n\t"
       
 10915             "EOR    $dst, $dst, $dst << 3 \n\t"
       
 10916             "MOV    $dst, $dst >> 30" %}
       
 10917   ins_encode %{
       
 10918     __ fcmpzd($src1$$FloatRegister);
       
 10919     __ floating_cmp($dst$$Register);
       
 10920   %}
       
 10921   ins_pipe( floating_cmp );
       
 10922 %}
       
 10923 #endif // !AARCH64
       
 10924 
       
 10925 //----------Branches---------------------------------------------------------
       
 10926 // Jump
       
 10927 // (compare 'operand indIndex' and 'instruct addP_reg_reg' above)
       
 10928 // FIXME
       
 10929 instruct jumpXtnd(iRegX switch_val, iRegP tmp) %{
       
 10930   match(Jump switch_val);
       
 10931   effect(TEMP tmp);
       
 10932   ins_cost(350);
       
 10933   format %{  "ADD    $tmp, $constanttablebase, $switch_val\n\t"
       
 10934              "LDR    $tmp,[$tmp + $constantoffset]\n\t"
       
 10935              "BX     $tmp" %}
       
 10936   size(20);
       
 10937   ins_encode %{
       
 10938     Register table_reg;
       
 10939     Register label_reg = $tmp$$Register;
       
 10940     if (constant_offset() == 0) {
       
 10941       table_reg = $constanttablebase;
       
 10942       __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
       
 10943     } else {
       
 10944       table_reg = $tmp$$Register;
       
 10945       int offset = $constantoffset;
       
 10946       if (is_memoryP(offset)) {
       
 10947         __ add(table_reg, $constanttablebase, $switch_val$$Register);
       
 10948         __ ldr(label_reg, Address(table_reg, offset));
       
 10949       } else {
       
 10950         __ mov_slow(table_reg, $constantoffset);
       
 10951         __ add(table_reg, $constanttablebase, table_reg);
       
 10952         __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
       
 10953       }
       
 10954     }
       
 10955     __ jump(label_reg); // ldr + b better than ldr to PC for branch predictor?
       
 10956     //    __ ldr(PC, Address($table$$Register, $switch_val$$Register));
       
 10957   %}
       
 10958   ins_pipe(ialu_reg_reg);
       
 10959 %}
       
 10960 
       
 10961 // // Direct Branch.
       
 10962 instruct branch(label labl) %{
       
 10963   match(Goto);
       
 10964   effect(USE labl);
       
 10965 
       
 10966   size(4);
       
 10967   ins_cost(BRANCH_COST);
       
 10968   format %{ "B     $labl" %}
       
 10969   ins_encode %{
       
 10970     __ b(*($labl$$label));
       
 10971   %}
       
 10972   ins_pipe(br);
       
 10973 %}
       
 10974 
       
 10975 // Conditional Direct Branch
       
 10976 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{
       
 10977   match(If cmp icc);
       
 10978   effect(USE labl);
       
 10979 
       
 10980   size(4);
       
 10981   ins_cost(BRANCH_COST);
       
 10982   format %{ "B$cmp   $icc,$labl" %}
       
 10983   ins_encode %{
       
 10984     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
       
 10985   %}
       
 10986   ins_pipe(br_cc);
       
 10987 %}
       
 10988 
       
 10989 #ifdef ARM
       
 10990 instruct branchCon_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, label labl) %{
       
 10991   match(If cmp icc);
       
 10992   effect(USE labl);
       
 10993   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);
       
 10994 
       
 10995   size(4);
       
 10996   ins_cost(BRANCH_COST);
       
 10997   format %{ "B$cmp   $icc,$labl" %}
       
 10998   ins_encode %{
       
 10999     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
       
 11000   %}
       
 11001   ins_pipe(br_cc);
       
 11002 %}
       
 11003 #endif
       
 11004 
       
 11005 #ifdef AARCH64
       
 11006 instruct cbzI(cmpOp cmp, iRegI op1, immI0 op2, label labl) %{
       
 11007   match(If cmp (CmpI op1 op2));
       
 11008   effect(USE labl);
       
 11009   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
       
 11010             _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
       
 11011   size(4);
       
 11012   ins_cost(BRANCH_COST);
       
 11013   format %{ "CB{N}Z $op1, $labl\t! int $cmp" %}
       
 11014   ins_encode %{
       
 11015     if ($cmp$$cmpcode == eq) {
       
 11016       __ cbz_w($op1$$Register, *($labl$$label));
       
 11017     } else {
       
 11018       __ cbnz_w($op1$$Register, *($labl$$label));
       
 11019     }
       
 11020   %}
       
 11021   ins_pipe(br_cc); // FIXME
       
 11022 %}
       
 11023 
       
 11024 instruct cbzP(cmpOpP cmp, iRegP op1, immP0 op2, label labl) %{
       
 11025   match(If cmp (CmpP op1 op2));
       
 11026   effect(USE labl);
       
 11027   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
       
 11028             _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
       
 11029   size(4);
       
 11030   ins_cost(BRANCH_COST);
       
 11031   format %{ "CB{N}Z $op1, $labl\t! ptr $cmp" %}
       
 11032   ins_encode %{
       
 11033     if ($cmp$$cmpcode == eq) {
       
 11034       __ cbz($op1$$Register, *($labl$$label));
       
 11035     } else {
       
 11036       __ cbnz($op1$$Register, *($labl$$label));
       
 11037     }
       
 11038   %}
       
 11039   ins_pipe(br_cc); // FIXME
       
 11040 %}
       
 11041 
       
 11042 instruct cbzL(cmpOpL cmp, iRegL op1, immL0 op2, label labl) %{
       
 11043   match(If cmp (CmpL op1 op2));
       
 11044   effect(USE labl);
       
 11045   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
       
 11046             _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
       
 11047   size(4);
       
 11048   ins_cost(BRANCH_COST);
       
 11049   format %{ "CB{N}Z $op1, $labl\t! long $cmp" %}
       
 11050   ins_encode %{
       
 11051     if ($cmp$$cmpcode == eq) {
       
 11052       __ cbz($op1$$Register, *($labl$$label));
       
 11053     } else {
       
 11054       __ cbnz($op1$$Register, *($labl$$label));
       
 11055     }
       
 11056   %}
       
 11057   ins_pipe(br_cc); // FIXME
       
 11058 %}
       
 11059 #endif
       
 11060 
       
 11061 instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{
       
 11062   match(If cmp icc);
       
 11063   effect(USE labl);
       
 11064 
       
 11065   size(4);
       
 11066   ins_cost(BRANCH_COST);
       
 11067   format %{ "B$cmp  $icc,$labl" %}
       
 11068   ins_encode %{
       
 11069     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
       
 11070   %}
       
 11071   ins_pipe(br_cc);
       
 11072 %}
       
 11073 
       
 11074 instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{
       
 11075   match(If cmp pcc);
       
 11076   effect(USE labl);
       
 11077 
       
 11078   size(4);
       
 11079   ins_cost(BRANCH_COST);
       
 11080   format %{ "B$cmp  $pcc,$labl" %}
       
 11081   ins_encode %{
       
 11082     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
       
 11083   %}
       
 11084   ins_pipe(br_cc);
       
 11085 %}
       
 11086 
       
 11087 #ifndef AARCH64
       
 11088 instruct branchConL_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, label labl) %{
       
 11089   match(If cmp xcc);
       
 11090   effect(USE labl);
       
 11091   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
       
 11092 
       
 11093   size(4);
       
 11094   ins_cost(BRANCH_COST);
       
 11095   format %{ "B$cmp  $xcc,$labl" %}
       
 11096   ins_encode %{
       
 11097     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
       
 11098   %}
       
 11099   ins_pipe(br_cc);
       
 11100 %}
       
 11101 
       
 11102 instruct branchConL_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, label labl) %{
       
 11103   match(If cmp xcc);
       
 11104   effect(USE labl);
       
 11105   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
       
 11106 
       
 11107   size(4);
       
 11108   ins_cost(BRANCH_COST);
       
 11109   format %{ "B$cmp  $xcc,$labl" %}
       
 11110   ins_encode %{
       
 11111     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
       
 11112   %}
       
 11113   ins_pipe(br_cc);
       
 11114 %}
       
 11115 
       
 11116 instruct branchConL_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, label labl) %{
       
 11117   match(If cmp xcc);
       
 11118   effect(USE labl);
       
 11119   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le );
       
 11120 
       
 11121   size(4);
       
 11122   ins_cost(BRANCH_COST);
       
 11123   format %{ "B$cmp  $xcc,$labl" %}
       
 11124   ins_encode %{
       
 11125     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
       
 11126   %}
       
 11127   ins_pipe(br_cc);
       
 11128 %}
       
 11129 #endif
       
 11130 
       
 11131 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
       
 11132   match(CountedLoopEnd cmp icc);
       
 11133   effect(USE labl);
       
 11134 
       
 11135   size(4);
       
 11136   ins_cost(BRANCH_COST);
       
 11137   format %{ "B$cmp   $icc,$labl\t! Loop end" %}
       
 11138   ins_encode %{
       
 11139     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
       
 11140   %}
       
 11141   ins_pipe(br_cc);
       
 11142 %}
       
 11143 
       
 11144 // instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{
       
 11145 //   match(CountedLoopEnd cmp icc);
       
 11146 //   ins_pipe(br_cc);
       
 11147 // %}
       
 11148 
       
 11149 // ============================================================================
       
 11150 // Long Compare
       
 11151 //
       
 11152 // Currently we hold longs in 2 registers.  Comparing such values efficiently
       
 11153 // is tricky.  The flavor of compare used depends on whether we are testing
       
 11154 // for LT, LE, or EQ.  For a simple LT test we can check just the sign bit.
       
 11155 // The GE test is the negated LT test.  The LE test can be had by commuting
       
 11156 // the operands (yielding a GE test) and then negating; negate again for the
       
 11157 // GT test.  The EQ test is done by ORcc'ing the high and low halves, and the
       
 11158 // NE test is negated from that.
       
 11159 
       
 11160 // Due to a shortcoming in the ADLC, it mixes up expressions like:
       
 11161 // (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)).  Note the
       
 11162 // difference between 'Y' and '0L'.  The tree-matches for the CmpI sections
       
 11163 // are collapsed internally in the ADLC's dfa-gen code.  The match for
       
 11164 // (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the
       
 11165 // foo match ends up with the wrong leaf.  One fix is to not match both
       
 11166 // reg-reg and reg-zero forms of long-compare.  This is unfortunate because
       
 11167 // both forms beat the trinary form of long-compare and both are very useful
       
 11168 // on Intel which has so few registers.
       
 11169 
       
 11170 // instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{
       
 11171 //   match(If cmp xcc);
       
 11172 //   ins_pipe(br_cc);
       
 11173 // %}
       
 11174 
       
 11175 // Manifest a CmpL3 result in an integer register.  Very painful.
       
 11176 // This is the test to avoid.
       
 11177 #ifdef AARCH64
       
 11178 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr) %{
       
 11179   match(Set dst (CmpL3 src1 src2));
       
 11180   // effect(KILL fcc); // nobody cares if flagsRegF is killed
       
 11181   effect(KILL ccr);
       
 11182   ins_cost(DEFAULT_COST*3); // FIXME
       
 11183   size(12);
       
 11184   format %{ "CMP    $src1,$src2\n\t"
       
 11185             "CSET   $dst, gt\n\t"
       
 11186             "CSINV  $dst, $dst, ZR, ge" %}
       
 11187   ins_encode %{
       
 11188     Register dst = $dst$$Register;
       
 11189     __ cmp($src1$$Register, $src2$$Register);
       
 11190     __ cset(dst, gt);            // 1 if '>', else 0
       
 11191     __ csinv(dst, dst, ZR, ge);  // previous value if '>=', else -1
       
 11192   %}
       
 11193   ins_pipe( ialu_cconly_reg_reg ); // FIXME
       
 11194 %}
       
 11195 // TODO cmpL3_reg_imm
       
 11196 #else
       
 11197 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
       
 11198   match(Set dst (CmpL3 src1 src2) );
       
 11199   effect( KILL ccr );
       
 11200   ins_cost(6*DEFAULT_COST); // FIXME
       
 11201   size(32);
       
 11202   format %{
       
 11203       "CMP    $src1.hi, $src2.hi\t\t! long\n"
       
 11204     "\tMOV.gt $dst, 1\n"
       
 11205     "\tmvn.lt $dst, 0\n"
       
 11206     "\tB.ne   done\n"
       
 11207     "\tSUBS   $dst, $src1.lo, $src2.lo\n"
       
 11208     "\tMOV.hi $dst, 1\n"
       
 11209     "\tmvn.lo $dst, 0\n"
       
 11210     "done:"     %}
       
 11211   ins_encode %{
       
 11212     Label done;
       
 11213     __ cmp($src1$$Register->successor(), $src2$$Register->successor());
       
 11214     __ mov($dst$$Register, 1, gt);
       
 11215     __ mvn($dst$$Register, 0, lt);
       
 11216     __ b(done, ne);
       
 11217     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
       
 11218     __ mov($dst$$Register, 1, hi);
       
 11219     __ mvn($dst$$Register, 0, lo);
       
 11220     __ bind(done);
       
 11221   %}
       
 11222   ins_pipe(cmpL_reg);
       
 11223 %}
       
 11224 #endif
       
 11225 
       
 11226 #ifndef AARCH64
       
 11227 // Conditional move
       
 11228 instruct cmovLL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, iRegL src) %{
       
 11229   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
       
 11230   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
       
 11231 
       
 11232   ins_cost(150);
       
 11233   size(8);
       
 11234   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
       
 11235             "MOV$cmp  $dst,$src.hi" %}
       
 11236   ins_encode %{
       
 11237     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
 11238     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
       
 11239   %}
       
 11240   ins_pipe(ialu_reg);
       
 11241 %}
       
 11242 
       
 11243 instruct cmovLL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, iRegL src) %{
       
 11244   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
       
 11245   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
       
 11246 
       
 11247   ins_cost(150);
       
 11248   size(8);
       
 11249   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
       
 11250             "MOV$cmp  $dst,$src.hi" %}
       
 11251   ins_encode %{
       
 11252     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
 11253     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
       
 11254   %}
       
 11255   ins_pipe(ialu_reg);
       
 11256 %}
       
 11257 
       
 11258 instruct cmovLL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, iRegL src) %{
       
 11259   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
       
 11260   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
       
 11261 
       
 11262   ins_cost(150);
       
 11263   size(8);
       
 11264   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
       
 11265             "MOV$cmp  $dst,$src.hi" %}
       
 11266   ins_encode %{
       
 11267     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
 11268     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
       
 11269   %}
       
 11270   ins_pipe(ialu_reg);
       
 11271 %}
       
 11272 
       
 11273 instruct cmovLL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, immL0 src) %{
       
 11274   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
       
 11275   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
       
 11276   ins_cost(140);
       
 11277   size(8);
       
 11278   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
       
 11279             "MOV$cmp  $dst,0" %}
       
 11280   ins_encode %{
       
 11281     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
       
 11282     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
       
 11283   %}
       
 11284   ins_pipe(ialu_imm);
       
 11285 %}
       
 11286 
       
 11287 instruct cmovLL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, immL0 src) %{
       
 11288   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
       
 11289   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
       
 11290   ins_cost(140);
       
 11291   size(8);
       
 11292   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
       
 11293             "MOV$cmp  $dst,0" %}
       
 11294   ins_encode %{
       
 11295     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
       
 11296     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
       
 11297   %}
       
 11298   ins_pipe(ialu_imm);
       
 11299 %}
       
 11300 
       
 11301 instruct cmovLL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, immL0 src) %{
       
 11302   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
       
 11303   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
       
 11304   ins_cost(140);
       
 11305   size(8);
       
 11306   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
       
 11307             "MOV$cmp  $dst,0" %}
       
 11308   ins_encode %{
       
 11309     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
       
 11310     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
       
 11311   %}
       
 11312   ins_pipe(ialu_imm);
       
 11313 %}
       
 11314 #endif // !AARCH64
       
 11315 
       
 11316 #ifndef AARCH64
       
 11317 instruct cmovIL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, iRegI src) %{
       
 11318   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
       
 11319   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
       
 11320 
       
 11321   ins_cost(150);
       
 11322   size(4);
       
 11323   format %{ "MOV$cmp  $dst,$src" %}
       
 11324   ins_encode %{
       
 11325     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
 11326   %}
       
 11327   ins_pipe(ialu_reg);
       
 11328 %}
       
 11329 
       
 11330 instruct cmovIL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, iRegI src) %{
       
 11331   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
       
 11332   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
       
 11333 
       
 11334   ins_cost(150);
       
 11335   size(4);
       
 11336   format %{ "MOV$cmp  $dst,$src" %}
       
 11337   ins_encode %{
       
 11338     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
 11339   %}
       
 11340   ins_pipe(ialu_reg);
       
 11341 %}
       
 11342 
       
 11343 instruct cmovIL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, iRegI src) %{
       
 11344   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
       
 11345   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
       
 11346 
       
 11347   ins_cost(150);
       
 11348   size(4);
       
 11349   format %{ "MOV$cmp  $dst,$src" %}
       
 11350   ins_encode %{
       
 11351     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
 11352   %}
       
 11353   ins_pipe(ialu_reg);
       
 11354 %}
       
 11355 #endif // !AARCH64
       
 11356 
       
 11357 #ifndef AARCH64
       
 11358 instruct cmovIL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immI16 src) %{
       
 11359   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
       
 11360   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
       
 11361 
       
 11362   ins_cost(140);
       
 11363   format %{ "MOVW$cmp  $dst,$src" %}
       
 11364   ins_encode %{
       
 11365     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
 11366   %}
       
 11367   ins_pipe(ialu_imm);
       
 11368 %}
       
 11369 
       
 11370 instruct cmovIL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, immI16 src) %{
       
 11371   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
       
 11372   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
       
 11373 
       
 11374   ins_cost(140);
       
 11375   format %{ "MOVW$cmp  $dst,$src" %}
       
 11376   ins_encode %{
       
 11377     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
 11378   %}
       
 11379   ins_pipe(ialu_imm);
       
 11380 %}
       
 11381 
       
 11382 instruct cmovIL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immI16 src) %{
       
 11383   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
       
 11384   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
       
 11385 
       
 11386   ins_cost(140);
       
 11387   format %{ "MOVW$cmp  $dst,$src" %}
       
 11388   ins_encode %{
       
 11389     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
 11390   %}
       
 11391   ins_pipe(ialu_imm);
       
 11392 %}
       
 11393 
       
 11394 instruct cmovPL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, iRegP src) %{
       
 11395   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
       
 11396   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
       
 11397 
       
 11398   ins_cost(150);
       
 11399   size(4);
       
 11400   format %{ "MOV$cmp  $dst,$src" %}
       
 11401   ins_encode %{
       
 11402     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
 11403   %}
       
 11404   ins_pipe(ialu_reg);
       
 11405 %}
       
 11406 
       
 11407 instruct cmovPL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, iRegP src) %{
       
 11408   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
       
 11409   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
       
 11410 
       
 11411   ins_cost(150);
       
 11412   size(4);
       
 11413   format %{ "MOV$cmp  $dst,$src" %}
       
 11414   ins_encode %{
       
 11415     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
 11416   %}
       
 11417   ins_pipe(ialu_reg);
       
 11418 %}
       
 11419 
       
 11420 instruct cmovPL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, iRegP src) %{
       
 11421   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
       
 11422   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
       
 11423 
       
 11424   ins_cost(150);
       
 11425   size(4);
       
 11426   format %{ "MOV$cmp  $dst,$src" %}
       
 11427   ins_encode %{
       
 11428     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
       
 11429   %}
       
 11430   ins_pipe(ialu_reg);
       
 11431 %}
       
 11432 
       
 11433 instruct cmovPL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, immP0 src) %{
       
 11434   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
       
 11435   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
       
 11436 
       
 11437   ins_cost(140);
       
 11438   format %{ "MOVW$cmp  $dst,$src" %}
       
 11439   ins_encode %{
       
 11440     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
 11441   %}
       
 11442   ins_pipe(ialu_imm);
       
 11443 %}
       
 11444 
       
 11445 instruct cmovPL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, immP0 src) %{
       
 11446   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
       
 11447   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
       
 11448 
       
 11449   ins_cost(140);
       
 11450   format %{ "MOVW$cmp  $dst,$src" %}
       
 11451   ins_encode %{
       
 11452     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
 11453   %}
       
 11454   ins_pipe(ialu_imm);
       
 11455 %}
       
 11456 
       
 11457 instruct cmovPL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, immP0 src) %{
       
 11458   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
       
 11459   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
       
 11460 
       
 11461   ins_cost(140);
       
 11462   format %{ "MOVW$cmp  $dst,$src" %}
       
 11463   ins_encode %{
       
 11464     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
       
 11465   %}
       
 11466   ins_pipe(ialu_imm);
       
 11467 %}
       
 11468 
       
 11469 instruct cmovFL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regF dst, regF src) %{
       
 11470   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
       
 11471   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
       
 11472   ins_cost(150);
       
 11473   size(4);
       
 11474   format %{ "FCPYS$cmp $dst,$src" %}
       
 11475   ins_encode %{
       
 11476     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
 11477   %}
       
 11478   ins_pipe(int_conditional_float_move);
       
 11479 %}
       
 11480 
       
 11481 instruct cmovFL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regF dst, regF src) %{
       
 11482   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
       
 11483   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
       
 11484   ins_cost(150);
       
 11485   size(4);
       
 11486   format %{ "FCPYS$cmp $dst,$src" %}
       
 11487   ins_encode %{
       
 11488     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
 11489   %}
       
 11490   ins_pipe(int_conditional_float_move);
       
 11491 %}
       
 11492 
       
 11493 instruct cmovFL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regF dst, regF src) %{
       
 11494   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
       
 11495   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
       
 11496   ins_cost(150);
       
 11497   size(4);
       
 11498   format %{ "FCPYS$cmp $dst,$src" %}
       
 11499   ins_encode %{
       
 11500     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
 11501   %}
       
 11502   ins_pipe(int_conditional_float_move);
       
 11503 %}
       
 11504 
       
 11505 instruct cmovDL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regD dst, regD src) %{
       
 11506   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
       
 11507   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
       
 11508 
       
 11509   ins_cost(150);
       
 11510   size(4);
       
 11511   format %{ "FCPYD$cmp $dst,$src" %}
       
 11512   ins_encode %{
       
 11513     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
 11514   %}
       
 11515   ins_pipe(int_conditional_float_move);
       
 11516 %}
       
 11517 
       
 11518 instruct cmovDL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regD dst, regD src) %{
       
 11519   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
       
 11520   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
       
 11521 
       
 11522   ins_cost(150);
       
 11523   size(4);
       
 11524   format %{ "FCPYD$cmp $dst,$src" %}
       
 11525   ins_encode %{
       
 11526     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
 11527   %}
       
 11528   ins_pipe(int_conditional_float_move);
       
 11529 %}
       
 11530 
       
 11531 instruct cmovDL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regD dst, regD src) %{
       
 11532   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
       
 11533   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
       
 11534 
       
 11535   ins_cost(150);
       
 11536   size(4);
       
 11537   format %{ "FCPYD$cmp $dst,$src" %}
       
 11538   ins_encode %{
       
 11539     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
       
 11540   %}
       
 11541   ins_pipe(int_conditional_float_move);
       
 11542 %}
       
 11543 #endif // !AARCH64
       
 11544 
       
 11545 // ============================================================================
       
 11546 // Safepoint Instruction
       
 11547 #ifdef AARCH64
       
 11548 instruct safePoint_poll(iRegP poll, flagsReg icc, RtempRegP tmp) %{
       
 11549   match(SafePoint poll);
       
 11550   // The handler stub kills Rtemp
       
 11551   effect(USE poll, KILL tmp, KILL icc);
       
 11552 
       
 11553   size(4);
       
 11554   format %{ "LDR   ZR,[$poll]\t! Safepoint: poll for GC" %}
       
 11555   ins_encode %{
       
 11556     __ relocate(relocInfo::poll_type);
       
 11557     __ ldr(ZR, Address($poll$$Register));
       
 11558   %}
       
 11559   ins_pipe(loadPollP);
       
 11560 %}
       
 11561 #else
       
 11562 // rather than KILL R12, it would be better to use any reg as
       
 11563 // TEMP. Can't do that at this point because it crashes the compiler
       
 11564 instruct safePoint_poll(iRegP poll, R12RegI tmp, flagsReg icc) %{
       
 11565   match(SafePoint poll);
       
 11566   effect(USE poll, KILL tmp, KILL icc);
       
 11567 
       
 11568   size(4);
       
 11569   format %{ "LDR   $tmp,[$poll]\t! Safepoint: poll for GC" %}
       
 11570   ins_encode %{
       
 11571     __ relocate(relocInfo::poll_type);
       
 11572     __ ldr($tmp$$Register, Address($poll$$Register));
       
 11573   %}
       
 11574   ins_pipe(loadPollP);
       
 11575 %}
       
 11576 #endif
       
 11577 
       
 11578 
       
 11579 // ============================================================================
       
 11580 // Call Instructions
       
 11581 // Call Java Static Instruction
       
 11582 instruct CallStaticJavaDirect( method meth ) %{
       
 11583   match(CallStaticJava);
       
 11584   predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke());
       
 11585   effect(USE meth);
       
 11586 
       
 11587   ins_cost(CALL_COST);
       
 11588   format %{ "CALL,static ==> " %}
       
 11589   ins_encode( Java_Static_Call( meth ), call_epilog );
       
 11590   ins_pipe(simple_call);
       
 11591 %}
       
 11592 
       
 11593 // Call Java Static Instruction (method handle version)
       
 11594 instruct CallStaticJavaHandle( method meth ) %{
       
 11595   match(CallStaticJava);
       
 11596   predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke());
       
 11597   effect(USE meth);
       
 11598   // FP is saved by all callees (for interpreter stack correction).
       
 11599   // We use it here for a similar purpose, in {preserve,restore}_FP.
       
 11600 
       
 11601   ins_cost(CALL_COST);
       
 11602   format %{ "CALL,static/MethodHandle ==> " %}
       
 11603   ins_encode( preserve_SP, Java_Static_Call( meth ), restore_SP, call_epilog );
       
 11604   ins_pipe(simple_call);
       
 11605 %}
       
 11606 
       
 11607 // Call Java Dynamic Instruction
       
 11608 instruct CallDynamicJavaDirect( method meth ) %{
       
 11609   match(CallDynamicJava);
       
 11610   effect(USE meth);
       
 11611 
       
 11612   ins_cost(CALL_COST);
       
 11613   format %{ "MOV_OOP    (empty),R_R8\n\t"
       
 11614             "CALL,dynamic  ; NOP ==> " %}
       
 11615   ins_encode( Java_Dynamic_Call( meth ), call_epilog );
       
 11616   ins_pipe(call);
       
 11617 %}
       
 11618 
       
 11619 // Call Runtime Instruction
       
 11620 instruct CallRuntimeDirect(method meth) %{
       
 11621   match(CallRuntime);
       
 11622   effect(USE meth);
       
 11623   ins_cost(CALL_COST);
       
 11624   format %{ "CALL,runtime" %}
       
 11625 #ifdef AARCH64
       
 11626   ins_encode( save_last_PC, Java_To_Runtime( meth ),
       
 11627               call_epilog );
       
 11628 #else
       
 11629   ins_encode( Java_To_Runtime( meth ),
       
 11630               call_epilog );
       
 11631 #endif
       
 11632   ins_pipe(simple_call);
       
 11633 %}
       
 11634 
       
 11635 // Call runtime without safepoint - same as CallRuntime
       
 11636 instruct CallLeafDirect(method meth) %{
       
 11637   match(CallLeaf);
       
 11638   effect(USE meth);
       
 11639   ins_cost(CALL_COST);
       
 11640   format %{ "CALL,runtime leaf" %}
       
 11641   // TODO: ned save_last_PC here?
       
 11642   ins_encode( Java_To_Runtime( meth ),
       
 11643               call_epilog );
       
 11644   ins_pipe(simple_call);
       
 11645 %}
       
 11646 
       
 11647 // Call runtime without safepoint - same as CallLeaf
       
 11648 instruct CallLeafNoFPDirect(method meth) %{
       
 11649   match(CallLeafNoFP);
       
 11650   effect(USE meth);
       
 11651   ins_cost(CALL_COST);
       
 11652   format %{ "CALL,runtime leaf nofp" %}
       
 11653   // TODO: ned save_last_PC here?
       
 11654   ins_encode( Java_To_Runtime( meth ),
       
 11655               call_epilog );
       
 11656   ins_pipe(simple_call);
       
 11657 %}
       
 11658 
       
 11659 // Tail Call; Jump from runtime stub to Java code.
       
 11660 // Also known as an 'interprocedural jump'.
       
 11661 // Target of jump will eventually return to caller.
       
 11662 // TailJump below removes the return address.
       
 11663 instruct TailCalljmpInd(IPRegP jump_target, inline_cache_regP method_oop) %{
       
 11664   match(TailCall jump_target method_oop );
       
 11665 
       
 11666   ins_cost(CALL_COST);
       
 11667   format %{ "MOV    Rexception_pc, LR\n\t"
       
 11668             "jump   $jump_target  \t! $method_oop holds method oop" %}
       
 11669   ins_encode %{
       
 11670     __ mov(Rexception_pc, LR);   // this is used only to call
       
 11671                                  // StubRoutines::forward_exception_entry()
       
 11672                                  // which expects PC of exception in
       
 11673                                  // R5. FIXME?
       
 11674     __ jump($jump_target$$Register);
       
 11675   %}
       
 11676   ins_pipe(tail_call);
       
 11677 %}
       
 11678 
       
 11679 
       
 11680 // Return Instruction
       
 11681 instruct Ret() %{
       
 11682   match(Return);
       
 11683 
       
 11684   format %{ "ret LR" %}
       
 11685 
       
 11686   ins_encode %{
       
 11687     __ ret(LR);
       
 11688   %}
       
 11689 
       
 11690   ins_pipe(br);
       
 11691 %}
       
 11692 
       
 11693 
       
 11694 // Tail Jump; remove the return address; jump to target.
       
 11695 // TailCall above leaves the return address around.
       
 11696 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
       
 11697 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
       
 11698 // "restore" before this instruction (in Epilogue), we need to materialize it
       
 11699 // in %i0.
       
 11700 instruct tailjmpInd(IPRegP jump_target, RExceptionRegP ex_oop) %{
       
 11701   match( TailJump jump_target ex_oop );
       
 11702   ins_cost(CALL_COST);
       
 11703   format %{ "MOV    Rexception_pc, LR\n\t"
       
 11704             "jump   $jump_target \t! $ex_oop holds exc. oop" %}
       
 11705   ins_encode %{
       
 11706     __ mov(Rexception_pc, LR);
       
 11707     __ jump($jump_target$$Register);
       
 11708   %}
       
 11709   ins_pipe(tail_call);
       
 11710 %}
       
 11711 
       
 11712 // Create exception oop: created by stack-crawling runtime code.
       
 11713 // Created exception is now available to this handler, and is setup
       
 11714 // just prior to jumping to this handler.  No code emitted.
       
 11715 instruct CreateException( RExceptionRegP ex_oop )
       
 11716 %{
       
 11717   match(Set ex_oop (CreateEx));
       
 11718   ins_cost(0);
       
 11719 
       
 11720   size(0);
       
 11721   // use the following format syntax
       
 11722   format %{ "! exception oop is in Rexception_obj; no code emitted" %}
       
 11723   ins_encode();
       
 11724   ins_pipe(empty);
       
 11725 %}
       
 11726 
       
 11727 
       
 11728 // Rethrow exception:
       
 11729 // The exception oop will come in the first argument position.
       
 11730 // Then JUMP (not call) to the rethrow stub code.
       
 11731 instruct RethrowException()
       
 11732 %{
       
 11733   match(Rethrow);
       
 11734   ins_cost(CALL_COST);
       
 11735 
       
 11736   // use the following format syntax
       
 11737   format %{ "b    rethrow_stub" %}
       
 11738   ins_encode %{
       
 11739     Register scratch = R1_tmp;
       
 11740     assert_different_registers(scratch, c_rarg0, LR);
       
 11741     __ jump(OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type, scratch);
       
 11742   %}
       
 11743   ins_pipe(tail_call);
       
 11744 %}
       
 11745 
       
 11746 
       
 11747 // Die now
       
 11748 instruct ShouldNotReachHere( )
       
 11749 %{
       
 11750   match(Halt);
       
 11751   ins_cost(CALL_COST);
       
 11752 
       
 11753   size(4);
       
 11754   // Use the following format syntax
       
 11755   format %{ "breakpoint   ; ShouldNotReachHere" %}
       
 11756   ins_encode %{
       
 11757     __ breakpoint();
       
 11758   %}
       
 11759   ins_pipe(tail_call);
       
 11760 %}
       
 11761 
       
 11762 // ============================================================================
       
 11763 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
       
 11764 // array for an instance of the superklass.  Set a hidden internal cache on a
       
 11765 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
       
 11766 // not zero for a miss or zero for a hit.  The encoding ALSO sets flags.
       
 11767 instruct partialSubtypeCheck( R0RegP index, R1RegP sub, R2RegP super, flagsRegP pcc, LRRegP lr ) %{
       
 11768   match(Set index (PartialSubtypeCheck sub super));
       
 11769   effect( KILL pcc, KILL lr );
       
 11770   ins_cost(DEFAULT_COST*10);
       
 11771   format %{ "CALL   PartialSubtypeCheck" %}
       
 11772   ins_encode %{
       
 11773     __ call(StubRoutines::Arm::partial_subtype_check(), relocInfo::runtime_call_type);
       
 11774   %}
       
 11775   ins_pipe(partial_subtype_check_pipe);
       
 11776 %}
       
 11777 
       
 11778 /* instruct partialSubtypeCheck_vs_zero( flagsRegP pcc, o1RegP sub, o2RegP super, immP0 zero, o0RegP idx, o7RegP o7 ) %{ */
       
 11779 /*   match(Set pcc (CmpP (PartialSubtypeCheck sub super) zero)); */
       
 11780 /*   ins_pipe(partial_subtype_check_pipe); */
       
 11781 /* %} */
       
 11782 
       
 11783 
       
 11784 // ============================================================================
       
 11785 // inlined locking and unlocking
       
 11786 
       
 11787 #ifdef AARCH64
       
 11788 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch, iRegP scratch3 )
       
 11789 #else
       
 11790 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch )
       
 11791 #endif
       
 11792 %{
       
 11793   match(Set pcc (FastLock object box));
       
 11794 
       
 11795 #ifdef AARCH64
       
 11796   effect(TEMP scratch, TEMP scratch2, TEMP scratch3);
       
 11797 #else
       
 11798   effect(TEMP scratch, TEMP scratch2);
       
 11799 #endif
       
 11800   ins_cost(100);
       
 11801 
       
 11802 #ifdef AARCH64
       
 11803   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2, $scratch3" %}
       
 11804   ins_encode %{
       
 11805     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register, $scratch3$$Register);
       
 11806   %}
       
 11807 #else
       
 11808   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2" %}
       
 11809   ins_encode %{
       
 11810     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
       
 11811   %}
       
 11812 #endif
       
 11813   ins_pipe(long_memory_op);
       
 11814 %}
       
 11815 
       
 11816 
       
 11817 #ifdef AARCH64
       
 11818 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch, iRegP scratch3 ) %{
       
 11819   match(Set pcc (FastUnlock object box));
       
 11820   effect(TEMP scratch, TEMP scratch2, TEMP scratch3);
       
 11821   ins_cost(100);
       
 11822 
       
 11823   format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2, $scratch3" %}
       
 11824   ins_encode %{
       
 11825     __ fast_unlock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register, $scratch3$$Register);
       
 11826   %}
       
 11827   ins_pipe(long_memory_op);
       
 11828 %}
       
 11829 #else
       
 11830 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch ) %{
       
 11831   match(Set pcc (FastUnlock object box));
       
 11832   effect(TEMP scratch, TEMP scratch2);
       
 11833   ins_cost(100);
       
 11834 
       
 11835   format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2" %}
       
 11836   ins_encode %{
       
 11837     __ fast_unlock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
       
 11838   %}
       
 11839   ins_pipe(long_memory_op);
       
 11840 %}
       
 11841 #endif
       
 11842 
       
 11843 #ifdef AARCH64
       
 11844 // TODO: add version that takes immI cnt?
       
 11845 instruct clear_array(iRegX cnt, iRegP base, iRegP ptr, iRegX temp, Universe dummy, flagsReg cpsr) %{
       
 11846   match(Set dummy (ClearArray cnt base));
       
 11847   effect(TEMP temp, TEMP ptr, KILL cpsr);
       
 11848   ins_cost(300);
       
 11849   format %{
       
 11850       "        MOV    $temp,$cnt\n"
       
 11851       "        ADD    $ptr,$base,$cnt\n"
       
 11852       "        SUBS   $temp,$temp,16\t! Count down dword pair in bytes\n"
       
 11853       "        B.lt   done16\n"
       
 11854       "loop:   STP    ZR,ZR,[$ptr,-16]!\n"
       
 11855       "        SUBS   $temp,$temp,16\t! Count down dword pair in bytes\n"
       
 11856       "        B.ge   loop\t! Clearing loop\n"
       
 11857       "done16: ADDS   $temp,$temp,8\t! Room for 1 more long?\n"
       
 11858       "        B.lt   done\n"
       
 11859       "        STR    ZR,[$base+$temp]\n"
       
 11860       "done:"
       
 11861   %}
       
 11862   ins_encode %{
       
 11863     // TODO: preload?
       
 11864     __ mov($temp$$Register, $cnt$$Register);
       
 11865     __ add($ptr$$Register, $base$$Register, $cnt$$Register);
       
 11866     Label loop, done, done16;
       
 11867     __ subs($temp$$Register, $temp$$Register, 16);
       
 11868     __ b(done16, lt);
       
 11869     __ bind(loop);
       
 11870     __ stp(ZR, ZR, Address($ptr$$Register, -16, pre_indexed));
       
 11871     __ subs($temp$$Register, $temp$$Register, 16);
       
 11872     __ b(loop, ge);
       
 11873     __ bind(done16);
       
 11874     __ adds($temp$$Register, $temp$$Register, 8);
       
 11875     __ b(done, lt);
       
 11876     // $temp should be 0 here
       
 11877     __ str(ZR, Address($base$$Register, $temp$$Register));
       
 11878     __ bind(done);
       
 11879   %}
       
 11880   ins_pipe(long_memory_op);
       
 11881 %}
       
 11882 #else
       
 11883 // Count and Base registers are fixed because the allocator cannot
       
 11884 // kill unknown registers.  The encodings are generic.
       
 11885 instruct clear_array(iRegX cnt, iRegP base, iRegI temp, iRegX zero, Universe dummy, flagsReg cpsr) %{
       
 11886   match(Set dummy (ClearArray cnt base));
       
 11887   effect(TEMP temp, TEMP zero, KILL cpsr);
       
 11888   ins_cost(300);
       
 11889   format %{ "MOV    $zero,0\n"
       
 11890       "        MOV    $temp,$cnt\n"
       
 11891       "loop:   SUBS   $temp,$temp,4\t! Count down a dword of bytes\n"
       
 11892       "        STR.ge $zero,[$base+$temp]\t! delay slot"
       
 11893       "        B.gt   loop\t\t! Clearing loop\n" %}
       
 11894   ins_encode %{
       
 11895     __ mov($zero$$Register, 0);
       
 11896     __ mov($temp$$Register, $cnt$$Register);
       
 11897     Label(loop);
       
 11898     __ bind(loop);
       
 11899     __ subs($temp$$Register, $temp$$Register, 4);
       
 11900     __ str($zero$$Register, Address($base$$Register, $temp$$Register), ge);
       
 11901     __ b(loop, gt);
       
 11902   %}
       
 11903   ins_pipe(long_memory_op);
       
 11904 %}
       
 11905 #endif
       
 11906 
       
 11907 #ifdef XXX
       
 11908 // FIXME: Why R0/R1/R2/R3?
       
 11909 instruct string_compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result,
       
 11910                         iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
       
 11911   predicate(!CompactStrings);
       
 11912   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
       
 11913   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, TEMP tmp1, TEMP tmp2);
       
 11914   ins_cost(300);
       
 11915   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // TEMP $tmp1, $tmp2" %}
       
 11916   ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result, tmp1, tmp2) );
       
 11917 
       
 11918   ins_pipe(long_memory_op);
       
 11919 %}
       
 11920 
       
 11921 // FIXME: Why R0/R1/R2?
       
 11922 instruct string_equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2,
       
 11923                        flagsReg ccr) %{
       
 11924   predicate(!CompactStrings);
       
 11925   match(Set result (StrEquals (Binary str1 str2) cnt));
       
 11926   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp1, TEMP tmp2, TEMP result, KILL ccr);
       
 11927 
       
 11928   ins_cost(300);
       
 11929   format %{ "String Equals $str1,$str2,$cnt -> $result   // TEMP $tmp1, $tmp2" %}
       
 11930   ins_encode( enc_String_Equals(str1, str2, cnt, result, tmp1, tmp2) );
       
 11931   ins_pipe(long_memory_op);
       
 11932 %}
       
 11933 
       
 11934 // FIXME: Why R0/R1?
       
 11935 instruct array_equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result,
       
 11936                       flagsReg ccr) %{
       
 11937   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
       
 11938   match(Set result (AryEq ary1 ary2));
       
 11939   effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP result, KILL ccr);
       
 11940 
       
 11941   ins_cost(300);
       
 11942   format %{ "Array Equals $ary1,$ary2 -> $result   // TEMP $tmp1,$tmp2,$tmp3" %}
       
 11943   ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, result));
       
 11944   ins_pipe(long_memory_op);
       
 11945 %}
       
 11946 #endif
       
 11947 
       
 11948 //---------- Zeros Count Instructions ------------------------------------------
       
 11949 
       
 11950 instruct countLeadingZerosI(iRegI dst, iRegI src) %{
       
 11951   match(Set dst (CountLeadingZerosI src));
       
 11952   size(4);
       
 11953   format %{ "CLZ_32 $dst,$src" %}
       
 11954   ins_encode %{
       
 11955     __ clz_32($dst$$Register, $src$$Register);
       
 11956   %}
       
 11957   ins_pipe(ialu_reg);
       
 11958 %}
       
 11959 
       
 11960 #ifdef AARCH64
       
 11961 instruct countLeadingZerosL(iRegI dst, iRegL src) %{
       
 11962   match(Set dst (CountLeadingZerosL src));
       
 11963   size(4);
       
 11964   format %{ "CLZ $dst,$src" %}
       
 11965   ins_encode %{
       
 11966     __ clz($dst$$Register, $src$$Register);
       
 11967   %}
       
 11968   ins_pipe(ialu_reg);
       
 11969 %}
       
 11970 #else
       
 11971 instruct countLeadingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
       
 11972   match(Set dst (CountLeadingZerosL src));
       
 11973   effect(TEMP tmp, TEMP dst, KILL ccr);
       
 11974   size(16);
       
 11975   format %{ "CLZ    $dst,$src.hi\n\t"
       
 11976             "TEQ    $dst,32\n\t"
       
 11977             "CLZ.eq $tmp,$src.lo\n\t"
       
 11978             "ADD.eq $dst, $dst, $tmp\n\t" %}
       
 11979   ins_encode %{
       
 11980     __ clz($dst$$Register, $src$$Register->successor());
       
 11981     __ teq($dst$$Register, 32);
       
 11982     __ clz($tmp$$Register, $src$$Register, eq);
       
 11983     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
       
 11984   %}
       
 11985   ins_pipe(ialu_reg);
       
 11986 %}
       
 11987 #endif
       
 11988 
       
 11989 instruct countTrailingZerosI(iRegI dst, iRegI src, iRegI tmp) %{
       
 11990   match(Set dst (CountTrailingZerosI src));
       
 11991   effect(TEMP tmp);
       
 11992   size(8);
       
 11993   format %{ "RBIT_32 $tmp, $src\n\t"
       
 11994             "CLZ_32  $dst,$tmp" %}
       
 11995   ins_encode %{
       
 11996     __ rbit_32($tmp$$Register, $src$$Register);
       
 11997     __ clz_32($dst$$Register, $tmp$$Register);
       
 11998   %}
       
 11999   ins_pipe(ialu_reg);
       
 12000 %}
       
 12001 
       
 12002 #ifdef AARCH64
       
 12003 instruct countTrailingZerosL(iRegI dst, iRegL src, iRegL tmp) %{
       
 12004   match(Set dst (CountTrailingZerosL src));
       
 12005   effect(TEMP tmp);
       
 12006   size(8);
       
 12007   format %{ "RBIT $tmp, $src\n\t"
       
 12008             "CLZ  $dst,$tmp" %}
       
 12009   ins_encode %{
       
 12010     __ rbit($tmp$$Register, $src$$Register);
       
 12011     __ clz($dst$$Register, $tmp$$Register);
       
 12012   %}
       
 12013   ins_pipe(ialu_reg);
       
 12014 %}
       
 12015 #else
       
 12016 instruct countTrailingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
       
 12017   match(Set dst (CountTrailingZerosL src));
       
 12018   effect(TEMP tmp, TEMP dst, KILL ccr);
       
 12019   size(24);
       
 12020   format %{ "RBIT   $tmp,$src.lo\n\t"
       
 12021             "CLZ    $dst,$tmp\n\t"
       
 12022             "TEQ    $dst,32\n\t"
       
 12023             "RBIT   $tmp,$src.hi\n\t"
       
 12024             "CLZ.eq $tmp,$tmp\n\t"
       
 12025             "ADD.eq $dst,$dst,$tmp\n\t" %}
       
 12026   ins_encode %{
       
 12027     __ rbit($tmp$$Register, $src$$Register);
       
 12028     __ clz($dst$$Register, $tmp$$Register);
       
 12029     __ teq($dst$$Register, 32);
       
 12030     __ rbit($tmp$$Register, $src$$Register->successor());
       
 12031     __ clz($tmp$$Register, $tmp$$Register, eq);
       
 12032     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
       
 12033   %}
       
 12034   ins_pipe(ialu_reg);
       
 12035 %}
       
 12036 #endif
       
 12037 
       
 12038 
       
 12039 //---------- Population Count Instructions -------------------------------------
       
 12040 
       
 12041 #ifdef AARCH64
       
 12042 instruct popCountI(iRegI dst, iRegI src, regD_low tmp) %{
       
 12043   predicate(UsePopCountInstruction);
       
 12044   match(Set dst (PopCountI src));
       
 12045   effect(TEMP tmp);
       
 12046   size(20);
       
 12047 
       
 12048   format %{ "MOV_W      $dst,$src\n\t"
       
 12049             "FMOV_dx    $tmp,$dst\n\t"
       
 12050             "VCNT       $tmp.8B,$tmp.8B\n\t"
       
 12051             "ADDV       $tmp.B,$tmp.8B\n\t"
       
 12052             "FMRS       $dst,$tmp" %}
       
 12053 
       
 12054   ins_encode %{
       
 12055     __ mov_w($dst$$Register, $src$$Register);
       
 12056     __ fmov_dx($tmp$$FloatRegister, $dst$$Register);
       
 12057     int quad = 0;
       
 12058     int cnt_size = 0; // VELEM_SIZE_8
       
 12059     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister, quad, cnt_size);
       
 12060     int add_size = 0; // VELEM_SIZE_8
       
 12061     __ addv($tmp$$FloatRegister, $tmp$$FloatRegister, quad, add_size);
       
 12062     __ fmrs($dst$$Register, $tmp$$FloatRegister);
       
 12063   %}
       
 12064   ins_pipe(ialu_reg); // FIXME
       
 12065 %}
       
 12066 #else
       
 12067 instruct popCountI(iRegI dst, iRegI src, regD_low tmp) %{
       
 12068   predicate(UsePopCountInstruction);
       
 12069   match(Set dst (PopCountI src));
       
 12070   effect(TEMP tmp);
       
 12071 
       
 12072   format %{ "FMSR       $tmp,$src\n\t"
       
 12073             "VCNT.8     $tmp,$tmp\n\t"
       
 12074             "VPADDL.U8  $tmp,$tmp\n\t"
       
 12075             "VPADDL.U16 $tmp,$tmp\n\t"
       
 12076             "FMRS       $dst,$tmp" %}
       
 12077   size(20);
       
 12078 
       
 12079   ins_encode %{
       
 12080     __ fmsr($tmp$$FloatRegister, $src$$Register);
       
 12081     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
       
 12082     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
       
 12083     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
       
 12084     __ fmrs($dst$$Register, $tmp$$FloatRegister);
       
 12085   %}
       
 12086   ins_pipe(ialu_reg); // FIXME
       
 12087 %}
       
 12088 #endif
       
 12089 
       
 12090 #ifdef AARCH64
       
 12091 instruct popCountL(iRegI dst, iRegL src, regD tmp) %{
       
 12092   predicate(UsePopCountInstruction);
       
 12093   match(Set dst (PopCountL src));
       
 12094   effect(TEMP tmp);
       
 12095   size(16);
       
 12096 
       
 12097   format %{ "FMOV_dx    $tmp,$src\n\t"
       
 12098             "VCNT       $tmp.8B,$tmp.8B\n\t"
       
 12099             "ADDV       $tmp.B,$tmp.8B\n\t"
       
 12100             "FMOV_ws    $dst,$tmp" %}
       
 12101 
       
 12102   ins_encode %{
       
 12103     __ fmov_dx($tmp$$FloatRegister, $src$$Register);
       
 12104     int quad = 0;
       
 12105     int cnt_size = 0;
       
 12106     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister, quad, cnt_size);
       
 12107     int add_size = 0;
       
 12108     __ addv($tmp$$FloatRegister, $tmp$$FloatRegister, quad, add_size);
       
 12109     __ fmov_ws($dst$$Register, $tmp$$FloatRegister);
       
 12110   %}
       
 12111   ins_pipe(ialu_reg); // FIXME
       
 12112 %}
       
 12113 #else
       
 12114 // Note: Long.bitCount(long) returns an int.
       
 12115 instruct popCountL(iRegI dst, iRegL src, regD_low tmp) %{
       
 12116   predicate(UsePopCountInstruction);
       
 12117   match(Set dst (PopCountL src));
       
 12118   effect(TEMP tmp);
       
 12119 
       
 12120   format %{ "FMDRR       $tmp,$src.lo,$src.hi\n\t"
       
 12121             "VCNT.8      $tmp,$tmp\n\t"
       
 12122             "VPADDL.U8   $tmp,$tmp\n\t"
       
 12123             "VPADDL.U16  $tmp,$tmp\n\t"
       
 12124             "VPADDL.U32  $tmp,$tmp\n\t"
       
 12125             "FMRS        $dst,$tmp" %}
       
 12126 
       
 12127   size(32);
       
 12128 
       
 12129   ins_encode %{
       
 12130     __ fmdrr($tmp$$FloatRegister, $src$$Register, $src$$Register->successor());
       
 12131     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
       
 12132     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
       
 12133     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
       
 12134     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 32, 0);
       
 12135     __ fmrs($dst$$Register, $tmp$$FloatRegister);
       
 12136   %}
       
 12137   ins_pipe(ialu_reg);
       
 12138 %}
       
 12139 #endif
       
 12140 
       
 12141 
       
 12142 // ============================================================================
       
 12143 //------------Bytes reverse--------------------------------------------------
       
 12144 
       
 12145 instruct bytes_reverse_int(iRegI dst, iRegI src) %{
       
 12146   match(Set dst (ReverseBytesI src));
       
 12147 
       
 12148   size(4);
       
 12149   format %{ "REV32 $dst,$src" %}
       
 12150   ins_encode %{
       
 12151 #ifdef AARCH64
       
 12152     __ rev_w($dst$$Register, $src$$Register);
       
 12153     // high 32 bits zeroed, not sign extended
       
 12154 #else
       
 12155     __ rev($dst$$Register, $src$$Register);
       
 12156 #endif
       
 12157   %}
       
 12158   ins_pipe( iload_mem ); // FIXME
       
 12159 %}
       
 12160 
       
 12161 instruct bytes_reverse_long(iRegL dst, iRegL src) %{
       
 12162   match(Set dst (ReverseBytesL src));
       
 12163 #ifdef AARCH64
       
 12164 //size(4);
       
 12165   format %{ "REV $dst,$src"  %}
       
 12166   ins_encode %{
       
 12167     __ rev($dst$$Register, $src$$Register);
       
 12168   %}
       
 12169   ins_pipe(ialu_reg_reg); // FIXME
       
 12170 #else
       
 12171   effect(TEMP dst);
       
 12172   size(8);
       
 12173   format %{ "REV $dst.lo,$src.lo\n\t"
       
 12174             "REV $dst.hi,$src.hi" %}
       
 12175   ins_encode %{
       
 12176     __ rev($dst$$Register, $src$$Register->successor());
       
 12177     __ rev($dst$$Register->successor(), $src$$Register);
       
 12178   %}
       
 12179   ins_pipe( iload_mem ); // FIXME
       
 12180 #endif
       
 12181 %}
       
 12182 
       
 12183 instruct bytes_reverse_unsigned_short(iRegI dst, iRegI src) %{
       
 12184   match(Set dst (ReverseBytesUS src));
       
 12185 #ifdef AARCH64
       
 12186   size(4);
       
 12187   format %{ "REV16_W $dst,$src" %}
       
 12188   ins_encode %{
       
 12189     __ rev16_w($dst$$Register, $src$$Register);
       
 12190     // high 32 bits zeroed
       
 12191   %}
       
 12192 #else
       
 12193   size(4);
       
 12194   format %{ "REV16 $dst,$src" %}
       
 12195   ins_encode %{
       
 12196     __ rev16($dst$$Register, $src$$Register);
       
 12197   %}
       
 12198 #endif
       
 12199   ins_pipe( iload_mem ); // FIXME
       
 12200 %}
       
 12201 
       
 12202 instruct bytes_reverse_short(iRegI dst, iRegI src) %{
       
 12203   match(Set dst (ReverseBytesS src));
       
 12204 #ifdef AARCH64
       
 12205   size(8);
       
 12206   format %{ "REV16_W $dst,$src\n\t"
       
 12207             "SIGN_EXT16 $dst" %}
       
 12208   ins_encode %{
       
 12209     __ rev16_w($dst$$Register, $src$$Register);
       
 12210     __ sign_extend($dst$$Register, $dst$$Register, 16);
       
 12211   %}
       
 12212 #else
       
 12213   size(4);
       
 12214   format %{ "REVSH $dst,$src" %}
       
 12215   ins_encode %{
       
 12216     __ revsh($dst$$Register, $src$$Register);
       
 12217   %}
       
 12218 #endif
       
 12219   ins_pipe( iload_mem ); // FIXME
       
 12220 %}
       
 12221 
       
 12222 
       
 12223 // ====================VECTOR INSTRUCTIONS=====================================
       
 12224 
       
 12225 // Load Aligned Packed values into a Double Register
       
 12226 instruct loadV8(vecD dst, memoryD mem) %{
       
 12227   predicate(n->as_LoadVector()->memory_size() == 8);
       
 12228   match(Set dst (LoadVector mem));
       
 12229   ins_cost(MEMORY_REF_COST);
       
 12230   size(4);
       
 12231   format %{ "FLDD   $mem,$dst\t! load vector (8 bytes)" %}
       
 12232   ins_encode %{
       
 12233     __ ldr_double($dst$$FloatRegister, $mem$$Address);
       
 12234   %}
       
 12235   ins_pipe(floadD_mem);
       
 12236 %}
       
 12237 
       
 12238 // Load Aligned Packed values into a Double Register Pair
       
 12239 instruct loadV16(vecX dst, memoryvld mem) %{
       
 12240   predicate(n->as_LoadVector()->memory_size() == 16);
       
 12241   match(Set dst (LoadVector mem));
       
 12242   ins_cost(MEMORY_REF_COST);
       
 12243   size(4);
       
 12244   format %{ "VLD1   $mem,$dst.Q\t! load vector (16 bytes)" %}
       
 12245   ins_encode %{
       
 12246     __ vld1($dst$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
       
 12247   %}
       
 12248   ins_pipe(floadD_mem); // FIXME
       
 12249 %}
       
 12250 
       
 12251 // Store Vector in Double register to memory
       
 12252 instruct storeV8(memoryD mem, vecD src) %{
       
 12253   predicate(n->as_StoreVector()->memory_size() == 8);
       
 12254   match(Set mem (StoreVector mem src));
       
 12255   ins_cost(MEMORY_REF_COST);
       
 12256   size(4);
       
 12257   format %{ "FSTD   $src,$mem\t! store vector (8 bytes)" %}
       
 12258   ins_encode %{
       
 12259     __ str_double($src$$FloatRegister, $mem$$Address);
       
 12260   %}
       
 12261   ins_pipe(fstoreD_mem_reg);
       
 12262 %}
       
 12263 
       
 12264 // Store Vector in Double Register Pair to memory
       
 12265 instruct storeV16(memoryvld mem, vecX src) %{
       
 12266   predicate(n->as_StoreVector()->memory_size() == 16);
       
 12267   match(Set mem (StoreVector mem src));
       
 12268   ins_cost(MEMORY_REF_COST);
       
 12269   size(4);
       
 12270   format %{ "VST1   $src,$mem\t! store vector (16 bytes)" %}
       
 12271   ins_encode %{
       
 12272     __ vst1($src$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
       
 12273   %}
       
 12274   ins_pipe(fstoreD_mem_reg); // FIXME
       
 12275 %}
       
 12276 
       
 12277 #ifndef AARCH64
       
 12278 // Replicate scalar to packed byte values in Double register
       
 12279 instruct Repl8B_reg(vecD dst, iRegI src, iRegI tmp) %{
       
 12280   predicate(n->as_Vector()->length() == 8);
       
 12281   match(Set dst (ReplicateB src));
       
 12282   ins_cost(DEFAULT_COST*4);
       
 12283   effect(TEMP tmp);
       
 12284   size(16);
       
 12285 
       
 12286   // FIXME: could use PKH instruction instead?
       
 12287   format %{ "LSL      $tmp, $src, 24 \n\t"
       
 12288             "OR       $tmp, $tmp, ($tmp >> 8) \n\t"
       
 12289             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
       
 12290             "FMDRR    $dst,$tmp,$tmp\t" %}
       
 12291   ins_encode %{
       
 12292     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 24));
       
 12293     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 8));
       
 12294     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
       
 12295     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
       
 12296   %}
       
 12297   ins_pipe(ialu_reg); // FIXME
       
 12298 %}
       
 12299 #endif /* !AARCH64 */
       
 12300 
       
 12301 // Replicate scalar to packed byte values in Double register
       
 12302 instruct Repl8B_reg_simd(vecD dst, iRegI src) %{
       
 12303   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
       
 12304   match(Set dst (ReplicateB src));
       
 12305   size(4);
       
 12306 
       
 12307   format %{ "VDUP.8 $dst,$src\t" %}
       
 12308   ins_encode %{
       
 12309     bool quad = false;
       
 12310     __ vdupI($dst$$FloatRegister, $src$$Register,
       
 12311              MacroAssembler::VELEM_SIZE_8, quad);
       
 12312   %}
       
 12313   ins_pipe(ialu_reg); // FIXME
       
 12314 %}
       
 12315 
       
 12316 // Replicate scalar to packed byte values in Double register pair
       
 12317 instruct Repl16B_reg(vecX dst, iRegI src) %{
       
 12318   predicate(n->as_Vector()->length_in_bytes() == 16);
       
 12319   match(Set dst (ReplicateB src));
       
 12320   size(4);
       
 12321 
       
 12322   format %{ "VDUP.8 $dst.Q,$src\t" %}
       
 12323   ins_encode %{
       
 12324     bool quad = true;
       
 12325     __ vdupI($dst$$FloatRegister, $src$$Register,
       
 12326              MacroAssembler::VELEM_SIZE_8, quad);
       
 12327   %}
       
 12328   ins_pipe(ialu_reg); // FIXME
       
 12329 %}
       
 12330 
       
 12331 #ifndef AARCH64
       
 12332 // Replicate scalar constant to packed byte values in Double register
       
 12333 instruct Repl8B_immI(vecD dst, immI src, iRegI tmp) %{
       
 12334   predicate(n->as_Vector()->length() == 8);
       
 12335   match(Set dst (ReplicateB src));
       
 12336   ins_cost(DEFAULT_COST*2);
       
 12337   effect(TEMP tmp);
       
 12338   size(12);
       
 12339 
       
 12340   format %{ "MOV      $tmp, Repl4($src))\n\t"
       
 12341             "FMDRR    $dst,$tmp,$tmp\t" %}
       
 12342   ins_encode( LdReplImmI(src, dst, tmp, (4), (1)) );
       
 12343   ins_pipe(loadConFD); // FIXME
       
 12344 %}
       
 12345 #endif /* !AARCH64 */
       
 12346 
       
 12347 // Replicate scalar constant to packed byte values in Double register
       
 12348 // TODO: support negative constants with MVNI?
       
 12349 instruct Repl8B_immU8(vecD dst, immU8 src) %{
       
 12350   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
       
 12351   match(Set dst (ReplicateB src));
       
 12352   size(4);
       
 12353 
       
 12354   format %{ "VMOV.U8  $dst,$src" %}
       
 12355   ins_encode %{
       
 12356     bool quad = false;
       
 12357     __ vmovI($dst$$FloatRegister, $src$$constant,
       
 12358              MacroAssembler::VELEM_SIZE_8, quad);
       
 12359   %}
       
 12360   ins_pipe(loadConFD); // FIXME
       
 12361 %}
       
 12362 
       
 12363 // Replicate scalar constant to packed byte values in Double register pair
       
 12364 instruct Repl16B_immU8(vecX dst, immU8 src) %{
       
 12365   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
       
 12366   match(Set dst (ReplicateB src));
       
 12367   size(4);
       
 12368 
       
 12369   format %{ "VMOV.U8  $dst.Q,$src" %}
       
 12370   ins_encode %{
       
 12371     bool quad = true;
       
 12372     __ vmovI($dst$$FloatRegister, $src$$constant,
       
 12373              MacroAssembler::VELEM_SIZE_8, quad);
       
 12374   %}
       
 12375   ins_pipe(loadConFD); // FIXME
       
 12376 %}
       
 12377 
       
 12378 #ifndef AARCH64
       
 12379 // Replicate scalar to packed short/char values into Double register
       
 12380 instruct Repl4S_reg(vecD dst, iRegI src, iRegI tmp) %{
       
 12381   predicate(n->as_Vector()->length() == 4);
       
 12382   match(Set dst (ReplicateS src));
       
 12383   ins_cost(DEFAULT_COST*3);
       
 12384   effect(TEMP tmp);
       
 12385   size(12);
       
 12386 
       
 12387   // FIXME: could use PKH instruction instead?
       
 12388   format %{ "LSL      $tmp, $src, 16 \n\t"
       
 12389             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
       
 12390             "FMDRR    $dst,$tmp,$tmp\t" %}
       
 12391   ins_encode %{
       
 12392     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 16));
       
 12393     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
       
 12394     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
       
 12395   %}
       
 12396   ins_pipe(ialu_reg); // FIXME
       
 12397 %}
       
 12398 #endif /* !AARCH64 */
       
 12399 
       
 12400 // Replicate scalar to packed byte values in Double register
       
 12401 instruct Repl4S_reg_simd(vecD dst, iRegI src) %{
       
 12402   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
       
 12403   match(Set dst (ReplicateS src));
       
 12404   size(4);
       
 12405 
       
 12406   format %{ "VDUP.16 $dst,$src\t" %}
       
 12407   ins_encode %{
       
 12408     bool quad = false;
       
 12409     __ vdupI($dst$$FloatRegister, $src$$Register,
       
 12410              MacroAssembler::VELEM_SIZE_16, quad);
       
 12411   %}
       
 12412   ins_pipe(ialu_reg); // FIXME
       
 12413 %}
       
 12414 
       
 12415 // Replicate scalar to packed byte values in Double register pair
       
 12416 instruct Repl8S_reg(vecX dst, iRegI src) %{
       
 12417   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
       
 12418   match(Set dst (ReplicateS src));
       
 12419   size(4);
       
 12420 
       
 12421   format %{ "VDUP.16 $dst.Q,$src\t" %}
       
 12422   ins_encode %{
       
 12423     bool quad = true;
       
 12424     __ vdupI($dst$$FloatRegister, $src$$Register,
       
 12425              MacroAssembler::VELEM_SIZE_16, quad);
       
 12426   %}
       
 12427   ins_pipe(ialu_reg); // FIXME
       
 12428 %}
       
 12429 
       
 12430 
       
 12431 #ifndef AARCH64
       
 12432 // Replicate scalar constant to packed short/char values in Double register
       
 12433 instruct Repl4S_immI(vecD dst, immI src, iRegP tmp) %{
       
 12434   predicate(n->as_Vector()->length() == 4);
       
 12435   match(Set dst (ReplicateS src));
       
 12436   effect(TEMP tmp);
       
 12437   size(12);
       
 12438   ins_cost(DEFAULT_COST*4); // FIXME
       
 12439 
       
 12440   format %{ "MOV      $tmp, Repl2($src))\n\t"
       
 12441             "FMDRR    $dst,$tmp,$tmp\t" %}
       
 12442   ins_encode( LdReplImmI(src, dst, tmp, (2), (2)) );
       
 12443   ins_pipe(loadConFD); // FIXME
       
 12444 %}
       
 12445 #endif /* !AARCH64 */
       
 12446 
       
 12447 // Replicate scalar constant to packed byte values in Double register
       
 12448 instruct Repl4S_immU8(vecD dst, immU8 src) %{
       
 12449   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
       
 12450   match(Set dst (ReplicateS src));
       
 12451   size(4);
       
 12452 
       
 12453   format %{ "VMOV.U16  $dst,$src" %}
       
 12454   ins_encode %{
       
 12455     bool quad = false;
       
 12456     __ vmovI($dst$$FloatRegister, $src$$constant,
       
 12457              MacroAssembler::VELEM_SIZE_16, quad);
       
 12458   %}
       
 12459   ins_pipe(loadConFD); // FIXME
       
 12460 %}
       
 12461 
       
 12462 // Replicate scalar constant to packed byte values in Double register pair
       
 12463 instruct Repl8S_immU8(vecX dst, immU8 src) %{
       
 12464   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
       
 12465   match(Set dst (ReplicateS src));
       
 12466   size(4);
       
 12467 
       
 12468   format %{ "VMOV.U16  $dst.Q,$src" %}
       
 12469   ins_encode %{
       
 12470     bool quad = true;
       
 12471     __ vmovI($dst$$FloatRegister, $src$$constant,
       
 12472              MacroAssembler::VELEM_SIZE_16, quad);
       
 12473   %}
       
 12474   ins_pipe(loadConFD); // FIXME
       
 12475 %}
       
 12476 
       
 12477 #ifndef AARCH64
       
 12478 // Replicate scalar to packed int values in Double register
       
 12479 instruct Repl2I_reg(vecD dst, iRegI src) %{
       
 12480   predicate(n->as_Vector()->length() == 2);
       
 12481   match(Set dst (ReplicateI src));
       
 12482   size(4);
       
 12483 
       
 12484   format %{ "FMDRR    $dst,$src,$src\t" %}
       
 12485   ins_encode %{
       
 12486     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
       
 12487   %}
       
 12488   ins_pipe(ialu_reg); // FIXME
       
 12489 %}
       
 12490 
       
 12491 // Replicate scalar to packed int values in Double register pair
       
 12492 instruct Repl4I_reg(vecX dst, iRegI src) %{
       
 12493   predicate(n->as_Vector()->length() == 4);
       
 12494   match(Set dst (ReplicateI src));
       
 12495   ins_cost(DEFAULT_COST*2);
       
 12496   size(8);
       
 12497 
       
 12498   format %{ "FMDRR    $dst.lo,$src,$src\n\t"
       
 12499             "FMDRR    $dst.hi,$src,$src" %}
       
 12500 
       
 12501   ins_encode %{
       
 12502     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
       
 12503     __ fmdrr($dst$$FloatRegister->successor()->successor(),
       
 12504              $src$$Register, $src$$Register);
       
 12505   %}
       
 12506   ins_pipe(ialu_reg); // FIXME
       
 12507 %}
       
 12508 #endif /* !AARCH64 */
       
 12509 
       
 12510 // Replicate scalar to packed int values in Double register
       
 12511 instruct Repl2I_reg_simd(vecD dst, iRegI src) %{
       
 12512   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
       
 12513   match(Set dst (ReplicateI src));
       
 12514   size(4);
       
 12515 
       
 12516   format %{ "VDUP.32 $dst.D,$src\t" %}
       
 12517   ins_encode %{
       
 12518     bool quad = false;
       
 12519     __ vdupI($dst$$FloatRegister, $src$$Register,
       
 12520              MacroAssembler::VELEM_SIZE_32, quad);
       
 12521   %}
       
 12522   ins_pipe(ialu_reg); // FIXME
       
 12523 %}
       
 12524 
       
 12525 // Replicate scalar to packed int values in Double register pair
       
 12526 instruct Repl4I_reg_simd(vecX dst, iRegI src) %{
       
 12527   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
       
 12528   match(Set dst (ReplicateI src));
       
 12529   size(4);
       
 12530 
       
 12531   format %{ "VDUP.32 $dst.Q,$src\t" %}
       
 12532   ins_encode %{
       
 12533     bool quad = true;
       
 12534     __ vdupI($dst$$FloatRegister, $src$$Register,
       
 12535              MacroAssembler::VELEM_SIZE_32, quad);
       
 12536   %}
       
 12537   ins_pipe(ialu_reg); // FIXME
       
 12538 %}
       
 12539 
       
 12540 
       
 12541 #ifndef AARCH64
       
 12542 // Replicate scalar zero constant to packed int values in Double register
       
 12543 instruct Repl2I_immI(vecD dst, immI src, iRegI tmp) %{
       
 12544   predicate(n->as_Vector()->length() == 2);
       
 12545   match(Set dst (ReplicateI src));
       
 12546   effect(TEMP tmp);
       
 12547   size(12);
       
 12548   ins_cost(DEFAULT_COST*4); // FIXME
       
 12549 
       
 12550   format %{ "MOV      $tmp, Repl1($src))\n\t"
       
 12551             "FMDRR    $dst,$tmp,$tmp\t" %}
       
 12552   ins_encode( LdReplImmI(src, dst, tmp, (1), (4)) );
       
 12553   ins_pipe(loadConFD); // FIXME
       
 12554 %}
       
 12555 #endif /* !AARCH64 */
       
 12556 
       
 12557 // Replicate scalar constant to packed byte values in Double register
       
 12558 instruct Repl2I_immU8(vecD dst, immU8 src) %{
       
 12559   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
       
 12560   match(Set dst (ReplicateI src));
       
 12561   size(4);
       
 12562 
       
 12563   format %{ "VMOV.I32  $dst.D,$src" %}
       
 12564   ins_encode %{
       
 12565     bool quad = false;
       
 12566     __ vmovI($dst$$FloatRegister, $src$$constant,
       
 12567              MacroAssembler::VELEM_SIZE_32, quad);
       
 12568   %}
       
 12569   ins_pipe(loadConFD); // FIXME
       
 12570 %}
       
 12571 
       
 12572 // Replicate scalar constant to packed byte values in Double register pair
       
 12573 instruct Repl4I_immU8(vecX dst, immU8 src) %{
       
 12574   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
       
 12575   match(Set dst (ReplicateI src));
       
 12576   size(4);
       
 12577 
       
 12578   format %{ "VMOV.I32  $dst.Q,$src" %}
       
 12579   ins_encode %{
       
 12580     bool quad = true;
       
 12581     __ vmovI($dst$$FloatRegister, $src$$constant,
       
 12582              MacroAssembler::VELEM_SIZE_32, quad);
       
 12583   %}
       
 12584   ins_pipe(loadConFD); // FIXME
       
 12585 %}
       
 12586 
       
 12587 #ifdef AARCH64
       
 12588 // Replicate scalar to packed byte values in Double register pair
       
 12589 instruct Repl2L_reg(vecX dst, iRegL src) %{
       
 12590   predicate(n->as_Vector()->length() == 2);
       
 12591   match(Set dst (ReplicateL src));
       
 12592   size(4*1);
       
 12593   ins_cost(DEFAULT_COST*1); // FIXME
       
 12594 
       
 12595   format %{ "VDUP.2D $dst.Q,$src\t" %}
       
 12596   ins_encode %{
       
 12597     bool quad = true;
       
 12598     __ vdupI($dst$$FloatRegister, $src$$Register,
       
 12599              MacroAssembler::VELEM_SIZE_64, quad);
       
 12600   %}
       
 12601   ins_pipe(ialu_reg); // FIXME
       
 12602 %}
       
 12603 #else /* !AARCH64 */
       
 12604 // Replicate scalar to packed byte values in Double register pair
       
 12605 instruct Repl2L_reg(vecX dst, iRegL src) %{
       
 12606   predicate(n->as_Vector()->length() == 2);
       
 12607   match(Set dst (ReplicateL src));
       
 12608   size(8);
       
 12609   ins_cost(DEFAULT_COST*2); // FIXME
       
 12610 
       
 12611   format %{ "FMDRR $dst.D,$src.lo,$src.hi\t\n"
       
 12612             "FMDRR $dst.D.next,$src.lo,$src.hi" %}
       
 12613   ins_encode %{
       
 12614     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
       
 12615     __ fmdrr($dst$$FloatRegister->successor()->successor(),
       
 12616              $src$$Register, $src$$Register->successor());
       
 12617   %}
       
 12618   ins_pipe(ialu_reg); // FIXME
       
 12619 %}
       
 12620 
       
 12621 
       
 12622 // Replicate scalar to packed float values in Double register
       
 12623 instruct Repl2F_regI(vecD dst, iRegI src) %{
       
 12624   predicate(n->as_Vector()->length() == 2);
       
 12625   match(Set dst (ReplicateF src));
       
 12626   size(4);
       
 12627 
       
 12628   format %{ "FMDRR    $dst.D,$src,$src\t" %}
       
 12629   ins_encode %{
       
 12630     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
       
 12631   %}
       
 12632   ins_pipe(ialu_reg); // FIXME
       
 12633 %}
       
 12634 
       
 12635 // Replicate scalar to packed float values in Double register
       
 12636 instruct Repl2F_reg_vfp(vecD dst, regF src) %{
       
 12637   predicate(n->as_Vector()->length() == 2);
       
 12638   match(Set dst (ReplicateF src));
       
 12639   size(4*2);
       
 12640   ins_cost(DEFAULT_COST*2); // FIXME
       
 12641 
       
 12642   expand %{
       
 12643     iRegI tmp;
       
 12644     MoveF2I_reg_reg(tmp, src);
       
 12645     Repl2F_regI(dst,tmp);
       
 12646   %}
       
 12647 %}
       
 12648 #endif /* !AARCH64 */
       
 12649 
       
 12650 // Replicate scalar to packed float values in Double register
       
 12651 instruct Repl2F_reg_simd(vecD dst, regF src) %{
       
 12652   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
       
 12653   match(Set dst (ReplicateF src));
       
 12654   size(4);
       
 12655   ins_cost(DEFAULT_COST); // FIXME
       
 12656 
       
 12657   format %{ "VDUP.32  $dst.D,$src.D\t" %}
       
 12658   ins_encode %{
       
 12659     bool quad = false;
       
 12660     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
       
 12661   %}
       
 12662   ins_pipe(ialu_reg); // FIXME
       
 12663 %}
       
 12664 
       
 12665 #ifndef AARCH64
       
 12666 // Replicate scalar to packed float values in Double register pair
       
 12667 instruct Repl4F_reg(vecX dst, regF src, iRegI tmp) %{
       
 12668   predicate(n->as_Vector()->length() == 4);
       
 12669   match(Set dst (ReplicateF src));
       
 12670   effect(TEMP tmp);
       
 12671   size(4*3);
       
 12672   ins_cost(DEFAULT_COST*3); // FIXME
       
 12673 
       
 12674   format %{ "FMRS     $tmp,$src\n\t"
       
 12675             "FMDRR    $dst.D,$tmp,$tmp\n\t"
       
 12676             "FMDRR    $dst.D.next,$tmp,$tmp\t" %}
       
 12677   ins_encode %{
       
 12678     __ fmrs($tmp$$Register, $src$$FloatRegister);
       
 12679     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
       
 12680     __ fmdrr($dst$$FloatRegister->successor()->successor(),
       
 12681              $tmp$$Register, $tmp$$Register);
       
 12682   %}
       
 12683   ins_pipe(ialu_reg); // FIXME
       
 12684 %}
       
 12685 #endif /* !AARCH64 */
       
 12686 
       
 12687 // Replicate scalar to packed float values in Double register pair
       
 12688 instruct Repl4F_reg_simd(vecX dst, regF src) %{
       
 12689   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
       
 12690   match(Set dst (ReplicateF src));
       
 12691   size(4);
       
 12692   ins_cost(DEFAULT_COST); // FIXME
       
 12693 
       
 12694   format %{ "VDUP.32  $dst.Q,$src.D\t" %}
       
 12695   ins_encode %{
       
 12696     bool quad = true;
       
 12697     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
       
 12698   %}
       
 12699   ins_pipe(ialu_reg); // FIXME
       
 12700 %}
       
 12701 
       
 12702 #ifndef AARCH64
       
 12703 // Replicate scalar zero constant to packed float values in Double register
       
 12704 instruct Repl2F_immI(vecD dst, immF src, iRegI tmp) %{
       
 12705   predicate(n->as_Vector()->length() == 2);
       
 12706   match(Set dst (ReplicateF src));
       
 12707   effect(TEMP tmp);
       
 12708   size(12);
       
 12709   ins_cost(DEFAULT_COST*4); // FIXME
       
 12710 
       
 12711   format %{ "MOV      $tmp, Repl1($src))\n\t"
       
 12712             "FMDRR    $dst,$tmp,$tmp\t" %}
       
 12713   ins_encode( LdReplImmF(src, dst, tmp) );
       
 12714   ins_pipe(loadConFD); // FIXME
       
 12715 %}
       
 12716 #endif /* !AAARCH64 */
       
 12717 
       
 12718 // Replicate scalar to packed double float values in Double register pair
       
 12719 instruct Repl2D_reg(vecX dst, regD src) %{
       
 12720 #ifdef AARCH64
       
 12721   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
       
 12722   match(Set dst (ReplicateD src));
       
 12723   size(4*1);
       
 12724   ins_cost(DEFAULT_COST*1); // FIXME
       
 12725 
       
 12726   format %{ "VDUP     $dst.2D,$src\t" %}
       
 12727   ins_encode %{
       
 12728     bool quad = true;
       
 12729     __ vdupD($dst$$FloatRegister, $src$$FloatRegister, quad);
       
 12730   %}
       
 12731 #else
       
 12732   predicate(n->as_Vector()->length() == 2);
       
 12733   match(Set dst (ReplicateD src));
       
 12734   size(4*2);
       
 12735   ins_cost(DEFAULT_COST*2); // FIXME
       
 12736 
       
 12737   format %{ "FCPYD    $dst.D.a,$src\n\t"
       
 12738             "FCPYD    $dst.D.b,$src\t" %}
       
 12739   ins_encode %{
       
 12740     FloatRegister dsta = $dst$$FloatRegister;
       
 12741     FloatRegister src = $src$$FloatRegister;
       
 12742     __ fcpyd(dsta, src);
       
 12743     FloatRegister dstb = dsta->successor()->successor();
       
 12744     __ fcpyd(dstb, src);
       
 12745   %}
       
 12746 #endif
       
 12747   ins_pipe(ialu_reg); // FIXME
       
 12748 %}
       
 12749 
       
 12750 // ====================VECTOR ARITHMETIC=======================================
       
 12751 
       
 12752 // --------------------------------- ADD --------------------------------------
       
 12753 
       
 12754 // Bytes vector add
       
 12755 instruct vadd8B_reg(vecD dst, vecD src1, vecD src2) %{
       
 12756   predicate(n->as_Vector()->length() == 8);
       
 12757   match(Set dst (AddVB src1 src2));
       
 12758   format %{ "VADD.I8 $dst,$src1,$src2\t! add packed8B" %}
       
 12759   size(4);
       
 12760   ins_encode %{
       
 12761     bool quad = false;
       
 12762     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 12763              MacroAssembler::VELEM_SIZE_8, quad);
       
 12764   %}
       
 12765   ins_pipe( ialu_reg_reg ); // FIXME
       
 12766 %}
       
 12767 
       
 12768 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
       
 12769   predicate(n->as_Vector()->length() == 16);
       
 12770   match(Set dst (AddVB src1 src2));
       
 12771   size(4);
       
 12772   format %{ "VADD.I8 $dst.Q,$src1.Q,$src2.Q\t! add packed16B" %}
       
 12773   ins_encode %{
       
 12774     bool quad = true;
       
 12775     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 12776              MacroAssembler::VELEM_SIZE_8, quad);
       
 12777   %}
       
 12778   ins_pipe( ialu_reg_reg ); // FIXME
       
 12779 %}
       
 12780 
       
 12781 // Shorts/Chars vector add
       
 12782 instruct vadd4S_reg(vecD dst, vecD src1, vecD src2) %{
       
 12783   predicate(n->as_Vector()->length() == 4);
       
 12784   match(Set dst (AddVS src1 src2));
       
 12785   size(4);
       
 12786   format %{ "VADD.I16 $dst,$src1,$src2\t! add packed4S" %}
       
 12787   ins_encode %{
       
 12788     bool quad = false;
       
 12789     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 12790              MacroAssembler::VELEM_SIZE_16, quad);
       
 12791   %}
       
 12792   ins_pipe( ialu_reg_reg ); // FIXME
       
 12793 %}
       
 12794 
       
 12795 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
       
 12796   predicate(n->as_Vector()->length() == 8);
       
 12797   match(Set dst (AddVS src1 src2));
       
 12798   size(4);
       
 12799   format %{ "VADD.I16 $dst.Q,$src1.Q,$src2.Q\t! add packed8S" %}
       
 12800   ins_encode %{
       
 12801     bool quad = true;
       
 12802     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 12803              MacroAssembler::VELEM_SIZE_16, quad);
       
 12804   %}
       
 12805   ins_pipe( ialu_reg_reg ); // FIXME
       
 12806 %}
       
 12807 
       
 12808 // Integers vector add
       
 12809 instruct vadd2I_reg(vecD dst, vecD src1, vecD src2) %{
       
 12810   predicate(n->as_Vector()->length() == 2);
       
 12811   match(Set dst (AddVI src1 src2));
       
 12812   size(4);
       
 12813   format %{ "VADD.I32 $dst.D,$src1.D,$src2.D\t! add packed2I" %}
       
 12814   ins_encode %{
       
 12815     bool quad = false;
       
 12816     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 12817              MacroAssembler::VELEM_SIZE_32, quad);
       
 12818   %}
       
 12819   ins_pipe( ialu_reg_reg ); // FIXME
       
 12820 %}
       
 12821 
       
 12822 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
       
 12823   predicate(n->as_Vector()->length() == 4);
       
 12824   match(Set dst (AddVI src1 src2));
       
 12825   size(4);
       
 12826   format %{ "VADD.I32 $dst.Q,$src1.Q,$src2.Q\t! add packed4I" %}
       
 12827   ins_encode %{
       
 12828     bool quad = true;
       
 12829     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 12830              MacroAssembler::VELEM_SIZE_32, quad);
       
 12831   %}
       
 12832   ins_pipe( ialu_reg_reg ); // FIXME
       
 12833 %}
       
 12834 
       
 12835 // Longs vector add
       
 12836 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
       
 12837   predicate(n->as_Vector()->length() == 2);
       
 12838   match(Set dst (AddVL src1 src2));
       
 12839   size(4);
       
 12840   format %{ "VADD.I64 $dst.Q,$src1.Q,$src2.Q\t! add packed2L" %}
       
 12841   ins_encode %{
       
 12842     bool quad = true;
       
 12843     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 12844              MacroAssembler::VELEM_SIZE_64, quad);
       
 12845   %}
       
 12846   ins_pipe( ialu_reg_reg ); // FIXME
       
 12847 %}
       
 12848 
       
 12849 // Floats vector add
       
 12850 instruct vadd2F_reg(vecD dst, vecD src1, vecD src2) %{
       
 12851   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
       
 12852   match(Set dst (AddVF src1 src2));
       
 12853   size(4);
       
 12854   format %{ "VADD.F32 $dst,$src1,$src2\t! add packed2F" %}
       
 12855   ins_encode %{
       
 12856     bool quad = false;
       
 12857     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 12858              MacroAssembler::VFA_SIZE_F32, quad);
       
 12859   %}
       
 12860   ins_pipe( faddD_reg_reg ); // FIXME
       
 12861 %}
       
 12862 
       
 12863 #ifndef AARCH64
       
 12864 instruct vadd2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
       
 12865   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
       
 12866   match(Set dst (AddVF src1 src2));
       
 12867   ins_cost(DEFAULT_COST*2); // FIXME
       
 12868 
       
 12869   size(4*2);
       
 12870   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
       
 12871             "FADDS  $dst.b,$src1.b,$src2.b" %}
       
 12872   ins_encode %{
       
 12873     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
       
 12874     __ add_float($dst$$FloatRegister->successor(),
       
 12875              $src1$$FloatRegister->successor(),
       
 12876              $src2$$FloatRegister->successor());
       
 12877   %}
       
 12878 
       
 12879   ins_pipe(faddF_reg_reg); // FIXME
       
 12880 %}
       
 12881 #endif
       
 12882 
       
 12883 instruct vadd4F_reg_simd(vecX dst, vecX src1, vecX src2) %{
       
 12884   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
       
 12885   match(Set dst (AddVF src1 src2));
       
 12886   size(4);
       
 12887   format %{ "VADD.F32 $dst.Q,$src1.Q,$src2.Q\t! add packed4F" %}
       
 12888   ins_encode %{
       
 12889     bool quad = true;
       
 12890     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 12891              MacroAssembler::VFA_SIZE_F32, quad);
       
 12892   %}
       
 12893   ins_pipe( faddD_reg_reg ); // FIXME
       
 12894 %}
       
 12895 
       
 12896 #ifdef AARCH64
       
 12897 instruct vadd2D_reg_simd(vecX dst, vecX src1, vecX src2) %{
       
 12898   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
       
 12899   match(Set dst (AddVD src1 src2));
       
 12900   size(4);
       
 12901   format %{ "VADD.F64 $dst.Q,$src1.Q,$src2.Q\t! add packed2D" %}
       
 12902   ins_encode %{
       
 12903     bool quad = true;
       
 12904     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 12905              MacroAssembler::VFA_SIZE_F64, quad);
       
 12906   %}
       
 12907   ins_pipe( faddD_reg_reg ); // FIXME
       
 12908 %}
       
 12909 #else
       
 12910 instruct vadd4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
       
 12911   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
       
 12912   match(Set dst (AddVF src1 src2));
       
 12913   size(4*4);
       
 12914   ins_cost(DEFAULT_COST*4); // FIXME
       
 12915 
       
 12916   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
       
 12917             "FADDS  $dst.b,$src1.b,$src2.b\n\t"
       
 12918             "FADDS  $dst.c,$src1.c,$src2.c\n\t"
       
 12919             "FADDS  $dst.d,$src1.d,$src2.d" %}
       
 12920 
       
 12921   ins_encode %{
       
 12922     FloatRegister dsta = $dst$$FloatRegister;
       
 12923     FloatRegister src1a = $src1$$FloatRegister;
       
 12924     FloatRegister src2a = $src2$$FloatRegister;
       
 12925     __ add_float(dsta, src1a, src2a);
       
 12926     FloatRegister dstb = dsta->successor();
       
 12927     FloatRegister src1b = src1a->successor();
       
 12928     FloatRegister src2b = src2a->successor();
       
 12929     __ add_float(dstb, src1b, src2b);
       
 12930     FloatRegister dstc = dstb->successor();
       
 12931     FloatRegister src1c = src1b->successor();
       
 12932     FloatRegister src2c = src2b->successor();
       
 12933     __ add_float(dstc, src1c, src2c);
       
 12934     FloatRegister dstd = dstc->successor();
       
 12935     FloatRegister src1d = src1c->successor();
       
 12936     FloatRegister src2d = src2c->successor();
       
 12937     __ add_float(dstd, src1d, src2d);
       
 12938   %}
       
 12939 
       
 12940   ins_pipe(faddF_reg_reg); // FIXME
       
 12941 %}
       
 12942 
       
 12943 instruct vadd2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
       
 12944   predicate(n->as_Vector()->length() == 2);
       
 12945   match(Set dst (AddVD src1 src2));
       
 12946   size(4*2);
       
 12947   ins_cost(DEFAULT_COST*2); // FIXME
       
 12948 
       
 12949   format %{ "FADDD  $dst.a,$src1.a,$src2.a\n\t"
       
 12950             "FADDD  $dst.b,$src1.b,$src2.b" %}
       
 12951 
       
 12952   ins_encode %{
       
 12953     FloatRegister dsta = $dst$$FloatRegister;
       
 12954     FloatRegister src1a = $src1$$FloatRegister;
       
 12955     FloatRegister src2a = $src2$$FloatRegister;
       
 12956     __ add_double(dsta, src1a, src2a);
       
 12957     FloatRegister dstb = dsta->successor()->successor();
       
 12958     FloatRegister src1b = src1a->successor()->successor();
       
 12959     FloatRegister src2b = src2a->successor()->successor();
       
 12960     __ add_double(dstb, src1b, src2b);
       
 12961   %}
       
 12962 
       
 12963   ins_pipe(faddF_reg_reg); // FIXME
       
 12964 %}
       
 12965 #endif
       
 12966 
       
 12967 
       
 12968 // Bytes vector sub
       
 12969 instruct vsub8B_reg(vecD dst, vecD src1, vecD src2) %{
       
 12970   predicate(n->as_Vector()->length() == 8);
       
 12971   match(Set dst (SubVB src1 src2));
       
 12972   size(4);
       
 12973   format %{ "VSUB.I8 $dst,$src1,$src2\t! sub packed8B" %}
       
 12974   ins_encode %{
       
 12975     bool quad = false;
       
 12976     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 12977              MacroAssembler::VELEM_SIZE_8, quad);
       
 12978   %}
       
 12979   ins_pipe( ialu_reg_reg ); // FIXME
       
 12980 %}
       
 12981 
       
 12982 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
       
 12983   predicate(n->as_Vector()->length() == 16);
       
 12984   match(Set dst (SubVB src1 src2));
       
 12985   size(4);
       
 12986   format %{ "VSUB.I8 $dst.Q,$src1.Q,$src2.Q\t! sub packed16B" %}
       
 12987   ins_encode %{
       
 12988     bool quad = true;
       
 12989     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 12990              MacroAssembler::VELEM_SIZE_8, quad);
       
 12991   %}
       
 12992   ins_pipe( ialu_reg_reg ); // FIXME
       
 12993 %}
       
 12994 
       
 12995 // Shorts/Chars vector sub
       
 12996 instruct vsub4S_reg(vecD dst, vecD src1, vecD src2) %{
       
 12997   predicate(n->as_Vector()->length() == 4);
       
 12998   match(Set dst (SubVS src1 src2));
       
 12999   size(4);
       
 13000   format %{ "VSUB.I16 $dst,$src1,$src2\t! sub packed4S" %}
       
 13001   ins_encode %{
       
 13002     bool quad = false;
       
 13003     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 13004              MacroAssembler::VELEM_SIZE_16, quad);
       
 13005   %}
       
 13006   ins_pipe( ialu_reg_reg ); // FIXME
       
 13007 %}
       
 13008 
       
 13009 instruct vsub16S_reg(vecX dst, vecX src1, vecX src2) %{
       
 13010   predicate(n->as_Vector()->length() == 8);
       
 13011   match(Set dst (SubVS src1 src2));
       
 13012   size(4);
       
 13013   format %{ "VSUB.I16 $dst.Q,$src1.Q,$src2.Q\t! sub packed8S" %}
       
 13014   ins_encode %{
       
 13015     bool quad = true;
       
 13016     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 13017              MacroAssembler::VELEM_SIZE_16, quad);
       
 13018   %}
       
 13019   ins_pipe( ialu_reg_reg ); // FIXME
       
 13020 %}
       
 13021 
       
 13022 // Integers vector sub
       
 13023 instruct vsub2I_reg(vecD dst, vecD src1, vecD src2) %{
       
 13024   predicate(n->as_Vector()->length() == 2);
       
 13025   match(Set dst (SubVI src1 src2));
       
 13026   size(4);
       
 13027   format %{ "VSUB.I32 $dst,$src1,$src2\t! sub packed2I" %}
       
 13028   ins_encode %{
       
 13029     bool quad = false;
       
 13030     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 13031              MacroAssembler::VELEM_SIZE_32, quad);
       
 13032   %}
       
 13033   ins_pipe( ialu_reg_reg ); // FIXME
       
 13034 %}
       
 13035 
       
 13036 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
       
 13037   predicate(n->as_Vector()->length() == 4);
       
 13038   match(Set dst (SubVI src1 src2));
       
 13039   size(4);
       
 13040   format %{ "VSUB.I32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4I" %}
       
 13041   ins_encode %{
       
 13042     bool quad = true;
       
 13043     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 13044              MacroAssembler::VELEM_SIZE_32, quad);
       
 13045   %}
       
 13046   ins_pipe( ialu_reg_reg ); // FIXME
       
 13047 %}
       
 13048 
       
 13049 // Longs vector sub
       
 13050 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
       
 13051   predicate(n->as_Vector()->length() == 2);
       
 13052   match(Set dst (SubVL src1 src2));
       
 13053   size(4);
       
 13054   format %{ "VSUB.I64 $dst.Q,$src1.Q,$src2.Q\t! sub packed2L" %}
       
 13055   ins_encode %{
       
 13056     bool quad = true;
       
 13057     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 13058              MacroAssembler::VELEM_SIZE_64, quad);
       
 13059   %}
       
 13060   ins_pipe( ialu_reg_reg ); // FIXME
       
 13061 %}
       
 13062 
       
 13063 // Floats vector sub
       
 13064 instruct vsub2F_reg(vecD dst, vecD src1, vecD src2) %{
       
 13065   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
       
 13066   match(Set dst (SubVF src1 src2));
       
 13067   size(4);
       
 13068   format %{ "VSUB.F32 $dst,$src1,$src2\t! sub packed2F" %}
       
 13069   ins_encode %{
       
 13070     bool quad = false;
       
 13071     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 13072              MacroAssembler::VFA_SIZE_F32, quad);
       
 13073   %}
       
 13074   ins_pipe( faddF_reg_reg ); // FIXME
       
 13075 %}
       
 13076 
       
 13077 #ifndef AARCH64
       
 13078 instruct vsub2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
       
 13079   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
       
 13080   match(Set dst (SubVF src1 src2));
       
 13081   size(4*2);
       
 13082   ins_cost(DEFAULT_COST*2); // FIXME
       
 13083 
       
 13084   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
       
 13085             "FSUBS  $dst.b,$src1.b,$src2.b" %}
       
 13086 
       
 13087   ins_encode %{
       
 13088     FloatRegister dsta = $dst$$FloatRegister;
       
 13089     FloatRegister src1a = $src1$$FloatRegister;
       
 13090     FloatRegister src2a = $src2$$FloatRegister;
       
 13091     __ sub_float(dsta, src1a, src2a);
       
 13092     FloatRegister dstb = dsta->successor();
       
 13093     FloatRegister src1b = src1a->successor();
       
 13094     FloatRegister src2b = src2a->successor();
       
 13095     __ sub_float(dstb, src1b, src2b);
       
 13096   %}
       
 13097 
       
 13098   ins_pipe(faddF_reg_reg); // FIXME
       
 13099 %}
       
 13100 #endif
       
 13101 
       
 13102 
       
 13103 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
       
 13104   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
       
 13105   match(Set dst (SubVF src1 src2));
       
 13106   size(4);
       
 13107   format %{ "VSUB.F32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4F" %}
       
 13108   ins_encode %{
       
 13109     bool quad = true;
       
 13110     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 13111              MacroAssembler::VFA_SIZE_F32, quad);
       
 13112   %}
       
 13113   ins_pipe( faddF_reg_reg ); // FIXME
       
 13114 %}
       
 13115 
       
 13116 #ifdef AARCH64
       
 13117 instruct vsub2D_reg_simd(vecX dst, vecX src1, vecX src2) %{
       
 13118   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
       
 13119   match(Set dst (SubVD src1 src2));
       
 13120   size(4);
       
 13121   format %{ "VSUB.F64 $dst.Q,$src1.Q,$src2.Q\t! add packed2D" %}
       
 13122   ins_encode %{
       
 13123     bool quad = true;
       
 13124     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 13125              MacroAssembler::VFA_SIZE_F64, quad);
       
 13126   %}
       
 13127   ins_pipe( faddD_reg_reg ); // FIXME
       
 13128 %}
       
 13129 #else
       
 13130 instruct vsub4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
       
 13131   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
       
 13132   match(Set dst (SubVF src1 src2));
       
 13133   size(4*4);
       
 13134   ins_cost(DEFAULT_COST*4); // FIXME
       
 13135 
       
 13136   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
       
 13137             "FSUBS  $dst.b,$src1.b,$src2.b\n\t"
       
 13138             "FSUBS  $dst.c,$src1.c,$src2.c\n\t"
       
 13139             "FSUBS  $dst.d,$src1.d,$src2.d" %}
       
 13140 
       
 13141   ins_encode %{
       
 13142     FloatRegister dsta = $dst$$FloatRegister;
       
 13143     FloatRegister src1a = $src1$$FloatRegister;
       
 13144     FloatRegister src2a = $src2$$FloatRegister;
       
 13145     __ sub_float(dsta, src1a, src2a);
       
 13146     FloatRegister dstb = dsta->successor();
       
 13147     FloatRegister src1b = src1a->successor();
       
 13148     FloatRegister src2b = src2a->successor();
       
 13149     __ sub_float(dstb, src1b, src2b);
       
 13150     FloatRegister dstc = dstb->successor();
       
 13151     FloatRegister src1c = src1b->successor();
       
 13152     FloatRegister src2c = src2b->successor();
       
 13153     __ sub_float(dstc, src1c, src2c);
       
 13154     FloatRegister dstd = dstc->successor();
       
 13155     FloatRegister src1d = src1c->successor();
       
 13156     FloatRegister src2d = src2c->successor();
       
 13157     __ sub_float(dstd, src1d, src2d);
       
 13158   %}
       
 13159 
       
 13160   ins_pipe(faddF_reg_reg); // FIXME
       
 13161 %}
       
 13162 
       
 13163 instruct vsub2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
       
 13164   predicate(n->as_Vector()->length() == 2);
       
 13165   match(Set dst (SubVD src1 src2));
       
 13166   size(4*2);
       
 13167   ins_cost(DEFAULT_COST*2); // FIXME
       
 13168 
       
 13169   format %{ "FSUBD  $dst.a,$src1.a,$src2.a\n\t"
       
 13170             "FSUBD  $dst.b,$src1.b,$src2.b" %}
       
 13171 
       
 13172   ins_encode %{
       
 13173     FloatRegister dsta = $dst$$FloatRegister;
       
 13174     FloatRegister src1a = $src1$$FloatRegister;
       
 13175     FloatRegister src2a = $src2$$FloatRegister;
       
 13176     __ sub_double(dsta, src1a, src2a);
       
 13177     FloatRegister dstb = dsta->successor()->successor();
       
 13178     FloatRegister src1b = src1a->successor()->successor();
       
 13179     FloatRegister src2b = src2a->successor()->successor();
       
 13180     __ sub_double(dstb, src1b, src2b);
       
 13181   %}
       
 13182 
       
 13183   ins_pipe(faddF_reg_reg); // FIXME
       
 13184 %}
       
 13185 #endif
       
 13186 
       
 13187 // Shorts/Chars vector mul
       
 13188 instruct vmul4S_reg(vecD dst, vecD src1, vecD src2) %{
       
 13189   predicate(n->as_Vector()->length() == 4);
       
 13190   match(Set dst (MulVS src1 src2));
       
 13191   size(4);
       
 13192   format %{ "VMUL.I16 $dst,$src1,$src2\t! mul packed4S" %}
       
 13193   ins_encode %{
       
 13194     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 13195              MacroAssembler::VELEM_SIZE_16, 0);
       
 13196   %}
       
 13197   ins_pipe( ialu_reg_reg ); // FIXME
       
 13198 %}
       
 13199 
       
 13200 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2) %{
       
 13201   predicate(n->as_Vector()->length() == 8);
       
 13202   match(Set dst (MulVS src1 src2));
       
 13203   size(4);
       
 13204   format %{ "VMUL.I16 $dst.Q,$src1.Q,$src2.Q\t! mul packed8S" %}
       
 13205   ins_encode %{
       
 13206     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 13207              MacroAssembler::VELEM_SIZE_16, 1);
       
 13208   %}
       
 13209   ins_pipe( ialu_reg_reg ); // FIXME
       
 13210 %}
       
 13211 
       
 13212 // Integers vector mul
       
 13213 instruct vmul2I_reg(vecD dst, vecD src1, vecD src2) %{
       
 13214   predicate(n->as_Vector()->length() == 2);
       
 13215   match(Set dst (MulVI src1 src2));
       
 13216   size(4);
       
 13217   format %{ "VMUL.I32 $dst,$src1,$src2\t! mul packed2I" %}
       
 13218   ins_encode %{
       
 13219     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 13220              MacroAssembler::VELEM_SIZE_32, 0);
       
 13221   %}
       
 13222   ins_pipe( ialu_reg_reg ); // FIXME
       
 13223 %}
       
 13224 
       
 13225 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
       
 13226   predicate(n->as_Vector()->length() == 4);
       
 13227   match(Set dst (MulVI src1 src2));
       
 13228   size(4);
       
 13229   format %{ "VMUL.I32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4I" %}
       
 13230   ins_encode %{
       
 13231     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 13232              MacroAssembler::VELEM_SIZE_32, 1);
       
 13233   %}
       
 13234   ins_pipe( ialu_reg_reg ); // FIXME
       
 13235 %}
       
 13236 
       
 13237 // Floats vector mul
       
 13238 instruct vmul2F_reg(vecD dst, vecD src1, vecD src2) %{
       
 13239   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
       
 13240   match(Set dst (MulVF src1 src2));
       
 13241   size(4);
       
 13242   format %{ "VMUL.F32 $dst,$src1,$src2\t! mul packed2F" %}
       
 13243   ins_encode %{
       
 13244     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 13245              MacroAssembler::VFA_SIZE_F32, 0);
       
 13246   %}
       
 13247   ins_pipe( fmulF_reg_reg ); // FIXME
       
 13248 %}
       
 13249 
       
 13250 #ifndef AARCH64
       
 13251 instruct vmul2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
       
 13252   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
       
 13253   match(Set dst (MulVF src1 src2));
       
 13254   size(4*2);
       
 13255   ins_cost(DEFAULT_COST*2); // FIXME
       
 13256 
       
 13257   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
       
 13258             "FMULS  $dst.b,$src1.b,$src2.b" %}
       
 13259   ins_encode %{
       
 13260     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
       
 13261     __ mul_float($dst$$FloatRegister->successor(),
       
 13262              $src1$$FloatRegister->successor(),
       
 13263              $src2$$FloatRegister->successor());
       
 13264   %}
       
 13265 
       
 13266   ins_pipe(fmulF_reg_reg); // FIXME
       
 13267 %}
       
 13268 #endif
       
 13269 
       
 13270 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
       
 13271   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
       
 13272   match(Set dst (MulVF src1 src2));
       
 13273   size(4);
       
 13274   format %{ "VMUL.F32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4F" %}
       
 13275   ins_encode %{
       
 13276     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 13277              MacroAssembler::VFA_SIZE_F32, 1);
       
 13278   %}
       
 13279   ins_pipe( fmulF_reg_reg ); // FIXME
       
 13280 %}
       
 13281 
       
 13282 #ifndef AARCH64
       
 13283 instruct vmul4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
       
 13284   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
       
 13285   match(Set dst (MulVF src1 src2));
       
 13286   size(4*4);
       
 13287   ins_cost(DEFAULT_COST*4); // FIXME
       
 13288 
       
 13289   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
       
 13290             "FMULS  $dst.b,$src1.b,$src2.b\n\t"
       
 13291             "FMULS  $dst.c,$src1.c,$src2.c\n\t"
       
 13292             "FMULS  $dst.d,$src1.d,$src2.d" %}
       
 13293 
       
 13294   ins_encode %{
       
 13295     FloatRegister dsta = $dst$$FloatRegister;
       
 13296     FloatRegister src1a = $src1$$FloatRegister;
       
 13297     FloatRegister src2a = $src2$$FloatRegister;
       
 13298     __ mul_float(dsta, src1a, src2a);
       
 13299     FloatRegister dstb = dsta->successor();
       
 13300     FloatRegister src1b = src1a->successor();
       
 13301     FloatRegister src2b = src2a->successor();
       
 13302     __ mul_float(dstb, src1b, src2b);
       
 13303     FloatRegister dstc = dstb->successor();
       
 13304     FloatRegister src1c = src1b->successor();
       
 13305     FloatRegister src2c = src2b->successor();
       
 13306     __ mul_float(dstc, src1c, src2c);
       
 13307     FloatRegister dstd = dstc->successor();
       
 13308     FloatRegister src1d = src1c->successor();
       
 13309     FloatRegister src2d = src2c->successor();
       
 13310     __ mul_float(dstd, src1d, src2d);
       
 13311   %}
       
 13312 
       
 13313   ins_pipe(fmulF_reg_reg); // FIXME
       
 13314 %}
       
 13315 #endif
       
 13316 
       
 13317 #ifdef AARCH64
       
 13318 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{
       
 13319   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
       
 13320   match(Set dst (MulVD src1 src2));
       
 13321   size(4*1);
       
 13322   ins_cost(DEFAULT_COST*1); // FIXME
       
 13323 
       
 13324   format %{ "FMUL.2D $dst,$src1,$src2\t! double[2]" %}
       
 13325   ins_encode %{
       
 13326     int quad = 1;
       
 13327     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 13328              MacroAssembler::VFA_SIZE_F64, quad);
       
 13329   %}
       
 13330 
       
 13331   ins_pipe(fdivF_reg_reg); // FIXME
       
 13332 %}
       
 13333 #else
       
 13334 instruct vmul2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
       
 13335   predicate(n->as_Vector()->length() == 2);
       
 13336   match(Set dst (MulVD src1 src2));
       
 13337   size(4*2);
       
 13338   ins_cost(DEFAULT_COST*2); // FIXME
       
 13339 
       
 13340   format %{ "FMULD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
       
 13341             "FMULD  $dst.D.b,$src1.D.b,$src2.D.b" %}
       
 13342   ins_encode %{
       
 13343     FloatRegister dsta = $dst$$FloatRegister;
       
 13344     FloatRegister src1a = $src1$$FloatRegister;
       
 13345     FloatRegister src2a = $src2$$FloatRegister;
       
 13346     __ mul_double(dsta, src1a, src2a);
       
 13347     FloatRegister dstb = dsta->successor()->successor();
       
 13348     FloatRegister src1b = src1a->successor()->successor();
       
 13349     FloatRegister src2b = src2a->successor()->successor();
       
 13350     __ mul_double(dstb, src1b, src2b);
       
 13351   %}
       
 13352 
       
 13353   ins_pipe(fmulD_reg_reg); // FIXME
       
 13354 %}
       
 13355 #endif
       
 13356 
       
 13357 
       
 13358 // Floats vector div
       
 13359 instruct vdiv2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
       
 13360   predicate(n->as_Vector()->length() == 2);
       
 13361   match(Set dst (DivVF src1 src2));
       
 13362 #ifdef AARCH64
       
 13363   size(4*1);
       
 13364   ins_cost(DEFAULT_COST*1); // FIXME
       
 13365 
       
 13366   format %{ "FDIV.2S $dst,$src1,$src2\t! float[2]" %}
       
 13367   ins_encode %{
       
 13368     int quad = 0;
       
 13369     __ vdivF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 13370              MacroAssembler::VFA_SIZE_F32, quad);
       
 13371   %}
       
 13372 
       
 13373   ins_pipe(fdivF_reg_reg); // FIXME
       
 13374 #else
       
 13375   size(4*2);
       
 13376   ins_cost(DEFAULT_COST*2); // FIXME
       
 13377 
       
 13378   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
       
 13379             "FDIVS  $dst.b,$src1.b,$src2.b" %}
       
 13380   ins_encode %{
       
 13381     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
       
 13382     __ div_float($dst$$FloatRegister->successor(),
       
 13383              $src1$$FloatRegister->successor(),
       
 13384              $src2$$FloatRegister->successor());
       
 13385   %}
       
 13386 
       
 13387   ins_pipe(fdivF_reg_reg); // FIXME
       
 13388 #endif
       
 13389 %}
       
 13390 
       
 13391 instruct vdiv4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
       
 13392   predicate(n->as_Vector()->length() == 4);
       
 13393   match(Set dst (DivVF src1 src2));
       
 13394 #ifdef AARCH64
       
 13395   size(4*1);
       
 13396   ins_cost(DEFAULT_COST*1); // FIXME
       
 13397 
       
 13398   format %{ "FDIV.4S $dst,$src1,$src2\t! float[4]" %}
       
 13399   ins_encode %{
       
 13400     int quad = 1;
       
 13401     __ vdivF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 13402              MacroAssembler::VFA_SIZE_F32, quad);
       
 13403   %}
       
 13404 
       
 13405   ins_pipe(fdivF_reg_reg); // FIXME
       
 13406 #else
       
 13407   size(4*4);
       
 13408   ins_cost(DEFAULT_COST*4); // FIXME
       
 13409 
       
 13410   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
       
 13411             "FDIVS  $dst.b,$src1.b,$src2.b\n\t"
       
 13412             "FDIVS  $dst.c,$src1.c,$src2.c\n\t"
       
 13413             "FDIVS  $dst.d,$src1.d,$src2.d" %}
       
 13414 
       
 13415   ins_encode %{
       
 13416     FloatRegister dsta = $dst$$FloatRegister;
       
 13417     FloatRegister src1a = $src1$$FloatRegister;
       
 13418     FloatRegister src2a = $src2$$FloatRegister;
       
 13419     __ div_float(dsta, src1a, src2a);
       
 13420     FloatRegister dstb = dsta->successor();
       
 13421     FloatRegister src1b = src1a->successor();
       
 13422     FloatRegister src2b = src2a->successor();
       
 13423     __ div_float(dstb, src1b, src2b);
       
 13424     FloatRegister dstc = dstb->successor();
       
 13425     FloatRegister src1c = src1b->successor();
       
 13426     FloatRegister src2c = src2b->successor();
       
 13427     __ div_float(dstc, src1c, src2c);
       
 13428     FloatRegister dstd = dstc->successor();
       
 13429     FloatRegister src1d = src1c->successor();
       
 13430     FloatRegister src2d = src2c->successor();
       
 13431     __ div_float(dstd, src1d, src2d);
       
 13432   %}
       
 13433 
       
 13434   ins_pipe(fdivF_reg_reg); // FIXME
       
 13435 #endif
       
 13436 %}
       
 13437 
       
 13438 #ifdef AARCH64
       
 13439 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{
       
 13440   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
       
 13441   match(Set dst (DivVD src1 src2));
       
 13442   size(4*1);
       
 13443   ins_cost(DEFAULT_COST*1); // FIXME
       
 13444 
       
 13445   format %{ "FDIV.2D $dst,$src1,$src2\t! double[2]" %}
       
 13446   ins_encode %{
       
 13447     int quad = 1;
       
 13448     __ vdivF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 13449              MacroAssembler::VFA_SIZE_F64, quad);
       
 13450   %}
       
 13451 
       
 13452   ins_pipe(fdivF_reg_reg); // FIXME
       
 13453 %}
       
 13454 #else
       
 13455 instruct vdiv2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
       
 13456   predicate(n->as_Vector()->length() == 2);
       
 13457   match(Set dst (DivVD src1 src2));
       
 13458   size(4*2);
       
 13459   ins_cost(DEFAULT_COST*2); // FIXME
       
 13460 
       
 13461   format %{ "FDIVD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
       
 13462             "FDIVD  $dst.D.b,$src1.D.b,$src2.D.b" %}
       
 13463   ins_encode %{
       
 13464     FloatRegister dsta = $dst$$FloatRegister;
       
 13465     FloatRegister src1a = $src1$$FloatRegister;
       
 13466     FloatRegister src2a = $src2$$FloatRegister;
       
 13467     __ div_double(dsta, src1a, src2a);
       
 13468     FloatRegister dstb = dsta->successor()->successor();
       
 13469     FloatRegister src1b = src1a->successor()->successor();
       
 13470     FloatRegister src2b = src2a->successor()->successor();
       
 13471     __ div_double(dstb, src1b, src2b);
       
 13472   %}
       
 13473 
       
 13474   ins_pipe(fdivD_reg_reg); // FIXME
       
 13475 %}
       
 13476 #endif
       
 13477 
       
 13478 // --------------------------------- NEG --------------------------------------
       
 13479 
       
 13480 instruct vneg8B_reg(vecD dst, vecD src) %{
       
 13481   predicate(n->as_Vector()->length_in_bytes() == 8);
       
 13482   effect(DEF dst, USE src);
       
 13483   size(4);
       
 13484   ins_cost(DEFAULT_COST); // FIXME
       
 13485   format %{ "VNEG.S8 $dst.D,$src.D\t! neg packed8B" %}
       
 13486   ins_encode %{
       
 13487     bool quad = false;
       
 13488     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
       
 13489               MacroAssembler::VELEM_SIZE_8, quad);
       
 13490   %}
       
 13491   ins_pipe( ialu_reg_reg ); // FIXME
       
 13492 %}
       
 13493 
       
 13494 instruct vneg16B_reg(vecX dst, vecX src) %{
       
 13495   predicate(n->as_Vector()->length_in_bytes() == 16);
       
 13496   effect(DEF dst, USE src);
       
 13497   size(4);
       
 13498   ins_cost(DEFAULT_COST); // FIXME
       
 13499   format %{ "VNEG.S8 $dst.Q,$src.Q\t! neg0 packed16B" %}
       
 13500   ins_encode %{
       
 13501     bool _float = false;
       
 13502     bool quad = true;
       
 13503     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
       
 13504               MacroAssembler::VELEM_SIZE_8, quad);
       
 13505   %}
       
 13506   ins_pipe( ialu_reg_reg ); // FIXME
       
 13507 %}
       
 13508 
       
 13509 // ------------------------------ Shift ---------------------------------------
       
 13510 
       
 13511 instruct vslcntD(vecD dst, iRegI cnt) %{
       
 13512   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
       
 13513   match(Set dst (LShiftCntV cnt));
       
 13514   size(4);
       
 13515   ins_cost(DEFAULT_COST); // FIXME
       
 13516   expand %{
       
 13517     Repl8B_reg_simd(dst, cnt);
       
 13518   %}
       
 13519 %}
       
 13520 
       
 13521 instruct vslcntX(vecX dst, iRegI cnt) %{
       
 13522   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
       
 13523   match(Set dst (LShiftCntV cnt));
       
 13524   size(4);
       
 13525   ins_cost(DEFAULT_COST); // FIXME
       
 13526   expand %{
       
 13527     Repl16B_reg(dst, cnt);
       
 13528   %}
       
 13529 %}
       
 13530 
       
 13531 // Low bits of vector "shift" elements are used, so it
       
 13532 // doesn't matter if we treat it as ints or bytes here.
       
 13533 instruct vsrcntD(vecD dst, iRegI cnt) %{
       
 13534   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
       
 13535   match(Set dst (RShiftCntV cnt));
       
 13536   size(4*2);
       
 13537   ins_cost(DEFAULT_COST*2); // FIXME
       
 13538 
       
 13539   format %{ "VDUP.8 $dst.D,$cnt\n\t"
       
 13540             "VNEG.S8 $dst.D,$dst.D\t! neg packed8B" %}
       
 13541   ins_encode %{
       
 13542     bool quad = false;
       
 13543     __ vdupI($dst$$FloatRegister, $cnt$$Register,
       
 13544              MacroAssembler::VELEM_SIZE_8, quad);
       
 13545     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
       
 13546               MacroAssembler::VELEM_SIZE_8, quad);
       
 13547   %}
       
 13548   ins_pipe( ialu_reg_reg ); // FIXME
       
 13549 %}
       
 13550 
       
 13551 instruct vsrcntX(vecX dst, iRegI cnt) %{
       
 13552   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
       
 13553   match(Set dst (RShiftCntV cnt));
       
 13554   size(4*2);
       
 13555   ins_cost(DEFAULT_COST*2); // FIXME
       
 13556   format %{ "VDUP.8 $dst.Q,$cnt\n\t"
       
 13557             "VNEG.S8 $dst.Q,$dst.Q\t! neg packed16B" %}
       
 13558   ins_encode %{
       
 13559     bool quad = true;
       
 13560     __ vdupI($dst$$FloatRegister, $cnt$$Register,
       
 13561              MacroAssembler::VELEM_SIZE_8, quad);
       
 13562     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
       
 13563               MacroAssembler::VELEM_SIZE_8, quad);
       
 13564   %}
       
 13565   ins_pipe( ialu_reg_reg ); // FIXME
       
 13566 %}
       
 13567 
       
 13568 // Byte vector logical left/right shift based on sign
       
 13569 instruct vsh8B_reg(vecD dst, vecD src, vecD shift) %{
       
 13570   predicate(n->as_Vector()->length() == 8);
       
 13571   effect(DEF dst, USE src, USE shift);
       
 13572   size(4);
       
 13573   ins_cost(DEFAULT_COST); // FIXME
       
 13574   format %{
       
 13575     "VSHL.U8 $dst.D,$src.D,$shift.D\t! logical left/right shift packed8B"
       
 13576   %}
       
 13577   ins_encode %{
       
 13578     bool quad = false;
       
 13579     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
       
 13580               MacroAssembler::VELEM_SIZE_8, quad);
       
 13581   %}
       
 13582   ins_pipe( ialu_reg_reg ); // FIXME
       
 13583 %}
       
 13584 
       
 13585 instruct vsh16B_reg(vecX dst, vecX src, vecX shift) %{
       
 13586   predicate(n->as_Vector()->length() == 16);
       
 13587   effect(DEF dst, USE src, USE shift);
       
 13588   size(4);
       
 13589   ins_cost(DEFAULT_COST); // FIXME
       
 13590   format %{
       
 13591     "VSHL.U8 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed16B"
       
 13592   %}
       
 13593   ins_encode %{
       
 13594     bool quad = true;
       
 13595     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
       
 13596               MacroAssembler::VELEM_SIZE_8, quad);
       
 13597   %}
       
 13598   ins_pipe( ialu_reg_reg ); // FIXME
       
 13599 %}
       
 13600 
       
 13601 // Shorts/Char vector logical left/right shift based on sign
       
 13602 instruct vsh4S_reg(vecD dst, vecD src, vecD shift) %{
       
 13603   predicate(n->as_Vector()->length() == 4);
       
 13604   effect(DEF dst, USE src, USE shift);
       
 13605   size(4);
       
 13606   ins_cost(DEFAULT_COST); // FIXME
       
 13607   format %{
       
 13608     "VSHL.U16 $dst.D,$src.D,$shift.D\t! logical left/right shift packed4S"
       
 13609   %}
       
 13610   ins_encode %{
       
 13611     bool quad = false;
       
 13612     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
       
 13613               MacroAssembler::VELEM_SIZE_16, quad);
       
 13614   %}
       
 13615   ins_pipe( ialu_reg_reg ); // FIXME
       
 13616 %}
       
 13617 
       
 13618 instruct vsh8S_reg(vecX dst, vecX src, vecX shift) %{
       
 13619   predicate(n->as_Vector()->length() == 8);
       
 13620   effect(DEF dst, USE src, USE shift);
       
 13621   size(4);
       
 13622   ins_cost(DEFAULT_COST); // FIXME
       
 13623   format %{
       
 13624     "VSHL.U16 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed8S"
       
 13625   %}
       
 13626   ins_encode %{
       
 13627     bool quad = true;
       
 13628     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
       
 13629               MacroAssembler::VELEM_SIZE_16, quad);
       
 13630   %}
       
 13631   ins_pipe( ialu_reg_reg ); // FIXME
       
 13632 %}
       
 13633 
       
 13634 // Integers vector logical left/right shift based on sign
       
 13635 instruct vsh2I_reg(vecD dst, vecD src, vecD shift) %{
       
 13636   predicate(n->as_Vector()->length() == 2);
       
 13637   effect(DEF dst, USE src, USE shift);
       
 13638   size(4);
       
 13639   ins_cost(DEFAULT_COST); // FIXME
       
 13640   format %{
       
 13641     "VSHL.U32 $dst.D,$src.D,$shift.D\t! logical left/right shift packed2I"
       
 13642   %}
       
 13643   ins_encode %{
       
 13644     bool quad = false;
       
 13645     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
       
 13646               MacroAssembler::VELEM_SIZE_32, quad);
       
 13647   %}
       
 13648   ins_pipe( ialu_reg_reg ); // FIXME
       
 13649 %}
       
 13650 
       
 13651 instruct vsh4I_reg(vecX dst, vecX src, vecX shift) %{
       
 13652   predicate(n->as_Vector()->length() == 4);
       
 13653   effect(DEF dst, USE src, USE shift);
       
 13654   size(4);
       
 13655   ins_cost(DEFAULT_COST); // FIXME
       
 13656   format %{
       
 13657     "VSHL.U32 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed4I"
       
 13658   %}
       
 13659   ins_encode %{
       
 13660     bool quad = true;
       
 13661     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
       
 13662               MacroAssembler::VELEM_SIZE_32, quad);
       
 13663   %}
       
 13664   ins_pipe( ialu_reg_reg ); // FIXME
       
 13665 %}
       
 13666 
       
 13667 // Longs vector logical left/right shift based on sign
       
 13668 instruct vsh2L_reg(vecX dst, vecX src, vecX shift) %{
       
 13669   predicate(n->as_Vector()->length() == 2);
       
 13670   effect(DEF dst, USE src, USE shift);
       
 13671   size(4);
       
 13672   ins_cost(DEFAULT_COST); // FIXME
       
 13673   format %{
       
 13674     "VSHL.U64 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed2L"
       
 13675   %}
       
 13676   ins_encode %{
       
 13677     bool quad = true;
       
 13678     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
       
 13679               MacroAssembler::VELEM_SIZE_64, quad);
       
 13680   %}
       
 13681   ins_pipe( ialu_reg_reg ); // FIXME
       
 13682 %}
       
 13683 
       
 13684 // ------------------------------ LeftShift -----------------------------------
       
 13685 
       
 13686 // Byte vector left shift
       
 13687 instruct vsl8B_reg(vecD dst, vecD src, vecD shift) %{
       
 13688   predicate(n->as_Vector()->length() == 8);
       
 13689   match(Set dst (LShiftVB src shift));
       
 13690   size(4*1);
       
 13691   ins_cost(DEFAULT_COST*1); // FIXME
       
 13692   expand %{
       
 13693     vsh8B_reg(dst, src, shift);
       
 13694   %}
       
 13695 %}
       
 13696 
       
 13697 instruct vsl16B_reg(vecX dst, vecX src, vecX shift) %{
       
 13698   predicate(n->as_Vector()->length() == 16);
       
 13699   match(Set dst (LShiftVB src shift));
       
 13700   size(4*1);
       
 13701   ins_cost(DEFAULT_COST*1); // FIXME
       
 13702   expand %{
       
 13703     vsh16B_reg(dst, src, shift);
       
 13704   %}
       
 13705 %}
       
 13706 
       
 13707 instruct vsl8B_immI(vecD dst, vecD src, immI shift) %{
       
 13708   predicate(n->as_Vector()->length() == 8);
       
 13709   match(Set dst (LShiftVB src shift));
       
 13710   size(4);
       
 13711   ins_cost(DEFAULT_COST); // FIXME
       
 13712   format %{
       
 13713     "VSHL.I8 $dst.D,$src.D,$shift\t! logical left shift packed8B"
       
 13714   %}
       
 13715   ins_encode %{
       
 13716     bool quad = false;
       
 13717     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
       
 13718              quad);
       
 13719   %}
       
 13720   ins_pipe( ialu_reg_reg ); // FIXME
       
 13721 %}
       
 13722 
       
 13723 instruct vsl16B_immI(vecX dst, vecX src, immI shift) %{
       
 13724   predicate(n->as_Vector()->length() == 16);
       
 13725   match(Set dst (LShiftVB src shift));
       
 13726   size(4);
       
 13727   ins_cost(DEFAULT_COST); // FIXME
       
 13728   format %{
       
 13729     "VSHL.I8 $dst.Q,$src.Q,$shift\t! logical left shift packed16B"
       
 13730   %}
       
 13731   ins_encode %{
       
 13732     bool quad = true;
       
 13733     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
       
 13734              quad);
       
 13735   %}
       
 13736   ins_pipe( ialu_reg_reg ); // FIXME
       
 13737 %}
       
 13738 
       
 13739 // Shorts/Chars vector logical left/right shift
       
 13740 instruct vsl4S_reg(vecD dst, vecD src, vecD shift) %{
       
 13741   predicate(n->as_Vector()->length() == 4);
       
 13742   match(Set dst (LShiftVS src shift));
       
 13743   match(Set dst (URShiftVS src shift));
       
 13744   size(4*1);
       
 13745   ins_cost(DEFAULT_COST*1); // FIXME
       
 13746   expand %{
       
 13747     vsh4S_reg(dst, src, shift);
       
 13748   %}
       
 13749 %}
       
 13750 
       
 13751 instruct vsl8S_reg(vecX dst, vecX src, vecX shift) %{
       
 13752   predicate(n->as_Vector()->length() == 8);
       
 13753   match(Set dst (LShiftVS src shift));
       
 13754   match(Set dst (URShiftVS src shift));
       
 13755   size(4*1);
       
 13756   ins_cost(DEFAULT_COST*1); // FIXME
       
 13757   expand %{
       
 13758     vsh8S_reg(dst, src, shift);
       
 13759   %}
       
 13760 %}
       
 13761 
       
 13762 instruct vsl4S_immI(vecD dst, vecD src, immI shift) %{
       
 13763   predicate(n->as_Vector()->length() == 4);
       
 13764   match(Set dst (LShiftVS src shift));
       
 13765   size(4);
       
 13766   ins_cost(DEFAULT_COST); // FIXME
       
 13767   format %{
       
 13768     "VSHL.I16 $dst.D,$src.D,$shift\t! logical left shift packed4S"
       
 13769   %}
       
 13770   ins_encode %{
       
 13771     bool quad = false;
       
 13772     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
       
 13773              quad);
       
 13774   %}
       
 13775   ins_pipe( ialu_reg_reg ); // FIXME
       
 13776 %}
       
 13777 
       
 13778 instruct vsl8S_immI(vecX dst, vecX src, immI shift) %{
       
 13779   predicate(n->as_Vector()->length() == 8);
       
 13780   match(Set dst (LShiftVS src shift));
       
 13781   size(4);
       
 13782   ins_cost(DEFAULT_COST); // FIXME
       
 13783   format %{
       
 13784     "VSHL.I16 $dst.Q,$src.Q,$shift\t! logical left shift packed8S"
       
 13785   %}
       
 13786   ins_encode %{
       
 13787     bool quad = true;
       
 13788     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
       
 13789              quad);
       
 13790   %}
       
 13791   ins_pipe( ialu_reg_reg ); // FIXME
       
 13792 %}
       
 13793 
       
 13794 // Integers vector logical left/right shift
       
 13795 instruct vsl2I_reg(vecD dst, vecD src, vecD shift) %{
       
 13796   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
       
 13797   match(Set dst (LShiftVI src shift));
       
 13798   match(Set dst (URShiftVI src shift));
       
 13799   size(4*1);
       
 13800   ins_cost(DEFAULT_COST*1); // FIXME
       
 13801   expand %{
       
 13802     vsh2I_reg(dst, src, shift);
       
 13803   %}
       
 13804 %}
       
 13805 
       
 13806 instruct vsl4I_reg(vecX dst, vecX src, vecX shift) %{
       
 13807   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
       
 13808   match(Set dst (LShiftVI src shift));
       
 13809   match(Set dst (URShiftVI src shift));
       
 13810   size(4*1);
       
 13811   ins_cost(DEFAULT_COST*1); // FIXME
       
 13812   expand %{
       
 13813     vsh4I_reg(dst, src, shift);
       
 13814   %}
       
 13815 %}
       
 13816 
       
 13817 instruct vsl2I_immI(vecD dst, vecD src, immI shift) %{
       
 13818   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
       
 13819   match(Set dst (LShiftVI src shift));
       
 13820   size(4);
       
 13821   ins_cost(DEFAULT_COST); // FIXME
       
 13822   format %{
       
 13823     "VSHL.I32 $dst.D,$src.D,$shift\t! logical left shift packed2I"
       
 13824   %}
       
 13825   ins_encode %{
       
 13826     bool quad = false;
       
 13827     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
       
 13828              quad);
       
 13829   %}
       
 13830   ins_pipe( ialu_reg_reg ); // FIXME
       
 13831 %}
       
 13832 
       
 13833 instruct vsl4I_immI(vecX dst, vecX src, immI shift) %{
       
 13834   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
       
 13835   match(Set dst (LShiftVI src shift));
       
 13836   size(4);
       
 13837   ins_cost(DEFAULT_COST); // FIXME
       
 13838   format %{
       
 13839     "VSHL.I32 $dst.Q,$src.Q,$shift\t! logical left shift packed4I"
       
 13840   %}
       
 13841   ins_encode %{
       
 13842     bool quad = true;
       
 13843     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
       
 13844              quad);
       
 13845   %}
       
 13846   ins_pipe( ialu_reg_reg ); // FIXME
       
 13847 %}
       
 13848 
       
 13849 // Longs vector logical left/right shift
       
 13850 instruct vsl2L_reg(vecX dst, vecX src, vecX shift) %{
       
 13851   predicate(n->as_Vector()->length() == 2);
       
 13852   match(Set dst (LShiftVL src shift));
       
 13853   match(Set dst (URShiftVL src shift));
       
 13854   size(4*1);
       
 13855   ins_cost(DEFAULT_COST*1); // FIXME
       
 13856   expand %{
       
 13857     vsh2L_reg(dst, src, shift);
       
 13858   %}
       
 13859 %}
       
 13860 
       
 13861 instruct vsl2L_immI(vecX dst, vecX src, immI shift) %{
       
 13862   predicate(n->as_Vector()->length() == 2);
       
 13863   match(Set dst (LShiftVL src shift));
       
 13864   size(4);
       
 13865   ins_cost(DEFAULT_COST); // FIXME
       
 13866   format %{
       
 13867     "VSHL.I64 $dst.Q,$src.Q,$shift\t! logical left shift packed2L"
       
 13868   %}
       
 13869   ins_encode %{
       
 13870     bool quad = true;
       
 13871     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
       
 13872              quad);
       
 13873   %}
       
 13874   ins_pipe( ialu_reg_reg ); // FIXME
       
 13875 %}
       
 13876 
       
 13877 // ----------------------- LogicalRightShift -----------------------------------
       
 13878 
       
 13879 // Bytes/Shorts vector logical right shift produces incorrect Java result
       
 13880 // for negative data because java code convert short value into int with
       
 13881 // sign extension before a shift.
       
 13882 
       
 13883 // Chars vector logical right shift
       
 13884 instruct vsrl4S_immI(vecD dst, vecD src, immI shift) %{
       
 13885   predicate(n->as_Vector()->length() == 4);
       
 13886   match(Set dst (URShiftVS src shift));
       
 13887   size(4);
       
 13888   ins_cost(DEFAULT_COST); // FIXME
       
 13889   format %{
       
 13890     "VSHR.U16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
       
 13891   %}
       
 13892   ins_encode %{
       
 13893     bool quad = false;
       
 13894     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
       
 13895              quad);
       
 13896   %}
       
 13897   ins_pipe( ialu_reg_reg ); // FIXME
       
 13898 %}
       
 13899 
       
 13900 instruct vsrl8S_immI(vecX dst, vecX src, immI shift) %{
       
 13901   predicate(n->as_Vector()->length() == 8);
       
 13902   match(Set dst (URShiftVS src shift));
       
 13903   size(4);
       
 13904   ins_cost(DEFAULT_COST); // FIXME
       
 13905   format %{
       
 13906     "VSHR.U16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
       
 13907   %}
       
 13908   ins_encode %{
       
 13909     bool quad = true;
       
 13910     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
       
 13911              quad);
       
 13912   %}
       
 13913   ins_pipe( ialu_reg_reg ); // FIXME
       
 13914 %}
       
 13915 
       
 13916 // Integers vector logical right shift
       
 13917 instruct vsrl2I_immI(vecD dst, vecD src, immI shift) %{
       
 13918   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
       
 13919   match(Set dst (URShiftVI src shift));
       
 13920   size(4);
       
 13921   ins_cost(DEFAULT_COST); // FIXME
       
 13922   format %{
       
 13923     "VSHR.U32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
       
 13924   %}
       
 13925   ins_encode %{
       
 13926     bool quad = false;
       
 13927     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
       
 13928              quad);
       
 13929   %}
       
 13930   ins_pipe( ialu_reg_reg ); // FIXME
       
 13931 %}
       
 13932 
       
 13933 instruct vsrl4I_immI(vecX dst, vecX src, immI shift) %{
       
 13934   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
       
 13935   match(Set dst (URShiftVI src shift));
       
 13936   size(4);
       
 13937   ins_cost(DEFAULT_COST); // FIXME
       
 13938   format %{
       
 13939     "VSHR.U32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
       
 13940   %}
       
 13941   ins_encode %{
       
 13942     bool quad = true;
       
 13943     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
       
 13944              quad);
       
 13945   %}
       
 13946   ins_pipe( ialu_reg_reg ); // FIXME
       
 13947 %}
       
 13948 
       
 13949 // Longs vector logical right shift
       
 13950 instruct vsrl2L_immI(vecX dst, vecX src, immI shift) %{
       
 13951   predicate(n->as_Vector()->length() == 2);
       
 13952   match(Set dst (URShiftVL src shift));
       
 13953   size(4);
       
 13954   ins_cost(DEFAULT_COST); // FIXME
       
 13955   format %{
       
 13956     "VSHR.U64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
       
 13957   %}
       
 13958   ins_encode %{
       
 13959     bool quad = true;
       
 13960     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
       
 13961              quad);
       
 13962   %}
       
 13963   ins_pipe( ialu_reg_reg ); // FIXME
       
 13964 %}
       
 13965 
       
 13966 // ------------------- ArithmeticRightShift -----------------------------------
       
 13967 
       
 13968 // Bytes vector arithmetic left/right shift based on sign
       
 13969 instruct vsha8B_reg(vecD dst, vecD src, vecD shift) %{
       
 13970   predicate(n->as_Vector()->length() == 8);
       
 13971   effect(DEF dst, USE src, USE shift);
       
 13972   size(4);
       
 13973   ins_cost(DEFAULT_COST); // FIXME
       
 13974   format %{
       
 13975     "VSHL.S8 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed8B"
       
 13976   %}
       
 13977   ins_encode %{
       
 13978     bool quad = false;
       
 13979     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
       
 13980               MacroAssembler::VELEM_SIZE_8, quad);
       
 13981   %}
       
 13982   ins_pipe( ialu_reg_reg ); // FIXME
       
 13983 %}
       
 13984 
       
 13985 instruct vsha16B_reg(vecX dst, vecX src, vecX shift) %{
       
 13986   predicate(n->as_Vector()->length() == 16);
       
 13987   effect(DEF dst, USE src, USE shift);
       
 13988   size(4);
       
 13989   ins_cost(DEFAULT_COST); // FIXME
       
 13990   format %{
       
 13991     "VSHL.S8 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed16B"
       
 13992   %}
       
 13993   ins_encode %{
       
 13994     bool quad = true;
       
 13995     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
       
 13996               MacroAssembler::VELEM_SIZE_8, quad);
       
 13997   %}
       
 13998   ins_pipe( ialu_reg_reg ); // FIXME
       
 13999 %}
       
 14000 
       
 14001 // Shorts vector arithmetic left/right shift based on sign
       
 14002 instruct vsha4S_reg(vecD dst, vecD src, vecD shift) %{
       
 14003   predicate(n->as_Vector()->length() == 4);
       
 14004   effect(DEF dst, USE src, USE shift);
       
 14005   size(4);
       
 14006   ins_cost(DEFAULT_COST); // FIXME
       
 14007   format %{
       
 14008     "VSHL.S16 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed4S"
       
 14009   %}
       
 14010   ins_encode %{
       
 14011     bool quad = false;
       
 14012     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
       
 14013               MacroAssembler::VELEM_SIZE_16, quad);
       
 14014   %}
       
 14015   ins_pipe( ialu_reg_reg ); // FIXME
       
 14016 %}
       
 14017 
       
 14018 instruct vsha8S_reg(vecX dst, vecX src, vecX shift) %{
       
 14019   predicate(n->as_Vector()->length() == 8);
       
 14020   effect(DEF dst, USE src, USE shift);
       
 14021   size(4);
       
 14022   ins_cost(DEFAULT_COST); // FIXME
       
 14023   format %{
       
 14024     "VSHL.S16 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed8S"
       
 14025   %}
       
 14026   ins_encode %{
       
 14027     bool quad = true;
       
 14028     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
       
 14029               MacroAssembler::VELEM_SIZE_16, quad);
       
 14030   %}
       
 14031   ins_pipe( ialu_reg_reg ); // FIXME
       
 14032 %}
       
 14033 
       
 14034 // Integers vector arithmetic left/right shift based on sign
       
 14035 instruct vsha2I_reg(vecD dst, vecD src, vecD shift) %{
       
 14036   predicate(n->as_Vector()->length() == 2);
       
 14037   effect(DEF dst, USE src, USE shift);
       
 14038   size(4);
       
 14039   ins_cost(DEFAULT_COST); // FIXME
       
 14040   format %{
       
 14041     "VSHL.S32 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed2I"
       
 14042   %}
       
 14043   ins_encode %{
       
 14044     bool quad = false;
       
 14045     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
       
 14046               MacroAssembler::VELEM_SIZE_32, quad);
       
 14047   %}
       
 14048   ins_pipe( ialu_reg_reg ); // FIXME
       
 14049 %}
       
 14050 
       
 14051 instruct vsha4I_reg(vecX dst, vecX src, vecX shift) %{
       
 14052   predicate(n->as_Vector()->length() == 4);
       
 14053   effect(DEF dst, USE src, USE shift);
       
 14054   size(4);
       
 14055   ins_cost(DEFAULT_COST); // FIXME
       
 14056   format %{
       
 14057     "VSHL.S32 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed4I"
       
 14058   %}
       
 14059   ins_encode %{
       
 14060     bool quad = true;
       
 14061     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
       
 14062               MacroAssembler::VELEM_SIZE_32, quad);
       
 14063   %}
       
 14064   ins_pipe( ialu_reg_reg ); // FIXME
       
 14065 %}
       
 14066 
       
 14067 // Longs vector arithmetic left/right shift based on sign
       
 14068 instruct vsha2L_reg(vecX dst, vecX src, vecX shift) %{
       
 14069   predicate(n->as_Vector()->length() == 2);
       
 14070   effect(DEF dst, USE src, USE shift);
       
 14071   size(4);
       
 14072   ins_cost(DEFAULT_COST); // FIXME
       
 14073   format %{
       
 14074     "VSHL.S64 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed2L"
       
 14075   %}
       
 14076   ins_encode %{
       
 14077     bool quad = true;
       
 14078     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
       
 14079               MacroAssembler::VELEM_SIZE_64, quad);
       
 14080   %}
       
 14081   ins_pipe( ialu_reg_reg ); // FIXME
       
 14082 %}
       
 14083 
       
 14084 // Byte vector arithmetic right shift
       
 14085 
       
 14086 instruct vsra8B_reg(vecD dst, vecD src, vecD shift) %{
       
 14087   predicate(n->as_Vector()->length() == 8);
       
 14088   match(Set dst (RShiftVB src shift));
       
 14089   size(4);
       
 14090   ins_cost(DEFAULT_COST); // FIXME
       
 14091   expand %{
       
 14092     vsha8B_reg(dst, src, shift);
       
 14093   %}
       
 14094 %}
       
 14095 
       
 14096 instruct vsrl16B_reg(vecX dst, vecX src, vecX shift) %{
       
 14097   predicate(n->as_Vector()->length() == 16);
       
 14098   match(Set dst (RShiftVB src shift));
       
 14099   size(4);
       
 14100   ins_cost(DEFAULT_COST); // FIXME
       
 14101   expand %{
       
 14102     vsha16B_reg(dst, src, shift);
       
 14103   %}
       
 14104 %}
       
 14105 
       
 14106 instruct vsrl8B_immI(vecD dst, vecD src, immI shift) %{
       
 14107   predicate(n->as_Vector()->length() == 8);
       
 14108   match(Set dst (RShiftVB src shift));
       
 14109   size(4);
       
 14110   ins_cost(DEFAULT_COST); // FIXME
       
 14111   format %{
       
 14112     "VSHR.S8 $dst.D,$src.D,$shift\t! logical right shift packed8B"
       
 14113   %}
       
 14114   ins_encode %{
       
 14115     bool quad = false;
       
 14116     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
       
 14117              quad);
       
 14118   %}
       
 14119   ins_pipe( ialu_reg_reg ); // FIXME
       
 14120 %}
       
 14121 
       
 14122 instruct vsrl16B_immI(vecX dst, vecX src, immI shift) %{
       
 14123   predicate(n->as_Vector()->length() == 16);
       
 14124   match(Set dst (RShiftVB src shift));
       
 14125   size(4);
       
 14126   ins_cost(DEFAULT_COST); // FIXME
       
 14127   format %{
       
 14128     "VSHR.S8 $dst.Q,$src.Q,$shift\t! logical right shift packed16B"
       
 14129   %}
       
 14130   ins_encode %{
       
 14131     bool quad = true;
       
 14132     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
       
 14133              quad);
       
 14134   %}
       
 14135   ins_pipe( ialu_reg_reg ); // FIXME
       
 14136 %}
       
 14137 
       
 14138 // Shorts vector arithmetic right shift
       
 14139 instruct vsra4S_reg(vecD dst, vecD src, vecD shift) %{
       
 14140   predicate(n->as_Vector()->length() == 4);
       
 14141   match(Set dst (RShiftVS src shift));
       
 14142   size(4);
       
 14143   ins_cost(DEFAULT_COST); // FIXME
       
 14144   expand %{
       
 14145     vsha4S_reg(dst, src, shift);
       
 14146   %}
       
 14147 %}
       
 14148 
       
 14149 instruct vsra8S_reg(vecX dst, vecX src, vecX shift) %{
       
 14150   predicate(n->as_Vector()->length() == 8);
       
 14151   match(Set dst (RShiftVS src shift));
       
 14152   size(4);
       
 14153   ins_cost(DEFAULT_COST); // FIXME
       
 14154   expand %{
       
 14155     vsha8S_reg(dst, src, shift);
       
 14156   %}
       
 14157 %}
       
 14158 
       
 14159 instruct vsra4S_immI(vecD dst, vecD src, immI shift) %{
       
 14160   predicate(n->as_Vector()->length() == 4);
       
 14161   match(Set dst (RShiftVS src shift));
       
 14162   size(4);
       
 14163   ins_cost(DEFAULT_COST); // FIXME
       
 14164   format %{
       
 14165     "VSHR.S16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
       
 14166   %}
       
 14167   ins_encode %{
       
 14168     bool quad = false;
       
 14169     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
       
 14170              quad);
       
 14171   %}
       
 14172   ins_pipe( ialu_reg_reg ); // FIXME
       
 14173 %}
       
 14174 
       
 14175 instruct vsra8S_immI(vecX dst, vecX src, immI shift) %{
       
 14176   predicate(n->as_Vector()->length() == 8);
       
 14177   match(Set dst (RShiftVS src shift));
       
 14178   size(4);
       
 14179   ins_cost(DEFAULT_COST); // FIXME
       
 14180   format %{
       
 14181     "VSHR.S16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
       
 14182   %}
       
 14183   ins_encode %{
       
 14184     bool quad = true;
       
 14185     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
       
 14186              quad);
       
 14187   %}
       
 14188   ins_pipe( ialu_reg_reg ); // FIXME
       
 14189 %}
       
 14190 
       
 14191 // Integers vector arithmetic right shift
       
 14192 instruct vsra2I_reg(vecD dst, vecD src, vecD shift) %{
       
 14193   predicate(n->as_Vector()->length() == 2);
       
 14194   match(Set dst (RShiftVI src shift));
       
 14195   size(4);
       
 14196   ins_cost(DEFAULT_COST); // FIXME
       
 14197   expand %{
       
 14198     vsha2I_reg(dst, src, shift);
       
 14199   %}
       
 14200 %}
       
 14201 
       
 14202 instruct vsra4I_reg(vecX dst, vecX src, vecX shift) %{
       
 14203   predicate(n->as_Vector()->length() == 4);
       
 14204   match(Set dst (RShiftVI src shift));
       
 14205   size(4);
       
 14206   ins_cost(DEFAULT_COST); // FIXME
       
 14207   expand %{
       
 14208     vsha4I_reg(dst, src, shift);
       
 14209   %}
       
 14210 %}
       
 14211 
       
 14212 instruct vsra2I_immI(vecD dst, vecD src, immI shift) %{
       
 14213   predicate(n->as_Vector()->length() == 2);
       
 14214   match(Set dst (RShiftVI src shift));
       
 14215   size(4);
       
 14216   ins_cost(DEFAULT_COST); // FIXME
       
 14217   format %{
       
 14218     "VSHR.S32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
       
 14219   %}
       
 14220   ins_encode %{
       
 14221     bool quad = false;
       
 14222     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
       
 14223              quad);
       
 14224   %}
       
 14225   ins_pipe( ialu_reg_reg ); // FIXME
       
 14226 %}
       
 14227 
       
 14228 instruct vsra4I_immI(vecX dst, vecX src, immI shift) %{
       
 14229   predicate(n->as_Vector()->length() == 4);
       
 14230   match(Set dst (RShiftVI src shift));
       
 14231   size(4);
       
 14232   ins_cost(DEFAULT_COST); // FIXME
       
 14233   format %{
       
 14234     "VSHR.S32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
       
 14235   %}
       
 14236   ins_encode %{
       
 14237     bool quad = true;
       
 14238     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
       
 14239              quad);
       
 14240   %}
       
 14241   ins_pipe( ialu_reg_reg ); // FIXME
       
 14242 %}
       
 14243 
       
 14244 // Longs vector arithmetic right shift
       
 14245 instruct vsra2L_reg(vecX dst, vecX src, vecX shift) %{
       
 14246   predicate(n->as_Vector()->length() == 2);
       
 14247   match(Set dst (RShiftVL src shift));
       
 14248   size(4);
       
 14249   ins_cost(DEFAULT_COST); // FIXME
       
 14250   expand %{
       
 14251     vsha2L_reg(dst, src, shift);
       
 14252   %}
       
 14253 %}
       
 14254 
       
 14255 instruct vsra2L_immI(vecX dst, vecX src, immI shift) %{
       
 14256   predicate(n->as_Vector()->length() == 2);
       
 14257   match(Set dst (RShiftVL src shift));
       
 14258   size(4);
       
 14259   ins_cost(DEFAULT_COST); // FIXME
       
 14260   format %{
       
 14261     "VSHR.S64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
       
 14262   %}
       
 14263   ins_encode %{
       
 14264     bool quad = true;
       
 14265     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
       
 14266              quad);
       
 14267   %}
       
 14268   ins_pipe( ialu_reg_reg ); // FIXME
       
 14269 %}
       
 14270 
       
 14271 // --------------------------------- AND --------------------------------------
       
 14272 
       
 14273 instruct vandD(vecD dst, vecD src1, vecD src2) %{
       
 14274   predicate(n->as_Vector()->length_in_bytes() == 8);
       
 14275   match(Set dst (AndV src1 src2));
       
 14276   format %{ "VAND    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
       
 14277   ins_encode %{
       
 14278     bool quad = false;
       
 14279     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 14280              quad);
       
 14281   %}
       
 14282   ins_pipe( ialu_reg_reg ); // FIXME
       
 14283 %}
       
 14284 
       
 14285 instruct vandX(vecX dst, vecX src1, vecX src2) %{
       
 14286   predicate(n->as_Vector()->length_in_bytes() == 16);
       
 14287   match(Set dst (AndV src1 src2));
       
 14288   format %{ "VAND    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
       
 14289   ins_encode %{
       
 14290     bool quad = true;
       
 14291     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 14292              quad);
       
 14293   %}
       
 14294   ins_pipe( ialu_reg_reg ); // FIXME
       
 14295 %}
       
 14296 
       
 14297 // --------------------------------- OR ---------------------------------------
       
 14298 
       
 14299 instruct vorD(vecD dst, vecD src1, vecD src2) %{
       
 14300   predicate(n->as_Vector()->length_in_bytes() == 8);
       
 14301   match(Set dst (OrV src1 src2));
       
 14302   format %{ "VOR     $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
       
 14303   ins_encode %{
       
 14304     bool quad = false;
       
 14305     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 14306             quad);
       
 14307   %}
       
 14308   ins_pipe( ialu_reg_reg ); // FIXME
       
 14309 %}
       
 14310 
       
 14311 instruct vorX(vecX dst, vecX src1, vecX src2) %{
       
 14312   predicate(n->as_Vector()->length_in_bytes() == 16);
       
 14313   match(Set dst (OrV src1 src2));
       
 14314   format %{ "VOR     $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
       
 14315   ins_encode %{
       
 14316     bool quad = true;
       
 14317     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 14318             quad);
       
 14319   %}
       
 14320   ins_pipe( ialu_reg_reg ); // FIXME
       
 14321 %}
       
 14322 
       
 14323 // --------------------------------- XOR --------------------------------------
       
 14324 
       
 14325 instruct vxorD(vecD dst, vecD src1, vecD src2) %{
       
 14326   predicate(n->as_Vector()->length_in_bytes() == 8);
       
 14327   match(Set dst (XorV src1 src2));
       
 14328   format %{ "VXOR    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
       
 14329   ins_encode %{
       
 14330     bool quad = false;
       
 14331     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 14332              quad);
       
 14333   %}
       
 14334   ins_pipe( ialu_reg_reg ); // FIXME
       
 14335 %}
       
 14336 
       
 14337 instruct vxorX(vecX dst, vecX src1, vecX src2) %{
       
 14338   predicate(n->as_Vector()->length_in_bytes() == 16);
       
 14339   match(Set dst (XorV src1 src2));
       
 14340   format %{ "VXOR    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
       
 14341   ins_encode %{
       
 14342     bool quad = true;
       
 14343     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
       
 14344              quad);
       
 14345   %}
       
 14346   ins_pipe( ialu_reg_reg ); // FIXME
       
 14347 %}
       
 14348 
       
 14349 
       
 14350 //----------PEEPHOLE RULES-----------------------------------------------------
       
 14351 // These must follow all instruction definitions as they use the names
       
 14352 // defined in the instructions definitions.
       
 14353 //
       
 14354 // peepmatch ( root_instr_name [preceding_instruction]* );
       
 14355 //
       
 14356 // peepconstraint %{
       
 14357 // (instruction_number.operand_name relational_op instruction_number.operand_name
       
 14358 //  [, ...] );
       
 14359 // // instruction numbers are zero-based using left to right order in peepmatch
       
 14360 //
       
 14361 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
       
 14362 // // provide an instruction_number.operand_name for each operand that appears
       
 14363 // // in the replacement instruction's match rule
       
 14364 //
       
 14365 // ---------VM FLAGS---------------------------------------------------------
       
 14366 //
       
 14367 // All peephole optimizations can be turned off using -XX:-OptoPeephole
       
 14368 //
       
 14369 // Each peephole rule is given an identifying number starting with zero and
       
 14370 // increasing by one in the order seen by the parser.  An individual peephole
       
 14371 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
       
 14372 // on the command-line.
       
 14373 //
       
 14374 // ---------CURRENT LIMITATIONS----------------------------------------------
       
 14375 //
       
 14376 // Only match adjacent instructions in same basic block
       
 14377 // Only equality constraints
       
 14378 // Only constraints between operands, not (0.dest_reg == EAX_enc)
       
 14379 // Only one replacement instruction
       
 14380 //
       
 14381 // ---------EXAMPLE----------------------------------------------------------
       
 14382 //
       
 14383 // // pertinent parts of existing instructions in architecture description
       
 14384 // instruct movI(eRegI dst, eRegI src) %{
       
 14385 //   match(Set dst (CopyI src));
       
 14386 // %}
       
 14387 //
       
 14388 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
       
 14389 //   match(Set dst (AddI dst src));
       
 14390 //   effect(KILL cr);
       
 14391 // %}
       
 14392 //
       
 14393 // // Change (inc mov) to lea
       
 14394 // peephole %{
       
 14395 //   // increment preceeded by register-register move
       
 14396 //   peepmatch ( incI_eReg movI );
       
 14397 //   // require that the destination register of the increment
       
 14398 //   // match the destination register of the move
       
 14399 //   peepconstraint ( 0.dst == 1.dst );
       
 14400 //   // construct a replacement instruction that sets
       
 14401 //   // the destination to ( move's source register + one )
       
 14402 //   peepreplace ( incI_eReg_immI1( 0.dst 1.src 0.src ) );
       
 14403 // %}
       
 14404 //
       
 14405 
       
 14406 // // Change load of spilled value to only a spill
       
 14407 // instruct storeI(memory mem, eRegI src) %{
       
 14408 //   match(Set mem (StoreI mem src));
       
 14409 // %}
       
 14410 //
       
 14411 // instruct loadI(eRegI dst, memory mem) %{
       
 14412 //   match(Set dst (LoadI mem));
       
 14413 // %}
       
 14414 //
       
 14415 // peephole %{
       
 14416 //   peepmatch ( loadI storeI );
       
 14417 //   peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
       
 14418 //   peepreplace ( storeI( 1.mem 1.mem 1.src ) );
       
 14419 // %}
       
 14420 
       
 14421 //----------SMARTSPILL RULES---------------------------------------------------
       
 14422 // These must follow all instruction definitions as they use the names
       
 14423 // defined in the instructions definitions.
       
 14424 //
       
 14425 // ARM will probably not have any of these rules due to RISC instruction set.
       
 14426 
       
 14427 //----------PIPELINE-----------------------------------------------------------
       
 14428 // Rules which define the behavior of the target architectures pipeline.