1 //
   2 // Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
   3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4 //
   5 // This code is free software; you can redistribute it and/or modify it
   6 // under the terms of the GNU General Public License version 2 only, as
   7 // published by the Free Software Foundation.
   8 //
   9 // This code is distributed in the hope that it will be useful, but WITHOUT
  10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12 // version 2 for more details (a copy is included in the LICENSE file that
  13 // accompanied this code).
  14 //
  15 // You should have received a copy of the GNU General Public License version
  16 // 2 along with this work; if not, write to the Free Software Foundation,
  17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18 //
  19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20 // or visit www.oracle.com if you need additional information or have any
  21 // questions.
  22 //
  23 
  24 // ARM Architecture Description File
  25 
  26 //----------DEFINITION BLOCK---------------------------------------------------
  27 // Define name --> value mappings to inform the ADLC of an integer valued name
  28 // Current support includes integer values in the range [0, 0x7FFFFFFF]
  29 // Format:
  30 //        int_def  <name>         ( <int_value>, <expression>);
  31 // Generated Code in ad_<arch>.hpp
  32 //        #define  <name>   (<expression>)
  33 //        // value == <int_value>
  34 // Generated code in ad_<arch>.cpp adlc_verification()
  35 //        assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
  36 //
  37 definitions %{
  38 // The default cost (of an ALU instruction).
  39   int_def DEFAULT_COST      (    100,     100);
  40   int_def HUGE_COST         (1000000, 1000000);
  41 
  42 // Memory refs are twice as expensive as run-of-the-mill.
  43   int_def MEMORY_REF_COST   (    200, DEFAULT_COST * 2);
  44 
  45 // Branches are even more expensive.
  46   int_def BRANCH_COST       (    300, DEFAULT_COST * 3);
  47   int_def CALL_COST         (    300, DEFAULT_COST * 3);
  48 %}
  49 
  50 
  51 //----------SOURCE BLOCK-------------------------------------------------------
  52 // This is a block of C++ code which provides values, functions, and
  53 // definitions necessary in the rest of the architecture description
  54 source_hpp %{
  55 // Header information of the source block.
  56 // Method declarations/definitions which are used outside
  57 // the ad-scope can conveniently be defined here.
  58 //
  59 // To keep related declarations/definitions/uses close together,
  60 // we switch between source %{ }% and source_hpp %{ }% freely as needed.
  61 
  62 // Does destination need to be loaded in a register then passed to a
  63 // branch instruction?
  64 extern bool maybe_far_call(const CallNode *n);
  65 extern bool maybe_far_call(const MachCallNode *n);
  66 static inline bool cache_reachable() {
  67   return MacroAssembler::_cache_fully_reachable();
  68 }
  69 
  70 #define ldr_32 ldr
  71 #define str_32 str
  72 #define tst_32 tst
  73 #define teq_32 teq
  74 #if 1
  75 extern bool PrintOptoAssembly;
  76 #endif
  77 
  78 class c2 {
  79 public:
  80   static OptoRegPair return_value(int ideal_reg);
  81 };
  82 
  83 class CallStubImpl {
  84 
  85   //--------------------------------------------------------------
  86   //---<  Used for optimization in Compile::Shorten_branches  >---
  87   //--------------------------------------------------------------
  88 
  89  public:
  90   // Size of call trampoline stub.
  91   static uint size_call_trampoline() {
  92     return 0; // no call trampolines on this platform
  93   }
  94 
  95   // number of relocations needed by a call trampoline stub
  96   static uint reloc_call_trampoline() {
  97     return 0; // no call trampolines on this platform
  98   }
  99 };
 100 
 101 class HandlerImpl {
 102 
 103  public:
 104 
 105   static int emit_exception_handler(CodeBuffer &cbuf);
 106   static int emit_deopt_handler(CodeBuffer& cbuf);
 107 
 108   static uint size_exception_handler() {
 109     return ( 3 * 4 );
 110   }
 111 
 112 
 113   static uint size_deopt_handler() {
 114     return ( 9 * 4 );
 115   }
 116 
 117 };
 118 
 119 class Node::PD {
 120 public:
 121   enum NodeFlags {
 122     _last_flag = Node::_last_flag
 123   };
 124 };
 125 
 126 %}
 127 
 128 source %{
 129 #define __ _masm.
 130 
 131 static FloatRegister reg_to_FloatRegister_object(int register_encoding);
 132 static Register reg_to_register_object(int register_encoding);
 133 
 134 void PhaseOutput::pd_perform_mach_node_analysis() {
 135 }
 136 
 137 int MachNode::pd_alignment_required() const {
 138   return 1;
 139 }
 140 
 141 int MachNode::compute_padding(int current_offset) const {
 142   return 0;
 143 }
 144 
 145 // ****************************************************************************
 146 
 147 // REQUIRED FUNCTIONALITY
 148 
 149 // Indicate if the safepoint node needs the polling page as an input.
 150 // Since ARM does not have absolute addressing, it does.
 151 bool SafePointNode::needs_polling_address_input() {
 152   return true;
 153 }
 154 
 155 // emit an interrupt that is caught by the debugger (for debugging compiler)
 156 void emit_break(CodeBuffer &cbuf) {
 157   C2_MacroAssembler _masm(&cbuf);
 158   __ breakpoint();
 159 }
 160 
 161 #ifndef PRODUCT
 162 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream *st ) const {
 163   st->print("TA");
 164 }
 165 #endif
 166 
 167 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 168   emit_break(cbuf);
 169 }
 170 
 171 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
 172   return MachNode::size(ra_);
 173 }
 174 
 175 
 176 void emit_nop(CodeBuffer &cbuf) {
 177   C2_MacroAssembler _masm(&cbuf);
 178   __ nop();
 179 }
 180 
 181 
 182 void emit_call_reloc(CodeBuffer &cbuf, const MachCallNode *n, MachOper *m, RelocationHolder const& rspec) {
 183   int ret_addr_offset0 = n->as_MachCall()->ret_addr_offset();
 184   int call_site_offset = cbuf.insts()->mark_off();
 185   C2_MacroAssembler _masm(&cbuf);
 186   __ set_inst_mark(); // needed in emit_to_interp_stub() to locate the call
 187   address target = (address)m->method();
 188   assert(n->as_MachCall()->entry_point() == target, "sanity");
 189   assert(maybe_far_call(n) == !__ reachable_from_cache(target), "sanity");
 190   assert(cache_reachable() == __ cache_fully_reachable(), "sanity");
 191 
 192   assert(target != NULL, "need real address");
 193 
 194   int ret_addr_offset = -1;
 195   if (rspec.type() == relocInfo::runtime_call_type) {
 196     __ call(target, rspec);
 197     ret_addr_offset = __ offset();
 198   } else {
 199     // scratches Rtemp
 200     ret_addr_offset = __ patchable_call(target, rspec, true);
 201   }
 202   assert(ret_addr_offset - call_site_offset == ret_addr_offset0, "fix ret_addr_offset()");
 203 }
 204 
 205 //=============================================================================
 206 // REQUIRED FUNCTIONALITY for encoding
 207 void emit_lo(CodeBuffer &cbuf, int val) {  }
 208 void emit_hi(CodeBuffer &cbuf, int val) {  }
 209 
 210 
 211 //=============================================================================
 212 const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask();
 213 
 214 int ConstantTable::calculate_table_base_offset() const {
 215   int offset = -(size() / 2);
 216   // flds, fldd: 8-bit  offset multiplied by 4: +/- 1024
 217   // ldr, ldrb : 12-bit offset:                 +/- 4096
 218   if (!Assembler::is_simm10(offset)) {
 219     offset = Assembler::min_simm10;
 220   }
 221   return offset;
 222 }
 223 
 224 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
 225 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
 226   ShouldNotReachHere();
 227 }
 228 
 229 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
 230   Compile* C = ra_->C;
 231   ConstantTable& constant_table = C->output()->constant_table();
 232   C2_MacroAssembler _masm(&cbuf);
 233 
 234   Register r = as_Register(ra_->get_encode(this));
 235   CodeSection* consts_section = __ code()->consts();
 236   int consts_size = consts_section->align_at_start(consts_section->size());
 237   assert(constant_table.size() == consts_size, "must be: %d == %d", constant_table.size(), consts_size);
 238 
 239   // Materialize the constant table base.
 240   address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
 241   RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
 242   __ mov_address(r, baseaddr, rspec);
 243 }
 244 
 245 uint MachConstantBaseNode::size(PhaseRegAlloc*) const {
 246   return 8;
 247 }
 248 
 249 #ifndef PRODUCT
 250 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
 251   char reg[128];
 252   ra_->dump_register(this, reg);
 253   st->print("MOV_SLOW    &constanttable,%s\t! constant table base", reg);
 254 }
 255 #endif
 256 
 257 #ifndef PRODUCT
 258 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
 259   Compile* C = ra_->C;
 260 
 261   for (int i = 0; i < OptoPrologueNops; i++) {
 262     st->print_cr("NOP"); st->print("\t");
 263   }
 264 
 265   size_t framesize = C->output()->frame_size_in_bytes();
 266   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
 267   int bangsize = C->output()->bang_size_in_bytes();
 268   // Remove two words for return addr and rbp,
 269   framesize -= 2*wordSize;
 270   bangsize -= 2*wordSize;
 271 
 272   // Calls to C2R adapters often do not accept exceptional returns.
 273   // We require that their callers must bang for them.  But be careful, because
 274   // some VM calls (such as call site linkage) can use several kilobytes of
 275   // stack.  But the stack safety zone should account for that.
 276   // See bugs 4446381, 4468289, 4497237.
 277   if (C->output()->need_stack_bang(bangsize)) {
 278     st->print_cr("! stack bang (%d bytes)", bangsize); st->print("\t");
 279   }
 280   st->print_cr("PUSH   R_FP|R_LR_LR"); st->print("\t");
 281   if (framesize != 0) {
 282     st->print   ("SUB    R_SP, R_SP, " SIZE_FORMAT,framesize);
 283   }
 284 }
 285 #endif
 286 
 287 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 288   Compile* C = ra_->C;
 289   C2_MacroAssembler _masm(&cbuf);
 290 
 291   for (int i = 0; i < OptoPrologueNops; i++) {
 292     __ nop();
 293   }
 294 
 295   size_t framesize = C->output()->frame_size_in_bytes();
 296   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
 297   int bangsize = C->output()->bang_size_in_bytes();
 298   // Remove two words for return addr and fp,
 299   framesize -= 2*wordSize;
 300   bangsize -= 2*wordSize;
 301 
 302   // Calls to C2R adapters often do not accept exceptional returns.
 303   // We require that their callers must bang for them.  But be careful, because
 304   // some VM calls (such as call site linkage) can use several kilobytes of
 305   // stack.  But the stack safety zone should account for that.
 306   // See bugs 4446381, 4468289, 4497237.
 307   if (C->output()->need_stack_bang(bangsize)) {
 308     __ arm_stack_overflow_check(bangsize, Rtemp);
 309   }
 310 
 311   __ raw_push(FP, LR);
 312   if (framesize != 0) {
 313     __ sub_slow(SP, SP, framesize);
 314   }
 315 
 316   // offset from scratch buffer is not valid
 317   if (strcmp(cbuf.name(), "Compile::Fill_buffer") == 0) {
 318     C->output()->set_frame_complete( __ offset() );
 319   }
 320 
 321   if (C->has_mach_constant_base_node()) {
 322     // NOTE: We set the table base offset here because users might be
 323     // emitted before MachConstantBaseNode.
 324     ConstantTable& constant_table = C->output()->constant_table();
 325     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
 326   }
 327 }
 328 
 329 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
 330   return MachNode::size(ra_);
 331 }
 332 
 333 int MachPrologNode::reloc() const {
 334   return 10; // a large enough number
 335 }
 336 
 337 //=============================================================================
 338 #ifndef PRODUCT
 339 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
 340   Compile* C = ra_->C;
 341 
 342   size_t framesize = C->output()->frame_size_in_bytes();
 343   framesize -= 2*wordSize;
 344 
 345   if (framesize != 0) {
 346     st->print("ADD    R_SP, R_SP, " SIZE_FORMAT "\n\t",framesize);
 347   }
 348   st->print("POP    R_FP|R_LR_LR");
 349 
 350   if (do_polling() && ra_->C->is_method_compilation()) {
 351     st->print("\n\t");
 352     st->print("MOV    Rtemp, #PollAddr\t! Load Polling address\n\t");
 353     st->print("LDR    Rtemp,[Rtemp]\t!Poll for Safepointing");
 354   }
 355 }
 356 #endif
 357 
 358 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 359   C2_MacroAssembler _masm(&cbuf);
 360   Compile* C = ra_->C;
 361 
 362   size_t framesize = C->output()->frame_size_in_bytes();
 363   framesize -= 2*wordSize;
 364   if (framesize != 0) {
 365     __ add_slow(SP, SP, framesize);
 366   }
 367   __ raw_pop(FP, LR);
 368 
 369   // If this does safepoint polling, then do it here
 370   if (do_polling() && ra_->C->is_method_compilation()) {
 371     __ read_polling_page(Rtemp, relocInfo::poll_return_type);
 372   }
 373 }
 374 
 375 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
 376   return MachNode::size(ra_);
 377 }
 378 
 379 int MachEpilogNode::reloc() const {
 380   return 16; // a large enough number
 381 }
 382 
 383 const Pipeline * MachEpilogNode::pipeline() const {
 384   return MachNode::pipeline_class();
 385 }
 386 
 387 //=============================================================================
 388 
 389 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
 390 enum RC { rc_bad, rc_int, rc_float, rc_stack };
 391 static enum RC rc_class( OptoReg::Name reg ) {
 392   if (!OptoReg::is_valid(reg)) return rc_bad;
 393   if (OptoReg::is_stack(reg)) return rc_stack;
 394   VMReg r = OptoReg::as_VMReg(reg);
 395   if (r->is_Register()) return rc_int;
 396   assert(r->is_FloatRegister(), "must be");
 397   return rc_float;
 398 }
 399 
 400 static inline bool is_iRegLd_memhd(OptoReg::Name src_first, OptoReg::Name src_second, int offset) {
 401   int rlo = Matcher::_regEncode[src_first];
 402   int rhi = Matcher::_regEncode[src_second];
 403   if (!((rlo&1)==0 && (rlo+1 == rhi))) {
 404     tty->print_cr("CAUGHT BAD LDRD/STRD");
 405   }
 406   return (rlo&1)==0 && (rlo+1 == rhi) && is_memoryHD(offset);
 407 }
 408 
 409 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
 410                                         PhaseRegAlloc *ra_,
 411                                         bool do_size,
 412                                         outputStream* st ) const {
 413   // Get registers to move
 414   OptoReg::Name src_second = ra_->get_reg_second(in(1));
 415   OptoReg::Name src_first = ra_->get_reg_first(in(1));
 416   OptoReg::Name dst_second = ra_->get_reg_second(this );
 417   OptoReg::Name dst_first = ra_->get_reg_first(this );
 418 
 419   enum RC src_second_rc = rc_class(src_second);
 420   enum RC src_first_rc = rc_class(src_first);
 421   enum RC dst_second_rc = rc_class(dst_second);
 422   enum RC dst_first_rc = rc_class(dst_first);
 423 
 424   assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
 425 
 426   // Generate spill code!
 427   int size = 0;
 428 
 429   if (src_first == dst_first && src_second == dst_second)
 430     return size;            // Self copy, no move
 431 
 432 #ifdef TODO
 433   if (bottom_type()->isa_vect() != NULL) {
 434   }
 435 #endif
 436 
 437   // Shared code does not expect instruction set capability based bailouts here.
 438   // Handle offset unreachable bailout with minimal change in shared code.
 439   // Bailout only for real instruction emit.
 440   // This requires a single comment change in shared code. ( see output.cpp "Normal" instruction case )
 441 
 442   C2_MacroAssembler _masm(cbuf);
 443 
 444   // --------------------------------------
 445   // Check for mem-mem move.  Load into unused float registers and fall into
 446   // the float-store case.
 447   if (src_first_rc == rc_stack && dst_first_rc == rc_stack) {
 448     int offset = ra_->reg2offset(src_first);
 449     if (cbuf && !is_memoryfp(offset)) {
 450       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 451       return 0;
 452     } else {
 453       if (src_second_rc != rc_bad) {
 454         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
 455         src_first     = OptoReg::Name(R_mem_copy_lo_num);
 456         src_second    = OptoReg::Name(R_mem_copy_hi_num);
 457         src_first_rc  = rc_float;
 458         src_second_rc = rc_float;
 459         if (cbuf) {
 460           __ ldr_double(Rmemcopy, Address(SP, offset));
 461         } else if (!do_size) {
 462           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
 463         }
 464       } else {
 465         src_first     = OptoReg::Name(R_mem_copy_lo_num);
 466         src_first_rc  = rc_float;
 467         if (cbuf) {
 468           __ ldr_float(Rmemcopy, Address(SP, offset));
 469         } else if (!do_size) {
 470           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
 471         }
 472       }
 473       size += 4;
 474     }
 475   }
 476 
 477   if (src_second_rc == rc_stack && dst_second_rc == rc_stack) {
 478     Unimplemented();
 479   }
 480 
 481   // --------------------------------------
 482   // Check for integer reg-reg copy
 483   if (src_first_rc == rc_int && dst_first_rc == rc_int) {
 484     // Else normal reg-reg copy
 485     assert( src_second != dst_first, "smashed second before evacuating it" );
 486     if (cbuf) {
 487       __ mov(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
 488 #ifndef PRODUCT
 489     } else if (!do_size) {
 490       st->print("MOV    R_%s, R_%s\t# spill",
 491                 Matcher::regName[dst_first],
 492                 Matcher::regName[src_first]);
 493 #endif
 494     }
 495     size += 4;
 496   }
 497 
 498   // Check for integer store
 499   if (src_first_rc == rc_int && dst_first_rc == rc_stack) {
 500     int offset = ra_->reg2offset(dst_first);
 501     if (cbuf && !is_memoryI(offset)) {
 502       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 503       return 0;
 504     } else {
 505       if (src_second_rc != rc_bad && is_iRegLd_memhd(src_first, src_second, offset)) {
 506         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
 507         if (cbuf) {
 508           __ str_64(reg_to_register_object(Matcher::_regEncode[src_first]), Address(SP, offset));
 509 #ifndef PRODUCT
 510         } else if (!do_size) {
 511           if (size != 0) st->print("\n\t");
 512           st->print(STR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
 513 #endif
 514         }
 515         return size + 4;
 516       } else {
 517         if (cbuf) {
 518           __ str_32(reg_to_register_object(Matcher::_regEncode[src_first]), Address(SP, offset));
 519 #ifndef PRODUCT
 520         } else if (!do_size) {
 521           if (size != 0) st->print("\n\t");
 522           st->print(STR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
 523 #endif
 524         }
 525       }
 526     }
 527     size += 4;
 528   }
 529 
 530   // Check for integer load
 531   if (dst_first_rc == rc_int && src_first_rc == rc_stack) {
 532     int offset = ra_->reg2offset(src_first);
 533     if (cbuf && !is_memoryI(offset)) {
 534       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 535       return 0;
 536     } else {
 537       if (src_second_rc != rc_bad && is_iRegLd_memhd(dst_first, dst_second, offset)) {
 538         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
 539         if (cbuf) {
 540           __ ldr_64(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
 541 #ifndef PRODUCT
 542         } else if (!do_size) {
 543           if (size != 0) st->print("\n\t");
 544           st->print(LDR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
 545 #endif
 546         }
 547         return size + 4;
 548       } else {
 549         if (cbuf) {
 550           __ ldr_32(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
 551 #ifndef PRODUCT
 552         } else if (!do_size) {
 553           if (size != 0) st->print("\n\t");
 554           st->print(LDR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
 555 #endif
 556         }
 557       }
 558     }
 559     size += 4;
 560   }
 561 
 562   // Check for float reg-reg copy
 563   if (src_first_rc == rc_float && dst_first_rc == rc_float) {
 564     if (src_second_rc != rc_bad) {
 565       assert((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
 566       if (cbuf) {
 567       __ mov_double(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
 568 #ifndef PRODUCT
 569       } else if (!do_size) {
 570         st->print(MOV_DOUBLE "    R_%s, R_%s\t# spill",
 571                   Matcher::regName[dst_first],
 572                   Matcher::regName[src_first]);
 573 #endif
 574       }
 575       return 4;
 576     }
 577     if (cbuf) {
 578       __ mov_float(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
 579 #ifndef PRODUCT
 580     } else if (!do_size) {
 581       st->print(MOV_FLOAT "    R_%s, R_%s\t# spill",
 582                 Matcher::regName[dst_first],
 583                 Matcher::regName[src_first]);
 584 #endif
 585     }
 586     size = 4;
 587   }
 588 
 589   // Check for float store
 590   if (src_first_rc == rc_float && dst_first_rc == rc_stack) {
 591     int offset = ra_->reg2offset(dst_first);
 592     if (cbuf && !is_memoryfp(offset)) {
 593       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 594       return 0;
 595     } else {
 596       // Further check for aligned-adjacent pair, so we can use a double store
 597       if (src_second_rc != rc_bad) {
 598         assert((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers and stack slots must be aligned/contiguous");
 599         if (cbuf) {
 600           __ str_double(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(SP, offset));
 601 #ifndef PRODUCT
 602         } else if (!do_size) {
 603           if (size != 0) st->print("\n\t");
 604           st->print(STR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
 605 #endif
 606         }
 607         return size + 4;
 608       } else {
 609         if (cbuf) {
 610           __ str_float(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(SP, offset));
 611 #ifndef PRODUCT
 612         } else if (!do_size) {
 613           if (size != 0) st->print("\n\t");
 614           st->print(STR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
 615 #endif
 616         }
 617       }
 618     }
 619     size += 4;
 620   }
 621 
 622   // Check for float load
 623   if (dst_first_rc == rc_float && src_first_rc == rc_stack) {
 624     int offset = ra_->reg2offset(src_first);
 625     if (cbuf && !is_memoryfp(offset)) {
 626       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 627       return 0;
 628     } else {
 629       // Further check for aligned-adjacent pair, so we can use a double store
 630       if (src_second_rc != rc_bad) {
 631         assert((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers and stack slots must be aligned/contiguous");
 632         if (cbuf) {
 633           __ ldr_double(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
 634 #ifndef PRODUCT
 635         } else if (!do_size) {
 636           if (size != 0) st->print("\n\t");
 637           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
 638 #endif
 639         }
 640         return size + 4;
 641       } else {
 642         if (cbuf) {
 643           __ ldr_float(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
 644 #ifndef PRODUCT
 645         } else if (!do_size) {
 646           if (size != 0) st->print("\n\t");
 647           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
 648 #endif
 649         }
 650       }
 651     }
 652     size += 4;
 653   }
 654 
 655   // check for int reg -> float reg move
 656   if (src_first_rc == rc_int && dst_first_rc == rc_float) {
 657     // Further check for aligned-adjacent pair, so we can use a single instruction
 658     if (src_second_rc != rc_bad) {
 659       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
 660       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
 661       assert(src_second_rc == rc_int && dst_second_rc == rc_float, "unsupported");
 662       if (cbuf) {
 663         __ fmdrr(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]), reg_to_register_object(Matcher::_regEncode[src_second]));
 664 #ifndef PRODUCT
 665       } else if (!do_size) {
 666         if (size != 0) st->print("\n\t");
 667         st->print("FMDRR   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first), OptoReg::regname(src_second));
 668 #endif
 669       }
 670       return size + 4;
 671     } else {
 672       if (cbuf) {
 673         __ fmsr(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
 674 #ifndef PRODUCT
 675       } else if (!do_size) {
 676         if (size != 0) st->print("\n\t");
 677         st->print(FMSR "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
 678 #endif
 679       }
 680       size += 4;
 681     }
 682   }
 683 
 684   // check for float reg -> int reg move
 685   if (src_first_rc == rc_float && dst_first_rc == rc_int) {
 686     // Further check for aligned-adjacent pair, so we can use a single instruction
 687     if (src_second_rc != rc_bad) {
 688       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
 689       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
 690       assert(src_second_rc == rc_float && dst_second_rc == rc_int, "unsupported");
 691       if (cbuf) {
 692         __ fmrrd(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[dst_second]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
 693 #ifndef PRODUCT
 694       } else if (!do_size) {
 695         if (size != 0) st->print("\n\t");
 696         st->print("FMRRD   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(dst_second), OptoReg::regname(src_first));
 697 #endif
 698       }
 699       return size + 4;
 700     } else {
 701       if (cbuf) {
 702         __ fmrs(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
 703 #ifndef PRODUCT
 704       } else if (!do_size) {
 705         if (size != 0) st->print("\n\t");
 706         st->print(FMRS "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
 707 #endif
 708       }
 709       size += 4;
 710     }
 711   }
 712 
 713   // --------------------------------------------------------------------
 714   // Check for hi bits still needing moving.  Only happens for misaligned
 715   // arguments to native calls.
 716   if (src_second == dst_second)
 717     return size;               // Self copy; no move
 718   assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" );
 719 
 720   // Check for integer reg-reg copy.  Hi bits are stuck up in the top
 721   // 32-bits of a 64-bit register, but are needed in low bits of another
 722   // register (else it's a hi-bits-to-hi-bits copy which should have
 723   // happened already as part of a 64-bit move)
 724   if (src_second_rc == rc_int && dst_second_rc == rc_int) {
 725     if (cbuf) {
 726       __ mov(reg_to_register_object(Matcher::_regEncode[dst_second]), reg_to_register_object(Matcher::_regEncode[src_second]));
 727 #ifndef PRODUCT
 728     } else if (!do_size) {
 729       if (size != 0) st->print("\n\t");
 730       st->print("MOV    R_%s, R_%s\t# spill high",
 731                 Matcher::regName[dst_second],
 732                 Matcher::regName[src_second]);
 733 #endif
 734     }
 735     return size+4;
 736   }
 737 
 738   // Check for high word integer store
 739   if (src_second_rc == rc_int && dst_second_rc == rc_stack) {
 740     int offset = ra_->reg2offset(dst_second);
 741 
 742     if (cbuf && !is_memoryP(offset)) {
 743       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 744       return 0;
 745     } else {
 746       if (cbuf) {
 747         __ str(reg_to_register_object(Matcher::_regEncode[src_second]), Address(SP, offset));
 748 #ifndef PRODUCT
 749       } else if (!do_size) {
 750         if (size != 0) st->print("\n\t");
 751         st->print("STR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_second), offset);
 752 #endif
 753       }
 754     }
 755     return size + 4;
 756   }
 757 
 758   // Check for high word integer load
 759   if (dst_second_rc == rc_int && src_second_rc == rc_stack) {
 760     int offset = ra_->reg2offset(src_second);
 761     if (cbuf && !is_memoryP(offset)) {
 762       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 763       return 0;
 764     } else {
 765       if (cbuf) {
 766         __ ldr(reg_to_register_object(Matcher::_regEncode[dst_second]), Address(SP, offset));
 767 #ifndef PRODUCT
 768       } else if (!do_size) {
 769         if (size != 0) st->print("\n\t");
 770         st->print("LDR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_second), offset);
 771 #endif
 772       }
 773     }
 774     return size + 4;
 775   }
 776 
 777   Unimplemented();
 778   return 0; // Mute compiler
 779 }
 780 
 781 #ifndef PRODUCT
 782 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
 783   implementation( NULL, ra_, false, st );
 784 }
 785 #endif
 786 
 787 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 788   implementation( &cbuf, ra_, false, NULL );
 789 }
 790 
 791 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
 792   return implementation( NULL, ra_, true, NULL );
 793 }
 794 
 795 //=============================================================================
 796 #ifndef PRODUCT
 797 void MachNopNode::format( PhaseRegAlloc *, outputStream *st ) const {
 798   st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
 799 }
 800 #endif
 801 
 802 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
 803   C2_MacroAssembler _masm(&cbuf);
 804   for(int i = 0; i < _count; i += 1) {
 805     __ nop();
 806   }
 807 }
 808 
 809 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
 810   return 4 * _count;
 811 }
 812 
 813 
 814 //=============================================================================
 815 #ifndef PRODUCT
 816 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
 817   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
 818   int reg = ra_->get_reg_first(this);
 819   st->print("ADD    %s,R_SP+#%d",Matcher::regName[reg], offset);
 820 }
 821 #endif
 822 
 823 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 824   C2_MacroAssembler _masm(&cbuf);
 825   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
 826   int reg = ra_->get_encode(this);
 827   Register dst = reg_to_register_object(reg);
 828 
 829   if (is_aimm(offset)) {
 830     __ add(dst, SP, offset);
 831   } else {
 832     __ mov_slow(dst, offset);
 833     __ add(dst, SP, dst);
 834   }
 835 }
 836 
 837 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
 838   // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_)
 839   assert(ra_ == ra_->C->regalloc(), "sanity");
 840   return ra_->C->output()->scratch_emit_size(this);
 841 }
 842 
 843 //=============================================================================
 844 #ifndef PRODUCT
 845 #define R_RTEMP "R_R12"
 846 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
 847   st->print_cr("\nUEP:");
 848   if (UseCompressedClassPointers) {
 849     st->print_cr("\tLDR_w " R_RTEMP ",[R_R0 + oopDesc::klass_offset_in_bytes]\t! Inline cache check");
 850     st->print_cr("\tdecode_klass " R_RTEMP);
 851   } else {
 852     st->print_cr("\tLDR   " R_RTEMP ",[R_R0 + oopDesc::klass_offset_in_bytes]\t! Inline cache check");
 853   }
 854   st->print_cr("\tCMP   " R_RTEMP ",R_R8" );
 855   st->print   ("\tB.NE  SharedRuntime::handle_ic_miss_stub");
 856 }
 857 #endif
 858 
 859 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 860   C2_MacroAssembler _masm(&cbuf);
 861   Register iCache  = reg_to_register_object(Matcher::inline_cache_reg_encode());
 862   assert(iCache == Ricklass, "should be");
 863   Register receiver = R0;
 864 
 865   __ load_klass(Rtemp, receiver);
 866   __ cmp(Rtemp, iCache);
 867   __ jump(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type, noreg, ne);
 868 }
 869 
 870 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
 871   return MachNode::size(ra_);
 872 }
 873 
 874 
 875 //=============================================================================
 876 
 877 // Emit exception handler code.
 878 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) {
 879   C2_MacroAssembler _masm(&cbuf);
 880 
 881   address base = __ start_a_stub(size_exception_handler());
 882   if (base == NULL) {
 883     ciEnv::current()->record_failure("CodeCache is full");
 884     return 0;  // CodeBuffer::expand failed
 885   }
 886 
 887   int offset = __ offset();
 888 
 889   // OK to trash LR, because exception blob will kill it
 890   __ jump(OptoRuntime::exception_blob()->entry_point(), relocInfo::runtime_call_type, LR_tmp);
 891 
 892   assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
 893 
 894   __ end_a_stub();
 895 
 896   return offset;
 897 }
 898 
 899 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
 900   // Can't use any of the current frame's registers as we may have deopted
 901   // at a poll and everything can be live.
 902   C2_MacroAssembler _masm(&cbuf);
 903 
 904   address base = __ start_a_stub(size_deopt_handler());
 905   if (base == NULL) {
 906     ciEnv::current()->record_failure("CodeCache is full");
 907     return 0;  // CodeBuffer::expand failed
 908   }
 909 
 910   int offset = __ offset();
 911   address deopt_pc = __ pc();
 912 
 913   __ sub(SP, SP, wordSize); // make room for saved PC
 914   __ push(LR); // save LR that may be live when we get here
 915   __ mov_relative_address(LR, deopt_pc);
 916   __ str(LR, Address(SP, wordSize)); // save deopt PC
 917   __ pop(LR); // restore LR
 918   __ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, noreg);
 919 
 920   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
 921 
 922   __ end_a_stub();
 923   return offset;
 924 }
 925 
 926 const bool Matcher::match_rule_supported(int opcode) {
 927   if (!has_match_rule(opcode))
 928     return false;
 929 
 930   switch (opcode) {
 931   case Op_PopCountI:
 932   case Op_PopCountL:
 933     if (!UsePopCountInstruction)
 934       return false;
 935     break;
 936   case Op_LShiftCntV:
 937   case Op_RShiftCntV:
 938   case Op_AddVB:
 939   case Op_AddVS:
 940   case Op_AddVI:
 941   case Op_AddVL:
 942   case Op_SubVB:
 943   case Op_SubVS:
 944   case Op_SubVI:
 945   case Op_SubVL:
 946   case Op_MulVS:
 947   case Op_MulVI:
 948   case Op_LShiftVB:
 949   case Op_LShiftVS:
 950   case Op_LShiftVI:
 951   case Op_LShiftVL:
 952   case Op_RShiftVB:
 953   case Op_RShiftVS:
 954   case Op_RShiftVI:
 955   case Op_RShiftVL:
 956   case Op_URShiftVB:
 957   case Op_URShiftVS:
 958   case Op_URShiftVI:
 959   case Op_URShiftVL:
 960   case Op_AndV:
 961   case Op_OrV:
 962   case Op_XorV:
 963     return VM_Version::has_simd();
 964   case Op_LoadVector:
 965   case Op_StoreVector:
 966   case Op_AddVF:
 967   case Op_SubVF:
 968   case Op_MulVF:
 969     return VM_Version::has_vfp() || VM_Version::has_simd();
 970   case Op_AddVD:
 971   case Op_SubVD:
 972   case Op_MulVD:
 973   case Op_DivVF:
 974   case Op_DivVD:
 975     return VM_Version::has_vfp();
 976   }
 977 
 978   return true;  // Per default match rules are supported.
 979 }
 980 
 981 const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
 982 
 983   // TODO
 984   // identify extra cases that we might want to provide match rules for
 985   // e.g. Op_ vector nodes and other intrinsics while guarding with vlen
 986   bool ret_value = match_rule_supported(opcode);
 987   // Add rules here.
 988 
 989   return ret_value;  // Per default match rules are supported.
 990 }
 991 
 992 const bool Matcher::has_predicated_vectors(void) {
 993   return false;
 994 }
 995 
 996 const int Matcher::float_pressure(int default_pressure_threshold) {
 997   return default_pressure_threshold;
 998 }
 999 
1000 int Matcher::regnum_to_fpu_offset(int regnum) {
1001   return regnum - 32; // The FP registers are in the second chunk
1002 }
1003 
1004 // Vector width in bytes
1005 const int Matcher::vector_width_in_bytes(BasicType bt) {
1006   return MaxVectorSize;
1007 }
1008 
1009 // Vector ideal reg corresponding to specified size in bytes
1010 const uint Matcher::vector_ideal_reg(int size) {
1011   assert(MaxVectorSize >= size, "");
1012   switch(size) {
1013     case  8: return Op_VecD;
1014     case 16: return Op_VecX;
1015   }
1016   ShouldNotReachHere();
1017   return 0;
1018 }
1019 
1020 // Limits on vector size (number of elements) loaded into vector.
1021 const int Matcher::max_vector_size(const BasicType bt) {
1022   assert(is_java_primitive(bt), "only primitive type vectors");
1023   return vector_width_in_bytes(bt)/type2aelembytes(bt);
1024 }
1025 
1026 const int Matcher::min_vector_size(const BasicType bt) {
1027   assert(is_java_primitive(bt), "only primitive type vectors");
1028   return 8/type2aelembytes(bt);
1029 }
1030 
1031 // ARM doesn't support misaligned vectors store/load.
1032 const bool Matcher::misaligned_vectors_ok() {
1033   return false;
1034 }
1035 
1036 // ARM doesn't support AES intrinsics
1037 const bool Matcher::pass_original_key_for_aes() {
1038   return false;
1039 }
1040 
1041 const bool Matcher::convL2FSupported(void) {
1042   return false;
1043 }
1044 
1045 // Is this branch offset short enough that a short branch can be used?
1046 //
1047 // NOTE: If the platform does not provide any short branch variants, then
1048 //       this method should return false for offset 0.
1049 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
1050   // The passed offset is relative to address of the branch.
1051   // On ARM a branch displacement is calculated relative to address
1052   // of the branch + 8.
1053   //
1054   // offset -= 8;
1055   // return (Assembler::is_simm24(offset));
1056   return false;
1057 }
1058 
1059 const bool Matcher::isSimpleConstant64(jlong value) {
1060   // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
1061   return false;
1062 }
1063 
1064 // No scaling for the parameter the ClearArray node.
1065 const bool Matcher::init_array_count_is_in_bytes = true;
1066 
1067 // Needs 2 CMOV's for longs.
1068 const int Matcher::long_cmove_cost() { return 2; }
1069 
1070 // CMOVF/CMOVD are expensive on ARM.
1071 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
1072 
1073 // Does the CPU require late expand (see block.cpp for description of late expand)?
1074 const bool Matcher::require_postalloc_expand = false;
1075 
1076 // Do we need to mask the count passed to shift instructions or does
1077 // the cpu only look at the lower 5/6 bits anyway?
1078 // FIXME: does this handle vector shifts as well?
1079 const bool Matcher::need_masked_shift_count = true;
1080 
1081 const bool Matcher::convi2l_type_required = true;
1082 
1083 // No support for generic vector operands.
1084 const bool Matcher::supports_generic_vector_operands  = false;
1085 
1086 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) {
1087   ShouldNotReachHere(); // generic vector operands not supported
1088   return NULL;
1089 }
1090 
1091 bool Matcher::is_generic_reg2reg_move(MachNode* m) {
1092   ShouldNotReachHere();  // generic vector operands not supported
1093   return false;
1094 }
1095 
1096 bool Matcher::is_generic_vector(MachOper* opnd)  {
1097   ShouldNotReachHere();  // generic vector operands not supported
1098   return false;
1099 }
1100 
1101 // Should the matcher clone input 'm' of node 'n'?
1102 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
1103   if (is_vshift_con_pattern(n, m)) { // ShiftV src (ShiftCntV con)
1104     mstack.push(m, Visit);           // m = ShiftCntV
1105     return true;
1106   }
1107   return false;
1108 }
1109 
1110 // Should the Matcher clone shifts on addressing modes, expecting them
1111 // to be subsumed into complex addressing expressions or compute them
1112 // into registers?
1113 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
1114   return clone_base_plus_offset_address(m, mstack, address_visited);
1115 }
1116 
1117 void Compile::reshape_address(AddPNode* addp) {
1118 }
1119 
1120 bool Matcher::narrow_oop_use_complex_address() {
1121   NOT_LP64(ShouldNotCallThis());
1122   assert(UseCompressedOops, "only for compressed oops code");
1123   return false;
1124 }
1125 
1126 bool Matcher::narrow_klass_use_complex_address() {
1127   NOT_LP64(ShouldNotCallThis());
1128   assert(UseCompressedClassPointers, "only for compressed klass code");
1129   return false;
1130 }
1131 
1132 bool Matcher::const_oop_prefer_decode() {
1133   NOT_LP64(ShouldNotCallThis());
1134   return true;
1135 }
1136 
1137 bool Matcher::const_klass_prefer_decode() {
1138   NOT_LP64(ShouldNotCallThis());
1139   return true;
1140 }
1141 
1142 // Is it better to copy float constants, or load them directly from memory?
1143 // Intel can load a float constant from a direct address, requiring no
1144 // extra registers.  Most RISCs will have to materialize an address into a
1145 // register first, so they would do better to copy the constant from stack.
1146 const bool Matcher::rematerialize_float_constants = false;
1147 
1148 // If CPU can load and store mis-aligned doubles directly then no fixup is
1149 // needed.  Else we split the double into 2 integer pieces and move it
1150 // piece-by-piece.  Only happens when passing doubles into C code as the
1151 // Java calling convention forces doubles to be aligned.
1152 const bool Matcher::misaligned_doubles_ok = false;
1153 
1154 // No-op on ARM.
1155 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {
1156 }
1157 
1158 // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode.
1159 const bool Matcher::strict_fp_requires_explicit_rounding = false;
1160 
1161 // Are floats converted to double when stored to stack during deoptimization?
1162 // ARM does not handle callee-save floats.
1163 bool Matcher::float_in_double() {
1164   return false;
1165 }
1166 
1167 // Do ints take an entire long register or just half?
1168 // Note that we if-def off of _LP64.
1169 // The relevant question is how the int is callee-saved.  In _LP64
1170 // the whole long is written but de-opt'ing will have to extract
1171 // the relevant 32 bits, in not-_LP64 only the low 32 bits is written.
1172 #ifdef _LP64
1173 const bool Matcher::int_in_long = true;
1174 #else
1175 const bool Matcher::int_in_long = false;
1176 #endif
1177 
1178 // Return whether or not this register is ever used as an argument.  This
1179 // function is used on startup to build the trampoline stubs in generateOptoStub.
1180 // Registers not mentioned will be killed by the VM call in the trampoline, and
1181 // arguments in those registers not be available to the callee.
1182 bool Matcher::can_be_java_arg( int reg ) {
1183   if (reg == R_R0_num ||
1184       reg == R_R1_num ||
1185       reg == R_R2_num ||
1186       reg == R_R3_num) return true;
1187 
1188   if (reg >= R_S0_num &&
1189       reg <= R_S13_num) return true;
1190   return false;
1191 }
1192 
1193 bool Matcher::is_spillable_arg( int reg ) {
1194   return can_be_java_arg(reg);
1195 }
1196 
1197 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
1198   return false;
1199 }
1200 
1201 // Register for DIVI projection of divmodI
1202 RegMask Matcher::divI_proj_mask() {
1203   ShouldNotReachHere();
1204   return RegMask();
1205 }
1206 
1207 // Register for MODI projection of divmodI
1208 RegMask Matcher::modI_proj_mask() {
1209   ShouldNotReachHere();
1210   return RegMask();
1211 }
1212 
1213 // Register for DIVL projection of divmodL
1214 RegMask Matcher::divL_proj_mask() {
1215   ShouldNotReachHere();
1216   return RegMask();
1217 }
1218 
1219 // Register for MODL projection of divmodL
1220 RegMask Matcher::modL_proj_mask() {
1221   ShouldNotReachHere();
1222   return RegMask();
1223 }
1224 
1225 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
1226   return FP_REGP_mask();
1227 }
1228 
1229 bool maybe_far_call(const CallNode *n) {
1230   return !MacroAssembler::_reachable_from_cache(n->as_Call()->entry_point());
1231 }
1232 
1233 bool maybe_far_call(const MachCallNode *n) {
1234   return !MacroAssembler::_reachable_from_cache(n->as_MachCall()->entry_point());
1235 }
1236 
1237 %}
1238 
1239 //----------ENCODING BLOCK-----------------------------------------------------
1240 // This block specifies the encoding classes used by the compiler to output
1241 // byte streams.  Encoding classes are parameterized macros used by
1242 // Machine Instruction Nodes in order to generate the bit encoding of the
1243 // instruction.  Operands specify their base encoding interface with the
1244 // interface keyword.  There are currently supported four interfaces,
1245 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
1246 // operand to generate a function which returns its register number when
1247 // queried.   CONST_INTER causes an operand to generate a function which
1248 // returns the value of the constant when queried.  MEMORY_INTER causes an
1249 // operand to generate four functions which return the Base Register, the
1250 // Index Register, the Scale Value, and the Offset Value of the operand when
1251 // queried.  COND_INTER causes an operand to generate six functions which
1252 // return the encoding code (ie - encoding bits for the instruction)
1253 // associated with each basic boolean condition for a conditional instruction.
1254 //
1255 // Instructions specify two basic values for encoding.  Again, a function
1256 // is available to check if the constant displacement is an oop. They use the
1257 // ins_encode keyword to specify their encoding classes (which must be
1258 // a sequence of enc_class names, and their parameters, specified in
1259 // the encoding block), and they use the
1260 // opcode keyword to specify, in order, their primary, secondary, and
1261 // tertiary opcode.  Only the opcode sections which a particular instruction
1262 // needs for encoding need to be specified.
1263 encode %{
1264   enc_class call_epilog %{
1265     // nothing
1266   %}
1267 
1268   enc_class Java_To_Runtime (method meth) %{
1269     // CALL directly to the runtime
1270     emit_call_reloc(cbuf, as_MachCall(), $meth, runtime_call_Relocation::spec());
1271   %}
1272 
1273   enc_class Java_Static_Call (method meth) %{
1274     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
1275     // who we intended to call.
1276 
1277     if ( !_method) {
1278       emit_call_reloc(cbuf, as_MachCall(), $meth, runtime_call_Relocation::spec());
1279     } else {
1280       int method_index = resolved_method_index(cbuf);
1281       RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
1282                                                   : static_call_Relocation::spec(method_index);
1283       emit_call_reloc(cbuf, as_MachCall(), $meth, rspec);
1284 
1285       // Emit stubs for static call.
1286       address stub = CompiledStaticCall::emit_to_interp_stub(cbuf);
1287       if (stub == NULL) {
1288         ciEnv::current()->record_failure("CodeCache is full");
1289         return;
1290       }
1291     }
1292   %}
1293 
1294   enc_class save_last_PC %{
1295     // preserve mark
1296     address mark = cbuf.insts()->mark();
1297     debug_only(int off0 = cbuf.insts_size());
1298     C2_MacroAssembler _masm(&cbuf);
1299     int ret_addr_offset = as_MachCall()->ret_addr_offset();
1300     __ adr(LR, mark + ret_addr_offset);
1301     __ str(LR, Address(Rthread, JavaThread::last_Java_pc_offset()));
1302     debug_only(int off1 = cbuf.insts_size());
1303     assert(off1 - off0 == 2 * Assembler::InstructionSize, "correct size prediction");
1304     // restore mark
1305     cbuf.insts()->set_mark(mark);
1306   %}
1307 
1308   enc_class preserve_SP %{
1309     // preserve mark
1310     address mark = cbuf.insts()->mark();
1311     debug_only(int off0 = cbuf.insts_size());
1312     C2_MacroAssembler _masm(&cbuf);
1313     // FP is preserved across all calls, even compiled calls.
1314     // Use it to preserve SP in places where the callee might change the SP.
1315     __ mov(Rmh_SP_save, SP);
1316     debug_only(int off1 = cbuf.insts_size());
1317     assert(off1 - off0 == 4, "correct size prediction");
1318     // restore mark
1319     cbuf.insts()->set_mark(mark);
1320   %}
1321 
1322   enc_class restore_SP %{
1323     C2_MacroAssembler _masm(&cbuf);
1324     __ mov(SP, Rmh_SP_save);
1325   %}
1326 
1327   enc_class Java_Dynamic_Call (method meth) %{
1328     C2_MacroAssembler _masm(&cbuf);
1329     Register R8_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode());
1330     assert(R8_ic_reg == Ricklass, "should be");
1331     __ set_inst_mark();
1332     __ movw(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) & 0xffff);
1333     __ movt(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) >> 16);
1334     address  virtual_call_oop_addr = __ inst_mark();
1335     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
1336     // who we intended to call.
1337     int method_index = resolved_method_index(cbuf);
1338     __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index));
1339     emit_call_reloc(cbuf, as_MachCall(), $meth, RelocationHolder::none);
1340   %}
1341 
1342   enc_class LdReplImmI(immI src, regD dst, iRegI tmp, int cnt, int wth) %{
1343     // FIXME: load from constant table?
1344     // Load a constant replicated "count" times with width "width"
1345     int count = $cnt$$constant;
1346     int width = $wth$$constant;
1347     assert(count*width == 4, "sanity");
1348     int val = $src$$constant;
1349     if (width < 4) {
1350       int bit_width = width * 8;
1351       val &= (((int)1) << bit_width) - 1; // mask off sign bits
1352       for (int i = 0; i < count - 1; i++) {
1353         val |= (val << bit_width);
1354       }
1355     }
1356     C2_MacroAssembler _masm(&cbuf);
1357 
1358     if (val == -1) {
1359       __ mvn($tmp$$Register, 0);
1360     } else if (val == 0) {
1361       __ mov($tmp$$Register, 0);
1362     } else {
1363       __ movw($tmp$$Register, val & 0xffff);
1364       __ movt($tmp$$Register, (unsigned int)val >> 16);
1365     }
1366     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
1367   %}
1368 
1369   enc_class LdReplImmF(immF src, regD dst, iRegI tmp) %{
1370     // Replicate float con 2 times and pack into vector (8 bytes) in regD.
1371     float fval = $src$$constant;
1372     int val = *((int*)&fval);
1373     C2_MacroAssembler _masm(&cbuf);
1374 
1375     if (val == -1) {
1376       __ mvn($tmp$$Register, 0);
1377     } else if (val == 0) {
1378       __ mov($tmp$$Register, 0);
1379     } else {
1380       __ movw($tmp$$Register, val & 0xffff);
1381       __ movt($tmp$$Register, (unsigned int)val >> 16);
1382     }
1383     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
1384   %}
1385 
1386   enc_class enc_String_Compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result, iRegI tmp1, iRegI tmp2) %{
1387     Label Ldone, Lloop;
1388     C2_MacroAssembler _masm(&cbuf);
1389 
1390     Register   str1_reg = $str1$$Register;
1391     Register   str2_reg = $str2$$Register;
1392     Register   cnt1_reg = $cnt1$$Register; // int
1393     Register   cnt2_reg = $cnt2$$Register; // int
1394     Register   tmp1_reg = $tmp1$$Register;
1395     Register   tmp2_reg = $tmp2$$Register;
1396     Register result_reg = $result$$Register;
1397 
1398     assert_different_registers(str1_reg, str2_reg, cnt1_reg, cnt2_reg, tmp1_reg, tmp2_reg);
1399 
1400     // Compute the minimum of the string lengths(str1_reg) and the
1401     // difference of the string lengths (stack)
1402 
1403     // See if the lengths are different, and calculate min in str1_reg.
1404     // Stash diff in tmp2 in case we need it for a tie-breaker.
1405     __ subs_32(tmp2_reg, cnt1_reg, cnt2_reg);
1406     __ mov(cnt1_reg, AsmOperand(cnt1_reg, lsl, exact_log2(sizeof(jchar)))); // scale the limit
1407     __ mov(cnt1_reg, AsmOperand(cnt2_reg, lsl, exact_log2(sizeof(jchar))), pl); // scale the limit
1408 
1409     // reallocate cnt1_reg, cnt2_reg, result_reg
1410     // Note:  limit_reg holds the string length pre-scaled by 2
1411     Register limit_reg = cnt1_reg;
1412     Register  chr2_reg = cnt2_reg;
1413     Register  chr1_reg = tmp1_reg;
1414     // str{12} are the base pointers
1415 
1416     // Is the minimum length zero?
1417     __ cmp_32(limit_reg, 0);
1418     if (result_reg != tmp2_reg) {
1419       __ mov(result_reg, tmp2_reg, eq);
1420     }
1421     __ b(Ldone, eq);
1422 
1423     // Load first characters
1424     __ ldrh(chr1_reg, Address(str1_reg, 0));
1425     __ ldrh(chr2_reg, Address(str2_reg, 0));
1426 
1427     // Compare first characters
1428     __ subs(chr1_reg, chr1_reg, chr2_reg);
1429     if (result_reg != chr1_reg) {
1430       __ mov(result_reg, chr1_reg, ne);
1431     }
1432     __ b(Ldone, ne);
1433 
1434     {
1435       // Check after comparing first character to see if strings are equivalent
1436       // Check if the strings start at same location
1437       __ cmp(str1_reg, str2_reg);
1438       // Check if the length difference is zero
1439       __ cond_cmp(tmp2_reg, 0, eq);
1440       __ mov(result_reg, 0, eq); // result is zero
1441       __ b(Ldone, eq);
1442       // Strings might not be equal
1443     }
1444 
1445     __ subs(chr1_reg, limit_reg, 1 * sizeof(jchar));
1446     if (result_reg != tmp2_reg) {
1447       __ mov(result_reg, tmp2_reg, eq);
1448     }
1449     __ b(Ldone, eq);
1450 
1451     // Shift str1_reg and str2_reg to the end of the arrays, negate limit
1452     __ add(str1_reg, str1_reg, limit_reg);
1453     __ add(str2_reg, str2_reg, limit_reg);
1454     __ neg(limit_reg, chr1_reg);  // limit = -(limit-2)
1455 
1456     // Compare the rest of the characters
1457     __ bind(Lloop);
1458     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
1459     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
1460     __ subs(chr1_reg, chr1_reg, chr2_reg);
1461     if (result_reg != chr1_reg) {
1462       __ mov(result_reg, chr1_reg, ne);
1463     }
1464     __ b(Ldone, ne);
1465 
1466     __ adds(limit_reg, limit_reg, sizeof(jchar));
1467     __ b(Lloop, ne);
1468 
1469     // If strings are equal up to min length, return the length difference.
1470     if (result_reg != tmp2_reg) {
1471       __ mov(result_reg, tmp2_reg);
1472     }
1473 
1474     // Otherwise, return the difference between the first mismatched chars.
1475     __ bind(Ldone);
1476   %}
1477 
1478   enc_class enc_String_Equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2) %{
1479     Label Lchar, Lchar_loop, Ldone, Lequal;
1480     C2_MacroAssembler _masm(&cbuf);
1481 
1482     Register   str1_reg = $str1$$Register;
1483     Register   str2_reg = $str2$$Register;
1484     Register    cnt_reg = $cnt$$Register; // int
1485     Register   tmp1_reg = $tmp1$$Register;
1486     Register   tmp2_reg = $tmp2$$Register;
1487     Register result_reg = $result$$Register;
1488 
1489     assert_different_registers(str1_reg, str2_reg, cnt_reg, tmp1_reg, tmp2_reg, result_reg);
1490 
1491     __ cmp(str1_reg, str2_reg); //same char[] ?
1492     __ b(Lequal, eq);
1493 
1494     __ cbz_32(cnt_reg, Lequal); // count == 0
1495 
1496     //rename registers
1497     Register limit_reg = cnt_reg;
1498     Register  chr1_reg = tmp1_reg;
1499     Register  chr2_reg = tmp2_reg;
1500 
1501     __ logical_shift_left(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
1502 
1503     //check for alignment and position the pointers to the ends
1504     __ orr(chr1_reg, str1_reg, str2_reg);
1505     __ tst(chr1_reg, 0x3);
1506 
1507     // notZero means at least one not 4-byte aligned.
1508     // We could optimize the case when both arrays are not aligned
1509     // but it is not frequent case and it requires additional checks.
1510     __ b(Lchar, ne);
1511 
1512     // Compare char[] arrays aligned to 4 bytes.
1513     __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg,
1514                           chr1_reg, chr2_reg, Ldone);
1515 
1516     __ b(Lequal); // equal
1517 
1518     // char by char compare
1519     __ bind(Lchar);
1520     __ mov(result_reg, 0);
1521     __ add(str1_reg, limit_reg, str1_reg);
1522     __ add(str2_reg, limit_reg, str2_reg);
1523     __ neg(limit_reg, limit_reg); //negate count
1524 
1525     // Lchar_loop
1526     __ bind(Lchar_loop);
1527     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
1528     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
1529     __ cmp(chr1_reg, chr2_reg);
1530     __ b(Ldone, ne);
1531     __ adds(limit_reg, limit_reg, sizeof(jchar));
1532     __ b(Lchar_loop, ne);
1533 
1534     __ bind(Lequal);
1535     __ mov(result_reg, 1);  //equal
1536 
1537     __ bind(Ldone);
1538   %}
1539 
1540   enc_class enc_Array_Equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result) %{
1541     Label Ldone, Lloop, Lequal;
1542     C2_MacroAssembler _masm(&cbuf);
1543 
1544     Register   ary1_reg = $ary1$$Register;
1545     Register   ary2_reg = $ary2$$Register;
1546     Register   tmp1_reg = $tmp1$$Register;
1547     Register   tmp2_reg = $tmp2$$Register;
1548     Register   tmp3_reg = $tmp3$$Register;
1549     Register result_reg = $result$$Register;
1550 
1551     assert_different_registers(ary1_reg, ary2_reg, tmp1_reg, tmp2_reg, tmp3_reg, result_reg);
1552 
1553     int length_offset  = arrayOopDesc::length_offset_in_bytes();
1554     int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
1555 
1556     // return true if the same array
1557     __ teq(ary1_reg, ary2_reg);
1558     __ mov(result_reg, 1, eq);
1559     __ b(Ldone, eq); // equal
1560 
1561     __ tst(ary1_reg, ary1_reg);
1562     __ mov(result_reg, 0, eq);
1563     __ b(Ldone, eq);    // not equal
1564 
1565     __ tst(ary2_reg, ary2_reg);
1566     __ mov(result_reg, 0, eq);
1567     __ b(Ldone, eq);    // not equal
1568 
1569     //load the lengths of arrays
1570     __ ldr_s32(tmp1_reg, Address(ary1_reg, length_offset)); // int
1571     __ ldr_s32(tmp2_reg, Address(ary2_reg, length_offset)); // int
1572 
1573     // return false if the two arrays are not equal length
1574     __ teq_32(tmp1_reg, tmp2_reg);
1575     __ mov(result_reg, 0, ne);
1576     __ b(Ldone, ne);    // not equal
1577 
1578     __ tst(tmp1_reg, tmp1_reg);
1579     __ mov(result_reg, 1, eq);
1580     __ b(Ldone, eq);    // zero-length arrays are equal
1581 
1582     // load array addresses
1583     __ add(ary1_reg, ary1_reg, base_offset);
1584     __ add(ary2_reg, ary2_reg, base_offset);
1585 
1586     // renaming registers
1587     Register chr1_reg  =  tmp3_reg;   // for characters in ary1
1588     Register chr2_reg  =  tmp2_reg;   // for characters in ary2
1589     Register limit_reg =  tmp1_reg;   // length
1590 
1591     // set byte count
1592     __ logical_shift_left_32(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
1593 
1594     // Compare char[] arrays aligned to 4 bytes.
1595     __ char_arrays_equals(ary1_reg, ary2_reg, limit_reg, result_reg,
1596                           chr1_reg, chr2_reg, Ldone);
1597     __ bind(Lequal);
1598     __ mov(result_reg, 1);  //equal
1599 
1600     __ bind(Ldone);
1601     %}
1602 %}
1603 
1604 //----------FRAME--------------------------------------------------------------
1605 // Definition of frame structure and management information.
1606 //
1607 //  S T A C K   L A Y O U T    Allocators stack-slot number
1608 //                             |   (to get allocators register number
1609 //  G  Owned by    |        |  v    add VMRegImpl::stack0)
1610 //  r   CALLER     |        |
1611 //  o     |        +--------+      pad to even-align allocators stack-slot
1612 //  w     V        |  pad0  |        numbers; owned by CALLER
1613 //  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
1614 //  h     ^        |   in   |  5
1615 //        |        |  args  |  4   Holes in incoming args owned by SELF
1616 //  |     |        |        |  3
1617 //  |     |        +--------+
1618 //  V     |        | old out|      Empty on Intel, window on Sparc
1619 //        |    old |preserve|      Must be even aligned.
1620 //        |     SP-+--------+----> Matcher::_old_SP, 8 (or 16 in LP64)-byte aligned
1621 //        |        |   in   |  3   area for Intel ret address
1622 //     Owned by    |preserve|      Empty on Sparc.
1623 //       SELF      +--------+
1624 //        |        |  pad2  |  2   pad to align old SP
1625 //        |        +--------+  1
1626 //        |        | locks  |  0
1627 //        |        +--------+----> VMRegImpl::stack0, 8 (or 16 in LP64)-byte aligned
1628 //        |        |  pad1  | 11   pad to align new SP
1629 //        |        +--------+
1630 //        |        |        | 10
1631 //        |        | spills |  9   spills
1632 //        V        |        |  8   (pad0 slot for callee)
1633 //      -----------+--------+----> Matcher::_out_arg_limit, unaligned
1634 //        ^        |  out   |  7
1635 //        |        |  args  |  6   Holes in outgoing args owned by CALLEE
1636 //     Owned by    +--------+
1637 //      CALLEE     | new out|  6   Empty on Intel, window on Sparc
1638 //        |    new |preserve|      Must be even-aligned.
1639 //        |     SP-+--------+----> Matcher::_new_SP, even aligned
1640 //        |        |        |
1641 //
1642 // Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
1643 //         known from SELF's arguments and the Java calling convention.
1644 //         Region 6-7 is determined per call site.
1645 // Note 2: If the calling convention leaves holes in the incoming argument
1646 //         area, those holes are owned by SELF.  Holes in the outgoing area
1647 //         are owned by the CALLEE.  Holes should not be nessecary in the
1648 //         incoming area, as the Java calling convention is completely under
1649 //         the control of the AD file.  Doubles can be sorted and packed to
1650 //         avoid holes.  Holes in the outgoing arguments may be nessecary for
1651 //         varargs C calling conventions.
1652 // Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
1653 //         even aligned with pad0 as needed.
1654 //         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
1655 //         region 6-11 is even aligned; it may be padded out more so that
1656 //         the region from SP to FP meets the minimum stack alignment.
1657 
1658 frame %{
1659   // What direction does stack grow in (assumed to be same for native & Java)
1660   stack_direction(TOWARDS_LOW);
1661 
1662   // These two registers define part of the calling convention
1663   // between compiled code and the interpreter.
1664   inline_cache_reg(R_Ricklass);          // Inline Cache Register or Method* for I2C
1665   interpreter_method_oop_reg(R_Rmethod); // Method Oop Register when calling interpreter
1666 
1667   // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
1668   cisc_spilling_operand_name(indOffset);
1669 
1670   // Number of stack slots consumed by a Monitor enter
1671   sync_stack_slots(1 * VMRegImpl::slots_per_word);
1672 
1673   // Compiled code's Frame Pointer
1674   frame_pointer(R_R13);
1675 
1676   // Stack alignment requirement
1677   stack_alignment(StackAlignmentInBytes);
1678   //  LP64: Alignment size in bytes (128-bit -> 16 bytes)
1679   // !LP64: Alignment size in bytes (64-bit  ->  8 bytes)
1680 
1681   // Number of stack slots between incoming argument block and the start of
1682   // a new frame.  The PROLOG must add this many slots to the stack.  The
1683   // EPILOG must remove this many slots.
1684   // FP + LR
1685   in_preserve_stack_slots(2 * VMRegImpl::slots_per_word);
1686 
1687   // Number of outgoing stack slots killed above the out_preserve_stack_slots
1688   // for calls to C.  Supports the var-args backing area for register parms.
1689   // ADLC doesn't support parsing expressions, so I folded the math by hand.
1690   varargs_C_out_slots_killed( 0);
1691 
1692   // The after-PROLOG location of the return address.  Location of
1693   // return address specifies a type (REG or STACK) and a number
1694   // representing the register number (i.e. - use a register name) or
1695   // stack slot.
1696   // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
1697   // Otherwise, it is above the locks and verification slot and alignment word
1698   return_addr(STACK - 1*VMRegImpl::slots_per_word +
1699               align_up((Compile::current()->in_preserve_stack_slots() +
1700                         Compile::current()->fixed_slots()),
1701                        stack_alignment_in_slots()));
1702 
1703   // Body of function which returns an OptoRegs array locating
1704   // arguments either in registers or in stack slots for calling
1705   // java
1706   calling_convention %{
1707     (void) SharedRuntime::java_calling_convention(sig_bt, regs, length, is_outgoing);
1708 
1709   %}
1710 
1711   // Body of function which returns an OptoRegs array locating
1712   // arguments either in registers or in stack slots for callin
1713   // C.
1714   c_calling_convention %{
1715     // This is obviously always outgoing
1716     (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
1717   %}
1718 
1719   // Location of compiled Java return values.  Same as C
1720   return_value %{
1721     return c2::return_value(ideal_reg);
1722   %}
1723 
1724 %}
1725 
1726 //----------ATTRIBUTES---------------------------------------------------------
1727 //----------Instruction Attributes---------------------------------------------
1728 ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute
1729 ins_attrib ins_size(32);           // Required size attribute (in bits)
1730 ins_attrib ins_short_branch(0);    // Required flag: is this instruction a
1731                                    // non-matching short branch variant of some
1732                                                             // long branch?
1733 
1734 //----------OPERANDS-----------------------------------------------------------
1735 // Operand definitions must precede instruction definitions for correct parsing
1736 // in the ADLC because operands constitute user defined types which are used in
1737 // instruction definitions.
1738 
1739 //----------Simple Operands----------------------------------------------------
1740 // Immediate Operands
1741 // Integer Immediate: 32-bit
1742 operand immI() %{
1743   match(ConI);
1744 
1745   op_cost(0);
1746   // formats are generated automatically for constants and base registers
1747   format %{ %}
1748   interface(CONST_INTER);
1749 %}
1750 
1751 // Integer Immediate: 8-bit unsigned - for VMOV
1752 operand immU8() %{
1753   predicate(0 <= n->get_int() && (n->get_int() <= 255));
1754   match(ConI);
1755   op_cost(0);
1756 
1757   format %{ %}
1758   interface(CONST_INTER);
1759 %}
1760 
1761 // Integer Immediate: 16-bit
1762 operand immI16() %{
1763   predicate((n->get_int() >> 16) == 0 && VM_Version::supports_movw());
1764   match(ConI);
1765   op_cost(0);
1766 
1767   format %{ %}
1768   interface(CONST_INTER);
1769 %}
1770 
1771 // Integer Immediate: offset for half and double word loads and stores
1772 operand immIHD() %{
1773   predicate(is_memoryHD(n->get_int()));
1774   match(ConI);
1775   op_cost(0);
1776   format %{ %}
1777   interface(CONST_INTER);
1778 %}
1779 
1780 // Integer Immediate: offset for fp loads and stores
1781 operand immIFP() %{
1782   predicate(is_memoryfp(n->get_int()) && ((n->get_int() & 3) == 0));
1783   match(ConI);
1784   op_cost(0);
1785 
1786   format %{ %}
1787   interface(CONST_INTER);
1788 %}
1789 
1790 // Valid scale values for addressing modes and shifts
1791 operand immU5() %{
1792   predicate(0 <= n->get_int() && (n->get_int() <= 31));
1793   match(ConI);
1794   op_cost(0);
1795 
1796   format %{ %}
1797   interface(CONST_INTER);
1798 %}
1799 
1800 // Integer Immediate: 6-bit
1801 operand immU6Big() %{
1802   predicate(n->get_int() >= 32 && n->get_int() <= 63);
1803   match(ConI);
1804   op_cost(0);
1805   format %{ %}
1806   interface(CONST_INTER);
1807 %}
1808 
1809 // Integer Immediate: 0-bit
1810 operand immI0() %{
1811   predicate(n->get_int() == 0);
1812   match(ConI);
1813   op_cost(0);
1814 
1815   format %{ %}
1816   interface(CONST_INTER);
1817 %}
1818 
1819 // Integer Immediate: the value 1
1820 operand immI_1() %{
1821   predicate(n->get_int() == 1);
1822   match(ConI);
1823   op_cost(0);
1824 
1825   format %{ %}
1826   interface(CONST_INTER);
1827 %}
1828 
1829 // Integer Immediate: the value 2
1830 operand immI_2() %{
1831   predicate(n->get_int() == 2);
1832   match(ConI);
1833   op_cost(0);
1834 
1835   format %{ %}
1836   interface(CONST_INTER);
1837 %}
1838 
1839 // Integer Immediate: the value 3
1840 operand immI_3() %{
1841   predicate(n->get_int() == 3);
1842   match(ConI);
1843   op_cost(0);
1844 
1845   format %{ %}
1846   interface(CONST_INTER);
1847 %}
1848 
1849 // Integer Immediate: the value 4
1850 operand immI_4() %{
1851   predicate(n->get_int() == 4);
1852   match(ConI);
1853   op_cost(0);
1854 
1855   format %{ %}
1856   interface(CONST_INTER);
1857 %}
1858 
1859 // Integer Immediate: the value 8
1860 operand immI_8() %{
1861   predicate(n->get_int() == 8);
1862   match(ConI);
1863   op_cost(0);
1864 
1865   format %{ %}
1866   interface(CONST_INTER);
1867 %}
1868 
1869 // Int Immediate non-negative
1870 operand immU31()
1871 %{
1872   predicate(n->get_int() >= 0);
1873   match(ConI);
1874 
1875   op_cost(0);
1876   format %{ %}
1877   interface(CONST_INTER);
1878 %}
1879 
1880 // Integer Immediate: the values 32-63
1881 operand immI_32_63() %{
1882   predicate(n->get_int() >= 32 && n->get_int() <= 63);
1883   match(ConI);
1884   op_cost(0);
1885 
1886   format %{ %}
1887   interface(CONST_INTER);
1888 %}
1889 
1890 // Immediates for special shifts (sign extend)
1891 
1892 // Integer Immediate: the value 16
1893 operand immI_16() %{
1894   predicate(n->get_int() == 16);
1895   match(ConI);
1896   op_cost(0);
1897 
1898   format %{ %}
1899   interface(CONST_INTER);
1900 %}
1901 
1902 // Integer Immediate: the value 24
1903 operand immI_24() %{
1904   predicate(n->get_int() == 24);
1905   match(ConI);
1906   op_cost(0);
1907 
1908   format %{ %}
1909   interface(CONST_INTER);
1910 %}
1911 
1912 // Integer Immediate: the value 255
1913 operand immI_255() %{
1914   predicate( n->get_int() == 255 );
1915   match(ConI);
1916   op_cost(0);
1917 
1918   format %{ %}
1919   interface(CONST_INTER);
1920 %}
1921 
1922 // Integer Immediate: the value 65535
1923 operand immI_65535() %{
1924   predicate(n->get_int() == 65535);
1925   match(ConI);
1926   op_cost(0);
1927 
1928   format %{ %}
1929   interface(CONST_INTER);
1930 %}
1931 
1932 // Integer Immediates for arithmetic instructions
1933 
1934 operand aimmI() %{
1935   predicate(is_aimm(n->get_int()));
1936   match(ConI);
1937   op_cost(0);
1938 
1939   format %{ %}
1940   interface(CONST_INTER);
1941 %}
1942 
1943 operand aimmIneg() %{
1944   predicate(is_aimm(-n->get_int()));
1945   match(ConI);
1946   op_cost(0);
1947 
1948   format %{ %}
1949   interface(CONST_INTER);
1950 %}
1951 
1952 operand aimmU31() %{
1953   predicate((0 <= n->get_int()) && is_aimm(n->get_int()));
1954   match(ConI);
1955   op_cost(0);
1956 
1957   format %{ %}
1958   interface(CONST_INTER);
1959 %}
1960 
1961 // Integer Immediates for logical instructions
1962 
1963 operand limmI() %{
1964   predicate(is_limmI(n->get_int()));
1965   match(ConI);
1966   op_cost(0);
1967 
1968   format %{ %}
1969   interface(CONST_INTER);
1970 %}
1971 
1972 operand limmIlow8() %{
1973   predicate(is_limmI_low(n->get_int(), 8));
1974   match(ConI);
1975   op_cost(0);
1976 
1977   format %{ %}
1978   interface(CONST_INTER);
1979 %}
1980 
1981 operand limmU31() %{
1982   predicate(0 <= n->get_int() && is_limmI(n->get_int()));
1983   match(ConI);
1984   op_cost(0);
1985 
1986   format %{ %}
1987   interface(CONST_INTER);
1988 %}
1989 
1990 operand limmIn() %{
1991   predicate(is_limmI(~n->get_int()));
1992   match(ConI);
1993   op_cost(0);
1994 
1995   format %{ %}
1996   interface(CONST_INTER);
1997 %}
1998 
1999 
2000 // Long Immediate: the value FF
2001 operand immL_FF() %{
2002   predicate( n->get_long() == 0xFFL );
2003   match(ConL);
2004   op_cost(0);
2005 
2006   format %{ %}
2007   interface(CONST_INTER);
2008 %}
2009 
2010 // Long Immediate: the value FFFF
2011 operand immL_FFFF() %{
2012   predicate( n->get_long() == 0xFFFFL );
2013   match(ConL);
2014   op_cost(0);
2015 
2016   format %{ %}
2017   interface(CONST_INTER);
2018 %}
2019 
2020 // Pointer Immediate: 32 or 64-bit
2021 operand immP() %{
2022   match(ConP);
2023 
2024   op_cost(5);
2025   // formats are generated automatically for constants and base registers
2026   format %{ %}
2027   interface(CONST_INTER);
2028 %}
2029 
2030 operand immP0() %{
2031   predicate(n->get_ptr() == 0);
2032   match(ConP);
2033   op_cost(0);
2034 
2035   format %{ %}
2036   interface(CONST_INTER);
2037 %}
2038 
2039 // Pointer Immediate
2040 operand immN()
2041 %{
2042   match(ConN);
2043 
2044   op_cost(10);
2045   format %{ %}
2046   interface(CONST_INTER);
2047 %}
2048 
2049 operand immNKlass()
2050 %{
2051   match(ConNKlass);
2052 
2053   op_cost(10);
2054   format %{ %}
2055   interface(CONST_INTER);
2056 %}
2057 
2058 // NULL Pointer Immediate
2059 operand immN0()
2060 %{
2061   predicate(n->get_narrowcon() == 0);
2062   match(ConN);
2063 
2064   op_cost(0);
2065   format %{ %}
2066   interface(CONST_INTER);
2067 %}
2068 
2069 operand immL() %{
2070   match(ConL);
2071   op_cost(40);
2072   // formats are generated automatically for constants and base registers
2073   format %{ %}
2074   interface(CONST_INTER);
2075 %}
2076 
2077 operand immL0() %{
2078   predicate(n->get_long() == 0L);
2079   match(ConL);
2080   op_cost(0);
2081   // formats are generated automatically for constants and base registers
2082   format %{ %}
2083   interface(CONST_INTER);
2084 %}
2085 
2086 // Long Immediate: 16-bit
2087 operand immL16() %{
2088   predicate(n->get_long() >= 0 && n->get_long() < (1<<16)  && VM_Version::supports_movw());
2089   match(ConL);
2090   op_cost(0);
2091 
2092   format %{ %}
2093   interface(CONST_INTER);
2094 %}
2095 
2096 // Long Immediate: low 32-bit mask
2097 operand immL_32bits() %{
2098   predicate(n->get_long() == 0xFFFFFFFFL);
2099   match(ConL);
2100   op_cost(0);
2101 
2102   format %{ %}
2103   interface(CONST_INTER);
2104 %}
2105 
2106 // Double Immediate
2107 operand immD() %{
2108   match(ConD);
2109 
2110   op_cost(40);
2111   format %{ %}
2112   interface(CONST_INTER);
2113 %}
2114 
2115 // Double Immediate: +0.0d.
2116 operand immD0() %{
2117   predicate(jlong_cast(n->getd()) == 0);
2118 
2119   match(ConD);
2120   op_cost(0);
2121   format %{ %}
2122   interface(CONST_INTER);
2123 %}
2124 
2125 operand imm8D() %{
2126   predicate(Assembler::double_num(n->getd()).can_be_imm8());
2127   match(ConD);
2128 
2129   op_cost(0);
2130   format %{ %}
2131   interface(CONST_INTER);
2132 %}
2133 
2134 // Float Immediate
2135 operand immF() %{
2136   match(ConF);
2137 
2138   op_cost(20);
2139   format %{ %}
2140   interface(CONST_INTER);
2141 %}
2142 
2143 // Float Immediate: +0.0f
2144 operand immF0() %{
2145   predicate(jint_cast(n->getf()) == 0);
2146   match(ConF);
2147 
2148   op_cost(0);
2149   format %{ %}
2150   interface(CONST_INTER);
2151 %}
2152 
2153 // Float Immediate: encoded as 8 bits
2154 operand imm8F() %{
2155   predicate(Assembler::float_num(n->getf()).can_be_imm8());
2156   match(ConF);
2157 
2158   op_cost(0);
2159   format %{ %}
2160   interface(CONST_INTER);
2161 %}
2162 
2163 // Integer Register Operands
2164 // Integer Register
2165 operand iRegI() %{
2166   constraint(ALLOC_IN_RC(int_reg));
2167   match(RegI);
2168   match(R0RegI);
2169   match(R1RegI);
2170   match(R2RegI);
2171   match(R3RegI);
2172   match(R12RegI);
2173 
2174   format %{ %}
2175   interface(REG_INTER);
2176 %}
2177 
2178 // Pointer Register
2179 operand iRegP() %{
2180   constraint(ALLOC_IN_RC(ptr_reg));
2181   match(RegP);
2182   match(R0RegP);
2183   match(R1RegP);
2184   match(R2RegP);
2185   match(RExceptionRegP);
2186   match(R8RegP);
2187   match(R9RegP);
2188   match(RthreadRegP); // FIXME: move to sp_ptr_RegP?
2189   match(R12RegP);
2190   match(LRRegP);
2191 
2192   match(sp_ptr_RegP);
2193   match(store_ptr_RegP);
2194 
2195   format %{ %}
2196   interface(REG_INTER);
2197 %}
2198 
2199 // GPRs + Rthread + SP
2200 operand sp_ptr_RegP() %{
2201   constraint(ALLOC_IN_RC(sp_ptr_reg));
2202   match(RegP);
2203   match(iRegP);
2204   match(SPRegP); // FIXME: check cost
2205 
2206   format %{ %}
2207   interface(REG_INTER);
2208 %}
2209 
2210 
2211 operand R0RegP() %{
2212   constraint(ALLOC_IN_RC(R0_regP));
2213   match(iRegP);
2214 
2215   format %{ %}
2216   interface(REG_INTER);
2217 %}
2218 
2219 operand R1RegP() %{
2220   constraint(ALLOC_IN_RC(R1_regP));
2221   match(iRegP);
2222 
2223   format %{ %}
2224   interface(REG_INTER);
2225 %}
2226 
2227 operand R8RegP() %{
2228   constraint(ALLOC_IN_RC(R8_regP));
2229   match(iRegP);
2230 
2231   format %{ %}
2232   interface(REG_INTER);
2233 %}
2234 
2235 operand R9RegP() %{
2236   constraint(ALLOC_IN_RC(R9_regP));
2237   match(iRegP);
2238 
2239   format %{ %}
2240   interface(REG_INTER);
2241 %}
2242 
2243 operand R12RegP() %{
2244   constraint(ALLOC_IN_RC(R12_regP));
2245   match(iRegP);
2246 
2247   format %{ %}
2248   interface(REG_INTER);
2249 %}
2250 
2251 operand R2RegP() %{
2252   constraint(ALLOC_IN_RC(R2_regP));
2253   match(iRegP);
2254 
2255   format %{ %}
2256   interface(REG_INTER);
2257 %}
2258 
2259 operand RExceptionRegP() %{
2260   constraint(ALLOC_IN_RC(Rexception_regP));
2261   match(iRegP);
2262 
2263   format %{ %}
2264   interface(REG_INTER);
2265 %}
2266 
2267 operand RthreadRegP() %{
2268   constraint(ALLOC_IN_RC(Rthread_regP));
2269   match(iRegP);
2270 
2271   format %{ %}
2272   interface(REG_INTER);
2273 %}
2274 
2275 operand IPRegP() %{
2276   constraint(ALLOC_IN_RC(IP_regP));
2277   match(iRegP);
2278 
2279   format %{ %}
2280   interface(REG_INTER);
2281 %}
2282 
2283 operand SPRegP() %{
2284   constraint(ALLOC_IN_RC(SP_regP));
2285   match(iRegP);
2286 
2287   format %{ %}
2288   interface(REG_INTER);
2289 %}
2290 
2291 operand LRRegP() %{
2292   constraint(ALLOC_IN_RC(LR_regP));
2293   match(iRegP);
2294 
2295   format %{ %}
2296   interface(REG_INTER);
2297 %}
2298 
2299 operand R0RegI() %{
2300   constraint(ALLOC_IN_RC(R0_regI));
2301   match(iRegI);
2302 
2303   format %{ %}
2304   interface(REG_INTER);
2305 %}
2306 
2307 operand R1RegI() %{
2308   constraint(ALLOC_IN_RC(R1_regI));
2309   match(iRegI);
2310 
2311   format %{ %}
2312   interface(REG_INTER);
2313 %}
2314 
2315 operand R2RegI() %{
2316   constraint(ALLOC_IN_RC(R2_regI));
2317   match(iRegI);
2318 
2319   format %{ %}
2320   interface(REG_INTER);
2321 %}
2322 
2323 operand R3RegI() %{
2324   constraint(ALLOC_IN_RC(R3_regI));
2325   match(iRegI);
2326 
2327   format %{ %}
2328   interface(REG_INTER);
2329 %}
2330 
2331 operand R12RegI() %{
2332   constraint(ALLOC_IN_RC(R12_regI));
2333   match(iRegI);
2334 
2335   format %{ %}
2336   interface(REG_INTER);
2337 %}
2338 
2339 // Long Register
2340 operand iRegL() %{
2341   constraint(ALLOC_IN_RC(long_reg));
2342   match(RegL);
2343   match(R0R1RegL);
2344   match(R2R3RegL);
2345 //match(iRegLex);
2346 
2347   format %{ %}
2348   interface(REG_INTER);
2349 %}
2350 
2351 operand iRegLd() %{
2352   constraint(ALLOC_IN_RC(long_reg_align));
2353   match(iRegL); // FIXME: allows unaligned R11/R12?
2354 
2355   format %{ %}
2356   interface(REG_INTER);
2357 %}
2358 
2359 // first long arg, or return value
2360 operand R0R1RegL() %{
2361   constraint(ALLOC_IN_RC(R0R1_regL));
2362   match(iRegL);
2363 
2364   format %{ %}
2365   interface(REG_INTER);
2366 %}
2367 
2368 operand R2R3RegL() %{
2369   constraint(ALLOC_IN_RC(R2R3_regL));
2370   match(iRegL);
2371 
2372   format %{ %}
2373   interface(REG_INTER);
2374 %}
2375 
2376 // Condition Code Flag Register
2377 operand flagsReg() %{
2378   constraint(ALLOC_IN_RC(int_flags));
2379   match(RegFlags);
2380 
2381   format %{ "apsr" %}
2382   interface(REG_INTER);
2383 %}
2384 
2385 // Result of compare to 0 (TST)
2386 operand flagsReg_EQNELTGE() %{
2387   constraint(ALLOC_IN_RC(int_flags));
2388   match(RegFlags);
2389 
2390   format %{ "apsr_EQNELTGE" %}
2391   interface(REG_INTER);
2392 %}
2393 
2394 // Condition Code Register, unsigned comparisons.
2395 operand flagsRegU() %{
2396   constraint(ALLOC_IN_RC(int_flags));
2397   match(RegFlags);
2398 #ifdef TODO
2399   match(RegFlagsP);
2400 #endif
2401 
2402   format %{ "apsr_U" %}
2403   interface(REG_INTER);
2404 %}
2405 
2406 // Condition Code Register, pointer comparisons.
2407 operand flagsRegP() %{
2408   constraint(ALLOC_IN_RC(int_flags));
2409   match(RegFlags);
2410 
2411   format %{ "apsr_P" %}
2412   interface(REG_INTER);
2413 %}
2414 
2415 // Condition Code Register, long comparisons.
2416 operand flagsRegL_LTGE() %{
2417   constraint(ALLOC_IN_RC(int_flags));
2418   match(RegFlags);
2419 
2420   format %{ "apsr_L_LTGE" %}
2421   interface(REG_INTER);
2422 %}
2423 
2424 operand flagsRegL_EQNE() %{
2425   constraint(ALLOC_IN_RC(int_flags));
2426   match(RegFlags);
2427 
2428   format %{ "apsr_L_EQNE" %}
2429   interface(REG_INTER);
2430 %}
2431 
2432 operand flagsRegL_LEGT() %{
2433   constraint(ALLOC_IN_RC(int_flags));
2434   match(RegFlags);
2435 
2436   format %{ "apsr_L_LEGT" %}
2437   interface(REG_INTER);
2438 %}
2439 
2440 operand flagsRegUL_LTGE() %{
2441   constraint(ALLOC_IN_RC(int_flags));
2442   match(RegFlags);
2443 
2444   format %{ "apsr_UL_LTGE" %}
2445   interface(REG_INTER);
2446 %}
2447 
2448 operand flagsRegUL_EQNE() %{
2449   constraint(ALLOC_IN_RC(int_flags));
2450   match(RegFlags);
2451 
2452   format %{ "apsr_UL_EQNE" %}
2453   interface(REG_INTER);
2454 %}
2455 
2456 operand flagsRegUL_LEGT() %{
2457   constraint(ALLOC_IN_RC(int_flags));
2458   match(RegFlags);
2459 
2460   format %{ "apsr_UL_LEGT" %}
2461   interface(REG_INTER);
2462 %}
2463 
2464 // Condition Code Register, floating comparisons, unordered same as "less".
2465 operand flagsRegF() %{
2466   constraint(ALLOC_IN_RC(float_flags));
2467   match(RegFlags);
2468 
2469   format %{ "fpscr_F" %}
2470   interface(REG_INTER);
2471 %}
2472 
2473 // Vectors
2474 operand vecD() %{
2475   constraint(ALLOC_IN_RC(actual_dflt_reg));
2476   match(VecD);
2477 
2478   format %{ %}
2479   interface(REG_INTER);
2480 %}
2481 
2482 operand vecX() %{
2483   constraint(ALLOC_IN_RC(vectorx_reg));
2484   match(VecX);
2485 
2486   format %{ %}
2487   interface(REG_INTER);
2488 %}
2489 
2490 operand regD() %{
2491   constraint(ALLOC_IN_RC(actual_dflt_reg));
2492   match(RegD);
2493   match(regD_low);
2494 
2495   format %{ %}
2496   interface(REG_INTER);
2497 %}
2498 
2499 operand regF() %{
2500   constraint(ALLOC_IN_RC(sflt_reg));
2501   match(RegF);
2502 
2503   format %{ %}
2504   interface(REG_INTER);
2505 %}
2506 
2507 operand regD_low() %{
2508   constraint(ALLOC_IN_RC(dflt_low_reg));
2509   match(RegD);
2510 
2511   format %{ %}
2512   interface(REG_INTER);
2513 %}
2514 
2515 // Special Registers
2516 
2517 // Method Register
2518 operand inline_cache_regP(iRegP reg) %{
2519   constraint(ALLOC_IN_RC(Ricklass_regP));
2520   match(reg);
2521   format %{ %}
2522   interface(REG_INTER);
2523 %}
2524 
2525 operand interpreter_method_oop_regP(iRegP reg) %{
2526   constraint(ALLOC_IN_RC(Rmethod_regP));
2527   match(reg);
2528   format %{ %}
2529   interface(REG_INTER);
2530 %}
2531 
2532 
2533 //----------Complex Operands---------------------------------------------------
2534 // Indirect Memory Reference
2535 operand indirect(sp_ptr_RegP reg) %{
2536   constraint(ALLOC_IN_RC(sp_ptr_reg));
2537   match(reg);
2538 
2539   op_cost(100);
2540   format %{ "[$reg]" %}
2541   interface(MEMORY_INTER) %{
2542     base($reg);
2543     index(0xf); // PC => no index
2544     scale(0x0);
2545     disp(0x0);
2546   %}
2547 %}
2548 
2549 
2550 // Indirect with Offset in ]-4096, 4096[
2551 operand indOffset12(sp_ptr_RegP reg, immI12 offset) %{
2552   constraint(ALLOC_IN_RC(sp_ptr_reg));
2553   match(AddP reg offset);
2554 
2555   op_cost(100);
2556   format %{ "[$reg + $offset]" %}
2557   interface(MEMORY_INTER) %{
2558     base($reg);
2559     index(0xf); // PC => no index
2560     scale(0x0);
2561     disp($offset);
2562   %}
2563 %}
2564 
2565 // Indirect with offset for float load/store
2566 operand indOffsetFP(sp_ptr_RegP reg, immIFP offset) %{
2567   constraint(ALLOC_IN_RC(sp_ptr_reg));
2568   match(AddP reg offset);
2569 
2570   op_cost(100);
2571   format %{ "[$reg + $offset]" %}
2572   interface(MEMORY_INTER) %{
2573     base($reg);
2574     index(0xf); // PC => no index
2575     scale(0x0);
2576     disp($offset);
2577   %}
2578 %}
2579 
2580 // Indirect with Offset for half and double words
2581 operand indOffsetHD(sp_ptr_RegP reg, immIHD offset) %{
2582   constraint(ALLOC_IN_RC(sp_ptr_reg));
2583   match(AddP reg offset);
2584 
2585   op_cost(100);
2586   format %{ "[$reg + $offset]" %}
2587   interface(MEMORY_INTER) %{
2588     base($reg);
2589     index(0xf); // PC => no index
2590     scale(0x0);
2591     disp($offset);
2592   %}
2593 %}
2594 
2595 // Indirect with Offset and Offset+4 in ]-1024, 1024[
2596 operand indOffsetFPx2(sp_ptr_RegP reg, immX10x2 offset) %{
2597   constraint(ALLOC_IN_RC(sp_ptr_reg));
2598   match(AddP reg offset);
2599 
2600   op_cost(100);
2601   format %{ "[$reg + $offset]" %}
2602   interface(MEMORY_INTER) %{
2603     base($reg);
2604     index(0xf); // PC => no index
2605     scale(0x0);
2606     disp($offset);
2607   %}
2608 %}
2609 
2610 // Indirect with Offset and Offset+4 in ]-4096, 4096[
2611 operand indOffset12x2(sp_ptr_RegP reg, immI12x2 offset) %{
2612   constraint(ALLOC_IN_RC(sp_ptr_reg));
2613   match(AddP reg offset);
2614 
2615   op_cost(100);
2616   format %{ "[$reg + $offset]" %}
2617   interface(MEMORY_INTER) %{
2618     base($reg);
2619     index(0xf); // PC => no index
2620     scale(0x0);
2621     disp($offset);
2622   %}
2623 %}
2624 
2625 // Indirect with Register Index
2626 operand indIndex(iRegP addr, iRegX index) %{
2627   constraint(ALLOC_IN_RC(ptr_reg));
2628   match(AddP addr index);
2629 
2630   op_cost(100);
2631   format %{ "[$addr + $index]" %}
2632   interface(MEMORY_INTER) %{
2633     base($addr);
2634     index($index);
2635     scale(0x0);
2636     disp(0x0);
2637   %}
2638 %}
2639 
2640 // Indirect Memory Times Scale Plus Index Register
2641 operand indIndexScale(iRegP addr, iRegX index, immU5 scale) %{
2642   constraint(ALLOC_IN_RC(ptr_reg));
2643   match(AddP addr (LShiftX index scale));
2644 
2645   op_cost(100);
2646   format %{"[$addr + $index << $scale]" %}
2647   interface(MEMORY_INTER) %{
2648     base($addr);
2649     index($index);
2650     scale($scale);
2651     disp(0x0);
2652   %}
2653 %}
2654 
2655 // Operands for expressing Control Flow
2656 // NOTE:  Label is a predefined operand which should not be redefined in
2657 //        the AD file.  It is generically handled within the ADLC.
2658 
2659 //----------Conditional Branch Operands----------------------------------------
2660 // Comparison Op  - This is the operation of the comparison, and is limited to
2661 //                  the following set of codes:
2662 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
2663 //
2664 // Other attributes of the comparison, such as unsignedness, are specified
2665 // by the comparison instruction that sets a condition code flags register.
2666 // That result is represented by a flags operand whose subtype is appropriate
2667 // to the unsignedness (etc.) of the comparison.
2668 //
2669 // Later, the instruction which matches both the Comparison Op (a Bool) and
2670 // the flags (produced by the Cmp) specifies the coding of the comparison op
2671 // by matching a specific subtype of Bool operand below, such as cmpOpU.
2672 
2673 operand cmpOp() %{
2674   match(Bool);
2675 
2676   format %{ "" %}
2677   interface(COND_INTER) %{
2678     equal(0x0);
2679     not_equal(0x1);
2680     less(0xb);
2681     greater_equal(0xa);
2682     less_equal(0xd);
2683     greater(0xc);
2684     overflow(0x0); // unsupported/unimplemented
2685     no_overflow(0x0); // unsupported/unimplemented
2686   %}
2687 %}
2688 
2689 // integer comparison with 0, signed
2690 operand cmpOp0() %{
2691   match(Bool);
2692 
2693   format %{ "" %}
2694   interface(COND_INTER) %{
2695     equal(0x0);
2696     not_equal(0x1);
2697     less(0x4);
2698     greater_equal(0x5);
2699     less_equal(0xd); // unsupported
2700     greater(0xc); // unsupported
2701     overflow(0x0); // unsupported/unimplemented
2702     no_overflow(0x0); // unsupported/unimplemented
2703   %}
2704 %}
2705 
2706 // Comparison Op, unsigned
2707 operand cmpOpU() %{
2708   match(Bool);
2709 
2710   format %{ "u" %}
2711   interface(COND_INTER) %{
2712     equal(0x0);
2713     not_equal(0x1);
2714     less(0x3);
2715     greater_equal(0x2);
2716     less_equal(0x9);
2717     greater(0x8);
2718     overflow(0x0); // unsupported/unimplemented
2719     no_overflow(0x0); // unsupported/unimplemented
2720   %}
2721 %}
2722 
2723 // Comparison Op, pointer (same as unsigned)
2724 operand cmpOpP() %{
2725   match(Bool);
2726 
2727   format %{ "p" %}
2728   interface(COND_INTER) %{
2729     equal(0x0);
2730     not_equal(0x1);
2731     less(0x3);
2732     greater_equal(0x2);
2733     less_equal(0x9);
2734     greater(0x8);
2735     overflow(0x0); // unsupported/unimplemented
2736     no_overflow(0x0); // unsupported/unimplemented
2737   %}
2738 %}
2739 
2740 operand cmpOpL() %{
2741   match(Bool);
2742 
2743   format %{ "L" %}
2744   interface(COND_INTER) %{
2745     equal(0x0);
2746     not_equal(0x1);
2747     less(0xb);
2748     greater_equal(0xa);
2749     less_equal(0xd);
2750     greater(0xc);
2751     overflow(0x0); // unsupported/unimplemented
2752     no_overflow(0x0); // unsupported/unimplemented
2753   %}
2754 %}
2755 
2756 operand cmpOpL_commute() %{
2757   match(Bool);
2758 
2759   format %{ "L" %}
2760   interface(COND_INTER) %{
2761     equal(0x0);
2762     not_equal(0x1);
2763     less(0xc);
2764     greater_equal(0xd);
2765     less_equal(0xa);
2766     greater(0xb);
2767     overflow(0x0); // unsupported/unimplemented
2768     no_overflow(0x0); // unsupported/unimplemented
2769   %}
2770 %}
2771 
2772 operand cmpOpUL() %{
2773   match(Bool);
2774 
2775   format %{ "UL" %}
2776   interface(COND_INTER) %{
2777     equal(0x0);
2778     not_equal(0x1);
2779     less(0x3);
2780     greater_equal(0x2);
2781     less_equal(0x9);
2782     greater(0x8);
2783     overflow(0x0); // unsupported/unimplemented
2784     no_overflow(0x0); // unsupported/unimplemented
2785   %}
2786 %}
2787 
2788 operand cmpOpUL_commute() %{
2789   match(Bool);
2790 
2791   format %{ "UL" %}
2792   interface(COND_INTER) %{
2793     equal(0x0);
2794     not_equal(0x1);
2795     less(0x8);
2796     greater_equal(0x9);
2797     less_equal(0x2);
2798     greater(0x3);
2799     overflow(0x0); // unsupported/unimplemented
2800     no_overflow(0x0); // unsupported/unimplemented
2801   %}
2802 %}
2803 
2804 
2805 //----------OPERAND CLASSES----------------------------------------------------
2806 // Operand Classes are groups of operands that are used to simplify
2807 // instruction definitions by not requiring the AD writer to specify separate
2808 // instructions for every form of operand when the instruction accepts
2809 // multiple operand types with the same basic encoding and format.  The classic
2810 // case of this is memory operands.
2811 
2812 opclass memoryI ( indirect, indOffset12, indIndex, indIndexScale );
2813 opclass memoryP ( indirect, indOffset12, indIndex, indIndexScale );
2814 opclass memoryF ( indirect, indOffsetFP );
2815 opclass memoryF2 ( indirect, indOffsetFPx2 );
2816 opclass memoryD ( indirect, indOffsetFP );
2817 opclass memoryfp( indirect, indOffsetFP );
2818 opclass memoryB ( indirect, indIndex, indOffsetHD );
2819 opclass memoryS ( indirect, indIndex, indOffsetHD );
2820 opclass memoryL ( indirect, indIndex, indOffsetHD );
2821 
2822 opclass memoryScaledI(indIndexScale);
2823 opclass memoryScaledP(indIndexScale);
2824 
2825 // when ldrex/strex is used:
2826 opclass memoryex ( indirect );
2827 opclass indIndexMemory( indIndex );
2828 opclass memorylong ( indirect, indOffset12x2 );
2829 opclass memoryvld ( indirect /* , write back mode not implemented */ );
2830 
2831 //----------PIPELINE-----------------------------------------------------------
2832 pipeline %{
2833 
2834 //----------ATTRIBUTES---------------------------------------------------------
2835 attributes %{
2836   fixed_size_instructions;           // Fixed size instructions
2837   max_instructions_per_bundle = 4;   // Up to 4 instructions per bundle
2838   instruction_unit_size = 4;         // An instruction is 4 bytes long
2839   instruction_fetch_unit_size = 16;  // The processor fetches one line
2840   instruction_fetch_units = 1;       // of 16 bytes
2841 
2842   // List of nop instructions
2843   nops( Nop_A0, Nop_A1, Nop_MS, Nop_FA, Nop_BR );
2844 %}
2845 
2846 //----------RESOURCES----------------------------------------------------------
2847 // Resources are the functional units available to the machine
2848 resources(A0, A1, MS, BR, FA, FM, IDIV, FDIV, IALU = A0 | A1);
2849 
2850 //----------PIPELINE DESCRIPTION-----------------------------------------------
2851 // Pipeline Description specifies the stages in the machine's pipeline
2852 
2853 pipe_desc(A, P, F, B, I, J, S, R, E, C, M, W, X, T, D);
2854 
2855 //----------PIPELINE CLASSES---------------------------------------------------
2856 // Pipeline Classes describe the stages in which input and output are
2857 // referenced by the hardware pipeline.
2858 
2859 // Integer ALU reg-reg operation
2860 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
2861     single_instruction;
2862     dst   : E(write);
2863     src1  : R(read);
2864     src2  : R(read);
2865     IALU  : R;
2866 %}
2867 
2868 // Integer ALU reg-reg long operation
2869 pipe_class ialu_reg_reg_2(iRegL dst, iRegL src1, iRegL src2) %{
2870     instruction_count(2);
2871     dst   : E(write);
2872     src1  : R(read);
2873     src2  : R(read);
2874     IALU  : R;
2875     IALU  : R;
2876 %}
2877 
2878 // Integer ALU reg-reg long dependent operation
2879 pipe_class ialu_reg_reg_2_dep(iRegL dst, iRegL src1, iRegL src2, flagsReg cr) %{
2880     instruction_count(1); multiple_bundles;
2881     dst   : E(write);
2882     src1  : R(read);
2883     src2  : R(read);
2884     cr    : E(write);
2885     IALU  : R(2);
2886 %}
2887 
2888 // Integer ALU reg-imm operaion
2889 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) %{
2890     single_instruction;
2891     dst   : E(write);
2892     src1  : R(read);
2893     IALU  : R;
2894 %}
2895 
2896 // Integer ALU reg-reg operation with condition code
2897 pipe_class ialu_cc_reg_reg(iRegI dst, iRegI src1, iRegI src2, flagsReg cr) %{
2898     single_instruction;
2899     dst   : E(write);
2900     cr    : E(write);
2901     src1  : R(read);
2902     src2  : R(read);
2903     IALU  : R;
2904 %}
2905 
2906 // Integer ALU zero-reg operation
2907 pipe_class ialu_zero_reg(iRegI dst, immI0 zero, iRegI src2) %{
2908     single_instruction;
2909     dst   : E(write);
2910     src2  : R(read);
2911     IALU  : R;
2912 %}
2913 
2914 // Integer ALU zero-reg operation with condition code only
2915 pipe_class ialu_cconly_zero_reg(flagsReg cr, iRegI src) %{
2916     single_instruction;
2917     cr    : E(write);
2918     src   : R(read);
2919     IALU  : R;
2920 %}
2921 
2922 // Integer ALU reg-reg operation with condition code only
2923 pipe_class ialu_cconly_reg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
2924     single_instruction;
2925     cr    : E(write);
2926     src1  : R(read);
2927     src2  : R(read);
2928     IALU  : R;
2929 %}
2930 
2931 // Integer ALU reg-imm operation with condition code only
2932 pipe_class ialu_cconly_reg_imm(flagsReg cr, iRegI src1) %{
2933     single_instruction;
2934     cr    : E(write);
2935     src1  : R(read);
2936     IALU  : R;
2937 %}
2938 
2939 // Integer ALU reg-reg-zero operation with condition code only
2940 pipe_class ialu_cconly_reg_reg_zero(flagsReg cr, iRegI src1, iRegI src2, immI0 zero) %{
2941     single_instruction;
2942     cr    : E(write);
2943     src1  : R(read);
2944     src2  : R(read);
2945     IALU  : R;
2946 %}
2947 
2948 // Integer ALU reg-imm-zero operation with condition code only
2949 pipe_class ialu_cconly_reg_imm_zero(flagsReg cr, iRegI src1, immI0 zero) %{
2950     single_instruction;
2951     cr    : E(write);
2952     src1  : R(read);
2953     IALU  : R;
2954 %}
2955 
2956 // Integer ALU reg-reg operation with condition code, src1 modified
2957 pipe_class ialu_cc_rwreg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
2958     single_instruction;
2959     cr    : E(write);
2960     src1  : E(write);
2961     src1  : R(read);
2962     src2  : R(read);
2963     IALU  : R;
2964 %}
2965 
2966 pipe_class cmpL_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg cr ) %{
2967     multiple_bundles;
2968     dst   : E(write)+4;
2969     cr    : E(write);
2970     src1  : R(read);
2971     src2  : R(read);
2972     IALU  : R(3);
2973     BR    : R(2);
2974 %}
2975 
2976 // Integer ALU operation
2977 pipe_class ialu_none(iRegI dst) %{
2978     single_instruction;
2979     dst   : E(write);
2980     IALU  : R;
2981 %}
2982 
2983 // Integer ALU reg operation
2984 pipe_class ialu_reg(iRegI dst, iRegI src) %{
2985     single_instruction; may_have_no_code;
2986     dst   : E(write);
2987     src   : R(read);
2988     IALU  : R;
2989 %}
2990 
2991 // Integer ALU reg conditional operation
2992 // This instruction has a 1 cycle stall, and cannot execute
2993 // in the same cycle as the instruction setting the condition
2994 // code. We kludge this by pretending to read the condition code
2995 // 1 cycle earlier, and by marking the functional units as busy
2996 // for 2 cycles with the result available 1 cycle later than
2997 // is really the case.
2998 pipe_class ialu_reg_flags( iRegI op2_out, iRegI op2_in, iRegI op1, flagsReg cr ) %{
2999     single_instruction;
3000     op2_out : C(write);
3001     op1     : R(read);
3002     cr      : R(read);       // This is really E, with a 1 cycle stall
3003     BR      : R(2);
3004     MS      : R(2);
3005 %}
3006 
3007 // Integer ALU reg operation
3008 pipe_class ialu_move_reg_L_to_I(iRegI dst, iRegL src) %{
3009     single_instruction; may_have_no_code;
3010     dst   : E(write);
3011     src   : R(read);
3012     IALU  : R;
3013 %}
3014 pipe_class ialu_move_reg_I_to_L(iRegL dst, iRegI src) %{
3015     single_instruction; may_have_no_code;
3016     dst   : E(write);
3017     src   : R(read);
3018     IALU  : R;
3019 %}
3020 
3021 // Two integer ALU reg operations
3022 pipe_class ialu_reg_2(iRegL dst, iRegL src) %{
3023     instruction_count(2);
3024     dst   : E(write);
3025     src   : R(read);
3026     A0    : R;
3027     A1    : R;
3028 %}
3029 
3030 // Two integer ALU reg operations
3031 pipe_class ialu_move_reg_L_to_L(iRegL dst, iRegL src) %{
3032     instruction_count(2); may_have_no_code;
3033     dst   : E(write);
3034     src   : R(read);
3035     A0    : R;
3036     A1    : R;
3037 %}
3038 
3039 // Integer ALU imm operation
3040 pipe_class ialu_imm(iRegI dst) %{
3041     single_instruction;
3042     dst   : E(write);
3043     IALU  : R;
3044 %}
3045 
3046 pipe_class ialu_imm_n(iRegI dst) %{
3047     single_instruction;
3048     dst   : E(write);
3049     IALU  : R;
3050 %}
3051 
3052 // Integer ALU reg-reg with carry operation
3053 pipe_class ialu_reg_reg_cy(iRegI dst, iRegI src1, iRegI src2, iRegI cy) %{
3054     single_instruction;
3055     dst   : E(write);
3056     src1  : R(read);
3057     src2  : R(read);
3058     IALU  : R;
3059 %}
3060 
3061 // Integer ALU cc operation
3062 pipe_class ialu_cc(iRegI dst, flagsReg cc) %{
3063     single_instruction;
3064     dst   : E(write);
3065     cc    : R(read);
3066     IALU  : R;
3067 %}
3068 
3069 // Integer ALU cc / second IALU operation
3070 pipe_class ialu_reg_ialu( iRegI dst, iRegI src ) %{
3071     instruction_count(1); multiple_bundles;
3072     dst   : E(write)+1;
3073     src   : R(read);
3074     IALU  : R;
3075 %}
3076 
3077 // Integer ALU cc / second IALU operation
3078 pipe_class ialu_reg_reg_ialu( iRegI dst, iRegI p, iRegI q ) %{
3079     instruction_count(1); multiple_bundles;
3080     dst   : E(write)+1;
3081     p     : R(read);
3082     q     : R(read);
3083     IALU  : R;
3084 %}
3085 
3086 // Integer ALU hi-lo-reg operation
3087 pipe_class ialu_hi_lo_reg(iRegI dst, immI src) %{
3088     instruction_count(1); multiple_bundles;
3089     dst   : E(write)+1;
3090     IALU  : R(2);
3091 %}
3092 
3093 // Long Constant
3094 pipe_class loadConL( iRegL dst, immL src ) %{
3095     instruction_count(2); multiple_bundles;
3096     dst   : E(write)+1;
3097     IALU  : R(2);
3098     IALU  : R(2);
3099 %}
3100 
3101 // Pointer Constant
3102 pipe_class loadConP( iRegP dst, immP src ) %{
3103     instruction_count(0); multiple_bundles;
3104     fixed_latency(6);
3105 %}
3106 
3107 // Long Constant small
3108 pipe_class loadConLlo( iRegL dst, immL src ) %{
3109     instruction_count(2);
3110     dst   : E(write);
3111     IALU  : R;
3112     IALU  : R;
3113 %}
3114 
3115 // [PHH] This is wrong for 64-bit.  See LdImmF/D.
3116 pipe_class loadConFD(regF dst, immF src, iRegP tmp) %{
3117     instruction_count(1); multiple_bundles;
3118     src   : R(read);
3119     dst   : M(write)+1;
3120     IALU  : R;
3121     MS    : E;
3122 %}
3123 
3124 // Integer ALU nop operation
3125 pipe_class ialu_nop() %{
3126     single_instruction;
3127     IALU  : R;
3128 %}
3129 
3130 // Integer ALU nop operation
3131 pipe_class ialu_nop_A0() %{
3132     single_instruction;
3133     A0    : R;
3134 %}
3135 
3136 // Integer ALU nop operation
3137 pipe_class ialu_nop_A1() %{
3138     single_instruction;
3139     A1    : R;
3140 %}
3141 
3142 // Integer Multiply reg-reg operation
3143 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
3144     single_instruction;
3145     dst   : E(write);
3146     src1  : R(read);
3147     src2  : R(read);
3148     MS    : R(5);
3149 %}
3150 
3151 pipe_class mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
3152     single_instruction;
3153     dst   : E(write)+4;
3154     src1  : R(read);
3155     src2  : R(read);
3156     MS    : R(6);
3157 %}
3158 
3159 // Integer Divide reg-reg
3160 pipe_class sdiv_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI temp, flagsReg cr) %{
3161     instruction_count(1); multiple_bundles;
3162     dst   : E(write);
3163     temp  : E(write);
3164     src1  : R(read);
3165     src2  : R(read);
3166     temp  : R(read);
3167     MS    : R(38);
3168 %}
3169 
3170 // Long Divide
3171 pipe_class divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
3172     dst  : E(write)+71;
3173     src1 : R(read);
3174     src2 : R(read)+1;
3175     MS   : R(70);
3176 %}
3177 
3178 // Floating Point Add Float
3179 pipe_class faddF_reg_reg(regF dst, regF src1, regF src2) %{
3180     single_instruction;
3181     dst   : X(write);
3182     src1  : E(read);
3183     src2  : E(read);
3184     FA    : R;
3185 %}
3186 
3187 // Floating Point Add Double
3188 pipe_class faddD_reg_reg(regD dst, regD src1, regD src2) %{
3189     single_instruction;
3190     dst   : X(write);
3191     src1  : E(read);
3192     src2  : E(read);
3193     FA    : R;
3194 %}
3195 
3196 // Floating Point Conditional Move based on integer flags
3197 pipe_class int_conditional_float_move (cmpOp cmp, flagsReg cr, regF dst, regF src) %{
3198     single_instruction;
3199     dst   : X(write);
3200     src   : E(read);
3201     cr    : R(read);
3202     FA    : R(2);
3203     BR    : R(2);
3204 %}
3205 
3206 // Floating Point Conditional Move based on integer flags
3207 pipe_class int_conditional_double_move (cmpOp cmp, flagsReg cr, regD dst, regD src) %{
3208     single_instruction;
3209     dst   : X(write);
3210     src   : E(read);
3211     cr    : R(read);
3212     FA    : R(2);
3213     BR    : R(2);
3214 %}
3215 
3216 // Floating Point Multiply Float
3217 pipe_class fmulF_reg_reg(regF dst, regF src1, regF src2) %{
3218     single_instruction;
3219     dst   : X(write);
3220     src1  : E(read);
3221     src2  : E(read);
3222     FM    : R;
3223 %}
3224 
3225 // Floating Point Multiply Double
3226 pipe_class fmulD_reg_reg(regD dst, regD src1, regD src2) %{
3227     single_instruction;
3228     dst   : X(write);
3229     src1  : E(read);
3230     src2  : E(read);
3231     FM    : R;
3232 %}
3233 
3234 // Floating Point Divide Float
3235 pipe_class fdivF_reg_reg(regF dst, regF src1, regF src2) %{
3236     single_instruction;
3237     dst   : X(write);
3238     src1  : E(read);
3239     src2  : E(read);
3240     FM    : R;
3241     FDIV  : C(14);
3242 %}
3243 
3244 // Floating Point Divide Double
3245 pipe_class fdivD_reg_reg(regD dst, regD src1, regD src2) %{
3246     single_instruction;
3247     dst   : X(write);
3248     src1  : E(read);
3249     src2  : E(read);
3250     FM    : R;
3251     FDIV  : C(17);
3252 %}
3253 
3254 // Floating Point Move/Negate/Abs Float
3255 pipe_class faddF_reg(regF dst, regF src) %{
3256     single_instruction;
3257     dst   : W(write);
3258     src   : E(read);
3259     FA    : R(1);
3260 %}
3261 
3262 // Floating Point Move/Negate/Abs Double
3263 pipe_class faddD_reg(regD dst, regD src) %{
3264     single_instruction;
3265     dst   : W(write);
3266     src   : E(read);
3267     FA    : R;
3268 %}
3269 
3270 // Floating Point Convert F->D
3271 pipe_class fcvtF2D(regD dst, regF src) %{
3272     single_instruction;
3273     dst   : X(write);
3274     src   : E(read);
3275     FA    : R;
3276 %}
3277 
3278 // Floating Point Convert I->D
3279 pipe_class fcvtI2D(regD dst, regF src) %{
3280     single_instruction;
3281     dst   : X(write);
3282     src   : E(read);
3283     FA    : R;
3284 %}
3285 
3286 // Floating Point Convert LHi->D
3287 pipe_class fcvtLHi2D(regD dst, regD src) %{
3288     single_instruction;
3289     dst   : X(write);
3290     src   : E(read);
3291     FA    : R;
3292 %}
3293 
3294 // Floating Point Convert L->D
3295 pipe_class fcvtL2D(regD dst, iRegL src) %{
3296     single_instruction;
3297     dst   : X(write);
3298     src   : E(read);
3299     FA    : R;
3300 %}
3301 
3302 // Floating Point Convert L->F
3303 pipe_class fcvtL2F(regF dst, iRegL src) %{
3304     single_instruction;
3305     dst   : X(write);
3306     src   : E(read);
3307     FA    : R;
3308 %}
3309 
3310 // Floating Point Convert D->F
3311 pipe_class fcvtD2F(regD dst, regF src) %{
3312     single_instruction;
3313     dst   : X(write);
3314     src   : E(read);
3315     FA    : R;
3316 %}
3317 
3318 // Floating Point Convert I->L
3319 pipe_class fcvtI2L(regD dst, regF src) %{
3320     single_instruction;
3321     dst   : X(write);
3322     src   : E(read);
3323     FA    : R;
3324 %}
3325 
3326 // Floating Point Convert D->F
3327 pipe_class fcvtD2I(iRegI dst, regD src, flagsReg cr) %{
3328     instruction_count(1); multiple_bundles;
3329     dst   : X(write)+6;
3330     src   : E(read);
3331     FA    : R;
3332 %}
3333 
3334 // Floating Point Convert D->L
3335 pipe_class fcvtD2L(regD dst, regD src, flagsReg cr) %{
3336     instruction_count(1); multiple_bundles;
3337     dst   : X(write)+6;
3338     src   : E(read);
3339     FA    : R;
3340 %}
3341 
3342 // Floating Point Convert F->I
3343 pipe_class fcvtF2I(regF dst, regF src, flagsReg cr) %{
3344     instruction_count(1); multiple_bundles;
3345     dst   : X(write)+6;
3346     src   : E(read);
3347     FA    : R;
3348 %}
3349 
3350 // Floating Point Convert F->L
3351 pipe_class fcvtF2L(regD dst, regF src, flagsReg cr) %{
3352     instruction_count(1); multiple_bundles;
3353     dst   : X(write)+6;
3354     src   : E(read);
3355     FA    : R;
3356 %}
3357 
3358 // Floating Point Convert I->F
3359 pipe_class fcvtI2F(regF dst, regF src) %{
3360     single_instruction;
3361     dst   : X(write);
3362     src   : E(read);
3363     FA    : R;
3364 %}
3365 
3366 // Floating Point Compare
3367 pipe_class faddF_fcc_reg_reg_zero(flagsRegF cr, regF src1, regF src2, immI0 zero) %{
3368     single_instruction;
3369     cr    : X(write);
3370     src1  : E(read);
3371     src2  : E(read);
3372     FA    : R;
3373 %}
3374 
3375 // Floating Point Compare
3376 pipe_class faddD_fcc_reg_reg_zero(flagsRegF cr, regD src1, regD src2, immI0 zero) %{
3377     single_instruction;
3378     cr    : X(write);
3379     src1  : E(read);
3380     src2  : E(read);
3381     FA    : R;
3382 %}
3383 
3384 // Floating Add Nop
3385 pipe_class fadd_nop() %{
3386     single_instruction;
3387     FA  : R;
3388 %}
3389 
3390 // Integer Store to Memory
3391 pipe_class istore_mem_reg(memoryI mem, iRegI src) %{
3392     single_instruction;
3393     mem   : R(read);
3394     src   : C(read);
3395     MS    : R;
3396 %}
3397 
3398 // Integer Store to Memory
3399 pipe_class istore_mem_spORreg(memoryI mem, sp_ptr_RegP src) %{
3400     single_instruction;
3401     mem   : R(read);
3402     src   : C(read);
3403     MS    : R;
3404 %}
3405 
3406 // Float Store
3407 pipe_class fstoreF_mem_reg(memoryF mem, RegF src) %{
3408     single_instruction;
3409     mem : R(read);
3410     src : C(read);
3411     MS  : R;
3412 %}
3413 
3414 // Float Store
3415 pipe_class fstoreF_mem_zero(memoryF mem, immF0 src) %{
3416     single_instruction;
3417     mem : R(read);
3418     MS  : R;
3419 %}
3420 
3421 // Double Store
3422 pipe_class fstoreD_mem_reg(memoryD mem, RegD src) %{
3423     instruction_count(1);
3424     mem : R(read);
3425     src : C(read);
3426     MS  : R;
3427 %}
3428 
3429 // Double Store
3430 pipe_class fstoreD_mem_zero(memoryD mem, immD0 src) %{
3431     single_instruction;
3432     mem : R(read);
3433     MS  : R;
3434 %}
3435 
3436 // Integer Load (when sign bit propagation not needed)
3437 pipe_class iload_mem(iRegI dst, memoryI mem) %{
3438     single_instruction;
3439     mem : R(read);
3440     dst : C(write);
3441     MS  : R;
3442 %}
3443 
3444 // Integer Load (when sign bit propagation or masking is needed)
3445 pipe_class iload_mask_mem(iRegI dst, memoryI mem) %{
3446     single_instruction;
3447     mem : R(read);
3448     dst : M(write);
3449     MS  : R;
3450 %}
3451 
3452 // Float Load
3453 pipe_class floadF_mem(regF dst, memoryF mem) %{
3454     single_instruction;
3455     mem : R(read);
3456     dst : M(write);
3457     MS  : R;
3458 %}
3459 
3460 // Float Load
3461 pipe_class floadD_mem(regD dst, memoryD mem) %{
3462     instruction_count(1); multiple_bundles; // Again, unaligned argument is only multiple case
3463     mem : R(read);
3464     dst : M(write);
3465     MS  : R;
3466 %}
3467 
3468 // Memory Nop
3469 pipe_class mem_nop() %{
3470     single_instruction;
3471     MS  : R;
3472 %}
3473 
3474 pipe_class sethi(iRegP dst, immI src) %{
3475     single_instruction;
3476     dst  : E(write);
3477     IALU : R;
3478 %}
3479 
3480 pipe_class loadPollP(iRegP poll) %{
3481     single_instruction;
3482     poll : R(read);
3483     MS   : R;
3484 %}
3485 
3486 pipe_class br(Universe br, label labl) %{
3487     single_instruction_with_delay_slot;
3488     BR  : R;
3489 %}
3490 
3491 pipe_class br_cc(Universe br, cmpOp cmp, flagsReg cr, label labl) %{
3492     single_instruction_with_delay_slot;
3493     cr    : E(read);
3494     BR    : R;
3495 %}
3496 
3497 pipe_class br_reg(Universe br, cmpOp cmp, iRegI op1, label labl) %{
3498     single_instruction_with_delay_slot;
3499     op1 : E(read);
3500     BR  : R;
3501     MS  : R;
3502 %}
3503 
3504 pipe_class br_nop() %{
3505     single_instruction;
3506     BR  : R;
3507 %}
3508 
3509 pipe_class simple_call(method meth) %{
3510     instruction_count(2); multiple_bundles; force_serialization;
3511     fixed_latency(100);
3512     BR  : R(1);
3513     MS  : R(1);
3514     A0  : R(1);
3515 %}
3516 
3517 pipe_class compiled_call(method meth) %{
3518     instruction_count(1); multiple_bundles; force_serialization;
3519     fixed_latency(100);
3520     MS  : R(1);
3521 %}
3522 
3523 pipe_class call(method meth) %{
3524     instruction_count(0); multiple_bundles; force_serialization;
3525     fixed_latency(100);
3526 %}
3527 
3528 pipe_class tail_call(Universe ignore, label labl) %{
3529     single_instruction; has_delay_slot;
3530     fixed_latency(100);
3531     BR  : R(1);
3532     MS  : R(1);
3533 %}
3534 
3535 pipe_class ret(Universe ignore) %{
3536     single_instruction; has_delay_slot;
3537     BR  : R(1);
3538     MS  : R(1);
3539 %}
3540 
3541 // The real do-nothing guy
3542 pipe_class empty( ) %{
3543     instruction_count(0);
3544 %}
3545 
3546 pipe_class long_memory_op() %{
3547     instruction_count(0); multiple_bundles; force_serialization;
3548     fixed_latency(25);
3549     MS  : R(1);
3550 %}
3551 
3552 // Check-cast
3553 pipe_class partial_subtype_check_pipe(Universe ignore, iRegP array, iRegP match ) %{
3554     array : R(read);
3555     match  : R(read);
3556     IALU   : R(2);
3557     BR     : R(2);
3558     MS     : R;
3559 %}
3560 
3561 // Convert FPU flags into +1,0,-1
3562 pipe_class floating_cmp( iRegI dst, regF src1, regF src2 ) %{
3563     src1  : E(read);
3564     src2  : E(read);
3565     dst   : E(write);
3566     FA    : R;
3567     MS    : R(2);
3568     BR    : R(2);
3569 %}
3570 
3571 // Compare for p < q, and conditionally add y
3572 pipe_class cadd_cmpltmask( iRegI p, iRegI q, iRegI y ) %{
3573     p     : E(read);
3574     q     : E(read);
3575     y     : E(read);
3576     IALU  : R(3)
3577 %}
3578 
3579 // Perform a compare, then move conditionally in a branch delay slot.
3580 pipe_class min_max( iRegI src2, iRegI srcdst ) %{
3581     src2   : E(read);
3582     srcdst : E(read);
3583     IALU   : R;
3584     BR     : R;
3585 %}
3586 
3587 // Define the class for the Nop node
3588 define %{
3589    MachNop = ialu_nop;
3590 %}
3591 
3592 %}
3593 
3594 //----------INSTRUCTIONS-------------------------------------------------------
3595 
3596 //------------Special Nop instructions for bundling - no match rules-----------
3597 // Nop using the A0 functional unit
3598 instruct Nop_A0() %{
3599   ins_pipe(ialu_nop_A0);
3600 %}
3601 
3602 // Nop using the A1 functional unit
3603 instruct Nop_A1( ) %{
3604   ins_pipe(ialu_nop_A1);
3605 %}
3606 
3607 // Nop using the memory functional unit
3608 instruct Nop_MS( ) %{
3609   ins_pipe(mem_nop);
3610 %}
3611 
3612 // Nop using the floating add functional unit
3613 instruct Nop_FA( ) %{
3614   ins_pipe(fadd_nop);
3615 %}
3616 
3617 // Nop using the branch functional unit
3618 instruct Nop_BR( ) %{
3619   ins_pipe(br_nop);
3620 %}
3621 
3622 //----------Load/Store/Move Instructions---------------------------------------
3623 //----------Load Instructions--------------------------------------------------
3624 // Load Byte (8bit signed)
3625 instruct loadB(iRegI dst, memoryB mem) %{
3626   match(Set dst (LoadB mem));
3627   ins_cost(MEMORY_REF_COST);
3628 
3629   size(4);
3630   format %{ "LDRSB   $dst,$mem\t! byte -> int" %}
3631   ins_encode %{
3632     __ ldrsb($dst$$Register, $mem$$Address);
3633   %}
3634   ins_pipe(iload_mask_mem);
3635 %}
3636 
3637 // Load Byte (8bit signed) into a Long Register
3638 instruct loadB2L(iRegL dst, memoryB mem) %{
3639   match(Set dst (ConvI2L (LoadB mem)));
3640   ins_cost(MEMORY_REF_COST);
3641 
3642   size(8);
3643   format %{ "LDRSB $dst.lo,$mem\t! byte -> long\n\t"
3644             "ASR   $dst.hi,$dst.lo,31" %}
3645   ins_encode %{
3646     __ ldrsb($dst$$Register, $mem$$Address);
3647     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
3648   %}
3649   ins_pipe(iload_mask_mem);
3650 %}
3651 
3652 // Load Unsigned Byte (8bit UNsigned) into an int reg
3653 instruct loadUB(iRegI dst, memoryB mem) %{
3654   match(Set dst (LoadUB mem));
3655   ins_cost(MEMORY_REF_COST);
3656 
3657   size(4);
3658   format %{ "LDRB   $dst,$mem\t! ubyte -> int" %}
3659   ins_encode %{
3660     __ ldrb($dst$$Register, $mem$$Address);
3661   %}
3662   ins_pipe(iload_mem);
3663 %}
3664 
3665 // Load Unsigned Byte (8bit UNsigned) into a Long Register
3666 instruct loadUB2L(iRegL dst, memoryB mem) %{
3667   match(Set dst (ConvI2L (LoadUB mem)));
3668   ins_cost(MEMORY_REF_COST);
3669 
3670   size(8);
3671   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
3672             "MOV   $dst.hi,0" %}
3673   ins_encode %{
3674     __ ldrb($dst$$Register, $mem$$Address);
3675     __ mov($dst$$Register->successor(), 0);
3676   %}
3677   ins_pipe(iload_mem);
3678 %}
3679 
3680 // Load Unsigned Byte (8 bit UNsigned) with immediate mask into Long Register
3681 instruct loadUB2L_limmI(iRegL dst, memoryB mem, limmIlow8 mask) %{
3682   match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
3683 
3684   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
3685   size(12);
3686   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
3687             "MOV   $dst.hi,0\n\t"
3688             "AND  $dst.lo,$dst.lo,$mask" %}
3689   ins_encode %{
3690     __ ldrb($dst$$Register, $mem$$Address);
3691     __ mov($dst$$Register->successor(), 0);
3692     __ andr($dst$$Register, $dst$$Register, limmI_low($mask$$constant, 8));
3693   %}
3694   ins_pipe(iload_mem);
3695 %}
3696 
3697 // Load Short (16bit signed)
3698 
3699 instruct loadS(iRegI dst, memoryS mem) %{
3700   match(Set dst (LoadS mem));
3701   ins_cost(MEMORY_REF_COST);
3702 
3703   size(4);
3704   format %{ "LDRSH   $dst,$mem\t! short" %}
3705   ins_encode %{
3706     __ ldrsh($dst$$Register, $mem$$Address);
3707   %}
3708   ins_pipe(iload_mask_mem);
3709 %}
3710 
3711 // Load Short (16 bit signed) to Byte (8 bit signed)
3712 instruct loadS2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
3713   match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
3714   ins_cost(MEMORY_REF_COST);
3715 
3716   size(4);
3717 
3718   format %{ "LDRSB   $dst,$mem\t! short -> byte" %}
3719   ins_encode %{
3720     __ ldrsb($dst$$Register, $mem$$Address);
3721   %}
3722   ins_pipe(iload_mask_mem);
3723 %}
3724 
3725 // Load Short (16bit signed) into a Long Register
3726 instruct loadS2L(iRegL dst, memoryS mem) %{
3727   match(Set dst (ConvI2L (LoadS mem)));
3728   ins_cost(MEMORY_REF_COST);
3729 
3730   size(8);
3731   format %{ "LDRSH $dst.lo,$mem\t! short -> long\n\t"
3732             "ASR   $dst.hi,$dst.lo,31" %}
3733   ins_encode %{
3734     __ ldrsh($dst$$Register, $mem$$Address);
3735     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
3736   %}
3737   ins_pipe(iload_mask_mem);
3738 %}
3739 
3740 // Load Unsigned Short/Char (16bit UNsigned)
3741 
3742 
3743 instruct loadUS(iRegI dst, memoryS mem) %{
3744   match(Set dst (LoadUS mem));
3745   ins_cost(MEMORY_REF_COST);
3746 
3747   size(4);
3748   format %{ "LDRH   $dst,$mem\t! ushort/char" %}
3749   ins_encode %{
3750     __ ldrh($dst$$Register, $mem$$Address);
3751   %}
3752   ins_pipe(iload_mem);
3753 %}
3754 
3755 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
3756 instruct loadUS2B(iRegI dst, memoryB mem, immI_24 twentyfour) %{
3757   match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
3758   ins_cost(MEMORY_REF_COST);
3759 
3760   size(4);
3761   format %{ "LDRSB   $dst,$mem\t! ushort -> byte" %}
3762   ins_encode %{
3763     __ ldrsb($dst$$Register, $mem$$Address);
3764   %}
3765   ins_pipe(iload_mask_mem);
3766 %}
3767 
3768 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register
3769 instruct loadUS2L(iRegL dst, memoryS mem) %{
3770   match(Set dst (ConvI2L (LoadUS mem)));
3771   ins_cost(MEMORY_REF_COST);
3772 
3773   size(8);
3774   format %{ "LDRH  $dst.lo,$mem\t! short -> long\n\t"
3775             "MOV   $dst.hi, 0" %}
3776   ins_encode %{
3777     __ ldrh($dst$$Register, $mem$$Address);
3778     __ mov($dst$$Register->successor(), 0);
3779   %}
3780   ins_pipe(iload_mem);
3781 %}
3782 
3783 // Load Unsigned Short/Char (16bit UNsigned) with mask 0xFF into a Long Register
3784 instruct loadUS2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
3785   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
3786   ins_cost(MEMORY_REF_COST);
3787 
3788   size(8);
3789   format %{ "LDRB  $dst.lo,$mem\t! \n\t"
3790             "MOV   $dst.hi, 0" %}
3791   ins_encode %{
3792     __ ldrb($dst$$Register, $mem$$Address);
3793     __ mov($dst$$Register->successor(), 0);
3794   %}
3795   ins_pipe(iload_mem);
3796 %}
3797 
3798 // Load Unsigned Short/Char (16bit UNsigned) with a immediate mask into a Long Register
3799 instruct loadUS2L_limmI(iRegL dst, memoryS mem, limmI mask) %{
3800   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
3801   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
3802 
3803   size(12);
3804   format %{ "LDRH   $dst,$mem\t! ushort/char & mask -> long\n\t"
3805             "MOV    $dst.hi, 0\n\t"
3806             "AND    $dst,$dst,$mask" %}
3807   ins_encode %{
3808     __ ldrh($dst$$Register, $mem$$Address);
3809     __ mov($dst$$Register->successor(), 0);
3810     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
3811   %}
3812   ins_pipe(iload_mem);
3813 %}
3814 
3815 // Load Integer
3816 
3817 
3818 instruct loadI(iRegI dst, memoryI mem) %{
3819   match(Set dst (LoadI mem));
3820   ins_cost(MEMORY_REF_COST);
3821 
3822   size(4);
3823   format %{ "ldr_s32 $dst,$mem\t! int" %}
3824   ins_encode %{
3825     __ ldr_s32($dst$$Register, $mem$$Address);
3826   %}
3827   ins_pipe(iload_mem);
3828 %}
3829 
3830 // Load Integer to Byte (8 bit signed)
3831 instruct loadI2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
3832   match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
3833   ins_cost(MEMORY_REF_COST);
3834 
3835   size(4);
3836 
3837   format %{ "LDRSB   $dst,$mem\t! int -> byte" %}
3838   ins_encode %{
3839     __ ldrsb($dst$$Register, $mem$$Address);
3840   %}
3841   ins_pipe(iload_mask_mem);
3842 %}
3843 
3844 // Load Integer to Unsigned Byte (8 bit UNsigned)
3845 instruct loadI2UB(iRegI dst, memoryB mem, immI_255 mask) %{
3846   match(Set dst (AndI (LoadI mem) mask));
3847   ins_cost(MEMORY_REF_COST);
3848 
3849   size(4);
3850 
3851   format %{ "LDRB   $dst,$mem\t! int -> ubyte" %}
3852   ins_encode %{
3853     __ ldrb($dst$$Register, $mem$$Address);
3854   %}
3855   ins_pipe(iload_mask_mem);
3856 %}
3857 
3858 // Load Integer to Short (16 bit signed)
3859 instruct loadI2S(iRegI dst, memoryS mem, immI_16 sixteen) %{
3860   match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
3861   ins_cost(MEMORY_REF_COST);
3862 
3863   size(4);
3864   format %{ "LDRSH   $dst,$mem\t! int -> short" %}
3865   ins_encode %{
3866     __ ldrsh($dst$$Register, $mem$$Address);
3867   %}
3868   ins_pipe(iload_mask_mem);
3869 %}
3870 
3871 // Load Integer to Unsigned Short (16 bit UNsigned)
3872 instruct loadI2US(iRegI dst, memoryS mem, immI_65535 mask) %{
3873   match(Set dst (AndI (LoadI mem) mask));
3874   ins_cost(MEMORY_REF_COST);
3875 
3876   size(4);
3877   format %{ "LDRH   $dst,$mem\t! int -> ushort/char" %}
3878   ins_encode %{
3879     __ ldrh($dst$$Register, $mem$$Address);
3880   %}
3881   ins_pipe(iload_mask_mem);
3882 %}
3883 
3884 // Load Integer into a Long Register
3885 instruct loadI2L(iRegL dst, memoryI mem) %{
3886   match(Set dst (ConvI2L (LoadI mem)));
3887   ins_cost(MEMORY_REF_COST);
3888 
3889   size(8);
3890   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
3891             "ASR   $dst.hi,$dst.lo,31\t! int->long" %}
3892   ins_encode %{
3893     __ ldr($dst$$Register, $mem$$Address);
3894     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
3895   %}
3896   ins_pipe(iload_mask_mem);
3897 %}
3898 
3899 // Load Integer with mask 0xFF into a Long Register
3900 instruct loadI2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
3901   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
3902   ins_cost(MEMORY_REF_COST);
3903 
3904   size(8);
3905   format %{ "LDRB   $dst.lo,$mem\t! int & 0xFF -> long\n\t"
3906             "MOV    $dst.hi, 0" %}
3907   ins_encode %{
3908     __ ldrb($dst$$Register, $mem$$Address);
3909     __ mov($dst$$Register->successor(), 0);
3910   %}
3911   ins_pipe(iload_mem);
3912 %}
3913 
3914 // Load Integer with mask 0xFFFF into a Long Register
3915 instruct loadI2L_immI_65535(iRegL dst, memoryS mem, immI_65535 mask) %{
3916   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
3917   ins_cost(MEMORY_REF_COST);
3918 
3919   size(8);
3920   format %{ "LDRH   $dst,$mem\t! int & 0xFFFF -> long\n\t"
3921             "MOV    $dst.hi, 0" %}
3922   ins_encode %{
3923     __ ldrh($dst$$Register, $mem$$Address);
3924     __ mov($dst$$Register->successor(), 0);
3925   %}
3926   ins_pipe(iload_mask_mem);
3927 %}
3928 
3929 // Load Integer with a 31-bit immediate mask into a Long Register
3930 instruct loadI2L_limmU31(iRegL dst, memoryI mem, limmU31 mask) %{
3931   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
3932   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
3933 
3934   size(12);
3935   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
3936             "MOV    $dst.hi, 0\n\t"
3937             "AND   $dst,$dst,$mask" %}
3938 
3939   ins_encode %{
3940     __ ldr($dst$$Register, $mem$$Address);
3941     __ mov($dst$$Register->successor(), 0);
3942     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
3943   %}
3944   ins_pipe(iload_mem);
3945 %}
3946 
3947 // Load Integer with a 31-bit mask into a Long Register
3948 // FIXME: use iRegI mask, remove tmp?
3949 instruct loadI2L_immU31(iRegL dst, memoryI mem, immU31 mask, iRegI tmp) %{
3950   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
3951   effect(TEMP dst, TEMP tmp);
3952 
3953   ins_cost(MEMORY_REF_COST + 4*DEFAULT_COST);
3954   size(20);
3955   format %{ "LDR      $mem,$dst\t! int & 31-bit mask -> long\n\t"
3956             "MOV      $dst.hi, 0\n\t"
3957             "MOV_SLOW $tmp,$mask\n\t"
3958             "AND      $dst,$tmp,$dst" %}
3959   ins_encode %{
3960     __ ldr($dst$$Register, $mem$$Address);
3961     __ mov($dst$$Register->successor(), 0);
3962     __ mov_slow($tmp$$Register, $mask$$constant);
3963     __ andr($dst$$Register, $dst$$Register, $tmp$$Register);
3964   %}
3965   ins_pipe(iload_mem);
3966 %}
3967 
3968 // Load Unsigned Integer into a Long Register
3969 instruct loadUI2L(iRegL dst, memoryI mem, immL_32bits mask) %{
3970   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
3971   ins_cost(MEMORY_REF_COST);
3972 
3973   size(8);
3974   format %{ "LDR   $dst.lo,$mem\t! uint -> long\n\t"
3975             "MOV   $dst.hi,0" %}
3976   ins_encode %{
3977     __ ldr($dst$$Register, $mem$$Address);
3978     __ mov($dst$$Register->successor(), 0);
3979   %}
3980   ins_pipe(iload_mem);
3981 %}
3982 
3983 // Load Long
3984 
3985 
3986 instruct loadL(iRegLd dst, memoryL mem ) %{
3987   predicate(!((LoadLNode*)n)->require_atomic_access());
3988   match(Set dst (LoadL mem));
3989   effect(TEMP dst);
3990   ins_cost(MEMORY_REF_COST);
3991 
3992   size(4);
3993   format %{ "ldr_64  $dst,$mem\t! long" %}
3994   ins_encode %{
3995     __ ldr_64($dst$$Register, $mem$$Address);
3996   %}
3997   ins_pipe(iload_mem);
3998 %}
3999 
4000 instruct loadL_2instr(iRegL dst, memorylong mem ) %{
4001   predicate(!((LoadLNode*)n)->require_atomic_access());
4002   match(Set dst (LoadL mem));
4003   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
4004 
4005   size(8);
4006   format %{ "LDR    $dst.lo,$mem \t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
4007             "LDR    $dst.hi,$mem+4 or $mem" %}
4008   ins_encode %{
4009     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4010     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
4011 
4012     if ($dst$$Register == reg_to_register_object($mem$$base)) {
4013       __ ldr($dst$$Register->successor(), Amemhi);
4014       __ ldr($dst$$Register, Amemlo);
4015     } else {
4016       __ ldr($dst$$Register, Amemlo);
4017       __ ldr($dst$$Register->successor(), Amemhi);
4018     }
4019   %}
4020   ins_pipe(iload_mem);
4021 %}
4022 
4023 instruct loadL_volatile(iRegL dst, indirect mem ) %{
4024   predicate(((LoadLNode*)n)->require_atomic_access());
4025   match(Set dst (LoadL mem));
4026   ins_cost(MEMORY_REF_COST);
4027 
4028   size(4);
4029   format %{ "LDMIA    $dst,$mem\t! long" %}
4030   ins_encode %{
4031     // FIXME: why is ldmia considered atomic?  Should be ldrexd
4032     RegisterSet set($dst$$Register);
4033     set = set | reg_to_register_object($dst$$reg + 1);
4034     __ ldmia(reg_to_register_object($mem$$base), set);
4035   %}
4036   ins_pipe(iload_mem);
4037 %}
4038 
4039 instruct loadL_volatile_fp(iRegL dst, memoryD mem ) %{
4040   predicate(((LoadLNode*)n)->require_atomic_access());
4041   match(Set dst (LoadL mem));
4042   ins_cost(MEMORY_REF_COST);
4043 
4044   size(8);
4045   format %{ "FLDD      S14, $mem"
4046             "FMRRD    $dst, S14\t! long \n't" %}
4047   ins_encode %{
4048     __ fldd(S14, $mem$$Address);
4049     __ fmrrd($dst$$Register, $dst$$Register->successor(), S14);
4050   %}
4051   ins_pipe(iload_mem);
4052 %}
4053 
4054 instruct loadL_unaligned(iRegL dst, memorylong mem ) %{
4055   match(Set dst (LoadL_unaligned mem));
4056   ins_cost(MEMORY_REF_COST);
4057 
4058   size(8);
4059   format %{ "LDR    $dst.lo,$mem\t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
4060             "LDR    $dst.hi,$mem+4" %}
4061   ins_encode %{
4062     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4063     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
4064 
4065     if ($dst$$Register == reg_to_register_object($mem$$base)) {
4066       __ ldr($dst$$Register->successor(), Amemhi);
4067       __ ldr($dst$$Register, Amemlo);
4068     } else {
4069       __ ldr($dst$$Register, Amemlo);
4070       __ ldr($dst$$Register->successor(), Amemhi);
4071     }
4072   %}
4073   ins_pipe(iload_mem);
4074 %}
4075 
4076 // Load Range
4077 instruct loadRange(iRegI dst, memoryI mem) %{
4078   match(Set dst (LoadRange mem));
4079   ins_cost(MEMORY_REF_COST);
4080 
4081   size(4);
4082   format %{ "LDR_u32 $dst,$mem\t! range" %}
4083   ins_encode %{
4084     __ ldr_u32($dst$$Register, $mem$$Address);
4085   %}
4086   ins_pipe(iload_mem);
4087 %}
4088 
4089 // Load Pointer
4090 
4091 
4092 instruct loadP(iRegP dst, memoryP mem) %{
4093   match(Set dst (LoadP mem));
4094   ins_cost(MEMORY_REF_COST);
4095   size(4);
4096 
4097   format %{ "LDR   $dst,$mem\t! ptr" %}
4098   ins_encode %{
4099     __ ldr($dst$$Register, $mem$$Address);
4100   %}
4101   ins_pipe(iload_mem);
4102 %}
4103 
4104 #ifdef XXX
4105 // FIXME XXXX
4106 //instruct loadSP(iRegP dst, memoryP mem) %{
4107 instruct loadSP(SPRegP dst, memoryP mem, iRegP tmp) %{
4108   match(Set dst (LoadP mem));
4109   effect(TEMP tmp);
4110   ins_cost(MEMORY_REF_COST+1);
4111   size(8);
4112 
4113   format %{ "LDR   $tmp,$mem\t! ptr\n\t"
4114             "MOV   $dst,$tmp\t! ptr" %}
4115   ins_encode %{
4116     __ ldr($tmp$$Register, $mem$$Address);
4117     __ mov($dst$$Register, $tmp$$Register);
4118   %}
4119   ins_pipe(iload_mem);
4120 %}
4121 #endif
4122 
4123 #ifdef _LP64
4124 // Load Compressed Pointer
4125 
4126 // XXX This variant shouldn't be necessary if 6217251 is implemented
4127 instruct loadNoff(iRegN dst, memoryScaledI mem, aimmX off, iRegP tmp) %{
4128   match(Set dst (LoadN (AddP mem off)));
4129   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
4130   effect(TEMP tmp);
4131   size(4 * 2);
4132 
4133   format %{ "ldr_u32 $dst,$mem+$off\t! compressed ptr temp=$tmp" %}
4134   ins_encode %{
4135     Register base = reg_to_register_object($mem$$base);
4136     __ add($tmp$$Register, base, $off$$constant);
4137     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4138     __ ldr_u32($dst$$Register, nmem);
4139   %}
4140   ins_pipe(iload_mem);
4141 %}
4142 
4143 instruct loadN(iRegN dst, memoryI mem) %{
4144   match(Set dst (LoadN mem));
4145   ins_cost(MEMORY_REF_COST);
4146   size(4);
4147 
4148   format %{ "ldr_u32 $dst,$mem\t! compressed ptr" %}
4149   ins_encode %{
4150     __ ldr_u32($dst$$Register, $mem$$Address);
4151   %}
4152   ins_pipe(iload_mem);
4153 %}
4154 #endif
4155 
4156 // Load Klass Pointer
4157 instruct loadKlass(iRegP dst, memoryI mem) %{
4158   match(Set dst (LoadKlass mem));
4159   ins_cost(MEMORY_REF_COST);
4160   size(4);
4161 
4162   format %{ "LDR   $dst,$mem\t! klass ptr" %}
4163   ins_encode %{
4164     __ ldr($dst$$Register, $mem$$Address);
4165   %}
4166   ins_pipe(iload_mem);
4167 %}
4168 
4169 #ifdef _LP64
4170 // Load narrow Klass Pointer
4171 instruct loadNKlass(iRegN dst, memoryI mem) %{
4172   match(Set dst (LoadNKlass mem));
4173   ins_cost(MEMORY_REF_COST);
4174   size(4);
4175 
4176   format %{ "ldr_u32 $dst,$mem\t! compressed klass ptr" %}
4177   ins_encode %{
4178     __ ldr_u32($dst$$Register, $mem$$Address);
4179   %}
4180   ins_pipe(iload_mem);
4181 %}
4182 #endif
4183 
4184 
4185 instruct loadD(regD dst, memoryD mem) %{
4186   match(Set dst (LoadD mem));
4187   ins_cost(MEMORY_REF_COST);
4188 
4189   size(4);
4190   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
4191   // only LDREXD and STREXD are 64-bit single-copy atomic
4192   format %{ "FLDD   $dst,$mem" %}
4193   ins_encode %{
4194     __ ldr_double($dst$$FloatRegister, $mem$$Address);
4195   %}
4196   ins_pipe(floadD_mem);
4197 %}
4198 
4199 // Load Double - UNaligned
4200 instruct loadD_unaligned(regD_low dst, memoryF2 mem ) %{
4201   match(Set dst (LoadD_unaligned mem));
4202   ins_cost(MEMORY_REF_COST*2+DEFAULT_COST);
4203   size(8);
4204   format %{ "FLDS    $dst.lo,$mem\t! misaligned double\n"
4205           "\tFLDS    $dst.hi,$mem+4\t!" %}
4206   ins_encode %{
4207     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4208     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
4209       __ flds($dst$$FloatRegister, Amemlo);
4210       __ flds($dst$$FloatRegister->successor(), Amemhi);
4211   %}
4212   ins_pipe(iload_mem);
4213 %}
4214 
4215 
4216 instruct loadF(regF dst, memoryF mem) %{
4217   match(Set dst (LoadF mem));
4218 
4219   ins_cost(MEMORY_REF_COST);
4220   size(4);
4221   format %{ "FLDS    $dst,$mem" %}
4222   ins_encode %{
4223     __ ldr_float($dst$$FloatRegister, $mem$$Address);
4224   %}
4225   ins_pipe(floadF_mem);
4226 %}
4227 
4228 
4229 // // Load Constant
4230 instruct loadConI( iRegI dst, immI src ) %{
4231   match(Set dst src);
4232   ins_cost(DEFAULT_COST * 3/2);
4233   format %{ "MOV_SLOW    $dst, $src" %}
4234   ins_encode %{
4235     __ mov_slow($dst$$Register, $src$$constant);
4236   %}
4237   ins_pipe(ialu_hi_lo_reg);
4238 %}
4239 
4240 instruct loadConIMov( iRegI dst, immIMov src ) %{
4241   match(Set dst src);
4242   size(4);
4243   format %{ "MOV    $dst, $src" %}
4244   ins_encode %{
4245     __ mov($dst$$Register, $src$$constant);
4246   %}
4247   ins_pipe(ialu_imm);
4248 %}
4249 
4250 instruct loadConIMovn( iRegI dst, immIRotn src ) %{
4251   match(Set dst src);
4252   size(4);
4253   format %{ "MVN    $dst, ~$src" %}
4254   ins_encode %{
4255     __ mvn($dst$$Register, ~$src$$constant);
4256   %}
4257   ins_pipe(ialu_imm_n);
4258 %}
4259 
4260 instruct loadConI16( iRegI dst, immI16 src ) %{
4261   match(Set dst src);
4262   size(4);
4263   format %{ "MOVW    $dst, $src" %}
4264   ins_encode %{
4265     __ movw($dst$$Register, $src$$constant);
4266   %}
4267   ins_pipe(ialu_imm_n);
4268 %}
4269 
4270 instruct loadConP(iRegP dst, immP src) %{
4271   match(Set dst src);
4272   ins_cost(DEFAULT_COST * 3/2);
4273   format %{ "MOV_SLOW    $dst,$src\t!ptr" %}
4274   ins_encode %{
4275     relocInfo::relocType constant_reloc = _opnds[1]->constant_reloc();
4276     intptr_t val = $src$$constant;
4277     if (constant_reloc == relocInfo::oop_type) {
4278       __ mov_oop($dst$$Register, (jobject)val);
4279     } else if (constant_reloc == relocInfo::metadata_type) {
4280       __ mov_metadata($dst$$Register, (Metadata*)val);
4281     } else {
4282       __ mov_slow($dst$$Register, val);
4283     }
4284   %}
4285   ins_pipe(loadConP);
4286 %}
4287 
4288 
4289 instruct loadConL(iRegL dst, immL src) %{
4290   match(Set dst src);
4291   ins_cost(DEFAULT_COST * 4);
4292   format %{ "MOV_SLOW   $dst.lo, $src & 0x0FFFFFFFFL \t! long\n\t"
4293             "MOV_SLOW   $dst.hi, $src >> 32" %}
4294   ins_encode %{
4295     __ mov_slow(reg_to_register_object($dst$$reg), $src$$constant & 0x0FFFFFFFFL);
4296     __ mov_slow(reg_to_register_object($dst$$reg + 1), ((julong)($src$$constant)) >> 32);
4297   %}
4298   ins_pipe(loadConL);
4299 %}
4300 
4301 instruct loadConL16( iRegL dst, immL16 src ) %{
4302   match(Set dst src);
4303   ins_cost(DEFAULT_COST * 2);
4304 
4305   size(8);
4306   format %{ "MOVW    $dst.lo, $src \n\t"
4307             "MOVW    $dst.hi, 0 \n\t" %}
4308   ins_encode %{
4309     __ movw($dst$$Register, $src$$constant);
4310     __ movw($dst$$Register->successor(), 0);
4311   %}
4312   ins_pipe(ialu_imm);
4313 %}
4314 
4315 instruct loadConF_imm8(regF dst, imm8F src) %{
4316   match(Set dst src);
4317   ins_cost(DEFAULT_COST);
4318   size(4);
4319 
4320   format %{ "FCONSTS      $dst, $src"%}
4321 
4322   ins_encode %{
4323     __ fconsts($dst$$FloatRegister, Assembler::float_num($src$$constant).imm8());
4324   %}
4325   ins_pipe(loadConFD); // FIXME
4326 %}
4327 
4328 
4329 instruct loadConF(regF dst, immF src, iRegI tmp) %{
4330   match(Set dst src);
4331   ins_cost(DEFAULT_COST * 2);
4332   effect(TEMP tmp);
4333   size(3*4);
4334 
4335   format %{ "MOV_SLOW  $tmp, $src\n\t"
4336             "FMSR      $dst, $tmp"%}
4337 
4338   ins_encode %{
4339     // FIXME revisit once 6961697 is in
4340     union {
4341       jfloat f;
4342       int i;
4343     } v;
4344     v.f = $src$$constant;
4345     __ mov_slow($tmp$$Register, v.i);
4346     __ fmsr($dst$$FloatRegister, $tmp$$Register);
4347   %}
4348   ins_pipe(loadConFD); // FIXME
4349 %}
4350 
4351 instruct loadConD_imm8(regD dst, imm8D src) %{
4352   match(Set dst src);
4353   ins_cost(DEFAULT_COST);
4354   size(4);
4355 
4356   format %{ "FCONSTD      $dst, $src"%}
4357 
4358   ins_encode %{
4359     __ fconstd($dst$$FloatRegister, Assembler::double_num($src$$constant).imm8());
4360   %}
4361   ins_pipe(loadConFD); // FIXME
4362 %}
4363 
4364 instruct loadConD(regD dst, immD src, iRegP tmp) %{
4365   match(Set dst src);
4366   effect(TEMP tmp);
4367   ins_cost(MEMORY_REF_COST);
4368   format %{ "FLDD  $dst, [$constanttablebase + $constantoffset]\t! load from constant table: double=$src" %}
4369 
4370   ins_encode %{
4371     Register r = $constanttablebase;
4372     int offset  = $constantoffset($src);
4373     if (!is_memoryD(offset)) {                // can't use a predicate
4374                                               // in load constant instructs
4375       __ add_slow($tmp$$Register, r, offset);
4376       r = $tmp$$Register;
4377       offset = 0;
4378     }
4379     __ ldr_double($dst$$FloatRegister, Address(r, offset));
4380   %}
4381   ins_pipe(loadConFD);
4382 %}
4383 
4384 // Prefetch instructions.
4385 // Must be safe to execute with invalid address (cannot fault).
4386 
4387 instruct prefetchAlloc_mp( memoryP mem ) %{
4388   predicate(VM_Version::has_multiprocessing_extensions());
4389   match( PrefetchAllocation mem );
4390   ins_cost(MEMORY_REF_COST);
4391   size(4);
4392 
4393   format %{ "PLDW $mem\t! Prefetch allocation" %}
4394   ins_encode %{
4395     __ pldw($mem$$Address);
4396   %}
4397   ins_pipe(iload_mem);
4398 %}
4399 
4400 instruct prefetchAlloc_sp( memoryP mem ) %{
4401   predicate(!VM_Version::has_multiprocessing_extensions());
4402   match( PrefetchAllocation mem );
4403   ins_cost(MEMORY_REF_COST);
4404   size(4);
4405 
4406   format %{ "PLD $mem\t! Prefetch allocation" %}
4407   ins_encode %{
4408     __ pld($mem$$Address);
4409   %}
4410   ins_pipe(iload_mem);
4411 %}
4412 
4413 
4414 //----------Store Instructions-------------------------------------------------
4415 // Store Byte
4416 instruct storeB(memoryB mem, store_RegI src) %{
4417   match(Set mem (StoreB mem src));
4418   ins_cost(MEMORY_REF_COST);
4419 
4420   size(4);
4421   format %{ "STRB    $src,$mem\t! byte" %}
4422   ins_encode %{
4423     __ strb($src$$Register, $mem$$Address);
4424   %}
4425   ins_pipe(istore_mem_reg);
4426 %}
4427 
4428 instruct storeCM(memoryB mem, store_RegI src) %{
4429   match(Set mem (StoreCM mem src));
4430   ins_cost(MEMORY_REF_COST);
4431 
4432   size(4);
4433   format %{ "STRB    $src,$mem\t! CMS card-mark byte" %}
4434   ins_encode %{
4435     __ strb($src$$Register, $mem$$Address);
4436   %}
4437   ins_pipe(istore_mem_reg);
4438 %}
4439 
4440 // Store Char/Short
4441 
4442 
4443 instruct storeC(memoryS mem, store_RegI src) %{
4444   match(Set mem (StoreC mem src));
4445   ins_cost(MEMORY_REF_COST);
4446 
4447   size(4);
4448   format %{ "STRH    $src,$mem\t! short" %}
4449   ins_encode %{
4450     __ strh($src$$Register, $mem$$Address);
4451   %}
4452   ins_pipe(istore_mem_reg);
4453 %}
4454 
4455 // Store Integer
4456 
4457 
4458 instruct storeI(memoryI mem, store_RegI src) %{
4459   match(Set mem (StoreI mem src));
4460   ins_cost(MEMORY_REF_COST);
4461 
4462   size(4);
4463   format %{ "str_32 $src,$mem" %}
4464   ins_encode %{
4465     __ str_32($src$$Register, $mem$$Address);
4466   %}
4467   ins_pipe(istore_mem_reg);
4468 %}
4469 
4470 // Store Long
4471 
4472 
4473 instruct storeL(memoryL mem, store_RegLd src) %{
4474   predicate(!((StoreLNode*)n)->require_atomic_access());
4475   match(Set mem (StoreL mem src));
4476   ins_cost(MEMORY_REF_COST);
4477 
4478   size(4);
4479   format %{ "str_64  $src,$mem\t! long\n\t" %}
4480 
4481   ins_encode %{
4482     __ str_64($src$$Register, $mem$$Address);
4483   %}
4484   ins_pipe(istore_mem_reg);
4485 %}
4486 
4487 instruct storeL_2instr(memorylong mem, iRegL src) %{
4488   predicate(!((StoreLNode*)n)->require_atomic_access());
4489   match(Set mem (StoreL mem src));
4490   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
4491 
4492   size(8);
4493   format %{ "STR    $src.lo,$mem\t! long\n\t"
4494             "STR    $src.hi,$mem+4" %}
4495 
4496   ins_encode %{
4497     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4498     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
4499     __ str($src$$Register, Amemlo);
4500     __ str($src$$Register->successor(), Amemhi);
4501   %}
4502   ins_pipe(istore_mem_reg);
4503 %}
4504 
4505 instruct storeL_volatile(indirect mem, iRegL src) %{
4506   predicate(((StoreLNode*)n)->require_atomic_access());
4507   match(Set mem (StoreL mem src));
4508   ins_cost(MEMORY_REF_COST);
4509   size(4);
4510   format %{ "STMIA    $src,$mem\t! long" %}
4511   ins_encode %{
4512     // FIXME: why is stmia considered atomic?  Should be strexd
4513     RegisterSet set($src$$Register);
4514     set = set | reg_to_register_object($src$$reg + 1);
4515     __ stmia(reg_to_register_object($mem$$base), set);
4516   %}
4517   ins_pipe(istore_mem_reg);
4518 %}
4519 
4520 instruct storeL_volatile_fp(memoryD mem, iRegL src) %{
4521   predicate(((StoreLNode*)n)->require_atomic_access());
4522   match(Set mem (StoreL mem src));
4523   ins_cost(MEMORY_REF_COST);
4524   size(8);
4525   format %{ "FMDRR    S14, $src\t! long \n\t"
4526             "FSTD     S14, $mem" %}
4527   ins_encode %{
4528     __ fmdrr(S14, $src$$Register, $src$$Register->successor());
4529     __ fstd(S14, $mem$$Address);
4530   %}
4531   ins_pipe(istore_mem_reg);
4532 %}
4533 
4534 #ifdef XXX
4535 // Move SP Pointer
4536 //instruct movSP(sp_ptr_RegP dst, SPRegP src) %{
4537 //instruct movSP(iRegP dst, SPRegP src) %{
4538 instruct movSP(store_ptr_RegP dst, SPRegP src) %{
4539   match(Set dst src);
4540 //predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con == TypeFunc::FramePtr);
4541   ins_cost(MEMORY_REF_COST);
4542   size(4);
4543 
4544   format %{ "MOV    $dst,$src\t! SP ptr\n\t" %}
4545   ins_encode %{
4546     assert(false, "XXX1 got here");
4547     __ mov($dst$$Register, SP);
4548     __ mov($dst$$Register, $src$$Register);
4549   %}
4550   ins_pipe(ialu_reg);
4551 %}
4552 #endif
4553 
4554 
4555 // Store Pointer
4556 
4557 
4558 instruct storeP(memoryP mem, store_ptr_RegP src) %{
4559   match(Set mem (StoreP mem src));
4560   ins_cost(MEMORY_REF_COST);
4561   size(4);
4562 
4563   format %{ "STR    $src,$mem\t! ptr" %}
4564   ins_encode %{
4565     __ str($src$$Register, $mem$$Address);
4566   %}
4567   ins_pipe(istore_mem_spORreg);
4568 %}
4569 
4570 
4571 #ifdef _LP64
4572 // Store Compressed Pointer
4573 
4574 
4575 instruct storeN(memoryI mem, store_RegN src) %{
4576   match(Set mem (StoreN mem src));
4577   ins_cost(MEMORY_REF_COST);
4578   size(4);
4579 
4580   format %{ "str_32 $src,$mem\t! compressed ptr" %}
4581   ins_encode %{
4582     __ str_32($src$$Register, $mem$$Address);
4583   %}
4584   ins_pipe(istore_mem_reg);
4585 %}
4586 
4587 
4588 // Store Compressed Klass Pointer
4589 instruct storeNKlass(memoryI mem, store_RegN src) %{
4590   match(Set mem (StoreNKlass mem src));
4591   ins_cost(MEMORY_REF_COST);
4592   size(4);
4593 
4594   format %{ "str_32 $src,$mem\t! compressed klass ptr" %}
4595   ins_encode %{
4596     __ str_32($src$$Register, $mem$$Address);
4597   %}
4598   ins_pipe(istore_mem_reg);
4599 %}
4600 #endif
4601 
4602 // Store Double
4603 
4604 
4605 instruct storeD(memoryD mem, regD src) %{
4606   match(Set mem (StoreD mem src));
4607   ins_cost(MEMORY_REF_COST);
4608 
4609   size(4);
4610   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
4611   // only LDREXD and STREXD are 64-bit single-copy atomic
4612   format %{ "FSTD   $src,$mem" %}
4613   ins_encode %{
4614     __ str_double($src$$FloatRegister, $mem$$Address);
4615   %}
4616   ins_pipe(fstoreD_mem_reg);
4617 %}
4618 
4619 
4620 // Store Float
4621 
4622 
4623 instruct storeF( memoryF mem, regF src) %{
4624   match(Set mem (StoreF mem src));
4625   ins_cost(MEMORY_REF_COST);
4626 
4627   size(4);
4628   format %{ "FSTS    $src,$mem" %}
4629   ins_encode %{
4630     __ str_float($src$$FloatRegister, $mem$$Address);
4631   %}
4632   ins_pipe(fstoreF_mem_reg);
4633 %}
4634 
4635 
4636 //----------MemBar Instructions-----------------------------------------------
4637 // Memory barrier flavors
4638 
4639 // pattern-match out unnecessary membars
4640 instruct membar_storestore() %{
4641   match(MemBarStoreStore);
4642   ins_cost(4*MEMORY_REF_COST);
4643 
4644   size(4);
4645   format %{ "MEMBAR-storestore" %}
4646   ins_encode %{
4647     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore), noreg);
4648   %}
4649   ins_pipe(long_memory_op);
4650 %}
4651 
4652 instruct membar_acquire() %{
4653   match(MemBarAcquire);
4654   match(LoadFence);
4655   ins_cost(4*MEMORY_REF_COST);
4656 
4657   size(4);
4658   format %{ "MEMBAR-acquire" %}
4659   ins_encode %{
4660     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), noreg);
4661   %}
4662   ins_pipe(long_memory_op);
4663 %}
4664 
4665 instruct membar_acquire_lock() %{
4666   match(MemBarAcquireLock);
4667   ins_cost(0);
4668 
4669   size(0);
4670   format %{ "!MEMBAR-acquire (CAS in prior FastLock so empty encoding)" %}
4671   ins_encode( );
4672   ins_pipe(empty);
4673 %}
4674 
4675 instruct membar_release() %{
4676   match(MemBarRelease);
4677   match(StoreFence);
4678   ins_cost(4*MEMORY_REF_COST);
4679 
4680   size(4);
4681   format %{ "MEMBAR-release" %}
4682   ins_encode %{
4683     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), noreg);
4684   %}
4685   ins_pipe(long_memory_op);
4686 %}
4687 
4688 instruct membar_release_lock() %{
4689   match(MemBarReleaseLock);
4690   ins_cost(0);
4691 
4692   size(0);
4693   format %{ "!MEMBAR-release (CAS in succeeding FastUnlock so empty encoding)" %}
4694   ins_encode( );
4695   ins_pipe(empty);
4696 %}
4697 
4698 instruct membar_volatile() %{
4699   match(MemBarVolatile);
4700   ins_cost(4*MEMORY_REF_COST);
4701 
4702   size(4);
4703   format %{ "MEMBAR-volatile" %}
4704   ins_encode %{
4705     __ membar(MacroAssembler::StoreLoad, noreg);
4706   %}
4707   ins_pipe(long_memory_op);
4708 %}
4709 
4710 instruct unnecessary_membar_volatile() %{
4711   match(MemBarVolatile);
4712   predicate(Matcher::post_store_load_barrier(n));
4713   ins_cost(0);
4714 
4715   size(0);
4716   format %{ "!MEMBAR-volatile (unnecessary so empty encoding)" %}
4717   ins_encode( );
4718   ins_pipe(empty);
4719 %}
4720 
4721 //----------Register Move Instructions-----------------------------------------
4722 // instruct roundDouble_nop(regD dst) %{
4723 //   match(Set dst (RoundDouble dst));
4724 //   ins_pipe(empty);
4725 // %}
4726 
4727 
4728 // instruct roundFloat_nop(regF dst) %{
4729 //   match(Set dst (RoundFloat dst));
4730 //   ins_pipe(empty);
4731 // %}
4732 
4733 
4734 
4735 // Cast Index to Pointer for unsafe natives
4736 instruct castX2P(iRegX src, iRegP dst) %{
4737   match(Set dst (CastX2P src));
4738 
4739   format %{ "MOV    $dst,$src\t! IntX->Ptr if $dst != $src" %}
4740   ins_encode %{
4741     if ($dst$$Register !=  $src$$Register) {
4742       __ mov($dst$$Register, $src$$Register);
4743     }
4744   %}
4745   ins_pipe(ialu_reg);
4746 %}
4747 
4748 // Cast Pointer to Index for unsafe natives
4749 instruct castP2X(iRegP src, iRegX dst) %{
4750   match(Set dst (CastP2X src));
4751 
4752   format %{ "MOV    $dst,$src\t! Ptr->IntX if $dst != $src" %}
4753   ins_encode %{
4754     if ($dst$$Register !=  $src$$Register) {
4755       __ mov($dst$$Register, $src$$Register);
4756     }
4757   %}
4758   ins_pipe(ialu_reg);
4759 %}
4760 
4761 //----------Conditional Move---------------------------------------------------
4762 // Conditional move
4763 instruct cmovIP_reg(cmpOpP cmp, flagsRegP pcc, iRegI dst, iRegI src) %{
4764   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
4765   ins_cost(150);
4766   size(4);
4767   format %{ "MOV$cmp  $dst,$src\t! int" %}
4768   ins_encode %{
4769     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
4770   %}
4771   ins_pipe(ialu_reg);
4772 %}
4773 
4774 
4775 instruct cmovIP_immMov(cmpOpP cmp, flagsRegP pcc, iRegI dst, immIMov src) %{
4776   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
4777   ins_cost(140);
4778   size(4);
4779   format %{ "MOV$cmp  $dst,$src" %}
4780   ins_encode %{
4781     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4782   %}
4783   ins_pipe(ialu_imm);
4784 %}
4785 
4786 instruct cmovIP_imm16(cmpOpP cmp, flagsRegP pcc, iRegI dst, immI16 src) %{
4787   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
4788   ins_cost(140);
4789   size(4);
4790   format %{ "MOVw$cmp  $dst,$src" %}
4791   ins_encode %{
4792     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4793   %}
4794   ins_pipe(ialu_imm);
4795 %}
4796 
4797 instruct cmovI_reg(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src) %{
4798   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
4799   ins_cost(150);
4800   size(4);
4801   format %{ "MOV$cmp  $dst,$src" %}
4802   ins_encode %{
4803     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
4804   %}
4805   ins_pipe(ialu_reg);
4806 %}
4807 
4808 
4809 instruct cmovI_immMov(cmpOp cmp, flagsReg icc, iRegI dst, immIMov src) %{
4810   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
4811   ins_cost(140);
4812   size(4);
4813   format %{ "MOV$cmp  $dst,$src" %}
4814   ins_encode %{
4815     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4816   %}
4817   ins_pipe(ialu_imm);
4818 %}
4819 
4820 instruct cmovII_imm16(cmpOp cmp, flagsReg icc, iRegI dst, immI16 src) %{
4821   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
4822   ins_cost(140);
4823   size(4);
4824   format %{ "MOVw$cmp  $dst,$src" %}
4825   ins_encode %{
4826     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4827   %}
4828   ins_pipe(ialu_imm);
4829 %}
4830 
4831 instruct cmovII_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, iRegI src) %{
4832   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
4833   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
4834             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
4835             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
4836             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
4837   ins_cost(150);
4838   size(4);
4839   format %{ "MOV$cmp  $dst,$src" %}
4840   ins_encode %{
4841     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
4842   %}
4843   ins_pipe(ialu_reg);
4844 %}
4845 
4846 instruct cmovII_immMov_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immIMov src) %{
4847   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
4848   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
4849             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
4850             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
4851             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
4852   ins_cost(140);
4853   size(4);
4854   format %{ "MOV$cmp  $dst,$src" %}
4855   ins_encode %{
4856     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4857   %}
4858   ins_pipe(ialu_imm);
4859 %}
4860 
4861 instruct cmovII_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immI16 src) %{
4862   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
4863   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
4864             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
4865             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
4866             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
4867   ins_cost(140);
4868   size(4);
4869   format %{ "MOVW$cmp  $dst,$src" %}
4870   ins_encode %{
4871     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4872   %}
4873   ins_pipe(ialu_imm);
4874 %}
4875 
4876 instruct cmovIIu_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
4877   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
4878   ins_cost(150);
4879   size(4);
4880   format %{ "MOV$cmp  $dst,$src" %}
4881   ins_encode %{
4882     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
4883   %}
4884   ins_pipe(ialu_reg);
4885 %}
4886 
4887 instruct cmovIIu_immMov(cmpOpU cmp, flagsRegU icc, iRegI dst, immIMov src) %{
4888   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
4889   ins_cost(140);
4890   size(4);
4891   format %{ "MOV$cmp  $dst,$src" %}
4892   ins_encode %{
4893     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4894   %}
4895   ins_pipe(ialu_imm);
4896 %}
4897 
4898 instruct cmovIIu_imm16(cmpOpU cmp, flagsRegU icc, iRegI dst, immI16 src) %{
4899   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
4900   ins_cost(140);
4901   size(4);
4902   format %{ "MOVW$cmp  $dst,$src" %}
4903   ins_encode %{
4904     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4905   %}
4906   ins_pipe(ialu_imm);
4907 %}
4908 
4909 // Conditional move
4910 instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{
4911   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
4912   ins_cost(150);
4913   size(4);
4914   format %{ "MOV$cmp  $dst,$src" %}
4915   ins_encode %{
4916     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
4917   %}
4918   ins_pipe(ialu_reg);
4919 %}
4920 
4921 instruct cmovPP_imm(cmpOpP cmp, flagsRegP pcc, iRegP dst, immP0 src) %{
4922   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
4923   ins_cost(140);
4924   size(4);
4925   format %{ "MOV$cmp  $dst,$src" %}
4926   ins_encode %{
4927     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4928   %}
4929   ins_pipe(ialu_imm);
4930 %}
4931 
4932 // This instruction also works with CmpN so we don't need cmovPN_reg.
4933 instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{
4934   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
4935   ins_cost(150);
4936 
4937   size(4);
4938   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
4939   ins_encode %{
4940     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
4941   %}
4942   ins_pipe(ialu_reg);
4943 %}
4944 
4945 instruct cmovPI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, iRegP src) %{
4946   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
4947   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
4948             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
4949             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
4950             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
4951   ins_cost(150);
4952 
4953   size(4);
4954   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
4955   ins_encode %{
4956     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
4957   %}
4958   ins_pipe(ialu_reg);
4959 %}
4960 
4961 instruct cmovPIu_reg(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src) %{
4962   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
4963   ins_cost(150);
4964 
4965   size(4);
4966   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
4967   ins_encode %{
4968     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
4969   %}
4970   ins_pipe(ialu_reg);
4971 %}
4972 
4973 instruct cmovPI_imm(cmpOp cmp, flagsReg icc, iRegP dst, immP0 src) %{
4974   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
4975   ins_cost(140);
4976 
4977   size(4);
4978   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
4979   ins_encode %{
4980     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4981   %}
4982   ins_pipe(ialu_imm);
4983 %}
4984 
4985 instruct cmovPI_imm_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, immP0 src) %{
4986   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
4987   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
4988             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
4989             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
4990             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
4991   ins_cost(140);
4992 
4993   size(4);
4994   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
4995   ins_encode %{
4996     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4997   %}
4998   ins_pipe(ialu_imm);
4999 %}
5000 
5001 instruct cmovPIu_imm(cmpOpU cmp, flagsRegU icc, iRegP dst, immP0 src) %{
5002   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
5003   ins_cost(140);
5004 
5005   size(4);
5006   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
5007   ins_encode %{
5008     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
5009   %}
5010   ins_pipe(ialu_imm);
5011 %}
5012 
5013 
5014 // Conditional move
5015 instruct cmovFP_reg(cmpOpP cmp, flagsRegP pcc, regF dst, regF src) %{
5016   match(Set dst (CMoveF (Binary cmp pcc) (Binary dst src)));
5017   ins_cost(150);
5018   size(4);
5019   format %{ "FCPYS$cmp $dst,$src" %}
5020   ins_encode %{
5021     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
5022   %}
5023   ins_pipe(int_conditional_float_move);
5024 %}
5025 
5026 instruct cmovFI_reg(cmpOp cmp, flagsReg icc, regF dst, regF src) %{
5027   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
5028   ins_cost(150);
5029 
5030   size(4);
5031   format %{ "FCPYS$cmp $dst,$src" %}
5032   ins_encode %{
5033     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
5034   %}
5035   ins_pipe(int_conditional_float_move);
5036 %}
5037 
5038 instruct cmovFI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regF dst, regF src) %{
5039   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
5040   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
5041             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
5042             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
5043             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
5044   ins_cost(150);
5045 
5046   size(4);
5047   format %{ "FCPYS$cmp $dst,$src" %}
5048   ins_encode %{
5049     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
5050   %}
5051   ins_pipe(int_conditional_float_move);
5052 %}
5053 
5054 instruct cmovFIu_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src) %{
5055   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
5056   ins_cost(150);
5057 
5058   size(4);
5059   format %{ "FCPYS$cmp $dst,$src" %}
5060   ins_encode %{
5061     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
5062   %}
5063   ins_pipe(int_conditional_float_move);
5064 %}
5065 
5066 // Conditional move
5067 instruct cmovDP_reg(cmpOpP cmp, flagsRegP pcc, regD dst, regD src) %{
5068   match(Set dst (CMoveD (Binary cmp pcc) (Binary dst src)));
5069   ins_cost(150);
5070   size(4);
5071   format %{ "FCPYD$cmp $dst,$src" %}
5072   ins_encode %{
5073     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
5074   %}
5075   ins_pipe(int_conditional_double_move);
5076 %}
5077 
5078 instruct cmovDI_reg(cmpOp cmp, flagsReg icc, regD dst, regD src) %{
5079   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
5080   ins_cost(150);
5081 
5082   size(4);
5083   format %{ "FCPYD$cmp $dst,$src" %}
5084   ins_encode %{
5085     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
5086   %}
5087   ins_pipe(int_conditional_double_move);
5088 %}
5089 
5090 instruct cmovDI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regD dst, regD src) %{
5091   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
5092   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
5093   ins_cost(150);
5094 
5095   size(4);
5096   format %{ "FCPYD$cmp $dst,$src" %}
5097   ins_encode %{
5098     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
5099   %}
5100   ins_pipe(int_conditional_double_move);
5101 %}
5102 
5103 instruct cmovDIu_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src) %{
5104   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
5105   ins_cost(150);
5106 
5107   size(4);
5108   format %{ "FCPYD$cmp $dst,$src" %}
5109   ins_encode %{
5110     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
5111   %}
5112   ins_pipe(int_conditional_double_move);
5113 %}
5114 
5115 // Conditional move
5116 instruct cmovLP_reg(cmpOpP cmp, flagsRegP pcc, iRegL dst, iRegL src) %{
5117   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
5118   ins_cost(150);
5119 
5120   size(8);
5121   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
5122             "MOV$cmp  $dst.hi,$src.hi" %}
5123   ins_encode %{
5124     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
5125     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
5126   %}
5127   ins_pipe(ialu_reg);
5128 %}
5129 
5130 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
5131 // (hi($con$$constant), lo($con$$constant)) becomes
5132 instruct cmovLP_immRot(cmpOpP cmp, flagsRegP pcc, iRegL dst, immLlowRot src) %{
5133   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
5134   ins_cost(140);
5135 
5136   size(8);
5137   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
5138             "MOV$cmp  $dst.hi,0" %}
5139   ins_encode %{
5140     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
5141     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
5142   %}
5143   ins_pipe(ialu_imm);
5144 %}
5145 
5146 instruct cmovLP_imm16(cmpOpP cmp, flagsRegP pcc, iRegL dst, immL16 src) %{
5147   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
5148   ins_cost(140);
5149 
5150   size(8);
5151   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
5152             "MOV$cmp  $dst.hi,0" %}
5153   ins_encode %{
5154     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
5155     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
5156   %}
5157   ins_pipe(ialu_imm);
5158 %}
5159 
5160 instruct cmovLI_reg(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src) %{
5161   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5162   ins_cost(150);
5163 
5164   size(8);
5165   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
5166             "MOV$cmp  $dst.hi,$src.hi" %}
5167   ins_encode %{
5168     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
5169     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
5170   %}
5171   ins_pipe(ialu_reg);
5172 %}
5173 
5174 instruct cmovLI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, iRegL src) %{
5175   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5176   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
5177             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
5178             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
5179             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
5180   ins_cost(150);
5181 
5182   size(8);
5183   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
5184             "MOV$cmp  $dst.hi,$src.hi" %}
5185   ins_encode %{
5186     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
5187     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
5188   %}
5189   ins_pipe(ialu_reg);
5190 %}
5191 
5192 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
5193 // (hi($con$$constant), lo($con$$constant)) becomes
5194 instruct cmovLI_immRot(cmpOp cmp, flagsReg icc, iRegL dst, immLlowRot src) %{
5195   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5196   ins_cost(140);
5197 
5198   size(8);
5199   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
5200             "MOV$cmp  $dst.hi,0" %}
5201   ins_encode %{
5202     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
5203     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
5204   %}
5205   ins_pipe(ialu_imm);
5206 %}
5207 
5208 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
5209 // (hi($con$$constant), lo($con$$constant)) becomes
5210 instruct cmovLI_immRot_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immLlowRot src) %{
5211   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5212   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
5213             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
5214             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
5215             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
5216   ins_cost(140);
5217 
5218   size(8);
5219   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
5220             "MOV$cmp  $dst.hi,0" %}
5221   ins_encode %{
5222     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
5223     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
5224   %}
5225   ins_pipe(ialu_imm);
5226 %}
5227 
5228 instruct cmovLI_imm16(cmpOp cmp, flagsReg icc, iRegL dst, immL16 src) %{
5229   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5230   ins_cost(140);
5231 
5232   size(8);
5233   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
5234             "MOV$cmp  $dst.hi,0" %}
5235   ins_encode %{
5236     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
5237     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
5238   %}
5239   ins_pipe(ialu_imm);
5240 %}
5241 
5242 instruct cmovLI_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immL16 src) %{
5243   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5244   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
5245             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
5246             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
5247             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
5248   ins_cost(140);
5249 
5250   size(8);
5251   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
5252             "MOV$cmp  $dst.hi,0" %}
5253   ins_encode %{
5254     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
5255     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
5256   %}
5257   ins_pipe(ialu_imm);
5258 %}
5259 
5260 instruct cmovLIu_reg(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src) %{
5261   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5262   ins_cost(150);
5263 
5264   size(8);
5265   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
5266             "MOV$cmp  $dst.hi,$src.hi" %}
5267   ins_encode %{
5268     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
5269     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
5270   %}
5271   ins_pipe(ialu_reg);
5272 %}
5273 
5274 
5275 //----------OS and Locking Instructions----------------------------------------
5276 
5277 // This name is KNOWN by the ADLC and cannot be changed.
5278 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
5279 // for this guy.
5280 instruct tlsLoadP(RthreadRegP dst) %{
5281   match(Set dst (ThreadLocal));
5282 
5283   size(0);
5284   ins_cost(0);
5285   format %{ "! TLS is in $dst" %}
5286   ins_encode( /*empty encoding*/ );
5287   ins_pipe(ialu_none);
5288 %}
5289 
5290 instruct checkCastPP( iRegP dst ) %{
5291   match(Set dst (CheckCastPP dst));
5292 
5293   size(0);
5294   format %{ "! checkcastPP of $dst" %}
5295   ins_encode( /*empty encoding*/ );
5296   ins_pipe(empty);
5297 %}
5298 
5299 
5300 instruct castPP( iRegP dst ) %{
5301   match(Set dst (CastPP dst));
5302   format %{ "! castPP of $dst" %}
5303   ins_encode( /*empty encoding*/ );
5304   ins_pipe(empty);
5305 %}
5306 
5307 instruct castII( iRegI dst ) %{
5308   match(Set dst (CastII dst));
5309   format %{ "! castII of $dst" %}
5310   ins_encode( /*empty encoding*/ );
5311   ins_cost(0);
5312   ins_pipe(empty);
5313 %}
5314 
5315 //----------Arithmetic Instructions--------------------------------------------
5316 // Addition Instructions
5317 // Register Addition
5318 instruct addI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
5319   match(Set dst (AddI src1 src2));
5320 
5321   size(4);
5322   format %{ "add_32 $dst,$src1,$src2\t! int" %}
5323   ins_encode %{
5324     __ add_32($dst$$Register, $src1$$Register, $src2$$Register);
5325   %}
5326   ins_pipe(ialu_reg_reg);
5327 %}
5328 
5329 instruct addshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5330   match(Set dst (AddI (LShiftI src1 src2) src3));
5331 
5332   size(4);
5333   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
5334   ins_encode %{
5335     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
5336   %}
5337   ins_pipe(ialu_reg_reg);
5338 %}
5339 
5340 
5341 instruct addshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
5342   match(Set dst (AddI (LShiftI src1 src2) src3));
5343 
5344   size(4);
5345   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
5346   ins_encode %{
5347     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
5348   %}
5349   ins_pipe(ialu_reg_reg);
5350 %}
5351 
5352 instruct addsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5353   match(Set dst (AddI (RShiftI src1 src2) src3));
5354 
5355   size(4);
5356   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
5357   ins_encode %{
5358     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
5359   %}
5360   ins_pipe(ialu_reg_reg);
5361 %}
5362 
5363 instruct addsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
5364   match(Set dst (AddI (RShiftI src1 src2) src3));
5365 
5366   size(4);
5367   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
5368   ins_encode %{
5369     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
5370   %}
5371   ins_pipe(ialu_reg_reg);
5372 %}
5373 
5374 instruct addshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5375   match(Set dst (AddI (URShiftI src1 src2) src3));
5376 
5377   size(4);
5378   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
5379   ins_encode %{
5380     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
5381   %}
5382   ins_pipe(ialu_reg_reg);
5383 %}
5384 
5385 instruct addshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
5386   match(Set dst (AddI (URShiftI src1 src2) src3));
5387 
5388   size(4);
5389   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
5390   ins_encode %{
5391     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
5392   %}
5393   ins_pipe(ialu_reg_reg);
5394 %}
5395 
5396 // Immediate Addition
5397 instruct addI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
5398   match(Set dst (AddI src1 src2));
5399 
5400   size(4);
5401   format %{ "add_32 $dst,$src1,$src2\t! int" %}
5402   ins_encode %{
5403     __ add_32($dst$$Register, $src1$$Register, $src2$$constant);
5404   %}
5405   ins_pipe(ialu_reg_imm);
5406 %}
5407 
5408 // Pointer Register Addition
5409 instruct addP_reg_reg(iRegP dst, iRegP src1, iRegX src2) %{
5410   match(Set dst (AddP src1 src2));
5411 
5412   size(4);
5413   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
5414   ins_encode %{
5415     __ add($dst$$Register, $src1$$Register, $src2$$Register);
5416   %}
5417   ins_pipe(ialu_reg_reg);
5418 %}
5419 
5420 
5421 // shifted iRegX operand
5422 operand shiftedX(iRegX src2, shimmX src3) %{
5423 //constraint(ALLOC_IN_RC(sp_ptr_reg));
5424   match(LShiftX src2 src3);
5425 
5426   op_cost(1);
5427   format %{ "$src2 << $src3" %}
5428   interface(MEMORY_INTER) %{
5429     base($src2);
5430     index(0xff);
5431     scale($src3);
5432     disp(0x0);
5433   %}
5434 %}
5435 
5436 instruct addshlP_reg_reg_imm(iRegP dst, iRegP src1, shiftedX src2) %{
5437   match(Set dst (AddP src1 src2));
5438 
5439   ins_cost(DEFAULT_COST * 3/2);
5440   size(4);
5441   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
5442   ins_encode %{
5443     Register base = reg_to_register_object($src2$$base);
5444     __ add($dst$$Register, $src1$$Register, AsmOperand(base, lsl, $src2$$scale));
5445   %}
5446   ins_pipe(ialu_reg_reg);
5447 %}
5448 
5449 // Pointer Immediate Addition
5450 instruct addP_reg_aimmX(iRegP dst, iRegP src1, aimmX src2) %{
5451   match(Set dst (AddP src1 src2));
5452 
5453   size(4);
5454   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
5455   ins_encode %{
5456     __ add($dst$$Register, $src1$$Register, $src2$$constant);
5457   %}
5458   ins_pipe(ialu_reg_imm);
5459 %}
5460 
5461 // Long Addition
5462 instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg ccr) %{
5463   match(Set dst (AddL src1 src2));
5464   effect(KILL ccr);
5465   size(8);
5466   format %{ "ADDS    $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
5467             "ADC     $dst.hi,$src1.hi,$src2.hi" %}
5468   ins_encode %{
5469     __ adds($dst$$Register, $src1$$Register, $src2$$Register);
5470     __ adc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
5471   %}
5472   ins_pipe(ialu_reg_reg);
5473 %}
5474 
5475 // TODO
5476 
5477 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
5478 // (hi($con$$constant), lo($con$$constant)) becomes
5479 instruct addL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg ccr) %{
5480   match(Set dst (AddL src1 con));
5481   effect(KILL ccr);
5482   size(8);
5483   format %{ "ADDS    $dst.lo,$src1.lo,$con\t! long\n\t"
5484             "ADC     $dst.hi,$src1.hi,0" %}
5485   ins_encode %{
5486     __ adds($dst$$Register, $src1$$Register, $con$$constant);
5487     __ adc($dst$$Register->successor(), $src1$$Register->successor(), 0);
5488   %}
5489   ins_pipe(ialu_reg_imm);
5490 %}
5491 
5492 //----------Conditional_store--------------------------------------------------
5493 // Conditional-store of the updated heap-top.
5494 // Used during allocation of the shared heap.
5495 // Sets flags (EQ) on success.
5496 
5497 // LoadP-locked.
5498 instruct loadPLocked(iRegP dst, memoryex mem) %{
5499   match(Set dst (LoadPLocked mem));
5500   size(4);
5501   format %{ "LDREX  $dst,$mem" %}
5502   ins_encode %{
5503     __ ldrex($dst$$Register,$mem$$Address);
5504   %}
5505   ins_pipe(iload_mem);
5506 %}
5507 
5508 instruct storePConditional( memoryex heap_top_ptr, iRegP oldval, iRegP newval, iRegI tmp, flagsRegP pcc ) %{
5509   predicate(_kids[1]->_kids[0]->_leaf->Opcode() == Op_LoadPLocked); // only works in conjunction with a LoadPLocked node
5510   match(Set pcc (StorePConditional heap_top_ptr (Binary oldval newval)));
5511   effect( TEMP tmp );
5512   size(8);
5513   format %{ "STREX  $tmp,$newval,$heap_top_ptr\n\t"
5514             "CMP    $tmp, 0" %}
5515   ins_encode %{
5516     __ strex($tmp$$Register, $newval$$Register, $heap_top_ptr$$Address);
5517     __ cmp($tmp$$Register, 0);
5518   %}
5519   ins_pipe( long_memory_op );
5520 %}
5521 
5522 // Conditional-store of an intx value.
5523 instruct storeXConditional( memoryex mem, iRegX oldval, iRegX newval, iRegX tmp, flagsReg icc ) %{
5524   match(Set icc (StoreIConditional mem (Binary oldval newval)));
5525   effect( TEMP tmp );
5526   size(28);
5527   format %{ "loop: \n\t"
5528             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem], DOESN'T set $newval=[$mem] in any case\n\t"
5529             "XORS     $tmp,$tmp, $oldval\n\t"
5530             "STREX.eq $tmp, $newval, $mem\n\t"
5531             "CMP.eq   $tmp, 1 \n\t"
5532             "B.eq     loop \n\t"
5533             "TEQ      $tmp, 0\n\t"
5534             "membar   LoadStore|LoadLoad" %}
5535   ins_encode %{
5536     Label loop;
5537     __ bind(loop);
5538     __ ldrex($tmp$$Register, $mem$$Address);
5539     __ eors($tmp$$Register, $tmp$$Register, $oldval$$Register);
5540     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
5541     __ cmp($tmp$$Register, 1, eq);
5542     __ b(loop, eq);
5543     __ teq($tmp$$Register, 0);
5544     // used by biased locking only. Requires a membar.
5545     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadStore | MacroAssembler::LoadLoad), noreg);
5546   %}
5547   ins_pipe( long_memory_op );
5548 %}
5549 
5550 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
5551 
5552 instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegLd newval, iRegI res, iRegLd tmp, flagsReg ccr ) %{
5553   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
5554   effect( KILL ccr, TEMP tmp);
5555   size(32);
5556   format %{ "loop: \n\t"
5557             "LDREXD   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
5558             "CMP      $tmp.lo, $oldval.lo\n\t"
5559             "CMP.eq   $tmp.hi, $oldval.hi\n\t"
5560             "STREXD.eq $tmp, $newval, $mem\n\t"
5561             "MOV.ne   $tmp, 0 \n\t"
5562             "XORS.eq  $tmp,$tmp, 1 \n\t"
5563             "B.eq     loop \n\t"
5564             "MOV      $res, $tmp" %}
5565   ins_encode %{
5566     Label loop;
5567     __ bind(loop);
5568     __ ldrexd($tmp$$Register, $mem$$Address);
5569     __ cmp($tmp$$Register, $oldval$$Register);
5570     __ cmp($tmp$$Register->successor(), $oldval$$Register->successor(), eq);
5571     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address, eq);
5572     __ mov($tmp$$Register, 0, ne);
5573     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
5574     __ b(loop, eq);
5575     __ mov($res$$Register, $tmp$$Register);
5576   %}
5577   ins_pipe( long_memory_op );
5578 %}
5579 
5580 
5581 instruct compareAndSwapI_bool(memoryex mem, iRegI oldval, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
5582   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
5583   effect( KILL ccr, TEMP tmp);
5584   size(28);
5585   format %{ "loop: \n\t"
5586             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
5587             "CMP      $tmp, $oldval\n\t"
5588             "STREX.eq $tmp, $newval, $mem\n\t"
5589             "MOV.ne   $tmp, 0 \n\t"
5590             "XORS.eq  $tmp,$tmp, 1 \n\t"
5591             "B.eq     loop \n\t"
5592             "MOV      $res, $tmp" %}
5593 
5594   ins_encode %{
5595     Label loop;
5596     __ bind(loop);
5597     __ ldrex($tmp$$Register,$mem$$Address);
5598     __ cmp($tmp$$Register, $oldval$$Register);
5599     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
5600     __ mov($tmp$$Register, 0, ne);
5601     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
5602     __ b(loop, eq);
5603     __ mov($res$$Register, $tmp$$Register);
5604   %}
5605   ins_pipe( long_memory_op );
5606 %}
5607 
5608 instruct compareAndSwapP_bool(memoryex mem, iRegP oldval, iRegP newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
5609   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
5610   effect( KILL ccr, TEMP tmp);
5611   size(28);
5612   format %{ "loop: \n\t"
5613             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
5614             "CMP      $tmp, $oldval\n\t"
5615             "STREX.eq $tmp, $newval, $mem\n\t"
5616             "MOV.ne   $tmp, 0 \n\t"
5617             "EORS.eq  $tmp,$tmp, 1 \n\t"
5618             "B.eq     loop \n\t"
5619             "MOV      $res, $tmp" %}
5620 
5621   ins_encode %{
5622     Label loop;
5623     __ bind(loop);
5624     __ ldrex($tmp$$Register,$mem$$Address);
5625     __ cmp($tmp$$Register, $oldval$$Register);
5626     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
5627     __ mov($tmp$$Register, 0, ne);
5628     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
5629     __ b(loop, eq);
5630     __ mov($res$$Register, $tmp$$Register);
5631   %}
5632   ins_pipe( long_memory_op );
5633 %}
5634 
5635 instruct xaddI_aimmI_no_res(memoryex mem, aimmI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
5636   predicate(n->as_LoadStore()->result_not_used());
5637   match(Set dummy (GetAndAddI mem add));
5638   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
5639   size(20);
5640   format %{ "loop: \n\t"
5641             "LDREX    $tmp1, $mem\n\t"
5642             "ADD      $tmp1, $tmp1, $add\n\t"
5643             "STREX    $tmp2, $tmp1, $mem\n\t"
5644             "CMP      $tmp2, 0 \n\t"
5645             "B.ne     loop \n\t" %}
5646 
5647   ins_encode %{
5648     Label loop;
5649     __ bind(loop);
5650     __ ldrex($tmp1$$Register,$mem$$Address);
5651     __ add($tmp1$$Register, $tmp1$$Register, $add$$constant);
5652     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5653     __ cmp($tmp2$$Register, 0);
5654     __ b(loop, ne);
5655   %}
5656   ins_pipe( long_memory_op );
5657 %}
5658 
5659 instruct xaddI_reg_no_res(memoryex mem, iRegI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
5660   predicate(n->as_LoadStore()->result_not_used());
5661   match(Set dummy (GetAndAddI mem add));
5662   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
5663   size(20);
5664   format %{ "loop: \n\t"
5665             "LDREX    $tmp1, $mem\n\t"
5666             "ADD      $tmp1, $tmp1, $add\n\t"
5667             "STREX    $tmp2, $tmp1, $mem\n\t"
5668             "CMP      $tmp2, 0 \n\t"
5669             "B.ne     loop \n\t" %}
5670 
5671   ins_encode %{
5672     Label loop;
5673     __ bind(loop);
5674     __ ldrex($tmp1$$Register,$mem$$Address);
5675     __ add($tmp1$$Register, $tmp1$$Register, $add$$Register);
5676     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5677     __ cmp($tmp2$$Register, 0);
5678     __ b(loop, ne);
5679   %}
5680   ins_pipe( long_memory_op );
5681 %}
5682 
5683 instruct xaddI_aimmI(memoryex mem, aimmI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
5684   match(Set res (GetAndAddI mem add));
5685   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
5686   size(20);
5687   format %{ "loop: \n\t"
5688             "LDREX    $res, $mem\n\t"
5689             "ADD      $tmp1, $res, $add\n\t"
5690             "STREX    $tmp2, $tmp1, $mem\n\t"
5691             "CMP      $tmp2, 0 \n\t"
5692             "B.ne     loop \n\t" %}
5693 
5694   ins_encode %{
5695     Label loop;
5696     __ bind(loop);
5697     __ ldrex($res$$Register,$mem$$Address);
5698     __ add($tmp1$$Register, $res$$Register, $add$$constant);
5699     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5700     __ cmp($tmp2$$Register, 0);
5701     __ b(loop, ne);
5702   %}
5703   ins_pipe( long_memory_op );
5704 %}
5705 
5706 instruct xaddI_reg(memoryex mem, iRegI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
5707   match(Set res (GetAndAddI mem add));
5708   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
5709   size(20);
5710   format %{ "loop: \n\t"
5711             "LDREX    $res, $mem\n\t"
5712             "ADD      $tmp1, $res, $add\n\t"
5713             "STREX    $tmp2, $tmp1, $mem\n\t"
5714             "CMP      $tmp2, 0 \n\t"
5715             "B.ne     loop \n\t" %}
5716 
5717   ins_encode %{
5718     Label loop;
5719     __ bind(loop);
5720     __ ldrex($res$$Register,$mem$$Address);
5721     __ add($tmp1$$Register, $res$$Register, $add$$Register);
5722     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5723     __ cmp($tmp2$$Register, 0);
5724     __ b(loop, ne);
5725   %}
5726   ins_pipe( long_memory_op );
5727 %}
5728 
5729 instruct xaddL_reg_no_res(memoryex mem, iRegL add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
5730   predicate(n->as_LoadStore()->result_not_used());
5731   match(Set dummy (GetAndAddL mem add));
5732   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
5733   size(24);
5734   format %{ "loop: \n\t"
5735             "LDREXD   $tmp1, $mem\n\t"
5736             "ADDS     $tmp1.lo, $tmp1.lo, $add.lo\n\t"
5737             "ADC      $tmp1.hi, $tmp1.hi, $add.hi\n\t"
5738             "STREXD   $tmp2, $tmp1, $mem\n\t"
5739             "CMP      $tmp2, 0 \n\t"
5740             "B.ne     loop \n\t" %}
5741 
5742   ins_encode %{
5743     Label loop;
5744     __ bind(loop);
5745     __ ldrexd($tmp1$$Register, $mem$$Address);
5746     __ adds($tmp1$$Register, $tmp1$$Register, $add$$Register);
5747     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), $add$$Register->successor());
5748     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5749     __ cmp($tmp2$$Register, 0);
5750     __ b(loop, ne);
5751   %}
5752   ins_pipe( long_memory_op );
5753 %}
5754 
5755 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
5756 // (hi($con$$constant), lo($con$$constant)) becomes
5757 instruct xaddL_immRot_no_res(memoryex mem, immLlowRot add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
5758   predicate(n->as_LoadStore()->result_not_used());
5759   match(Set dummy (GetAndAddL mem add));
5760   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
5761   size(24);
5762   format %{ "loop: \n\t"
5763             "LDREXD   $tmp1, $mem\n\t"
5764             "ADDS     $tmp1.lo, $tmp1.lo, $add\n\t"
5765             "ADC      $tmp1.hi, $tmp1.hi, 0\n\t"
5766             "STREXD   $tmp2, $tmp1, $mem\n\t"
5767             "CMP      $tmp2, 0 \n\t"
5768             "B.ne     loop \n\t" %}
5769 
5770   ins_encode %{
5771     Label loop;
5772     __ bind(loop);
5773     __ ldrexd($tmp1$$Register, $mem$$Address);
5774     __ adds($tmp1$$Register, $tmp1$$Register, $add$$constant);
5775     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), 0);
5776     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5777     __ cmp($tmp2$$Register, 0);
5778     __ b(loop, ne);
5779   %}
5780   ins_pipe( long_memory_op );
5781 %}
5782 
5783 instruct xaddL_reg(memoryex mem, iRegL add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
5784   match(Set res (GetAndAddL mem add));
5785   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
5786   size(24);
5787   format %{ "loop: \n\t"
5788             "LDREXD   $res, $mem\n\t"
5789             "ADDS     $tmp1.lo, $res.lo, $add.lo\n\t"
5790             "ADC      $tmp1.hi, $res.hi, $add.hi\n\t"
5791             "STREXD   $tmp2, $tmp1, $mem\n\t"
5792             "CMP      $tmp2, 0 \n\t"
5793             "B.ne     loop \n\t" %}
5794 
5795   ins_encode %{
5796     Label loop;
5797     __ bind(loop);
5798     __ ldrexd($res$$Register, $mem$$Address);
5799     __ adds($tmp1$$Register, $res$$Register, $add$$Register);
5800     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), $add$$Register->successor());
5801     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5802     __ cmp($tmp2$$Register, 0);
5803     __ b(loop, ne);
5804   %}
5805   ins_pipe( long_memory_op );
5806 %}
5807 
5808 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
5809 // (hi($con$$constant), lo($con$$constant)) becomes
5810 instruct xaddL_immRot(memoryex mem, immLlowRot add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
5811   match(Set res (GetAndAddL mem add));
5812   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
5813   size(24);
5814   format %{ "loop: \n\t"
5815             "LDREXD   $res, $mem\n\t"
5816             "ADDS     $tmp1.lo, $res.lo, $add\n\t"
5817             "ADC      $tmp1.hi, $res.hi, 0\n\t"
5818             "STREXD   $tmp2, $tmp1, $mem\n\t"
5819             "CMP      $tmp2, 0 \n\t"
5820             "B.ne     loop \n\t" %}
5821 
5822   ins_encode %{
5823     Label loop;
5824     __ bind(loop);
5825     __ ldrexd($res$$Register, $mem$$Address);
5826     __ adds($tmp1$$Register, $res$$Register, $add$$constant);
5827     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), 0);
5828     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5829     __ cmp($tmp2$$Register, 0);
5830     __ b(loop, ne);
5831   %}
5832   ins_pipe( long_memory_op );
5833 %}
5834 
5835 instruct xchgI(memoryex mem, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr) %{
5836   match(Set res (GetAndSetI mem newval));
5837   effect(KILL ccr, TEMP tmp, TEMP res);
5838   size(16);
5839   format %{ "loop: \n\t"
5840             "LDREX    $res, $mem\n\t"
5841             "STREX    $tmp, $newval, $mem\n\t"
5842             "CMP      $tmp, 0 \n\t"
5843             "B.ne     loop \n\t" %}
5844 
5845   ins_encode %{
5846     Label loop;
5847     __ bind(loop);
5848     __ ldrex($res$$Register,$mem$$Address);
5849     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
5850     __ cmp($tmp$$Register, 0);
5851     __ b(loop, ne);
5852   %}
5853   ins_pipe( long_memory_op );
5854 %}
5855 
5856 instruct xchgL(memoryex mem, iRegLd newval, iRegLd res, iRegI tmp, flagsReg ccr) %{
5857   match(Set res (GetAndSetL mem newval));
5858   effect( KILL ccr, TEMP tmp, TEMP res);
5859   size(16);
5860   format %{ "loop: \n\t"
5861             "LDREXD   $res, $mem\n\t"
5862             "STREXD   $tmp, $newval, $mem\n\t"
5863             "CMP      $tmp, 0 \n\t"
5864             "B.ne     loop \n\t" %}
5865 
5866   ins_encode %{
5867     Label loop;
5868     __ bind(loop);
5869     __ ldrexd($res$$Register, $mem$$Address);
5870     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address);
5871     __ cmp($tmp$$Register, 0);
5872     __ b(loop, ne);
5873   %}
5874   ins_pipe( long_memory_op );
5875 %}
5876 
5877 instruct xchgP(memoryex mem, iRegP newval, iRegP res, iRegI tmp, flagsReg ccr) %{
5878   match(Set res (GetAndSetP mem newval));
5879   effect(KILL ccr, TEMP tmp, TEMP res);
5880   size(16);
5881   format %{ "loop: \n\t"
5882             "LDREX    $res, $mem\n\t"
5883             "STREX    $tmp, $newval, $mem\n\t"
5884             "CMP      $tmp, 0 \n\t"
5885             "B.ne     loop \n\t" %}
5886 
5887   ins_encode %{
5888     Label loop;
5889     __ bind(loop);
5890     __ ldrex($res$$Register,$mem$$Address);
5891     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
5892     __ cmp($tmp$$Register, 0);
5893     __ b(loop, ne);
5894   %}
5895   ins_pipe( long_memory_op );
5896 %}
5897 
5898 //---------------------
5899 // Subtraction Instructions
5900 // Register Subtraction
5901 instruct subI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
5902   match(Set dst (SubI src1 src2));
5903 
5904   size(4);
5905   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
5906   ins_encode %{
5907     __ sub_32($dst$$Register, $src1$$Register, $src2$$Register);
5908   %}
5909   ins_pipe(ialu_reg_reg);
5910 %}
5911 
5912 instruct subshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5913   match(Set dst (SubI src1 (LShiftI src2 src3)));
5914 
5915   size(4);
5916   format %{ "SUB    $dst,$src1,$src2<<$src3" %}
5917   ins_encode %{
5918     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
5919   %}
5920   ins_pipe(ialu_reg_reg);
5921 %}
5922 
5923 instruct subshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
5924   match(Set dst (SubI src1 (LShiftI src2 src3)));
5925 
5926   size(4);
5927   format %{ "sub_32 $dst,$src1,$src2<<$src3\t! int" %}
5928   ins_encode %{
5929     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
5930   %}
5931   ins_pipe(ialu_reg_reg);
5932 %}
5933 
5934 instruct subsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5935   match(Set dst (SubI src1 (RShiftI src2 src3)));
5936 
5937   size(4);
5938   format %{ "SUB    $dst,$src1,$src2>>$src3" %}
5939   ins_encode %{
5940     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
5941   %}
5942   ins_pipe(ialu_reg_reg);
5943 %}
5944 
5945 instruct subsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
5946   match(Set dst (SubI src1 (RShiftI src2 src3)));
5947 
5948   size(4);
5949   format %{ "sub_32 $dst,$src1,$src2>>$src3\t! int" %}
5950   ins_encode %{
5951     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
5952   %}
5953   ins_pipe(ialu_reg_reg);
5954 %}
5955 
5956 instruct subshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5957   match(Set dst (SubI src1 (URShiftI src2 src3)));
5958 
5959   size(4);
5960   format %{ "SUB    $dst,$src1,$src2>>>$src3" %}
5961   ins_encode %{
5962     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
5963   %}
5964   ins_pipe(ialu_reg_reg);
5965 %}
5966 
5967 instruct subshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
5968   match(Set dst (SubI src1 (URShiftI src2 src3)));
5969 
5970   size(4);
5971   format %{ "sub_32 $dst,$src1,$src2>>>$src3\t! int" %}
5972   ins_encode %{
5973     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
5974   %}
5975   ins_pipe(ialu_reg_reg);
5976 %}
5977 
5978 instruct rsbshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5979   match(Set dst (SubI (LShiftI src1 src2) src3));
5980 
5981   size(4);
5982   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
5983   ins_encode %{
5984     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
5985   %}
5986   ins_pipe(ialu_reg_reg);
5987 %}
5988 
5989 instruct rsbshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
5990   match(Set dst (SubI (LShiftI src1 src2) src3));
5991 
5992   size(4);
5993   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
5994   ins_encode %{
5995     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
5996   %}
5997   ins_pipe(ialu_reg_reg);
5998 %}
5999 
6000 instruct rsbsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6001   match(Set dst (SubI (RShiftI src1 src2) src3));
6002 
6003   size(4);
6004   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
6005   ins_encode %{
6006     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
6007   %}
6008   ins_pipe(ialu_reg_reg);
6009 %}
6010 
6011 instruct rsbsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
6012   match(Set dst (SubI (RShiftI src1 src2) src3));
6013 
6014   size(4);
6015   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
6016   ins_encode %{
6017     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
6018   %}
6019   ins_pipe(ialu_reg_reg);
6020 %}
6021 
6022 instruct rsbshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6023   match(Set dst (SubI (URShiftI src1 src2) src3));
6024 
6025   size(4);
6026   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
6027   ins_encode %{
6028     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
6029   %}
6030   ins_pipe(ialu_reg_reg);
6031 %}
6032 
6033 instruct rsbshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
6034   match(Set dst (SubI (URShiftI src1 src2) src3));
6035 
6036   size(4);
6037   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
6038   ins_encode %{
6039     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
6040   %}
6041   ins_pipe(ialu_reg_reg);
6042 %}
6043 
6044 // Immediate Subtraction
6045 instruct subI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
6046   match(Set dst (SubI src1 src2));
6047 
6048   size(4);
6049   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
6050   ins_encode %{
6051     __ sub_32($dst$$Register, $src1$$Register, $src2$$constant);
6052   %}
6053   ins_pipe(ialu_reg_imm);
6054 %}
6055 
6056 instruct subI_reg_immRotneg(iRegI dst, iRegI src1, aimmIneg src2) %{
6057   match(Set dst (AddI src1 src2));
6058 
6059   size(4);
6060   format %{ "sub_32 $dst,$src1,-($src2)\t! int" %}
6061   ins_encode %{
6062     __ sub_32($dst$$Register, $src1$$Register, -$src2$$constant);
6063   %}
6064   ins_pipe(ialu_reg_imm);
6065 %}
6066 
6067 instruct subI_immRot_reg(iRegI dst, immIRot src1, iRegI src2) %{
6068   match(Set dst (SubI src1 src2));
6069 
6070   size(4);
6071   format %{ "RSB    $dst,$src2,src1" %}
6072   ins_encode %{
6073     __ rsb($dst$$Register, $src2$$Register, $src1$$constant);
6074   %}
6075   ins_pipe(ialu_zero_reg);
6076 %}
6077 
6078 // Register Subtraction
6079 instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg icc ) %{
6080   match(Set dst (SubL src1 src2));
6081   effect (KILL icc);
6082 
6083   size(8);
6084   format %{ "SUBS   $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
6085             "SBC    $dst.hi,$src1.hi,$src2.hi" %}
6086   ins_encode %{
6087     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
6088     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
6089   %}
6090   ins_pipe(ialu_reg_reg);
6091 %}
6092 
6093 // TODO
6094 
6095 // Immediate Subtraction
6096 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6097 // (hi($con$$constant), lo($con$$constant)) becomes
6098 instruct subL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg icc) %{
6099   match(Set dst (SubL src1 con));
6100   effect (KILL icc);
6101 
6102   size(8);
6103   format %{ "SUB    $dst.lo,$src1.lo,$con\t! long\n\t"
6104             "SBC    $dst.hi,$src1.hi,0" %}
6105   ins_encode %{
6106     __ subs($dst$$Register, $src1$$Register, $con$$constant);
6107     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), 0);
6108   %}
6109   ins_pipe(ialu_reg_imm);
6110 %}
6111 
6112 // Long negation
6113 instruct negL_reg_reg(iRegL dst, immL0 zero, iRegL src2, flagsReg icc) %{
6114   match(Set dst (SubL zero src2));
6115   effect (KILL icc);
6116 
6117   size(8);
6118   format %{ "RSBS   $dst.lo,$src2.lo,0\t! long\n\t"
6119             "RSC    $dst.hi,$src2.hi,0" %}
6120   ins_encode %{
6121     __ rsbs($dst$$Register, $src2$$Register, 0);
6122     __ rsc($dst$$Register->successor(), $src2$$Register->successor(), 0);
6123   %}
6124   ins_pipe(ialu_zero_reg);
6125 %}
6126 
6127 // Multiplication Instructions
6128 // Integer Multiplication
6129 // Register Multiplication
6130 instruct mulI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6131   match(Set dst (MulI src1 src2));
6132 
6133   size(4);
6134   format %{ "mul_32 $dst,$src1,$src2" %}
6135   ins_encode %{
6136     __ mul_32($dst$$Register, $src1$$Register, $src2$$Register);
6137   %}
6138   ins_pipe(imul_reg_reg);
6139 %}
6140 
6141 instruct mulL_lo1_hi2(iRegL dst, iRegL src1, iRegL src2) %{
6142   effect(DEF dst, USE src1, USE src2);
6143   size(4);
6144   format %{ "MUL  $dst.hi,$src1.lo,$src2.hi\t! long" %}
6145   ins_encode %{
6146     __ mul($dst$$Register->successor(), $src1$$Register, $src2$$Register->successor());
6147   %}
6148   ins_pipe(imul_reg_reg);
6149 %}
6150 
6151 instruct mulL_hi1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
6152   effect(USE_DEF dst, USE src1, USE src2);
6153   size(8);
6154   format %{ "MLA  $dst.hi,$src1.hi,$src2.lo,$dst.hi\t! long\n\t"
6155             "MOV  $dst.lo, 0"%}
6156   ins_encode %{
6157     __ mla($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register, $dst$$Register->successor());
6158     __ mov($dst$$Register, 0);
6159   %}
6160   ins_pipe(imul_reg_reg);
6161 %}
6162 
6163 instruct mulL_lo1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
6164   effect(USE_DEF dst, USE src1, USE src2);
6165   size(4);
6166   format %{ "UMLAL  $dst.lo,$dst.hi,$src1,$src2\t! long" %}
6167   ins_encode %{
6168     __ umlal($dst$$Register, $dst$$Register->successor(), $src1$$Register, $src2$$Register);
6169   %}
6170   ins_pipe(imul_reg_reg);
6171 %}
6172 
6173 instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
6174   match(Set dst (MulL src1 src2));
6175 
6176   expand %{
6177     mulL_lo1_hi2(dst, src1, src2);
6178     mulL_hi1_lo2(dst, src1, src2);
6179     mulL_lo1_lo2(dst, src1, src2);
6180   %}
6181 %}
6182 
6183 // Integer Division
6184 // Register Division
6185 instruct divI_reg_reg(R1RegI dst, R0RegI src1, R2RegI src2, LRRegP lr, flagsReg ccr) %{
6186   match(Set dst (DivI src1 src2));
6187   effect( KILL ccr, KILL src1, KILL src2, KILL lr);
6188   ins_cost((2+71)*DEFAULT_COST);
6189 
6190   format %{ "DIV   $dst,$src1,$src2 ! call to StubRoutines::Arm::idiv_irem_entry()" %}
6191   ins_encode %{
6192     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
6193   %}
6194   ins_pipe(sdiv_reg_reg);
6195 %}
6196 
6197 // Register Long Division
6198 instruct divL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
6199   match(Set dst (DivL src1 src2));
6200   effect(CALL);
6201   ins_cost(DEFAULT_COST*71);
6202   format %{ "DIVL  $src1,$src2,$dst\t! long ! call to SharedRuntime::ldiv" %}
6203   ins_encode %{
6204     address target = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);
6205     __ call(target, relocInfo::runtime_call_type);
6206   %}
6207   ins_pipe(divL_reg_reg);
6208 %}
6209 
6210 // Integer Remainder
6211 // Register Remainder
6212 instruct modI_reg_reg(R0RegI dst, R0RegI src1, R2RegI src2, R1RegI temp, LRRegP lr, flagsReg ccr ) %{
6213   match(Set dst (ModI src1 src2));
6214   effect( KILL ccr, KILL temp, KILL src2, KILL lr);
6215 
6216   format %{ "MODI   $dst,$src1,$src2\t ! call to StubRoutines::Arm::idiv_irem_entry" %}
6217   ins_encode %{
6218     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
6219   %}
6220   ins_pipe(sdiv_reg_reg);
6221 %}
6222 
6223 // Register Long Remainder
6224 instruct modL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
6225   match(Set dst (ModL src1 src2));
6226   effect(CALL);
6227   ins_cost(MEMORY_REF_COST); // FIXME
6228   format %{ "modL    $dst,$src1,$src2\t ! call to SharedRuntime::lrem" %}
6229   ins_encode %{
6230     address target = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
6231     __ call(target, relocInfo::runtime_call_type);
6232   %}
6233   ins_pipe(divL_reg_reg);
6234 %}
6235 
6236 // Integer Shift Instructions
6237 
6238 // Register Shift Left
6239 instruct shlI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6240   match(Set dst (LShiftI src1 src2));
6241 
6242   size(4);
6243   format %{ "LSL  $dst,$src1,$src2 \n\t" %}
6244   ins_encode %{
6245     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
6246   %}
6247   ins_pipe(ialu_reg_reg);
6248 %}
6249 
6250 // Register Shift Left Immediate
6251 instruct shlI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
6252   match(Set dst (LShiftI src1 src2));
6253 
6254   size(4);
6255   format %{ "LSL    $dst,$src1,$src2\t! int" %}
6256   ins_encode %{
6257     __ logical_shift_left($dst$$Register, $src1$$Register, $src2$$constant);
6258   %}
6259   ins_pipe(ialu_reg_imm);
6260 %}
6261 
6262 instruct shlL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
6263   effect(USE_DEF dst, USE src1, USE src2);
6264   size(4);
6265   format %{"OR  $dst.hi,$dst.hi,($src1.hi << $src2)"  %}
6266   ins_encode %{
6267     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$Register));
6268   %}
6269   ins_pipe(ialu_reg_reg);
6270 %}
6271 
6272 instruct shlL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
6273   effect(USE_DEF dst, USE src1, USE src2);
6274   size(4);
6275   format %{ "LSL  $dst.lo,$src1.lo,$src2 \n\t" %}
6276   ins_encode %{
6277     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
6278   %}
6279   ins_pipe(ialu_reg_reg);
6280 %}
6281 
6282 instruct shlL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
6283   effect(DEF dst, USE src1, USE src2, KILL ccr);
6284   size(16);
6285   format %{ "SUBS  $dst.hi,$src2,32 \n\t"
6286             "LSLpl $dst.hi,$src1.lo,$dst.hi \n\t"
6287             "RSBmi $dst.hi,$dst.hi,0 \n\t"
6288             "LSRmi $dst.hi,$src1.lo,$dst.hi" %}
6289 
6290   ins_encode %{
6291     // $src1$$Register and $dst$$Register->successor() can't be the same
6292     __ subs($dst$$Register->successor(), $src2$$Register, 32);
6293     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $dst$$Register->successor()), pl);
6294     __ rsb($dst$$Register->successor(), $dst$$Register->successor(), 0, mi);
6295     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsr, $dst$$Register->successor()), mi);
6296   %}
6297   ins_pipe(ialu_reg_reg);
6298 %}
6299 
6300 instruct shlL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
6301   match(Set dst (LShiftL src1 src2));
6302 
6303   expand %{
6304     flagsReg ccr;
6305     shlL_reg_reg_overlap(dst, src1, src2, ccr);
6306     shlL_reg_reg_merge_hi(dst, src1, src2);
6307     shlL_reg_reg_merge_lo(dst, src1, src2);
6308   %}
6309 %}
6310 
6311 // Register Shift Left Immediate
6312 instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
6313   match(Set dst (LShiftL src1 src2));
6314 
6315   size(8);
6316   format %{ "LSL   $dst.hi,$src1.lo,$src2-32\t! or mov if $src2==32\n\t"
6317             "MOV   $dst.lo, 0" %}
6318   ins_encode %{
6319     if ($src2$$constant == 32) {
6320       __ mov($dst$$Register->successor(), $src1$$Register);
6321     } else {
6322       __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $src2$$constant-32));
6323     }
6324     __ mov($dst$$Register, 0);
6325   %}
6326   ins_pipe(ialu_reg_imm);
6327 %}
6328 
6329 instruct shlL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
6330   match(Set dst (LShiftL src1 src2));
6331 
6332   size(12);
6333   format %{ "LSL   $dst.hi,$src1.lo,$src2\n\t"
6334             "OR    $dst.hi, $dst.hi, $src1.lo >> 32-$src2\n\t"
6335             "LSL   $dst.lo,$src1.lo,$src2" %}
6336   ins_encode %{
6337     // The order of the following 3 instructions matters: src1.lo and
6338     // dst.hi can't overlap but src.hi and dst.hi can.
6339     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$constant));
6340     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register, lsr, 32-$src2$$constant));
6341     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
6342   %}
6343   ins_pipe(ialu_reg_imm);
6344 %}
6345 
6346 // Register Arithmetic Shift Right
6347 instruct sarI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6348   match(Set dst (RShiftI src1 src2));
6349   size(4);
6350   format %{ "ASR    $dst,$src1,$src2\t! int" %}
6351   ins_encode %{
6352     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
6353   %}
6354   ins_pipe(ialu_reg_reg);
6355 %}
6356 
6357 // Register Arithmetic Shift Right Immediate
6358 instruct sarI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
6359   match(Set dst (RShiftI src1 src2));
6360 
6361   size(4);
6362   format %{ "ASR    $dst,$src1,$src2" %}
6363   ins_encode %{
6364     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
6365   %}
6366   ins_pipe(ialu_reg_imm);
6367 %}
6368 
6369 // Register Shift Right Arithmetic Long
6370 instruct sarL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
6371   effect(USE_DEF dst, USE src1, USE src2);
6372   size(4);
6373   format %{ "OR  $dst.lo,$dst.lo,($src1.lo >> $src2)"  %}
6374   ins_encode %{
6375     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
6376   %}
6377   ins_pipe(ialu_reg_reg);
6378 %}
6379 
6380 instruct sarL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
6381   effect(USE_DEF dst, USE src1, USE src2);
6382   size(4);
6383   format %{ "ASR  $dst.hi,$src1.hi,$src2 \n\t" %}
6384   ins_encode %{
6385     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$Register));
6386   %}
6387   ins_pipe(ialu_reg_reg);
6388 %}
6389 
6390 instruct sarL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
6391   effect(DEF dst, USE src1, USE src2, KILL ccr);
6392   size(16);
6393   format %{ "SUBS  $dst.lo,$src2,32 \n\t"
6394             "ASRpl $dst.lo,$src1.hi,$dst.lo \n\t"
6395             "RSBmi $dst.lo,$dst.lo,0 \n\t"
6396             "LSLmi $dst.lo,$src1.hi,$dst.lo" %}
6397 
6398   ins_encode %{
6399     // $src1$$Register->successor() and $dst$$Register can't be the same
6400     __ subs($dst$$Register, $src2$$Register, 32);
6401     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $dst$$Register), pl);
6402     __ rsb($dst$$Register, $dst$$Register, 0, mi);
6403     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
6404   %}
6405   ins_pipe(ialu_reg_reg);
6406 %}
6407 
6408 instruct sarL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
6409   match(Set dst (RShiftL src1 src2));
6410 
6411   expand %{
6412     flagsReg ccr;
6413     sarL_reg_reg_overlap(dst, src1, src2, ccr);
6414     sarL_reg_reg_merge_lo(dst, src1, src2);
6415     sarL_reg_reg_merge_hi(dst, src1, src2);
6416   %}
6417 %}
6418 
6419 // Register Shift Left Immediate
6420 instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
6421   match(Set dst (RShiftL src1 src2));
6422 
6423   size(8);
6424   format %{ "ASR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
6425             "ASR   $dst.hi,$src1.hi, $src2" %}
6426   ins_encode %{
6427     if ($src2$$constant == 32) {
6428       __ mov($dst$$Register, $src1$$Register->successor());
6429     } else{
6430       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $src2$$constant-32));
6431     }
6432     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, 0));
6433   %}
6434 
6435   ins_pipe(ialu_reg_imm);
6436 %}
6437 
6438 instruct sarL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
6439   match(Set dst (RShiftL src1 src2));
6440   size(12);
6441   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
6442             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
6443             "ASR   $dst.hi,$src1.hi,$src2" %}
6444   ins_encode %{
6445     // The order of the following 3 instructions matters: src1.lo and
6446     // dst.hi can't overlap but src.hi and dst.hi can.
6447     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
6448     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
6449     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$constant));
6450   %}
6451   ins_pipe(ialu_reg_imm);
6452 %}
6453 
6454 // Register Shift Right
6455 instruct shrI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6456   match(Set dst (URShiftI src1 src2));
6457   size(4);
6458   format %{ "LSR    $dst,$src1,$src2\t! int" %}
6459   ins_encode %{
6460     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
6461   %}
6462   ins_pipe(ialu_reg_reg);
6463 %}
6464 
6465 // Register Shift Right Immediate
6466 instruct shrI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
6467   match(Set dst (URShiftI src1 src2));
6468 
6469   size(4);
6470   format %{ "LSR    $dst,$src1,$src2" %}
6471   ins_encode %{
6472     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
6473   %}
6474   ins_pipe(ialu_reg_imm);
6475 %}
6476 
6477 // Register Shift Right
6478 instruct shrL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
6479   effect(USE_DEF dst, USE src1, USE src2);
6480   size(4);
6481   format %{ "OR   $dst.lo,$dst,($src1.lo >>> $src2)"  %}
6482   ins_encode %{
6483     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
6484   %}
6485   ins_pipe(ialu_reg_reg);
6486 %}
6487 
6488 instruct shrL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
6489   effect(USE_DEF dst, USE src1, USE src2);
6490   size(4);
6491   format %{ "LSR  $dst.hi,$src1.hi,$src2 \n\t" %}
6492   ins_encode %{
6493     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$Register));
6494   %}
6495   ins_pipe(ialu_reg_reg);
6496 %}
6497 
6498 instruct shrL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
6499   effect(DEF dst, USE src1, USE src2, KILL ccr);
6500   size(16);
6501   format %{ "SUBS  $dst,$src2,32 \n\t"
6502             "LSRpl $dst,$src1.hi,$dst \n\t"
6503             "RSBmi $dst,$dst,0 \n\t"
6504             "LSLmi $dst,$src1.hi,$dst" %}
6505 
6506   ins_encode %{
6507     // $src1$$Register->successor() and $dst$$Register can't be the same
6508     __ subs($dst$$Register, $src2$$Register, 32);
6509     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $dst$$Register), pl);
6510     __ rsb($dst$$Register, $dst$$Register, 0, mi);
6511     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
6512   %}
6513   ins_pipe(ialu_reg_reg);
6514 %}
6515 
6516 instruct shrL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
6517   match(Set dst (URShiftL src1 src2));
6518 
6519   expand %{
6520     flagsReg ccr;
6521     shrL_reg_reg_overlap(dst, src1, src2, ccr);
6522     shrL_reg_reg_merge_lo(dst, src1, src2);
6523     shrL_reg_reg_merge_hi(dst, src1, src2);
6524   %}
6525 %}
6526 
6527 // Register Shift Right Immediate
6528 instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
6529   match(Set dst (URShiftL src1 src2));
6530 
6531   size(8);
6532   format %{ "LSR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
6533             "MOV   $dst.hi, 0" %}
6534   ins_encode %{
6535     if ($src2$$constant == 32) {
6536       __ mov($dst$$Register, $src1$$Register->successor());
6537     } else {
6538       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $src2$$constant-32));
6539     }
6540     __ mov($dst$$Register->successor(), 0);
6541   %}
6542 
6543   ins_pipe(ialu_reg_imm);
6544 %}
6545 
6546 instruct shrL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
6547   match(Set dst (URShiftL src1 src2));
6548 
6549   size(12);
6550   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
6551             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
6552             "LSR   $dst.hi,$src1.hi,$src2" %}
6553   ins_encode %{
6554     // The order of the following 3 instructions matters: src1.lo and
6555     // dst.hi can't overlap but src.hi and dst.hi can.
6556     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
6557     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
6558     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$constant));
6559   %}
6560   ins_pipe(ialu_reg_imm);
6561 %}
6562 
6563 
6564 instruct shrP_reg_imm5(iRegX dst, iRegP src1, immU5 src2) %{
6565   match(Set dst (URShiftI (CastP2X src1) src2));
6566   size(4);
6567   format %{ "LSR    $dst,$src1,$src2\t! Cast ptr $src1 to int and shift" %}
6568   ins_encode %{
6569     __ logical_shift_right($dst$$Register, $src1$$Register, $src2$$constant);
6570   %}
6571   ins_pipe(ialu_reg_imm);
6572 %}
6573 
6574 //----------Floating Point Arithmetic Instructions-----------------------------
6575 
6576 //  Add float single precision
6577 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
6578   match(Set dst (AddF src1 src2));
6579 
6580   size(4);
6581   format %{ "FADDS  $dst,$src1,$src2" %}
6582   ins_encode %{
6583     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6584   %}
6585 
6586   ins_pipe(faddF_reg_reg);
6587 %}
6588 
6589 //  Add float double precision
6590 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
6591   match(Set dst (AddD src1 src2));
6592 
6593   size(4);
6594   format %{ "FADDD  $dst,$src1,$src2" %}
6595   ins_encode %{
6596     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6597   %}
6598 
6599   ins_pipe(faddD_reg_reg);
6600 %}
6601 
6602 //  Sub float single precision
6603 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
6604   match(Set dst (SubF src1 src2));
6605 
6606   size(4);
6607   format %{ "FSUBS  $dst,$src1,$src2" %}
6608   ins_encode %{
6609     __ sub_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6610   %}
6611   ins_pipe(faddF_reg_reg);
6612 %}
6613 
6614 //  Sub float double precision
6615 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
6616   match(Set dst (SubD src1 src2));
6617 
6618   size(4);
6619   format %{ "FSUBD  $dst,$src1,$src2" %}
6620   ins_encode %{
6621     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6622   %}
6623   ins_pipe(faddD_reg_reg);
6624 %}
6625 
6626 //  Mul float single precision
6627 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
6628   match(Set dst (MulF src1 src2));
6629 
6630   size(4);
6631   format %{ "FMULS  $dst,$src1,$src2" %}
6632   ins_encode %{
6633     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6634   %}
6635 
6636   ins_pipe(fmulF_reg_reg);
6637 %}
6638 
6639 //  Mul float double precision
6640 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
6641   match(Set dst (MulD src1 src2));
6642 
6643   size(4);
6644   format %{ "FMULD  $dst,$src1,$src2" %}
6645   ins_encode %{
6646     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6647   %}
6648 
6649   ins_pipe(fmulD_reg_reg);
6650 %}
6651 
6652 //  Div float single precision
6653 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
6654   match(Set dst (DivF src1 src2));
6655 
6656   size(4);
6657   format %{ "FDIVS  $dst,$src1,$src2" %}
6658   ins_encode %{
6659     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6660   %}
6661 
6662   ins_pipe(fdivF_reg_reg);
6663 %}
6664 
6665 //  Div float double precision
6666 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
6667   match(Set dst (DivD src1 src2));
6668 
6669   size(4);
6670   format %{ "FDIVD  $dst,$src1,$src2" %}
6671   ins_encode %{
6672     __ div_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6673   %}
6674 
6675   ins_pipe(fdivD_reg_reg);
6676 %}
6677 
6678 //  Absolute float double precision
6679 instruct absD_reg(regD dst, regD src) %{
6680   match(Set dst (AbsD src));
6681 
6682   size(4);
6683   format %{ "FABSd  $dst,$src" %}
6684   ins_encode %{
6685     __ abs_double($dst$$FloatRegister, $src$$FloatRegister);
6686   %}
6687   ins_pipe(faddD_reg);
6688 %}
6689 
6690 //  Absolute float single precision
6691 instruct absF_reg(regF dst, regF src) %{
6692   match(Set dst (AbsF src));
6693   format %{ "FABSs  $dst,$src" %}
6694   ins_encode %{
6695     __ abs_float($dst$$FloatRegister, $src$$FloatRegister);
6696   %}
6697   ins_pipe(faddF_reg);
6698 %}
6699 
6700 instruct negF_reg(regF dst, regF src) %{
6701   match(Set dst (NegF src));
6702 
6703   size(4);
6704   format %{ "FNEGs  $dst,$src" %}
6705   ins_encode %{
6706     __ neg_float($dst$$FloatRegister, $src$$FloatRegister);
6707   %}
6708   ins_pipe(faddF_reg);
6709 %}
6710 
6711 instruct negD_reg(regD dst, regD src) %{
6712   match(Set dst (NegD src));
6713 
6714   format %{ "FNEGd  $dst,$src" %}
6715   ins_encode %{
6716     __ neg_double($dst$$FloatRegister, $src$$FloatRegister);
6717   %}
6718   ins_pipe(faddD_reg);
6719 %}
6720 
6721 //  Sqrt float double precision
6722 instruct sqrtF_reg_reg(regF dst, regF src) %{
6723   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
6724 
6725   size(4);
6726   format %{ "FSQRTS $dst,$src" %}
6727   ins_encode %{
6728     __ sqrt_float($dst$$FloatRegister, $src$$FloatRegister);
6729   %}
6730   ins_pipe(fdivF_reg_reg);
6731 %}
6732 
6733 //  Sqrt float double precision
6734 instruct sqrtD_reg_reg(regD dst, regD src) %{
6735   match(Set dst (SqrtD src));
6736 
6737   size(4);
6738   format %{ "FSQRTD $dst,$src" %}
6739   ins_encode %{
6740     __ sqrt_double($dst$$FloatRegister, $src$$FloatRegister);
6741   %}
6742   ins_pipe(fdivD_reg_reg);
6743 %}
6744 
6745 //----------Logical Instructions-----------------------------------------------
6746 // And Instructions
6747 // Register And
6748 instruct andI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6749   match(Set dst (AndI src1 src2));
6750 
6751   size(4);
6752   format %{ "and_32 $dst,$src1,$src2" %}
6753   ins_encode %{
6754     __ and_32($dst$$Register, $src1$$Register, $src2$$Register);
6755   %}
6756   ins_pipe(ialu_reg_reg);
6757 %}
6758 
6759 instruct andshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6760   match(Set dst (AndI src1 (LShiftI src2 src3)));
6761 
6762   size(4);
6763   format %{ "AND    $dst,$src1,$src2<<$src3" %}
6764   ins_encode %{
6765     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
6766   %}
6767   ins_pipe(ialu_reg_reg);
6768 %}
6769 
6770 instruct andshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6771   match(Set dst (AndI src1 (LShiftI src2 src3)));
6772 
6773   size(4);
6774   format %{ "and_32 $dst,$src1,$src2<<$src3" %}
6775   ins_encode %{
6776     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
6777   %}
6778   ins_pipe(ialu_reg_reg);
6779 %}
6780 
6781 instruct andsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6782   match(Set dst (AndI src1 (RShiftI src2 src3)));
6783 
6784   size(4);
6785   format %{ "AND    $dst,$src1,$src2>>$src3" %}
6786   ins_encode %{
6787     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
6788   %}
6789   ins_pipe(ialu_reg_reg);
6790 %}
6791 
6792 instruct andsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6793   match(Set dst (AndI src1 (RShiftI src2 src3)));
6794 
6795   size(4);
6796   format %{ "and_32 $dst,$src1,$src2>>$src3" %}
6797   ins_encode %{
6798     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
6799   %}
6800   ins_pipe(ialu_reg_reg);
6801 %}
6802 
6803 instruct andshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6804   match(Set dst (AndI src1 (URShiftI src2 src3)));
6805 
6806   size(4);
6807   format %{ "AND    $dst,$src1,$src2>>>$src3" %}
6808   ins_encode %{
6809     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
6810   %}
6811   ins_pipe(ialu_reg_reg);
6812 %}
6813 
6814 instruct andshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6815   match(Set dst (AndI src1 (URShiftI src2 src3)));
6816 
6817   size(4);
6818   format %{ "and_32 $dst,$src1,$src2>>>$src3" %}
6819   ins_encode %{
6820     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
6821   %}
6822   ins_pipe(ialu_reg_reg);
6823 %}
6824 
6825 // Immediate And
6826 instruct andI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
6827   match(Set dst (AndI src1 src2));
6828 
6829   size(4);
6830   format %{ "and_32 $dst,$src1,$src2\t! int" %}
6831   ins_encode %{
6832     __ and_32($dst$$Register, $src1$$Register, $src2$$constant);
6833   %}
6834   ins_pipe(ialu_reg_imm);
6835 %}
6836 
6837 instruct andI_reg_limmn(iRegI dst, iRegI src1, limmIn src2) %{
6838   match(Set dst (AndI src1 src2));
6839 
6840   size(4);
6841   format %{ "bic    $dst,$src1,~$src2\t! int" %}
6842   ins_encode %{
6843     __ bic($dst$$Register, $src1$$Register, ~$src2$$constant);
6844   %}
6845   ins_pipe(ialu_reg_imm);
6846 %}
6847 
6848 // Register And Long
6849 instruct andL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
6850   match(Set dst (AndL src1 src2));
6851 
6852   ins_cost(DEFAULT_COST);
6853   size(8);
6854   format %{ "AND    $dst,$src1,$src2\t! long" %}
6855   ins_encode %{
6856     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
6857     __ andr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
6858   %}
6859   ins_pipe(ialu_reg_reg);
6860 %}
6861 
6862 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6863 // (hi($con$$constant), lo($con$$constant)) becomes
6864 instruct andL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
6865   match(Set dst (AndL src1 con));
6866   ins_cost(DEFAULT_COST);
6867   size(8);
6868   format %{ "AND    $dst,$src1,$con\t! long" %}
6869   ins_encode %{
6870     __ andr($dst$$Register, $src1$$Register, $con$$constant);
6871     __ andr($dst$$Register->successor(), $src1$$Register->successor(), 0);
6872   %}
6873   ins_pipe(ialu_reg_imm);
6874 %}
6875 
6876 // Or Instructions
6877 // Register Or
6878 instruct orI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6879   match(Set dst (OrI src1 src2));
6880 
6881   size(4);
6882   format %{ "orr_32 $dst,$src1,$src2\t! int" %}
6883   ins_encode %{
6884     __ orr_32($dst$$Register, $src1$$Register, $src2$$Register);
6885   %}
6886   ins_pipe(ialu_reg_reg);
6887 %}
6888 
6889 instruct orshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6890   match(Set dst (OrI src1 (LShiftI src2 src3)));
6891 
6892   size(4);
6893   format %{ "OR    $dst,$src1,$src2<<$src3" %}
6894   ins_encode %{
6895     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
6896   %}
6897   ins_pipe(ialu_reg_reg);
6898 %}
6899 
6900 instruct orshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6901   match(Set dst (OrI src1 (LShiftI src2 src3)));
6902 
6903   size(4);
6904   format %{ "orr_32 $dst,$src1,$src2<<$src3" %}
6905   ins_encode %{
6906     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
6907   %}
6908   ins_pipe(ialu_reg_reg);
6909 %}
6910 
6911 instruct orsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6912   match(Set dst (OrI src1 (RShiftI src2 src3)));
6913 
6914   size(4);
6915   format %{ "OR    $dst,$src1,$src2>>$src3" %}
6916   ins_encode %{
6917     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
6918   %}
6919   ins_pipe(ialu_reg_reg);
6920 %}
6921 
6922 instruct orsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6923   match(Set dst (OrI src1 (RShiftI src2 src3)));
6924 
6925   size(4);
6926   format %{ "orr_32 $dst,$src1,$src2>>$src3" %}
6927   ins_encode %{
6928     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
6929   %}
6930   ins_pipe(ialu_reg_reg);
6931 %}
6932 
6933 instruct orshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6934   match(Set dst (OrI src1 (URShiftI src2 src3)));
6935 
6936   size(4);
6937   format %{ "OR    $dst,$src1,$src2>>>$src3" %}
6938   ins_encode %{
6939     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
6940   %}
6941   ins_pipe(ialu_reg_reg);
6942 %}
6943 
6944 instruct orshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6945   match(Set dst (OrI src1 (URShiftI src2 src3)));
6946 
6947   size(4);
6948   format %{ "orr_32 $dst,$src1,$src2>>>$src3" %}
6949   ins_encode %{
6950     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
6951   %}
6952   ins_pipe(ialu_reg_reg);
6953 %}
6954 
6955 // Immediate Or
6956 instruct orI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
6957   match(Set dst (OrI src1 src2));
6958 
6959   size(4);
6960   format %{ "orr_32  $dst,$src1,$src2" %}
6961   ins_encode %{
6962     __ orr_32($dst$$Register, $src1$$Register, $src2$$constant);
6963   %}
6964   ins_pipe(ialu_reg_imm);
6965 %}
6966 // TODO: orn_32 with limmIn
6967 
6968 // Register Or Long
6969 instruct orL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
6970   match(Set dst (OrL src1 src2));
6971 
6972   ins_cost(DEFAULT_COST);
6973   size(8);
6974   format %{ "OR     $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
6975             "OR     $dst.hi,$src1.hi,$src2.hi" %}
6976   ins_encode %{
6977     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
6978     __ orr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
6979   %}
6980   ins_pipe(ialu_reg_reg);
6981 %}
6982 
6983 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6984 // (hi($con$$constant), lo($con$$constant)) becomes
6985 instruct orL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
6986   match(Set dst (OrL src1 con));
6987   ins_cost(DEFAULT_COST);
6988   size(8);
6989   format %{ "OR     $dst.lo,$src1.lo,$con\t! long\n\t"
6990             "OR     $dst.hi,$src1.hi,$con" %}
6991   ins_encode %{
6992     __ orr($dst$$Register, $src1$$Register, $con$$constant);
6993     __ orr($dst$$Register->successor(), $src1$$Register->successor(), 0);
6994   %}
6995   ins_pipe(ialu_reg_imm);
6996 %}
6997 
6998 #ifdef TODO
6999 // Use SPRegP to match Rthread (TLS register) without spilling.
7000 // Use store_ptr_RegP to match Rthread (TLS register) without spilling.
7001 // Use sp_ptr_RegP to match Rthread (TLS register) without spilling.
7002 instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
7003   match(Set dst (OrI src1 (CastP2X src2)));
7004   size(4);
7005   format %{ "OR     $dst,$src1,$src2" %}
7006   ins_encode %{
7007     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
7008   %}
7009   ins_pipe(ialu_reg_reg);
7010 %}
7011 #endif
7012 
7013 // Xor Instructions
7014 // Register Xor
7015 instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
7016   match(Set dst (XorI src1 src2));
7017 
7018   size(4);
7019   format %{ "eor_32 $dst,$src1,$src2" %}
7020   ins_encode %{
7021     __ eor_32($dst$$Register, $src1$$Register, $src2$$Register);
7022   %}
7023   ins_pipe(ialu_reg_reg);
7024 %}
7025 
7026 instruct xorshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
7027   match(Set dst (XorI src1 (LShiftI src2 src3)));
7028 
7029   size(4);
7030   format %{ "XOR    $dst,$src1,$src2<<$src3" %}
7031   ins_encode %{
7032     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
7033   %}
7034   ins_pipe(ialu_reg_reg);
7035 %}
7036 
7037 instruct xorshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
7038   match(Set dst (XorI src1 (LShiftI src2 src3)));
7039 
7040   size(4);
7041   format %{ "eor_32 $dst,$src1,$src2<<$src3" %}
7042   ins_encode %{
7043     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
7044   %}
7045   ins_pipe(ialu_reg_reg);
7046 %}
7047 
7048 instruct xorsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
7049   match(Set dst (XorI src1 (RShiftI src2 src3)));
7050 
7051   size(4);
7052   format %{ "XOR    $dst,$src1,$src2>>$src3" %}
7053   ins_encode %{
7054     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
7055   %}
7056   ins_pipe(ialu_reg_reg);
7057 %}
7058 
7059 instruct xorsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
7060   match(Set dst (XorI src1 (RShiftI src2 src3)));
7061 
7062   size(4);
7063   format %{ "eor_32 $dst,$src1,$src2>>$src3" %}
7064   ins_encode %{
7065     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
7066   %}
7067   ins_pipe(ialu_reg_reg);
7068 %}
7069 
7070 instruct xorshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
7071   match(Set dst (XorI src1 (URShiftI src2 src3)));
7072 
7073   size(4);
7074   format %{ "XOR    $dst,$src1,$src2>>>$src3" %}
7075   ins_encode %{
7076     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
7077   %}
7078   ins_pipe(ialu_reg_reg);
7079 %}
7080 
7081 instruct xorshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
7082   match(Set dst (XorI src1 (URShiftI src2 src3)));
7083 
7084   size(4);
7085   format %{ "eor_32 $dst,$src1,$src2>>>$src3" %}
7086   ins_encode %{
7087     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
7088   %}
7089   ins_pipe(ialu_reg_reg);
7090 %}
7091 
7092 // Immediate Xor
7093 instruct xorI_reg_imm(iRegI dst, iRegI src1, limmI src2) %{
7094   match(Set dst (XorI src1 src2));
7095 
7096   size(4);
7097   format %{ "eor_32 $dst,$src1,$src2" %}
7098   ins_encode %{
7099     __ eor_32($dst$$Register, $src1$$Register, $src2$$constant);
7100   %}
7101   ins_pipe(ialu_reg_imm);
7102 %}
7103 
7104 // Register Xor Long
7105 instruct xorL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
7106   match(Set dst (XorL src1 src2));
7107   ins_cost(DEFAULT_COST);
7108   size(8);
7109   format %{ "XOR     $dst.hi,$src1.hi,$src2.hi\t! long\n\t"
7110             "XOR     $dst.lo,$src1.lo,$src2.lo\t! long" %}
7111   ins_encode %{
7112     __ eor($dst$$Register, $src1$$Register, $src2$$Register);
7113     __ eor($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
7114   %}
7115   ins_pipe(ialu_reg_reg);
7116 %}
7117 
7118 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7119 // (hi($con$$constant), lo($con$$constant)) becomes
7120 instruct xorL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
7121   match(Set dst (XorL src1 con));
7122   ins_cost(DEFAULT_COST);
7123   size(8);
7124   format %{ "XOR     $dst.hi,$src1.hi,$con\t! long\n\t"
7125             "XOR     $dst.lo,$src1.lo,0\t! long" %}
7126   ins_encode %{
7127     __ eor($dst$$Register, $src1$$Register, $con$$constant);
7128     __ eor($dst$$Register->successor(), $src1$$Register->successor(), 0);
7129   %}
7130   ins_pipe(ialu_reg_imm);
7131 %}
7132 
7133 //----------Convert to Boolean-------------------------------------------------
7134 instruct convI2B( iRegI dst, iRegI src, flagsReg ccr ) %{
7135   match(Set dst (Conv2B src));
7136   effect(KILL ccr);
7137   size(12);
7138   ins_cost(DEFAULT_COST*2);
7139   format %{ "TST    $src,$src \n\t"
7140             "MOV    $dst, 0   \n\t"
7141             "MOV.ne $dst, 1" %}
7142   ins_encode %{ // FIXME: can do better?
7143     __ tst($src$$Register, $src$$Register);
7144     __ mov($dst$$Register, 0);
7145     __ mov($dst$$Register, 1, ne);
7146   %}
7147   ins_pipe(ialu_reg_ialu);
7148 %}
7149 
7150 instruct convP2B( iRegI dst, iRegP src, flagsReg ccr ) %{
7151   match(Set dst (Conv2B src));
7152   effect(KILL ccr);
7153   size(12);
7154   ins_cost(DEFAULT_COST*2);
7155   format %{ "TST    $src,$src \n\t"
7156             "MOV    $dst, 0   \n\t"
7157             "MOV.ne $dst, 1" %}
7158   ins_encode %{
7159     __ tst($src$$Register, $src$$Register);
7160     __ mov($dst$$Register, 0);
7161     __ mov($dst$$Register, 1, ne);
7162   %}
7163   ins_pipe(ialu_reg_ialu);
7164 %}
7165 
7166 instruct cmpLTMask_reg_reg( iRegI dst, iRegI p, iRegI q, flagsReg ccr ) %{
7167   match(Set dst (CmpLTMask p q));
7168   effect( KILL ccr );
7169   ins_cost(DEFAULT_COST*3);
7170   format %{ "CMP    $p,$q\n\t"
7171             "MOV    $dst, #0\n\t"
7172             "MOV.lt $dst, #-1" %}
7173   ins_encode %{
7174     __ cmp($p$$Register, $q$$Register);
7175     __ mov($dst$$Register, 0);
7176     __ mvn($dst$$Register, 0, lt);
7177   %}
7178   ins_pipe(ialu_reg_reg_ialu);
7179 %}
7180 
7181 instruct cmpLTMask_reg_imm( iRegI dst, iRegI p, aimmI q, flagsReg ccr ) %{
7182   match(Set dst (CmpLTMask p q));
7183   effect( KILL ccr );
7184   ins_cost(DEFAULT_COST*3);
7185   format %{ "CMP    $p,$q\n\t"
7186             "MOV    $dst, #0\n\t"
7187             "MOV.lt $dst, #-1" %}
7188   ins_encode %{
7189     __ cmp($p$$Register, $q$$constant);
7190     __ mov($dst$$Register, 0);
7191     __ mvn($dst$$Register, 0, lt);
7192   %}
7193   ins_pipe(ialu_reg_reg_ialu);
7194 %}
7195 
7196 instruct cadd_cmpLTMask3( iRegI p, iRegI q, iRegI y, iRegI z, flagsReg ccr ) %{
7197   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
7198   effect( KILL ccr );
7199   ins_cost(DEFAULT_COST*2);
7200   format %{ "CMP    $p,$q\n\t"
7201             "ADD.lt $z,$y,$z" %}
7202   ins_encode %{
7203     __ cmp($p$$Register, $q$$Register);
7204     __ add($z$$Register, $y$$Register, $z$$Register, lt);
7205   %}
7206   ins_pipe( cadd_cmpltmask );
7207 %}
7208 
7209 // FIXME: remove unused "dst"
7210 instruct cadd_cmpLTMask4( iRegI dst, iRegI p, aimmI q, iRegI y, iRegI z, flagsReg ccr ) %{
7211   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
7212   effect( KILL ccr );
7213   ins_cost(DEFAULT_COST*2);
7214   format %{ "CMP    $p,$q\n\t"
7215             "ADD.lt $z,$y,$z" %}
7216   ins_encode %{
7217     __ cmp($p$$Register, $q$$constant);
7218     __ add($z$$Register, $y$$Register, $z$$Register, lt);
7219   %}
7220   ins_pipe( cadd_cmpltmask );
7221 %}
7222 
7223 instruct cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, flagsReg ccr ) %{
7224   match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
7225   effect( KILL ccr );
7226   ins_cost(DEFAULT_COST*2);
7227   format %{ "SUBS   $p,$p,$q\n\t"
7228             "ADD.lt $p,$y,$p" %}
7229   ins_encode %{
7230     __ subs($p$$Register, $p$$Register, $q$$Register);
7231     __ add($p$$Register, $y$$Register, $p$$Register, lt);
7232   %}
7233   ins_pipe( cadd_cmpltmask );
7234 %}
7235 
7236 //----------Arithmetic Conversion Instructions---------------------------------
7237 // The conversions operations are all Alpha sorted.  Please keep it that way!
7238 
7239 instruct convD2F_reg(regF dst, regD src) %{
7240   match(Set dst (ConvD2F src));
7241   size(4);
7242   format %{ "FCVTSD  $dst,$src" %}
7243   ins_encode %{
7244     __ convert_d2f($dst$$FloatRegister, $src$$FloatRegister);
7245   %}
7246   ins_pipe(fcvtD2F);
7247 %}
7248 
7249 // Convert a double to an int in a float register.
7250 // If the double is a NAN, stuff a zero in instead.
7251 
7252 instruct convD2I_reg_reg(iRegI dst, regD src, regF tmp) %{
7253   match(Set dst (ConvD2I src));
7254   effect( TEMP tmp );
7255   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
7256   format %{ "FTOSIZD  $tmp,$src\n\t"
7257             "FMRS     $dst, $tmp" %}
7258   ins_encode %{
7259     __ ftosizd($tmp$$FloatRegister, $src$$FloatRegister);
7260     __ fmrs($dst$$Register, $tmp$$FloatRegister);
7261   %}
7262   ins_pipe(fcvtD2I);
7263 %}
7264 
7265 // Convert a double to a long in a double register.
7266 // If the double is a NAN, stuff a zero in instead.
7267 
7268 // Double to Long conversion
7269 instruct convD2L_reg(R0R1RegL dst, regD src) %{
7270   match(Set dst (ConvD2L src));
7271   effect(CALL);
7272   ins_cost(MEMORY_REF_COST); // FIXME
7273   format %{ "convD2L    $dst,$src\t ! call to SharedRuntime::d2l" %}
7274   ins_encode %{
7275 #ifndef __ABI_HARD__
7276     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
7277 #else
7278     if ($src$$FloatRegister != D0) {
7279       __ mov_double(D0, $src$$FloatRegister);
7280     }
7281 #endif
7282     address target = CAST_FROM_FN_PTR(address, SharedRuntime::d2l);
7283     __ call(target, relocInfo::runtime_call_type);
7284   %}
7285   ins_pipe(fcvtD2L);
7286 %}
7287 
7288 instruct convF2D_reg(regD dst, regF src) %{
7289   match(Set dst (ConvF2D src));
7290   size(4);
7291   format %{ "FCVTDS  $dst,$src" %}
7292   ins_encode %{
7293     __ convert_f2d($dst$$FloatRegister, $src$$FloatRegister);
7294   %}
7295   ins_pipe(fcvtF2D);
7296 %}
7297 
7298 instruct convF2I_reg_reg(iRegI dst, regF src, regF tmp) %{
7299   match(Set dst (ConvF2I src));
7300   effect( TEMP tmp );
7301   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
7302   size(8);
7303   format %{ "FTOSIZS  $tmp,$src\n\t"
7304             "FMRS     $dst, $tmp" %}
7305   ins_encode %{
7306     __ ftosizs($tmp$$FloatRegister, $src$$FloatRegister);
7307     __ fmrs($dst$$Register, $tmp$$FloatRegister);
7308   %}
7309   ins_pipe(fcvtF2I);
7310 %}
7311 
7312 // Float to Long conversion
7313 instruct convF2L_reg(R0R1RegL dst, regF src, R0RegI arg1) %{
7314   match(Set dst (ConvF2L src));
7315   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
7316   effect(CALL);
7317   format %{ "convF2L  $dst,$src\t! call to SharedRuntime::f2l" %}
7318   ins_encode %{
7319 #ifndef __ABI_HARD__
7320     __ fmrs($arg1$$Register, $src$$FloatRegister);
7321 #else
7322     if($src$$FloatRegister != S0) {
7323       __ mov_float(S0, $src$$FloatRegister);
7324     }
7325 #endif
7326     address target = CAST_FROM_FN_PTR(address, SharedRuntime::f2l);
7327     __ call(target, relocInfo::runtime_call_type);
7328   %}
7329   ins_pipe(fcvtF2L);
7330 %}
7331 
7332 instruct convI2D_reg_reg(iRegI src, regD_low dst) %{
7333   match(Set dst (ConvI2D src));
7334   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
7335   size(8);
7336   format %{ "FMSR     $dst,$src \n\t"
7337             "FSITOD   $dst $dst"%}
7338   ins_encode %{
7339       __ fmsr($dst$$FloatRegister, $src$$Register);
7340       __ fsitod($dst$$FloatRegister, $dst$$FloatRegister);
7341   %}
7342   ins_pipe(fcvtI2D);
7343 %}
7344 
7345 instruct convI2F_reg_reg( regF dst, iRegI src ) %{
7346   match(Set dst (ConvI2F src));
7347   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
7348   size(8);
7349   format %{ "FMSR     $dst,$src \n\t"
7350             "FSITOS   $dst, $dst"%}
7351   ins_encode %{
7352       __ fmsr($dst$$FloatRegister, $src$$Register);
7353       __ fsitos($dst$$FloatRegister, $dst$$FloatRegister);
7354   %}
7355   ins_pipe(fcvtI2F);
7356 %}
7357 
7358 instruct convI2L_reg(iRegL dst, iRegI src) %{
7359   match(Set dst (ConvI2L src));
7360   size(8);
7361   format %{ "MOV    $dst.lo, $src \n\t"
7362             "ASR    $dst.hi,$src,31\t! int->long" %}
7363   ins_encode %{
7364     __ mov($dst$$Register, $src$$Register);
7365     __ mov($dst$$Register->successor(), AsmOperand($src$$Register, asr, 31));
7366   %}
7367   ins_pipe(ialu_reg_reg);
7368 %}
7369 
7370 // Zero-extend convert int to long
7371 instruct convI2L_reg_zex(iRegL dst, iRegI src, immL_32bits mask ) %{
7372   match(Set dst (AndL (ConvI2L src) mask) );
7373   size(8);
7374   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend int to long\n\t"
7375             "MOV    $dst.hi, 0"%}
7376   ins_encode %{
7377     __ mov($dst$$Register, $src$$Register);
7378     __ mov($dst$$Register->successor(), 0);
7379   %}
7380   ins_pipe(ialu_reg_reg);
7381 %}
7382 
7383 // Zero-extend long
7384 instruct zerox_long(iRegL dst, iRegL src, immL_32bits mask ) %{
7385   match(Set dst (AndL src mask) );
7386   size(8);
7387   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend long\n\t"
7388             "MOV    $dst.hi, 0"%}
7389   ins_encode %{
7390     __ mov($dst$$Register, $src$$Register);
7391     __ mov($dst$$Register->successor(), 0);
7392   %}
7393   ins_pipe(ialu_reg_reg);
7394 %}
7395 
7396 instruct MoveF2I_reg_reg(iRegI dst, regF src) %{
7397   match(Set dst (MoveF2I src));
7398   effect(DEF dst, USE src);
7399   ins_cost(MEMORY_REF_COST); // FIXME
7400 
7401   size(4);
7402   format %{ "FMRS   $dst,$src\t! MoveF2I" %}
7403   ins_encode %{
7404     __ fmrs($dst$$Register, $src$$FloatRegister);
7405   %}
7406   ins_pipe(iload_mem); // FIXME
7407 %}
7408 
7409 instruct MoveI2F_reg_reg(regF dst, iRegI src) %{
7410   match(Set dst (MoveI2F src));
7411   ins_cost(MEMORY_REF_COST); // FIXME
7412 
7413   size(4);
7414   format %{ "FMSR   $dst,$src\t! MoveI2F" %}
7415   ins_encode %{
7416     __ fmsr($dst$$FloatRegister, $src$$Register);
7417   %}
7418   ins_pipe(iload_mem); // FIXME
7419 %}
7420 
7421 instruct MoveD2L_reg_reg(iRegL dst, regD src) %{
7422   match(Set dst (MoveD2L src));
7423   effect(DEF dst, USE src);
7424   ins_cost(MEMORY_REF_COST); // FIXME
7425 
7426   size(4);
7427   format %{ "FMRRD    $dst,$src\t! MoveD2L" %}
7428   ins_encode %{
7429     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
7430   %}
7431   ins_pipe(iload_mem); // FIXME
7432 %}
7433 
7434 instruct MoveL2D_reg_reg(regD dst, iRegL src) %{
7435   match(Set dst (MoveL2D src));
7436   effect(DEF dst, USE src);
7437   ins_cost(MEMORY_REF_COST); // FIXME
7438 
7439   size(4);
7440   format %{ "FMDRR   $dst,$src\t! MoveL2D" %}
7441   ins_encode %{
7442     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
7443   %}
7444   ins_pipe(ialu_reg_reg); // FIXME
7445 %}
7446 
7447 //-----------
7448 // Long to Double conversion
7449 
7450 // Magic constant, 0x43300000
7451 instruct loadConI_x43300000(iRegI dst) %{
7452   effect(DEF dst);
7453   size(8);
7454   format %{ "MOV_SLOW  $dst,0x43300000\t! 2^52" %}
7455   ins_encode %{
7456     __ mov_slow($dst$$Register, 0x43300000);
7457   %}
7458   ins_pipe(ialu_none);
7459 %}
7460 
7461 // Magic constant, 0x41f00000
7462 instruct loadConI_x41f00000(iRegI dst) %{
7463   effect(DEF dst);
7464   size(8);
7465   format %{ "MOV_SLOW  $dst, 0x41f00000\t! 2^32" %}
7466   ins_encode %{
7467     __ mov_slow($dst$$Register, 0x41f00000);
7468   %}
7469   ins_pipe(ialu_none);
7470 %}
7471 
7472 instruct loadConI_x0(iRegI dst) %{
7473   effect(DEF dst);
7474   size(4);
7475   format %{ "MOV  $dst, 0x0\t! 0" %}
7476   ins_encode %{
7477     __ mov($dst$$Register, 0);
7478   %}
7479   ins_pipe(ialu_none);
7480 %}
7481 
7482 // Construct a double from two float halves
7483 instruct regDHi_regDLo_to_regD(regD_low dst, regD_low src1, regD_low src2) %{
7484   effect(DEF dst, USE src1, USE src2);
7485   size(8);
7486   format %{ "FCPYS  $dst.hi,$src1.hi\n\t"
7487             "FCPYS  $dst.lo,$src2.lo" %}
7488   ins_encode %{
7489     __ fcpys($dst$$FloatRegister->successor(), $src1$$FloatRegister->successor());
7490     __ fcpys($dst$$FloatRegister, $src2$$FloatRegister);
7491   %}
7492   ins_pipe(faddD_reg_reg);
7493 %}
7494 
7495 // Convert integer in high half of a double register (in the lower half of
7496 // the double register file) to double
7497 instruct convI2D_regDHi_regD(regD dst, regD_low src) %{
7498   effect(DEF dst, USE src);
7499   size(4);
7500   format %{ "FSITOD  $dst,$src" %}
7501   ins_encode %{
7502     __ fsitod($dst$$FloatRegister, $src$$FloatRegister->successor());
7503   %}
7504   ins_pipe(fcvtLHi2D);
7505 %}
7506 
7507 // Add float double precision
7508 instruct addD_regD_regD(regD dst, regD src1, regD src2) %{
7509   effect(DEF dst, USE src1, USE src2);
7510   size(4);
7511   format %{ "FADDD  $dst,$src1,$src2" %}
7512   ins_encode %{
7513     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
7514   %}
7515   ins_pipe(faddD_reg_reg);
7516 %}
7517 
7518 // Sub float double precision
7519 instruct subD_regD_regD(regD dst, regD src1, regD src2) %{
7520   effect(DEF dst, USE src1, USE src2);
7521   size(4);
7522   format %{ "FSUBD  $dst,$src1,$src2" %}
7523   ins_encode %{
7524     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
7525   %}
7526   ins_pipe(faddD_reg_reg);
7527 %}
7528 
7529 // Mul float double precision
7530 instruct mulD_regD_regD(regD dst, regD src1, regD src2) %{
7531   effect(DEF dst, USE src1, USE src2);
7532   size(4);
7533   format %{ "FMULD  $dst,$src1,$src2" %}
7534   ins_encode %{
7535     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
7536   %}
7537   ins_pipe(fmulD_reg_reg);
7538 %}
7539 
7540 instruct regL_to_regD(regD dst, iRegL src) %{
7541   // No match rule to avoid chain rule match.
7542   effect(DEF dst, USE src);
7543   ins_cost(MEMORY_REF_COST);
7544   size(4);
7545   format %{ "FMDRR   $dst,$src\t! regL to regD" %}
7546   ins_encode %{
7547     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
7548   %}
7549   ins_pipe(ialu_reg_reg); // FIXME
7550 %}
7551 
7552 instruct regI_regI_to_regD(regD dst, iRegI src1, iRegI src2) %{
7553   // No match rule to avoid chain rule match.
7554   effect(DEF dst, USE src1, USE src2);
7555   ins_cost(MEMORY_REF_COST);
7556   size(4);
7557   format %{ "FMDRR   $dst,$src1,$src2\t! regI,regI to regD" %}
7558   ins_encode %{
7559     __ fmdrr($dst$$FloatRegister, $src1$$Register, $src2$$Register);
7560   %}
7561   ins_pipe(ialu_reg_reg); // FIXME
7562 %}
7563 
7564 instruct convL2D_reg_slow_fxtof(regD dst, iRegL src) %{
7565   match(Set dst (ConvL2D src));
7566   ins_cost(DEFAULT_COST*8 + MEMORY_REF_COST*6); // FIXME
7567 
7568   expand %{
7569     regD_low   tmpsrc;
7570     iRegI      ix43300000;
7571     iRegI      ix41f00000;
7572     iRegI      ix0;
7573     regD_low   dx43300000;
7574     regD       dx41f00000;
7575     regD       tmp1;
7576     regD_low   tmp2;
7577     regD       tmp3;
7578     regD       tmp4;
7579 
7580     regL_to_regD(tmpsrc, src);
7581 
7582     loadConI_x43300000(ix43300000);
7583     loadConI_x41f00000(ix41f00000);
7584     loadConI_x0(ix0);
7585 
7586     regI_regI_to_regD(dx43300000, ix0, ix43300000);
7587     regI_regI_to_regD(dx41f00000, ix0, ix41f00000);
7588 
7589     convI2D_regDHi_regD(tmp1, tmpsrc);
7590     regDHi_regDLo_to_regD(tmp2, dx43300000, tmpsrc);
7591     subD_regD_regD(tmp3, tmp2, dx43300000);
7592     mulD_regD_regD(tmp4, tmp1, dx41f00000);
7593     addD_regD_regD(dst, tmp3, tmp4);
7594   %}
7595 %}
7596 
7597 instruct convL2I_reg(iRegI dst, iRegL src) %{
7598   match(Set dst (ConvL2I src));
7599   size(4);
7600   format %{ "MOV    $dst,$src.lo\t! long->int" %}
7601   ins_encode %{
7602     __ mov($dst$$Register, $src$$Register);
7603   %}
7604   ins_pipe(ialu_move_reg_I_to_L);
7605 %}
7606 
7607 // Register Shift Right Immediate
7608 instruct shrL_reg_imm6_L2I(iRegI dst, iRegL src, immI_32_63 cnt) %{
7609   match(Set dst (ConvL2I (RShiftL src cnt)));
7610   size(4);
7611   format %{ "ASR    $dst,$src.hi,($cnt - 32)\t! long->int or mov if $cnt==32" %}
7612   ins_encode %{
7613     if ($cnt$$constant == 32) {
7614       __ mov($dst$$Register, $src$$Register->successor());
7615     } else {
7616       __ mov($dst$$Register, AsmOperand($src$$Register->successor(), asr, $cnt$$constant - 32));
7617     }
7618   %}
7619   ins_pipe(ialu_reg_imm);
7620 %}
7621 
7622 
7623 //----------Control Flow Instructions------------------------------------------
7624 // Compare Instructions
7625 // Compare Integers
7626 instruct compI_iReg(flagsReg icc, iRegI op1, iRegI op2) %{
7627   match(Set icc (CmpI op1 op2));
7628   effect( DEF icc, USE op1, USE op2 );
7629 
7630   size(4);
7631   format %{ "cmp_32 $op1,$op2\t! int" %}
7632   ins_encode %{
7633     __ cmp_32($op1$$Register, $op2$$Register);
7634   %}
7635   ins_pipe(ialu_cconly_reg_reg);
7636 %}
7637 
7638 #ifdef _LP64
7639 // Compare compressed pointers
7640 instruct compN_reg2(flagsRegU icc, iRegN op1, iRegN op2) %{
7641   match(Set icc (CmpN op1 op2));
7642   effect( DEF icc, USE op1, USE op2 );
7643 
7644   size(4);
7645   format %{ "cmp_32 $op1,$op2\t! int" %}
7646   ins_encode %{
7647     __ cmp_32($op1$$Register, $op2$$Register);
7648   %}
7649   ins_pipe(ialu_cconly_reg_reg);
7650 %}
7651 #endif
7652 
7653 instruct compU_iReg(flagsRegU icc, iRegI op1, iRegI op2) %{
7654   match(Set icc (CmpU op1 op2));
7655 
7656   size(4);
7657   format %{ "cmp_32 $op1,$op2\t! unsigned int" %}
7658   ins_encode %{
7659     __ cmp_32($op1$$Register, $op2$$Register);
7660   %}
7661   ins_pipe(ialu_cconly_reg_reg);
7662 %}
7663 
7664 instruct compI_iReg_immneg(flagsReg icc, iRegI op1, aimmIneg op2) %{
7665   match(Set icc (CmpI op1 op2));
7666   effect( DEF icc, USE op1 );
7667 
7668   size(4);
7669   format %{ "cmn_32 $op1,-$op2\t! int" %}
7670   ins_encode %{
7671     __ cmn_32($op1$$Register, -$op2$$constant);
7672   %}
7673   ins_pipe(ialu_cconly_reg_imm);
7674 %}
7675 
7676 instruct compI_iReg_imm(flagsReg icc, iRegI op1, aimmI op2) %{
7677   match(Set icc (CmpI op1 op2));
7678   effect( DEF icc, USE op1 );
7679 
7680   size(4);
7681   format %{ "cmp_32 $op1,$op2\t! int" %}
7682   ins_encode %{
7683     __ cmp_32($op1$$Register, $op2$$constant);
7684   %}
7685   ins_pipe(ialu_cconly_reg_imm);
7686 %}
7687 
7688 instruct testI_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immI0 zero ) %{
7689   match(Set icc (CmpI (AndI op1 op2) zero));
7690   size(4);
7691   format %{ "tst_32 $op2,$op1" %}
7692 
7693   ins_encode %{
7694     __ tst_32($op1$$Register, $op2$$Register);
7695   %}
7696   ins_pipe(ialu_cconly_reg_reg_zero);
7697 %}
7698 
7699 instruct testshlI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
7700   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
7701   size(4);
7702   format %{ "TST   $op2,$op1<<$op3" %}
7703 
7704   ins_encode %{
7705     __ tst($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$Register));
7706   %}
7707   ins_pipe(ialu_cconly_reg_reg_zero);
7708 %}
7709 
7710 instruct testshlI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
7711   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
7712   size(4);
7713   format %{ "tst_32 $op2,$op1<<$op3" %}
7714 
7715   ins_encode %{
7716     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$constant));
7717   %}
7718   ins_pipe(ialu_cconly_reg_reg_zero);
7719 %}
7720 
7721 instruct testsarI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
7722   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
7723   size(4);
7724   format %{ "TST   $op2,$op1<<$op3" %}
7725 
7726   ins_encode %{
7727     __ tst($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$Register));
7728   %}
7729   ins_pipe(ialu_cconly_reg_reg_zero);
7730 %}
7731 
7732 instruct testsarI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
7733   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
7734   size(4);
7735   format %{ "tst_32 $op2,$op1<<$op3" %}
7736 
7737   ins_encode %{
7738     __ tst_32($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$constant));
7739   %}
7740   ins_pipe(ialu_cconly_reg_reg_zero);
7741 %}
7742 
7743 instruct testshrI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
7744   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
7745   size(4);
7746   format %{ "TST   $op2,$op1<<$op3" %}
7747 
7748   ins_encode %{
7749     __ tst($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$Register));
7750   %}
7751   ins_pipe(ialu_cconly_reg_reg_zero);
7752 %}
7753 
7754 instruct testshrI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
7755   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
7756   size(4);
7757   format %{ "tst_32 $op2,$op1<<$op3" %}
7758 
7759   ins_encode %{
7760     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$constant));
7761   %}
7762   ins_pipe(ialu_cconly_reg_reg_zero);
7763 %}
7764 
7765 instruct testI_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, limmI op2, immI0 zero ) %{
7766   match(Set icc (CmpI (AndI op1 op2) zero));
7767   size(4);
7768   format %{ "tst_32 $op2,$op1" %}
7769 
7770   ins_encode %{
7771     __ tst_32($op1$$Register, $op2$$constant);
7772   %}
7773   ins_pipe(ialu_cconly_reg_imm_zero);
7774 %}
7775 
7776 instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
7777   match(Set xcc (CmpL op1 op2));
7778   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
7779 
7780   size(8);
7781   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! long\n\t"
7782             "SBCS    $tmp,$op1.hi,$op2.hi" %}
7783   ins_encode %{
7784     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
7785     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
7786   %}
7787   ins_pipe(ialu_cconly_reg_reg);
7788 %}
7789 
7790 instruct compUL_reg_reg_LTGE(flagsRegUL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
7791   match(Set xcc (CmpUL op1 op2));
7792   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
7793 
7794   size(8);
7795   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! unsigned long\n\t"
7796             "SBCS    $tmp,$op1.hi,$op2.hi" %}
7797   ins_encode %{
7798     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
7799     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
7800   %}
7801   ins_pipe(ialu_cconly_reg_reg);
7802 %}
7803 
7804 instruct compL_reg_reg_EQNE(flagsRegL_EQNE xcc, iRegL op1, iRegL op2) %{
7805   match(Set xcc (CmpL op1 op2));
7806   effect( DEF xcc, USE op1, USE op2 );
7807 
7808   size(8);
7809   format %{ "TEQ    $op1.hi,$op2.hi\t\t! long\n\t"
7810             "TEQ.eq $op1.lo,$op2.lo" %}
7811   ins_encode %{
7812     __ teq($op1$$Register->successor(), $op2$$Register->successor());
7813     __ teq($op1$$Register, $op2$$Register, eq);
7814   %}
7815   ins_pipe(ialu_cconly_reg_reg);
7816 %}
7817 
7818 instruct compL_reg_reg_LEGT(flagsRegL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
7819   match(Set xcc (CmpL op1 op2));
7820   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
7821 
7822   size(8);
7823   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! long\n\t"
7824             "SBCS    $tmp,$op2.hi,$op1.hi" %}
7825   ins_encode %{
7826     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
7827     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
7828   %}
7829   ins_pipe(ialu_cconly_reg_reg);
7830 %}
7831 
7832 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7833 // (hi($con$$constant), lo($con$$constant)) becomes
7834 instruct compL_reg_con_LTGE(flagsRegL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
7835   match(Set xcc (CmpL op1 con));
7836   effect( DEF xcc, USE op1, USE con, TEMP tmp );
7837 
7838   size(8);
7839   format %{ "SUBS    $tmp,$op1.low,$con\t\t! long\n\t"
7840             "SBCS    $tmp,$op1.hi,0" %}
7841   ins_encode %{
7842     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
7843     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
7844   %}
7845 
7846   ins_pipe(ialu_cconly_reg_reg);
7847 %}
7848 
7849 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7850 // (hi($con$$constant), lo($con$$constant)) becomes
7851 instruct compL_reg_con_EQNE(flagsRegL_EQNE xcc, iRegL op1, immLlowRot con) %{
7852   match(Set xcc (CmpL op1 con));
7853   effect( DEF xcc, USE op1, USE con );
7854 
7855   size(8);
7856   format %{ "TEQ    $op1.hi,0\t\t! long\n\t"
7857             "TEQ.eq $op1.lo,$con" %}
7858   ins_encode %{
7859     __ teq($op1$$Register->successor(), 0);
7860     __ teq($op1$$Register, $con$$constant, eq);
7861   %}
7862 
7863   ins_pipe(ialu_cconly_reg_reg);
7864 %}
7865 
7866 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7867 // (hi($con$$constant), lo($con$$constant)) becomes
7868 instruct compL_reg_con_LEGT(flagsRegL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
7869   match(Set xcc (CmpL op1 con));
7870   effect( DEF xcc, USE op1, USE con, TEMP tmp );
7871 
7872   size(8);
7873   format %{ "RSBS    $tmp,$op1.low,$con\t\t! long\n\t"
7874             "RSCS    $tmp,$op1.hi,0" %}
7875   ins_encode %{
7876     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
7877     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
7878   %}
7879 
7880   ins_pipe(ialu_cconly_reg_reg);
7881 %}
7882 
7883 instruct compUL_reg_reg_EQNE(flagsRegUL_EQNE xcc, iRegL op1, iRegL op2) %{
7884   match(Set xcc (CmpUL op1 op2));
7885   effect(DEF xcc, USE op1, USE op2);
7886 
7887   size(8);
7888   format %{ "TEQ    $op1.hi,$op2.hi\t\t! unsigned long\n\t"
7889             "TEQ.eq $op1.lo,$op2.lo" %}
7890   ins_encode %{
7891     __ teq($op1$$Register->successor(), $op2$$Register->successor());
7892     __ teq($op1$$Register, $op2$$Register, eq);
7893   %}
7894   ins_pipe(ialu_cconly_reg_reg);
7895 %}
7896 
7897 instruct compUL_reg_reg_LEGT(flagsRegUL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
7898   match(Set xcc (CmpUL op1 op2));
7899   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
7900 
7901   size(8);
7902   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! unsigned long\n\t"
7903             "SBCS    $tmp,$op2.hi,$op1.hi" %}
7904   ins_encode %{
7905     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
7906     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
7907   %}
7908   ins_pipe(ialu_cconly_reg_reg);
7909 %}
7910 
7911 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7912 // (hi($con$$constant), lo($con$$constant)) becomes
7913 instruct compUL_reg_con_LTGE(flagsRegUL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
7914   match(Set xcc (CmpUL op1 con));
7915   effect(DEF xcc, USE op1, USE con, TEMP tmp);
7916 
7917   size(8);
7918   format %{ "SUBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
7919             "SBCS    $tmp,$op1.hi,0" %}
7920   ins_encode %{
7921     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
7922     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
7923   %}
7924 
7925   ins_pipe(ialu_cconly_reg_reg);
7926 %}
7927 
7928 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7929 // (hi($con$$constant), lo($con$$constant)) becomes
7930 instruct compUL_reg_con_EQNE(flagsRegUL_EQNE xcc, iRegL op1, immLlowRot con) %{
7931   match(Set xcc (CmpUL op1 con));
7932   effect(DEF xcc, USE op1, USE con);
7933 
7934   size(8);
7935   format %{ "TEQ    $op1.hi,0\t\t! unsigned long\n\t"
7936             "TEQ.eq $op1.lo,$con" %}
7937   ins_encode %{
7938     __ teq($op1$$Register->successor(), 0);
7939     __ teq($op1$$Register, $con$$constant, eq);
7940   %}
7941 
7942   ins_pipe(ialu_cconly_reg_reg);
7943 %}
7944 
7945 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7946 // (hi($con$$constant), lo($con$$constant)) becomes
7947 instruct compUL_reg_con_LEGT(flagsRegUL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
7948   match(Set xcc (CmpUL op1 con));
7949   effect(DEF xcc, USE op1, USE con, TEMP tmp);
7950 
7951   size(8);
7952   format %{ "RSBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
7953             "RSCS    $tmp,$op1.hi,0" %}
7954   ins_encode %{
7955     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
7956     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
7957   %}
7958 
7959   ins_pipe(ialu_cconly_reg_reg);
7960 %}
7961 
7962 /* instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ */
7963 /*   match(Set xcc (CmpL (AndL op1 op2) zero)); */
7964 /*   ins_encode %{ */
7965 /*     __ stop("testL_reg_reg unimplemented"); */
7966 /*   %} */
7967 /*   ins_pipe(ialu_cconly_reg_reg); */
7968 /* %} */
7969 
7970 /* // useful for checking the alignment of a pointer: */
7971 /* instruct testL_reg_con(flagsRegL xcc, iRegL op1, immLlowRot con, immL0 zero) %{ */
7972 /*   match(Set xcc (CmpL (AndL op1 con) zero)); */
7973 /*   ins_encode %{ */
7974 /*     __ stop("testL_reg_con unimplemented"); */
7975 /*   %} */
7976 /*   ins_pipe(ialu_cconly_reg_reg); */
7977 /* %} */
7978 
7979 instruct compU_iReg_imm(flagsRegU icc, iRegI op1, aimmU31 op2 ) %{
7980   match(Set icc (CmpU op1 op2));
7981 
7982   size(4);
7983   format %{ "cmp_32 $op1,$op2\t! unsigned" %}
7984   ins_encode %{
7985     __ cmp_32($op1$$Register, $op2$$constant);
7986   %}
7987   ins_pipe(ialu_cconly_reg_imm);
7988 %}
7989 
7990 // Compare Pointers
7991 instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{
7992   match(Set pcc (CmpP op1 op2));
7993 
7994   size(4);
7995   format %{ "CMP    $op1,$op2\t! ptr" %}
7996   ins_encode %{
7997     __ cmp($op1$$Register, $op2$$Register);
7998   %}
7999   ins_pipe(ialu_cconly_reg_reg);
8000 %}
8001 
8002 instruct compP_iRegP_imm(flagsRegP pcc, iRegP op1, aimmP op2 ) %{
8003   match(Set pcc (CmpP op1 op2));
8004 
8005   size(4);
8006   format %{ "CMP    $op1,$op2\t! ptr" %}
8007   ins_encode %{
8008     assert($op2$$constant == 0 || _opnds[2]->constant_reloc() == relocInfo::none, "reloc in cmp?");
8009     __ cmp($op1$$Register, $op2$$constant);
8010   %}
8011   ins_pipe(ialu_cconly_reg_imm);
8012 %}
8013 
8014 //----------Max and Min--------------------------------------------------------
8015 // Min Instructions
8016 // Conditional move for min
8017 instruct cmovI_reg_lt( iRegI op2, iRegI op1, flagsReg icc ) %{
8018   effect( USE_DEF op2, USE op1, USE icc );
8019 
8020   size(4);
8021   format %{ "MOV.lt  $op2,$op1\t! min" %}
8022   ins_encode %{
8023     __ mov($op2$$Register, $op1$$Register, lt);
8024   %}
8025   ins_pipe(ialu_reg_flags);
8026 %}
8027 
8028 // Min Register with Register.
8029 instruct minI_eReg(iRegI op1, iRegI op2) %{
8030   match(Set op2 (MinI op1 op2));
8031   ins_cost(DEFAULT_COST*2);
8032   expand %{
8033     flagsReg icc;
8034     compI_iReg(icc,op1,op2);
8035     cmovI_reg_lt(op2,op1,icc);
8036   %}
8037 %}
8038 
8039 // Max Instructions
8040 // Conditional move for max
8041 instruct cmovI_reg_gt( iRegI op2, iRegI op1, flagsReg icc ) %{
8042   effect( USE_DEF op2, USE op1, USE icc );
8043   format %{ "MOV.gt  $op2,$op1\t! max" %}
8044   ins_encode %{
8045     __ mov($op2$$Register, $op1$$Register, gt);
8046   %}
8047   ins_pipe(ialu_reg_flags);
8048 %}
8049 
8050 // Max Register with Register
8051 instruct maxI_eReg(iRegI op1, iRegI op2) %{
8052   match(Set op2 (MaxI op1 op2));
8053   ins_cost(DEFAULT_COST*2);
8054   expand %{
8055     flagsReg icc;
8056     compI_iReg(icc,op1,op2);
8057     cmovI_reg_gt(op2,op1,icc);
8058   %}
8059 %}
8060 
8061 
8062 //----------Float Compares----------------------------------------------------
8063 // Compare floating, generate condition code
8064 instruct cmpF_cc(flagsRegF fcc, flagsReg icc, regF src1, regF src2) %{
8065   match(Set icc (CmpF src1 src2));
8066   effect(KILL fcc);
8067 
8068   size(8);
8069   format %{ "FCMPs  $src1,$src2\n\t"
8070             "FMSTAT" %}
8071   ins_encode %{
8072     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
8073     __ fmstat();
8074   %}
8075   ins_pipe(faddF_fcc_reg_reg_zero);
8076 %}
8077 
8078 instruct cmpF0_cc(flagsRegF fcc, flagsReg icc, regF src1, immF0 src2) %{
8079   match(Set icc (CmpF src1 src2));
8080   effect(KILL fcc);
8081 
8082   size(8);
8083   format %{ "FCMPs  $src1,$src2\n\t"
8084             "FMSTAT" %}
8085   ins_encode %{
8086     __ fcmpzs($src1$$FloatRegister);
8087     __ fmstat();
8088   %}
8089   ins_pipe(faddF_fcc_reg_reg_zero);
8090 %}
8091 
8092 instruct cmpD_cc(flagsRegF fcc, flagsReg icc, regD src1, regD src2) %{
8093   match(Set icc (CmpD src1 src2));
8094   effect(KILL fcc);
8095 
8096   size(8);
8097   format %{ "FCMPd  $src1,$src2 \n\t"
8098             "FMSTAT" %}
8099   ins_encode %{
8100     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
8101     __ fmstat();
8102   %}
8103   ins_pipe(faddD_fcc_reg_reg_zero);
8104 %}
8105 
8106 instruct cmpD0_cc(flagsRegF fcc, flagsReg icc, regD src1, immD0 src2) %{
8107   match(Set icc (CmpD src1 src2));
8108   effect(KILL fcc);
8109 
8110   size(8);
8111   format %{ "FCMPZd  $src1,$src2 \n\t"
8112             "FMSTAT" %}
8113   ins_encode %{
8114     __ fcmpzd($src1$$FloatRegister);
8115     __ fmstat();
8116   %}
8117   ins_pipe(faddD_fcc_reg_reg_zero);
8118 %}
8119 
8120 // Compare floating, generate -1,0,1
8121 instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsRegF fcc) %{
8122   match(Set dst (CmpF3 src1 src2));
8123   effect(KILL fcc);
8124   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
8125   size(20);
8126   // same number of instructions as code using conditional moves but
8127   // doesn't kill integer condition register
8128   format %{ "FCMPs  $dst,$src1,$src2 \n\t"
8129             "VMRS   $dst, FPSCR \n\t"
8130             "OR     $dst, $dst, 0x08000000 \n\t"
8131             "EOR    $dst, $dst, $dst << 3 \n\t"
8132             "MOV    $dst, $dst >> 30" %}
8133   ins_encode %{
8134     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
8135     __ floating_cmp($dst$$Register);
8136   %}
8137   ins_pipe( floating_cmp );
8138 %}
8139 
8140 instruct cmpF0_reg(iRegI dst, regF src1, immF0 src2, flagsRegF fcc) %{
8141   match(Set dst (CmpF3 src1 src2));
8142   effect(KILL fcc);
8143   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
8144   size(20);
8145   // same number of instructions as code using conditional moves but
8146   // doesn't kill integer condition register
8147   format %{ "FCMPZs $dst,$src1,$src2 \n\t"
8148             "VMRS   $dst, FPSCR \n\t"
8149             "OR     $dst, $dst, 0x08000000 \n\t"
8150             "EOR    $dst, $dst, $dst << 3 \n\t"
8151             "MOV    $dst, $dst >> 30" %}
8152   ins_encode %{
8153     __ fcmpzs($src1$$FloatRegister);
8154     __ floating_cmp($dst$$Register);
8155   %}
8156   ins_pipe( floating_cmp );
8157 %}
8158 
8159 instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsRegF fcc) %{
8160   match(Set dst (CmpD3 src1 src2));
8161   effect(KILL fcc);
8162   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
8163   size(20);
8164   // same number of instructions as code using conditional moves but
8165   // doesn't kill integer condition register
8166   format %{ "FCMPd  $dst,$src1,$src2 \n\t"
8167             "VMRS   $dst, FPSCR \n\t"
8168             "OR     $dst, $dst, 0x08000000 \n\t"
8169             "EOR    $dst, $dst, $dst << 3 \n\t"
8170             "MOV    $dst, $dst >> 30" %}
8171   ins_encode %{
8172     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
8173     __ floating_cmp($dst$$Register);
8174   %}
8175   ins_pipe( floating_cmp );
8176 %}
8177 
8178 instruct cmpD0_reg(iRegI dst, regD src1, immD0 src2, flagsRegF fcc) %{
8179   match(Set dst (CmpD3 src1 src2));
8180   effect(KILL fcc);
8181   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
8182   size(20);
8183   // same number of instructions as code using conditional moves but
8184   // doesn't kill integer condition register
8185   format %{ "FCMPZd $dst,$src1,$src2 \n\t"
8186             "VMRS   $dst, FPSCR \n\t"
8187             "OR     $dst, $dst, 0x08000000 \n\t"
8188             "EOR    $dst, $dst, $dst << 3 \n\t"
8189             "MOV    $dst, $dst >> 30" %}
8190   ins_encode %{
8191     __ fcmpzd($src1$$FloatRegister);
8192     __ floating_cmp($dst$$Register);
8193   %}
8194   ins_pipe( floating_cmp );
8195 %}
8196 
8197 //----------Branches---------------------------------------------------------
8198 // Jump
8199 // (compare 'operand indIndex' and 'instruct addP_reg_reg' above)
8200 // FIXME
8201 instruct jumpXtnd(iRegX switch_val, iRegP tmp) %{
8202   match(Jump switch_val);
8203   effect(TEMP tmp);
8204   ins_cost(350);
8205   format %{  "ADD    $tmp, $constanttablebase, $switch_val\n\t"
8206              "LDR    $tmp,[$tmp + $constantoffset]\n\t"
8207              "BX     $tmp" %}
8208   size(20);
8209   ins_encode %{
8210     Register table_reg;
8211     Register label_reg = $tmp$$Register;
8212     if (constant_offset() == 0) {
8213       table_reg = $constanttablebase;
8214       __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
8215     } else {
8216       table_reg = $tmp$$Register;
8217       int offset = $constantoffset;
8218       if (is_memoryP(offset)) {
8219         __ add(table_reg, $constanttablebase, $switch_val$$Register);
8220         __ ldr(label_reg, Address(table_reg, offset));
8221       } else {
8222         __ mov_slow(table_reg, $constantoffset);
8223         __ add(table_reg, $constanttablebase, table_reg);
8224         __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
8225       }
8226     }
8227     __ jump(label_reg); // ldr + b better than ldr to PC for branch predictor?
8228     //    __ ldr(PC, Address($table$$Register, $switch_val$$Register));
8229   %}
8230   ins_pipe(ialu_reg_reg);
8231 %}
8232 
8233 // // Direct Branch.
8234 instruct branch(label labl) %{
8235   match(Goto);
8236   effect(USE labl);
8237 
8238   size(4);
8239   ins_cost(BRANCH_COST);
8240   format %{ "B     $labl" %}
8241   ins_encode %{
8242     __ b(*($labl$$label));
8243   %}
8244   ins_pipe(br);
8245 %}
8246 
8247 // Conditional Direct Branch
8248 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{
8249   match(If cmp icc);
8250   effect(USE labl);
8251 
8252   size(4);
8253   ins_cost(BRANCH_COST);
8254   format %{ "B$cmp   $icc,$labl" %}
8255   ins_encode %{
8256     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8257   %}
8258   ins_pipe(br_cc);
8259 %}
8260 
8261 #ifdef ARM
8262 instruct branchCon_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, label labl) %{
8263   match(If cmp icc);
8264   effect(USE labl);
8265   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
8266 
8267   size(4);
8268   ins_cost(BRANCH_COST);
8269   format %{ "B$cmp   $icc,$labl" %}
8270   ins_encode %{
8271     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8272   %}
8273   ins_pipe(br_cc);
8274 %}
8275 #endif
8276 
8277 
8278 instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{
8279   match(If cmp icc);
8280   effect(USE labl);
8281 
8282   size(4);
8283   ins_cost(BRANCH_COST);
8284   format %{ "B$cmp  $icc,$labl" %}
8285   ins_encode %{
8286     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8287   %}
8288   ins_pipe(br_cc);
8289 %}
8290 
8291 instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{
8292   match(If cmp pcc);
8293   effect(USE labl);
8294 
8295   size(4);
8296   ins_cost(BRANCH_COST);
8297   format %{ "B$cmp  $pcc,$labl" %}
8298   ins_encode %{
8299     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8300   %}
8301   ins_pipe(br_cc);
8302 %}
8303 
8304 instruct branchConL_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, label labl) %{
8305   match(If cmp xcc);
8306   effect(USE labl);
8307   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8308 
8309   size(4);
8310   ins_cost(BRANCH_COST);
8311   format %{ "B$cmp  $xcc,$labl" %}
8312   ins_encode %{
8313     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8314   %}
8315   ins_pipe(br_cc);
8316 %}
8317 
8318 instruct branchConL_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, label labl) %{
8319   match(If cmp xcc);
8320   effect(USE labl);
8321   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8322 
8323   size(4);
8324   ins_cost(BRANCH_COST);
8325   format %{ "B$cmp  $xcc,$labl" %}
8326   ins_encode %{
8327     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8328   %}
8329   ins_pipe(br_cc);
8330 %}
8331 
8332 instruct branchConL_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, label labl) %{
8333   match(If cmp xcc);
8334   effect(USE labl);
8335   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le );
8336 
8337   size(4);
8338   ins_cost(BRANCH_COST);
8339   format %{ "B$cmp  $xcc,$labl" %}
8340   ins_encode %{
8341     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8342   %}
8343   ins_pipe(br_cc);
8344 %}
8345 
8346 instruct branchConUL_LTGE(cmpOpUL cmp, flagsRegUL_LTGE xcc, label labl) %{
8347   match(If cmp xcc);
8348   effect(USE labl);
8349   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
8350 
8351   size(4);
8352   ins_cost(BRANCH_COST);
8353   format %{ "B$cmp  $xcc,$labl" %}
8354   ins_encode %{
8355     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8356   %}
8357   ins_pipe(br_cc);
8358 %}
8359 
8360 instruct branchConUL_EQNE(cmpOpUL cmp, flagsRegUL_EQNE xcc, label labl) %{
8361   match(If cmp xcc);
8362   effect(USE labl);
8363   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
8364 
8365   size(4);
8366   ins_cost(BRANCH_COST);
8367   format %{ "B$cmp  $xcc,$labl" %}
8368   ins_encode %{
8369     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8370   %}
8371   ins_pipe(br_cc);
8372 %}
8373 
8374 instruct branchConUL_LEGT(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, label labl) %{
8375   match(If cmp xcc);
8376   effect(USE labl);
8377   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le);
8378 
8379   size(4);
8380   ins_cost(BRANCH_COST);
8381   format %{ "B$cmp  $xcc,$labl" %}
8382   ins_encode %{
8383     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8384   %}
8385   ins_pipe(br_cc);
8386 %}
8387 
8388 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
8389   match(CountedLoopEnd cmp icc);
8390   effect(USE labl);
8391 
8392   size(4);
8393   ins_cost(BRANCH_COST);
8394   format %{ "B$cmp   $icc,$labl\t! Loop end" %}
8395   ins_encode %{
8396     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8397   %}
8398   ins_pipe(br_cc);
8399 %}
8400 
8401 // instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{
8402 //   match(CountedLoopEnd cmp icc);
8403 //   ins_pipe(br_cc);
8404 // %}
8405 
8406 // ============================================================================
8407 // Long Compare
8408 //
8409 // Currently we hold longs in 2 registers.  Comparing such values efficiently
8410 // is tricky.  The flavor of compare used depends on whether we are testing
8411 // for LT, LE, or EQ.  For a simple LT test we can check just the sign bit.
8412 // The GE test is the negated LT test.  The LE test can be had by commuting
8413 // the operands (yielding a GE test) and then negating; negate again for the
8414 // GT test.  The EQ test is done by ORcc'ing the high and low halves, and the
8415 // NE test is negated from that.
8416 
8417 // Due to a shortcoming in the ADLC, it mixes up expressions like:
8418 // (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)).  Note the
8419 // difference between 'Y' and '0L'.  The tree-matches for the CmpI sections
8420 // are collapsed internally in the ADLC's dfa-gen code.  The match for
8421 // (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the
8422 // foo match ends up with the wrong leaf.  One fix is to not match both
8423 // reg-reg and reg-zero forms of long-compare.  This is unfortunate because
8424 // both forms beat the trinary form of long-compare and both are very useful
8425 // on Intel which has so few registers.
8426 
8427 // instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{
8428 //   match(If cmp xcc);
8429 //   ins_pipe(br_cc);
8430 // %}
8431 
8432 // Manifest a CmpL3 result in an integer register.  Very painful.
8433 // This is the test to avoid.
8434 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
8435   match(Set dst (CmpL3 src1 src2) );
8436   effect( KILL ccr );
8437   ins_cost(6*DEFAULT_COST); // FIXME
8438   size(32);
8439   format %{
8440       "CMP    $src1.hi, $src2.hi\t\t! long\n"
8441     "\tMOV.gt $dst, 1\n"
8442     "\tmvn.lt $dst, 0\n"
8443     "\tB.ne   done\n"
8444     "\tSUBS   $dst, $src1.lo, $src2.lo\n"
8445     "\tMOV.hi $dst, 1\n"
8446     "\tmvn.lo $dst, 0\n"
8447     "done:"     %}
8448   ins_encode %{
8449     Label done;
8450     __ cmp($src1$$Register->successor(), $src2$$Register->successor());
8451     __ mov($dst$$Register, 1, gt);
8452     __ mvn($dst$$Register, 0, lt);
8453     __ b(done, ne);
8454     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
8455     __ mov($dst$$Register, 1, hi);
8456     __ mvn($dst$$Register, 0, lo);
8457     __ bind(done);
8458   %}
8459   ins_pipe(cmpL_reg);
8460 %}
8461 
8462 // Conditional move
8463 instruct cmovLL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, iRegL src) %{
8464   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
8465   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8466 
8467   ins_cost(150);
8468   size(8);
8469   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
8470             "MOV$cmp  $dst,$src.hi" %}
8471   ins_encode %{
8472     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8473     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
8474   %}
8475   ins_pipe(ialu_reg);
8476 %}
8477 
8478 instruct cmovLL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, iRegL src) %{
8479   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
8480   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8481 
8482   ins_cost(150);
8483   size(8);
8484   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
8485             "MOV$cmp  $dst,$src.hi" %}
8486   ins_encode %{
8487     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8488     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
8489   %}
8490   ins_pipe(ialu_reg);
8491 %}
8492 
8493 instruct cmovLL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, iRegL src) %{
8494   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
8495   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8496 
8497   ins_cost(150);
8498   size(8);
8499   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
8500             "MOV$cmp  $dst,$src.hi" %}
8501   ins_encode %{
8502     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8503     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
8504   %}
8505   ins_pipe(ialu_reg);
8506 %}
8507 
8508 instruct cmovLL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, immL0 src) %{
8509   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
8510   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8511   ins_cost(140);
8512   size(8);
8513   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
8514             "MOV$cmp  $dst,0" %}
8515   ins_encode %{
8516     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
8517     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
8518   %}
8519   ins_pipe(ialu_imm);
8520 %}
8521 
8522 instruct cmovLL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, immL0 src) %{
8523   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
8524   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8525   ins_cost(140);
8526   size(8);
8527   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
8528             "MOV$cmp  $dst,0" %}
8529   ins_encode %{
8530     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
8531     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
8532   %}
8533   ins_pipe(ialu_imm);
8534 %}
8535 
8536 instruct cmovLL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, immL0 src) %{
8537   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
8538   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8539   ins_cost(140);
8540   size(8);
8541   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
8542             "MOV$cmp  $dst,0" %}
8543   ins_encode %{
8544     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
8545     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
8546   %}
8547   ins_pipe(ialu_imm);
8548 %}
8549 
8550 instruct cmovIL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, iRegI src) %{
8551   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
8552   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8553 
8554   ins_cost(150);
8555   size(4);
8556   format %{ "MOV$cmp  $dst,$src" %}
8557   ins_encode %{
8558     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8559   %}
8560   ins_pipe(ialu_reg);
8561 %}
8562 
8563 instruct cmovIL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, iRegI src) %{
8564   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
8565   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8566 
8567   ins_cost(150);
8568   size(4);
8569   format %{ "MOV$cmp  $dst,$src" %}
8570   ins_encode %{
8571     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8572   %}
8573   ins_pipe(ialu_reg);
8574 %}
8575 
8576 instruct cmovIL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, iRegI src) %{
8577   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
8578   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8579 
8580   ins_cost(150);
8581   size(4);
8582   format %{ "MOV$cmp  $dst,$src" %}
8583   ins_encode %{
8584     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8585   %}
8586   ins_pipe(ialu_reg);
8587 %}
8588 
8589 instruct cmovIL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immI16 src) %{
8590   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
8591   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8592 
8593   ins_cost(140);
8594   format %{ "MOVW$cmp  $dst,$src" %}
8595   ins_encode %{
8596     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
8597   %}
8598   ins_pipe(ialu_imm);
8599 %}
8600 
8601 instruct cmovIL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, immI16 src) %{
8602   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
8603   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8604 
8605   ins_cost(140);
8606   format %{ "MOVW$cmp  $dst,$src" %}
8607   ins_encode %{
8608     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
8609   %}
8610   ins_pipe(ialu_imm);
8611 %}
8612 
8613 instruct cmovIL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immI16 src) %{
8614   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
8615   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8616 
8617   ins_cost(140);
8618   format %{ "MOVW$cmp  $dst,$src" %}
8619   ins_encode %{
8620     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
8621   %}
8622   ins_pipe(ialu_imm);
8623 %}
8624 
8625 instruct cmovPL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, iRegP src) %{
8626   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
8627   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8628 
8629   ins_cost(150);
8630   size(4);
8631   format %{ "MOV$cmp  $dst,$src" %}
8632   ins_encode %{
8633     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8634   %}
8635   ins_pipe(ialu_reg);
8636 %}
8637 
8638 instruct cmovPL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, iRegP src) %{
8639   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
8640   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8641 
8642   ins_cost(150);
8643   size(4);
8644   format %{ "MOV$cmp  $dst,$src" %}
8645   ins_encode %{
8646     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8647   %}
8648   ins_pipe(ialu_reg);
8649 %}
8650 
8651 instruct cmovPL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, iRegP src) %{
8652   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
8653   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8654 
8655   ins_cost(150);
8656   size(4);
8657   format %{ "MOV$cmp  $dst,$src" %}
8658   ins_encode %{
8659     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8660   %}
8661   ins_pipe(ialu_reg);
8662 %}
8663 
8664 instruct cmovPL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, immP0 src) %{
8665   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
8666   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8667 
8668   ins_cost(140);
8669   format %{ "MOVW$cmp  $dst,$src" %}
8670   ins_encode %{
8671     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
8672   %}
8673   ins_pipe(ialu_imm);
8674 %}
8675 
8676 instruct cmovPL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, immP0 src) %{
8677   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
8678   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8679 
8680   ins_cost(140);
8681   format %{ "MOVW$cmp  $dst,$src" %}
8682   ins_encode %{
8683     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
8684   %}
8685   ins_pipe(ialu_imm);
8686 %}
8687 
8688 instruct cmovPL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, immP0 src) %{
8689   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
8690   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8691 
8692   ins_cost(140);
8693   format %{ "MOVW$cmp  $dst,$src" %}
8694   ins_encode %{
8695     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
8696   %}
8697   ins_pipe(ialu_imm);
8698 %}
8699 
8700 instruct cmovFL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regF dst, regF src) %{
8701   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
8702   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8703   ins_cost(150);
8704   size(4);
8705   format %{ "FCPYS$cmp $dst,$src" %}
8706   ins_encode %{
8707     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
8708   %}
8709   ins_pipe(int_conditional_float_move);
8710 %}
8711 
8712 instruct cmovFL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regF dst, regF src) %{
8713   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
8714   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8715   ins_cost(150);
8716   size(4);
8717   format %{ "FCPYS$cmp $dst,$src" %}
8718   ins_encode %{
8719     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
8720   %}
8721   ins_pipe(int_conditional_float_move);
8722 %}
8723 
8724 instruct cmovFL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regF dst, regF src) %{
8725   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
8726   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8727   ins_cost(150);
8728   size(4);
8729   format %{ "FCPYS$cmp $dst,$src" %}
8730   ins_encode %{
8731     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
8732   %}
8733   ins_pipe(int_conditional_float_move);
8734 %}
8735 
8736 instruct cmovDL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regD dst, regD src) %{
8737   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
8738   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8739 
8740   ins_cost(150);
8741   size(4);
8742   format %{ "FCPYD$cmp $dst,$src" %}
8743   ins_encode %{
8744     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
8745   %}
8746   ins_pipe(int_conditional_float_move);
8747 %}
8748 
8749 instruct cmovDL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regD dst, regD src) %{
8750   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
8751   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8752 
8753   ins_cost(150);
8754   size(4);
8755   format %{ "FCPYD$cmp $dst,$src" %}
8756   ins_encode %{
8757     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
8758   %}
8759   ins_pipe(int_conditional_float_move);
8760 %}
8761 
8762 instruct cmovDL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regD dst, regD src) %{
8763   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
8764   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8765 
8766   ins_cost(150);
8767   size(4);
8768   format %{ "FCPYD$cmp $dst,$src" %}
8769   ins_encode %{
8770     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
8771   %}
8772   ins_pipe(int_conditional_float_move);
8773 %}
8774 
8775 // ============================================================================
8776 // Safepoint Instruction
8777 // rather than KILL R12, it would be better to use any reg as
8778 // TEMP. Can't do that at this point because it crashes the compiler
8779 instruct safePoint_poll(iRegP poll, R12RegI tmp, flagsReg icc) %{
8780   match(SafePoint poll);
8781   effect(USE poll, KILL tmp, KILL icc);
8782 
8783   size(4);
8784   format %{ "LDR   $tmp,[$poll]\t! Safepoint: poll for GC" %}
8785   ins_encode %{
8786     __ relocate(relocInfo::poll_type);
8787     __ ldr($tmp$$Register, Address($poll$$Register));
8788   %}
8789   ins_pipe(loadPollP);
8790 %}
8791 
8792 
8793 // ============================================================================
8794 // Call Instructions
8795 // Call Java Static Instruction
8796 instruct CallStaticJavaDirect( method meth ) %{
8797   match(CallStaticJava);
8798   predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke());
8799   effect(USE meth);
8800 
8801   ins_cost(CALL_COST);
8802   format %{ "CALL,static ==> " %}
8803   ins_encode( Java_Static_Call( meth ), call_epilog );
8804   ins_pipe(simple_call);
8805 %}
8806 
8807 // Call Java Static Instruction (method handle version)
8808 instruct CallStaticJavaHandle( method meth ) %{
8809   match(CallStaticJava);
8810   predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke());
8811   effect(USE meth);
8812   // FP is saved by all callees (for interpreter stack correction).
8813   // We use it here for a similar purpose, in {preserve,restore}_FP.
8814 
8815   ins_cost(CALL_COST);
8816   format %{ "CALL,static/MethodHandle ==> " %}
8817   ins_encode( preserve_SP, Java_Static_Call( meth ), restore_SP, call_epilog );
8818   ins_pipe(simple_call);
8819 %}
8820 
8821 // Call Java Dynamic Instruction
8822 instruct CallDynamicJavaDirect( method meth ) %{
8823   match(CallDynamicJava);
8824   effect(USE meth);
8825 
8826   ins_cost(CALL_COST);
8827   format %{ "MOV_OOP    (empty),R_R8\n\t"
8828             "CALL,dynamic  ; NOP ==> " %}
8829   ins_encode( Java_Dynamic_Call( meth ), call_epilog );
8830   ins_pipe(call);
8831 %}
8832 
8833 // Call Runtime Instruction
8834 instruct CallRuntimeDirect(method meth) %{
8835   match(CallRuntime);
8836   effect(USE meth);
8837   ins_cost(CALL_COST);
8838   format %{ "CALL,runtime" %}
8839   ins_encode( Java_To_Runtime( meth ),
8840               call_epilog );
8841   ins_pipe(simple_call);
8842 %}
8843 
8844 // Call runtime without safepoint - same as CallRuntime
8845 instruct CallLeafDirect(method meth) %{
8846   match(CallLeaf);
8847   effect(USE meth);
8848   ins_cost(CALL_COST);
8849   format %{ "CALL,runtime leaf" %}
8850   // TODO: ned save_last_PC here?
8851   ins_encode( Java_To_Runtime( meth ),
8852               call_epilog );
8853   ins_pipe(simple_call);
8854 %}
8855 
8856 // Call runtime without safepoint - same as CallLeaf
8857 instruct CallLeafNoFPDirect(method meth) %{
8858   match(CallLeafNoFP);
8859   effect(USE meth);
8860   ins_cost(CALL_COST);
8861   format %{ "CALL,runtime leaf nofp" %}
8862   // TODO: ned save_last_PC here?
8863   ins_encode( Java_To_Runtime( meth ),
8864               call_epilog );
8865   ins_pipe(simple_call);
8866 %}
8867 
8868 // Tail Call; Jump from runtime stub to Java code.
8869 // Also known as an 'interprocedural jump'.
8870 // Target of jump will eventually return to caller.
8871 // TailJump below removes the return address.
8872 instruct TailCalljmpInd(IPRegP jump_target, inline_cache_regP method_ptr) %{
8873   match(TailCall jump_target method_ptr);
8874 
8875   ins_cost(CALL_COST);
8876   format %{ "MOV    Rexception_pc, LR\n\t"
8877             "jump   $jump_target  \t! $method_ptr holds method" %}
8878   ins_encode %{
8879     __ mov(Rexception_pc, LR);   // this is used only to call
8880                                  // StubRoutines::forward_exception_entry()
8881                                  // which expects PC of exception in
8882                                  // R5. FIXME?
8883     __ jump($jump_target$$Register);
8884   %}
8885   ins_pipe(tail_call);
8886 %}
8887 
8888 
8889 // Return Instruction
8890 instruct Ret() %{
8891   match(Return);
8892 
8893   format %{ "ret LR" %}
8894 
8895   ins_encode %{
8896     __ ret(LR);
8897   %}
8898 
8899   ins_pipe(br);
8900 %}
8901 
8902 
8903 // Tail Jump; remove the return address; jump to target.
8904 // TailCall above leaves the return address around.
8905 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
8906 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
8907 // "restore" before this instruction (in Epilogue), we need to materialize it
8908 // in %i0.
8909 instruct tailjmpInd(IPRegP jump_target, RExceptionRegP ex_oop) %{
8910   match( TailJump jump_target ex_oop );
8911   ins_cost(CALL_COST);
8912   format %{ "MOV    Rexception_pc, LR\n\t"
8913             "jump   $jump_target \t! $ex_oop holds exc. oop" %}
8914   ins_encode %{
8915     __ mov(Rexception_pc, LR);
8916     __ jump($jump_target$$Register);
8917   %}
8918   ins_pipe(tail_call);
8919 %}
8920 
8921 // Create exception oop: created by stack-crawling runtime code.
8922 // Created exception is now available to this handler, and is setup
8923 // just prior to jumping to this handler.  No code emitted.
8924 instruct CreateException( RExceptionRegP ex_oop )
8925 %{
8926   match(Set ex_oop (CreateEx));
8927   ins_cost(0);
8928 
8929   size(0);
8930   // use the following format syntax
8931   format %{ "! exception oop is in Rexception_obj; no code emitted" %}
8932   ins_encode();
8933   ins_pipe(empty);
8934 %}
8935 
8936 
8937 // Rethrow exception:
8938 // The exception oop will come in the first argument position.
8939 // Then JUMP (not call) to the rethrow stub code.
8940 instruct RethrowException()
8941 %{
8942   match(Rethrow);
8943   ins_cost(CALL_COST);
8944 
8945   // use the following format syntax
8946   format %{ "b    rethrow_stub" %}
8947   ins_encode %{
8948     Register scratch = R1_tmp;
8949     assert_different_registers(scratch, c_rarg0, LR);
8950     __ jump(OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type, scratch);
8951   %}
8952   ins_pipe(tail_call);
8953 %}
8954 
8955 
8956 // Die now
8957 instruct ShouldNotReachHere( )
8958 %{
8959   match(Halt);
8960   ins_cost(CALL_COST);
8961 
8962   // Use the following format syntax
8963   format %{ "ShouldNotReachHere" %}
8964   ins_encode %{
8965     if (is_reachable()) {
8966       __ stop(_halt_reason);
8967     }
8968   %}
8969   ins_pipe(tail_call);
8970 %}
8971 
8972 // ============================================================================
8973 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
8974 // array for an instance of the superklass.  Set a hidden internal cache on a
8975 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
8976 // not zero for a miss or zero for a hit.  The encoding ALSO sets flags.
8977 instruct partialSubtypeCheck( R0RegP index, R1RegP sub, R2RegP super, flagsRegP pcc, LRRegP lr ) %{
8978   match(Set index (PartialSubtypeCheck sub super));
8979   effect( KILL pcc, KILL lr );
8980   ins_cost(DEFAULT_COST*10);
8981   format %{ "CALL   PartialSubtypeCheck" %}
8982   ins_encode %{
8983     __ call(StubRoutines::Arm::partial_subtype_check(), relocInfo::runtime_call_type);
8984   %}
8985   ins_pipe(partial_subtype_check_pipe);
8986 %}
8987 
8988 /* instruct partialSubtypeCheck_vs_zero( flagsRegP pcc, o1RegP sub, o2RegP super, immP0 zero, o0RegP idx, o7RegP o7 ) %{ */
8989 /*   match(Set pcc (CmpP (PartialSubtypeCheck sub super) zero)); */
8990 /*   ins_pipe(partial_subtype_check_pipe); */
8991 /* %} */
8992 
8993 
8994 // ============================================================================
8995 // inlined locking and unlocking
8996 
8997 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch )
8998 %{
8999   match(Set pcc (FastLock object box));
9000   predicate(!(UseBiasedLocking && !UseOptoBiasInlining));
9001 
9002   effect(TEMP scratch, TEMP scratch2);
9003   ins_cost(DEFAULT_COST*3);
9004 
9005   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2" %}
9006   ins_encode %{
9007     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
9008   %}
9009   ins_pipe(long_memory_op);
9010 %}
9011 
9012 instruct cmpFastLock_noBiasInline(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2,
9013                                   iRegP scratch, iRegP scratch3) %{
9014   match(Set pcc (FastLock object box));
9015   predicate(UseBiasedLocking && !UseOptoBiasInlining);
9016 
9017   effect(TEMP scratch, TEMP scratch2, TEMP scratch3);
9018   ins_cost(DEFAULT_COST*5);
9019 
9020   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2, $scratch3" %}
9021   ins_encode %{
9022     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register, $scratch3$$Register);
9023   %}
9024   ins_pipe(long_memory_op);
9025 %}
9026 
9027 
9028 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch ) %{
9029   match(Set pcc (FastUnlock object box));
9030   effect(TEMP scratch, TEMP scratch2);
9031   ins_cost(100);
9032 
9033   format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2" %}
9034   ins_encode %{
9035     __ fast_unlock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
9036   %}
9037   ins_pipe(long_memory_op);
9038 %}
9039 
9040 // Count and Base registers are fixed because the allocator cannot
9041 // kill unknown registers.  The encodings are generic.
9042 instruct clear_array(iRegX cnt, iRegP base, iRegI temp, iRegX zero, Universe dummy, flagsReg cpsr) %{
9043   match(Set dummy (ClearArray cnt base));
9044   effect(TEMP temp, TEMP zero, KILL cpsr);
9045   ins_cost(300);
9046   format %{ "MOV    $zero,0\n"
9047       "        MOV    $temp,$cnt\n"
9048       "loop:   SUBS   $temp,$temp,4\t! Count down a dword of bytes\n"
9049       "        STR.ge $zero,[$base+$temp]\t! delay slot"
9050       "        B.gt   loop\t\t! Clearing loop\n" %}
9051   ins_encode %{
9052     __ mov($zero$$Register, 0);
9053     __ mov($temp$$Register, $cnt$$Register);
9054     Label(loop);
9055     __ bind(loop);
9056     __ subs($temp$$Register, $temp$$Register, 4);
9057     __ str($zero$$Register, Address($base$$Register, $temp$$Register), ge);
9058     __ b(loop, gt);
9059   %}
9060   ins_pipe(long_memory_op);
9061 %}
9062 
9063 #ifdef XXX
9064 // FIXME: Why R0/R1/R2/R3?
9065 instruct string_compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result,
9066                         iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
9067   predicate(!CompactStrings);
9068   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
9069   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, TEMP tmp1, TEMP tmp2);
9070   ins_cost(300);
9071   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // TEMP $tmp1, $tmp2" %}
9072   ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result, tmp1, tmp2) );
9073 
9074   ins_pipe(long_memory_op);
9075 %}
9076 
9077 // FIXME: Why R0/R1/R2?
9078 instruct string_equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2,
9079                        flagsReg ccr) %{
9080   predicate(!CompactStrings);
9081   match(Set result (StrEquals (Binary str1 str2) cnt));
9082   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp1, TEMP tmp2, TEMP result, KILL ccr);
9083 
9084   ins_cost(300);
9085   format %{ "String Equals $str1,$str2,$cnt -> $result   // TEMP $tmp1, $tmp2" %}
9086   ins_encode( enc_String_Equals(str1, str2, cnt, result, tmp1, tmp2) );
9087   ins_pipe(long_memory_op);
9088 %}
9089 
9090 // FIXME: Why R0/R1?
9091 instruct array_equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result,
9092                       flagsReg ccr) %{
9093   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
9094   match(Set result (AryEq ary1 ary2));
9095   effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP result, KILL ccr);
9096 
9097   ins_cost(300);
9098   format %{ "Array Equals $ary1,$ary2 -> $result   // TEMP $tmp1,$tmp2,$tmp3" %}
9099   ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, result));
9100   ins_pipe(long_memory_op);
9101 %}
9102 #endif
9103 
9104 //---------- Zeros Count Instructions ------------------------------------------
9105 
9106 instruct countLeadingZerosI(iRegI dst, iRegI src) %{
9107   match(Set dst (CountLeadingZerosI src));
9108   size(4);
9109   format %{ "CLZ_32 $dst,$src" %}
9110   ins_encode %{
9111     __ clz_32($dst$$Register, $src$$Register);
9112   %}
9113   ins_pipe(ialu_reg);
9114 %}
9115 
9116 instruct countLeadingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
9117   match(Set dst (CountLeadingZerosL src));
9118   effect(TEMP tmp, TEMP dst, KILL ccr);
9119   size(16);
9120   format %{ "CLZ    $dst,$src.hi\n\t"
9121             "TEQ    $dst,32\n\t"
9122             "CLZ.eq $tmp,$src.lo\n\t"
9123             "ADD.eq $dst, $dst, $tmp\n\t" %}
9124   ins_encode %{
9125     __ clz($dst$$Register, $src$$Register->successor());
9126     __ teq($dst$$Register, 32);
9127     __ clz($tmp$$Register, $src$$Register, eq);
9128     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
9129   %}
9130   ins_pipe(ialu_reg);
9131 %}
9132 
9133 instruct countTrailingZerosI(iRegI dst, iRegI src, iRegI tmp) %{
9134   match(Set dst (CountTrailingZerosI src));
9135   effect(TEMP tmp);
9136   size(8);
9137   format %{ "RBIT_32 $tmp, $src\n\t"
9138             "CLZ_32  $dst,$tmp" %}
9139   ins_encode %{
9140     __ rbit_32($tmp$$Register, $src$$Register);
9141     __ clz_32($dst$$Register, $tmp$$Register);
9142   %}
9143   ins_pipe(ialu_reg);
9144 %}
9145 
9146 instruct countTrailingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
9147   match(Set dst (CountTrailingZerosL src));
9148   effect(TEMP tmp, TEMP dst, KILL ccr);
9149   size(24);
9150   format %{ "RBIT   $tmp,$src.lo\n\t"
9151             "CLZ    $dst,$tmp\n\t"
9152             "TEQ    $dst,32\n\t"
9153             "RBIT   $tmp,$src.hi\n\t"
9154             "CLZ.eq $tmp,$tmp\n\t"
9155             "ADD.eq $dst,$dst,$tmp\n\t" %}
9156   ins_encode %{
9157     __ rbit($tmp$$Register, $src$$Register);
9158     __ clz($dst$$Register, $tmp$$Register);
9159     __ teq($dst$$Register, 32);
9160     __ rbit($tmp$$Register, $src$$Register->successor());
9161     __ clz($tmp$$Register, $tmp$$Register, eq);
9162     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
9163   %}
9164   ins_pipe(ialu_reg);
9165 %}
9166 
9167 
9168 //---------- Population Count Instructions -------------------------------------
9169 
9170 instruct popCountI(iRegI dst, iRegI src, regD_low tmp) %{
9171   predicate(UsePopCountInstruction);
9172   match(Set dst (PopCountI src));
9173   effect(TEMP tmp);
9174 
9175   format %{ "FMSR       $tmp,$src\n\t"
9176             "VCNT.8     $tmp,$tmp\n\t"
9177             "VPADDL.U8  $tmp,$tmp\n\t"
9178             "VPADDL.U16 $tmp,$tmp\n\t"
9179             "FMRS       $dst,$tmp" %}
9180   size(20);
9181 
9182   ins_encode %{
9183     __ fmsr($tmp$$FloatRegister, $src$$Register);
9184     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
9185     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
9186     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
9187     __ fmrs($dst$$Register, $tmp$$FloatRegister);
9188   %}
9189   ins_pipe(ialu_reg); // FIXME
9190 %}
9191 
9192 // Note: Long.bitCount(long) returns an int.
9193 instruct popCountL(iRegI dst, iRegL src, regD_low tmp) %{
9194   predicate(UsePopCountInstruction);
9195   match(Set dst (PopCountL src));
9196   effect(TEMP tmp);
9197 
9198   format %{ "FMDRR       $tmp,$src.lo,$src.hi\n\t"
9199             "VCNT.8      $tmp,$tmp\n\t"
9200             "VPADDL.U8   $tmp,$tmp\n\t"
9201             "VPADDL.U16  $tmp,$tmp\n\t"
9202             "VPADDL.U32  $tmp,$tmp\n\t"
9203             "FMRS        $dst,$tmp" %}
9204 
9205   size(32);
9206 
9207   ins_encode %{
9208     __ fmdrr($tmp$$FloatRegister, $src$$Register, $src$$Register->successor());
9209     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
9210     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
9211     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
9212     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 32, 0);
9213     __ fmrs($dst$$Register, $tmp$$FloatRegister);
9214   %}
9215   ins_pipe(ialu_reg);
9216 %}
9217 
9218 
9219 // ============================================================================
9220 //------------Bytes reverse--------------------------------------------------
9221 
9222 instruct bytes_reverse_int(iRegI dst, iRegI src) %{
9223   match(Set dst (ReverseBytesI src));
9224 
9225   size(4);
9226   format %{ "REV32 $dst,$src" %}
9227   ins_encode %{
9228     __ rev($dst$$Register, $src$$Register);
9229   %}
9230   ins_pipe( iload_mem ); // FIXME
9231 %}
9232 
9233 instruct bytes_reverse_long(iRegL dst, iRegL src) %{
9234   match(Set dst (ReverseBytesL src));
9235   effect(TEMP dst);
9236   size(8);
9237   format %{ "REV $dst.lo,$src.lo\n\t"
9238             "REV $dst.hi,$src.hi" %}
9239   ins_encode %{
9240     __ rev($dst$$Register, $src$$Register->successor());
9241     __ rev($dst$$Register->successor(), $src$$Register);
9242   %}
9243   ins_pipe( iload_mem ); // FIXME
9244 %}
9245 
9246 instruct bytes_reverse_unsigned_short(iRegI dst, iRegI src) %{
9247   match(Set dst (ReverseBytesUS src));
9248   size(4);
9249   format %{ "REV16 $dst,$src" %}
9250   ins_encode %{
9251     __ rev16($dst$$Register, $src$$Register);
9252   %}
9253   ins_pipe( iload_mem ); // FIXME
9254 %}
9255 
9256 instruct bytes_reverse_short(iRegI dst, iRegI src) %{
9257   match(Set dst (ReverseBytesS src));
9258   size(4);
9259   format %{ "REVSH $dst,$src" %}
9260   ins_encode %{
9261     __ revsh($dst$$Register, $src$$Register);
9262   %}
9263   ins_pipe( iload_mem ); // FIXME
9264 %}
9265 
9266 
9267 // ====================VECTOR INSTRUCTIONS=====================================
9268 
9269 // Load Aligned Packed values into a Double Register
9270 instruct loadV8(vecD dst, memoryD mem) %{
9271   predicate(n->as_LoadVector()->memory_size() == 8);
9272   match(Set dst (LoadVector mem));
9273   ins_cost(MEMORY_REF_COST);
9274   size(4);
9275   format %{ "FLDD   $mem,$dst\t! load vector (8 bytes)" %}
9276   ins_encode %{
9277     __ ldr_double($dst$$FloatRegister, $mem$$Address);
9278   %}
9279   ins_pipe(floadD_mem);
9280 %}
9281 
9282 // Load Aligned Packed values into a Double Register Pair
9283 instruct loadV16(vecX dst, memoryvld mem) %{
9284   predicate(n->as_LoadVector()->memory_size() == 16);
9285   match(Set dst (LoadVector mem));
9286   ins_cost(MEMORY_REF_COST);
9287   size(4);
9288   format %{ "VLD1   $mem,$dst.Q\t! load vector (16 bytes)" %}
9289   ins_encode %{
9290     __ vld1($dst$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
9291   %}
9292   ins_pipe(floadD_mem); // FIXME
9293 %}
9294 
9295 // Store Vector in Double register to memory
9296 instruct storeV8(memoryD mem, vecD src) %{
9297   predicate(n->as_StoreVector()->memory_size() == 8);
9298   match(Set mem (StoreVector mem src));
9299   ins_cost(MEMORY_REF_COST);
9300   size(4);
9301   format %{ "FSTD   $src,$mem\t! store vector (8 bytes)" %}
9302   ins_encode %{
9303     __ str_double($src$$FloatRegister, $mem$$Address);
9304   %}
9305   ins_pipe(fstoreD_mem_reg);
9306 %}
9307 
9308 // Store Vector in Double Register Pair to memory
9309 instruct storeV16(memoryvld mem, vecX src) %{
9310   predicate(n->as_StoreVector()->memory_size() == 16);
9311   match(Set mem (StoreVector mem src));
9312   ins_cost(MEMORY_REF_COST);
9313   size(4);
9314   format %{ "VST1   $src,$mem\t! store vector (16 bytes)" %}
9315   ins_encode %{
9316     __ vst1($src$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
9317   %}
9318   ins_pipe(fstoreD_mem_reg); // FIXME
9319 %}
9320 
9321 // Replicate scalar to packed byte values in Double register
9322 instruct Repl8B_reg(vecD dst, iRegI src, iRegI tmp) %{
9323   predicate(n->as_Vector()->length() == 8);
9324   match(Set dst (ReplicateB src));
9325   ins_cost(DEFAULT_COST*4);
9326   effect(TEMP tmp);
9327   size(16);
9328 
9329   // FIXME: could use PKH instruction instead?
9330   format %{ "LSL      $tmp, $src, 24 \n\t"
9331             "OR       $tmp, $tmp, ($tmp >> 8) \n\t"
9332             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
9333             "FMDRR    $dst,$tmp,$tmp\t" %}
9334   ins_encode %{
9335     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 24));
9336     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 8));
9337     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
9338     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
9339   %}
9340   ins_pipe(ialu_reg); // FIXME
9341 %}
9342 
9343 // Replicate scalar to packed byte values in Double register
9344 instruct Repl8B_reg_simd(vecD dst, iRegI src) %{
9345   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9346   match(Set dst (ReplicateB src));
9347   size(4);
9348 
9349   format %{ "VDUP.8 $dst,$src\t" %}
9350   ins_encode %{
9351     bool quad = false;
9352     __ vdupI($dst$$FloatRegister, $src$$Register,
9353              MacroAssembler::VELEM_SIZE_8, quad);
9354   %}
9355   ins_pipe(ialu_reg); // FIXME
9356 %}
9357 
9358 // Replicate scalar to packed byte values in Double register pair
9359 instruct Repl16B_reg(vecX dst, iRegI src) %{
9360   predicate(n->as_Vector()->length_in_bytes() == 16);
9361   match(Set dst (ReplicateB src));
9362   size(4);
9363 
9364   format %{ "VDUP.8 $dst.Q,$src\t" %}
9365   ins_encode %{
9366     bool quad = true;
9367     __ vdupI($dst$$FloatRegister, $src$$Register,
9368              MacroAssembler::VELEM_SIZE_8, quad);
9369   %}
9370   ins_pipe(ialu_reg); // FIXME
9371 %}
9372 
9373 // Replicate scalar constant to packed byte values in Double register
9374 instruct Repl8B_immI(vecD dst, immI src, iRegI tmp) %{
9375   predicate(n->as_Vector()->length() == 8);
9376   match(Set dst (ReplicateB src));
9377   ins_cost(DEFAULT_COST*2);
9378   effect(TEMP tmp);
9379   size(12);
9380 
9381   format %{ "MOV      $tmp, Repl4($src))\n\t"
9382             "FMDRR    $dst,$tmp,$tmp\t" %}
9383   ins_encode( LdReplImmI(src, dst, tmp, (4), (1)) );
9384   ins_pipe(loadConFD); // FIXME
9385 %}
9386 
9387 // Replicate scalar constant to packed byte values in Double register
9388 // TODO: support negative constants with MVNI?
9389 instruct Repl8B_immU8(vecD dst, immU8 src) %{
9390   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9391   match(Set dst (ReplicateB src));
9392   size(4);
9393 
9394   format %{ "VMOV.U8  $dst,$src" %}
9395   ins_encode %{
9396     bool quad = false;
9397     __ vmovI($dst$$FloatRegister, $src$$constant,
9398              MacroAssembler::VELEM_SIZE_8, quad);
9399   %}
9400   ins_pipe(loadConFD); // FIXME
9401 %}
9402 
9403 // Replicate scalar constant to packed byte values in Double register pair
9404 instruct Repl16B_immU8(vecX dst, immU8 src) %{
9405   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
9406   match(Set dst (ReplicateB src));
9407   size(4);
9408 
9409   format %{ "VMOV.U8  $dst.Q,$src" %}
9410   ins_encode %{
9411     bool quad = true;
9412     __ vmovI($dst$$FloatRegister, $src$$constant,
9413              MacroAssembler::VELEM_SIZE_8, quad);
9414   %}
9415   ins_pipe(loadConFD); // FIXME
9416 %}
9417 
9418 // Replicate scalar to packed short/char values into Double register
9419 instruct Repl4S_reg(vecD dst, iRegI src, iRegI tmp) %{
9420   predicate(n->as_Vector()->length() == 4);
9421   match(Set dst (ReplicateS src));
9422   ins_cost(DEFAULT_COST*3);
9423   effect(TEMP tmp);
9424   size(12);
9425 
9426   // FIXME: could use PKH instruction instead?
9427   format %{ "LSL      $tmp, $src, 16 \n\t"
9428             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
9429             "FMDRR    $dst,$tmp,$tmp\t" %}
9430   ins_encode %{
9431     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 16));
9432     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
9433     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
9434   %}
9435   ins_pipe(ialu_reg); // FIXME
9436 %}
9437 
9438 // Replicate scalar to packed byte values in Double register
9439 instruct Repl4S_reg_simd(vecD dst, iRegI src) %{
9440   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9441   match(Set dst (ReplicateS src));
9442   size(4);
9443 
9444   format %{ "VDUP.16 $dst,$src\t" %}
9445   ins_encode %{
9446     bool quad = false;
9447     __ vdupI($dst$$FloatRegister, $src$$Register,
9448              MacroAssembler::VELEM_SIZE_16, quad);
9449   %}
9450   ins_pipe(ialu_reg); // FIXME
9451 %}
9452 
9453 // Replicate scalar to packed byte values in Double register pair
9454 instruct Repl8S_reg(vecX dst, iRegI src) %{
9455   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
9456   match(Set dst (ReplicateS src));
9457   size(4);
9458 
9459   format %{ "VDUP.16 $dst.Q,$src\t" %}
9460   ins_encode %{
9461     bool quad = true;
9462     __ vdupI($dst$$FloatRegister, $src$$Register,
9463              MacroAssembler::VELEM_SIZE_16, quad);
9464   %}
9465   ins_pipe(ialu_reg); // FIXME
9466 %}
9467 
9468 
9469 // Replicate scalar constant to packed short/char values in Double register
9470 instruct Repl4S_immI(vecD dst, immI src, iRegP tmp) %{
9471   predicate(n->as_Vector()->length() == 4);
9472   match(Set dst (ReplicateS src));
9473   effect(TEMP tmp);
9474   size(12);
9475   ins_cost(DEFAULT_COST*4); // FIXME
9476 
9477   format %{ "MOV      $tmp, Repl2($src))\n\t"
9478             "FMDRR    $dst,$tmp,$tmp\t" %}
9479   ins_encode( LdReplImmI(src, dst, tmp, (2), (2)) );
9480   ins_pipe(loadConFD); // FIXME
9481 %}
9482 
9483 // Replicate scalar constant to packed byte values in Double register
9484 instruct Repl4S_immU8(vecD dst, immU8 src) %{
9485   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9486   match(Set dst (ReplicateS src));
9487   size(4);
9488 
9489   format %{ "VMOV.U16  $dst,$src" %}
9490   ins_encode %{
9491     bool quad = false;
9492     __ vmovI($dst$$FloatRegister, $src$$constant,
9493              MacroAssembler::VELEM_SIZE_16, quad);
9494   %}
9495   ins_pipe(loadConFD); // FIXME
9496 %}
9497 
9498 // Replicate scalar constant to packed byte values in Double register pair
9499 instruct Repl8S_immU8(vecX dst, immU8 src) %{
9500   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
9501   match(Set dst (ReplicateS src));
9502   size(4);
9503 
9504   format %{ "VMOV.U16  $dst.Q,$src" %}
9505   ins_encode %{
9506     bool quad = true;
9507     __ vmovI($dst$$FloatRegister, $src$$constant,
9508              MacroAssembler::VELEM_SIZE_16, quad);
9509   %}
9510   ins_pipe(loadConFD); // FIXME
9511 %}
9512 
9513 // Replicate scalar to packed int values in Double register
9514 instruct Repl2I_reg(vecD dst, iRegI src) %{
9515   predicate(n->as_Vector()->length() == 2);
9516   match(Set dst (ReplicateI src));
9517   size(4);
9518 
9519   format %{ "FMDRR    $dst,$src,$src\t" %}
9520   ins_encode %{
9521     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
9522   %}
9523   ins_pipe(ialu_reg); // FIXME
9524 %}
9525 
9526 // Replicate scalar to packed int values in Double register pair
9527 instruct Repl4I_reg(vecX dst, iRegI src) %{
9528   predicate(n->as_Vector()->length() == 4);
9529   match(Set dst (ReplicateI src));
9530   ins_cost(DEFAULT_COST*2);
9531   size(8);
9532 
9533   format %{ "FMDRR    $dst.lo,$src,$src\n\t"
9534             "FMDRR    $dst.hi,$src,$src" %}
9535 
9536   ins_encode %{
9537     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
9538     __ fmdrr($dst$$FloatRegister->successor()->successor(),
9539              $src$$Register, $src$$Register);
9540   %}
9541   ins_pipe(ialu_reg); // FIXME
9542 %}
9543 
9544 // Replicate scalar to packed int values in Double register
9545 instruct Repl2I_reg_simd(vecD dst, iRegI src) %{
9546   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9547   match(Set dst (ReplicateI src));
9548   size(4);
9549 
9550   format %{ "VDUP.32 $dst.D,$src\t" %}
9551   ins_encode %{
9552     bool quad = false;
9553     __ vdupI($dst$$FloatRegister, $src$$Register,
9554              MacroAssembler::VELEM_SIZE_32, quad);
9555   %}
9556   ins_pipe(ialu_reg); // FIXME
9557 %}
9558 
9559 // Replicate scalar to packed int values in Double register pair
9560 instruct Repl4I_reg_simd(vecX dst, iRegI src) %{
9561   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
9562   match(Set dst (ReplicateI src));
9563   size(4);
9564 
9565   format %{ "VDUP.32 $dst.Q,$src\t" %}
9566   ins_encode %{
9567     bool quad = true;
9568     __ vdupI($dst$$FloatRegister, $src$$Register,
9569              MacroAssembler::VELEM_SIZE_32, quad);
9570   %}
9571   ins_pipe(ialu_reg); // FIXME
9572 %}
9573 
9574 
9575 // Replicate scalar zero constant to packed int values in Double register
9576 instruct Repl2I_immI(vecD dst, immI src, iRegI tmp) %{
9577   predicate(n->as_Vector()->length() == 2);
9578   match(Set dst (ReplicateI src));
9579   effect(TEMP tmp);
9580   size(12);
9581   ins_cost(DEFAULT_COST*4); // FIXME
9582 
9583   format %{ "MOV      $tmp, Repl1($src))\n\t"
9584             "FMDRR    $dst,$tmp,$tmp\t" %}
9585   ins_encode( LdReplImmI(src, dst, tmp, (1), (4)) );
9586   ins_pipe(loadConFD); // FIXME
9587 %}
9588 
9589 // Replicate scalar constant to packed byte values in Double register
9590 instruct Repl2I_immU8(vecD dst, immU8 src) %{
9591   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9592   match(Set dst (ReplicateI src));
9593   size(4);
9594 
9595   format %{ "VMOV.I32  $dst.D,$src" %}
9596   ins_encode %{
9597     bool quad = false;
9598     __ vmovI($dst$$FloatRegister, $src$$constant,
9599              MacroAssembler::VELEM_SIZE_32, quad);
9600   %}
9601   ins_pipe(loadConFD); // FIXME
9602 %}
9603 
9604 // Replicate scalar constant to packed byte values in Double register pair
9605 instruct Repl4I_immU8(vecX dst, immU8 src) %{
9606   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
9607   match(Set dst (ReplicateI src));
9608   size(4);
9609 
9610   format %{ "VMOV.I32  $dst.Q,$src" %}
9611   ins_encode %{
9612     bool quad = true;
9613     __ vmovI($dst$$FloatRegister, $src$$constant,
9614              MacroAssembler::VELEM_SIZE_32, quad);
9615   %}
9616   ins_pipe(loadConFD); // FIXME
9617 %}
9618 
9619 // Replicate scalar to packed byte values in Double register pair
9620 instruct Repl2L_reg(vecX dst, iRegL src) %{
9621   predicate(n->as_Vector()->length() == 2);
9622   match(Set dst (ReplicateL src));
9623   size(8);
9624   ins_cost(DEFAULT_COST*2); // FIXME
9625 
9626   format %{ "FMDRR $dst.D,$src.lo,$src.hi\t\n"
9627             "FMDRR $dst.D.next,$src.lo,$src.hi" %}
9628   ins_encode %{
9629     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
9630     __ fmdrr($dst$$FloatRegister->successor()->successor(),
9631              $src$$Register, $src$$Register->successor());
9632   %}
9633   ins_pipe(ialu_reg); // FIXME
9634 %}
9635 
9636 
9637 // Replicate scalar to packed float values in Double register
9638 instruct Repl2F_regI(vecD dst, iRegI src) %{
9639   predicate(n->as_Vector()->length() == 2);
9640   match(Set dst (ReplicateF src));
9641   size(4);
9642 
9643   format %{ "FMDRR    $dst.D,$src,$src\t" %}
9644   ins_encode %{
9645     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
9646   %}
9647   ins_pipe(ialu_reg); // FIXME
9648 %}
9649 
9650 // Replicate scalar to packed float values in Double register
9651 instruct Repl2F_reg_vfp(vecD dst, regF src) %{
9652   predicate(n->as_Vector()->length() == 2);
9653   match(Set dst (ReplicateF src));
9654   size(4*2);
9655   ins_cost(DEFAULT_COST*2); // FIXME
9656 
9657   expand %{
9658     iRegI tmp;
9659     MoveF2I_reg_reg(tmp, src);
9660     Repl2F_regI(dst,tmp);
9661   %}
9662 %}
9663 
9664 // Replicate scalar to packed float values in Double register
9665 instruct Repl2F_reg_simd(vecD dst, regF src) %{
9666   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9667   match(Set dst (ReplicateF src));
9668   size(4);
9669   ins_cost(DEFAULT_COST); // FIXME
9670 
9671   format %{ "VDUP.32  $dst.D,$src.D\t" %}
9672   ins_encode %{
9673     bool quad = false;
9674     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
9675   %}
9676   ins_pipe(ialu_reg); // FIXME
9677 %}
9678 
9679 // Replicate scalar to packed float values in Double register pair
9680 instruct Repl4F_reg(vecX dst, regF src, iRegI tmp) %{
9681   predicate(n->as_Vector()->length() == 4);
9682   match(Set dst (ReplicateF src));
9683   effect(TEMP tmp);
9684   size(4*3);
9685   ins_cost(DEFAULT_COST*3); // FIXME
9686 
9687   format %{ "FMRS     $tmp,$src\n\t"
9688             "FMDRR    $dst.D,$tmp,$tmp\n\t"
9689             "FMDRR    $dst.D.next,$tmp,$tmp\t" %}
9690   ins_encode %{
9691     __ fmrs($tmp$$Register, $src$$FloatRegister);
9692     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
9693     __ fmdrr($dst$$FloatRegister->successor()->successor(),
9694              $tmp$$Register, $tmp$$Register);
9695   %}
9696   ins_pipe(ialu_reg); // FIXME
9697 %}
9698 
9699 // Replicate scalar to packed float values in Double register pair
9700 instruct Repl4F_reg_simd(vecX dst, regF src) %{
9701   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
9702   match(Set dst (ReplicateF src));
9703   size(4);
9704   ins_cost(DEFAULT_COST); // FIXME
9705 
9706   format %{ "VDUP.32  $dst.Q,$src.D\t" %}
9707   ins_encode %{
9708     bool quad = true;
9709     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
9710   %}
9711   ins_pipe(ialu_reg); // FIXME
9712 %}
9713 
9714 // Replicate scalar zero constant to packed float values in Double register
9715 instruct Repl2F_immI(vecD dst, immF src, iRegI tmp) %{
9716   predicate(n->as_Vector()->length() == 2);
9717   match(Set dst (ReplicateF src));
9718   effect(TEMP tmp);
9719   size(12);
9720   ins_cost(DEFAULT_COST*4); // FIXME
9721 
9722   format %{ "MOV      $tmp, Repl1($src))\n\t"
9723             "FMDRR    $dst,$tmp,$tmp\t" %}
9724   ins_encode( LdReplImmF(src, dst, tmp) );
9725   ins_pipe(loadConFD); // FIXME
9726 %}
9727 
9728 // Replicate scalar to packed double float values in Double register pair
9729 instruct Repl2D_reg(vecX dst, regD src) %{
9730   predicate(n->as_Vector()->length() == 2);
9731   match(Set dst (ReplicateD src));
9732   size(4*2);
9733   ins_cost(DEFAULT_COST*2); // FIXME
9734 
9735   format %{ "FCPYD    $dst.D.a,$src\n\t"
9736             "FCPYD    $dst.D.b,$src\t" %}
9737   ins_encode %{
9738     FloatRegister dsta = $dst$$FloatRegister;
9739     FloatRegister src = $src$$FloatRegister;
9740     __ fcpyd(dsta, src);
9741     FloatRegister dstb = dsta->successor()->successor();
9742     __ fcpyd(dstb, src);
9743   %}
9744   ins_pipe(ialu_reg); // FIXME
9745 %}
9746 
9747 // ====================VECTOR ARITHMETIC=======================================
9748 
9749 // --------------------------------- ADD --------------------------------------
9750 
9751 // Bytes vector add
9752 instruct vadd8B_reg(vecD dst, vecD src1, vecD src2) %{
9753   predicate(n->as_Vector()->length() == 8);
9754   match(Set dst (AddVB src1 src2));
9755   format %{ "VADD.I8 $dst,$src1,$src2\t! add packed8B" %}
9756   size(4);
9757   ins_encode %{
9758     bool quad = false;
9759     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9760              MacroAssembler::VELEM_SIZE_8, quad);
9761   %}
9762   ins_pipe( ialu_reg_reg ); // FIXME
9763 %}
9764 
9765 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
9766   predicate(n->as_Vector()->length() == 16);
9767   match(Set dst (AddVB src1 src2));
9768   size(4);
9769   format %{ "VADD.I8 $dst.Q,$src1.Q,$src2.Q\t! add packed16B" %}
9770   ins_encode %{
9771     bool quad = true;
9772     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9773              MacroAssembler::VELEM_SIZE_8, quad);
9774   %}
9775   ins_pipe( ialu_reg_reg ); // FIXME
9776 %}
9777 
9778 // Shorts/Chars vector add
9779 instruct vadd4S_reg(vecD dst, vecD src1, vecD src2) %{
9780   predicate(n->as_Vector()->length() == 4);
9781   match(Set dst (AddVS src1 src2));
9782   size(4);
9783   format %{ "VADD.I16 $dst,$src1,$src2\t! add packed4S" %}
9784   ins_encode %{
9785     bool quad = false;
9786     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9787              MacroAssembler::VELEM_SIZE_16, quad);
9788   %}
9789   ins_pipe( ialu_reg_reg ); // FIXME
9790 %}
9791 
9792 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
9793   predicate(n->as_Vector()->length() == 8);
9794   match(Set dst (AddVS src1 src2));
9795   size(4);
9796   format %{ "VADD.I16 $dst.Q,$src1.Q,$src2.Q\t! add packed8S" %}
9797   ins_encode %{
9798     bool quad = true;
9799     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9800              MacroAssembler::VELEM_SIZE_16, quad);
9801   %}
9802   ins_pipe( ialu_reg_reg ); // FIXME
9803 %}
9804 
9805 // Integers vector add
9806 instruct vadd2I_reg(vecD dst, vecD src1, vecD src2) %{
9807   predicate(n->as_Vector()->length() == 2);
9808   match(Set dst (AddVI src1 src2));
9809   size(4);
9810   format %{ "VADD.I32 $dst.D,$src1.D,$src2.D\t! add packed2I" %}
9811   ins_encode %{
9812     bool quad = false;
9813     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9814              MacroAssembler::VELEM_SIZE_32, quad);
9815   %}
9816   ins_pipe( ialu_reg_reg ); // FIXME
9817 %}
9818 
9819 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
9820   predicate(n->as_Vector()->length() == 4);
9821   match(Set dst (AddVI src1 src2));
9822   size(4);
9823   format %{ "VADD.I32 $dst.Q,$src1.Q,$src2.Q\t! add packed4I" %}
9824   ins_encode %{
9825     bool quad = true;
9826     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9827              MacroAssembler::VELEM_SIZE_32, quad);
9828   %}
9829   ins_pipe( ialu_reg_reg ); // FIXME
9830 %}
9831 
9832 // Longs vector add
9833 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
9834   predicate(n->as_Vector()->length() == 2);
9835   match(Set dst (AddVL src1 src2));
9836   size(4);
9837   format %{ "VADD.I64 $dst.Q,$src1.Q,$src2.Q\t! add packed2L" %}
9838   ins_encode %{
9839     bool quad = true;
9840     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9841              MacroAssembler::VELEM_SIZE_64, quad);
9842   %}
9843   ins_pipe( ialu_reg_reg ); // FIXME
9844 %}
9845 
9846 // Floats vector add
9847 instruct vadd2F_reg(vecD dst, vecD src1, vecD src2) %{
9848   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
9849   match(Set dst (AddVF src1 src2));
9850   size(4);
9851   format %{ "VADD.F32 $dst,$src1,$src2\t! add packed2F" %}
9852   ins_encode %{
9853     bool quad = false;
9854     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9855              MacroAssembler::VFA_SIZE_F32, quad);
9856   %}
9857   ins_pipe( faddD_reg_reg ); // FIXME
9858 %}
9859 
9860 instruct vadd2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
9861   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
9862   match(Set dst (AddVF src1 src2));
9863   ins_cost(DEFAULT_COST*2); // FIXME
9864 
9865   size(4*2);
9866   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
9867             "FADDS  $dst.b,$src1.b,$src2.b" %}
9868   ins_encode %{
9869     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9870     __ add_float($dst$$FloatRegister->successor(),
9871              $src1$$FloatRegister->successor(),
9872              $src2$$FloatRegister->successor());
9873   %}
9874 
9875   ins_pipe(faddF_reg_reg); // FIXME
9876 %}
9877 
9878 instruct vadd4F_reg_simd(vecX dst, vecX src1, vecX src2) %{
9879   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
9880   match(Set dst (AddVF src1 src2));
9881   size(4);
9882   format %{ "VADD.F32 $dst.Q,$src1.Q,$src2.Q\t! add packed4F" %}
9883   ins_encode %{
9884     bool quad = true;
9885     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9886              MacroAssembler::VFA_SIZE_F32, quad);
9887   %}
9888   ins_pipe( faddD_reg_reg ); // FIXME
9889 %}
9890 
9891 instruct vadd4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
9892   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
9893   match(Set dst (AddVF src1 src2));
9894   size(4*4);
9895   ins_cost(DEFAULT_COST*4); // FIXME
9896 
9897   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
9898             "FADDS  $dst.b,$src1.b,$src2.b\n\t"
9899             "FADDS  $dst.c,$src1.c,$src2.c\n\t"
9900             "FADDS  $dst.d,$src1.d,$src2.d" %}
9901 
9902   ins_encode %{
9903     FloatRegister dsta = $dst$$FloatRegister;
9904     FloatRegister src1a = $src1$$FloatRegister;
9905     FloatRegister src2a = $src2$$FloatRegister;
9906     __ add_float(dsta, src1a, src2a);
9907     FloatRegister dstb = dsta->successor();
9908     FloatRegister src1b = src1a->successor();
9909     FloatRegister src2b = src2a->successor();
9910     __ add_float(dstb, src1b, src2b);
9911     FloatRegister dstc = dstb->successor();
9912     FloatRegister src1c = src1b->successor();
9913     FloatRegister src2c = src2b->successor();
9914     __ add_float(dstc, src1c, src2c);
9915     FloatRegister dstd = dstc->successor();
9916     FloatRegister src1d = src1c->successor();
9917     FloatRegister src2d = src2c->successor();
9918     __ add_float(dstd, src1d, src2d);
9919   %}
9920 
9921   ins_pipe(faddF_reg_reg); // FIXME
9922 %}
9923 
9924 instruct vadd2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
9925   predicate(n->as_Vector()->length() == 2);
9926   match(Set dst (AddVD src1 src2));
9927   size(4*2);
9928   ins_cost(DEFAULT_COST*2); // FIXME
9929 
9930   format %{ "FADDD  $dst.a,$src1.a,$src2.a\n\t"
9931             "FADDD  $dst.b,$src1.b,$src2.b" %}
9932 
9933   ins_encode %{
9934     FloatRegister dsta = $dst$$FloatRegister;
9935     FloatRegister src1a = $src1$$FloatRegister;
9936     FloatRegister src2a = $src2$$FloatRegister;
9937     __ add_double(dsta, src1a, src2a);
9938     FloatRegister dstb = dsta->successor()->successor();
9939     FloatRegister src1b = src1a->successor()->successor();
9940     FloatRegister src2b = src2a->successor()->successor();
9941     __ add_double(dstb, src1b, src2b);
9942   %}
9943 
9944   ins_pipe(faddF_reg_reg); // FIXME
9945 %}
9946 
9947 
9948 // Bytes vector sub
9949 instruct vsub8B_reg(vecD dst, vecD src1, vecD src2) %{
9950   predicate(n->as_Vector()->length() == 8);
9951   match(Set dst (SubVB src1 src2));
9952   size(4);
9953   format %{ "VSUB.I8 $dst,$src1,$src2\t! sub packed8B" %}
9954   ins_encode %{
9955     bool quad = false;
9956     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9957              MacroAssembler::VELEM_SIZE_8, quad);
9958   %}
9959   ins_pipe( ialu_reg_reg ); // FIXME
9960 %}
9961 
9962 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
9963   predicate(n->as_Vector()->length() == 16);
9964   match(Set dst (SubVB src1 src2));
9965   size(4);
9966   format %{ "VSUB.I8 $dst.Q,$src1.Q,$src2.Q\t! sub packed16B" %}
9967   ins_encode %{
9968     bool quad = true;
9969     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9970              MacroAssembler::VELEM_SIZE_8, quad);
9971   %}
9972   ins_pipe( ialu_reg_reg ); // FIXME
9973 %}
9974 
9975 // Shorts/Chars vector sub
9976 instruct vsub4S_reg(vecD dst, vecD src1, vecD src2) %{
9977   predicate(n->as_Vector()->length() == 4);
9978   match(Set dst (SubVS src1 src2));
9979   size(4);
9980   format %{ "VSUB.I16 $dst,$src1,$src2\t! sub packed4S" %}
9981   ins_encode %{
9982     bool quad = false;
9983     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9984              MacroAssembler::VELEM_SIZE_16, quad);
9985   %}
9986   ins_pipe( ialu_reg_reg ); // FIXME
9987 %}
9988 
9989 instruct vsub16S_reg(vecX dst, vecX src1, vecX src2) %{
9990   predicate(n->as_Vector()->length() == 8);
9991   match(Set dst (SubVS src1 src2));
9992   size(4);
9993   format %{ "VSUB.I16 $dst.Q,$src1.Q,$src2.Q\t! sub packed8S" %}
9994   ins_encode %{
9995     bool quad = true;
9996     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9997              MacroAssembler::VELEM_SIZE_16, quad);
9998   %}
9999   ins_pipe( ialu_reg_reg ); // FIXME
10000 %}
10001 
10002 // Integers vector sub
10003 instruct vsub2I_reg(vecD dst, vecD src1, vecD src2) %{
10004   predicate(n->as_Vector()->length() == 2);
10005   match(Set dst (SubVI src1 src2));
10006   size(4);
10007   format %{ "VSUB.I32 $dst,$src1,$src2\t! sub packed2I" %}
10008   ins_encode %{
10009     bool quad = false;
10010     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10011              MacroAssembler::VELEM_SIZE_32, quad);
10012   %}
10013   ins_pipe( ialu_reg_reg ); // FIXME
10014 %}
10015 
10016 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
10017   predicate(n->as_Vector()->length() == 4);
10018   match(Set dst (SubVI src1 src2));
10019   size(4);
10020   format %{ "VSUB.I32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4I" %}
10021   ins_encode %{
10022     bool quad = true;
10023     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10024              MacroAssembler::VELEM_SIZE_32, quad);
10025   %}
10026   ins_pipe( ialu_reg_reg ); // FIXME
10027 %}
10028 
10029 // Longs vector sub
10030 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
10031   predicate(n->as_Vector()->length() == 2);
10032   match(Set dst (SubVL src1 src2));
10033   size(4);
10034   format %{ "VSUB.I64 $dst.Q,$src1.Q,$src2.Q\t! sub packed2L" %}
10035   ins_encode %{
10036     bool quad = true;
10037     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10038              MacroAssembler::VELEM_SIZE_64, quad);
10039   %}
10040   ins_pipe( ialu_reg_reg ); // FIXME
10041 %}
10042 
10043 // Floats vector sub
10044 instruct vsub2F_reg(vecD dst, vecD src1, vecD src2) %{
10045   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
10046   match(Set dst (SubVF src1 src2));
10047   size(4);
10048   format %{ "VSUB.F32 $dst,$src1,$src2\t! sub packed2F" %}
10049   ins_encode %{
10050     bool quad = false;
10051     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10052              MacroAssembler::VFA_SIZE_F32, quad);
10053   %}
10054   ins_pipe( faddF_reg_reg ); // FIXME
10055 %}
10056 
10057 instruct vsub2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10058   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
10059   match(Set dst (SubVF src1 src2));
10060   size(4*2);
10061   ins_cost(DEFAULT_COST*2); // FIXME
10062 
10063   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10064             "FSUBS  $dst.b,$src1.b,$src2.b" %}
10065 
10066   ins_encode %{
10067     FloatRegister dsta = $dst$$FloatRegister;
10068     FloatRegister src1a = $src1$$FloatRegister;
10069     FloatRegister src2a = $src2$$FloatRegister;
10070     __ sub_float(dsta, src1a, src2a);
10071     FloatRegister dstb = dsta->successor();
10072     FloatRegister src1b = src1a->successor();
10073     FloatRegister src2b = src2a->successor();
10074     __ sub_float(dstb, src1b, src2b);
10075   %}
10076 
10077   ins_pipe(faddF_reg_reg); // FIXME
10078 %}
10079 
10080 
10081 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
10082   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
10083   match(Set dst (SubVF src1 src2));
10084   size(4);
10085   format %{ "VSUB.F32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4F" %}
10086   ins_encode %{
10087     bool quad = true;
10088     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10089              MacroAssembler::VFA_SIZE_F32, quad);
10090   %}
10091   ins_pipe( faddF_reg_reg ); // FIXME
10092 %}
10093 
10094 instruct vsub4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10095   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
10096   match(Set dst (SubVF src1 src2));
10097   size(4*4);
10098   ins_cost(DEFAULT_COST*4); // FIXME
10099 
10100   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10101             "FSUBS  $dst.b,$src1.b,$src2.b\n\t"
10102             "FSUBS  $dst.c,$src1.c,$src2.c\n\t"
10103             "FSUBS  $dst.d,$src1.d,$src2.d" %}
10104 
10105   ins_encode %{
10106     FloatRegister dsta = $dst$$FloatRegister;
10107     FloatRegister src1a = $src1$$FloatRegister;
10108     FloatRegister src2a = $src2$$FloatRegister;
10109     __ sub_float(dsta, src1a, src2a);
10110     FloatRegister dstb = dsta->successor();
10111     FloatRegister src1b = src1a->successor();
10112     FloatRegister src2b = src2a->successor();
10113     __ sub_float(dstb, src1b, src2b);
10114     FloatRegister dstc = dstb->successor();
10115     FloatRegister src1c = src1b->successor();
10116     FloatRegister src2c = src2b->successor();
10117     __ sub_float(dstc, src1c, src2c);
10118     FloatRegister dstd = dstc->successor();
10119     FloatRegister src1d = src1c->successor();
10120     FloatRegister src2d = src2c->successor();
10121     __ sub_float(dstd, src1d, src2d);
10122   %}
10123 
10124   ins_pipe(faddF_reg_reg); // FIXME
10125 %}
10126 
10127 instruct vsub2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10128   predicate(n->as_Vector()->length() == 2);
10129   match(Set dst (SubVD src1 src2));
10130   size(4*2);
10131   ins_cost(DEFAULT_COST*2); // FIXME
10132 
10133   format %{ "FSUBD  $dst.a,$src1.a,$src2.a\n\t"
10134             "FSUBD  $dst.b,$src1.b,$src2.b" %}
10135 
10136   ins_encode %{
10137     FloatRegister dsta = $dst$$FloatRegister;
10138     FloatRegister src1a = $src1$$FloatRegister;
10139     FloatRegister src2a = $src2$$FloatRegister;
10140     __ sub_double(dsta, src1a, src2a);
10141     FloatRegister dstb = dsta->successor()->successor();
10142     FloatRegister src1b = src1a->successor()->successor();
10143     FloatRegister src2b = src2a->successor()->successor();
10144     __ sub_double(dstb, src1b, src2b);
10145   %}
10146 
10147   ins_pipe(faddF_reg_reg); // FIXME
10148 %}
10149 
10150 // Shorts/Chars vector mul
10151 instruct vmul4S_reg(vecD dst, vecD src1, vecD src2) %{
10152   predicate(n->as_Vector()->length() == 4);
10153   match(Set dst (MulVS src1 src2));
10154   size(4);
10155   format %{ "VMUL.I16 $dst,$src1,$src2\t! mul packed4S" %}
10156   ins_encode %{
10157     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10158              MacroAssembler::VELEM_SIZE_16, 0);
10159   %}
10160   ins_pipe( ialu_reg_reg ); // FIXME
10161 %}
10162 
10163 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2) %{
10164   predicate(n->as_Vector()->length() == 8);
10165   match(Set dst (MulVS src1 src2));
10166   size(4);
10167   format %{ "VMUL.I16 $dst.Q,$src1.Q,$src2.Q\t! mul packed8S" %}
10168   ins_encode %{
10169     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10170              MacroAssembler::VELEM_SIZE_16, 1);
10171   %}
10172   ins_pipe( ialu_reg_reg ); // FIXME
10173 %}
10174 
10175 // Integers vector mul
10176 instruct vmul2I_reg(vecD dst, vecD src1, vecD src2) %{
10177   predicate(n->as_Vector()->length() == 2);
10178   match(Set dst (MulVI src1 src2));
10179   size(4);
10180   format %{ "VMUL.I32 $dst,$src1,$src2\t! mul packed2I" %}
10181   ins_encode %{
10182     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10183              MacroAssembler::VELEM_SIZE_32, 0);
10184   %}
10185   ins_pipe( ialu_reg_reg ); // FIXME
10186 %}
10187 
10188 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
10189   predicate(n->as_Vector()->length() == 4);
10190   match(Set dst (MulVI src1 src2));
10191   size(4);
10192   format %{ "VMUL.I32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4I" %}
10193   ins_encode %{
10194     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10195              MacroAssembler::VELEM_SIZE_32, 1);
10196   %}
10197   ins_pipe( ialu_reg_reg ); // FIXME
10198 %}
10199 
10200 // Floats vector mul
10201 instruct vmul2F_reg(vecD dst, vecD src1, vecD src2) %{
10202   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
10203   match(Set dst (MulVF src1 src2));
10204   size(4);
10205   format %{ "VMUL.F32 $dst,$src1,$src2\t! mul packed2F" %}
10206   ins_encode %{
10207     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10208              MacroAssembler::VFA_SIZE_F32, 0);
10209   %}
10210   ins_pipe( fmulF_reg_reg ); // FIXME
10211 %}
10212 
10213 instruct vmul2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10214   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
10215   match(Set dst (MulVF src1 src2));
10216   size(4*2);
10217   ins_cost(DEFAULT_COST*2); // FIXME
10218 
10219   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10220             "FMULS  $dst.b,$src1.b,$src2.b" %}
10221   ins_encode %{
10222     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10223     __ mul_float($dst$$FloatRegister->successor(),
10224              $src1$$FloatRegister->successor(),
10225              $src2$$FloatRegister->successor());
10226   %}
10227 
10228   ins_pipe(fmulF_reg_reg); // FIXME
10229 %}
10230 
10231 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
10232   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
10233   match(Set dst (MulVF src1 src2));
10234   size(4);
10235   format %{ "VMUL.F32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4F" %}
10236   ins_encode %{
10237     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10238              MacroAssembler::VFA_SIZE_F32, 1);
10239   %}
10240   ins_pipe( fmulF_reg_reg ); // FIXME
10241 %}
10242 
10243 instruct vmul4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10244   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
10245   match(Set dst (MulVF src1 src2));
10246   size(4*4);
10247   ins_cost(DEFAULT_COST*4); // FIXME
10248 
10249   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10250             "FMULS  $dst.b,$src1.b,$src2.b\n\t"
10251             "FMULS  $dst.c,$src1.c,$src2.c\n\t"
10252             "FMULS  $dst.d,$src1.d,$src2.d" %}
10253 
10254   ins_encode %{
10255     FloatRegister dsta = $dst$$FloatRegister;
10256     FloatRegister src1a = $src1$$FloatRegister;
10257     FloatRegister src2a = $src2$$FloatRegister;
10258     __ mul_float(dsta, src1a, src2a);
10259     FloatRegister dstb = dsta->successor();
10260     FloatRegister src1b = src1a->successor();
10261     FloatRegister src2b = src2a->successor();
10262     __ mul_float(dstb, src1b, src2b);
10263     FloatRegister dstc = dstb->successor();
10264     FloatRegister src1c = src1b->successor();
10265     FloatRegister src2c = src2b->successor();
10266     __ mul_float(dstc, src1c, src2c);
10267     FloatRegister dstd = dstc->successor();
10268     FloatRegister src1d = src1c->successor();
10269     FloatRegister src2d = src2c->successor();
10270     __ mul_float(dstd, src1d, src2d);
10271   %}
10272 
10273   ins_pipe(fmulF_reg_reg); // FIXME
10274 %}
10275 
10276 instruct vmul2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10277   predicate(n->as_Vector()->length() == 2);
10278   match(Set dst (MulVD src1 src2));
10279   size(4*2);
10280   ins_cost(DEFAULT_COST*2); // FIXME
10281 
10282   format %{ "FMULD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10283             "FMULD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10284   ins_encode %{
10285     FloatRegister dsta = $dst$$FloatRegister;
10286     FloatRegister src1a = $src1$$FloatRegister;
10287     FloatRegister src2a = $src2$$FloatRegister;
10288     __ mul_double(dsta, src1a, src2a);
10289     FloatRegister dstb = dsta->successor()->successor();
10290     FloatRegister src1b = src1a->successor()->successor();
10291     FloatRegister src2b = src2a->successor()->successor();
10292     __ mul_double(dstb, src1b, src2b);
10293   %}
10294 
10295   ins_pipe(fmulD_reg_reg); // FIXME
10296 %}
10297 
10298 
10299 // Floats vector div
10300 instruct vdiv2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10301   predicate(n->as_Vector()->length() == 2);
10302   match(Set dst (DivVF src1 src2));
10303   size(4*2);
10304   ins_cost(DEFAULT_COST*2); // FIXME
10305 
10306   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10307             "FDIVS  $dst.b,$src1.b,$src2.b" %}
10308   ins_encode %{
10309     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10310     __ div_float($dst$$FloatRegister->successor(),
10311              $src1$$FloatRegister->successor(),
10312              $src2$$FloatRegister->successor());
10313   %}
10314 
10315   ins_pipe(fdivF_reg_reg); // FIXME
10316 %}
10317 
10318 instruct vdiv4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10319   predicate(n->as_Vector()->length() == 4);
10320   match(Set dst (DivVF src1 src2));
10321   size(4*4);
10322   ins_cost(DEFAULT_COST*4); // FIXME
10323 
10324   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10325             "FDIVS  $dst.b,$src1.b,$src2.b\n\t"
10326             "FDIVS  $dst.c,$src1.c,$src2.c\n\t"
10327             "FDIVS  $dst.d,$src1.d,$src2.d" %}
10328 
10329   ins_encode %{
10330     FloatRegister dsta = $dst$$FloatRegister;
10331     FloatRegister src1a = $src1$$FloatRegister;
10332     FloatRegister src2a = $src2$$FloatRegister;
10333     __ div_float(dsta, src1a, src2a);
10334     FloatRegister dstb = dsta->successor();
10335     FloatRegister src1b = src1a->successor();
10336     FloatRegister src2b = src2a->successor();
10337     __ div_float(dstb, src1b, src2b);
10338     FloatRegister dstc = dstb->successor();
10339     FloatRegister src1c = src1b->successor();
10340     FloatRegister src2c = src2b->successor();
10341     __ div_float(dstc, src1c, src2c);
10342     FloatRegister dstd = dstc->successor();
10343     FloatRegister src1d = src1c->successor();
10344     FloatRegister src2d = src2c->successor();
10345     __ div_float(dstd, src1d, src2d);
10346   %}
10347 
10348   ins_pipe(fdivF_reg_reg); // FIXME
10349 %}
10350 
10351 instruct vdiv2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10352   predicate(n->as_Vector()->length() == 2);
10353   match(Set dst (DivVD src1 src2));
10354   size(4*2);
10355   ins_cost(DEFAULT_COST*2); // FIXME
10356 
10357   format %{ "FDIVD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10358             "FDIVD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10359   ins_encode %{
10360     FloatRegister dsta = $dst$$FloatRegister;
10361     FloatRegister src1a = $src1$$FloatRegister;
10362     FloatRegister src2a = $src2$$FloatRegister;
10363     __ div_double(dsta, src1a, src2a);
10364     FloatRegister dstb = dsta->successor()->successor();
10365     FloatRegister src1b = src1a->successor()->successor();
10366     FloatRegister src2b = src2a->successor()->successor();
10367     __ div_double(dstb, src1b, src2b);
10368   %}
10369 
10370   ins_pipe(fdivD_reg_reg); // FIXME
10371 %}
10372 
10373 // --------------------------------- NEG --------------------------------------
10374 
10375 instruct vneg8B_reg(vecD dst, vecD src) %{
10376   predicate(n->as_Vector()->length_in_bytes() == 8);
10377   effect(DEF dst, USE src);
10378   size(4);
10379   ins_cost(DEFAULT_COST); // FIXME
10380   format %{ "VNEG.S8 $dst.D,$src.D\t! neg packed8B" %}
10381   ins_encode %{
10382     bool quad = false;
10383     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
10384               MacroAssembler::VELEM_SIZE_8, quad);
10385   %}
10386   ins_pipe( ialu_reg_reg ); // FIXME
10387 %}
10388 
10389 instruct vneg16B_reg(vecX dst, vecX src) %{
10390   predicate(n->as_Vector()->length_in_bytes() == 16);
10391   effect(DEF dst, USE src);
10392   size(4);
10393   ins_cost(DEFAULT_COST); // FIXME
10394   format %{ "VNEG.S8 $dst.Q,$src.Q\t! neg0 packed16B" %}
10395   ins_encode %{
10396     bool _float = false;
10397     bool quad = true;
10398     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
10399               MacroAssembler::VELEM_SIZE_8, quad);
10400   %}
10401   ins_pipe( ialu_reg_reg ); // FIXME
10402 %}
10403 
10404 // ------------------------------ Shift ---------------------------------------
10405 
10406 instruct vslcntD(vecD dst, iRegI cnt) %{
10407   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
10408   match(Set dst (LShiftCntV cnt));
10409   size(4);
10410   ins_cost(DEFAULT_COST); // FIXME
10411   expand %{
10412     Repl8B_reg_simd(dst, cnt);
10413   %}
10414 %}
10415 
10416 instruct vslcntX(vecX dst, iRegI cnt) %{
10417   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
10418   match(Set dst (LShiftCntV cnt));
10419   size(4);
10420   ins_cost(DEFAULT_COST); // FIXME
10421   expand %{
10422     Repl16B_reg(dst, cnt);
10423   %}
10424 %}
10425 
10426 // Low bits of vector "shift" elements are used, so it
10427 // doesn't matter if we treat it as ints or bytes here.
10428 instruct vsrcntD(vecD dst, iRegI cnt) %{
10429   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
10430   match(Set dst (RShiftCntV cnt));
10431   size(4*2);
10432   ins_cost(DEFAULT_COST*2); // FIXME
10433 
10434   format %{ "VDUP.8 $dst.D,$cnt\n\t"
10435             "VNEG.S8 $dst.D,$dst.D\t! neg packed8B" %}
10436   ins_encode %{
10437     bool quad = false;
10438     __ vdupI($dst$$FloatRegister, $cnt$$Register,
10439              MacroAssembler::VELEM_SIZE_8, quad);
10440     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
10441               MacroAssembler::VELEM_SIZE_8, quad);
10442   %}
10443   ins_pipe( ialu_reg_reg ); // FIXME
10444 %}
10445 
10446 instruct vsrcntX(vecX dst, iRegI cnt) %{
10447   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
10448   match(Set dst (RShiftCntV cnt));
10449   size(4*2);
10450   ins_cost(DEFAULT_COST*2); // FIXME
10451   format %{ "VDUP.8 $dst.Q,$cnt\n\t"
10452             "VNEG.S8 $dst.Q,$dst.Q\t! neg packed16B" %}
10453   ins_encode %{
10454     bool quad = true;
10455     __ vdupI($dst$$FloatRegister, $cnt$$Register,
10456              MacroAssembler::VELEM_SIZE_8, quad);
10457     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
10458               MacroAssembler::VELEM_SIZE_8, quad);
10459   %}
10460   ins_pipe( ialu_reg_reg ); // FIXME
10461 %}
10462 
10463 // Byte vector logical left/right shift based on sign
10464 instruct vsh8B_reg(vecD dst, vecD src, vecD shift) %{
10465   predicate(n->as_Vector()->length() == 8);
10466   effect(DEF dst, USE src, USE shift);
10467   size(4);
10468   ins_cost(DEFAULT_COST); // FIXME
10469   format %{
10470     "VSHL.U8 $dst.D,$src.D,$shift.D\t! logical left/right shift packed8B"
10471   %}
10472   ins_encode %{
10473     bool quad = false;
10474     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10475               MacroAssembler::VELEM_SIZE_8, quad);
10476   %}
10477   ins_pipe( ialu_reg_reg ); // FIXME
10478 %}
10479 
10480 instruct vsh16B_reg(vecX dst, vecX src, vecX shift) %{
10481   predicate(n->as_Vector()->length() == 16);
10482   effect(DEF dst, USE src, USE shift);
10483   size(4);
10484   ins_cost(DEFAULT_COST); // FIXME
10485   format %{
10486     "VSHL.U8 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed16B"
10487   %}
10488   ins_encode %{
10489     bool quad = true;
10490     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10491               MacroAssembler::VELEM_SIZE_8, quad);
10492   %}
10493   ins_pipe( ialu_reg_reg ); // FIXME
10494 %}
10495 
10496 // Shorts/Char vector logical left/right shift based on sign
10497 instruct vsh4S_reg(vecD dst, vecD src, vecD shift) %{
10498   predicate(n->as_Vector()->length() == 4);
10499   effect(DEF dst, USE src, USE shift);
10500   size(4);
10501   ins_cost(DEFAULT_COST); // FIXME
10502   format %{
10503     "VSHL.U16 $dst.D,$src.D,$shift.D\t! logical left/right shift packed4S"
10504   %}
10505   ins_encode %{
10506     bool quad = false;
10507     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10508               MacroAssembler::VELEM_SIZE_16, quad);
10509   %}
10510   ins_pipe( ialu_reg_reg ); // FIXME
10511 %}
10512 
10513 instruct vsh8S_reg(vecX dst, vecX src, vecX shift) %{
10514   predicate(n->as_Vector()->length() == 8);
10515   effect(DEF dst, USE src, USE shift);
10516   size(4);
10517   ins_cost(DEFAULT_COST); // FIXME
10518   format %{
10519     "VSHL.U16 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed8S"
10520   %}
10521   ins_encode %{
10522     bool quad = true;
10523     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10524               MacroAssembler::VELEM_SIZE_16, quad);
10525   %}
10526   ins_pipe( ialu_reg_reg ); // FIXME
10527 %}
10528 
10529 // Integers vector logical left/right shift based on sign
10530 instruct vsh2I_reg(vecD dst, vecD src, vecD shift) %{
10531   predicate(n->as_Vector()->length() == 2);
10532   effect(DEF dst, USE src, USE shift);
10533   size(4);
10534   ins_cost(DEFAULT_COST); // FIXME
10535   format %{
10536     "VSHL.U32 $dst.D,$src.D,$shift.D\t! logical left/right shift packed2I"
10537   %}
10538   ins_encode %{
10539     bool quad = false;
10540     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10541               MacroAssembler::VELEM_SIZE_32, quad);
10542   %}
10543   ins_pipe( ialu_reg_reg ); // FIXME
10544 %}
10545 
10546 instruct vsh4I_reg(vecX dst, vecX src, vecX shift) %{
10547   predicate(n->as_Vector()->length() == 4);
10548   effect(DEF dst, USE src, USE shift);
10549   size(4);
10550   ins_cost(DEFAULT_COST); // FIXME
10551   format %{
10552     "VSHL.U32 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed4I"
10553   %}
10554   ins_encode %{
10555     bool quad = true;
10556     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10557               MacroAssembler::VELEM_SIZE_32, quad);
10558   %}
10559   ins_pipe( ialu_reg_reg ); // FIXME
10560 %}
10561 
10562 // Longs vector logical left/right shift based on sign
10563 instruct vsh2L_reg(vecX dst, vecX src, vecX shift) %{
10564   predicate(n->as_Vector()->length() == 2);
10565   effect(DEF dst, USE src, USE shift);
10566   size(4);
10567   ins_cost(DEFAULT_COST); // FIXME
10568   format %{
10569     "VSHL.U64 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed2L"
10570   %}
10571   ins_encode %{
10572     bool quad = true;
10573     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10574               MacroAssembler::VELEM_SIZE_64, quad);
10575   %}
10576   ins_pipe( ialu_reg_reg ); // FIXME
10577 %}
10578 
10579 // ------------------------------ LeftShift -----------------------------------
10580 
10581 // Byte vector left shift
10582 instruct vsl8B_reg(vecD dst, vecD src, vecD shift) %{
10583   predicate(n->as_Vector()->length() == 8);
10584   match(Set dst (LShiftVB src shift));
10585   size(4*1);
10586   ins_cost(DEFAULT_COST*1); // FIXME
10587   expand %{
10588     vsh8B_reg(dst, src, shift);
10589   %}
10590 %}
10591 
10592 instruct vsl16B_reg(vecX dst, vecX src, vecX shift) %{
10593   predicate(n->as_Vector()->length() == 16);
10594   match(Set dst (LShiftVB src shift));
10595   size(4*1);
10596   ins_cost(DEFAULT_COST*1); // FIXME
10597   expand %{
10598     vsh16B_reg(dst, src, shift);
10599   %}
10600 %}
10601 
10602 instruct vsl8B_immI(vecD dst, vecD src, immI shift) %{
10603   predicate(n->as_Vector()->length() == 8);
10604   match(Set dst (LShiftVB src (LShiftCntV shift)));
10605   size(4);
10606   ins_cost(DEFAULT_COST); // FIXME
10607   format %{
10608     "VSHL.I8 $dst.D,$src.D,$shift\t! logical left shift packed8B"
10609   %}
10610   ins_encode %{
10611     bool quad = false;
10612     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10613              quad);
10614   %}
10615   ins_pipe( ialu_reg_reg ); // FIXME
10616 %}
10617 
10618 instruct vsl16B_immI(vecX dst, vecX src, immI shift) %{
10619   predicate(n->as_Vector()->length() == 16);
10620   match(Set dst (LShiftVB src (LShiftCntV shift)));
10621   size(4);
10622   ins_cost(DEFAULT_COST); // FIXME
10623   format %{
10624     "VSHL.I8 $dst.Q,$src.Q,$shift\t! logical left shift packed16B"
10625   %}
10626   ins_encode %{
10627     bool quad = true;
10628     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10629              quad);
10630   %}
10631   ins_pipe( ialu_reg_reg ); // FIXME
10632 %}
10633 
10634 // Shorts/Chars vector logical left/right shift
10635 instruct vsl4S_reg(vecD dst, vecD src, vecD shift) %{
10636   predicate(n->as_Vector()->length() == 4);
10637   match(Set dst (LShiftVS src shift));
10638   match(Set dst (URShiftVS src shift));
10639   size(4*1);
10640   ins_cost(DEFAULT_COST*1); // FIXME
10641   expand %{
10642     vsh4S_reg(dst, src, shift);
10643   %}
10644 %}
10645 
10646 instruct vsl8S_reg(vecX dst, vecX src, vecX shift) %{
10647   predicate(n->as_Vector()->length() == 8);
10648   match(Set dst (LShiftVS src shift));
10649   match(Set dst (URShiftVS src shift));
10650   size(4*1);
10651   ins_cost(DEFAULT_COST*1); // FIXME
10652   expand %{
10653     vsh8S_reg(dst, src, shift);
10654   %}
10655 %}
10656 
10657 instruct vsl4S_immI(vecD dst, vecD src, immI shift) %{
10658   predicate(n->as_Vector()->length() == 4);
10659   match(Set dst (LShiftVS src (LShiftCntV shift)));
10660   size(4);
10661   ins_cost(DEFAULT_COST); // FIXME
10662   format %{
10663     "VSHL.I16 $dst.D,$src.D,$shift\t! logical left shift packed4S"
10664   %}
10665   ins_encode %{
10666     bool quad = false;
10667     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10668              quad);
10669   %}
10670   ins_pipe( ialu_reg_reg ); // FIXME
10671 %}
10672 
10673 instruct vsl8S_immI(vecX dst, vecX src, immI shift) %{
10674   predicate(n->as_Vector()->length() == 8);
10675   match(Set dst (LShiftVS src shift));
10676   size(4);
10677   ins_cost(DEFAULT_COST); // FIXME
10678   format %{
10679     "VSHL.I16 $dst.Q,$src.Q,$shift\t! logical left shift packed8S"
10680   %}
10681   ins_encode %{
10682     bool quad = true;
10683     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10684              quad);
10685   %}
10686   ins_pipe( ialu_reg_reg ); // FIXME
10687 %}
10688 
10689 // Integers vector logical left/right shift
10690 instruct vsl2I_reg(vecD dst, vecD src, vecD shift) %{
10691   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10692   match(Set dst (LShiftVI src shift));
10693   match(Set dst (URShiftVI src shift));
10694   size(4*1);
10695   ins_cost(DEFAULT_COST*1); // FIXME
10696   expand %{
10697     vsh2I_reg(dst, src, shift);
10698   %}
10699 %}
10700 
10701 instruct vsl4I_reg(vecX dst, vecX src, vecX shift) %{
10702   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10703   match(Set dst (LShiftVI src shift));
10704   match(Set dst (URShiftVI src shift));
10705   size(4*1);
10706   ins_cost(DEFAULT_COST*1); // FIXME
10707   expand %{
10708     vsh4I_reg(dst, src, shift);
10709   %}
10710 %}
10711 
10712 instruct vsl2I_immI(vecD dst, vecD src, immI shift) %{
10713   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10714   match(Set dst (LShiftVI src (LShiftCntV shift)));
10715   size(4);
10716   ins_cost(DEFAULT_COST); // FIXME
10717   format %{
10718     "VSHL.I32 $dst.D,$src.D,$shift\t! logical left shift packed2I"
10719   %}
10720   ins_encode %{
10721     bool quad = false;
10722     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10723              quad);
10724   %}
10725   ins_pipe( ialu_reg_reg ); // FIXME
10726 %}
10727 
10728 instruct vsl4I_immI(vecX dst, vecX src, immI shift) %{
10729   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10730   match(Set dst (LShiftVI src (LShiftCntV shift)));
10731   size(4);
10732   ins_cost(DEFAULT_COST); // FIXME
10733   format %{
10734     "VSHL.I32 $dst.Q,$src.Q,$shift\t! logical left shift packed4I"
10735   %}
10736   ins_encode %{
10737     bool quad = true;
10738     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10739              quad);
10740   %}
10741   ins_pipe( ialu_reg_reg ); // FIXME
10742 %}
10743 
10744 // Longs vector logical left/right shift
10745 instruct vsl2L_reg(vecX dst, vecX src, vecX shift) %{
10746   predicate(n->as_Vector()->length() == 2);
10747   match(Set dst (LShiftVL src shift));
10748   match(Set dst (URShiftVL src shift));
10749   size(4*1);
10750   ins_cost(DEFAULT_COST*1); // FIXME
10751   expand %{
10752     vsh2L_reg(dst, src, shift);
10753   %}
10754 %}
10755 
10756 instruct vsl2L_immI(vecX dst, vecX src, immI shift) %{
10757   predicate(n->as_Vector()->length() == 2);
10758   match(Set dst (LShiftVL src (LShiftCntV shift)));
10759   size(4);
10760   ins_cost(DEFAULT_COST); // FIXME
10761   format %{
10762     "VSHL.I64 $dst.Q,$src.Q,$shift\t! logical left shift packed2L"
10763   %}
10764   ins_encode %{
10765     bool quad = true;
10766     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
10767              quad);
10768   %}
10769   ins_pipe( ialu_reg_reg ); // FIXME
10770 %}
10771 
10772 // ----------------------- LogicalRightShift -----------------------------------
10773 
10774 // Bytes/Shorts vector logical right shift produces incorrect Java result
10775 // for negative data because java code convert short value into int with
10776 // sign extension before a shift.
10777 
10778 // Chars vector logical right shift
10779 instruct vsrl4S_immI(vecD dst, vecD src, immI shift) %{
10780   predicate(n->as_Vector()->length() == 4);
10781   match(Set dst (URShiftVS src (RShiftCntV shift)));
10782   size(4);
10783   ins_cost(DEFAULT_COST); // FIXME
10784   format %{
10785     "VSHR.U16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
10786   %}
10787   ins_encode %{
10788     bool quad = false;
10789     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10790              quad);
10791   %}
10792   ins_pipe( ialu_reg_reg ); // FIXME
10793 %}
10794 
10795 instruct vsrl8S_immI(vecX dst, vecX src, immI shift) %{
10796   predicate(n->as_Vector()->length() == 8);
10797   match(Set dst (URShiftVS src (RShiftCntV shift)));
10798   size(4);
10799   ins_cost(DEFAULT_COST); // FIXME
10800   format %{
10801     "VSHR.U16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
10802   %}
10803   ins_encode %{
10804     bool quad = true;
10805     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10806              quad);
10807   %}
10808   ins_pipe( ialu_reg_reg ); // FIXME
10809 %}
10810 
10811 // Integers vector logical right shift
10812 instruct vsrl2I_immI(vecD dst, vecD src, immI shift) %{
10813   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10814   match(Set dst (URShiftVI src (RShiftCntV shift)));
10815   size(4);
10816   ins_cost(DEFAULT_COST); // FIXME
10817   format %{
10818     "VSHR.U32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
10819   %}
10820   ins_encode %{
10821     bool quad = false;
10822     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10823              quad);
10824   %}
10825   ins_pipe( ialu_reg_reg ); // FIXME
10826 %}
10827 
10828 instruct vsrl4I_immI(vecX dst, vecX src, immI shift) %{
10829   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10830   match(Set dst (URShiftVI src (RShiftCntV shift)));
10831   size(4);
10832   ins_cost(DEFAULT_COST); // FIXME
10833   format %{
10834     "VSHR.U32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
10835   %}
10836   ins_encode %{
10837     bool quad = true;
10838     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10839              quad);
10840   %}
10841   ins_pipe( ialu_reg_reg ); // FIXME
10842 %}
10843 
10844 // Longs vector logical right shift
10845 instruct vsrl2L_immI(vecX dst, vecX src, immI shift) %{
10846   predicate(n->as_Vector()->length() == 2);
10847   match(Set dst (URShiftVL src (RShiftCntV shift)));
10848   size(4);
10849   ins_cost(DEFAULT_COST); // FIXME
10850   format %{
10851     "VSHR.U64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
10852   %}
10853   ins_encode %{
10854     bool quad = true;
10855     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
10856              quad);
10857   %}
10858   ins_pipe( ialu_reg_reg ); // FIXME
10859 %}
10860 
10861 // ------------------- ArithmeticRightShift -----------------------------------
10862 
10863 // Bytes vector arithmetic left/right shift based on sign
10864 instruct vsha8B_reg(vecD dst, vecD src, vecD shift) %{
10865   predicate(n->as_Vector()->length() == 8);
10866   effect(DEF dst, USE src, USE shift);
10867   size(4);
10868   ins_cost(DEFAULT_COST); // FIXME
10869   format %{
10870     "VSHL.S8 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed8B"
10871   %}
10872   ins_encode %{
10873     bool quad = false;
10874     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10875               MacroAssembler::VELEM_SIZE_8, quad);
10876   %}
10877   ins_pipe( ialu_reg_reg ); // FIXME
10878 %}
10879 
10880 instruct vsha16B_reg(vecX dst, vecX src, vecX shift) %{
10881   predicate(n->as_Vector()->length() == 16);
10882   effect(DEF dst, USE src, USE shift);
10883   size(4);
10884   ins_cost(DEFAULT_COST); // FIXME
10885   format %{
10886     "VSHL.S8 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed16B"
10887   %}
10888   ins_encode %{
10889     bool quad = true;
10890     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10891               MacroAssembler::VELEM_SIZE_8, quad);
10892   %}
10893   ins_pipe( ialu_reg_reg ); // FIXME
10894 %}
10895 
10896 // Shorts vector arithmetic left/right shift based on sign
10897 instruct vsha4S_reg(vecD dst, vecD src, vecD shift) %{
10898   predicate(n->as_Vector()->length() == 4);
10899   effect(DEF dst, USE src, USE shift);
10900   size(4);
10901   ins_cost(DEFAULT_COST); // FIXME
10902   format %{
10903     "VSHL.S16 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed4S"
10904   %}
10905   ins_encode %{
10906     bool quad = false;
10907     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10908               MacroAssembler::VELEM_SIZE_16, quad);
10909   %}
10910   ins_pipe( ialu_reg_reg ); // FIXME
10911 %}
10912 
10913 instruct vsha8S_reg(vecX dst, vecX src, vecX shift) %{
10914   predicate(n->as_Vector()->length() == 8);
10915   effect(DEF dst, USE src, USE shift);
10916   size(4);
10917   ins_cost(DEFAULT_COST); // FIXME
10918   format %{
10919     "VSHL.S16 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed8S"
10920   %}
10921   ins_encode %{
10922     bool quad = true;
10923     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10924               MacroAssembler::VELEM_SIZE_16, quad);
10925   %}
10926   ins_pipe( ialu_reg_reg ); // FIXME
10927 %}
10928 
10929 // Integers vector arithmetic left/right shift based on sign
10930 instruct vsha2I_reg(vecD dst, vecD src, vecD shift) %{
10931   predicate(n->as_Vector()->length() == 2);
10932   effect(DEF dst, USE src, USE shift);
10933   size(4);
10934   ins_cost(DEFAULT_COST); // FIXME
10935   format %{
10936     "VSHL.S32 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed2I"
10937   %}
10938   ins_encode %{
10939     bool quad = false;
10940     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10941               MacroAssembler::VELEM_SIZE_32, quad);
10942   %}
10943   ins_pipe( ialu_reg_reg ); // FIXME
10944 %}
10945 
10946 instruct vsha4I_reg(vecX dst, vecX src, vecX shift) %{
10947   predicate(n->as_Vector()->length() == 4);
10948   effect(DEF dst, USE src, USE shift);
10949   size(4);
10950   ins_cost(DEFAULT_COST); // FIXME
10951   format %{
10952     "VSHL.S32 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed4I"
10953   %}
10954   ins_encode %{
10955     bool quad = true;
10956     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10957               MacroAssembler::VELEM_SIZE_32, quad);
10958   %}
10959   ins_pipe( ialu_reg_reg ); // FIXME
10960 %}
10961 
10962 // Longs vector arithmetic left/right shift based on sign
10963 instruct vsha2L_reg(vecX dst, vecX src, vecX shift) %{
10964   predicate(n->as_Vector()->length() == 2);
10965   effect(DEF dst, USE src, USE shift);
10966   size(4);
10967   ins_cost(DEFAULT_COST); // FIXME
10968   format %{
10969     "VSHL.S64 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed2L"
10970   %}
10971   ins_encode %{
10972     bool quad = true;
10973     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10974               MacroAssembler::VELEM_SIZE_64, quad);
10975   %}
10976   ins_pipe( ialu_reg_reg ); // FIXME
10977 %}
10978 
10979 // Byte vector arithmetic right shift
10980 
10981 instruct vsra8B_reg(vecD dst, vecD src, vecD shift) %{
10982   predicate(n->as_Vector()->length() == 8);
10983   match(Set dst (RShiftVB src shift));
10984   size(4);
10985   ins_cost(DEFAULT_COST); // FIXME
10986   expand %{
10987     vsha8B_reg(dst, src, shift);
10988   %}
10989 %}
10990 
10991 instruct vsrl16B_reg(vecX dst, vecX src, vecX shift) %{
10992   predicate(n->as_Vector()->length() == 16);
10993   match(Set dst (RShiftVB src shift));
10994   size(4);
10995   ins_cost(DEFAULT_COST); // FIXME
10996   expand %{
10997     vsha16B_reg(dst, src, shift);
10998   %}
10999 %}
11000 
11001 instruct vsrl8B_immI(vecD dst, vecD src, immI shift) %{
11002   predicate(n->as_Vector()->length() == 8);
11003   match(Set dst (RShiftVB src shift));
11004   size(4);
11005   ins_cost(DEFAULT_COST); // FIXME
11006   format %{
11007     "VSHR.S8 $dst.D,$src.D,$shift\t! logical right shift packed8B"
11008   %}
11009   ins_encode %{
11010     bool quad = false;
11011     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
11012              quad);
11013   %}
11014   ins_pipe( ialu_reg_reg ); // FIXME
11015 %}
11016 
11017 instruct vsrl16B_immI(vecX dst, vecX src, immI shift) %{
11018   predicate(n->as_Vector()->length() == 16);
11019   match(Set dst (RShiftVB src shift));
11020   size(4);
11021   ins_cost(DEFAULT_COST); // FIXME
11022   format %{
11023     "VSHR.S8 $dst.Q,$src.Q,$shift\t! logical right shift packed16B"
11024   %}
11025   ins_encode %{
11026     bool quad = true;
11027     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
11028              quad);
11029   %}
11030   ins_pipe( ialu_reg_reg ); // FIXME
11031 %}
11032 
11033 // Shorts vector arithmetic right shift
11034 instruct vsra4S_reg(vecD dst, vecD src, vecD shift) %{
11035   predicate(n->as_Vector()->length() == 4);
11036   match(Set dst (RShiftVS src shift));
11037   size(4);
11038   ins_cost(DEFAULT_COST); // FIXME
11039   expand %{
11040     vsha4S_reg(dst, src, shift);
11041   %}
11042 %}
11043 
11044 instruct vsra8S_reg(vecX dst, vecX src, vecX shift) %{
11045   predicate(n->as_Vector()->length() == 8);
11046   match(Set dst (RShiftVS src shift));
11047   size(4);
11048   ins_cost(DEFAULT_COST); // FIXME
11049   expand %{
11050     vsha8S_reg(dst, src, shift);
11051   %}
11052 %}
11053 
11054 instruct vsra4S_immI(vecD dst, vecD src, immI shift) %{
11055   predicate(n->as_Vector()->length() == 4);
11056   match(Set dst (RShiftVS src shift));
11057   size(4);
11058   ins_cost(DEFAULT_COST); // FIXME
11059   format %{
11060     "VSHR.S16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
11061   %}
11062   ins_encode %{
11063     bool quad = false;
11064     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
11065              quad);
11066   %}
11067   ins_pipe( ialu_reg_reg ); // FIXME
11068 %}
11069 
11070 instruct vsra8S_immI(vecX dst, vecX src, immI shift) %{
11071   predicate(n->as_Vector()->length() == 8);
11072   match(Set dst (RShiftVS src shift));
11073   size(4);
11074   ins_cost(DEFAULT_COST); // FIXME
11075   format %{
11076     "VSHR.S16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
11077   %}
11078   ins_encode %{
11079     bool quad = true;
11080     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
11081              quad);
11082   %}
11083   ins_pipe( ialu_reg_reg ); // FIXME
11084 %}
11085 
11086 // Integers vector arithmetic right shift
11087 instruct vsra2I_reg(vecD dst, vecD src, vecD shift) %{
11088   predicate(n->as_Vector()->length() == 2);
11089   match(Set dst (RShiftVI src shift));
11090   size(4);
11091   ins_cost(DEFAULT_COST); // FIXME
11092   expand %{
11093     vsha2I_reg(dst, src, shift);
11094   %}
11095 %}
11096 
11097 instruct vsra4I_reg(vecX dst, vecX src, vecX shift) %{
11098   predicate(n->as_Vector()->length() == 4);
11099   match(Set dst (RShiftVI src shift));
11100   size(4);
11101   ins_cost(DEFAULT_COST); // FIXME
11102   expand %{
11103     vsha4I_reg(dst, src, shift);
11104   %}
11105 %}
11106 
11107 instruct vsra2I_immI(vecD dst, vecD src, immI shift) %{
11108   predicate(n->as_Vector()->length() == 2);
11109   match(Set dst (RShiftVI src shift));
11110   size(4);
11111   ins_cost(DEFAULT_COST); // FIXME
11112   format %{
11113     "VSHR.S32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
11114   %}
11115   ins_encode %{
11116     bool quad = false;
11117     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11118              quad);
11119   %}
11120   ins_pipe( ialu_reg_reg ); // FIXME
11121 %}
11122 
11123 instruct vsra4I_immI(vecX dst, vecX src, immI shift) %{
11124   predicate(n->as_Vector()->length() == 4);
11125   match(Set dst (RShiftVI src shift));
11126   size(4);
11127   ins_cost(DEFAULT_COST); // FIXME
11128   format %{
11129     "VSHR.S32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
11130   %}
11131   ins_encode %{
11132     bool quad = true;
11133     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11134              quad);
11135   %}
11136   ins_pipe( ialu_reg_reg ); // FIXME
11137 %}
11138 
11139 // Longs vector arithmetic right shift
11140 instruct vsra2L_reg(vecX dst, vecX src, vecX shift) %{
11141   predicate(n->as_Vector()->length() == 2);
11142   match(Set dst (RShiftVL src shift));
11143   size(4);
11144   ins_cost(DEFAULT_COST); // FIXME
11145   expand %{
11146     vsha2L_reg(dst, src, shift);
11147   %}
11148 %}
11149 
11150 instruct vsra2L_immI(vecX dst, vecX src, immI shift) %{
11151   predicate(n->as_Vector()->length() == 2);
11152   match(Set dst (RShiftVL src shift));
11153   size(4);
11154   ins_cost(DEFAULT_COST); // FIXME
11155   format %{
11156     "VSHR.S64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
11157   %}
11158   ins_encode %{
11159     bool quad = true;
11160     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
11161              quad);
11162   %}
11163   ins_pipe( ialu_reg_reg ); // FIXME
11164 %}
11165 
11166 // --------------------------------- AND --------------------------------------
11167 
11168 instruct vandD(vecD dst, vecD src1, vecD src2) %{
11169   predicate(n->as_Vector()->length_in_bytes() == 8);
11170   match(Set dst (AndV src1 src2));
11171   format %{ "VAND    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11172   ins_encode %{
11173     bool quad = false;
11174     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11175              quad);
11176   %}
11177   ins_pipe( ialu_reg_reg ); // FIXME
11178 %}
11179 
11180 instruct vandX(vecX dst, vecX src1, vecX src2) %{
11181   predicate(n->as_Vector()->length_in_bytes() == 16);
11182   match(Set dst (AndV src1 src2));
11183   format %{ "VAND    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11184   ins_encode %{
11185     bool quad = true;
11186     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11187              quad);
11188   %}
11189   ins_pipe( ialu_reg_reg ); // FIXME
11190 %}
11191 
11192 // --------------------------------- OR ---------------------------------------
11193 
11194 instruct vorD(vecD dst, vecD src1, vecD src2) %{
11195   predicate(n->as_Vector()->length_in_bytes() == 8);
11196   match(Set dst (OrV src1 src2));
11197   format %{ "VOR     $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11198   ins_encode %{
11199     bool quad = false;
11200     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11201             quad);
11202   %}
11203   ins_pipe( ialu_reg_reg ); // FIXME
11204 %}
11205 
11206 instruct vorX(vecX dst, vecX src1, vecX src2) %{
11207   predicate(n->as_Vector()->length_in_bytes() == 16);
11208   match(Set dst (OrV src1 src2));
11209   format %{ "VOR     $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11210   ins_encode %{
11211     bool quad = true;
11212     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11213             quad);
11214   %}
11215   ins_pipe( ialu_reg_reg ); // FIXME
11216 %}
11217 
11218 // --------------------------------- XOR --------------------------------------
11219 
11220 instruct vxorD(vecD dst, vecD src1, vecD src2) %{
11221   predicate(n->as_Vector()->length_in_bytes() == 8);
11222   match(Set dst (XorV src1 src2));
11223   format %{ "VXOR    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11224   ins_encode %{
11225     bool quad = false;
11226     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11227              quad);
11228   %}
11229   ins_pipe( ialu_reg_reg ); // FIXME
11230 %}
11231 
11232 instruct vxorX(vecX dst, vecX src1, vecX src2) %{
11233   predicate(n->as_Vector()->length_in_bytes() == 16);
11234   match(Set dst (XorV src1 src2));
11235   format %{ "VXOR    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11236   ins_encode %{
11237     bool quad = true;
11238     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11239              quad);
11240   %}
11241   ins_pipe( ialu_reg_reg ); // FIXME
11242 %}
11243 
11244 
11245 //----------PEEPHOLE RULES-----------------------------------------------------
11246 // These must follow all instruction definitions as they use the names
11247 // defined in the instructions definitions.
11248 //
11249 // peepmatch ( root_instr_name [preceding_instruction]* );
11250 //
11251 // peepconstraint %{
11252 // (instruction_number.operand_name relational_op instruction_number.operand_name
11253 //  [, ...] );
11254 // // instruction numbers are zero-based using left to right order in peepmatch
11255 //
11256 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
11257 // // provide an instruction_number.operand_name for each operand that appears
11258 // // in the replacement instruction's match rule
11259 //
11260 // ---------VM FLAGS---------------------------------------------------------
11261 //
11262 // All peephole optimizations can be turned off using -XX:-OptoPeephole
11263 //
11264 // Each peephole rule is given an identifying number starting with zero and
11265 // increasing by one in the order seen by the parser.  An individual peephole
11266 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
11267 // on the command-line.
11268 //
11269 // ---------CURRENT LIMITATIONS----------------------------------------------
11270 //
11271 // Only match adjacent instructions in same basic block
11272 // Only equality constraints
11273 // Only constraints between operands, not (0.dest_reg == EAX_enc)
11274 // Only one replacement instruction
11275 //
11276 // ---------EXAMPLE----------------------------------------------------------
11277 //
11278 // // pertinent parts of existing instructions in architecture description
11279 // instruct movI(eRegI dst, eRegI src) %{
11280 //   match(Set dst (CopyI src));
11281 // %}
11282 //
11283 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
11284 //   match(Set dst (AddI dst src));
11285 //   effect(KILL cr);
11286 // %}
11287 //
11288 // // Change (inc mov) to lea
11289 // peephole %{
11290 //   // increment preceeded by register-register move
11291 //   peepmatch ( incI_eReg movI );
11292 //   // require that the destination register of the increment
11293 //   // match the destination register of the move
11294 //   peepconstraint ( 0.dst == 1.dst );
11295 //   // construct a replacement instruction that sets
11296 //   // the destination to ( move's source register + one )
11297 //   peepreplace ( incI_eReg_immI1( 0.dst 1.src 0.src ) );
11298 // %}
11299 //
11300 
11301 // // Change load of spilled value to only a spill
11302 // instruct storeI(memory mem, eRegI src) %{
11303 //   match(Set mem (StoreI mem src));
11304 // %}
11305 //
11306 // instruct loadI(eRegI dst, memory mem) %{
11307 //   match(Set dst (LoadI mem));
11308 // %}
11309 //
11310 // peephole %{
11311 //   peepmatch ( loadI storeI );
11312 //   peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
11313 //   peepreplace ( storeI( 1.mem 1.mem 1.src ) );
11314 // %}
11315 
11316 //----------SMARTSPILL RULES---------------------------------------------------
11317 // These must follow all instruction definitions as they use the names
11318 // defined in the instructions definitions.
11319 //
11320 // ARM will probably not have any of these rules due to RISC instruction set.
11321 
11322 //----------PIPELINE-----------------------------------------------------------
11323 // Rules which define the behavior of the target architectures pipeline.