1 //
   2 // Copyright (c) 2008, 2018, 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 %}
 120 
 121 source %{
 122 #define __ _masm.
 123 
 124 static FloatRegister reg_to_FloatRegister_object(int register_encoding);
 125 static Register reg_to_register_object(int register_encoding);
 126 
 127 
 128 // ****************************************************************************
 129 
 130 // REQUIRED FUNCTIONALITY
 131 
 132 // Indicate if the safepoint node needs the polling page as an input.
 133 // Since ARM does not have absolute addressing, it does.
 134 bool SafePointNode::needs_polling_address_input() {
 135   return true;
 136 }
 137 
 138 // emit an interrupt that is caught by the debugger (for debugging compiler)
 139 void emit_break(CodeBuffer &cbuf) {
 140   MacroAssembler _masm(&cbuf);
 141   __ breakpoint();
 142 }
 143 
 144 #ifndef PRODUCT
 145 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream *st ) const {
 146   st->print("TA");
 147 }
 148 #endif
 149 
 150 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 151   emit_break(cbuf);
 152 }
 153 
 154 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
 155   return MachNode::size(ra_);
 156 }
 157 
 158 
 159 void emit_nop(CodeBuffer &cbuf) {
 160   MacroAssembler _masm(&cbuf);
 161   __ nop();
 162 }
 163 
 164 
 165 void emit_call_reloc(CodeBuffer &cbuf, const MachCallNode *n, MachOper *m, RelocationHolder const& rspec) {
 166   int ret_addr_offset0 = n->as_MachCall()->ret_addr_offset();
 167   int call_site_offset = cbuf.insts()->mark_off();
 168   MacroAssembler _masm(&cbuf);
 169   __ set_inst_mark(); // needed in emit_to_interp_stub() to locate the call
 170   address target = (address)m->method();
 171   assert(n->as_MachCall()->entry_point() == target, "sanity");
 172   assert(maybe_far_call(n) == !__ reachable_from_cache(target), "sanity");
 173   assert(cache_reachable() == __ cache_fully_reachable(), "sanity");
 174 
 175   assert(target != NULL, "need real address");
 176 
 177   int ret_addr_offset = -1;
 178   if (rspec.type() == relocInfo::runtime_call_type) {
 179     __ call(target, rspec);
 180     ret_addr_offset = __ offset();
 181   } else {
 182     // scratches Rtemp
 183     ret_addr_offset = __ patchable_call(target, rspec, true);
 184   }
 185   assert(ret_addr_offset - call_site_offset == ret_addr_offset0, "fix ret_addr_offset()");
 186 }
 187 
 188 //=============================================================================
 189 // REQUIRED FUNCTIONALITY for encoding
 190 void emit_lo(CodeBuffer &cbuf, int val) {  }
 191 void emit_hi(CodeBuffer &cbuf, int val) {  }
 192 
 193 
 194 //=============================================================================
 195 const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask();
 196 
 197 int Compile::ConstantTable::calculate_table_base_offset() const {
 198   int offset = -(size() / 2);
 199   // flds, fldd: 8-bit  offset multiplied by 4: +/- 1024
 200   // ldr, ldrb : 12-bit offset:                 +/- 4096
 201   if (!Assembler::is_simm10(offset)) {
 202     offset = Assembler::min_simm10();
 203   }
 204   return offset;
 205 }
 206 
 207 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
 208 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
 209   ShouldNotReachHere();
 210 }
 211 
 212 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
 213   Compile* C = ra_->C;
 214   Compile::ConstantTable& constant_table = C->constant_table();
 215   MacroAssembler _masm(&cbuf);
 216 
 217   Register r = as_Register(ra_->get_encode(this));
 218   CodeSection* consts_section = __ code()->consts();
 219   int consts_size = consts_section->align_at_start(consts_section->size());
 220   assert(constant_table.size() == consts_size, "must be: %d == %d", constant_table.size(), consts_size);
 221 
 222   // Materialize the constant table base.
 223   address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
 224   RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
 225   __ mov_address(r, baseaddr, rspec);
 226 }
 227 
 228 uint MachConstantBaseNode::size(PhaseRegAlloc*) const {
 229   return 8;
 230 }
 231 
 232 #ifndef PRODUCT
 233 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
 234   char reg[128];
 235   ra_->dump_register(this, reg);
 236   st->print("MOV_SLOW    &constanttable,%s\t! constant table base", reg);
 237 }
 238 #endif
 239 
 240 #ifndef PRODUCT
 241 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
 242   Compile* C = ra_->C;
 243 
 244   for (int i = 0; i < OptoPrologueNops; i++) {
 245     st->print_cr("NOP"); st->print("\t");
 246   }
 247 
 248   size_t framesize = C->frame_size_in_bytes();
 249   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
 250   int bangsize = C->bang_size_in_bytes();
 251   // Remove two words for return addr and rbp,
 252   framesize -= 2*wordSize;
 253   bangsize -= 2*wordSize;
 254 
 255   // Calls to C2R adapters often do not accept exceptional returns.
 256   // We require that their callers must bang for them.  But be careful, because
 257   // some VM calls (such as call site linkage) can use several kilobytes of
 258   // stack.  But the stack safety zone should account for that.
 259   // See bugs 4446381, 4468289, 4497237.
 260   if (C->need_stack_bang(bangsize)) {
 261     st->print_cr("! stack bang (%d bytes)", bangsize); st->print("\t");
 262   }
 263   st->print_cr("PUSH   R_FP|R_LR_LR"); st->print("\t");
 264   if (framesize != 0) {
 265     st->print   ("SUB    R_SP, R_SP, " SIZE_FORMAT,framesize);
 266   }
 267 }
 268 #endif
 269 
 270 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 271   Compile* C = ra_->C;
 272   MacroAssembler _masm(&cbuf);
 273 
 274   for (int i = 0; i < OptoPrologueNops; i++) {
 275     __ nop();
 276   }
 277 
 278   size_t framesize = C->frame_size_in_bytes();
 279   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
 280   int bangsize = C->bang_size_in_bytes();
 281   // Remove two words for return addr and fp,
 282   framesize -= 2*wordSize;
 283   bangsize -= 2*wordSize;
 284 
 285   // Calls to C2R adapters often do not accept exceptional returns.
 286   // We require that their callers must bang for them.  But be careful, because
 287   // some VM calls (such as call site linkage) can use several kilobytes of
 288   // stack.  But the stack safety zone should account for that.
 289   // See bugs 4446381, 4468289, 4497237.
 290   if (C->need_stack_bang(bangsize)) {
 291     __ arm_stack_overflow_check(bangsize, Rtemp);
 292   }
 293 
 294   __ raw_push(FP, LR);
 295   if (framesize != 0) {
 296     __ sub_slow(SP, SP, framesize);
 297   }
 298 
 299   // offset from scratch buffer is not valid
 300   if (strcmp(cbuf.name(), "Compile::Fill_buffer") == 0) {
 301     C->set_frame_complete( __ offset() );
 302   }
 303 
 304   if (C->has_mach_constant_base_node()) {
 305     // NOTE: We set the table base offset here because users might be
 306     // emitted before MachConstantBaseNode.
 307     Compile::ConstantTable& constant_table = C->constant_table();
 308     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
 309   }
 310 }
 311 
 312 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
 313   return MachNode::size(ra_);
 314 }
 315 
 316 int MachPrologNode::reloc() const {
 317   return 10; // a large enough number
 318 }
 319 
 320 //=============================================================================
 321 #ifndef PRODUCT
 322 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
 323   Compile* C = ra_->C;
 324 
 325   size_t framesize = C->frame_size_in_bytes();
 326   framesize -= 2*wordSize;
 327 
 328   if (framesize != 0) {
 329     st->print("ADD    R_SP, R_SP, " SIZE_FORMAT "\n\t",framesize);
 330   }
 331   st->print("POP    R_FP|R_LR_LR");
 332 
 333   if (do_polling() && ra_->C->is_method_compilation()) {
 334     st->print("\n\t");
 335     st->print("MOV    Rtemp, #PollAddr\t! Load Polling address\n\t");
 336     st->print("LDR    Rtemp,[Rtemp]\t!Poll for Safepointing");
 337   }
 338 }
 339 #endif
 340 
 341 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 342   MacroAssembler _masm(&cbuf);
 343   Compile* C = ra_->C;
 344 
 345   size_t framesize = C->frame_size_in_bytes();
 346   framesize -= 2*wordSize;
 347   if (framesize != 0) {
 348     __ add_slow(SP, SP, framesize);
 349   }
 350   __ raw_pop(FP, LR);
 351 
 352   // If this does safepoint polling, then do it here
 353   if (do_polling() && ra_->C->is_method_compilation()) {
 354     // mov_slow here is usually one or two instruction
 355     __ mov_address(Rtemp, (address)os::get_polling_page());
 356     __ relocate(relocInfo::poll_return_type);
 357     __ ldr(Rtemp, Address(Rtemp));
 358   }
 359 }
 360 
 361 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
 362   return MachNode::size(ra_);
 363 }
 364 
 365 int MachEpilogNode::reloc() const {
 366   return 16; // a large enough number
 367 }
 368 
 369 const Pipeline * MachEpilogNode::pipeline() const {
 370   return MachNode::pipeline_class();
 371 }
 372 
 373 int MachEpilogNode::safepoint_offset() const {
 374   assert( do_polling(), "no return for this epilog node");
 375   //  return MacroAssembler::size_of_sethi(os::get_polling_page());
 376   Unimplemented();
 377   return 0;
 378 }
 379 
 380 //=============================================================================
 381 
 382 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
 383 enum RC { rc_bad, rc_int, rc_float, rc_stack };
 384 static enum RC rc_class( OptoReg::Name reg ) {
 385   if (!OptoReg::is_valid(reg)) return rc_bad;
 386   if (OptoReg::is_stack(reg)) return rc_stack;
 387   VMReg r = OptoReg::as_VMReg(reg);
 388   if (r->is_Register()) return rc_int;
 389   assert(r->is_FloatRegister(), "must be");
 390   return rc_float;
 391 }
 392 
 393 static inline bool is_iRegLd_memhd(OptoReg::Name src_first, OptoReg::Name src_second, int offset) {
 394   int rlo = Matcher::_regEncode[src_first];
 395   int rhi = Matcher::_regEncode[src_second];
 396   if (!((rlo&1)==0 && (rlo+1 == rhi))) {
 397     tty->print_cr("CAUGHT BAD LDRD/STRD");
 398   }
 399   return (rlo&1)==0 && (rlo+1 == rhi) && is_memoryHD(offset);
 400 }
 401 
 402 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
 403                                         PhaseRegAlloc *ra_,
 404                                         bool do_size,
 405                                         outputStream* st ) const {
 406   // Get registers to move
 407   OptoReg::Name src_second = ra_->get_reg_second(in(1));
 408   OptoReg::Name src_first = ra_->get_reg_first(in(1));
 409   OptoReg::Name dst_second = ra_->get_reg_second(this );
 410   OptoReg::Name dst_first = ra_->get_reg_first(this );
 411 
 412   enum RC src_second_rc = rc_class(src_second);
 413   enum RC src_first_rc = rc_class(src_first);
 414   enum RC dst_second_rc = rc_class(dst_second);
 415   enum RC dst_first_rc = rc_class(dst_first);
 416 
 417   assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
 418 
 419   // Generate spill code!
 420   int size = 0;
 421 
 422   if (src_first == dst_first && src_second == dst_second)
 423     return size;            // Self copy, no move
 424 
 425 #ifdef TODO
 426   if (bottom_type()->isa_vect() != NULL) {
 427   }
 428 #endif
 429 
 430   // Shared code does not expect instruction set capability based bailouts here.
 431   // Handle offset unreachable bailout with minimal change in shared code.
 432   // Bailout only for real instruction emit.
 433   // This requires a single comment change in shared code. ( see output.cpp "Normal" instruction case )
 434 
 435   MacroAssembler _masm(cbuf);
 436 
 437   // --------------------------------------
 438   // Check for mem-mem move.  Load into unused float registers and fall into
 439   // the float-store case.
 440   if (src_first_rc == rc_stack && dst_first_rc == rc_stack) {
 441     int offset = ra_->reg2offset(src_first);
 442     if (cbuf && !is_memoryfp(offset)) {
 443       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 444       return 0;
 445     } else {
 446       if (src_second_rc != rc_bad) {
 447         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
 448         src_first     = OptoReg::Name(R_mem_copy_lo_num);
 449         src_second    = OptoReg::Name(R_mem_copy_hi_num);
 450         src_first_rc  = rc_float;
 451         src_second_rc = rc_float;
 452         if (cbuf) {
 453           __ ldr_double(Rmemcopy, Address(SP, offset));
 454         } else if (!do_size) {
 455           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
 456         }
 457       } else {
 458         src_first     = OptoReg::Name(R_mem_copy_lo_num);
 459         src_first_rc  = rc_float;
 460         if (cbuf) {
 461           __ ldr_float(Rmemcopy, Address(SP, offset));
 462         } else if (!do_size) {
 463           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
 464         }
 465       }
 466       size += 4;
 467     }
 468   }
 469 
 470   if (src_second_rc == rc_stack && dst_second_rc == rc_stack) {
 471     Unimplemented();
 472   }
 473 
 474   // --------------------------------------
 475   // Check for integer reg-reg copy
 476   if (src_first_rc == rc_int && dst_first_rc == rc_int) {
 477     // Else normal reg-reg copy
 478     assert( src_second != dst_first, "smashed second before evacuating it" );
 479     if (cbuf) {
 480       __ mov(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
 481 #ifndef PRODUCT
 482     } else if (!do_size) {
 483       st->print("MOV    R_%s, R_%s\t# spill",
 484                 Matcher::regName[dst_first],
 485                 Matcher::regName[src_first]);
 486 #endif
 487     }
 488     size += 4;
 489   }
 490 
 491   // Check for integer store
 492   if (src_first_rc == rc_int && dst_first_rc == rc_stack) {
 493     int offset = ra_->reg2offset(dst_first);
 494     if (cbuf && !is_memoryI(offset)) {
 495       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 496       return 0;
 497     } else {
 498       if (src_second_rc != rc_bad && is_iRegLd_memhd(src_first, src_second, offset)) {
 499         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
 500         if (cbuf) {
 501           __ str_64(reg_to_register_object(Matcher::_regEncode[src_first]), Address(SP, offset));
 502 #ifndef PRODUCT
 503         } else if (!do_size) {
 504           if (size != 0) st->print("\n\t");
 505           st->print(STR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
 506 #endif
 507         }
 508         return size + 4;
 509       } else {
 510         if (cbuf) {
 511           __ str_32(reg_to_register_object(Matcher::_regEncode[src_first]), Address(SP, offset));
 512 #ifndef PRODUCT
 513         } else if (!do_size) {
 514           if (size != 0) st->print("\n\t");
 515           st->print(STR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first), offset);
 516 #endif
 517         }
 518       }
 519     }
 520     size += 4;
 521   }
 522 
 523   // Check for integer load
 524   if (dst_first_rc == rc_int && src_first_rc == rc_stack) {
 525     int offset = ra_->reg2offset(src_first);
 526     if (cbuf && !is_memoryI(offset)) {
 527       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 528       return 0;
 529     } else {
 530       if (src_second_rc != rc_bad && is_iRegLd_memhd(dst_first, dst_second, offset)) {
 531         assert((src_first&1)==0 && src_first+1 == src_second, "pair of registers must be aligned/contiguous");
 532         if (cbuf) {
 533           __ ldr_64(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
 534 #ifndef PRODUCT
 535         } else if (!do_size) {
 536           if (size != 0) st->print("\n\t");
 537           st->print(LDR_64 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
 538 #endif
 539         }
 540         return size + 4;
 541       } else {
 542         if (cbuf) {
 543           __ ldr_32(reg_to_register_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
 544 #ifndef PRODUCT
 545         } else if (!do_size) {
 546           if (size != 0) st->print("\n\t");
 547           st->print(LDR_32 "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first), offset);
 548 #endif
 549         }
 550       }
 551     }
 552     size += 4;
 553   }
 554 
 555   // Check for float reg-reg copy
 556   if (src_first_rc == rc_float && dst_first_rc == rc_float) {
 557     if (src_second_rc != rc_bad) {
 558       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");
 559       if (cbuf) {
 560       __ mov_double(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
 561 #ifndef PRODUCT
 562       } else if (!do_size) {
 563         st->print(MOV_DOUBLE "    R_%s, R_%s\t# spill",
 564                   Matcher::regName[dst_first],
 565                   Matcher::regName[src_first]);
 566 #endif
 567       }
 568       return 4;
 569     }
 570     if (cbuf) {
 571       __ mov_float(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
 572 #ifndef PRODUCT
 573     } else if (!do_size) {
 574       st->print(MOV_FLOAT "    R_%s, R_%s\t# spill",
 575                 Matcher::regName[dst_first],
 576                 Matcher::regName[src_first]);
 577 #endif
 578     }
 579     size = 4;
 580   }
 581 
 582   // Check for float store
 583   if (src_first_rc == rc_float && dst_first_rc == rc_stack) {
 584     int offset = ra_->reg2offset(dst_first);
 585     if (cbuf && !is_memoryfp(offset)) {
 586       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 587       return 0;
 588     } else {
 589       // Further check for aligned-adjacent pair, so we can use a double store
 590       if (src_second_rc != rc_bad) {
 591         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");
 592         if (cbuf) {
 593           __ str_double(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(SP, offset));
 594 #ifndef PRODUCT
 595         } else if (!do_size) {
 596           if (size != 0) st->print("\n\t");
 597           st->print(STR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
 598 #endif
 599         }
 600         return size + 4;
 601       } else {
 602         if (cbuf) {
 603           __ str_float(reg_to_FloatRegister_object(Matcher::_regEncode[src_first]), Address(SP, offset));
 604 #ifndef PRODUCT
 605         } else if (!do_size) {
 606           if (size != 0) st->print("\n\t");
 607           st->print(STR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_first),offset);
 608 #endif
 609         }
 610       }
 611     }
 612     size += 4;
 613   }
 614 
 615   // Check for float load
 616   if (dst_first_rc == rc_float && src_first_rc == rc_stack) {
 617     int offset = ra_->reg2offset(src_first);
 618     if (cbuf && !is_memoryfp(offset)) {
 619       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 620       return 0;
 621     } else {
 622       // Further check for aligned-adjacent pair, so we can use a double store
 623       if (src_second_rc != rc_bad) {
 624         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");
 625         if (cbuf) {
 626           __ ldr_double(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
 627 #ifndef PRODUCT
 628         } else if (!do_size) {
 629           if (size != 0) st->print("\n\t");
 630           st->print(LDR_DOUBLE "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
 631 #endif
 632         }
 633         return size + 4;
 634       } else {
 635         if (cbuf) {
 636           __ ldr_float(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), Address(SP, offset));
 637 #ifndef PRODUCT
 638         } else if (!do_size) {
 639           if (size != 0) st->print("\n\t");
 640           st->print(LDR_FLOAT "   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_first),offset);
 641 #endif
 642         }
 643       }
 644     }
 645     size += 4;
 646   }
 647 
 648   // check for int reg -> float reg move
 649   if (src_first_rc == rc_int && dst_first_rc == rc_float) {
 650     // Further check for aligned-adjacent pair, so we can use a single instruction
 651     if (src_second_rc != rc_bad) {
 652       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
 653       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
 654       assert(src_second_rc == rc_int && dst_second_rc == rc_float, "unsupported");
 655       if (cbuf) {
 656         __ 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]));
 657 #ifndef PRODUCT
 658       } else if (!do_size) {
 659         if (size != 0) st->print("\n\t");
 660         st->print("FMDRR   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first), OptoReg::regname(src_second));
 661 #endif
 662       }
 663       return size + 4;
 664     } else {
 665       if (cbuf) {
 666         __ fmsr(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
 667 #ifndef PRODUCT
 668       } else if (!do_size) {
 669         if (size != 0) st->print("\n\t");
 670         st->print(FMSR "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
 671 #endif
 672       }
 673       size += 4;
 674     }
 675   }
 676 
 677   // check for float reg -> int reg move
 678   if (src_first_rc == rc_float && dst_first_rc == rc_int) {
 679     // Further check for aligned-adjacent pair, so we can use a single instruction
 680     if (src_second_rc != rc_bad) {
 681       assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
 682       assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
 683       assert(src_second_rc == rc_float && dst_second_rc == rc_int, "unsupported");
 684       if (cbuf) {
 685         __ 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]));
 686 #ifndef PRODUCT
 687       } else if (!do_size) {
 688         if (size != 0) st->print("\n\t");
 689         st->print("FMRRD   R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(dst_second), OptoReg::regname(src_first));
 690 #endif
 691       }
 692       return size + 4;
 693     } else {
 694       if (cbuf) {
 695         __ fmrs(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
 696 #ifndef PRODUCT
 697       } else if (!do_size) {
 698         if (size != 0) st->print("\n\t");
 699         st->print(FMRS "   R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
 700 #endif
 701       }
 702       size += 4;
 703     }
 704   }
 705 
 706   // --------------------------------------------------------------------
 707   // Check for hi bits still needing moving.  Only happens for misaligned
 708   // arguments to native calls.
 709   if (src_second == dst_second)
 710     return size;               // Self copy; no move
 711   assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" );
 712 
 713   // Check for integer reg-reg copy.  Hi bits are stuck up in the top
 714   // 32-bits of a 64-bit register, but are needed in low bits of another
 715   // register (else it's a hi-bits-to-hi-bits copy which should have
 716   // happened already as part of a 64-bit move)
 717   if (src_second_rc == rc_int && dst_second_rc == rc_int) {
 718     if (cbuf) {
 719       __ mov(reg_to_register_object(Matcher::_regEncode[dst_second]), reg_to_register_object(Matcher::_regEncode[src_second]));
 720 #ifndef PRODUCT
 721     } else if (!do_size) {
 722       if (size != 0) st->print("\n\t");
 723       st->print("MOV    R_%s, R_%s\t# spill high",
 724                 Matcher::regName[dst_second],
 725                 Matcher::regName[src_second]);
 726 #endif
 727     }
 728     return size+4;
 729   }
 730 
 731   // Check for high word integer store
 732   if (src_second_rc == rc_int && dst_second_rc == rc_stack) {
 733     int offset = ra_->reg2offset(dst_second);
 734 
 735     if (cbuf && !is_memoryP(offset)) {
 736       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 737       return 0;
 738     } else {
 739       if (cbuf) {
 740         __ str(reg_to_register_object(Matcher::_regEncode[src_second]), Address(SP, offset));
 741 #ifndef PRODUCT
 742       } else if (!do_size) {
 743         if (size != 0) st->print("\n\t");
 744         st->print("STR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(src_second), offset);
 745 #endif
 746       }
 747     }
 748     return size + 4;
 749   }
 750 
 751   // Check for high word integer load
 752   if (dst_second_rc == rc_int && src_second_rc == rc_stack) {
 753     int offset = ra_->reg2offset(src_second);
 754     if (cbuf && !is_memoryP(offset)) {
 755       ra_->C->record_method_not_compilable("unable to handle large constant offsets");
 756       return 0;
 757     } else {
 758       if (cbuf) {
 759         __ ldr(reg_to_register_object(Matcher::_regEncode[dst_second]), Address(SP, offset));
 760 #ifndef PRODUCT
 761       } else if (!do_size) {
 762         if (size != 0) st->print("\n\t");
 763         st->print("LDR   R_%s,[R_SP + #%d]\t! spill",OptoReg::regname(dst_second), offset);
 764 #endif
 765       }
 766     }
 767     return size + 4;
 768   }
 769 
 770   Unimplemented();
 771   return 0; // Mute compiler
 772 }
 773 
 774 #ifndef PRODUCT
 775 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
 776   implementation( NULL, ra_, false, st );
 777 }
 778 #endif
 779 
 780 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 781   implementation( &cbuf, ra_, false, NULL );
 782 }
 783 
 784 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
 785   return implementation( NULL, ra_, true, NULL );
 786 }
 787 
 788 //=============================================================================
 789 #ifndef PRODUCT
 790 void MachNopNode::format( PhaseRegAlloc *, outputStream *st ) const {
 791   st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
 792 }
 793 #endif
 794 
 795 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
 796   MacroAssembler _masm(&cbuf);
 797   for(int i = 0; i < _count; i += 1) {
 798     __ nop();
 799   }
 800 }
 801 
 802 uint MachNopNode::size(PhaseRegAlloc *ra_) const {
 803   return 4 * _count;
 804 }
 805 
 806 
 807 //=============================================================================
 808 #ifndef PRODUCT
 809 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
 810   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
 811   int reg = ra_->get_reg_first(this);
 812   st->print("ADD    %s,R_SP+#%d",Matcher::regName[reg], offset);
 813 }
 814 #endif
 815 
 816 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 817   MacroAssembler _masm(&cbuf);
 818   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
 819   int reg = ra_->get_encode(this);
 820   Register dst = reg_to_register_object(reg);
 821 
 822   if (is_aimm(offset)) {
 823     __ add(dst, SP, offset);
 824   } else {
 825     __ mov_slow(dst, offset);
 826     __ add(dst, SP, dst);
 827   }
 828 }
 829 
 830 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
 831   // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_)
 832   assert(ra_ == ra_->C->regalloc(), "sanity");
 833   return ra_->C->scratch_emit_size(this);
 834 }
 835 
 836 //=============================================================================
 837 #ifndef PRODUCT
 838 #define R_RTEMP "R_R12"
 839 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
 840   st->print_cr("\nUEP:");
 841   if (UseCompressedClassPointers) {
 842     st->print_cr("\tLDR_w " R_RTEMP ",[R_R0 + oopDesc::klass_offset_in_bytes]\t! Inline cache check");
 843     st->print_cr("\tdecode_klass " R_RTEMP);
 844   } else {
 845     st->print_cr("\tLDR   " R_RTEMP ",[R_R0 + oopDesc::klass_offset_in_bytes]\t! Inline cache check");
 846   }
 847   st->print_cr("\tCMP   " R_RTEMP ",R_R8" );
 848   st->print   ("\tB.NE  SharedRuntime::handle_ic_miss_stub");
 849 }
 850 #endif
 851 
 852 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 853   MacroAssembler _masm(&cbuf);
 854   Register iCache  = reg_to_register_object(Matcher::inline_cache_reg_encode());
 855   assert(iCache == Ricklass, "should be");
 856   Register receiver = R0;
 857 
 858   __ load_klass(Rtemp, receiver);
 859   __ cmp(Rtemp, iCache);
 860   __ jump(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type, noreg, ne);
 861 }
 862 
 863 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
 864   return MachNode::size(ra_);
 865 }
 866 
 867 
 868 //=============================================================================
 869 
 870 // Emit exception handler code.
 871 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) {
 872   MacroAssembler _masm(&cbuf);
 873 
 874   address base = __ start_a_stub(size_exception_handler());
 875   if (base == NULL) {
 876     ciEnv::current()->record_failure("CodeCache is full");
 877     return 0;  // CodeBuffer::expand failed
 878   }
 879 
 880   int offset = __ offset();
 881 
 882   // OK to trash LR, because exception blob will kill it
 883   __ jump(OptoRuntime::exception_blob()->entry_point(), relocInfo::runtime_call_type, LR_tmp);
 884 
 885   assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
 886 
 887   __ end_a_stub();
 888 
 889   return offset;
 890 }
 891 
 892 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
 893   // Can't use any of the current frame's registers as we may have deopted
 894   // at a poll and everything can be live.
 895   MacroAssembler _masm(&cbuf);
 896 
 897   address base = __ start_a_stub(size_deopt_handler());
 898   if (base == NULL) {
 899     ciEnv::current()->record_failure("CodeCache is full");
 900     return 0;  // CodeBuffer::expand failed
 901   }
 902 
 903   int offset = __ offset();
 904   address deopt_pc = __ pc();
 905 
 906   __ sub(SP, SP, wordSize); // make room for saved PC
 907   __ push(LR); // save LR that may be live when we get here
 908   __ mov_relative_address(LR, deopt_pc);
 909   __ str(LR, Address(SP, wordSize)); // save deopt PC
 910   __ pop(LR); // restore LR
 911   __ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, noreg);
 912 
 913   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
 914 
 915   __ end_a_stub();
 916   return offset;
 917 }
 918 
 919 const bool Matcher::match_rule_supported(int opcode) {
 920   if (!has_match_rule(opcode))
 921     return false;
 922 
 923   switch (opcode) {
 924   case Op_PopCountI:
 925   case Op_PopCountL:
 926     if (!UsePopCountInstruction)
 927       return false;
 928     break;
 929   case Op_LShiftCntV:
 930   case Op_RShiftCntV:
 931   case Op_AddVB:
 932   case Op_AddVS:
 933   case Op_AddVI:
 934   case Op_AddVL:
 935   case Op_SubVB:
 936   case Op_SubVS:
 937   case Op_SubVI:
 938   case Op_SubVL:
 939   case Op_MulVS:
 940   case Op_MulVI:
 941   case Op_LShiftVB:
 942   case Op_LShiftVS:
 943   case Op_LShiftVI:
 944   case Op_LShiftVL:
 945   case Op_RShiftVB:
 946   case Op_RShiftVS:
 947   case Op_RShiftVI:
 948   case Op_RShiftVL:
 949   case Op_URShiftVB:
 950   case Op_URShiftVS:
 951   case Op_URShiftVI:
 952   case Op_URShiftVL:
 953   case Op_AndV:
 954   case Op_OrV:
 955   case Op_XorV:
 956     return VM_Version::has_simd();
 957   case Op_LoadVector:
 958   case Op_StoreVector:
 959   case Op_AddVF:
 960   case Op_SubVF:
 961   case Op_MulVF:
 962     return VM_Version::has_vfp() || VM_Version::has_simd();
 963   case Op_AddVD:
 964   case Op_SubVD:
 965   case Op_MulVD:
 966   case Op_DivVF:
 967   case Op_DivVD:
 968     return VM_Version::has_vfp();
 969   }
 970 
 971   return true;  // Per default match rules are supported.
 972 }
 973 
 974 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) {
 975 
 976   // TODO
 977   // identify extra cases that we might want to provide match rules for
 978   // e.g. Op_ vector nodes and other intrinsics while guarding with vlen
 979   bool ret_value = match_rule_supported(opcode);
 980   // Add rules here.
 981 
 982   return ret_value;  // Per default match rules are supported.
 983 }
 984 
 985 const bool Matcher::has_predicated_vectors(void) {
 986   return false;
 987 }
 988 
 989 const int Matcher::float_pressure(int default_pressure_threshold) {
 990   return default_pressure_threshold;
 991 }
 992 
 993 int Matcher::regnum_to_fpu_offset(int regnum) {
 994   return regnum - 32; // The FP registers are in the second chunk
 995 }
 996 
 997 // Vector width in bytes
 998 const int Matcher::vector_width_in_bytes(BasicType bt) {
 999   return MaxVectorSize;
1000 }
1001 
1002 // Vector ideal reg corresponding to specified size in bytes
1003 const uint Matcher::vector_ideal_reg(int size) {
1004   assert(MaxVectorSize >= size, "");
1005   switch(size) {
1006     case  8: return Op_VecD;
1007     case 16: return Op_VecX;
1008   }
1009   ShouldNotReachHere();
1010   return 0;
1011 }
1012 
1013 const uint Matcher::vector_shift_count_ideal_reg(int size) {
1014   return vector_ideal_reg(size);
1015 }
1016 
1017 // Limits on vector size (number of elements) loaded into vector.
1018 const int Matcher::max_vector_size(const BasicType bt) {
1019   assert(is_java_primitive(bt), "only primitive type vectors");
1020   return vector_width_in_bytes(bt)/type2aelembytes(bt);
1021 }
1022 
1023 const int Matcher::min_vector_size(const BasicType bt) {
1024   assert(is_java_primitive(bt), "only primitive type vectors");
1025   return 8/type2aelembytes(bt);
1026 }
1027 
1028 // ARM doesn't support misaligned vectors store/load.
1029 const bool Matcher::misaligned_vectors_ok() {
1030   return false;
1031 }
1032 
1033 // ARM doesn't support AES intrinsics
1034 const bool Matcher::pass_original_key_for_aes() {
1035   return false;
1036 }
1037 
1038 const bool Matcher::convL2FSupported(void) {
1039   return false;
1040 }
1041 
1042 // Is this branch offset short enough that a short branch can be used?
1043 //
1044 // NOTE: If the platform does not provide any short branch variants, then
1045 //       this method should return false for offset 0.
1046 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
1047   // The passed offset is relative to address of the branch.
1048   // On ARM a branch displacement is calculated relative to address
1049   // of the branch + 8.
1050   //
1051   // offset -= 8;
1052   // return (Assembler::is_simm24(offset));
1053   return false;
1054 }
1055 
1056 const bool Matcher::isSimpleConstant64(jlong value) {
1057   // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
1058   return false;
1059 }
1060 
1061 // No scaling for the parameter the ClearArray node.
1062 const bool Matcher::init_array_count_is_in_bytes = true;
1063 
1064 // Needs 2 CMOV's for longs.
1065 const int Matcher::long_cmove_cost() { return 2; }
1066 
1067 // CMOVF/CMOVD are expensive on ARM.
1068 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
1069 
1070 // Does the CPU require late expand (see block.cpp for description of late expand)?
1071 const bool Matcher::require_postalloc_expand = false;
1072 
1073 // Do we need to mask the count passed to shift instructions or does
1074 // the cpu only look at the lower 5/6 bits anyway?
1075 // FIXME: does this handle vector shifts as well?
1076 const bool Matcher::need_masked_shift_count = true;
1077 
1078 const bool Matcher::convi2l_type_required = true;
1079 
1080 // Should the Matcher clone shifts on addressing modes, expecting them
1081 // to be subsumed into complex addressing expressions or compute them
1082 // into registers?
1083 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
1084   return clone_base_plus_offset_address(m, mstack, address_visited);
1085 }
1086 
1087 void Compile::reshape_address(AddPNode* addp) {
1088 }
1089 
1090 bool Matcher::narrow_oop_use_complex_address() {
1091   NOT_LP64(ShouldNotCallThis());
1092   assert(UseCompressedOops, "only for compressed oops code");
1093   return false;
1094 }
1095 
1096 bool Matcher::narrow_klass_use_complex_address() {
1097   NOT_LP64(ShouldNotCallThis());
1098   assert(UseCompressedClassPointers, "only for compressed klass code");
1099   return false;
1100 }
1101 
1102 bool Matcher::const_oop_prefer_decode() {
1103   NOT_LP64(ShouldNotCallThis());
1104   return true;
1105 }
1106 
1107 bool Matcher::const_klass_prefer_decode() {
1108   NOT_LP64(ShouldNotCallThis());
1109   return true;
1110 }
1111 
1112 // Is it better to copy float constants, or load them directly from memory?
1113 // Intel can load a float constant from a direct address, requiring no
1114 // extra registers.  Most RISCs will have to materialize an address into a
1115 // register first, so they would do better to copy the constant from stack.
1116 const bool Matcher::rematerialize_float_constants = false;
1117 
1118 // If CPU can load and store mis-aligned doubles directly then no fixup is
1119 // needed.  Else we split the double into 2 integer pieces and move it
1120 // piece-by-piece.  Only happens when passing doubles into C code as the
1121 // Java calling convention forces doubles to be aligned.
1122 const bool Matcher::misaligned_doubles_ok = false;
1123 
1124 // No-op on ARM.
1125 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {
1126 }
1127 
1128 // Advertise here if the CPU requires explicit rounding operations
1129 // to implement the UseStrictFP mode.
1130 const bool Matcher::strict_fp_requires_explicit_rounding = false;
1131 
1132 // Are floats converted to double when stored to stack during deoptimization?
1133 // ARM does not handle callee-save floats.
1134 bool Matcher::float_in_double() {
1135   return false;
1136 }
1137 
1138 // Do ints take an entire long register or just half?
1139 // Note that we if-def off of _LP64.
1140 // The relevant question is how the int is callee-saved.  In _LP64
1141 // the whole long is written but de-opt'ing will have to extract
1142 // the relevant 32 bits, in not-_LP64 only the low 32 bits is written.
1143 #ifdef _LP64
1144 const bool Matcher::int_in_long = true;
1145 #else
1146 const bool Matcher::int_in_long = false;
1147 #endif
1148 
1149 // Return whether or not this register is ever used as an argument.  This
1150 // function is used on startup to build the trampoline stubs in generateOptoStub.
1151 // Registers not mentioned will be killed by the VM call in the trampoline, and
1152 // arguments in those registers not be available to the callee.
1153 bool Matcher::can_be_java_arg( int reg ) {
1154   if (reg == R_R0_num ||
1155       reg == R_R1_num ||
1156       reg == R_R2_num ||
1157       reg == R_R3_num) return true;
1158 
1159   if (reg >= R_S0_num &&
1160       reg <= R_S13_num) return true;
1161   return false;
1162 }
1163 
1164 bool Matcher::is_spillable_arg( int reg ) {
1165   return can_be_java_arg(reg);
1166 }
1167 
1168 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
1169   return false;
1170 }
1171 
1172 // Register for DIVI projection of divmodI
1173 RegMask Matcher::divI_proj_mask() {
1174   ShouldNotReachHere();
1175   return RegMask();
1176 }
1177 
1178 // Register for MODI projection of divmodI
1179 RegMask Matcher::modI_proj_mask() {
1180   ShouldNotReachHere();
1181   return RegMask();
1182 }
1183 
1184 // Register for DIVL projection of divmodL
1185 RegMask Matcher::divL_proj_mask() {
1186   ShouldNotReachHere();
1187   return RegMask();
1188 }
1189 
1190 // Register for MODL projection of divmodL
1191 RegMask Matcher::modL_proj_mask() {
1192   ShouldNotReachHere();
1193   return RegMask();
1194 }
1195 
1196 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
1197   return FP_REGP_mask();
1198 }
1199 
1200 bool maybe_far_call(const CallNode *n) {
1201   return !MacroAssembler::_reachable_from_cache(n->as_Call()->entry_point());
1202 }
1203 
1204 bool maybe_far_call(const MachCallNode *n) {
1205   return !MacroAssembler::_reachable_from_cache(n->as_MachCall()->entry_point());
1206 }
1207 
1208 %}
1209 
1210 //----------ENCODING BLOCK-----------------------------------------------------
1211 // This block specifies the encoding classes used by the compiler to output
1212 // byte streams.  Encoding classes are parameterized macros used by
1213 // Machine Instruction Nodes in order to generate the bit encoding of the
1214 // instruction.  Operands specify their base encoding interface with the
1215 // interface keyword.  There are currently supported four interfaces,
1216 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
1217 // operand to generate a function which returns its register number when
1218 // queried.   CONST_INTER causes an operand to generate a function which
1219 // returns the value of the constant when queried.  MEMORY_INTER causes an
1220 // operand to generate four functions which return the Base Register, the
1221 // Index Register, the Scale Value, and the Offset Value of the operand when
1222 // queried.  COND_INTER causes an operand to generate six functions which
1223 // return the encoding code (ie - encoding bits for the instruction)
1224 // associated with each basic boolean condition for a conditional instruction.
1225 //
1226 // Instructions specify two basic values for encoding.  Again, a function
1227 // is available to check if the constant displacement is an oop. They use the
1228 // ins_encode keyword to specify their encoding classes (which must be
1229 // a sequence of enc_class names, and their parameters, specified in
1230 // the encoding block), and they use the
1231 // opcode keyword to specify, in order, their primary, secondary, and
1232 // tertiary opcode.  Only the opcode sections which a particular instruction
1233 // needs for encoding need to be specified.
1234 encode %{
1235   enc_class call_epilog %{
1236     // nothing
1237   %}
1238 
1239   enc_class Java_To_Runtime (method meth) %{
1240     // CALL directly to the runtime
1241     emit_call_reloc(cbuf, as_MachCall(), $meth, runtime_call_Relocation::spec());
1242   %}
1243 
1244   enc_class Java_Static_Call (method meth) %{
1245     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
1246     // who we intended to call.
1247 
1248     if ( !_method) {
1249       emit_call_reloc(cbuf, as_MachCall(), $meth, runtime_call_Relocation::spec());
1250     } else {
1251       int method_index = resolved_method_index(cbuf);
1252       RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
1253                                                   : static_call_Relocation::spec(method_index);
1254       emit_call_reloc(cbuf, as_MachCall(), $meth, rspec);
1255 
1256       // Emit stubs for static call.
1257       address stub = CompiledStaticCall::emit_to_interp_stub(cbuf);
1258       if (stub == NULL) {
1259         ciEnv::current()->record_failure("CodeCache is full");
1260         return;
1261       }
1262     }
1263   %}
1264 
1265   enc_class save_last_PC %{
1266     // preserve mark
1267     address mark = cbuf.insts()->mark();
1268     debug_only(int off0 = cbuf.insts_size());
1269     MacroAssembler _masm(&cbuf);
1270     int ret_addr_offset = as_MachCall()->ret_addr_offset();
1271     __ adr(LR, mark + ret_addr_offset);
1272     __ str(LR, Address(Rthread, JavaThread::last_Java_pc_offset()));
1273     debug_only(int off1 = cbuf.insts_size());
1274     assert(off1 - off0 == 2 * Assembler::InstructionSize, "correct size prediction");
1275     // restore mark
1276     cbuf.insts()->set_mark(mark);
1277   %}
1278 
1279   enc_class preserve_SP %{
1280     // preserve mark
1281     address mark = cbuf.insts()->mark();
1282     debug_only(int off0 = cbuf.insts_size());
1283     MacroAssembler _masm(&cbuf);
1284     // FP is preserved across all calls, even compiled calls.
1285     // Use it to preserve SP in places where the callee might change the SP.
1286     __ mov(Rmh_SP_save, SP);
1287     debug_only(int off1 = cbuf.insts_size());
1288     assert(off1 - off0 == 4, "correct size prediction");
1289     // restore mark
1290     cbuf.insts()->set_mark(mark);
1291   %}
1292 
1293   enc_class restore_SP %{
1294     MacroAssembler _masm(&cbuf);
1295     __ mov(SP, Rmh_SP_save);
1296   %}
1297 
1298   enc_class Java_Dynamic_Call (method meth) %{
1299     MacroAssembler _masm(&cbuf);
1300     Register R8_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode());
1301     assert(R8_ic_reg == Ricklass, "should be");
1302     __ set_inst_mark();
1303     __ movw(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) & 0xffff);
1304     __ movt(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) >> 16);
1305     address  virtual_call_oop_addr = __ inst_mark();
1306     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
1307     // who we intended to call.
1308     int method_index = resolved_method_index(cbuf);
1309     __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index));
1310     emit_call_reloc(cbuf, as_MachCall(), $meth, RelocationHolder::none);
1311   %}
1312 
1313   enc_class LdReplImmI(immI src, regD dst, iRegI tmp, int cnt, int wth) %{
1314     // FIXME: load from constant table?
1315     // Load a constant replicated "count" times with width "width"
1316     int count = $cnt$$constant;
1317     int width = $wth$$constant;
1318     assert(count*width == 4, "sanity");
1319     int val = $src$$constant;
1320     if (width < 4) {
1321       int bit_width = width * 8;
1322       val &= (((int)1) << bit_width) - 1; // mask off sign bits
1323       for (int i = 0; i < count - 1; i++) {
1324         val |= (val << bit_width);
1325       }
1326     }
1327     MacroAssembler _masm(&cbuf);
1328 
1329     if (val == -1) {
1330       __ mvn($tmp$$Register, 0);
1331     } else if (val == 0) {
1332       __ mov($tmp$$Register, 0);
1333     } else {
1334       __ movw($tmp$$Register, val & 0xffff);
1335       __ movt($tmp$$Register, (unsigned int)val >> 16);
1336     }
1337     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
1338   %}
1339 
1340   enc_class LdReplImmF(immF src, regD dst, iRegI tmp) %{
1341     // Replicate float con 2 times and pack into vector (8 bytes) in regD.
1342     float fval = $src$$constant;
1343     int val = *((int*)&fval);
1344     MacroAssembler _masm(&cbuf);
1345 
1346     if (val == -1) {
1347       __ mvn($tmp$$Register, 0);
1348     } else if (val == 0) {
1349       __ mov($tmp$$Register, 0);
1350     } else {
1351       __ movw($tmp$$Register, val & 0xffff);
1352       __ movt($tmp$$Register, (unsigned int)val >> 16);
1353     }
1354     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
1355   %}
1356 
1357   enc_class enc_String_Compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result, iRegI tmp1, iRegI tmp2) %{
1358     Label Ldone, Lloop;
1359     MacroAssembler _masm(&cbuf);
1360 
1361     Register   str1_reg = $str1$$Register;
1362     Register   str2_reg = $str2$$Register;
1363     Register   cnt1_reg = $cnt1$$Register; // int
1364     Register   cnt2_reg = $cnt2$$Register; // int
1365     Register   tmp1_reg = $tmp1$$Register;
1366     Register   tmp2_reg = $tmp2$$Register;
1367     Register result_reg = $result$$Register;
1368 
1369     assert_different_registers(str1_reg, str2_reg, cnt1_reg, cnt2_reg, tmp1_reg, tmp2_reg);
1370 
1371     // Compute the minimum of the string lengths(str1_reg) and the
1372     // difference of the string lengths (stack)
1373 
1374     // See if the lengths are different, and calculate min in str1_reg.
1375     // Stash diff in tmp2 in case we need it for a tie-breaker.
1376     __ subs_32(tmp2_reg, cnt1_reg, cnt2_reg);
1377     __ mov(cnt1_reg, AsmOperand(cnt1_reg, lsl, exact_log2(sizeof(jchar)))); // scale the limit
1378     __ mov(cnt1_reg, AsmOperand(cnt2_reg, lsl, exact_log2(sizeof(jchar))), pl); // scale the limit
1379 
1380     // reallocate cnt1_reg, cnt2_reg, result_reg
1381     // Note:  limit_reg holds the string length pre-scaled by 2
1382     Register limit_reg = cnt1_reg;
1383     Register  chr2_reg = cnt2_reg;
1384     Register  chr1_reg = tmp1_reg;
1385     // str{12} are the base pointers
1386 
1387     // Is the minimum length zero?
1388     __ cmp_32(limit_reg, 0);
1389     if (result_reg != tmp2_reg) {
1390       __ mov(result_reg, tmp2_reg, eq);
1391     }
1392     __ b(Ldone, eq);
1393 
1394     // Load first characters
1395     __ ldrh(chr1_reg, Address(str1_reg, 0));
1396     __ ldrh(chr2_reg, Address(str2_reg, 0));
1397 
1398     // Compare first characters
1399     __ subs(chr1_reg, chr1_reg, chr2_reg);
1400     if (result_reg != chr1_reg) {
1401       __ mov(result_reg, chr1_reg, ne);
1402     }
1403     __ b(Ldone, ne);
1404 
1405     {
1406       // Check after comparing first character to see if strings are equivalent
1407       // Check if the strings start at same location
1408       __ cmp(str1_reg, str2_reg);
1409       // Check if the length difference is zero
1410       __ cond_cmp(tmp2_reg, 0, eq);
1411       __ mov(result_reg, 0, eq); // result is zero
1412       __ b(Ldone, eq);
1413       // Strings might not be equal
1414     }
1415 
1416     __ subs(chr1_reg, limit_reg, 1 * sizeof(jchar));
1417     if (result_reg != tmp2_reg) {
1418       __ mov(result_reg, tmp2_reg, eq);
1419     }
1420     __ b(Ldone, eq);
1421 
1422     // Shift str1_reg and str2_reg to the end of the arrays, negate limit
1423     __ add(str1_reg, str1_reg, limit_reg);
1424     __ add(str2_reg, str2_reg, limit_reg);
1425     __ neg(limit_reg, chr1_reg);  // limit = -(limit-2)
1426 
1427     // Compare the rest of the characters
1428     __ bind(Lloop);
1429     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
1430     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
1431     __ subs(chr1_reg, chr1_reg, chr2_reg);
1432     if (result_reg != chr1_reg) {
1433       __ mov(result_reg, chr1_reg, ne);
1434     }
1435     __ b(Ldone, ne);
1436 
1437     __ adds(limit_reg, limit_reg, sizeof(jchar));
1438     __ b(Lloop, ne);
1439 
1440     // If strings are equal up to min length, return the length difference.
1441     if (result_reg != tmp2_reg) {
1442       __ mov(result_reg, tmp2_reg);
1443     }
1444 
1445     // Otherwise, return the difference between the first mismatched chars.
1446     __ bind(Ldone);
1447   %}
1448 
1449   enc_class enc_String_Equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2) %{
1450     Label Lchar, Lchar_loop, Ldone, Lequal;
1451     MacroAssembler _masm(&cbuf);
1452 
1453     Register   str1_reg = $str1$$Register;
1454     Register   str2_reg = $str2$$Register;
1455     Register    cnt_reg = $cnt$$Register; // int
1456     Register   tmp1_reg = $tmp1$$Register;
1457     Register   tmp2_reg = $tmp2$$Register;
1458     Register result_reg = $result$$Register;
1459 
1460     assert_different_registers(str1_reg, str2_reg, cnt_reg, tmp1_reg, tmp2_reg, result_reg);
1461 
1462     __ cmp(str1_reg, str2_reg); //same char[] ?
1463     __ b(Lequal, eq);
1464 
1465     __ cbz_32(cnt_reg, Lequal); // count == 0
1466 
1467     //rename registers
1468     Register limit_reg = cnt_reg;
1469     Register  chr1_reg = tmp1_reg;
1470     Register  chr2_reg = tmp2_reg;
1471 
1472     __ logical_shift_left(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
1473 
1474     //check for alignment and position the pointers to the ends
1475     __ orr(chr1_reg, str1_reg, str2_reg);
1476     __ tst(chr1_reg, 0x3);
1477 
1478     // notZero means at least one not 4-byte aligned.
1479     // We could optimize the case when both arrays are not aligned
1480     // but it is not frequent case and it requires additional checks.
1481     __ b(Lchar, ne);
1482 
1483     // Compare char[] arrays aligned to 4 bytes.
1484     __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg,
1485                           chr1_reg, chr2_reg, Ldone);
1486 
1487     __ b(Lequal); // equal
1488 
1489     // char by char compare
1490     __ bind(Lchar);
1491     __ mov(result_reg, 0);
1492     __ add(str1_reg, limit_reg, str1_reg);
1493     __ add(str2_reg, limit_reg, str2_reg);
1494     __ neg(limit_reg, limit_reg); //negate count
1495 
1496     // Lchar_loop
1497     __ bind(Lchar_loop);
1498     __ ldrh(chr1_reg, Address(str1_reg, limit_reg));
1499     __ ldrh(chr2_reg, Address(str2_reg, limit_reg));
1500     __ cmp(chr1_reg, chr2_reg);
1501     __ b(Ldone, ne);
1502     __ adds(limit_reg, limit_reg, sizeof(jchar));
1503     __ b(Lchar_loop, ne);
1504 
1505     __ bind(Lequal);
1506     __ mov(result_reg, 1);  //equal
1507 
1508     __ bind(Ldone);
1509   %}
1510 
1511   enc_class enc_Array_Equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result) %{
1512     Label Ldone, Lloop, Lequal;
1513     MacroAssembler _masm(&cbuf);
1514 
1515     Register   ary1_reg = $ary1$$Register;
1516     Register   ary2_reg = $ary2$$Register;
1517     Register   tmp1_reg = $tmp1$$Register;
1518     Register   tmp2_reg = $tmp2$$Register;
1519     Register   tmp3_reg = $tmp3$$Register;
1520     Register result_reg = $result$$Register;
1521 
1522     assert_different_registers(ary1_reg, ary2_reg, tmp1_reg, tmp2_reg, tmp3_reg, result_reg);
1523 
1524     int length_offset  = arrayOopDesc::length_offset_in_bytes();
1525     int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
1526 
1527     // return true if the same array
1528     __ teq(ary1_reg, ary2_reg);
1529     __ mov(result_reg, 1, eq);
1530     __ b(Ldone, eq); // equal
1531 
1532     __ tst(ary1_reg, ary1_reg);
1533     __ mov(result_reg, 0, eq);
1534     __ b(Ldone, eq);    // not equal
1535 
1536     __ tst(ary2_reg, ary2_reg);
1537     __ mov(result_reg, 0, eq);
1538     __ b(Ldone, eq);    // not equal
1539 
1540     //load the lengths of arrays
1541     __ ldr_s32(tmp1_reg, Address(ary1_reg, length_offset)); // int
1542     __ ldr_s32(tmp2_reg, Address(ary2_reg, length_offset)); // int
1543 
1544     // return false if the two arrays are not equal length
1545     __ teq_32(tmp1_reg, tmp2_reg);
1546     __ mov(result_reg, 0, ne);
1547     __ b(Ldone, ne);    // not equal
1548 
1549     __ tst(tmp1_reg, tmp1_reg);
1550     __ mov(result_reg, 1, eq);
1551     __ b(Ldone, eq);    // zero-length arrays are equal
1552 
1553     // load array addresses
1554     __ add(ary1_reg, ary1_reg, base_offset);
1555     __ add(ary2_reg, ary2_reg, base_offset);
1556 
1557     // renaming registers
1558     Register chr1_reg  =  tmp3_reg;   // for characters in ary1
1559     Register chr2_reg  =  tmp2_reg;   // for characters in ary2
1560     Register limit_reg =  tmp1_reg;   // length
1561 
1562     // set byte count
1563     __ logical_shift_left_32(limit_reg, limit_reg, exact_log2(sizeof(jchar)));
1564 
1565     // Compare char[] arrays aligned to 4 bytes.
1566     __ char_arrays_equals(ary1_reg, ary2_reg, limit_reg, result_reg,
1567                           chr1_reg, chr2_reg, Ldone);
1568     __ bind(Lequal);
1569     __ mov(result_reg, 1);  //equal
1570 
1571     __ bind(Ldone);
1572     %}
1573 %}
1574 
1575 //----------FRAME--------------------------------------------------------------
1576 // Definition of frame structure and management information.
1577 //
1578 //  S T A C K   L A Y O U T    Allocators stack-slot number
1579 //                             |   (to get allocators register number
1580 //  G  Owned by    |        |  v    add VMRegImpl::stack0)
1581 //  r   CALLER     |        |
1582 //  o     |        +--------+      pad to even-align allocators stack-slot
1583 //  w     V        |  pad0  |        numbers; owned by CALLER
1584 //  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
1585 //  h     ^        |   in   |  5
1586 //        |        |  args  |  4   Holes in incoming args owned by SELF
1587 //  |     |        |        |  3
1588 //  |     |        +--------+
1589 //  V     |        | old out|      Empty on Intel, window on Sparc
1590 //        |    old |preserve|      Must be even aligned.
1591 //        |     SP-+--------+----> Matcher::_old_SP, 8 (or 16 in LP64)-byte aligned
1592 //        |        |   in   |  3   area for Intel ret address
1593 //     Owned by    |preserve|      Empty on Sparc.
1594 //       SELF      +--------+
1595 //        |        |  pad2  |  2   pad to align old SP
1596 //        |        +--------+  1
1597 //        |        | locks  |  0
1598 //        |        +--------+----> VMRegImpl::stack0, 8 (or 16 in LP64)-byte aligned
1599 //        |        |  pad1  | 11   pad to align new SP
1600 //        |        +--------+
1601 //        |        |        | 10
1602 //        |        | spills |  9   spills
1603 //        V        |        |  8   (pad0 slot for callee)
1604 //      -----------+--------+----> Matcher::_out_arg_limit, unaligned
1605 //        ^        |  out   |  7
1606 //        |        |  args  |  6   Holes in outgoing args owned by CALLEE
1607 //     Owned by    +--------+
1608 //      CALLEE     | new out|  6   Empty on Intel, window on Sparc
1609 //        |    new |preserve|      Must be even-aligned.
1610 //        |     SP-+--------+----> Matcher::_new_SP, even aligned
1611 //        |        |        |
1612 //
1613 // Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
1614 //         known from SELF's arguments and the Java calling convention.
1615 //         Region 6-7 is determined per call site.
1616 // Note 2: If the calling convention leaves holes in the incoming argument
1617 //         area, those holes are owned by SELF.  Holes in the outgoing area
1618 //         are owned by the CALLEE.  Holes should not be nessecary in the
1619 //         incoming area, as the Java calling convention is completely under
1620 //         the control of the AD file.  Doubles can be sorted and packed to
1621 //         avoid holes.  Holes in the outgoing arguments may be nessecary for
1622 //         varargs C calling conventions.
1623 // Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
1624 //         even aligned with pad0 as needed.
1625 //         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
1626 //         region 6-11 is even aligned; it may be padded out more so that
1627 //         the region from SP to FP meets the minimum stack alignment.
1628 
1629 frame %{
1630   // What direction does stack grow in (assumed to be same for native & Java)
1631   stack_direction(TOWARDS_LOW);
1632 
1633   // These two registers define part of the calling convention
1634   // between compiled code and the interpreter.
1635   inline_cache_reg(R_Ricklass);          // Inline Cache Register or Method* for I2C
1636   interpreter_method_oop_reg(R_Rmethod); // Method Oop Register when calling interpreter
1637 
1638   // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
1639   cisc_spilling_operand_name(indOffset);
1640 
1641   // Number of stack slots consumed by a Monitor enter
1642   sync_stack_slots(1 * VMRegImpl::slots_per_word);
1643 
1644   // Compiled code's Frame Pointer
1645   frame_pointer(R_R13);
1646 
1647   // Stack alignment requirement
1648   stack_alignment(StackAlignmentInBytes);
1649   //  LP64: Alignment size in bytes (128-bit -> 16 bytes)
1650   // !LP64: Alignment size in bytes (64-bit  ->  8 bytes)
1651 
1652   // Number of stack slots between incoming argument block and the start of
1653   // a new frame.  The PROLOG must add this many slots to the stack.  The
1654   // EPILOG must remove this many slots.
1655   // FP + LR
1656   in_preserve_stack_slots(2 * VMRegImpl::slots_per_word);
1657 
1658   // Number of outgoing stack slots killed above the out_preserve_stack_slots
1659   // for calls to C.  Supports the var-args backing area for register parms.
1660   // ADLC doesn't support parsing expressions, so I folded the math by hand.
1661   varargs_C_out_slots_killed( 0);
1662 
1663   // The after-PROLOG location of the return address.  Location of
1664   // return address specifies a type (REG or STACK) and a number
1665   // representing the register number (i.e. - use a register name) or
1666   // stack slot.
1667   // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
1668   // Otherwise, it is above the locks and verification slot and alignment word
1669   return_addr(STACK - 1*VMRegImpl::slots_per_word +
1670               align_up((Compile::current()->in_preserve_stack_slots() +
1671                         Compile::current()->fixed_slots()),
1672                        stack_alignment_in_slots()));
1673 
1674   // Body of function which returns an OptoRegs array locating
1675   // arguments either in registers or in stack slots for calling
1676   // java
1677   calling_convention %{
1678     (void) SharedRuntime::java_calling_convention(sig_bt, regs, length, is_outgoing);
1679 
1680   %}
1681 
1682   // Body of function which returns an OptoRegs array locating
1683   // arguments either in registers or in stack slots for callin
1684   // C.
1685   c_calling_convention %{
1686     // This is obviously always outgoing
1687     (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
1688   %}
1689 
1690   // Location of compiled Java return values.  Same as C
1691   return_value %{
1692     return c2::return_value(ideal_reg);
1693   %}
1694 
1695 %}
1696 
1697 //----------ATTRIBUTES---------------------------------------------------------
1698 //----------Instruction Attributes---------------------------------------------
1699 ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute
1700 ins_attrib ins_size(32);           // Required size attribute (in bits)
1701 ins_attrib ins_short_branch(0);    // Required flag: is this instruction a
1702                                    // non-matching short branch variant of some
1703                                                             // long branch?
1704 
1705 //----------OPERANDS-----------------------------------------------------------
1706 // Operand definitions must precede instruction definitions for correct parsing
1707 // in the ADLC because operands constitute user defined types which are used in
1708 // instruction definitions.
1709 
1710 //----------Simple Operands----------------------------------------------------
1711 // Immediate Operands
1712 // Integer Immediate: 32-bit
1713 operand immI() %{
1714   match(ConI);
1715 
1716   op_cost(0);
1717   // formats are generated automatically for constants and base registers
1718   format %{ %}
1719   interface(CONST_INTER);
1720 %}
1721 
1722 // Integer Immediate: 8-bit unsigned - for VMOV
1723 operand immU8() %{
1724   predicate(0 <= n->get_int() && (n->get_int() <= 255));
1725   match(ConI);
1726   op_cost(0);
1727 
1728   format %{ %}
1729   interface(CONST_INTER);
1730 %}
1731 
1732 // Integer Immediate: 16-bit
1733 operand immI16() %{
1734   predicate((n->get_int() >> 16) == 0 && VM_Version::supports_movw());
1735   match(ConI);
1736   op_cost(0);
1737 
1738   format %{ %}
1739   interface(CONST_INTER);
1740 %}
1741 
1742 // Integer Immediate: offset for half and double word loads and stores
1743 operand immIHD() %{
1744   predicate(is_memoryHD(n->get_int()));
1745   match(ConI);
1746   op_cost(0);
1747   format %{ %}
1748   interface(CONST_INTER);
1749 %}
1750 
1751 // Integer Immediate: offset for fp loads and stores
1752 operand immIFP() %{
1753   predicate(is_memoryfp(n->get_int()) && ((n->get_int() & 3) == 0));
1754   match(ConI);
1755   op_cost(0);
1756 
1757   format %{ %}
1758   interface(CONST_INTER);
1759 %}
1760 
1761 // Valid scale values for addressing modes and shifts
1762 operand immU5() %{
1763   predicate(0 <= n->get_int() && (n->get_int() <= 31));
1764   match(ConI);
1765   op_cost(0);
1766 
1767   format %{ %}
1768   interface(CONST_INTER);
1769 %}
1770 
1771 // Integer Immediate: 6-bit
1772 operand immU6Big() %{
1773   predicate(n->get_int() >= 32 && n->get_int() <= 63);
1774   match(ConI);
1775   op_cost(0);
1776   format %{ %}
1777   interface(CONST_INTER);
1778 %}
1779 
1780 // Integer Immediate: 0-bit
1781 operand immI0() %{
1782   predicate(n->get_int() == 0);
1783   match(ConI);
1784   op_cost(0);
1785 
1786   format %{ %}
1787   interface(CONST_INTER);
1788 %}
1789 
1790 // Integer Immediate: the value 1
1791 operand immI_1() %{
1792   predicate(n->get_int() == 1);
1793   match(ConI);
1794   op_cost(0);
1795 
1796   format %{ %}
1797   interface(CONST_INTER);
1798 %}
1799 
1800 // Integer Immediate: the value 2
1801 operand immI_2() %{
1802   predicate(n->get_int() == 2);
1803   match(ConI);
1804   op_cost(0);
1805 
1806   format %{ %}
1807   interface(CONST_INTER);
1808 %}
1809 
1810 // Integer Immediate: the value 3
1811 operand immI_3() %{
1812   predicate(n->get_int() == 3);
1813   match(ConI);
1814   op_cost(0);
1815 
1816   format %{ %}
1817   interface(CONST_INTER);
1818 %}
1819 
1820 // Integer Immediate: the value 4
1821 operand immI_4() %{
1822   predicate(n->get_int() == 4);
1823   match(ConI);
1824   op_cost(0);
1825 
1826   format %{ %}
1827   interface(CONST_INTER);
1828 %}
1829 
1830 // Integer Immediate: the value 8
1831 operand immI_8() %{
1832   predicate(n->get_int() == 8);
1833   match(ConI);
1834   op_cost(0);
1835 
1836   format %{ %}
1837   interface(CONST_INTER);
1838 %}
1839 
1840 // Int Immediate non-negative
1841 operand immU31()
1842 %{
1843   predicate(n->get_int() >= 0);
1844   match(ConI);
1845 
1846   op_cost(0);
1847   format %{ %}
1848   interface(CONST_INTER);
1849 %}
1850 
1851 // Integer Immediate: the values 32-63
1852 operand immI_32_63() %{
1853   predicate(n->get_int() >= 32 && n->get_int() <= 63);
1854   match(ConI);
1855   op_cost(0);
1856 
1857   format %{ %}
1858   interface(CONST_INTER);
1859 %}
1860 
1861 // Immediates for special shifts (sign extend)
1862 
1863 // Integer Immediate: the value 16
1864 operand immI_16() %{
1865   predicate(n->get_int() == 16);
1866   match(ConI);
1867   op_cost(0);
1868 
1869   format %{ %}
1870   interface(CONST_INTER);
1871 %}
1872 
1873 // Integer Immediate: the value 24
1874 operand immI_24() %{
1875   predicate(n->get_int() == 24);
1876   match(ConI);
1877   op_cost(0);
1878 
1879   format %{ %}
1880   interface(CONST_INTER);
1881 %}
1882 
1883 // Integer Immediate: the value 255
1884 operand immI_255() %{
1885   predicate( n->get_int() == 255 );
1886   match(ConI);
1887   op_cost(0);
1888 
1889   format %{ %}
1890   interface(CONST_INTER);
1891 %}
1892 
1893 // Integer Immediate: the value 65535
1894 operand immI_65535() %{
1895   predicate(n->get_int() == 65535);
1896   match(ConI);
1897   op_cost(0);
1898 
1899   format %{ %}
1900   interface(CONST_INTER);
1901 %}
1902 
1903 // Integer Immediates for arithmetic instructions
1904 
1905 operand aimmI() %{
1906   predicate(is_aimm(n->get_int()));
1907   match(ConI);
1908   op_cost(0);
1909 
1910   format %{ %}
1911   interface(CONST_INTER);
1912 %}
1913 
1914 operand aimmIneg() %{
1915   predicate(is_aimm(-n->get_int()));
1916   match(ConI);
1917   op_cost(0);
1918 
1919   format %{ %}
1920   interface(CONST_INTER);
1921 %}
1922 
1923 operand aimmU31() %{
1924   predicate((0 <= n->get_int()) && is_aimm(n->get_int()));
1925   match(ConI);
1926   op_cost(0);
1927 
1928   format %{ %}
1929   interface(CONST_INTER);
1930 %}
1931 
1932 // Integer Immediates for logical instructions
1933 
1934 operand limmI() %{
1935   predicate(is_limmI(n->get_int()));
1936   match(ConI);
1937   op_cost(0);
1938 
1939   format %{ %}
1940   interface(CONST_INTER);
1941 %}
1942 
1943 operand limmIlow8() %{
1944   predicate(is_limmI_low(n->get_int(), 8));
1945   match(ConI);
1946   op_cost(0);
1947 
1948   format %{ %}
1949   interface(CONST_INTER);
1950 %}
1951 
1952 operand limmU31() %{
1953   predicate(0 <= n->get_int() && is_limmI(n->get_int()));
1954   match(ConI);
1955   op_cost(0);
1956 
1957   format %{ %}
1958   interface(CONST_INTER);
1959 %}
1960 
1961 operand limmIn() %{
1962   predicate(is_limmI(~n->get_int()));
1963   match(ConI);
1964   op_cost(0);
1965 
1966   format %{ %}
1967   interface(CONST_INTER);
1968 %}
1969 
1970 
1971 // Long Immediate: the value FF
1972 operand immL_FF() %{
1973   predicate( n->get_long() == 0xFFL );
1974   match(ConL);
1975   op_cost(0);
1976 
1977   format %{ %}
1978   interface(CONST_INTER);
1979 %}
1980 
1981 // Long Immediate: the value FFFF
1982 operand immL_FFFF() %{
1983   predicate( n->get_long() == 0xFFFFL );
1984   match(ConL);
1985   op_cost(0);
1986 
1987   format %{ %}
1988   interface(CONST_INTER);
1989 %}
1990 
1991 // Pointer Immediate: 32 or 64-bit
1992 operand immP() %{
1993   match(ConP);
1994 
1995   op_cost(5);
1996   // formats are generated automatically for constants and base registers
1997   format %{ %}
1998   interface(CONST_INTER);
1999 %}
2000 
2001 operand immP0() %{
2002   predicate(n->get_ptr() == 0);
2003   match(ConP);
2004   op_cost(0);
2005 
2006   format %{ %}
2007   interface(CONST_INTER);
2008 %}
2009 
2010 operand immP_poll() %{
2011   predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
2012   match(ConP);
2013 
2014   // formats are generated automatically for constants and base registers
2015   format %{ %}
2016   interface(CONST_INTER);
2017 %}
2018 
2019 // Pointer Immediate
2020 operand immN()
2021 %{
2022   match(ConN);
2023 
2024   op_cost(10);
2025   format %{ %}
2026   interface(CONST_INTER);
2027 %}
2028 
2029 operand immNKlass()
2030 %{
2031   match(ConNKlass);
2032 
2033   op_cost(10);
2034   format %{ %}
2035   interface(CONST_INTER);
2036 %}
2037 
2038 // NULL Pointer Immediate
2039 operand immN0()
2040 %{
2041   predicate(n->get_narrowcon() == 0);
2042   match(ConN);
2043 
2044   op_cost(0);
2045   format %{ %}
2046   interface(CONST_INTER);
2047 %}
2048 
2049 operand immL() %{
2050   match(ConL);
2051   op_cost(40);
2052   // formats are generated automatically for constants and base registers
2053   format %{ %}
2054   interface(CONST_INTER);
2055 %}
2056 
2057 operand immL0() %{
2058   predicate(n->get_long() == 0L);
2059   match(ConL);
2060   op_cost(0);
2061   // formats are generated automatically for constants and base registers
2062   format %{ %}
2063   interface(CONST_INTER);
2064 %}
2065 
2066 // Long Immediate: 16-bit
2067 operand immL16() %{
2068   predicate(n->get_long() >= 0 && n->get_long() < (1<<16)  && VM_Version::supports_movw());
2069   match(ConL);
2070   op_cost(0);
2071 
2072   format %{ %}
2073   interface(CONST_INTER);
2074 %}
2075 
2076 // Long Immediate: low 32-bit mask
2077 operand immL_32bits() %{
2078   predicate(n->get_long() == 0xFFFFFFFFL);
2079   match(ConL);
2080   op_cost(0);
2081 
2082   format %{ %}
2083   interface(CONST_INTER);
2084 %}
2085 
2086 // Double Immediate
2087 operand immD() %{
2088   match(ConD);
2089 
2090   op_cost(40);
2091   format %{ %}
2092   interface(CONST_INTER);
2093 %}
2094 
2095 // Double Immediate: +0.0d.
2096 operand immD0() %{
2097   predicate(jlong_cast(n->getd()) == 0);
2098 
2099   match(ConD);
2100   op_cost(0);
2101   format %{ %}
2102   interface(CONST_INTER);
2103 %}
2104 
2105 operand imm8D() %{
2106   predicate(Assembler::double_num(n->getd()).can_be_imm8());
2107   match(ConD);
2108 
2109   op_cost(0);
2110   format %{ %}
2111   interface(CONST_INTER);
2112 %}
2113 
2114 // Float Immediate
2115 operand immF() %{
2116   match(ConF);
2117 
2118   op_cost(20);
2119   format %{ %}
2120   interface(CONST_INTER);
2121 %}
2122 
2123 // Float Immediate: +0.0f
2124 operand immF0() %{
2125   predicate(jint_cast(n->getf()) == 0);
2126   match(ConF);
2127 
2128   op_cost(0);
2129   format %{ %}
2130   interface(CONST_INTER);
2131 %}
2132 
2133 // Float Immediate: encoded as 8 bits
2134 operand imm8F() %{
2135   predicate(Assembler::float_num(n->getf()).can_be_imm8());
2136   match(ConF);
2137 
2138   op_cost(0);
2139   format %{ %}
2140   interface(CONST_INTER);
2141 %}
2142 
2143 // Integer Register Operands
2144 // Integer Register
2145 operand iRegI() %{
2146   constraint(ALLOC_IN_RC(int_reg));
2147   match(RegI);
2148   match(R0RegI);
2149   match(R1RegI);
2150   match(R2RegI);
2151   match(R3RegI);
2152   match(R12RegI);
2153 
2154   format %{ %}
2155   interface(REG_INTER);
2156 %}
2157 
2158 // Pointer Register
2159 operand iRegP() %{
2160   constraint(ALLOC_IN_RC(ptr_reg));
2161   match(RegP);
2162   match(R0RegP);
2163   match(R1RegP);
2164   match(R2RegP);
2165   match(RExceptionRegP);
2166   match(R8RegP);
2167   match(R9RegP);
2168   match(RthreadRegP); // FIXME: move to sp_ptr_RegP?
2169   match(R12RegP);
2170   match(LRRegP);
2171 
2172   match(sp_ptr_RegP);
2173   match(store_ptr_RegP);
2174 
2175   format %{ %}
2176   interface(REG_INTER);
2177 %}
2178 
2179 // GPRs + Rthread + SP
2180 operand sp_ptr_RegP() %{
2181   constraint(ALLOC_IN_RC(sp_ptr_reg));
2182   match(RegP);
2183   match(iRegP);
2184   match(SPRegP); // FIXME: check cost
2185 
2186   format %{ %}
2187   interface(REG_INTER);
2188 %}
2189 
2190 
2191 operand R0RegP() %{
2192   constraint(ALLOC_IN_RC(R0_regP));
2193   match(iRegP);
2194 
2195   format %{ %}
2196   interface(REG_INTER);
2197 %}
2198 
2199 operand R1RegP() %{
2200   constraint(ALLOC_IN_RC(R1_regP));
2201   match(iRegP);
2202 
2203   format %{ %}
2204   interface(REG_INTER);
2205 %}
2206 
2207 operand R2RegP() %{
2208   constraint(ALLOC_IN_RC(R2_regP));
2209   match(iRegP);
2210 
2211   format %{ %}
2212   interface(REG_INTER);
2213 %}
2214 
2215 operand RExceptionRegP() %{
2216   constraint(ALLOC_IN_RC(Rexception_regP));
2217   match(iRegP);
2218 
2219   format %{ %}
2220   interface(REG_INTER);
2221 %}
2222 
2223 operand RthreadRegP() %{
2224   constraint(ALLOC_IN_RC(Rthread_regP));
2225   match(iRegP);
2226 
2227   format %{ %}
2228   interface(REG_INTER);
2229 %}
2230 
2231 operand IPRegP() %{
2232   constraint(ALLOC_IN_RC(IP_regP));
2233   match(iRegP);
2234 
2235   format %{ %}
2236   interface(REG_INTER);
2237 %}
2238 
2239 operand LRRegP() %{
2240   constraint(ALLOC_IN_RC(LR_regP));
2241   match(iRegP);
2242 
2243   format %{ %}
2244   interface(REG_INTER);
2245 %}
2246 
2247 operand R0RegI() %{
2248   constraint(ALLOC_IN_RC(R0_regI));
2249   match(iRegI);
2250 
2251   format %{ %}
2252   interface(REG_INTER);
2253 %}
2254 
2255 operand R1RegI() %{
2256   constraint(ALLOC_IN_RC(R1_regI));
2257   match(iRegI);
2258 
2259   format %{ %}
2260   interface(REG_INTER);
2261 %}
2262 
2263 operand R2RegI() %{
2264   constraint(ALLOC_IN_RC(R2_regI));
2265   match(iRegI);
2266 
2267   format %{ %}
2268   interface(REG_INTER);
2269 %}
2270 
2271 operand R3RegI() %{
2272   constraint(ALLOC_IN_RC(R3_regI));
2273   match(iRegI);
2274 
2275   format %{ %}
2276   interface(REG_INTER);
2277 %}
2278 
2279 operand R12RegI() %{
2280   constraint(ALLOC_IN_RC(R12_regI));
2281   match(iRegI);
2282 
2283   format %{ %}
2284   interface(REG_INTER);
2285 %}
2286 
2287 // Long Register
2288 operand iRegL() %{
2289   constraint(ALLOC_IN_RC(long_reg));
2290   match(RegL);
2291   match(R0R1RegL);
2292   match(R2R3RegL);
2293 //match(iRegLex);
2294 
2295   format %{ %}
2296   interface(REG_INTER);
2297 %}
2298 
2299 operand iRegLd() %{
2300   constraint(ALLOC_IN_RC(long_reg_align));
2301   match(iRegL); // FIXME: allows unaligned R11/R12?
2302 
2303   format %{ %}
2304   interface(REG_INTER);
2305 %}
2306 
2307 // first long arg, or return value
2308 operand R0R1RegL() %{
2309   constraint(ALLOC_IN_RC(R0R1_regL));
2310   match(iRegL);
2311 
2312   format %{ %}
2313   interface(REG_INTER);
2314 %}
2315 
2316 operand R2R3RegL() %{
2317   constraint(ALLOC_IN_RC(R2R3_regL));
2318   match(iRegL);
2319 
2320   format %{ %}
2321   interface(REG_INTER);
2322 %}
2323 
2324 // Condition Code Flag Register
2325 operand flagsReg() %{
2326   constraint(ALLOC_IN_RC(int_flags));
2327   match(RegFlags);
2328 
2329   format %{ "apsr" %}
2330   interface(REG_INTER);
2331 %}
2332 
2333 // Result of compare to 0 (TST)
2334 operand flagsReg_EQNELTGE() %{
2335   constraint(ALLOC_IN_RC(int_flags));
2336   match(RegFlags);
2337 
2338   format %{ "apsr_EQNELTGE" %}
2339   interface(REG_INTER);
2340 %}
2341 
2342 // Condition Code Register, unsigned comparisons.
2343 operand flagsRegU() %{
2344   constraint(ALLOC_IN_RC(int_flags));
2345   match(RegFlags);
2346 #ifdef TODO
2347   match(RegFlagsP);
2348 #endif
2349 
2350   format %{ "apsr_U" %}
2351   interface(REG_INTER);
2352 %}
2353 
2354 // Condition Code Register, pointer comparisons.
2355 operand flagsRegP() %{
2356   constraint(ALLOC_IN_RC(int_flags));
2357   match(RegFlags);
2358 
2359   format %{ "apsr_P" %}
2360   interface(REG_INTER);
2361 %}
2362 
2363 // Condition Code Register, long comparisons.
2364 operand flagsRegL_LTGE() %{
2365   constraint(ALLOC_IN_RC(int_flags));
2366   match(RegFlags);
2367 
2368   format %{ "apsr_L_LTGE" %}
2369   interface(REG_INTER);
2370 %}
2371 
2372 operand flagsRegL_EQNE() %{
2373   constraint(ALLOC_IN_RC(int_flags));
2374   match(RegFlags);
2375 
2376   format %{ "apsr_L_EQNE" %}
2377   interface(REG_INTER);
2378 %}
2379 
2380 operand flagsRegL_LEGT() %{
2381   constraint(ALLOC_IN_RC(int_flags));
2382   match(RegFlags);
2383 
2384   format %{ "apsr_L_LEGT" %}
2385   interface(REG_INTER);
2386 %}
2387 
2388 operand flagsRegUL_LTGE() %{
2389   constraint(ALLOC_IN_RC(int_flags));
2390   match(RegFlags);
2391 
2392   format %{ "apsr_UL_LTGE" %}
2393   interface(REG_INTER);
2394 %}
2395 
2396 operand flagsRegUL_EQNE() %{
2397   constraint(ALLOC_IN_RC(int_flags));
2398   match(RegFlags);
2399 
2400   format %{ "apsr_UL_EQNE" %}
2401   interface(REG_INTER);
2402 %}
2403 
2404 operand flagsRegUL_LEGT() %{
2405   constraint(ALLOC_IN_RC(int_flags));
2406   match(RegFlags);
2407 
2408   format %{ "apsr_UL_LEGT" %}
2409   interface(REG_INTER);
2410 %}
2411 
2412 // Condition Code Register, floating comparisons, unordered same as "less".
2413 operand flagsRegF() %{
2414   constraint(ALLOC_IN_RC(float_flags));
2415   match(RegFlags);
2416 
2417   format %{ "fpscr_F" %}
2418   interface(REG_INTER);
2419 %}
2420 
2421 // Vectors
2422 operand vecD() %{
2423   constraint(ALLOC_IN_RC(actual_dflt_reg));
2424   match(VecD);
2425 
2426   format %{ %}
2427   interface(REG_INTER);
2428 %}
2429 
2430 operand vecX() %{
2431   constraint(ALLOC_IN_RC(vectorx_reg));
2432   match(VecX);
2433 
2434   format %{ %}
2435   interface(REG_INTER);
2436 %}
2437 
2438 operand regD() %{
2439   constraint(ALLOC_IN_RC(actual_dflt_reg));
2440   match(RegD);
2441   match(regD_low);
2442 
2443   format %{ %}
2444   interface(REG_INTER);
2445 %}
2446 
2447 operand regF() %{
2448   constraint(ALLOC_IN_RC(sflt_reg));
2449   match(RegF);
2450 
2451   format %{ %}
2452   interface(REG_INTER);
2453 %}
2454 
2455 operand regD_low() %{
2456   constraint(ALLOC_IN_RC(dflt_low_reg));
2457   match(RegD);
2458 
2459   format %{ %}
2460   interface(REG_INTER);
2461 %}
2462 
2463 // Special Registers
2464 
2465 // Method Register
2466 operand inline_cache_regP(iRegP reg) %{
2467   constraint(ALLOC_IN_RC(Ricklass_regP));
2468   match(reg);
2469   format %{ %}
2470   interface(REG_INTER);
2471 %}
2472 
2473 operand interpreter_method_oop_regP(iRegP reg) %{
2474   constraint(ALLOC_IN_RC(Rmethod_regP));
2475   match(reg);
2476   format %{ %}
2477   interface(REG_INTER);
2478 %}
2479 
2480 
2481 //----------Complex Operands---------------------------------------------------
2482 // Indirect Memory Reference
2483 operand indirect(sp_ptr_RegP reg) %{
2484   constraint(ALLOC_IN_RC(sp_ptr_reg));
2485   match(reg);
2486 
2487   op_cost(100);
2488   format %{ "[$reg]" %}
2489   interface(MEMORY_INTER) %{
2490     base($reg);
2491     index(0xf); // PC => no index
2492     scale(0x0);
2493     disp(0x0);
2494   %}
2495 %}
2496 
2497 
2498 // Indirect with Offset in ]-4096, 4096[
2499 operand indOffset12(sp_ptr_RegP reg, immI12 offset) %{
2500   constraint(ALLOC_IN_RC(sp_ptr_reg));
2501   match(AddP reg offset);
2502 
2503   op_cost(100);
2504   format %{ "[$reg + $offset]" %}
2505   interface(MEMORY_INTER) %{
2506     base($reg);
2507     index(0xf); // PC => no index
2508     scale(0x0);
2509     disp($offset);
2510   %}
2511 %}
2512 
2513 // Indirect with offset for float load/store
2514 operand indOffsetFP(sp_ptr_RegP reg, immIFP offset) %{
2515   constraint(ALLOC_IN_RC(sp_ptr_reg));
2516   match(AddP reg offset);
2517 
2518   op_cost(100);
2519   format %{ "[$reg + $offset]" %}
2520   interface(MEMORY_INTER) %{
2521     base($reg);
2522     index(0xf); // PC => no index
2523     scale(0x0);
2524     disp($offset);
2525   %}
2526 %}
2527 
2528 // Indirect with Offset for half and double words
2529 operand indOffsetHD(sp_ptr_RegP reg, immIHD offset) %{
2530   constraint(ALLOC_IN_RC(sp_ptr_reg));
2531   match(AddP reg offset);
2532 
2533   op_cost(100);
2534   format %{ "[$reg + $offset]" %}
2535   interface(MEMORY_INTER) %{
2536     base($reg);
2537     index(0xf); // PC => no index
2538     scale(0x0);
2539     disp($offset);
2540   %}
2541 %}
2542 
2543 // Indirect with Offset and Offset+4 in ]-1024, 1024[
2544 operand indOffsetFPx2(sp_ptr_RegP reg, immX10x2 offset) %{
2545   constraint(ALLOC_IN_RC(sp_ptr_reg));
2546   match(AddP reg offset);
2547 
2548   op_cost(100);
2549   format %{ "[$reg + $offset]" %}
2550   interface(MEMORY_INTER) %{
2551     base($reg);
2552     index(0xf); // PC => no index
2553     scale(0x0);
2554     disp($offset);
2555   %}
2556 %}
2557 
2558 // Indirect with Offset and Offset+4 in ]-4096, 4096[
2559 operand indOffset12x2(sp_ptr_RegP reg, immI12x2 offset) %{
2560   constraint(ALLOC_IN_RC(sp_ptr_reg));
2561   match(AddP reg offset);
2562 
2563   op_cost(100);
2564   format %{ "[$reg + $offset]" %}
2565   interface(MEMORY_INTER) %{
2566     base($reg);
2567     index(0xf); // PC => no index
2568     scale(0x0);
2569     disp($offset);
2570   %}
2571 %}
2572 
2573 // Indirect with Register Index
2574 operand indIndex(iRegP addr, iRegX index) %{
2575   constraint(ALLOC_IN_RC(ptr_reg));
2576   match(AddP addr index);
2577 
2578   op_cost(100);
2579   format %{ "[$addr + $index]" %}
2580   interface(MEMORY_INTER) %{
2581     base($addr);
2582     index($index);
2583     scale(0x0);
2584     disp(0x0);
2585   %}
2586 %}
2587 
2588 // Indirect Memory Times Scale Plus Index Register
2589 operand indIndexScale(iRegP addr, iRegX index, immU5 scale) %{
2590   constraint(ALLOC_IN_RC(ptr_reg));
2591   match(AddP addr (LShiftX index scale));
2592 
2593   op_cost(100);
2594   format %{"[$addr + $index << $scale]" %}
2595   interface(MEMORY_INTER) %{
2596     base($addr);
2597     index($index);
2598     scale($scale);
2599     disp(0x0);
2600   %}
2601 %}
2602 
2603 // Operands for expressing Control Flow
2604 // NOTE:  Label is a predefined operand which should not be redefined in
2605 //        the AD file.  It is generically handled within the ADLC.
2606 
2607 //----------Conditional Branch Operands----------------------------------------
2608 // Comparison Op  - This is the operation of the comparison, and is limited to
2609 //                  the following set of codes:
2610 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
2611 //
2612 // Other attributes of the comparison, such as unsignedness, are specified
2613 // by the comparison instruction that sets a condition code flags register.
2614 // That result is represented by a flags operand whose subtype is appropriate
2615 // to the unsignedness (etc.) of the comparison.
2616 //
2617 // Later, the instruction which matches both the Comparison Op (a Bool) and
2618 // the flags (produced by the Cmp) specifies the coding of the comparison op
2619 // by matching a specific subtype of Bool operand below, such as cmpOpU.
2620 
2621 operand cmpOp() %{
2622   match(Bool);
2623 
2624   format %{ "" %}
2625   interface(COND_INTER) %{
2626     equal(0x0);
2627     not_equal(0x1);
2628     less(0xb);
2629     greater_equal(0xa);
2630     less_equal(0xd);
2631     greater(0xc);
2632     overflow(0x0); // unsupported/unimplemented
2633     no_overflow(0x0); // unsupported/unimplemented
2634   %}
2635 %}
2636 
2637 // integer comparison with 0, signed
2638 operand cmpOp0() %{
2639   match(Bool);
2640 
2641   format %{ "" %}
2642   interface(COND_INTER) %{
2643     equal(0x0);
2644     not_equal(0x1);
2645     less(0x4);
2646     greater_equal(0x5);
2647     less_equal(0xd); // unsupported
2648     greater(0xc); // unsupported
2649     overflow(0x0); // unsupported/unimplemented
2650     no_overflow(0x0); // unsupported/unimplemented
2651   %}
2652 %}
2653 
2654 // Comparison Op, unsigned
2655 operand cmpOpU() %{
2656   match(Bool);
2657 
2658   format %{ "u" %}
2659   interface(COND_INTER) %{
2660     equal(0x0);
2661     not_equal(0x1);
2662     less(0x3);
2663     greater_equal(0x2);
2664     less_equal(0x9);
2665     greater(0x8);
2666     overflow(0x0); // unsupported/unimplemented
2667     no_overflow(0x0); // unsupported/unimplemented
2668   %}
2669 %}
2670 
2671 // Comparison Op, pointer (same as unsigned)
2672 operand cmpOpP() %{
2673   match(Bool);
2674 
2675   format %{ "p" %}
2676   interface(COND_INTER) %{
2677     equal(0x0);
2678     not_equal(0x1);
2679     less(0x3);
2680     greater_equal(0x2);
2681     less_equal(0x9);
2682     greater(0x8);
2683     overflow(0x0); // unsupported/unimplemented
2684     no_overflow(0x0); // unsupported/unimplemented
2685   %}
2686 %}
2687 
2688 operand cmpOpL() %{
2689   match(Bool);
2690 
2691   format %{ "L" %}
2692   interface(COND_INTER) %{
2693     equal(0x0);
2694     not_equal(0x1);
2695     less(0xb);
2696     greater_equal(0xa);
2697     less_equal(0xd);
2698     greater(0xc);
2699     overflow(0x0); // unsupported/unimplemented
2700     no_overflow(0x0); // unsupported/unimplemented
2701   %}
2702 %}
2703 
2704 operand cmpOpL_commute() %{
2705   match(Bool);
2706 
2707   format %{ "L" %}
2708   interface(COND_INTER) %{
2709     equal(0x0);
2710     not_equal(0x1);
2711     less(0xc);
2712     greater_equal(0xd);
2713     less_equal(0xa);
2714     greater(0xb);
2715     overflow(0x0); // unsupported/unimplemented
2716     no_overflow(0x0); // unsupported/unimplemented
2717   %}
2718 %}
2719 
2720 operand cmpOpUL() %{
2721   match(Bool);
2722 
2723   format %{ "UL" %}
2724   interface(COND_INTER) %{
2725     equal(0x0);
2726     not_equal(0x1);
2727     less(0x3);
2728     greater_equal(0x2);
2729     less_equal(0x9);
2730     greater(0x8);
2731     overflow(0x0); // unsupported/unimplemented
2732     no_overflow(0x0); // unsupported/unimplemented
2733   %}
2734 %}
2735 
2736 operand cmpOpUL_commute() %{
2737   match(Bool);
2738 
2739   format %{ "UL" %}
2740   interface(COND_INTER) %{
2741     equal(0x0);
2742     not_equal(0x1);
2743     less(0x8);
2744     greater_equal(0x9);
2745     less_equal(0x2);
2746     greater(0x3);
2747     overflow(0x0); // unsupported/unimplemented
2748     no_overflow(0x0); // unsupported/unimplemented
2749   %}
2750 %}
2751 
2752 
2753 //----------OPERAND CLASSES----------------------------------------------------
2754 // Operand Classes are groups of operands that are used to simplify
2755 // instruction definitions by not requiring the AD writer to specify separate
2756 // instructions for every form of operand when the instruction accepts
2757 // multiple operand types with the same basic encoding and format.  The classic
2758 // case of this is memory operands.
2759 
2760 opclass memoryI ( indirect, indOffset12, indIndex, indIndexScale );
2761 opclass memoryP ( indirect, indOffset12, indIndex, indIndexScale );
2762 opclass memoryF ( indirect, indOffsetFP );
2763 opclass memoryF2 ( indirect, indOffsetFPx2 );
2764 opclass memoryD ( indirect, indOffsetFP );
2765 opclass memoryfp( indirect, indOffsetFP );
2766 opclass memoryB ( indirect, indIndex, indOffsetHD );
2767 opclass memoryS ( indirect, indIndex, indOffsetHD );
2768 opclass memoryL ( indirect, indIndex, indOffsetHD );
2769 
2770 opclass memoryScaledI(indIndexScale);
2771 opclass memoryScaledP(indIndexScale);
2772 
2773 // when ldrex/strex is used:
2774 opclass memoryex ( indirect );
2775 opclass indIndexMemory( indIndex );
2776 opclass memorylong ( indirect, indOffset12x2 );
2777 opclass memoryvld ( indirect /* , write back mode not implemented */ );
2778 
2779 //----------PIPELINE-----------------------------------------------------------
2780 pipeline %{
2781 
2782 //----------ATTRIBUTES---------------------------------------------------------
2783 attributes %{
2784   fixed_size_instructions;           // Fixed size instructions
2785   max_instructions_per_bundle = 4;   // Up to 4 instructions per bundle
2786   instruction_unit_size = 4;         // An instruction is 4 bytes long
2787   instruction_fetch_unit_size = 16;  // The processor fetches one line
2788   instruction_fetch_units = 1;       // of 16 bytes
2789 
2790   // List of nop instructions
2791   nops( Nop_A0, Nop_A1, Nop_MS, Nop_FA, Nop_BR );
2792 %}
2793 
2794 //----------RESOURCES----------------------------------------------------------
2795 // Resources are the functional units available to the machine
2796 resources(A0, A1, MS, BR, FA, FM, IDIV, FDIV, IALU = A0 | A1);
2797 
2798 //----------PIPELINE DESCRIPTION-----------------------------------------------
2799 // Pipeline Description specifies the stages in the machine's pipeline
2800 
2801 pipe_desc(A, P, F, B, I, J, S, R, E, C, M, W, X, T, D);
2802 
2803 //----------PIPELINE CLASSES---------------------------------------------------
2804 // Pipeline Classes describe the stages in which input and output are
2805 // referenced by the hardware pipeline.
2806 
2807 // Integer ALU reg-reg operation
2808 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
2809     single_instruction;
2810     dst   : E(write);
2811     src1  : R(read);
2812     src2  : R(read);
2813     IALU  : R;
2814 %}
2815 
2816 // Integer ALU reg-reg long operation
2817 pipe_class ialu_reg_reg_2(iRegL dst, iRegL src1, iRegL src2) %{
2818     instruction_count(2);
2819     dst   : E(write);
2820     src1  : R(read);
2821     src2  : R(read);
2822     IALU  : R;
2823     IALU  : R;
2824 %}
2825 
2826 // Integer ALU reg-reg long dependent operation
2827 pipe_class ialu_reg_reg_2_dep(iRegL dst, iRegL src1, iRegL src2, flagsReg cr) %{
2828     instruction_count(1); multiple_bundles;
2829     dst   : E(write);
2830     src1  : R(read);
2831     src2  : R(read);
2832     cr    : E(write);
2833     IALU  : R(2);
2834 %}
2835 
2836 // Integer ALU reg-imm operaion
2837 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) %{
2838     single_instruction;
2839     dst   : E(write);
2840     src1  : R(read);
2841     IALU  : R;
2842 %}
2843 
2844 // Integer ALU reg-reg operation with condition code
2845 pipe_class ialu_cc_reg_reg(iRegI dst, iRegI src1, iRegI src2, flagsReg cr) %{
2846     single_instruction;
2847     dst   : E(write);
2848     cr    : E(write);
2849     src1  : R(read);
2850     src2  : R(read);
2851     IALU  : R;
2852 %}
2853 
2854 // Integer ALU zero-reg operation
2855 pipe_class ialu_zero_reg(iRegI dst, immI0 zero, iRegI src2) %{
2856     single_instruction;
2857     dst   : E(write);
2858     src2  : R(read);
2859     IALU  : R;
2860 %}
2861 
2862 // Integer ALU zero-reg operation with condition code only
2863 pipe_class ialu_cconly_zero_reg(flagsReg cr, iRegI src) %{
2864     single_instruction;
2865     cr    : E(write);
2866     src   : R(read);
2867     IALU  : R;
2868 %}
2869 
2870 // Integer ALU reg-reg operation with condition code only
2871 pipe_class ialu_cconly_reg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
2872     single_instruction;
2873     cr    : E(write);
2874     src1  : R(read);
2875     src2  : R(read);
2876     IALU  : R;
2877 %}
2878 
2879 // Integer ALU reg-imm operation with condition code only
2880 pipe_class ialu_cconly_reg_imm(flagsReg cr, iRegI src1) %{
2881     single_instruction;
2882     cr    : E(write);
2883     src1  : R(read);
2884     IALU  : R;
2885 %}
2886 
2887 // Integer ALU reg-reg-zero operation with condition code only
2888 pipe_class ialu_cconly_reg_reg_zero(flagsReg cr, iRegI src1, iRegI src2, immI0 zero) %{
2889     single_instruction;
2890     cr    : E(write);
2891     src1  : R(read);
2892     src2  : R(read);
2893     IALU  : R;
2894 %}
2895 
2896 // Integer ALU reg-imm-zero operation with condition code only
2897 pipe_class ialu_cconly_reg_imm_zero(flagsReg cr, iRegI src1, immI0 zero) %{
2898     single_instruction;
2899     cr    : E(write);
2900     src1  : R(read);
2901     IALU  : R;
2902 %}
2903 
2904 // Integer ALU reg-reg operation with condition code, src1 modified
2905 pipe_class ialu_cc_rwreg_reg(flagsReg cr, iRegI src1, iRegI src2) %{
2906     single_instruction;
2907     cr    : E(write);
2908     src1  : E(write);
2909     src1  : R(read);
2910     src2  : R(read);
2911     IALU  : R;
2912 %}
2913 
2914 pipe_class cmpL_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg cr ) %{
2915     multiple_bundles;
2916     dst   : E(write)+4;
2917     cr    : E(write);
2918     src1  : R(read);
2919     src2  : R(read);
2920     IALU  : R(3);
2921     BR    : R(2);
2922 %}
2923 
2924 // Integer ALU operation
2925 pipe_class ialu_none(iRegI dst) %{
2926     single_instruction;
2927     dst   : E(write);
2928     IALU  : R;
2929 %}
2930 
2931 // Integer ALU reg operation
2932 pipe_class ialu_reg(iRegI dst, iRegI src) %{
2933     single_instruction; may_have_no_code;
2934     dst   : E(write);
2935     src   : R(read);
2936     IALU  : R;
2937 %}
2938 
2939 // Integer ALU reg conditional operation
2940 // This instruction has a 1 cycle stall, and cannot execute
2941 // in the same cycle as the instruction setting the condition
2942 // code. We kludge this by pretending to read the condition code
2943 // 1 cycle earlier, and by marking the functional units as busy
2944 // for 2 cycles with the result available 1 cycle later than
2945 // is really the case.
2946 pipe_class ialu_reg_flags( iRegI op2_out, iRegI op2_in, iRegI op1, flagsReg cr ) %{
2947     single_instruction;
2948     op2_out : C(write);
2949     op1     : R(read);
2950     cr      : R(read);       // This is really E, with a 1 cycle stall
2951     BR      : R(2);
2952     MS      : R(2);
2953 %}
2954 
2955 // Integer ALU reg operation
2956 pipe_class ialu_move_reg_L_to_I(iRegI dst, iRegL src) %{
2957     single_instruction; may_have_no_code;
2958     dst   : E(write);
2959     src   : R(read);
2960     IALU  : R;
2961 %}
2962 pipe_class ialu_move_reg_I_to_L(iRegL dst, iRegI src) %{
2963     single_instruction; may_have_no_code;
2964     dst   : E(write);
2965     src   : R(read);
2966     IALU  : R;
2967 %}
2968 
2969 // Two integer ALU reg operations
2970 pipe_class ialu_reg_2(iRegL dst, iRegL src) %{
2971     instruction_count(2);
2972     dst   : E(write);
2973     src   : R(read);
2974     A0    : R;
2975     A1    : R;
2976 %}
2977 
2978 // Two integer ALU reg operations
2979 pipe_class ialu_move_reg_L_to_L(iRegL dst, iRegL src) %{
2980     instruction_count(2); may_have_no_code;
2981     dst   : E(write);
2982     src   : R(read);
2983     A0    : R;
2984     A1    : R;
2985 %}
2986 
2987 // Integer ALU imm operation
2988 pipe_class ialu_imm(iRegI dst) %{
2989     single_instruction;
2990     dst   : E(write);
2991     IALU  : R;
2992 %}
2993 
2994 pipe_class ialu_imm_n(iRegI dst) %{
2995     single_instruction;
2996     dst   : E(write);
2997     IALU  : R;
2998 %}
2999 
3000 // Integer ALU reg-reg with carry operation
3001 pipe_class ialu_reg_reg_cy(iRegI dst, iRegI src1, iRegI src2, iRegI cy) %{
3002     single_instruction;
3003     dst   : E(write);
3004     src1  : R(read);
3005     src2  : R(read);
3006     IALU  : R;
3007 %}
3008 
3009 // Integer ALU cc operation
3010 pipe_class ialu_cc(iRegI dst, flagsReg cc) %{
3011     single_instruction;
3012     dst   : E(write);
3013     cc    : R(read);
3014     IALU  : R;
3015 %}
3016 
3017 // Integer ALU cc / second IALU operation
3018 pipe_class ialu_reg_ialu( iRegI dst, iRegI src ) %{
3019     instruction_count(1); multiple_bundles;
3020     dst   : E(write)+1;
3021     src   : R(read);
3022     IALU  : R;
3023 %}
3024 
3025 // Integer ALU cc / second IALU operation
3026 pipe_class ialu_reg_reg_ialu( iRegI dst, iRegI p, iRegI q ) %{
3027     instruction_count(1); multiple_bundles;
3028     dst   : E(write)+1;
3029     p     : R(read);
3030     q     : R(read);
3031     IALU  : R;
3032 %}
3033 
3034 // Integer ALU hi-lo-reg operation
3035 pipe_class ialu_hi_lo_reg(iRegI dst, immI src) %{
3036     instruction_count(1); multiple_bundles;
3037     dst   : E(write)+1;
3038     IALU  : R(2);
3039 %}
3040 
3041 // Long Constant
3042 pipe_class loadConL( iRegL dst, immL src ) %{
3043     instruction_count(2); multiple_bundles;
3044     dst   : E(write)+1;
3045     IALU  : R(2);
3046     IALU  : R(2);
3047 %}
3048 
3049 // Pointer Constant
3050 pipe_class loadConP( iRegP dst, immP src ) %{
3051     instruction_count(0); multiple_bundles;
3052     fixed_latency(6);
3053 %}
3054 
3055 // Polling Address
3056 pipe_class loadConP_poll( iRegP dst, immP_poll src ) %{
3057     dst   : E(write);
3058     IALU  : R;
3059 %}
3060 
3061 // Long Constant small
3062 pipe_class loadConLlo( iRegL dst, immL src ) %{
3063     instruction_count(2);
3064     dst   : E(write);
3065     IALU  : R;
3066     IALU  : R;
3067 %}
3068 
3069 // [PHH] This is wrong for 64-bit.  See LdImmF/D.
3070 pipe_class loadConFD(regF dst, immF src, iRegP tmp) %{
3071     instruction_count(1); multiple_bundles;
3072     src   : R(read);
3073     dst   : M(write)+1;
3074     IALU  : R;
3075     MS    : E;
3076 %}
3077 
3078 // Integer ALU nop operation
3079 pipe_class ialu_nop() %{
3080     single_instruction;
3081     IALU  : R;
3082 %}
3083 
3084 // Integer ALU nop operation
3085 pipe_class ialu_nop_A0() %{
3086     single_instruction;
3087     A0    : R;
3088 %}
3089 
3090 // Integer ALU nop operation
3091 pipe_class ialu_nop_A1() %{
3092     single_instruction;
3093     A1    : R;
3094 %}
3095 
3096 // Integer Multiply reg-reg operation
3097 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
3098     single_instruction;
3099     dst   : E(write);
3100     src1  : R(read);
3101     src2  : R(read);
3102     MS    : R(5);
3103 %}
3104 
3105 pipe_class mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
3106     single_instruction;
3107     dst   : E(write)+4;
3108     src1  : R(read);
3109     src2  : R(read);
3110     MS    : R(6);
3111 %}
3112 
3113 // Integer Divide reg-reg
3114 pipe_class sdiv_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI temp, flagsReg cr) %{
3115     instruction_count(1); multiple_bundles;
3116     dst   : E(write);
3117     temp  : E(write);
3118     src1  : R(read);
3119     src2  : R(read);
3120     temp  : R(read);
3121     MS    : R(38);
3122 %}
3123 
3124 // Long Divide
3125 pipe_class divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
3126     dst  : E(write)+71;
3127     src1 : R(read);
3128     src2 : R(read)+1;
3129     MS   : R(70);
3130 %}
3131 
3132 // Floating Point Add Float
3133 pipe_class faddF_reg_reg(regF dst, regF src1, regF src2) %{
3134     single_instruction;
3135     dst   : X(write);
3136     src1  : E(read);
3137     src2  : E(read);
3138     FA    : R;
3139 %}
3140 
3141 // Floating Point Add Double
3142 pipe_class faddD_reg_reg(regD dst, regD src1, regD src2) %{
3143     single_instruction;
3144     dst   : X(write);
3145     src1  : E(read);
3146     src2  : E(read);
3147     FA    : R;
3148 %}
3149 
3150 // Floating Point Conditional Move based on integer flags
3151 pipe_class int_conditional_float_move (cmpOp cmp, flagsReg cr, regF dst, regF src) %{
3152     single_instruction;
3153     dst   : X(write);
3154     src   : E(read);
3155     cr    : R(read);
3156     FA    : R(2);
3157     BR    : R(2);
3158 %}
3159 
3160 // Floating Point Conditional Move based on integer flags
3161 pipe_class int_conditional_double_move (cmpOp cmp, flagsReg cr, regD dst, regD src) %{
3162     single_instruction;
3163     dst   : X(write);
3164     src   : E(read);
3165     cr    : R(read);
3166     FA    : R(2);
3167     BR    : R(2);
3168 %}
3169 
3170 // Floating Point Multiply Float
3171 pipe_class fmulF_reg_reg(regF dst, regF src1, regF src2) %{
3172     single_instruction;
3173     dst   : X(write);
3174     src1  : E(read);
3175     src2  : E(read);
3176     FM    : R;
3177 %}
3178 
3179 // Floating Point Multiply Double
3180 pipe_class fmulD_reg_reg(regD dst, regD src1, regD src2) %{
3181     single_instruction;
3182     dst   : X(write);
3183     src1  : E(read);
3184     src2  : E(read);
3185     FM    : R;
3186 %}
3187 
3188 // Floating Point Divide Float
3189 pipe_class fdivF_reg_reg(regF dst, regF src1, regF src2) %{
3190     single_instruction;
3191     dst   : X(write);
3192     src1  : E(read);
3193     src2  : E(read);
3194     FM    : R;
3195     FDIV  : C(14);
3196 %}
3197 
3198 // Floating Point Divide Double
3199 pipe_class fdivD_reg_reg(regD dst, regD src1, regD src2) %{
3200     single_instruction;
3201     dst   : X(write);
3202     src1  : E(read);
3203     src2  : E(read);
3204     FM    : R;
3205     FDIV  : C(17);
3206 %}
3207 
3208 // Floating Point Move/Negate/Abs Float
3209 pipe_class faddF_reg(regF dst, regF src) %{
3210     single_instruction;
3211     dst   : W(write);
3212     src   : E(read);
3213     FA    : R(1);
3214 %}
3215 
3216 // Floating Point Move/Negate/Abs Double
3217 pipe_class faddD_reg(regD dst, regD src) %{
3218     single_instruction;
3219     dst   : W(write);
3220     src   : E(read);
3221     FA    : R;
3222 %}
3223 
3224 // Floating Point Convert F->D
3225 pipe_class fcvtF2D(regD dst, regF src) %{
3226     single_instruction;
3227     dst   : X(write);
3228     src   : E(read);
3229     FA    : R;
3230 %}
3231 
3232 // Floating Point Convert I->D
3233 pipe_class fcvtI2D(regD dst, regF src) %{
3234     single_instruction;
3235     dst   : X(write);
3236     src   : E(read);
3237     FA    : R;
3238 %}
3239 
3240 // Floating Point Convert LHi->D
3241 pipe_class fcvtLHi2D(regD dst, regD src) %{
3242     single_instruction;
3243     dst   : X(write);
3244     src   : E(read);
3245     FA    : R;
3246 %}
3247 
3248 // Floating Point Convert L->D
3249 pipe_class fcvtL2D(regD dst, iRegL src) %{
3250     single_instruction;
3251     dst   : X(write);
3252     src   : E(read);
3253     FA    : R;
3254 %}
3255 
3256 // Floating Point Convert L->F
3257 pipe_class fcvtL2F(regF dst, iRegL src) %{
3258     single_instruction;
3259     dst   : X(write);
3260     src   : E(read);
3261     FA    : R;
3262 %}
3263 
3264 // Floating Point Convert D->F
3265 pipe_class fcvtD2F(regD dst, regF src) %{
3266     single_instruction;
3267     dst   : X(write);
3268     src   : E(read);
3269     FA    : R;
3270 %}
3271 
3272 // Floating Point Convert I->L
3273 pipe_class fcvtI2L(regD dst, regF src) %{
3274     single_instruction;
3275     dst   : X(write);
3276     src   : E(read);
3277     FA    : R;
3278 %}
3279 
3280 // Floating Point Convert D->F
3281 pipe_class fcvtD2I(iRegI dst, regD src, flagsReg cr) %{
3282     instruction_count(1); multiple_bundles;
3283     dst   : X(write)+6;
3284     src   : E(read);
3285     FA    : R;
3286 %}
3287 
3288 // Floating Point Convert D->L
3289 pipe_class fcvtD2L(regD dst, regD src, flagsReg cr) %{
3290     instruction_count(1); multiple_bundles;
3291     dst   : X(write)+6;
3292     src   : E(read);
3293     FA    : R;
3294 %}
3295 
3296 // Floating Point Convert F->I
3297 pipe_class fcvtF2I(regF dst, regF src, flagsReg cr) %{
3298     instruction_count(1); multiple_bundles;
3299     dst   : X(write)+6;
3300     src   : E(read);
3301     FA    : R;
3302 %}
3303 
3304 // Floating Point Convert F->L
3305 pipe_class fcvtF2L(regD dst, regF src, flagsReg cr) %{
3306     instruction_count(1); multiple_bundles;
3307     dst   : X(write)+6;
3308     src   : E(read);
3309     FA    : R;
3310 %}
3311 
3312 // Floating Point Convert I->F
3313 pipe_class fcvtI2F(regF dst, regF src) %{
3314     single_instruction;
3315     dst   : X(write);
3316     src   : E(read);
3317     FA    : R;
3318 %}
3319 
3320 // Floating Point Compare
3321 pipe_class faddF_fcc_reg_reg_zero(flagsRegF cr, regF src1, regF src2, immI0 zero) %{
3322     single_instruction;
3323     cr    : X(write);
3324     src1  : E(read);
3325     src2  : E(read);
3326     FA    : R;
3327 %}
3328 
3329 // Floating Point Compare
3330 pipe_class faddD_fcc_reg_reg_zero(flagsRegF cr, regD src1, regD src2, immI0 zero) %{
3331     single_instruction;
3332     cr    : X(write);
3333     src1  : E(read);
3334     src2  : E(read);
3335     FA    : R;
3336 %}
3337 
3338 // Floating Add Nop
3339 pipe_class fadd_nop() %{
3340     single_instruction;
3341     FA  : R;
3342 %}
3343 
3344 // Integer Store to Memory
3345 pipe_class istore_mem_reg(memoryI mem, iRegI src) %{
3346     single_instruction;
3347     mem   : R(read);
3348     src   : C(read);
3349     MS    : R;
3350 %}
3351 
3352 // Integer Store to Memory
3353 pipe_class istore_mem_spORreg(memoryI mem, sp_ptr_RegP src) %{
3354     single_instruction;
3355     mem   : R(read);
3356     src   : C(read);
3357     MS    : R;
3358 %}
3359 
3360 // Float Store
3361 pipe_class fstoreF_mem_reg(memoryF mem, RegF src) %{
3362     single_instruction;
3363     mem : R(read);
3364     src : C(read);
3365     MS  : R;
3366 %}
3367 
3368 // Float Store
3369 pipe_class fstoreF_mem_zero(memoryF mem, immF0 src) %{
3370     single_instruction;
3371     mem : R(read);
3372     MS  : R;
3373 %}
3374 
3375 // Double Store
3376 pipe_class fstoreD_mem_reg(memoryD mem, RegD src) %{
3377     instruction_count(1);
3378     mem : R(read);
3379     src : C(read);
3380     MS  : R;
3381 %}
3382 
3383 // Double Store
3384 pipe_class fstoreD_mem_zero(memoryD mem, immD0 src) %{
3385     single_instruction;
3386     mem : R(read);
3387     MS  : R;
3388 %}
3389 
3390 // Integer Load (when sign bit propagation not needed)
3391 pipe_class iload_mem(iRegI dst, memoryI mem) %{
3392     single_instruction;
3393     mem : R(read);
3394     dst : C(write);
3395     MS  : R;
3396 %}
3397 
3398 // Integer Load (when sign bit propagation or masking is needed)
3399 pipe_class iload_mask_mem(iRegI dst, memoryI mem) %{
3400     single_instruction;
3401     mem : R(read);
3402     dst : M(write);
3403     MS  : R;
3404 %}
3405 
3406 // Float Load
3407 pipe_class floadF_mem(regF dst, memoryF mem) %{
3408     single_instruction;
3409     mem : R(read);
3410     dst : M(write);
3411     MS  : R;
3412 %}
3413 
3414 // Float Load
3415 pipe_class floadD_mem(regD dst, memoryD mem) %{
3416     instruction_count(1); multiple_bundles; // Again, unaligned argument is only multiple case
3417     mem : R(read);
3418     dst : M(write);
3419     MS  : R;
3420 %}
3421 
3422 // Memory Nop
3423 pipe_class mem_nop() %{
3424     single_instruction;
3425     MS  : R;
3426 %}
3427 
3428 pipe_class sethi(iRegP dst, immI src) %{
3429     single_instruction;
3430     dst  : E(write);
3431     IALU : R;
3432 %}
3433 
3434 pipe_class loadPollP(iRegP poll) %{
3435     single_instruction;
3436     poll : R(read);
3437     MS   : R;
3438 %}
3439 
3440 pipe_class br(Universe br, label labl) %{
3441     single_instruction_with_delay_slot;
3442     BR  : R;
3443 %}
3444 
3445 pipe_class br_cc(Universe br, cmpOp cmp, flagsReg cr, label labl) %{
3446     single_instruction_with_delay_slot;
3447     cr    : E(read);
3448     BR    : R;
3449 %}
3450 
3451 pipe_class br_reg(Universe br, cmpOp cmp, iRegI op1, label labl) %{
3452     single_instruction_with_delay_slot;
3453     op1 : E(read);
3454     BR  : R;
3455     MS  : R;
3456 %}
3457 
3458 pipe_class br_nop() %{
3459     single_instruction;
3460     BR  : R;
3461 %}
3462 
3463 pipe_class simple_call(method meth) %{
3464     instruction_count(2); multiple_bundles; force_serialization;
3465     fixed_latency(100);
3466     BR  : R(1);
3467     MS  : R(1);
3468     A0  : R(1);
3469 %}
3470 
3471 pipe_class compiled_call(method meth) %{
3472     instruction_count(1); multiple_bundles; force_serialization;
3473     fixed_latency(100);
3474     MS  : R(1);
3475 %}
3476 
3477 pipe_class call(method meth) %{
3478     instruction_count(0); multiple_bundles; force_serialization;
3479     fixed_latency(100);
3480 %}
3481 
3482 pipe_class tail_call(Universe ignore, label labl) %{
3483     single_instruction; has_delay_slot;
3484     fixed_latency(100);
3485     BR  : R(1);
3486     MS  : R(1);
3487 %}
3488 
3489 pipe_class ret(Universe ignore) %{
3490     single_instruction; has_delay_slot;
3491     BR  : R(1);
3492     MS  : R(1);
3493 %}
3494 
3495 // The real do-nothing guy
3496 pipe_class empty( ) %{
3497     instruction_count(0);
3498 %}
3499 
3500 pipe_class long_memory_op() %{
3501     instruction_count(0); multiple_bundles; force_serialization;
3502     fixed_latency(25);
3503     MS  : R(1);
3504 %}
3505 
3506 // Check-cast
3507 pipe_class partial_subtype_check_pipe(Universe ignore, iRegP array, iRegP match ) %{
3508     array : R(read);
3509     match  : R(read);
3510     IALU   : R(2);
3511     BR     : R(2);
3512     MS     : R;
3513 %}
3514 
3515 // Convert FPU flags into +1,0,-1
3516 pipe_class floating_cmp( iRegI dst, regF src1, regF src2 ) %{
3517     src1  : E(read);
3518     src2  : E(read);
3519     dst   : E(write);
3520     FA    : R;
3521     MS    : R(2);
3522     BR    : R(2);
3523 %}
3524 
3525 // Compare for p < q, and conditionally add y
3526 pipe_class cadd_cmpltmask( iRegI p, iRegI q, iRegI y ) %{
3527     p     : E(read);
3528     q     : E(read);
3529     y     : E(read);
3530     IALU  : R(3)
3531 %}
3532 
3533 // Perform a compare, then move conditionally in a branch delay slot.
3534 pipe_class min_max( iRegI src2, iRegI srcdst ) %{
3535     src2   : E(read);
3536     srcdst : E(read);
3537     IALU   : R;
3538     BR     : R;
3539 %}
3540 
3541 // Define the class for the Nop node
3542 define %{
3543    MachNop = ialu_nop;
3544 %}
3545 
3546 %}
3547 
3548 //----------INSTRUCTIONS-------------------------------------------------------
3549 
3550 //------------Special Nop instructions for bundling - no match rules-----------
3551 // Nop using the A0 functional unit
3552 instruct Nop_A0() %{
3553   ins_pipe(ialu_nop_A0);
3554 %}
3555 
3556 // Nop using the A1 functional unit
3557 instruct Nop_A1( ) %{
3558   ins_pipe(ialu_nop_A1);
3559 %}
3560 
3561 // Nop using the memory functional unit
3562 instruct Nop_MS( ) %{
3563   ins_pipe(mem_nop);
3564 %}
3565 
3566 // Nop using the floating add functional unit
3567 instruct Nop_FA( ) %{
3568   ins_pipe(fadd_nop);
3569 %}
3570 
3571 // Nop using the branch functional unit
3572 instruct Nop_BR( ) %{
3573   ins_pipe(br_nop);
3574 %}
3575 
3576 //----------Load/Store/Move Instructions---------------------------------------
3577 //----------Load Instructions--------------------------------------------------
3578 // Load Byte (8bit signed)
3579 instruct loadB(iRegI dst, memoryB mem) %{
3580   match(Set dst (LoadB mem));
3581   ins_cost(MEMORY_REF_COST);
3582 
3583   size(4);
3584   format %{ "LDRSB   $dst,$mem\t! byte -> int" %}
3585   ins_encode %{
3586     __ ldrsb($dst$$Register, $mem$$Address);
3587   %}
3588   ins_pipe(iload_mask_mem);
3589 %}
3590 
3591 // Load Byte (8bit signed) into a Long Register
3592 instruct loadB2L(iRegL dst, memoryB mem) %{
3593   match(Set dst (ConvI2L (LoadB mem)));
3594   ins_cost(MEMORY_REF_COST);
3595 
3596   size(8);
3597   format %{ "LDRSB $dst.lo,$mem\t! byte -> long\n\t"
3598             "ASR   $dst.hi,$dst.lo,31" %}
3599   ins_encode %{
3600     __ ldrsb($dst$$Register, $mem$$Address);
3601     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
3602   %}
3603   ins_pipe(iload_mask_mem);
3604 %}
3605 
3606 // Load Unsigned Byte (8bit UNsigned) into an int reg
3607 instruct loadUB(iRegI dst, memoryB mem) %{
3608   match(Set dst (LoadUB mem));
3609   ins_cost(MEMORY_REF_COST);
3610 
3611   size(4);
3612   format %{ "LDRB   $dst,$mem\t! ubyte -> int" %}
3613   ins_encode %{
3614     __ ldrb($dst$$Register, $mem$$Address);
3615   %}
3616   ins_pipe(iload_mem);
3617 %}
3618 
3619 // Load Unsigned Byte (8bit UNsigned) into a Long Register
3620 instruct loadUB2L(iRegL dst, memoryB mem) %{
3621   match(Set dst (ConvI2L (LoadUB mem)));
3622   ins_cost(MEMORY_REF_COST);
3623 
3624   size(8);
3625   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
3626             "MOV   $dst.hi,0" %}
3627   ins_encode %{
3628     __ ldrb($dst$$Register, $mem$$Address);
3629     __ mov($dst$$Register->successor(), 0);
3630   %}
3631   ins_pipe(iload_mem);
3632 %}
3633 
3634 // Load Unsigned Byte (8 bit UNsigned) with immediate mask into Long Register
3635 instruct loadUB2L_limmI(iRegL dst, memoryB mem, limmIlow8 mask) %{
3636   match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
3637 
3638   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
3639   size(12);
3640   format %{ "LDRB  $dst.lo,$mem\t! ubyte -> long\n\t"
3641             "MOV   $dst.hi,0\n\t"
3642             "AND  $dst.lo,$dst.lo,$mask" %}
3643   ins_encode %{
3644     __ ldrb($dst$$Register, $mem$$Address);
3645     __ mov($dst$$Register->successor(), 0);
3646     __ andr($dst$$Register, $dst$$Register, limmI_low($mask$$constant, 8));
3647   %}
3648   ins_pipe(iload_mem);
3649 %}
3650 
3651 // Load Short (16bit signed)
3652 
3653 instruct loadS(iRegI dst, memoryS mem) %{
3654   match(Set dst (LoadS mem));
3655   ins_cost(MEMORY_REF_COST);
3656 
3657   size(4);
3658   format %{ "LDRSH   $dst,$mem\t! short" %}
3659   ins_encode %{
3660     __ ldrsh($dst$$Register, $mem$$Address);
3661   %}
3662   ins_pipe(iload_mask_mem);
3663 %}
3664 
3665 // Load Short (16 bit signed) to Byte (8 bit signed)
3666 instruct loadS2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
3667   match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
3668   ins_cost(MEMORY_REF_COST);
3669 
3670   size(4);
3671 
3672   format %{ "LDRSB   $dst,$mem\t! short -> byte" %}
3673   ins_encode %{
3674     __ ldrsb($dst$$Register, $mem$$Address);
3675   %}
3676   ins_pipe(iload_mask_mem);
3677 %}
3678 
3679 // Load Short (16bit signed) into a Long Register
3680 instruct loadS2L(iRegL dst, memoryS mem) %{
3681   match(Set dst (ConvI2L (LoadS mem)));
3682   ins_cost(MEMORY_REF_COST);
3683 
3684   size(8);
3685   format %{ "LDRSH $dst.lo,$mem\t! short -> long\n\t"
3686             "ASR   $dst.hi,$dst.lo,31" %}
3687   ins_encode %{
3688     __ ldrsh($dst$$Register, $mem$$Address);
3689     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
3690   %}
3691   ins_pipe(iload_mask_mem);
3692 %}
3693 
3694 // Load Unsigned Short/Char (16bit UNsigned)
3695 
3696 
3697 instruct loadUS(iRegI dst, memoryS mem) %{
3698   match(Set dst (LoadUS mem));
3699   ins_cost(MEMORY_REF_COST);
3700 
3701   size(4);
3702   format %{ "LDRH   $dst,$mem\t! ushort/char" %}
3703   ins_encode %{
3704     __ ldrh($dst$$Register, $mem$$Address);
3705   %}
3706   ins_pipe(iload_mem);
3707 %}
3708 
3709 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
3710 instruct loadUS2B(iRegI dst, memoryB mem, immI_24 twentyfour) %{
3711   match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
3712   ins_cost(MEMORY_REF_COST);
3713 
3714   size(4);
3715   format %{ "LDRSB   $dst,$mem\t! ushort -> byte" %}
3716   ins_encode %{
3717     __ ldrsb($dst$$Register, $mem$$Address);
3718   %}
3719   ins_pipe(iload_mask_mem);
3720 %}
3721 
3722 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register
3723 instruct loadUS2L(iRegL dst, memoryS mem) %{
3724   match(Set dst (ConvI2L (LoadUS mem)));
3725   ins_cost(MEMORY_REF_COST);
3726 
3727   size(8);
3728   format %{ "LDRH  $dst.lo,$mem\t! short -> long\n\t"
3729             "MOV   $dst.hi, 0" %}
3730   ins_encode %{
3731     __ ldrh($dst$$Register, $mem$$Address);
3732     __ mov($dst$$Register->successor(), 0);
3733   %}
3734   ins_pipe(iload_mem);
3735 %}
3736 
3737 // Load Unsigned Short/Char (16bit UNsigned) with mask 0xFF into a Long Register
3738 instruct loadUS2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
3739   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
3740   ins_cost(MEMORY_REF_COST);
3741 
3742   size(8);
3743   format %{ "LDRB  $dst.lo,$mem\t! \n\t"
3744             "MOV   $dst.hi, 0" %}
3745   ins_encode %{
3746     __ ldrb($dst$$Register, $mem$$Address);
3747     __ mov($dst$$Register->successor(), 0);
3748   %}
3749   ins_pipe(iload_mem);
3750 %}
3751 
3752 // Load Unsigned Short/Char (16bit UNsigned) with a immediate mask into a Long Register
3753 instruct loadUS2L_limmI(iRegL dst, memoryS mem, limmI mask) %{
3754   match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
3755   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
3756 
3757   size(12);
3758   format %{ "LDRH   $dst,$mem\t! ushort/char & mask -> long\n\t"
3759             "MOV    $dst.hi, 0\n\t"
3760             "AND    $dst,$dst,$mask" %}
3761   ins_encode %{
3762     __ ldrh($dst$$Register, $mem$$Address);
3763     __ mov($dst$$Register->successor(), 0);
3764     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
3765   %}
3766   ins_pipe(iload_mem);
3767 %}
3768 
3769 // Load Integer
3770 
3771 
3772 instruct loadI(iRegI dst, memoryI mem) %{
3773   match(Set dst (LoadI mem));
3774   ins_cost(MEMORY_REF_COST);
3775 
3776   size(4);
3777   format %{ "ldr_s32 $dst,$mem\t! int" %}
3778   ins_encode %{
3779     __ ldr_s32($dst$$Register, $mem$$Address);
3780   %}
3781   ins_pipe(iload_mem);
3782 %}
3783 
3784 // Load Integer to Byte (8 bit signed)
3785 instruct loadI2B(iRegI dst, memoryS mem, immI_24 twentyfour) %{
3786   match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
3787   ins_cost(MEMORY_REF_COST);
3788 
3789   size(4);
3790 
3791   format %{ "LDRSB   $dst,$mem\t! int -> byte" %}
3792   ins_encode %{
3793     __ ldrsb($dst$$Register, $mem$$Address);
3794   %}
3795   ins_pipe(iload_mask_mem);
3796 %}
3797 
3798 // Load Integer to Unsigned Byte (8 bit UNsigned)
3799 instruct loadI2UB(iRegI dst, memoryB mem, immI_255 mask) %{
3800   match(Set dst (AndI (LoadI mem) mask));
3801   ins_cost(MEMORY_REF_COST);
3802 
3803   size(4);
3804 
3805   format %{ "LDRB   $dst,$mem\t! int -> ubyte" %}
3806   ins_encode %{
3807     __ ldrb($dst$$Register, $mem$$Address);
3808   %}
3809   ins_pipe(iload_mask_mem);
3810 %}
3811 
3812 // Load Integer to Short (16 bit signed)
3813 instruct loadI2S(iRegI dst, memoryS mem, immI_16 sixteen) %{
3814   match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
3815   ins_cost(MEMORY_REF_COST);
3816 
3817   size(4);
3818   format %{ "LDRSH   $dst,$mem\t! int -> short" %}
3819   ins_encode %{
3820     __ ldrsh($dst$$Register, $mem$$Address);
3821   %}
3822   ins_pipe(iload_mask_mem);
3823 %}
3824 
3825 // Load Integer to Unsigned Short (16 bit UNsigned)
3826 instruct loadI2US(iRegI dst, memoryS mem, immI_65535 mask) %{
3827   match(Set dst (AndI (LoadI mem) mask));
3828   ins_cost(MEMORY_REF_COST);
3829 
3830   size(4);
3831   format %{ "LDRH   $dst,$mem\t! int -> ushort/char" %}
3832   ins_encode %{
3833     __ ldrh($dst$$Register, $mem$$Address);
3834   %}
3835   ins_pipe(iload_mask_mem);
3836 %}
3837 
3838 // Load Integer into a Long Register
3839 instruct loadI2L(iRegL dst, memoryI mem) %{
3840   match(Set dst (ConvI2L (LoadI mem)));
3841   ins_cost(MEMORY_REF_COST);
3842 
3843   size(8);
3844   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
3845             "ASR   $dst.hi,$dst.lo,31\t! int->long" %}
3846   ins_encode %{
3847     __ ldr($dst$$Register, $mem$$Address);
3848     __ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
3849   %}
3850   ins_pipe(iload_mask_mem);
3851 %}
3852 
3853 // Load Integer with mask 0xFF into a Long Register
3854 instruct loadI2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
3855   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
3856   ins_cost(MEMORY_REF_COST);
3857 
3858   size(8);
3859   format %{ "LDRB   $dst.lo,$mem\t! int & 0xFF -> long\n\t"
3860             "MOV    $dst.hi, 0" %}
3861   ins_encode %{
3862     __ ldrb($dst$$Register, $mem$$Address);
3863     __ mov($dst$$Register->successor(), 0);
3864   %}
3865   ins_pipe(iload_mem);
3866 %}
3867 
3868 // Load Integer with mask 0xFFFF into a Long Register
3869 instruct loadI2L_immI_65535(iRegL dst, memoryS mem, immI_65535 mask) %{
3870   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
3871   ins_cost(MEMORY_REF_COST);
3872 
3873   size(8);
3874   format %{ "LDRH   $dst,$mem\t! int & 0xFFFF -> long\n\t"
3875             "MOV    $dst.hi, 0" %}
3876   ins_encode %{
3877     __ ldrh($dst$$Register, $mem$$Address);
3878     __ mov($dst$$Register->successor(), 0);
3879   %}
3880   ins_pipe(iload_mask_mem);
3881 %}
3882 
3883 // Load Integer with a 31-bit immediate mask into a Long Register
3884 instruct loadI2L_limmU31(iRegL dst, memoryI mem, limmU31 mask) %{
3885   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
3886   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
3887 
3888   size(12);
3889   format %{ "LDR   $dst.lo,$mem\t! int -> long\n\t"
3890             "MOV    $dst.hi, 0\n\t"
3891             "AND   $dst,$dst,$mask" %}
3892 
3893   ins_encode %{
3894     __ ldr($dst$$Register, $mem$$Address);
3895     __ mov($dst$$Register->successor(), 0);
3896     __ andr($dst$$Register, $dst$$Register, $mask$$constant);
3897   %}
3898   ins_pipe(iload_mem);
3899 %}
3900 
3901 // Load Integer with a 31-bit mask into a Long Register
3902 // FIXME: use iRegI mask, remove tmp?
3903 instruct loadI2L_immU31(iRegL dst, memoryI mem, immU31 mask, iRegI tmp) %{
3904   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
3905   effect(TEMP dst, TEMP tmp);
3906 
3907   ins_cost(MEMORY_REF_COST + 4*DEFAULT_COST);
3908   size(20);
3909   format %{ "LDR      $mem,$dst\t! int & 31-bit mask -> long\n\t"
3910             "MOV      $dst.hi, 0\n\t"
3911             "MOV_SLOW $tmp,$mask\n\t"
3912             "AND      $dst,$tmp,$dst" %}
3913   ins_encode %{
3914     __ ldr($dst$$Register, $mem$$Address);
3915     __ mov($dst$$Register->successor(), 0);
3916     __ mov_slow($tmp$$Register, $mask$$constant);
3917     __ andr($dst$$Register, $dst$$Register, $tmp$$Register);
3918   %}
3919   ins_pipe(iload_mem);
3920 %}
3921 
3922 // Load Unsigned Integer into a Long Register
3923 instruct loadUI2L(iRegL dst, memoryI mem, immL_32bits mask) %{
3924   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
3925   ins_cost(MEMORY_REF_COST);
3926 
3927   size(8);
3928   format %{ "LDR   $dst.lo,$mem\t! uint -> long\n\t"
3929             "MOV   $dst.hi,0" %}
3930   ins_encode %{
3931     __ ldr($dst$$Register, $mem$$Address);
3932     __ mov($dst$$Register->successor(), 0);
3933   %}
3934   ins_pipe(iload_mem);
3935 %}
3936 
3937 // Load Long
3938 
3939 
3940 instruct loadL(iRegLd dst, memoryL mem ) %{
3941   predicate(!((LoadLNode*)n)->require_atomic_access());
3942   match(Set dst (LoadL mem));
3943   effect(TEMP dst);
3944   ins_cost(MEMORY_REF_COST);
3945 
3946   size(4);
3947   format %{ "ldr_64  $dst,$mem\t! long" %}
3948   ins_encode %{
3949     __ ldr_64($dst$$Register, $mem$$Address);
3950   %}
3951   ins_pipe(iload_mem);
3952 %}
3953 
3954 instruct loadL_2instr(iRegL dst, memorylong mem ) %{
3955   predicate(!((LoadLNode*)n)->require_atomic_access());
3956   match(Set dst (LoadL mem));
3957   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
3958 
3959   size(8);
3960   format %{ "LDR    $dst.lo,$mem \t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
3961             "LDR    $dst.hi,$mem+4 or $mem" %}
3962   ins_encode %{
3963     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
3964     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
3965 
3966     if ($dst$$Register == reg_to_register_object($mem$$base)) {
3967       __ ldr($dst$$Register->successor(), Amemhi);
3968       __ ldr($dst$$Register, Amemlo);
3969     } else {
3970       __ ldr($dst$$Register, Amemlo);
3971       __ ldr($dst$$Register->successor(), Amemhi);
3972     }
3973   %}
3974   ins_pipe(iload_mem);
3975 %}
3976 
3977 instruct loadL_volatile(iRegL dst, indirect mem ) %{
3978   predicate(((LoadLNode*)n)->require_atomic_access());
3979   match(Set dst (LoadL mem));
3980   ins_cost(MEMORY_REF_COST);
3981 
3982   size(4);
3983   format %{ "LDMIA    $dst,$mem\t! long" %}
3984   ins_encode %{
3985     // FIXME: why is ldmia considered atomic?  Should be ldrexd
3986     RegisterSet set($dst$$Register);
3987     set = set | reg_to_register_object($dst$$reg + 1);
3988     __ ldmia(reg_to_register_object($mem$$base), set);
3989   %}
3990   ins_pipe(iload_mem);
3991 %}
3992 
3993 instruct loadL_volatile_fp(iRegL dst, memoryD mem ) %{
3994   predicate(((LoadLNode*)n)->require_atomic_access());
3995   match(Set dst (LoadL mem));
3996   ins_cost(MEMORY_REF_COST);
3997 
3998   size(8);
3999   format %{ "FLDD      S14, $mem"
4000             "FMRRD    $dst, S14\t! long \n't" %}
4001   ins_encode %{
4002     __ fldd(S14, $mem$$Address);
4003     __ fmrrd($dst$$Register, $dst$$Register->successor(), S14);
4004   %}
4005   ins_pipe(iload_mem);
4006 %}
4007 
4008 instruct loadL_unaligned(iRegL dst, memorylong mem ) %{
4009   match(Set dst (LoadL_unaligned mem));
4010   ins_cost(MEMORY_REF_COST);
4011 
4012   size(8);
4013   format %{ "LDR    $dst.lo,$mem\t! long order of instrs reversed if $dst.lo == base($mem)\n\t"
4014             "LDR    $dst.hi,$mem+4" %}
4015   ins_encode %{
4016     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4017     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
4018 
4019     if ($dst$$Register == reg_to_register_object($mem$$base)) {
4020       __ ldr($dst$$Register->successor(), Amemhi);
4021       __ ldr($dst$$Register, Amemlo);
4022     } else {
4023       __ ldr($dst$$Register, Amemlo);
4024       __ ldr($dst$$Register->successor(), Amemhi);
4025     }
4026   %}
4027   ins_pipe(iload_mem);
4028 %}
4029 
4030 // Load Range
4031 instruct loadRange(iRegI dst, memoryI mem) %{
4032   match(Set dst (LoadRange mem));
4033   ins_cost(MEMORY_REF_COST);
4034 
4035   size(4);
4036   format %{ "LDR_u32 $dst,$mem\t! range" %}
4037   ins_encode %{
4038     __ ldr_u32($dst$$Register, $mem$$Address);
4039   %}
4040   ins_pipe(iload_mem);
4041 %}
4042 
4043 // Load Pointer
4044 
4045 
4046 instruct loadP(iRegP dst, memoryP mem) %{
4047   match(Set dst (LoadP mem));
4048   ins_cost(MEMORY_REF_COST);
4049   size(4);
4050 
4051   format %{ "LDR   $dst,$mem\t! ptr" %}
4052   ins_encode %{
4053     __ ldr($dst$$Register, $mem$$Address);
4054   %}
4055   ins_pipe(iload_mem);
4056 %}
4057 
4058 #ifdef XXX
4059 // FIXME XXXX
4060 //instruct loadSP(iRegP dst, memoryP mem) %{
4061 instruct loadSP(SPRegP dst, memoryP mem, iRegP tmp) %{
4062   match(Set dst (LoadP mem));
4063   effect(TEMP tmp);
4064   ins_cost(MEMORY_REF_COST+1);
4065   size(8);
4066 
4067   format %{ "LDR   $tmp,$mem\t! ptr\n\t"
4068             "MOV   $dst,$tmp\t! ptr" %}
4069   ins_encode %{
4070     __ ldr($tmp$$Register, $mem$$Address);
4071     __ mov($dst$$Register, $tmp$$Register);
4072   %}
4073   ins_pipe(iload_mem);
4074 %}
4075 #endif
4076 
4077 #ifdef _LP64
4078 // Load Compressed Pointer
4079 
4080 // XXX This variant shouldn't be necessary if 6217251 is implemented
4081 instruct loadNoff(iRegN dst, memoryScaledI mem, aimmX off, iRegP tmp) %{
4082   match(Set dst (LoadN (AddP mem off)));
4083   ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
4084   effect(TEMP tmp);
4085   size(4 * 2);
4086 
4087   format %{ "ldr_u32 $dst,$mem+$off\t! compressed ptr temp=$tmp" %}
4088   ins_encode %{
4089     Register base = reg_to_register_object($mem$$base);
4090     __ add($tmp$$Register, base, $off$$constant);
4091     Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4092     __ ldr_u32($dst$$Register, nmem);
4093   %}
4094   ins_pipe(iload_mem);
4095 %}
4096 
4097 instruct loadN(iRegN dst, memoryI mem) %{
4098   match(Set dst (LoadN mem));
4099   ins_cost(MEMORY_REF_COST);
4100   size(4);
4101 
4102   format %{ "ldr_u32 $dst,$mem\t! compressed ptr" %}
4103   ins_encode %{
4104     __ ldr_u32($dst$$Register, $mem$$Address);
4105   %}
4106   ins_pipe(iload_mem);
4107 %}
4108 #endif
4109 
4110 // Load Klass Pointer
4111 instruct loadKlass(iRegP dst, memoryI mem) %{
4112   match(Set dst (LoadKlass mem));
4113   ins_cost(MEMORY_REF_COST);
4114   size(4);
4115 
4116   format %{ "LDR   $dst,$mem\t! klass ptr" %}
4117   ins_encode %{
4118     __ ldr($dst$$Register, $mem$$Address);
4119   %}
4120   ins_pipe(iload_mem);
4121 %}
4122 
4123 #ifdef _LP64
4124 // Load narrow Klass Pointer
4125 instruct loadNKlass(iRegN dst, memoryI mem) %{
4126   match(Set dst (LoadNKlass mem));
4127   ins_cost(MEMORY_REF_COST);
4128   size(4);
4129 
4130   format %{ "ldr_u32 $dst,$mem\t! compressed klass ptr" %}
4131   ins_encode %{
4132     __ ldr_u32($dst$$Register, $mem$$Address);
4133   %}
4134   ins_pipe(iload_mem);
4135 %}
4136 #endif
4137 
4138 
4139 instruct loadD(regD dst, memoryD mem) %{
4140   match(Set dst (LoadD mem));
4141   ins_cost(MEMORY_REF_COST);
4142 
4143   size(4);
4144   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
4145   // only LDREXD and STREXD are 64-bit single-copy atomic
4146   format %{ "FLDD   $dst,$mem" %}
4147   ins_encode %{
4148     __ ldr_double($dst$$FloatRegister, $mem$$Address);
4149   %}
4150   ins_pipe(floadD_mem);
4151 %}
4152 
4153 // Load Double - UNaligned
4154 instruct loadD_unaligned(regD_low dst, memoryF2 mem ) %{
4155   match(Set dst (LoadD_unaligned mem));
4156   ins_cost(MEMORY_REF_COST*2+DEFAULT_COST);
4157   size(8);
4158   format %{ "FLDS    $dst.lo,$mem\t! misaligned double\n"
4159           "\tFLDS    $dst.hi,$mem+4\t!" %}
4160   ins_encode %{
4161     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4162     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
4163       __ flds($dst$$FloatRegister, Amemlo);
4164       __ flds($dst$$FloatRegister->successor(), Amemhi);
4165   %}
4166   ins_pipe(iload_mem);
4167 %}
4168 
4169 
4170 instruct loadF(regF dst, memoryF mem) %{
4171   match(Set dst (LoadF mem));
4172 
4173   ins_cost(MEMORY_REF_COST);
4174   size(4);
4175   format %{ "FLDS    $dst,$mem" %}
4176   ins_encode %{
4177     __ ldr_float($dst$$FloatRegister, $mem$$Address);
4178   %}
4179   ins_pipe(floadF_mem);
4180 %}
4181 
4182 
4183 // // Load Constant
4184 instruct loadConI( iRegI dst, immI src ) %{
4185   match(Set dst src);
4186   ins_cost(DEFAULT_COST * 3/2);
4187   format %{ "MOV_SLOW    $dst, $src" %}
4188   ins_encode %{
4189     __ mov_slow($dst$$Register, $src$$constant);
4190   %}
4191   ins_pipe(ialu_hi_lo_reg);
4192 %}
4193 
4194 instruct loadConIMov( iRegI dst, immIMov src ) %{
4195   match(Set dst src);
4196   size(4);
4197   format %{ "MOV    $dst, $src" %}
4198   ins_encode %{
4199     __ mov($dst$$Register, $src$$constant);
4200   %}
4201   ins_pipe(ialu_imm);
4202 %}
4203 
4204 instruct loadConIMovn( iRegI dst, immIRotn src ) %{
4205   match(Set dst src);
4206   size(4);
4207   format %{ "MVN    $dst, ~$src" %}
4208   ins_encode %{
4209     __ mvn($dst$$Register, ~$src$$constant);
4210   %}
4211   ins_pipe(ialu_imm_n);
4212 %}
4213 
4214 instruct loadConI16( iRegI dst, immI16 src ) %{
4215   match(Set dst src);
4216   size(4);
4217   format %{ "MOVW    $dst, $src" %}
4218   ins_encode %{
4219     __ movw($dst$$Register, $src$$constant);
4220   %}
4221   ins_pipe(ialu_imm_n);
4222 %}
4223 
4224 instruct loadConP(iRegP dst, immP src) %{
4225   match(Set dst src);
4226   ins_cost(DEFAULT_COST * 3/2);
4227   format %{ "MOV_SLOW    $dst,$src\t!ptr" %}
4228   ins_encode %{
4229     relocInfo::relocType constant_reloc = _opnds[1]->constant_reloc();
4230     intptr_t val = $src$$constant;
4231     if (constant_reloc == relocInfo::oop_type) {
4232       __ mov_oop($dst$$Register, (jobject)val);
4233     } else if (constant_reloc == relocInfo::metadata_type) {
4234       __ mov_metadata($dst$$Register, (Metadata*)val);
4235     } else {
4236       __ mov_slow($dst$$Register, val);
4237     }
4238   %}
4239   ins_pipe(loadConP);
4240 %}
4241 
4242 
4243 instruct loadConP_poll(iRegP dst, immP_poll src) %{
4244   match(Set dst src);
4245   ins_cost(DEFAULT_COST);
4246   format %{ "MOV_SLOW    $dst,$src\t!ptr" %}
4247   ins_encode %{
4248       __ mov_slow($dst$$Register, $src$$constant);
4249   %}
4250   ins_pipe(loadConP_poll);
4251 %}
4252 
4253 instruct loadConL(iRegL dst, immL src) %{
4254   match(Set dst src);
4255   ins_cost(DEFAULT_COST * 4);
4256   format %{ "MOV_SLOW   $dst.lo, $src & 0x0FFFFFFFFL \t! long\n\t"
4257             "MOV_SLOW   $dst.hi, $src >> 32" %}
4258   ins_encode %{
4259     __ mov_slow(reg_to_register_object($dst$$reg), $src$$constant & 0x0FFFFFFFFL);
4260     __ mov_slow(reg_to_register_object($dst$$reg + 1), ((julong)($src$$constant)) >> 32);
4261   %}
4262   ins_pipe(loadConL);
4263 %}
4264 
4265 instruct loadConL16( iRegL dst, immL16 src ) %{
4266   match(Set dst src);
4267   ins_cost(DEFAULT_COST * 2);
4268 
4269   size(8);
4270   format %{ "MOVW    $dst.lo, $src \n\t"
4271             "MOVW    $dst.hi, 0 \n\t" %}
4272   ins_encode %{
4273     __ movw($dst$$Register, $src$$constant);
4274     __ movw($dst$$Register->successor(), 0);
4275   %}
4276   ins_pipe(ialu_imm);
4277 %}
4278 
4279 instruct loadConF_imm8(regF dst, imm8F src) %{
4280   match(Set dst src);
4281   ins_cost(DEFAULT_COST);
4282   size(4);
4283 
4284   format %{ "FCONSTS      $dst, $src"%}
4285 
4286   ins_encode %{
4287     __ fconsts($dst$$FloatRegister, Assembler::float_num($src$$constant).imm8());
4288   %}
4289   ins_pipe(loadConFD); // FIXME
4290 %}
4291 
4292 
4293 instruct loadConF(regF dst, immF src, iRegI tmp) %{
4294   match(Set dst src);
4295   ins_cost(DEFAULT_COST * 2);
4296   effect(TEMP tmp);
4297   size(3*4);
4298 
4299   format %{ "MOV_SLOW  $tmp, $src\n\t"
4300             "FMSR      $dst, $tmp"%}
4301 
4302   ins_encode %{
4303     // FIXME revisit once 6961697 is in
4304     union {
4305       jfloat f;
4306       int i;
4307     } v;
4308     v.f = $src$$constant;
4309     __ mov_slow($tmp$$Register, v.i);
4310     __ fmsr($dst$$FloatRegister, $tmp$$Register);
4311   %}
4312   ins_pipe(loadConFD); // FIXME
4313 %}
4314 
4315 instruct loadConD_imm8(regD dst, imm8D src) %{
4316   match(Set dst src);
4317   ins_cost(DEFAULT_COST);
4318   size(4);
4319 
4320   format %{ "FCONSTD      $dst, $src"%}
4321 
4322   ins_encode %{
4323     __ fconstd($dst$$FloatRegister, Assembler::double_num($src$$constant).imm8());
4324   %}
4325   ins_pipe(loadConFD); // FIXME
4326 %}
4327 
4328 instruct loadConD(regD dst, immD src, iRegP tmp) %{
4329   match(Set dst src);
4330   effect(TEMP tmp);
4331   ins_cost(MEMORY_REF_COST);
4332   format %{ "FLDD  $dst, [$constanttablebase + $constantoffset]\t! load from constant table: double=$src" %}
4333 
4334   ins_encode %{
4335     Register r = $constanttablebase;
4336     int offset  = $constantoffset($src);
4337     if (!is_memoryD(offset)) {                // can't use a predicate
4338                                               // in load constant instructs
4339       __ add_slow($tmp$$Register, r, offset);
4340       r = $tmp$$Register;
4341       offset = 0;
4342     }
4343     __ ldr_double($dst$$FloatRegister, Address(r, offset));
4344   %}
4345   ins_pipe(loadConFD);
4346 %}
4347 
4348 // Prefetch instructions.
4349 // Must be safe to execute with invalid address (cannot fault).
4350 
4351 instruct prefetchAlloc_mp( memoryP mem ) %{
4352   predicate(VM_Version::has_multiprocessing_extensions());
4353   match( PrefetchAllocation mem );
4354   ins_cost(MEMORY_REF_COST);
4355   size(4);
4356 
4357   format %{ "PLDW $mem\t! Prefetch allocation" %}
4358   ins_encode %{
4359     __ pldw($mem$$Address);
4360   %}
4361   ins_pipe(iload_mem);
4362 %}
4363 
4364 instruct prefetchAlloc_sp( memoryP mem ) %{
4365   predicate(!VM_Version::has_multiprocessing_extensions());
4366   match( PrefetchAllocation mem );
4367   ins_cost(MEMORY_REF_COST);
4368   size(4);
4369 
4370   format %{ "PLD $mem\t! Prefetch allocation" %}
4371   ins_encode %{
4372     __ pld($mem$$Address);
4373   %}
4374   ins_pipe(iload_mem);
4375 %}
4376 
4377 
4378 //----------Store Instructions-------------------------------------------------
4379 // Store Byte
4380 instruct storeB(memoryB mem, store_RegI src) %{
4381   match(Set mem (StoreB mem src));
4382   ins_cost(MEMORY_REF_COST);
4383 
4384   size(4);
4385   format %{ "STRB    $src,$mem\t! byte" %}
4386   ins_encode %{
4387     __ strb($src$$Register, $mem$$Address);
4388   %}
4389   ins_pipe(istore_mem_reg);
4390 %}
4391 
4392 instruct storeCM(memoryB mem, store_RegI src) %{
4393   match(Set mem (StoreCM mem src));
4394   ins_cost(MEMORY_REF_COST);
4395 
4396   size(4);
4397   format %{ "STRB    $src,$mem\t! CMS card-mark byte" %}
4398   ins_encode %{
4399     __ strb($src$$Register, $mem$$Address);
4400   %}
4401   ins_pipe(istore_mem_reg);
4402 %}
4403 
4404 // Store Char/Short
4405 
4406 
4407 instruct storeC(memoryS mem, store_RegI src) %{
4408   match(Set mem (StoreC mem src));
4409   ins_cost(MEMORY_REF_COST);
4410 
4411   size(4);
4412   format %{ "STRH    $src,$mem\t! short" %}
4413   ins_encode %{
4414     __ strh($src$$Register, $mem$$Address);
4415   %}
4416   ins_pipe(istore_mem_reg);
4417 %}
4418 
4419 // Store Integer
4420 
4421 
4422 instruct storeI(memoryI mem, store_RegI src) %{
4423   match(Set mem (StoreI mem src));
4424   ins_cost(MEMORY_REF_COST);
4425 
4426   size(4);
4427   format %{ "str_32 $src,$mem" %}
4428   ins_encode %{
4429     __ str_32($src$$Register, $mem$$Address);
4430   %}
4431   ins_pipe(istore_mem_reg);
4432 %}
4433 
4434 // Store Long
4435 
4436 
4437 instruct storeL(memoryL mem, store_RegLd src) %{
4438   predicate(!((StoreLNode*)n)->require_atomic_access());
4439   match(Set mem (StoreL mem src));
4440   ins_cost(MEMORY_REF_COST);
4441 
4442   size(4);
4443   format %{ "str_64  $src,$mem\t! long\n\t" %}
4444 
4445   ins_encode %{
4446     __ str_64($src$$Register, $mem$$Address);
4447   %}
4448   ins_pipe(istore_mem_reg);
4449 %}
4450 
4451 instruct storeL_2instr(memorylong mem, iRegL src) %{
4452   predicate(!((StoreLNode*)n)->require_atomic_access());
4453   match(Set mem (StoreL mem src));
4454   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
4455 
4456   size(8);
4457   format %{ "STR    $src.lo,$mem\t! long\n\t"
4458             "STR    $src.hi,$mem+4" %}
4459 
4460   ins_encode %{
4461     Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
4462     Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none);
4463     __ str($src$$Register, Amemlo);
4464     __ str($src$$Register->successor(), Amemhi);
4465   %}
4466   ins_pipe(istore_mem_reg);
4467 %}
4468 
4469 instruct storeL_volatile(indirect mem, iRegL src) %{
4470   predicate(((StoreLNode*)n)->require_atomic_access());
4471   match(Set mem (StoreL mem src));
4472   ins_cost(MEMORY_REF_COST);
4473   size(4);
4474   format %{ "STMIA    $src,$mem\t! long" %}
4475   ins_encode %{
4476     // FIXME: why is stmia considered atomic?  Should be strexd
4477     RegisterSet set($src$$Register);
4478     set = set | reg_to_register_object($src$$reg + 1);
4479     __ stmia(reg_to_register_object($mem$$base), set);
4480   %}
4481   ins_pipe(istore_mem_reg);
4482 %}
4483 
4484 instruct storeL_volatile_fp(memoryD mem, iRegL src) %{
4485   predicate(((StoreLNode*)n)->require_atomic_access());
4486   match(Set mem (StoreL mem src));
4487   ins_cost(MEMORY_REF_COST);
4488   size(8);
4489   format %{ "FMDRR    S14, $src\t! long \n\t"
4490             "FSTD     S14, $mem" %}
4491   ins_encode %{
4492     __ fmdrr(S14, $src$$Register, $src$$Register->successor());
4493     __ fstd(S14, $mem$$Address);
4494   %}
4495   ins_pipe(istore_mem_reg);
4496 %}
4497 
4498 #ifdef XXX
4499 // Move SP Pointer
4500 //instruct movSP(sp_ptr_RegP dst, SPRegP src) %{
4501 //instruct movSP(iRegP dst, SPRegP src) %{
4502 instruct movSP(store_ptr_RegP dst, SPRegP src) %{
4503   match(Set dst src);
4504 //predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con == TypeFunc::FramePtr);
4505   ins_cost(MEMORY_REF_COST);
4506   size(4);
4507 
4508   format %{ "MOV    $dst,$src\t! SP ptr\n\t" %}
4509   ins_encode %{
4510     assert(false, "XXX1 got here");
4511     __ mov($dst$$Register, SP);
4512     __ mov($dst$$Register, $src$$Register);
4513   %}
4514   ins_pipe(ialu_reg);
4515 %}
4516 #endif
4517 
4518 
4519 // Store Pointer
4520 
4521 
4522 instruct storeP(memoryP mem, store_ptr_RegP src) %{
4523   match(Set mem (StoreP mem src));
4524   ins_cost(MEMORY_REF_COST);
4525   size(4);
4526 
4527   format %{ "STR    $src,$mem\t! ptr" %}
4528   ins_encode %{
4529     __ str($src$$Register, $mem$$Address);
4530   %}
4531   ins_pipe(istore_mem_spORreg);
4532 %}
4533 
4534 
4535 #ifdef _LP64
4536 // Store Compressed Pointer
4537 
4538 
4539 instruct storeN(memoryI mem, store_RegN src) %{
4540   match(Set mem (StoreN mem src));
4541   ins_cost(MEMORY_REF_COST);
4542   size(4);
4543 
4544   format %{ "str_32 $src,$mem\t! compressed ptr" %}
4545   ins_encode %{
4546     __ str_32($src$$Register, $mem$$Address);
4547   %}
4548   ins_pipe(istore_mem_reg);
4549 %}
4550 
4551 
4552 // Store Compressed Klass Pointer
4553 instruct storeNKlass(memoryI mem, store_RegN src) %{
4554   match(Set mem (StoreNKlass mem src));
4555   ins_cost(MEMORY_REF_COST);
4556   size(4);
4557 
4558   format %{ "str_32 $src,$mem\t! compressed klass ptr" %}
4559   ins_encode %{
4560     __ str_32($src$$Register, $mem$$Address);
4561   %}
4562   ins_pipe(istore_mem_reg);
4563 %}
4564 #endif
4565 
4566 // Store Double
4567 
4568 
4569 instruct storeD(memoryD mem, regD src) %{
4570   match(Set mem (StoreD mem src));
4571   ins_cost(MEMORY_REF_COST);
4572 
4573   size(4);
4574   // FIXME: needs to be atomic, but  ARMv7 A.R.M. guarantees
4575   // only LDREXD and STREXD are 64-bit single-copy atomic
4576   format %{ "FSTD   $src,$mem" %}
4577   ins_encode %{
4578     __ str_double($src$$FloatRegister, $mem$$Address);
4579   %}
4580   ins_pipe(fstoreD_mem_reg);
4581 %}
4582 
4583 
4584 // Store Float
4585 
4586 
4587 instruct storeF( memoryF mem, regF src) %{
4588   match(Set mem (StoreF mem src));
4589   ins_cost(MEMORY_REF_COST);
4590 
4591   size(4);
4592   format %{ "FSTS    $src,$mem" %}
4593   ins_encode %{
4594     __ str_float($src$$FloatRegister, $mem$$Address);
4595   %}
4596   ins_pipe(fstoreF_mem_reg);
4597 %}
4598 
4599 
4600 //----------MemBar Instructions-----------------------------------------------
4601 // Memory barrier flavors
4602 
4603 // pattern-match out unnecessary membars
4604 instruct membar_storestore() %{
4605   match(MemBarStoreStore);
4606   ins_cost(4*MEMORY_REF_COST);
4607 
4608   size(4);
4609   format %{ "MEMBAR-storestore" %}
4610   ins_encode %{
4611     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore), noreg);
4612   %}
4613   ins_pipe(long_memory_op);
4614 %}
4615 
4616 instruct membar_acquire() %{
4617   match(MemBarAcquire);
4618   match(LoadFence);
4619   ins_cost(4*MEMORY_REF_COST);
4620 
4621   size(4);
4622   format %{ "MEMBAR-acquire" %}
4623   ins_encode %{
4624     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), noreg);
4625   %}
4626   ins_pipe(long_memory_op);
4627 %}
4628 
4629 instruct membar_acquire_lock() %{
4630   match(MemBarAcquireLock);
4631   ins_cost(0);
4632 
4633   size(0);
4634   format %{ "!MEMBAR-acquire (CAS in prior FastLock so empty encoding)" %}
4635   ins_encode( );
4636   ins_pipe(empty);
4637 %}
4638 
4639 instruct membar_release() %{
4640   match(MemBarRelease);
4641   match(StoreFence);
4642   ins_cost(4*MEMORY_REF_COST);
4643 
4644   size(4);
4645   format %{ "MEMBAR-release" %}
4646   ins_encode %{
4647     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), noreg);
4648   %}
4649   ins_pipe(long_memory_op);
4650 %}
4651 
4652 instruct membar_release_lock() %{
4653   match(MemBarReleaseLock);
4654   ins_cost(0);
4655 
4656   size(0);
4657   format %{ "!MEMBAR-release (CAS in succeeding FastUnlock so empty encoding)" %}
4658   ins_encode( );
4659   ins_pipe(empty);
4660 %}
4661 
4662 instruct membar_volatile() %{
4663   match(MemBarVolatile);
4664   ins_cost(4*MEMORY_REF_COST);
4665 
4666   size(4);
4667   format %{ "MEMBAR-volatile" %}
4668   ins_encode %{
4669     __ membar(MacroAssembler::StoreLoad, noreg);
4670   %}
4671   ins_pipe(long_memory_op);
4672 %}
4673 
4674 instruct unnecessary_membar_volatile() %{
4675   match(MemBarVolatile);
4676   predicate(Matcher::post_store_load_barrier(n));
4677   ins_cost(0);
4678 
4679   size(0);
4680   format %{ "!MEMBAR-volatile (unnecessary so empty encoding)" %}
4681   ins_encode( );
4682   ins_pipe(empty);
4683 %}
4684 
4685 //----------Register Move Instructions-----------------------------------------
4686 // instruct roundDouble_nop(regD dst) %{
4687 //   match(Set dst (RoundDouble dst));
4688 //   ins_pipe(empty);
4689 // %}
4690 
4691 
4692 // instruct roundFloat_nop(regF dst) %{
4693 //   match(Set dst (RoundFloat dst));
4694 //   ins_pipe(empty);
4695 // %}
4696 
4697 
4698 
4699 // Cast Index to Pointer for unsafe natives
4700 instruct castX2P(iRegX src, iRegP dst) %{
4701   match(Set dst (CastX2P src));
4702 
4703   format %{ "MOV    $dst,$src\t! IntX->Ptr if $dst != $src" %}
4704   ins_encode %{
4705     if ($dst$$Register !=  $src$$Register) {
4706       __ mov($dst$$Register, $src$$Register);
4707     }
4708   %}
4709   ins_pipe(ialu_reg);
4710 %}
4711 
4712 // Cast Pointer to Index for unsafe natives
4713 instruct castP2X(iRegP src, iRegX dst) %{
4714   match(Set dst (CastP2X src));
4715 
4716   format %{ "MOV    $dst,$src\t! Ptr->IntX if $dst != $src" %}
4717   ins_encode %{
4718     if ($dst$$Register !=  $src$$Register) {
4719       __ mov($dst$$Register, $src$$Register);
4720     }
4721   %}
4722   ins_pipe(ialu_reg);
4723 %}
4724 
4725 //----------Conditional Move---------------------------------------------------
4726 // Conditional move
4727 instruct cmovIP_reg(cmpOpP cmp, flagsRegP pcc, iRegI dst, iRegI src) %{
4728   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
4729   ins_cost(150);
4730   size(4);
4731   format %{ "MOV$cmp  $dst,$src\t! int" %}
4732   ins_encode %{
4733     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
4734   %}
4735   ins_pipe(ialu_reg);
4736 %}
4737 
4738 
4739 instruct cmovIP_immMov(cmpOpP cmp, flagsRegP pcc, iRegI dst, immIMov src) %{
4740   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
4741   ins_cost(140);
4742   size(4);
4743   format %{ "MOV$cmp  $dst,$src" %}
4744   ins_encode %{
4745     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4746   %}
4747   ins_pipe(ialu_imm);
4748 %}
4749 
4750 instruct cmovIP_imm16(cmpOpP cmp, flagsRegP pcc, iRegI dst, immI16 src) %{
4751   match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
4752   ins_cost(140);
4753   size(4);
4754   format %{ "MOVw$cmp  $dst,$src" %}
4755   ins_encode %{
4756     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4757   %}
4758   ins_pipe(ialu_imm);
4759 %}
4760 
4761 instruct cmovI_reg(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src) %{
4762   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
4763   ins_cost(150);
4764   size(4);
4765   format %{ "MOV$cmp  $dst,$src" %}
4766   ins_encode %{
4767     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
4768   %}
4769   ins_pipe(ialu_reg);
4770 %}
4771 
4772 
4773 instruct cmovI_immMov(cmpOp cmp, flagsReg icc, iRegI dst, immIMov src) %{
4774   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
4775   ins_cost(140);
4776   size(4);
4777   format %{ "MOV$cmp  $dst,$src" %}
4778   ins_encode %{
4779     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4780   %}
4781   ins_pipe(ialu_imm);
4782 %}
4783 
4784 instruct cmovII_imm16(cmpOp cmp, flagsReg icc, iRegI dst, immI16 src) %{
4785   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
4786   ins_cost(140);
4787   size(4);
4788   format %{ "MOVw$cmp  $dst,$src" %}
4789   ins_encode %{
4790     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4791   %}
4792   ins_pipe(ialu_imm);
4793 %}
4794 
4795 instruct cmovII_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, iRegI src) %{
4796   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
4797   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
4798             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
4799             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
4800             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
4801   ins_cost(150);
4802   size(4);
4803   format %{ "MOV$cmp  $dst,$src" %}
4804   ins_encode %{
4805     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
4806   %}
4807   ins_pipe(ialu_reg);
4808 %}
4809 
4810 instruct cmovII_immMov_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immIMov src) %{
4811   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
4812   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
4813             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
4814             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
4815             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
4816   ins_cost(140);
4817   size(4);
4818   format %{ "MOV$cmp  $dst,$src" %}
4819   ins_encode %{
4820     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4821   %}
4822   ins_pipe(ialu_imm);
4823 %}
4824 
4825 instruct cmovII_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immI16 src) %{
4826   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
4827   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
4828             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
4829             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
4830             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
4831   ins_cost(140);
4832   size(4);
4833   format %{ "MOVW$cmp  $dst,$src" %}
4834   ins_encode %{
4835     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4836   %}
4837   ins_pipe(ialu_imm);
4838 %}
4839 
4840 instruct cmovIIu_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
4841   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
4842   ins_cost(150);
4843   size(4);
4844   format %{ "MOV$cmp  $dst,$src" %}
4845   ins_encode %{
4846     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
4847   %}
4848   ins_pipe(ialu_reg);
4849 %}
4850 
4851 instruct cmovIIu_immMov(cmpOpU cmp, flagsRegU icc, iRegI dst, immIMov src) %{
4852   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
4853   ins_cost(140);
4854   size(4);
4855   format %{ "MOV$cmp  $dst,$src" %}
4856   ins_encode %{
4857     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4858   %}
4859   ins_pipe(ialu_imm);
4860 %}
4861 
4862 instruct cmovIIu_imm16(cmpOpU cmp, flagsRegU icc, iRegI dst, immI16 src) %{
4863   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
4864   ins_cost(140);
4865   size(4);
4866   format %{ "MOVW$cmp  $dst,$src" %}
4867   ins_encode %{
4868     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4869   %}
4870   ins_pipe(ialu_imm);
4871 %}
4872 
4873 // Conditional move
4874 instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{
4875   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
4876   ins_cost(150);
4877   size(4);
4878   format %{ "MOV$cmp  $dst,$src" %}
4879   ins_encode %{
4880     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
4881   %}
4882   ins_pipe(ialu_reg);
4883 %}
4884 
4885 instruct cmovPP_imm(cmpOpP cmp, flagsRegP pcc, iRegP dst, immP0 src) %{
4886   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
4887   ins_cost(140);
4888   size(4);
4889   format %{ "MOV$cmp  $dst,$src" %}
4890   ins_encode %{
4891     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4892   %}
4893   ins_pipe(ialu_imm);
4894 %}
4895 
4896 // This instruction also works with CmpN so we don't need cmovPN_reg.
4897 instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{
4898   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
4899   ins_cost(150);
4900 
4901   size(4);
4902   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
4903   ins_encode %{
4904     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
4905   %}
4906   ins_pipe(ialu_reg);
4907 %}
4908 
4909 instruct cmovPI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, iRegP src) %{
4910   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
4911   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
4912             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
4913             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
4914             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
4915   ins_cost(150);
4916 
4917   size(4);
4918   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
4919   ins_encode %{
4920     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
4921   %}
4922   ins_pipe(ialu_reg);
4923 %}
4924 
4925 instruct cmovPIu_reg(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src) %{
4926   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
4927   ins_cost(150);
4928 
4929   size(4);
4930   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
4931   ins_encode %{
4932     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
4933   %}
4934   ins_pipe(ialu_reg);
4935 %}
4936 
4937 instruct cmovPI_imm(cmpOp cmp, flagsReg icc, iRegP dst, immP0 src) %{
4938   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
4939   ins_cost(140);
4940 
4941   size(4);
4942   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
4943   ins_encode %{
4944     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4945   %}
4946   ins_pipe(ialu_imm);
4947 %}
4948 
4949 instruct cmovPI_imm_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, immP0 src) %{
4950   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
4951   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
4952             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
4953             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
4954             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
4955   ins_cost(140);
4956 
4957   size(4);
4958   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
4959   ins_encode %{
4960     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4961   %}
4962   ins_pipe(ialu_imm);
4963 %}
4964 
4965 instruct cmovPIu_imm(cmpOpU cmp, flagsRegU icc, iRegP dst, immP0 src) %{
4966   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
4967   ins_cost(140);
4968 
4969   size(4);
4970   format %{ "MOV$cmp  $dst,$src\t! ptr" %}
4971   ins_encode %{
4972     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
4973   %}
4974   ins_pipe(ialu_imm);
4975 %}
4976 
4977 
4978 // Conditional move
4979 instruct cmovFP_reg(cmpOpP cmp, flagsRegP pcc, regF dst, regF src) %{
4980   match(Set dst (CMoveF (Binary cmp pcc) (Binary dst src)));
4981   ins_cost(150);
4982   size(4);
4983   format %{ "FCPYS$cmp $dst,$src" %}
4984   ins_encode %{
4985     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
4986   %}
4987   ins_pipe(int_conditional_float_move);
4988 %}
4989 
4990 instruct cmovFI_reg(cmpOp cmp, flagsReg icc, regF dst, regF src) %{
4991   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
4992   ins_cost(150);
4993 
4994   size(4);
4995   format %{ "FCPYS$cmp $dst,$src" %}
4996   ins_encode %{
4997     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
4998   %}
4999   ins_pipe(int_conditional_float_move);
5000 %}
5001 
5002 instruct cmovFI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regF dst, regF src) %{
5003   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
5004   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
5005             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
5006             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
5007             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
5008   ins_cost(150);
5009 
5010   size(4);
5011   format %{ "FCPYS$cmp $dst,$src" %}
5012   ins_encode %{
5013     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
5014   %}
5015   ins_pipe(int_conditional_float_move);
5016 %}
5017 
5018 instruct cmovFIu_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src) %{
5019   match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
5020   ins_cost(150);
5021 
5022   size(4);
5023   format %{ "FCPYS$cmp $dst,$src" %}
5024   ins_encode %{
5025     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
5026   %}
5027   ins_pipe(int_conditional_float_move);
5028 %}
5029 
5030 // Conditional move
5031 instruct cmovDP_reg(cmpOpP cmp, flagsRegP pcc, regD dst, regD src) %{
5032   match(Set dst (CMoveD (Binary cmp pcc) (Binary dst src)));
5033   ins_cost(150);
5034   size(4);
5035   format %{ "FCPYD$cmp $dst,$src" %}
5036   ins_encode %{
5037     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
5038   %}
5039   ins_pipe(int_conditional_double_move);
5040 %}
5041 
5042 instruct cmovDI_reg(cmpOp cmp, flagsReg icc, regD dst, regD src) %{
5043   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
5044   ins_cost(150);
5045 
5046   size(4);
5047   format %{ "FCPYD$cmp $dst,$src" %}
5048   ins_encode %{
5049     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
5050   %}
5051   ins_pipe(int_conditional_double_move);
5052 %}
5053 
5054 instruct cmovDI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, regD dst, regD src) %{
5055   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
5056   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);
5057   ins_cost(150);
5058 
5059   size(4);
5060   format %{ "FCPYD$cmp $dst,$src" %}
5061   ins_encode %{
5062     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
5063   %}
5064   ins_pipe(int_conditional_double_move);
5065 %}
5066 
5067 instruct cmovDIu_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src) %{
5068   match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
5069   ins_cost(150);
5070 
5071   size(4);
5072   format %{ "FCPYD$cmp $dst,$src" %}
5073   ins_encode %{
5074     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
5075   %}
5076   ins_pipe(int_conditional_double_move);
5077 %}
5078 
5079 // Conditional move
5080 instruct cmovLP_reg(cmpOpP cmp, flagsRegP pcc, iRegL dst, iRegL src) %{
5081   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
5082   ins_cost(150);
5083 
5084   size(8);
5085   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
5086             "MOV$cmp  $dst.hi,$src.hi" %}
5087   ins_encode %{
5088     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
5089     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
5090   %}
5091   ins_pipe(ialu_reg);
5092 %}
5093 
5094 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
5095 // (hi($con$$constant), lo($con$$constant)) becomes
5096 instruct cmovLP_immRot(cmpOpP cmp, flagsRegP pcc, iRegL dst, immLlowRot src) %{
5097   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
5098   ins_cost(140);
5099 
5100   size(8);
5101   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
5102             "MOV$cmp  $dst.hi,0" %}
5103   ins_encode %{
5104     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
5105     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
5106   %}
5107   ins_pipe(ialu_imm);
5108 %}
5109 
5110 instruct cmovLP_imm16(cmpOpP cmp, flagsRegP pcc, iRegL dst, immL16 src) %{
5111   match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src)));
5112   ins_cost(140);
5113 
5114   size(8);
5115   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
5116             "MOV$cmp  $dst.hi,0" %}
5117   ins_encode %{
5118     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
5119     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
5120   %}
5121   ins_pipe(ialu_imm);
5122 %}
5123 
5124 instruct cmovLI_reg(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src) %{
5125   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5126   ins_cost(150);
5127 
5128   size(8);
5129   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
5130             "MOV$cmp  $dst.hi,$src.hi" %}
5131   ins_encode %{
5132     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
5133     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
5134   %}
5135   ins_pipe(ialu_reg);
5136 %}
5137 
5138 instruct cmovLI_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, iRegL src) %{
5139   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5140   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
5141             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
5142             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
5143             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
5144   ins_cost(150);
5145 
5146   size(8);
5147   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
5148             "MOV$cmp  $dst.hi,$src.hi" %}
5149   ins_encode %{
5150     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
5151     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
5152   %}
5153   ins_pipe(ialu_reg);
5154 %}
5155 
5156 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
5157 // (hi($con$$constant), lo($con$$constant)) becomes
5158 instruct cmovLI_immRot(cmpOp cmp, flagsReg icc, iRegL dst, immLlowRot src) %{
5159   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5160   ins_cost(140);
5161 
5162   size(8);
5163   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
5164             "MOV$cmp  $dst.hi,0" %}
5165   ins_encode %{
5166     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
5167     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
5168   %}
5169   ins_pipe(ialu_imm);
5170 %}
5171 
5172 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
5173 // (hi($con$$constant), lo($con$$constant)) becomes
5174 instruct cmovLI_immRot_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immLlowRot 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(140);
5181 
5182   size(8);
5183   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
5184             "MOV$cmp  $dst.hi,0" %}
5185   ins_encode %{
5186     __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
5187     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
5188   %}
5189   ins_pipe(ialu_imm);
5190 %}
5191 
5192 instruct cmovLI_imm16(cmpOp cmp, flagsReg icc, iRegL dst, immL16 src) %{
5193   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5194   ins_cost(140);
5195 
5196   size(8);
5197   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
5198             "MOV$cmp  $dst.hi,0" %}
5199   ins_encode %{
5200     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
5201     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
5202   %}
5203   ins_pipe(ialu_imm);
5204 %}
5205 
5206 instruct cmovLI_imm16_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, immL16 src) %{
5207   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5208   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
5209             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
5210             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
5211             _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
5212   ins_cost(140);
5213 
5214   size(8);
5215   format %{ "MOV$cmp  $dst.lo,$src\t! long\n\t"
5216             "MOV$cmp  $dst.hi,0" %}
5217   ins_encode %{
5218     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
5219     __ movw($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
5220   %}
5221   ins_pipe(ialu_imm);
5222 %}
5223 
5224 instruct cmovLIu_reg(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src) %{
5225   match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
5226   ins_cost(150);
5227 
5228   size(8);
5229   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
5230             "MOV$cmp  $dst.hi,$src.hi" %}
5231   ins_encode %{
5232     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
5233     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
5234   %}
5235   ins_pipe(ialu_reg);
5236 %}
5237 
5238 
5239 //----------OS and Locking Instructions----------------------------------------
5240 
5241 // This name is KNOWN by the ADLC and cannot be changed.
5242 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
5243 // for this guy.
5244 instruct tlsLoadP(RthreadRegP dst) %{
5245   match(Set dst (ThreadLocal));
5246 
5247   size(0);
5248   ins_cost(0);
5249   format %{ "! TLS is in $dst" %}
5250   ins_encode( /*empty encoding*/ );
5251   ins_pipe(ialu_none);
5252 %}
5253 
5254 instruct checkCastPP( iRegP dst ) %{
5255   match(Set dst (CheckCastPP dst));
5256 
5257   size(0);
5258   format %{ "! checkcastPP of $dst" %}
5259   ins_encode( /*empty encoding*/ );
5260   ins_pipe(empty);
5261 %}
5262 
5263 
5264 instruct castPP( iRegP dst ) %{
5265   match(Set dst (CastPP dst));
5266   format %{ "! castPP of $dst" %}
5267   ins_encode( /*empty encoding*/ );
5268   ins_pipe(empty);
5269 %}
5270 
5271 instruct castII( iRegI dst ) %{
5272   match(Set dst (CastII dst));
5273   format %{ "! castII of $dst" %}
5274   ins_encode( /*empty encoding*/ );
5275   ins_cost(0);
5276   ins_pipe(empty);
5277 %}
5278 
5279 //----------Arithmetic Instructions--------------------------------------------
5280 // Addition Instructions
5281 // Register Addition
5282 instruct addI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
5283   match(Set dst (AddI src1 src2));
5284 
5285   size(4);
5286   format %{ "add_32 $dst,$src1,$src2\t! int" %}
5287   ins_encode %{
5288     __ add_32($dst$$Register, $src1$$Register, $src2$$Register);
5289   %}
5290   ins_pipe(ialu_reg_reg);
5291 %}
5292 
5293 instruct addshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5294   match(Set dst (AddI (LShiftI src1 src2) src3));
5295 
5296   size(4);
5297   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
5298   ins_encode %{
5299     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
5300   %}
5301   ins_pipe(ialu_reg_reg);
5302 %}
5303 
5304 
5305 instruct addshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
5306   match(Set dst (AddI (LShiftI src1 src2) src3));
5307 
5308   size(4);
5309   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
5310   ins_encode %{
5311     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
5312   %}
5313   ins_pipe(ialu_reg_reg);
5314 %}
5315 
5316 instruct addsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5317   match(Set dst (AddI (RShiftI src1 src2) src3));
5318 
5319   size(4);
5320   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
5321   ins_encode %{
5322     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
5323   %}
5324   ins_pipe(ialu_reg_reg);
5325 %}
5326 
5327 instruct addsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
5328   match(Set dst (AddI (RShiftI src1 src2) src3));
5329 
5330   size(4);
5331   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
5332   ins_encode %{
5333     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
5334   %}
5335   ins_pipe(ialu_reg_reg);
5336 %}
5337 
5338 instruct addshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5339   match(Set dst (AddI (URShiftI src1 src2) src3));
5340 
5341   size(4);
5342   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
5343   ins_encode %{
5344     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
5345   %}
5346   ins_pipe(ialu_reg_reg);
5347 %}
5348 
5349 instruct addshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
5350   match(Set dst (AddI (URShiftI src1 src2) src3));
5351 
5352   size(4);
5353   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
5354   ins_encode %{
5355     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
5356   %}
5357   ins_pipe(ialu_reg_reg);
5358 %}
5359 
5360 // Immediate Addition
5361 instruct addI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
5362   match(Set dst (AddI src1 src2));
5363 
5364   size(4);
5365   format %{ "add_32 $dst,$src1,$src2\t! int" %}
5366   ins_encode %{
5367     __ add_32($dst$$Register, $src1$$Register, $src2$$constant);
5368   %}
5369   ins_pipe(ialu_reg_imm);
5370 %}
5371 
5372 // Pointer Register Addition
5373 instruct addP_reg_reg(iRegP dst, iRegP src1, iRegX src2) %{
5374   match(Set dst (AddP src1 src2));
5375 
5376   size(4);
5377   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
5378   ins_encode %{
5379     __ add($dst$$Register, $src1$$Register, $src2$$Register);
5380   %}
5381   ins_pipe(ialu_reg_reg);
5382 %}
5383 
5384 
5385 // shifted iRegX operand
5386 operand shiftedX(iRegX src2, shimmX src3) %{
5387 //constraint(ALLOC_IN_RC(sp_ptr_reg));
5388   match(LShiftX src2 src3);
5389 
5390   op_cost(1);
5391   format %{ "$src2 << $src3" %}
5392   interface(MEMORY_INTER) %{
5393     base($src2);
5394     index(0xff);
5395     scale($src3);
5396     disp(0x0);
5397   %}
5398 %}
5399 
5400 instruct addshlP_reg_reg_imm(iRegP dst, iRegP src1, shiftedX src2) %{
5401   match(Set dst (AddP src1 src2));
5402 
5403   ins_cost(DEFAULT_COST * 3/2);
5404   size(4);
5405   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
5406   ins_encode %{
5407     Register base = reg_to_register_object($src2$$base);
5408     __ add($dst$$Register, $src1$$Register, AsmOperand(base, lsl, $src2$$scale));
5409   %}
5410   ins_pipe(ialu_reg_reg);
5411 %}
5412 
5413 // Pointer Immediate Addition
5414 instruct addP_reg_aimmX(iRegP dst, iRegP src1, aimmX src2) %{
5415   match(Set dst (AddP src1 src2));
5416 
5417   size(4);
5418   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
5419   ins_encode %{
5420     __ add($dst$$Register, $src1$$Register, $src2$$constant);
5421   %}
5422   ins_pipe(ialu_reg_imm);
5423 %}
5424 
5425 // Long Addition
5426 instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg ccr) %{
5427   match(Set dst (AddL src1 src2));
5428   effect(KILL ccr);
5429   size(8);
5430   format %{ "ADDS    $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
5431             "ADC     $dst.hi,$src1.hi,$src2.hi" %}
5432   ins_encode %{
5433     __ adds($dst$$Register, $src1$$Register, $src2$$Register);
5434     __ adc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
5435   %}
5436   ins_pipe(ialu_reg_reg);
5437 %}
5438 
5439 // TODO
5440 
5441 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
5442 // (hi($con$$constant), lo($con$$constant)) becomes
5443 instruct addL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg ccr) %{
5444   match(Set dst (AddL src1 con));
5445   effect(KILL ccr);
5446   size(8);
5447   format %{ "ADDS    $dst.lo,$src1.lo,$con\t! long\n\t"
5448             "ADC     $dst.hi,$src1.hi,0" %}
5449   ins_encode %{
5450     __ adds($dst$$Register, $src1$$Register, $con$$constant);
5451     __ adc($dst$$Register->successor(), $src1$$Register->successor(), 0);
5452   %}
5453   ins_pipe(ialu_reg_imm);
5454 %}
5455 
5456 //----------Conditional_store--------------------------------------------------
5457 // Conditional-store of the updated heap-top.
5458 // Used during allocation of the shared heap.
5459 // Sets flags (EQ) on success.
5460 
5461 // LoadP-locked.
5462 instruct loadPLocked(iRegP dst, memoryex mem) %{
5463   match(Set dst (LoadPLocked mem));
5464   size(4);
5465   format %{ "LDREX  $dst,$mem" %}
5466   ins_encode %{
5467     __ ldrex($dst$$Register,$mem$$Address);
5468   %}
5469   ins_pipe(iload_mem);
5470 %}
5471 
5472 instruct storePConditional( memoryex heap_top_ptr, iRegP oldval, iRegP newval, iRegI tmp, flagsRegP pcc ) %{
5473   predicate(_kids[1]->_kids[0]->_leaf->Opcode() == Op_LoadPLocked); // only works in conjunction with a LoadPLocked node
5474   match(Set pcc (StorePConditional heap_top_ptr (Binary oldval newval)));
5475   effect( TEMP tmp );
5476   size(8);
5477   format %{ "STREX  $tmp,$newval,$heap_top_ptr\n\t"
5478             "CMP    $tmp, 0" %}
5479   ins_encode %{
5480     __ strex($tmp$$Register, $newval$$Register, $heap_top_ptr$$Address);
5481     __ cmp($tmp$$Register, 0);
5482   %}
5483   ins_pipe( long_memory_op );
5484 %}
5485 
5486 // Conditional-store of an intx value.
5487 instruct storeXConditional( memoryex mem, iRegX oldval, iRegX newval, iRegX tmp, flagsReg icc ) %{
5488   match(Set icc (StoreIConditional mem (Binary oldval newval)));
5489   effect( TEMP tmp );
5490   size(28);
5491   format %{ "loop: \n\t"
5492             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem], DOESN'T set $newval=[$mem] in any case\n\t"
5493             "XORS     $tmp,$tmp, $oldval\n\t"
5494             "STREX.eq $tmp, $newval, $mem\n\t"
5495             "CMP.eq   $tmp, 1 \n\t"
5496             "B.eq     loop \n\t"
5497             "TEQ      $tmp, 0\n\t"
5498             "membar   LoadStore|LoadLoad" %}
5499   ins_encode %{
5500     Label loop;
5501     __ bind(loop);
5502     __ ldrex($tmp$$Register, $mem$$Address);
5503     __ eors($tmp$$Register, $tmp$$Register, $oldval$$Register);
5504     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
5505     __ cmp($tmp$$Register, 1, eq);
5506     __ b(loop, eq);
5507     __ teq($tmp$$Register, 0);
5508     // used by biased locking only. Requires a membar.
5509     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadStore | MacroAssembler::LoadLoad), noreg);
5510   %}
5511   ins_pipe( long_memory_op );
5512 %}
5513 
5514 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
5515 
5516 instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegLd newval, iRegI res, iRegLd tmp, flagsReg ccr ) %{
5517   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
5518   effect( KILL ccr, TEMP tmp);
5519   size(32);
5520   format %{ "loop: \n\t"
5521             "LDREXD   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
5522             "CMP      $tmp.lo, $oldval.lo\n\t"
5523             "CMP.eq   $tmp.hi, $oldval.hi\n\t"
5524             "STREXD.eq $tmp, $newval, $mem\n\t"
5525             "MOV.ne   $tmp, 0 \n\t"
5526             "XORS.eq  $tmp,$tmp, 1 \n\t"
5527             "B.eq     loop \n\t"
5528             "MOV      $res, $tmp" %}
5529   ins_encode %{
5530     Label loop;
5531     __ bind(loop);
5532     __ ldrexd($tmp$$Register, $mem$$Address);
5533     __ cmp($tmp$$Register, $oldval$$Register);
5534     __ cmp($tmp$$Register->successor(), $oldval$$Register->successor(), eq);
5535     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address, eq);
5536     __ mov($tmp$$Register, 0, ne);
5537     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
5538     __ b(loop, eq);
5539     __ mov($res$$Register, $tmp$$Register);
5540   %}
5541   ins_pipe( long_memory_op );
5542 %}
5543 
5544 
5545 instruct compareAndSwapI_bool(memoryex mem, iRegI oldval, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
5546   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
5547   effect( KILL ccr, TEMP tmp);
5548   size(28);
5549   format %{ "loop: \n\t"
5550             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
5551             "CMP      $tmp, $oldval\n\t"
5552             "STREX.eq $tmp, $newval, $mem\n\t"
5553             "MOV.ne   $tmp, 0 \n\t"
5554             "XORS.eq  $tmp,$tmp, 1 \n\t"
5555             "B.eq     loop \n\t"
5556             "MOV      $res, $tmp" %}
5557 
5558   ins_encode %{
5559     Label loop;
5560     __ bind(loop);
5561     __ ldrex($tmp$$Register,$mem$$Address);
5562     __ cmp($tmp$$Register, $oldval$$Register);
5563     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
5564     __ mov($tmp$$Register, 0, ne);
5565     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
5566     __ b(loop, eq);
5567     __ mov($res$$Register, $tmp$$Register);
5568   %}
5569   ins_pipe( long_memory_op );
5570 %}
5571 
5572 instruct compareAndSwapP_bool(memoryex mem, iRegP oldval, iRegP newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
5573   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
5574   effect( KILL ccr, TEMP tmp);
5575   size(28);
5576   format %{ "loop: \n\t"
5577             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
5578             "CMP      $tmp, $oldval\n\t"
5579             "STREX.eq $tmp, $newval, $mem\n\t"
5580             "MOV.ne   $tmp, 0 \n\t"
5581             "EORS.eq  $tmp,$tmp, 1 \n\t"
5582             "B.eq     loop \n\t"
5583             "MOV      $res, $tmp" %}
5584 
5585   ins_encode %{
5586     Label loop;
5587     __ bind(loop);
5588     __ ldrex($tmp$$Register,$mem$$Address);
5589     __ cmp($tmp$$Register, $oldval$$Register);
5590     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
5591     __ mov($tmp$$Register, 0, ne);
5592     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
5593     __ b(loop, eq);
5594     __ mov($res$$Register, $tmp$$Register);
5595   %}
5596   ins_pipe( long_memory_op );
5597 %}
5598 
5599 instruct xaddI_aimmI_no_res(memoryex mem, aimmI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
5600   predicate(n->as_LoadStore()->result_not_used());
5601   match(Set dummy (GetAndAddI mem add));
5602   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
5603   size(20);
5604   format %{ "loop: \n\t"
5605             "LDREX    $tmp1, $mem\n\t"
5606             "ADD      $tmp1, $tmp1, $add\n\t"
5607             "STREX    $tmp2, $tmp1, $mem\n\t"
5608             "CMP      $tmp2, 0 \n\t"
5609             "B.ne     loop \n\t" %}
5610 
5611   ins_encode %{
5612     Label loop;
5613     __ bind(loop);
5614     __ ldrex($tmp1$$Register,$mem$$Address);
5615     __ add($tmp1$$Register, $tmp1$$Register, $add$$constant);
5616     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5617     __ cmp($tmp2$$Register, 0);
5618     __ b(loop, ne);
5619   %}
5620   ins_pipe( long_memory_op );
5621 %}
5622 
5623 instruct xaddI_reg_no_res(memoryex mem, iRegI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
5624   predicate(n->as_LoadStore()->result_not_used());
5625   match(Set dummy (GetAndAddI mem add));
5626   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
5627   size(20);
5628   format %{ "loop: \n\t"
5629             "LDREX    $tmp1, $mem\n\t"
5630             "ADD      $tmp1, $tmp1, $add\n\t"
5631             "STREX    $tmp2, $tmp1, $mem\n\t"
5632             "CMP      $tmp2, 0 \n\t"
5633             "B.ne     loop \n\t" %}
5634 
5635   ins_encode %{
5636     Label loop;
5637     __ bind(loop);
5638     __ ldrex($tmp1$$Register,$mem$$Address);
5639     __ add($tmp1$$Register, $tmp1$$Register, $add$$Register);
5640     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5641     __ cmp($tmp2$$Register, 0);
5642     __ b(loop, ne);
5643   %}
5644   ins_pipe( long_memory_op );
5645 %}
5646 
5647 instruct xaddI_aimmI(memoryex mem, aimmI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
5648   match(Set res (GetAndAddI mem add));
5649   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
5650   size(20);
5651   format %{ "loop: \n\t"
5652             "LDREX    $res, $mem\n\t"
5653             "ADD      $tmp1, $res, $add\n\t"
5654             "STREX    $tmp2, $tmp1, $mem\n\t"
5655             "CMP      $tmp2, 0 \n\t"
5656             "B.ne     loop \n\t" %}
5657 
5658   ins_encode %{
5659     Label loop;
5660     __ bind(loop);
5661     __ ldrex($res$$Register,$mem$$Address);
5662     __ add($tmp1$$Register, $res$$Register, $add$$constant);
5663     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5664     __ cmp($tmp2$$Register, 0);
5665     __ b(loop, ne);
5666   %}
5667   ins_pipe( long_memory_op );
5668 %}
5669 
5670 instruct xaddI_reg(memoryex mem, iRegI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
5671   match(Set res (GetAndAddI mem add));
5672   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
5673   size(20);
5674   format %{ "loop: \n\t"
5675             "LDREX    $res, $mem\n\t"
5676             "ADD      $tmp1, $res, $add\n\t"
5677             "STREX    $tmp2, $tmp1, $mem\n\t"
5678             "CMP      $tmp2, 0 \n\t"
5679             "B.ne     loop \n\t" %}
5680 
5681   ins_encode %{
5682     Label loop;
5683     __ bind(loop);
5684     __ ldrex($res$$Register,$mem$$Address);
5685     __ add($tmp1$$Register, $res$$Register, $add$$Register);
5686     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5687     __ cmp($tmp2$$Register, 0);
5688     __ b(loop, ne);
5689   %}
5690   ins_pipe( long_memory_op );
5691 %}
5692 
5693 instruct xaddL_reg_no_res(memoryex mem, iRegL add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
5694   predicate(n->as_LoadStore()->result_not_used());
5695   match(Set dummy (GetAndAddL mem add));
5696   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
5697   size(24);
5698   format %{ "loop: \n\t"
5699             "LDREXD   $tmp1, $mem\n\t"
5700             "ADDS     $tmp1.lo, $tmp1.lo, $add.lo\n\t"
5701             "ADC      $tmp1.hi, $tmp1.hi, $add.hi\n\t"
5702             "STREXD   $tmp2, $tmp1, $mem\n\t"
5703             "CMP      $tmp2, 0 \n\t"
5704             "B.ne     loop \n\t" %}
5705 
5706   ins_encode %{
5707     Label loop;
5708     __ bind(loop);
5709     __ ldrexd($tmp1$$Register, $mem$$Address);
5710     __ adds($tmp1$$Register, $tmp1$$Register, $add$$Register);
5711     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), $add$$Register->successor());
5712     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5713     __ cmp($tmp2$$Register, 0);
5714     __ b(loop, ne);
5715   %}
5716   ins_pipe( long_memory_op );
5717 %}
5718 
5719 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
5720 // (hi($con$$constant), lo($con$$constant)) becomes
5721 instruct xaddL_immRot_no_res(memoryex mem, immLlowRot add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
5722   predicate(n->as_LoadStore()->result_not_used());
5723   match(Set dummy (GetAndAddL mem add));
5724   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
5725   size(24);
5726   format %{ "loop: \n\t"
5727             "LDREXD   $tmp1, $mem\n\t"
5728             "ADDS     $tmp1.lo, $tmp1.lo, $add\n\t"
5729             "ADC      $tmp1.hi, $tmp1.hi, 0\n\t"
5730             "STREXD   $tmp2, $tmp1, $mem\n\t"
5731             "CMP      $tmp2, 0 \n\t"
5732             "B.ne     loop \n\t" %}
5733 
5734   ins_encode %{
5735     Label loop;
5736     __ bind(loop);
5737     __ ldrexd($tmp1$$Register, $mem$$Address);
5738     __ adds($tmp1$$Register, $tmp1$$Register, $add$$constant);
5739     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), 0);
5740     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5741     __ cmp($tmp2$$Register, 0);
5742     __ b(loop, ne);
5743   %}
5744   ins_pipe( long_memory_op );
5745 %}
5746 
5747 instruct xaddL_reg(memoryex mem, iRegL add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
5748   match(Set res (GetAndAddL mem add));
5749   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
5750   size(24);
5751   format %{ "loop: \n\t"
5752             "LDREXD   $res, $mem\n\t"
5753             "ADDS     $tmp1.lo, $res.lo, $add.lo\n\t"
5754             "ADC      $tmp1.hi, $res.hi, $add.hi\n\t"
5755             "STREXD   $tmp2, $tmp1, $mem\n\t"
5756             "CMP      $tmp2, 0 \n\t"
5757             "B.ne     loop \n\t" %}
5758 
5759   ins_encode %{
5760     Label loop;
5761     __ bind(loop);
5762     __ ldrexd($res$$Register, $mem$$Address);
5763     __ adds($tmp1$$Register, $res$$Register, $add$$Register);
5764     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), $add$$Register->successor());
5765     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5766     __ cmp($tmp2$$Register, 0);
5767     __ b(loop, ne);
5768   %}
5769   ins_pipe( long_memory_op );
5770 %}
5771 
5772 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
5773 // (hi($con$$constant), lo($con$$constant)) becomes
5774 instruct xaddL_immRot(memoryex mem, immLlowRot add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
5775   match(Set res (GetAndAddL mem add));
5776   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
5777   size(24);
5778   format %{ "loop: \n\t"
5779             "LDREXD   $res, $mem\n\t"
5780             "ADDS     $tmp1.lo, $res.lo, $add\n\t"
5781             "ADC      $tmp1.hi, $res.hi, 0\n\t"
5782             "STREXD   $tmp2, $tmp1, $mem\n\t"
5783             "CMP      $tmp2, 0 \n\t"
5784             "B.ne     loop \n\t" %}
5785 
5786   ins_encode %{
5787     Label loop;
5788     __ bind(loop);
5789     __ ldrexd($res$$Register, $mem$$Address);
5790     __ adds($tmp1$$Register, $res$$Register, $add$$constant);
5791     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), 0);
5792     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5793     __ cmp($tmp2$$Register, 0);
5794     __ b(loop, ne);
5795   %}
5796   ins_pipe( long_memory_op );
5797 %}
5798 
5799 instruct xchgI(memoryex mem, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr) %{
5800   match(Set res (GetAndSetI mem newval));
5801   effect(KILL ccr, TEMP tmp, TEMP res);
5802   size(16);
5803   format %{ "loop: \n\t"
5804             "LDREX    $res, $mem\n\t"
5805             "STREX    $tmp, $newval, $mem\n\t"
5806             "CMP      $tmp, 0 \n\t"
5807             "B.ne     loop \n\t" %}
5808 
5809   ins_encode %{
5810     Label loop;
5811     __ bind(loop);
5812     __ ldrex($res$$Register,$mem$$Address);
5813     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
5814     __ cmp($tmp$$Register, 0);
5815     __ b(loop, ne);
5816   %}
5817   ins_pipe( long_memory_op );
5818 %}
5819 
5820 instruct xchgL(memoryex mem, iRegLd newval, iRegLd res, iRegI tmp, flagsReg ccr) %{
5821   match(Set res (GetAndSetL mem newval));
5822   effect( KILL ccr, TEMP tmp, TEMP res);
5823   size(16);
5824   format %{ "loop: \n\t"
5825             "LDREXD   $res, $mem\n\t"
5826             "STREXD   $tmp, $newval, $mem\n\t"
5827             "CMP      $tmp, 0 \n\t"
5828             "B.ne     loop \n\t" %}
5829 
5830   ins_encode %{
5831     Label loop;
5832     __ bind(loop);
5833     __ ldrexd($res$$Register, $mem$$Address);
5834     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address);
5835     __ cmp($tmp$$Register, 0);
5836     __ b(loop, ne);
5837   %}
5838   ins_pipe( long_memory_op );
5839 %}
5840 
5841 instruct xchgP(memoryex mem, iRegP newval, iRegP res, iRegI tmp, flagsReg ccr) %{
5842   match(Set res (GetAndSetP mem newval));
5843   effect(KILL ccr, TEMP tmp, TEMP res);
5844   size(16);
5845   format %{ "loop: \n\t"
5846             "LDREX    $res, $mem\n\t"
5847             "STREX    $tmp, $newval, $mem\n\t"
5848             "CMP      $tmp, 0 \n\t"
5849             "B.ne     loop \n\t" %}
5850 
5851   ins_encode %{
5852     Label loop;
5853     __ bind(loop);
5854     __ ldrex($res$$Register,$mem$$Address);
5855     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
5856     __ cmp($tmp$$Register, 0);
5857     __ b(loop, ne);
5858   %}
5859   ins_pipe( long_memory_op );
5860 %}
5861 
5862 //---------------------
5863 // Subtraction Instructions
5864 // Register Subtraction
5865 instruct subI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
5866   match(Set dst (SubI src1 src2));
5867 
5868   size(4);
5869   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
5870   ins_encode %{
5871     __ sub_32($dst$$Register, $src1$$Register, $src2$$Register);
5872   %}
5873   ins_pipe(ialu_reg_reg);
5874 %}
5875 
5876 instruct subshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5877   match(Set dst (SubI src1 (LShiftI src2 src3)));
5878 
5879   size(4);
5880   format %{ "SUB    $dst,$src1,$src2<<$src3" %}
5881   ins_encode %{
5882     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
5883   %}
5884   ins_pipe(ialu_reg_reg);
5885 %}
5886 
5887 instruct subshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
5888   match(Set dst (SubI src1 (LShiftI src2 src3)));
5889 
5890   size(4);
5891   format %{ "sub_32 $dst,$src1,$src2<<$src3\t! int" %}
5892   ins_encode %{
5893     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
5894   %}
5895   ins_pipe(ialu_reg_reg);
5896 %}
5897 
5898 instruct subsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5899   match(Set dst (SubI src1 (RShiftI src2 src3)));
5900 
5901   size(4);
5902   format %{ "SUB    $dst,$src1,$src2>>$src3" %}
5903   ins_encode %{
5904     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
5905   %}
5906   ins_pipe(ialu_reg_reg);
5907 %}
5908 
5909 instruct subsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
5910   match(Set dst (SubI src1 (RShiftI src2 src3)));
5911 
5912   size(4);
5913   format %{ "sub_32 $dst,$src1,$src2>>$src3\t! int" %}
5914   ins_encode %{
5915     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
5916   %}
5917   ins_pipe(ialu_reg_reg);
5918 %}
5919 
5920 instruct subshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5921   match(Set dst (SubI src1 (URShiftI src2 src3)));
5922 
5923   size(4);
5924   format %{ "SUB    $dst,$src1,$src2>>>$src3" %}
5925   ins_encode %{
5926     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
5927   %}
5928   ins_pipe(ialu_reg_reg);
5929 %}
5930 
5931 instruct subshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
5932   match(Set dst (SubI src1 (URShiftI src2 src3)));
5933 
5934   size(4);
5935   format %{ "sub_32 $dst,$src1,$src2>>>$src3\t! int" %}
5936   ins_encode %{
5937     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
5938   %}
5939   ins_pipe(ialu_reg_reg);
5940 %}
5941 
5942 instruct rsbshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5943   match(Set dst (SubI (LShiftI src1 src2) src3));
5944 
5945   size(4);
5946   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
5947   ins_encode %{
5948     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
5949   %}
5950   ins_pipe(ialu_reg_reg);
5951 %}
5952 
5953 instruct rsbshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
5954   match(Set dst (SubI (LShiftI src1 src2) src3));
5955 
5956   size(4);
5957   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
5958   ins_encode %{
5959     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
5960   %}
5961   ins_pipe(ialu_reg_reg);
5962 %}
5963 
5964 instruct rsbsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5965   match(Set dst (SubI (RShiftI src1 src2) src3));
5966 
5967   size(4);
5968   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
5969   ins_encode %{
5970     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
5971   %}
5972   ins_pipe(ialu_reg_reg);
5973 %}
5974 
5975 instruct rsbsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
5976   match(Set dst (SubI (RShiftI src1 src2) src3));
5977 
5978   size(4);
5979   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
5980   ins_encode %{
5981     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
5982   %}
5983   ins_pipe(ialu_reg_reg);
5984 %}
5985 
5986 instruct rsbshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5987   match(Set dst (SubI (URShiftI src1 src2) src3));
5988 
5989   size(4);
5990   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
5991   ins_encode %{
5992     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
5993   %}
5994   ins_pipe(ialu_reg_reg);
5995 %}
5996 
5997 instruct rsbshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
5998   match(Set dst (SubI (URShiftI src1 src2) src3));
5999 
6000   size(4);
6001   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
6002   ins_encode %{
6003     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
6004   %}
6005   ins_pipe(ialu_reg_reg);
6006 %}
6007 
6008 // Immediate Subtraction
6009 instruct subI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
6010   match(Set dst (SubI src1 src2));
6011 
6012   size(4);
6013   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
6014   ins_encode %{
6015     __ sub_32($dst$$Register, $src1$$Register, $src2$$constant);
6016   %}
6017   ins_pipe(ialu_reg_imm);
6018 %}
6019 
6020 instruct subI_reg_immRotneg(iRegI dst, iRegI src1, aimmIneg src2) %{
6021   match(Set dst (AddI src1 src2));
6022 
6023   size(4);
6024   format %{ "sub_32 $dst,$src1,-($src2)\t! int" %}
6025   ins_encode %{
6026     __ sub_32($dst$$Register, $src1$$Register, -$src2$$constant);
6027   %}
6028   ins_pipe(ialu_reg_imm);
6029 %}
6030 
6031 instruct subI_immRot_reg(iRegI dst, immIRot src1, iRegI src2) %{
6032   match(Set dst (SubI src1 src2));
6033 
6034   size(4);
6035   format %{ "RSB    $dst,$src2,src1" %}
6036   ins_encode %{
6037     __ rsb($dst$$Register, $src2$$Register, $src1$$constant);
6038   %}
6039   ins_pipe(ialu_zero_reg);
6040 %}
6041 
6042 // Register Subtraction
6043 instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg icc ) %{
6044   match(Set dst (SubL src1 src2));
6045   effect (KILL icc);
6046 
6047   size(8);
6048   format %{ "SUBS   $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
6049             "SBC    $dst.hi,$src1.hi,$src2.hi" %}
6050   ins_encode %{
6051     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
6052     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
6053   %}
6054   ins_pipe(ialu_reg_reg);
6055 %}
6056 
6057 // TODO
6058 
6059 // Immediate Subtraction
6060 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6061 // (hi($con$$constant), lo($con$$constant)) becomes
6062 instruct subL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg icc) %{
6063   match(Set dst (SubL src1 con));
6064   effect (KILL icc);
6065 
6066   size(8);
6067   format %{ "SUB    $dst.lo,$src1.lo,$con\t! long\n\t"
6068             "SBC    $dst.hi,$src1.hi,0" %}
6069   ins_encode %{
6070     __ subs($dst$$Register, $src1$$Register, $con$$constant);
6071     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), 0);
6072   %}
6073   ins_pipe(ialu_reg_imm);
6074 %}
6075 
6076 // Long negation
6077 instruct negL_reg_reg(iRegL dst, immL0 zero, iRegL src2, flagsReg icc) %{
6078   match(Set dst (SubL zero src2));
6079   effect (KILL icc);
6080 
6081   size(8);
6082   format %{ "RSBS   $dst.lo,$src2.lo,0\t! long\n\t"
6083             "RSC    $dst.hi,$src2.hi,0" %}
6084   ins_encode %{
6085     __ rsbs($dst$$Register, $src2$$Register, 0);
6086     __ rsc($dst$$Register->successor(), $src2$$Register->successor(), 0);
6087   %}
6088   ins_pipe(ialu_zero_reg);
6089 %}
6090 
6091 // Multiplication Instructions
6092 // Integer Multiplication
6093 // Register Multiplication
6094 instruct mulI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6095   match(Set dst (MulI src1 src2));
6096 
6097   size(4);
6098   format %{ "mul_32 $dst,$src1,$src2" %}
6099   ins_encode %{
6100     __ mul_32($dst$$Register, $src1$$Register, $src2$$Register);
6101   %}
6102   ins_pipe(imul_reg_reg);
6103 %}
6104 
6105 instruct mulL_lo1_hi2(iRegL dst, iRegL src1, iRegL src2) %{
6106   effect(DEF dst, USE src1, USE src2);
6107   size(4);
6108   format %{ "MUL  $dst.hi,$src1.lo,$src2.hi\t! long" %}
6109   ins_encode %{
6110     __ mul($dst$$Register->successor(), $src1$$Register, $src2$$Register->successor());
6111   %}
6112   ins_pipe(imul_reg_reg);
6113 %}
6114 
6115 instruct mulL_hi1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
6116   effect(USE_DEF dst, USE src1, USE src2);
6117   size(8);
6118   format %{ "MLA  $dst.hi,$src1.hi,$src2.lo,$dst.hi\t! long\n\t"
6119             "MOV  $dst.lo, 0"%}
6120   ins_encode %{
6121     __ mla($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register, $dst$$Register->successor());
6122     __ mov($dst$$Register, 0);
6123   %}
6124   ins_pipe(imul_reg_reg);
6125 %}
6126 
6127 instruct mulL_lo1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
6128   effect(USE_DEF dst, USE src1, USE src2);
6129   size(4);
6130   format %{ "UMLAL  $dst.lo,$dst.hi,$src1,$src2\t! long" %}
6131   ins_encode %{
6132     __ umlal($dst$$Register, $dst$$Register->successor(), $src1$$Register, $src2$$Register);
6133   %}
6134   ins_pipe(imul_reg_reg);
6135 %}
6136 
6137 instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
6138   match(Set dst (MulL src1 src2));
6139 
6140   expand %{
6141     mulL_lo1_hi2(dst, src1, src2);
6142     mulL_hi1_lo2(dst, src1, src2);
6143     mulL_lo1_lo2(dst, src1, src2);
6144   %}
6145 %}
6146 
6147 // Integer Division
6148 // Register Division
6149 instruct divI_reg_reg(R1RegI dst, R0RegI src1, R2RegI src2, LRRegP lr, flagsReg ccr) %{
6150   match(Set dst (DivI src1 src2));
6151   effect( KILL ccr, KILL src1, KILL src2, KILL lr);
6152   ins_cost((2+71)*DEFAULT_COST);
6153 
6154   format %{ "DIV   $dst,$src1,$src2 ! call to StubRoutines::Arm::idiv_irem_entry()" %}
6155   ins_encode %{
6156     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
6157   %}
6158   ins_pipe(sdiv_reg_reg);
6159 %}
6160 
6161 // Register Long Division
6162 instruct divL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
6163   match(Set dst (DivL src1 src2));
6164   effect(CALL);
6165   ins_cost(DEFAULT_COST*71);
6166   format %{ "DIVL  $src1,$src2,$dst\t! long ! call to SharedRuntime::ldiv" %}
6167   ins_encode %{
6168     address target = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);
6169     __ call(target, relocInfo::runtime_call_type);
6170   %}
6171   ins_pipe(divL_reg_reg);
6172 %}
6173 
6174 // Integer Remainder
6175 // Register Remainder
6176 instruct modI_reg_reg(R0RegI dst, R0RegI src1, R2RegI src2, R1RegI temp, LRRegP lr, flagsReg ccr ) %{
6177   match(Set dst (ModI src1 src2));
6178   effect( KILL ccr, KILL temp, KILL src2, KILL lr);
6179 
6180   format %{ "MODI   $dst,$src1,$src2\t ! call to StubRoutines::Arm::idiv_irem_entry" %}
6181   ins_encode %{
6182     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
6183   %}
6184   ins_pipe(sdiv_reg_reg);
6185 %}
6186 
6187 // Register Long Remainder
6188 instruct modL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
6189   match(Set dst (ModL src1 src2));
6190   effect(CALL);
6191   ins_cost(MEMORY_REF_COST); // FIXME
6192   format %{ "modL    $dst,$src1,$src2\t ! call to SharedRuntime::lrem" %}
6193   ins_encode %{
6194     address target = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
6195     __ call(target, relocInfo::runtime_call_type);
6196   %}
6197   ins_pipe(divL_reg_reg);
6198 %}
6199 
6200 // Integer Shift Instructions
6201 
6202 // Register Shift Left
6203 instruct shlI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6204   match(Set dst (LShiftI src1 src2));
6205 
6206   size(4);
6207   format %{ "LSL  $dst,$src1,$src2 \n\t" %}
6208   ins_encode %{
6209     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
6210   %}
6211   ins_pipe(ialu_reg_reg);
6212 %}
6213 
6214 // Register Shift Left Immediate
6215 instruct shlI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
6216   match(Set dst (LShiftI src1 src2));
6217 
6218   size(4);
6219   format %{ "LSL    $dst,$src1,$src2\t! int" %}
6220   ins_encode %{
6221     __ logical_shift_left($dst$$Register, $src1$$Register, $src2$$constant);
6222   %}
6223   ins_pipe(ialu_reg_imm);
6224 %}
6225 
6226 instruct shlL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
6227   effect(USE_DEF dst, USE src1, USE src2);
6228   size(4);
6229   format %{"OR  $dst.hi,$dst.hi,($src1.hi << $src2)"  %}
6230   ins_encode %{
6231     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$Register));
6232   %}
6233   ins_pipe(ialu_reg_reg);
6234 %}
6235 
6236 instruct shlL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
6237   effect(USE_DEF dst, USE src1, USE src2);
6238   size(4);
6239   format %{ "LSL  $dst.lo,$src1.lo,$src2 \n\t" %}
6240   ins_encode %{
6241     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
6242   %}
6243   ins_pipe(ialu_reg_reg);
6244 %}
6245 
6246 instruct shlL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
6247   effect(DEF dst, USE src1, USE src2, KILL ccr);
6248   size(16);
6249   format %{ "SUBS  $dst.hi,$src2,32 \n\t"
6250             "LSLpl $dst.hi,$src1.lo,$dst.hi \n\t"
6251             "RSBmi $dst.hi,$dst.hi,0 \n\t"
6252             "LSRmi $dst.hi,$src1.lo,$dst.hi" %}
6253 
6254   ins_encode %{
6255     // $src1$$Register and $dst$$Register->successor() can't be the same
6256     __ subs($dst$$Register->successor(), $src2$$Register, 32);
6257     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $dst$$Register->successor()), pl);
6258     __ rsb($dst$$Register->successor(), $dst$$Register->successor(), 0, mi);
6259     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsr, $dst$$Register->successor()), mi);
6260   %}
6261   ins_pipe(ialu_reg_reg);
6262 %}
6263 
6264 instruct shlL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
6265   match(Set dst (LShiftL src1 src2));
6266 
6267   expand %{
6268     flagsReg ccr;
6269     shlL_reg_reg_overlap(dst, src1, src2, ccr);
6270     shlL_reg_reg_merge_hi(dst, src1, src2);
6271     shlL_reg_reg_merge_lo(dst, src1, src2);
6272   %}
6273 %}
6274 
6275 // Register Shift Left Immediate
6276 instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
6277   match(Set dst (LShiftL src1 src2));
6278 
6279   size(8);
6280   format %{ "LSL   $dst.hi,$src1.lo,$src2-32\t! or mov if $src2==32\n\t"
6281             "MOV   $dst.lo, 0" %}
6282   ins_encode %{
6283     if ($src2$$constant == 32) {
6284       __ mov($dst$$Register->successor(), $src1$$Register);
6285     } else {
6286       __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $src2$$constant-32));
6287     }
6288     __ mov($dst$$Register, 0);
6289   %}
6290   ins_pipe(ialu_reg_imm);
6291 %}
6292 
6293 instruct shlL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
6294   match(Set dst (LShiftL src1 src2));
6295 
6296   size(12);
6297   format %{ "LSL   $dst.hi,$src1.lo,$src2\n\t"
6298             "OR    $dst.hi, $dst.hi, $src1.lo >> 32-$src2\n\t"
6299             "LSL   $dst.lo,$src1.lo,$src2" %}
6300   ins_encode %{
6301     // The order of the following 3 instructions matters: src1.lo and
6302     // dst.hi can't overlap but src.hi and dst.hi can.
6303     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$constant));
6304     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register, lsr, 32-$src2$$constant));
6305     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
6306   %}
6307   ins_pipe(ialu_reg_imm);
6308 %}
6309 
6310 // Register Arithmetic Shift Right
6311 instruct sarI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6312   match(Set dst (RShiftI src1 src2));
6313   size(4);
6314   format %{ "ASR    $dst,$src1,$src2\t! int" %}
6315   ins_encode %{
6316     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
6317   %}
6318   ins_pipe(ialu_reg_reg);
6319 %}
6320 
6321 // Register Arithmetic Shift Right Immediate
6322 instruct sarI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
6323   match(Set dst (RShiftI src1 src2));
6324 
6325   size(4);
6326   format %{ "ASR    $dst,$src1,$src2" %}
6327   ins_encode %{
6328     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
6329   %}
6330   ins_pipe(ialu_reg_imm);
6331 %}
6332 
6333 // Register Shift Right Arithmetic Long
6334 instruct sarL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
6335   effect(USE_DEF dst, USE src1, USE src2);
6336   size(4);
6337   format %{ "OR  $dst.lo,$dst.lo,($src1.lo >> $src2)"  %}
6338   ins_encode %{
6339     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
6340   %}
6341   ins_pipe(ialu_reg_reg);
6342 %}
6343 
6344 instruct sarL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
6345   effect(USE_DEF dst, USE src1, USE src2);
6346   size(4);
6347   format %{ "ASR  $dst.hi,$src1.hi,$src2 \n\t" %}
6348   ins_encode %{
6349     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$Register));
6350   %}
6351   ins_pipe(ialu_reg_reg);
6352 %}
6353 
6354 instruct sarL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
6355   effect(DEF dst, USE src1, USE src2, KILL ccr);
6356   size(16);
6357   format %{ "SUBS  $dst.lo,$src2,32 \n\t"
6358             "ASRpl $dst.lo,$src1.hi,$dst.lo \n\t"
6359             "RSBmi $dst.lo,$dst.lo,0 \n\t"
6360             "LSLmi $dst.lo,$src1.hi,$dst.lo" %}
6361 
6362   ins_encode %{
6363     // $src1$$Register->successor() and $dst$$Register can't be the same
6364     __ subs($dst$$Register, $src2$$Register, 32);
6365     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $dst$$Register), pl);
6366     __ rsb($dst$$Register, $dst$$Register, 0, mi);
6367     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
6368   %}
6369   ins_pipe(ialu_reg_reg);
6370 %}
6371 
6372 instruct sarL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
6373   match(Set dst (RShiftL src1 src2));
6374 
6375   expand %{
6376     flagsReg ccr;
6377     sarL_reg_reg_overlap(dst, src1, src2, ccr);
6378     sarL_reg_reg_merge_lo(dst, src1, src2);
6379     sarL_reg_reg_merge_hi(dst, src1, src2);
6380   %}
6381 %}
6382 
6383 // Register Shift Left Immediate
6384 instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
6385   match(Set dst (RShiftL src1 src2));
6386 
6387   size(8);
6388   format %{ "ASR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
6389             "ASR   $dst.hi,$src1.hi, $src2" %}
6390   ins_encode %{
6391     if ($src2$$constant == 32) {
6392       __ mov($dst$$Register, $src1$$Register->successor());
6393     } else{
6394       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $src2$$constant-32));
6395     }
6396     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, 0));
6397   %}
6398 
6399   ins_pipe(ialu_reg_imm);
6400 %}
6401 
6402 instruct sarL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
6403   match(Set dst (RShiftL src1 src2));
6404   size(12);
6405   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
6406             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
6407             "ASR   $dst.hi,$src1.hi,$src2" %}
6408   ins_encode %{
6409     // The order of the following 3 instructions matters: src1.lo and
6410     // dst.hi can't overlap but src.hi and dst.hi can.
6411     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
6412     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
6413     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$constant));
6414   %}
6415   ins_pipe(ialu_reg_imm);
6416 %}
6417 
6418 // Register Shift Right
6419 instruct shrI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6420   match(Set dst (URShiftI src1 src2));
6421   size(4);
6422   format %{ "LSR    $dst,$src1,$src2\t! int" %}
6423   ins_encode %{
6424     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
6425   %}
6426   ins_pipe(ialu_reg_reg);
6427 %}
6428 
6429 // Register Shift Right Immediate
6430 instruct shrI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
6431   match(Set dst (URShiftI src1 src2));
6432 
6433   size(4);
6434   format %{ "LSR    $dst,$src1,$src2" %}
6435   ins_encode %{
6436     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
6437   %}
6438   ins_pipe(ialu_reg_imm);
6439 %}
6440 
6441 // Register Shift Right
6442 instruct shrL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
6443   effect(USE_DEF dst, USE src1, USE src2);
6444   size(4);
6445   format %{ "OR   $dst.lo,$dst,($src1.lo >>> $src2)"  %}
6446   ins_encode %{
6447     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
6448   %}
6449   ins_pipe(ialu_reg_reg);
6450 %}
6451 
6452 instruct shrL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
6453   effect(USE_DEF dst, USE src1, USE src2);
6454   size(4);
6455   format %{ "LSR  $dst.hi,$src1.hi,$src2 \n\t" %}
6456   ins_encode %{
6457     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$Register));
6458   %}
6459   ins_pipe(ialu_reg_reg);
6460 %}
6461 
6462 instruct shrL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
6463   effect(DEF dst, USE src1, USE src2, KILL ccr);
6464   size(16);
6465   format %{ "SUBS  $dst,$src2,32 \n\t"
6466             "LSRpl $dst,$src1.hi,$dst \n\t"
6467             "RSBmi $dst,$dst,0 \n\t"
6468             "LSLmi $dst,$src1.hi,$dst" %}
6469 
6470   ins_encode %{
6471     // $src1$$Register->successor() and $dst$$Register can't be the same
6472     __ subs($dst$$Register, $src2$$Register, 32);
6473     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $dst$$Register), pl);
6474     __ rsb($dst$$Register, $dst$$Register, 0, mi);
6475     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
6476   %}
6477   ins_pipe(ialu_reg_reg);
6478 %}
6479 
6480 instruct shrL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
6481   match(Set dst (URShiftL src1 src2));
6482 
6483   expand %{
6484     flagsReg ccr;
6485     shrL_reg_reg_overlap(dst, src1, src2, ccr);
6486     shrL_reg_reg_merge_lo(dst, src1, src2);
6487     shrL_reg_reg_merge_hi(dst, src1, src2);
6488   %}
6489 %}
6490 
6491 // Register Shift Right Immediate
6492 instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
6493   match(Set dst (URShiftL src1 src2));
6494 
6495   size(8);
6496   format %{ "LSR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
6497             "MOV   $dst.hi, 0" %}
6498   ins_encode %{
6499     if ($src2$$constant == 32) {
6500       __ mov($dst$$Register, $src1$$Register->successor());
6501     } else {
6502       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $src2$$constant-32));
6503     }
6504     __ mov($dst$$Register->successor(), 0);
6505   %}
6506 
6507   ins_pipe(ialu_reg_imm);
6508 %}
6509 
6510 instruct shrL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
6511   match(Set dst (URShiftL src1 src2));
6512 
6513   size(12);
6514   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
6515             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
6516             "LSR   $dst.hi,$src1.hi,$src2" %}
6517   ins_encode %{
6518     // The order of the following 3 instructions matters: src1.lo and
6519     // dst.hi can't overlap but src.hi and dst.hi can.
6520     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
6521     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
6522     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$constant));
6523   %}
6524   ins_pipe(ialu_reg_imm);
6525 %}
6526 
6527 
6528 instruct shrP_reg_imm5(iRegX dst, iRegP src1, immU5 src2) %{
6529   match(Set dst (URShiftI (CastP2X src1) src2));
6530   size(4);
6531   format %{ "LSR    $dst,$src1,$src2\t! Cast ptr $src1 to int and shift" %}
6532   ins_encode %{
6533     __ logical_shift_right($dst$$Register, $src1$$Register, $src2$$constant);
6534   %}
6535   ins_pipe(ialu_reg_imm);
6536 %}
6537 
6538 //----------Floating Point Arithmetic Instructions-----------------------------
6539 
6540 //  Add float single precision
6541 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
6542   match(Set dst (AddF src1 src2));
6543 
6544   size(4);
6545   format %{ "FADDS  $dst,$src1,$src2" %}
6546   ins_encode %{
6547     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6548   %}
6549 
6550   ins_pipe(faddF_reg_reg);
6551 %}
6552 
6553 //  Add float double precision
6554 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
6555   match(Set dst (AddD src1 src2));
6556 
6557   size(4);
6558   format %{ "FADDD  $dst,$src1,$src2" %}
6559   ins_encode %{
6560     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6561   %}
6562 
6563   ins_pipe(faddD_reg_reg);
6564 %}
6565 
6566 //  Sub float single precision
6567 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
6568   match(Set dst (SubF src1 src2));
6569 
6570   size(4);
6571   format %{ "FSUBS  $dst,$src1,$src2" %}
6572   ins_encode %{
6573     __ sub_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6574   %}
6575   ins_pipe(faddF_reg_reg);
6576 %}
6577 
6578 //  Sub float double precision
6579 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
6580   match(Set dst (SubD src1 src2));
6581 
6582   size(4);
6583   format %{ "FSUBD  $dst,$src1,$src2" %}
6584   ins_encode %{
6585     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6586   %}
6587   ins_pipe(faddD_reg_reg);
6588 %}
6589 
6590 //  Mul float single precision
6591 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
6592   match(Set dst (MulF src1 src2));
6593 
6594   size(4);
6595   format %{ "FMULS  $dst,$src1,$src2" %}
6596   ins_encode %{
6597     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6598   %}
6599 
6600   ins_pipe(fmulF_reg_reg);
6601 %}
6602 
6603 //  Mul float double precision
6604 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
6605   match(Set dst (MulD src1 src2));
6606 
6607   size(4);
6608   format %{ "FMULD  $dst,$src1,$src2" %}
6609   ins_encode %{
6610     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6611   %}
6612 
6613   ins_pipe(fmulD_reg_reg);
6614 %}
6615 
6616 //  Div float single precision
6617 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
6618   match(Set dst (DivF src1 src2));
6619 
6620   size(4);
6621   format %{ "FDIVS  $dst,$src1,$src2" %}
6622   ins_encode %{
6623     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6624   %}
6625 
6626   ins_pipe(fdivF_reg_reg);
6627 %}
6628 
6629 //  Div float double precision
6630 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
6631   match(Set dst (DivD src1 src2));
6632 
6633   size(4);
6634   format %{ "FDIVD  $dst,$src1,$src2" %}
6635   ins_encode %{
6636     __ div_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6637   %}
6638 
6639   ins_pipe(fdivD_reg_reg);
6640 %}
6641 
6642 //  Absolute float double precision
6643 instruct absD_reg(regD dst, regD src) %{
6644   match(Set dst (AbsD src));
6645 
6646   size(4);
6647   format %{ "FABSd  $dst,$src" %}
6648   ins_encode %{
6649     __ abs_double($dst$$FloatRegister, $src$$FloatRegister);
6650   %}
6651   ins_pipe(faddD_reg);
6652 %}
6653 
6654 //  Absolute float single precision
6655 instruct absF_reg(regF dst, regF src) %{
6656   match(Set dst (AbsF src));
6657   format %{ "FABSs  $dst,$src" %}
6658   ins_encode %{
6659     __ abs_float($dst$$FloatRegister, $src$$FloatRegister);
6660   %}
6661   ins_pipe(faddF_reg);
6662 %}
6663 
6664 instruct negF_reg(regF dst, regF src) %{
6665   match(Set dst (NegF src));
6666 
6667   size(4);
6668   format %{ "FNEGs  $dst,$src" %}
6669   ins_encode %{
6670     __ neg_float($dst$$FloatRegister, $src$$FloatRegister);
6671   %}
6672   ins_pipe(faddF_reg);
6673 %}
6674 
6675 instruct negD_reg(regD dst, regD src) %{
6676   match(Set dst (NegD src));
6677 
6678   format %{ "FNEGd  $dst,$src" %}
6679   ins_encode %{
6680     __ neg_double($dst$$FloatRegister, $src$$FloatRegister);
6681   %}
6682   ins_pipe(faddD_reg);
6683 %}
6684 
6685 //  Sqrt float double precision
6686 instruct sqrtF_reg_reg(regF dst, regF src) %{
6687   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
6688 
6689   size(4);
6690   format %{ "FSQRTS $dst,$src" %}
6691   ins_encode %{
6692     __ sqrt_float($dst$$FloatRegister, $src$$FloatRegister);
6693   %}
6694   ins_pipe(fdivF_reg_reg);
6695 %}
6696 
6697 //  Sqrt float double precision
6698 instruct sqrtD_reg_reg(regD dst, regD src) %{
6699   match(Set dst (SqrtD src));
6700 
6701   size(4);
6702   format %{ "FSQRTD $dst,$src" %}
6703   ins_encode %{
6704     __ sqrt_double($dst$$FloatRegister, $src$$FloatRegister);
6705   %}
6706   ins_pipe(fdivD_reg_reg);
6707 %}
6708 
6709 //----------Logical Instructions-----------------------------------------------
6710 // And Instructions
6711 // Register And
6712 instruct andI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6713   match(Set dst (AndI src1 src2));
6714 
6715   size(4);
6716   format %{ "and_32 $dst,$src1,$src2" %}
6717   ins_encode %{
6718     __ and_32($dst$$Register, $src1$$Register, $src2$$Register);
6719   %}
6720   ins_pipe(ialu_reg_reg);
6721 %}
6722 
6723 instruct andshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6724   match(Set dst (AndI src1 (LShiftI src2 src3)));
6725 
6726   size(4);
6727   format %{ "AND    $dst,$src1,$src2<<$src3" %}
6728   ins_encode %{
6729     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
6730   %}
6731   ins_pipe(ialu_reg_reg);
6732 %}
6733 
6734 instruct andshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6735   match(Set dst (AndI src1 (LShiftI src2 src3)));
6736 
6737   size(4);
6738   format %{ "and_32 $dst,$src1,$src2<<$src3" %}
6739   ins_encode %{
6740     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
6741   %}
6742   ins_pipe(ialu_reg_reg);
6743 %}
6744 
6745 instruct andsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6746   match(Set dst (AndI src1 (RShiftI src2 src3)));
6747 
6748   size(4);
6749   format %{ "AND    $dst,$src1,$src2>>$src3" %}
6750   ins_encode %{
6751     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
6752   %}
6753   ins_pipe(ialu_reg_reg);
6754 %}
6755 
6756 instruct andsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6757   match(Set dst (AndI src1 (RShiftI src2 src3)));
6758 
6759   size(4);
6760   format %{ "and_32 $dst,$src1,$src2>>$src3" %}
6761   ins_encode %{
6762     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
6763   %}
6764   ins_pipe(ialu_reg_reg);
6765 %}
6766 
6767 instruct andshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6768   match(Set dst (AndI src1 (URShiftI src2 src3)));
6769 
6770   size(4);
6771   format %{ "AND    $dst,$src1,$src2>>>$src3" %}
6772   ins_encode %{
6773     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
6774   %}
6775   ins_pipe(ialu_reg_reg);
6776 %}
6777 
6778 instruct andshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6779   match(Set dst (AndI src1 (URShiftI src2 src3)));
6780 
6781   size(4);
6782   format %{ "and_32 $dst,$src1,$src2>>>$src3" %}
6783   ins_encode %{
6784     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
6785   %}
6786   ins_pipe(ialu_reg_reg);
6787 %}
6788 
6789 // Immediate And
6790 instruct andI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
6791   match(Set dst (AndI src1 src2));
6792 
6793   size(4);
6794   format %{ "and_32 $dst,$src1,$src2\t! int" %}
6795   ins_encode %{
6796     __ and_32($dst$$Register, $src1$$Register, $src2$$constant);
6797   %}
6798   ins_pipe(ialu_reg_imm);
6799 %}
6800 
6801 instruct andI_reg_limmn(iRegI dst, iRegI src1, limmIn src2) %{
6802   match(Set dst (AndI src1 src2));
6803 
6804   size(4);
6805   format %{ "bic    $dst,$src1,~$src2\t! int" %}
6806   ins_encode %{
6807     __ bic($dst$$Register, $src1$$Register, ~$src2$$constant);
6808   %}
6809   ins_pipe(ialu_reg_imm);
6810 %}
6811 
6812 // Register And Long
6813 instruct andL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
6814   match(Set dst (AndL src1 src2));
6815 
6816   ins_cost(DEFAULT_COST);
6817   size(8);
6818   format %{ "AND    $dst,$src1,$src2\t! long" %}
6819   ins_encode %{
6820     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
6821     __ andr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
6822   %}
6823   ins_pipe(ialu_reg_reg);
6824 %}
6825 
6826 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6827 // (hi($con$$constant), lo($con$$constant)) becomes
6828 instruct andL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
6829   match(Set dst (AndL src1 con));
6830   ins_cost(DEFAULT_COST);
6831   size(8);
6832   format %{ "AND    $dst,$src1,$con\t! long" %}
6833   ins_encode %{
6834     __ andr($dst$$Register, $src1$$Register, $con$$constant);
6835     __ andr($dst$$Register->successor(), $src1$$Register->successor(), 0);
6836   %}
6837   ins_pipe(ialu_reg_imm);
6838 %}
6839 
6840 // Or Instructions
6841 // Register Or
6842 instruct orI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6843   match(Set dst (OrI src1 src2));
6844 
6845   size(4);
6846   format %{ "orr_32 $dst,$src1,$src2\t! int" %}
6847   ins_encode %{
6848     __ orr_32($dst$$Register, $src1$$Register, $src2$$Register);
6849   %}
6850   ins_pipe(ialu_reg_reg);
6851 %}
6852 
6853 instruct orshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6854   match(Set dst (OrI src1 (LShiftI src2 src3)));
6855 
6856   size(4);
6857   format %{ "OR    $dst,$src1,$src2<<$src3" %}
6858   ins_encode %{
6859     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
6860   %}
6861   ins_pipe(ialu_reg_reg);
6862 %}
6863 
6864 instruct orshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6865   match(Set dst (OrI src1 (LShiftI src2 src3)));
6866 
6867   size(4);
6868   format %{ "orr_32 $dst,$src1,$src2<<$src3" %}
6869   ins_encode %{
6870     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
6871   %}
6872   ins_pipe(ialu_reg_reg);
6873 %}
6874 
6875 instruct orsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6876   match(Set dst (OrI src1 (RShiftI src2 src3)));
6877 
6878   size(4);
6879   format %{ "OR    $dst,$src1,$src2>>$src3" %}
6880   ins_encode %{
6881     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
6882   %}
6883   ins_pipe(ialu_reg_reg);
6884 %}
6885 
6886 instruct orsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6887   match(Set dst (OrI src1 (RShiftI src2 src3)));
6888 
6889   size(4);
6890   format %{ "orr_32 $dst,$src1,$src2>>$src3" %}
6891   ins_encode %{
6892     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
6893   %}
6894   ins_pipe(ialu_reg_reg);
6895 %}
6896 
6897 instruct orshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6898   match(Set dst (OrI src1 (URShiftI src2 src3)));
6899 
6900   size(4);
6901   format %{ "OR    $dst,$src1,$src2>>>$src3" %}
6902   ins_encode %{
6903     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
6904   %}
6905   ins_pipe(ialu_reg_reg);
6906 %}
6907 
6908 instruct orshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6909   match(Set dst (OrI src1 (URShiftI src2 src3)));
6910 
6911   size(4);
6912   format %{ "orr_32 $dst,$src1,$src2>>>$src3" %}
6913   ins_encode %{
6914     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
6915   %}
6916   ins_pipe(ialu_reg_reg);
6917 %}
6918 
6919 // Immediate Or
6920 instruct orI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
6921   match(Set dst (OrI src1 src2));
6922 
6923   size(4);
6924   format %{ "orr_32  $dst,$src1,$src2" %}
6925   ins_encode %{
6926     __ orr_32($dst$$Register, $src1$$Register, $src2$$constant);
6927   %}
6928   ins_pipe(ialu_reg_imm);
6929 %}
6930 // TODO: orn_32 with limmIn
6931 
6932 // Register Or Long
6933 instruct orL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
6934   match(Set dst (OrL src1 src2));
6935 
6936   ins_cost(DEFAULT_COST);
6937   size(8);
6938   format %{ "OR     $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
6939             "OR     $dst.hi,$src1.hi,$src2.hi" %}
6940   ins_encode %{
6941     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
6942     __ orr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
6943   %}
6944   ins_pipe(ialu_reg_reg);
6945 %}
6946 
6947 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6948 // (hi($con$$constant), lo($con$$constant)) becomes
6949 instruct orL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
6950   match(Set dst (OrL src1 con));
6951   ins_cost(DEFAULT_COST);
6952   size(8);
6953   format %{ "OR     $dst.lo,$src1.lo,$con\t! long\n\t"
6954             "OR     $dst.hi,$src1.hi,$con" %}
6955   ins_encode %{
6956     __ orr($dst$$Register, $src1$$Register, $con$$constant);
6957     __ orr($dst$$Register->successor(), $src1$$Register->successor(), 0);
6958   %}
6959   ins_pipe(ialu_reg_imm);
6960 %}
6961 
6962 #ifdef TODO
6963 // Use SPRegP to match Rthread (TLS register) without spilling.
6964 // Use store_ptr_RegP to match Rthread (TLS register) without spilling.
6965 // Use sp_ptr_RegP to match Rthread (TLS register) without spilling.
6966 instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
6967   match(Set dst (OrI src1 (CastP2X src2)));
6968   size(4);
6969   format %{ "OR     $dst,$src1,$src2" %}
6970   ins_encode %{
6971     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
6972   %}
6973   ins_pipe(ialu_reg_reg);
6974 %}
6975 #endif
6976 
6977 // Xor Instructions
6978 // Register Xor
6979 instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6980   match(Set dst (XorI src1 src2));
6981 
6982   size(4);
6983   format %{ "eor_32 $dst,$src1,$src2" %}
6984   ins_encode %{
6985     __ eor_32($dst$$Register, $src1$$Register, $src2$$Register);
6986   %}
6987   ins_pipe(ialu_reg_reg);
6988 %}
6989 
6990 instruct xorshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6991   match(Set dst (XorI src1 (LShiftI src2 src3)));
6992 
6993   size(4);
6994   format %{ "XOR    $dst,$src1,$src2<<$src3" %}
6995   ins_encode %{
6996     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
6997   %}
6998   ins_pipe(ialu_reg_reg);
6999 %}
7000 
7001 instruct xorshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
7002   match(Set dst (XorI src1 (LShiftI src2 src3)));
7003 
7004   size(4);
7005   format %{ "eor_32 $dst,$src1,$src2<<$src3" %}
7006   ins_encode %{
7007     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
7008   %}
7009   ins_pipe(ialu_reg_reg);
7010 %}
7011 
7012 instruct xorsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
7013   match(Set dst (XorI src1 (RShiftI src2 src3)));
7014 
7015   size(4);
7016   format %{ "XOR    $dst,$src1,$src2>>$src3" %}
7017   ins_encode %{
7018     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
7019   %}
7020   ins_pipe(ialu_reg_reg);
7021 %}
7022 
7023 instruct xorsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
7024   match(Set dst (XorI src1 (RShiftI src2 src3)));
7025 
7026   size(4);
7027   format %{ "eor_32 $dst,$src1,$src2>>$src3" %}
7028   ins_encode %{
7029     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
7030   %}
7031   ins_pipe(ialu_reg_reg);
7032 %}
7033 
7034 instruct xorshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
7035   match(Set dst (XorI src1 (URShiftI src2 src3)));
7036 
7037   size(4);
7038   format %{ "XOR    $dst,$src1,$src2>>>$src3" %}
7039   ins_encode %{
7040     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
7041   %}
7042   ins_pipe(ialu_reg_reg);
7043 %}
7044 
7045 instruct xorshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
7046   match(Set dst (XorI src1 (URShiftI src2 src3)));
7047 
7048   size(4);
7049   format %{ "eor_32 $dst,$src1,$src2>>>$src3" %}
7050   ins_encode %{
7051     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
7052   %}
7053   ins_pipe(ialu_reg_reg);
7054 %}
7055 
7056 // Immediate Xor
7057 instruct xorI_reg_imm(iRegI dst, iRegI src1, limmI src2) %{
7058   match(Set dst (XorI src1 src2));
7059 
7060   size(4);
7061   format %{ "eor_32 $dst,$src1,$src2" %}
7062   ins_encode %{
7063     __ eor_32($dst$$Register, $src1$$Register, $src2$$constant);
7064   %}
7065   ins_pipe(ialu_reg_imm);
7066 %}
7067 
7068 // Register Xor Long
7069 instruct xorL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
7070   match(Set dst (XorL src1 src2));
7071   ins_cost(DEFAULT_COST);
7072   size(8);
7073   format %{ "XOR     $dst.hi,$src1.hi,$src2.hi\t! long\n\t"
7074             "XOR     $dst.lo,$src1.lo,$src2.lo\t! long" %}
7075   ins_encode %{
7076     __ eor($dst$$Register, $src1$$Register, $src2$$Register);
7077     __ eor($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
7078   %}
7079   ins_pipe(ialu_reg_reg);
7080 %}
7081 
7082 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7083 // (hi($con$$constant), lo($con$$constant)) becomes
7084 instruct xorL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
7085   match(Set dst (XorL src1 con));
7086   ins_cost(DEFAULT_COST);
7087   size(8);
7088   format %{ "XOR     $dst.hi,$src1.hi,$con\t! long\n\t"
7089             "XOR     $dst.lo,$src1.lo,0\t! long" %}
7090   ins_encode %{
7091     __ eor($dst$$Register, $src1$$Register, $con$$constant);
7092     __ eor($dst$$Register->successor(), $src1$$Register->successor(), 0);
7093   %}
7094   ins_pipe(ialu_reg_imm);
7095 %}
7096 
7097 //----------Convert to Boolean-------------------------------------------------
7098 instruct convI2B( iRegI dst, iRegI src, flagsReg ccr ) %{
7099   match(Set dst (Conv2B src));
7100   effect(KILL ccr);
7101   size(12);
7102   ins_cost(DEFAULT_COST*2);
7103   format %{ "TST    $src,$src \n\t"
7104             "MOV    $dst, 0   \n\t"
7105             "MOV.ne $dst, 1" %}
7106   ins_encode %{ // FIXME: can do better?
7107     __ tst($src$$Register, $src$$Register);
7108     __ mov($dst$$Register, 0);
7109     __ mov($dst$$Register, 1, ne);
7110   %}
7111   ins_pipe(ialu_reg_ialu);
7112 %}
7113 
7114 instruct convP2B( iRegI dst, iRegP src, flagsReg ccr ) %{
7115   match(Set dst (Conv2B src));
7116   effect(KILL ccr);
7117   size(12);
7118   ins_cost(DEFAULT_COST*2);
7119   format %{ "TST    $src,$src \n\t"
7120             "MOV    $dst, 0   \n\t"
7121             "MOV.ne $dst, 1" %}
7122   ins_encode %{
7123     __ tst($src$$Register, $src$$Register);
7124     __ mov($dst$$Register, 0);
7125     __ mov($dst$$Register, 1, ne);
7126   %}
7127   ins_pipe(ialu_reg_ialu);
7128 %}
7129 
7130 instruct cmpLTMask_reg_reg( iRegI dst, iRegI p, iRegI q, flagsReg ccr ) %{
7131   match(Set dst (CmpLTMask p q));
7132   effect( KILL ccr );
7133   ins_cost(DEFAULT_COST*3);
7134   format %{ "CMP    $p,$q\n\t"
7135             "MOV    $dst, #0\n\t"
7136             "MOV.lt $dst, #-1" %}
7137   ins_encode %{
7138     __ cmp($p$$Register, $q$$Register);
7139     __ mov($dst$$Register, 0);
7140     __ mvn($dst$$Register, 0, lt);
7141   %}
7142   ins_pipe(ialu_reg_reg_ialu);
7143 %}
7144 
7145 instruct cmpLTMask_reg_imm( iRegI dst, iRegI p, aimmI q, flagsReg ccr ) %{
7146   match(Set dst (CmpLTMask p q));
7147   effect( KILL ccr );
7148   ins_cost(DEFAULT_COST*3);
7149   format %{ "CMP    $p,$q\n\t"
7150             "MOV    $dst, #0\n\t"
7151             "MOV.lt $dst, #-1" %}
7152   ins_encode %{
7153     __ cmp($p$$Register, $q$$constant);
7154     __ mov($dst$$Register, 0);
7155     __ mvn($dst$$Register, 0, lt);
7156   %}
7157   ins_pipe(ialu_reg_reg_ialu);
7158 %}
7159 
7160 instruct cadd_cmpLTMask3( iRegI p, iRegI q, iRegI y, iRegI z, flagsReg ccr ) %{
7161   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
7162   effect( KILL ccr );
7163   ins_cost(DEFAULT_COST*2);
7164   format %{ "CMP    $p,$q\n\t"
7165             "ADD.lt $z,$y,$z" %}
7166   ins_encode %{
7167     __ cmp($p$$Register, $q$$Register);
7168     __ add($z$$Register, $y$$Register, $z$$Register, lt);
7169   %}
7170   ins_pipe( cadd_cmpltmask );
7171 %}
7172 
7173 // FIXME: remove unused "dst"
7174 instruct cadd_cmpLTMask4( iRegI dst, iRegI p, aimmI q, iRegI y, iRegI z, flagsReg ccr ) %{
7175   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
7176   effect( KILL ccr );
7177   ins_cost(DEFAULT_COST*2);
7178   format %{ "CMP    $p,$q\n\t"
7179             "ADD.lt $z,$y,$z" %}
7180   ins_encode %{
7181     __ cmp($p$$Register, $q$$constant);
7182     __ add($z$$Register, $y$$Register, $z$$Register, lt);
7183   %}
7184   ins_pipe( cadd_cmpltmask );
7185 %}
7186 
7187 instruct cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, flagsReg ccr ) %{
7188   match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
7189   effect( KILL ccr );
7190   ins_cost(DEFAULT_COST*2);
7191   format %{ "SUBS   $p,$p,$q\n\t"
7192             "ADD.lt $p,$y,$p" %}
7193   ins_encode %{
7194     __ subs($p$$Register, $p$$Register, $q$$Register);
7195     __ add($p$$Register, $y$$Register, $p$$Register, lt);
7196   %}
7197   ins_pipe( cadd_cmpltmask );
7198 %}
7199 
7200 //----------Arithmetic Conversion Instructions---------------------------------
7201 // The conversions operations are all Alpha sorted.  Please keep it that way!
7202 
7203 instruct convD2F_reg(regF dst, regD src) %{
7204   match(Set dst (ConvD2F src));
7205   size(4);
7206   format %{ "FCVTSD  $dst,$src" %}
7207   ins_encode %{
7208     __ convert_d2f($dst$$FloatRegister, $src$$FloatRegister);
7209   %}
7210   ins_pipe(fcvtD2F);
7211 %}
7212 
7213 // Convert a double to an int in a float register.
7214 // If the double is a NAN, stuff a zero in instead.
7215 
7216 instruct convD2I_reg_reg(iRegI dst, regD src, regF tmp) %{
7217   match(Set dst (ConvD2I src));
7218   effect( TEMP tmp );
7219   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
7220   format %{ "FTOSIZD  $tmp,$src\n\t"
7221             "FMRS     $dst, $tmp" %}
7222   ins_encode %{
7223     __ ftosizd($tmp$$FloatRegister, $src$$FloatRegister);
7224     __ fmrs($dst$$Register, $tmp$$FloatRegister);
7225   %}
7226   ins_pipe(fcvtD2I);
7227 %}
7228 
7229 // Convert a double to a long in a double register.
7230 // If the double is a NAN, stuff a zero in instead.
7231 
7232 // Double to Long conversion
7233 instruct convD2L_reg(R0R1RegL dst, regD src) %{
7234   match(Set dst (ConvD2L src));
7235   effect(CALL);
7236   ins_cost(MEMORY_REF_COST); // FIXME
7237   format %{ "convD2L    $dst,$src\t ! call to SharedRuntime::d2l" %}
7238   ins_encode %{
7239 #ifndef __ABI_HARD__
7240     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
7241 #else
7242     if ($src$$FloatRegister != D0) {
7243       __ mov_double(D0, $src$$FloatRegister);
7244     }
7245 #endif
7246     address target = CAST_FROM_FN_PTR(address, SharedRuntime::d2l);
7247     __ call(target, relocInfo::runtime_call_type);
7248   %}
7249   ins_pipe(fcvtD2L);
7250 %}
7251 
7252 instruct convF2D_reg(regD dst, regF src) %{
7253   match(Set dst (ConvF2D src));
7254   size(4);
7255   format %{ "FCVTDS  $dst,$src" %}
7256   ins_encode %{
7257     __ convert_f2d($dst$$FloatRegister, $src$$FloatRegister);
7258   %}
7259   ins_pipe(fcvtF2D);
7260 %}
7261 
7262 instruct convF2I_reg_reg(iRegI dst, regF src, regF tmp) %{
7263   match(Set dst (ConvF2I src));
7264   effect( TEMP tmp );
7265   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
7266   size(8);
7267   format %{ "FTOSIZS  $tmp,$src\n\t"
7268             "FMRS     $dst, $tmp" %}
7269   ins_encode %{
7270     __ ftosizs($tmp$$FloatRegister, $src$$FloatRegister);
7271     __ fmrs($dst$$Register, $tmp$$FloatRegister);
7272   %}
7273   ins_pipe(fcvtF2I);
7274 %}
7275 
7276 // Float to Long conversion
7277 instruct convF2L_reg(R0R1RegL dst, regF src, R0RegI arg1) %{
7278   match(Set dst (ConvF2L src));
7279   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
7280   effect(CALL);
7281   format %{ "convF2L  $dst,$src\t! call to SharedRuntime::f2l" %}
7282   ins_encode %{
7283 #ifndef __ABI_HARD__
7284     __ fmrs($arg1$$Register, $src$$FloatRegister);
7285 #else
7286     if($src$$FloatRegister != S0) {
7287       __ mov_float(S0, $src$$FloatRegister);
7288     }
7289 #endif
7290     address target = CAST_FROM_FN_PTR(address, SharedRuntime::f2l);
7291     __ call(target, relocInfo::runtime_call_type);
7292   %}
7293   ins_pipe(fcvtF2L);
7294 %}
7295 
7296 instruct convI2D_reg_reg(iRegI src, regD_low dst) %{
7297   match(Set dst (ConvI2D src));
7298   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
7299   size(8);
7300   format %{ "FMSR     $dst,$src \n\t"
7301             "FSITOD   $dst $dst"%}
7302   ins_encode %{
7303       __ fmsr($dst$$FloatRegister, $src$$Register);
7304       __ fsitod($dst$$FloatRegister, $dst$$FloatRegister);
7305   %}
7306   ins_pipe(fcvtI2D);
7307 %}
7308 
7309 instruct convI2F_reg_reg( regF dst, iRegI src ) %{
7310   match(Set dst (ConvI2F src));
7311   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
7312   size(8);
7313   format %{ "FMSR     $dst,$src \n\t"
7314             "FSITOS   $dst, $dst"%}
7315   ins_encode %{
7316       __ fmsr($dst$$FloatRegister, $src$$Register);
7317       __ fsitos($dst$$FloatRegister, $dst$$FloatRegister);
7318   %}
7319   ins_pipe(fcvtI2F);
7320 %}
7321 
7322 instruct convI2L_reg(iRegL dst, iRegI src) %{
7323   match(Set dst (ConvI2L src));
7324   size(8);
7325   format %{ "MOV    $dst.lo, $src \n\t"
7326             "ASR    $dst.hi,$src,31\t! int->long" %}
7327   ins_encode %{
7328     __ mov($dst$$Register, $src$$Register);
7329     __ mov($dst$$Register->successor(), AsmOperand($src$$Register, asr, 31));
7330   %}
7331   ins_pipe(ialu_reg_reg);
7332 %}
7333 
7334 // Zero-extend convert int to long
7335 instruct convI2L_reg_zex(iRegL dst, iRegI src, immL_32bits mask ) %{
7336   match(Set dst (AndL (ConvI2L src) mask) );
7337   size(8);
7338   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend int to long\n\t"
7339             "MOV    $dst.hi, 0"%}
7340   ins_encode %{
7341     __ mov($dst$$Register, $src$$Register);
7342     __ mov($dst$$Register->successor(), 0);
7343   %}
7344   ins_pipe(ialu_reg_reg);
7345 %}
7346 
7347 // Zero-extend long
7348 instruct zerox_long(iRegL dst, iRegL src, immL_32bits mask ) %{
7349   match(Set dst (AndL src mask) );
7350   size(8);
7351   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend long\n\t"
7352             "MOV    $dst.hi, 0"%}
7353   ins_encode %{
7354     __ mov($dst$$Register, $src$$Register);
7355     __ mov($dst$$Register->successor(), 0);
7356   %}
7357   ins_pipe(ialu_reg_reg);
7358 %}
7359 
7360 instruct MoveF2I_reg_reg(iRegI dst, regF src) %{
7361   match(Set dst (MoveF2I src));
7362   effect(DEF dst, USE src);
7363   ins_cost(MEMORY_REF_COST); // FIXME
7364 
7365   size(4);
7366   format %{ "FMRS   $dst,$src\t! MoveF2I" %}
7367   ins_encode %{
7368     __ fmrs($dst$$Register, $src$$FloatRegister);
7369   %}
7370   ins_pipe(iload_mem); // FIXME
7371 %}
7372 
7373 instruct MoveI2F_reg_reg(regF dst, iRegI src) %{
7374   match(Set dst (MoveI2F src));
7375   ins_cost(MEMORY_REF_COST); // FIXME
7376 
7377   size(4);
7378   format %{ "FMSR   $dst,$src\t! MoveI2F" %}
7379   ins_encode %{
7380     __ fmsr($dst$$FloatRegister, $src$$Register);
7381   %}
7382   ins_pipe(iload_mem); // FIXME
7383 %}
7384 
7385 instruct MoveD2L_reg_reg(iRegL dst, regD src) %{
7386   match(Set dst (MoveD2L src));
7387   effect(DEF dst, USE src);
7388   ins_cost(MEMORY_REF_COST); // FIXME
7389 
7390   size(4);
7391   format %{ "FMRRD    $dst,$src\t! MoveD2L" %}
7392   ins_encode %{
7393     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
7394   %}
7395   ins_pipe(iload_mem); // FIXME
7396 %}
7397 
7398 instruct MoveL2D_reg_reg(regD dst, iRegL src) %{
7399   match(Set dst (MoveL2D src));
7400   effect(DEF dst, USE src);
7401   ins_cost(MEMORY_REF_COST); // FIXME
7402 
7403   size(4);
7404   format %{ "FMDRR   $dst,$src\t! MoveL2D" %}
7405   ins_encode %{
7406     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
7407   %}
7408   ins_pipe(ialu_reg_reg); // FIXME
7409 %}
7410 
7411 //-----------
7412 // Long to Double conversion
7413 
7414 // Magic constant, 0x43300000
7415 instruct loadConI_x43300000(iRegI dst) %{
7416   effect(DEF dst);
7417   size(8);
7418   format %{ "MOV_SLOW  $dst,0x43300000\t! 2^52" %}
7419   ins_encode %{
7420     __ mov_slow($dst$$Register, 0x43300000);
7421   %}
7422   ins_pipe(ialu_none);
7423 %}
7424 
7425 // Magic constant, 0x41f00000
7426 instruct loadConI_x41f00000(iRegI dst) %{
7427   effect(DEF dst);
7428   size(8);
7429   format %{ "MOV_SLOW  $dst, 0x41f00000\t! 2^32" %}
7430   ins_encode %{
7431     __ mov_slow($dst$$Register, 0x41f00000);
7432   %}
7433   ins_pipe(ialu_none);
7434 %}
7435 
7436 instruct loadConI_x0(iRegI dst) %{
7437   effect(DEF dst);
7438   size(4);
7439   format %{ "MOV  $dst, 0x0\t! 0" %}
7440   ins_encode %{
7441     __ mov($dst$$Register, 0);
7442   %}
7443   ins_pipe(ialu_none);
7444 %}
7445 
7446 // Construct a double from two float halves
7447 instruct regDHi_regDLo_to_regD(regD_low dst, regD_low src1, regD_low src2) %{
7448   effect(DEF dst, USE src1, USE src2);
7449   size(8);
7450   format %{ "FCPYS  $dst.hi,$src1.hi\n\t"
7451             "FCPYS  $dst.lo,$src2.lo" %}
7452   ins_encode %{
7453     __ fcpys($dst$$FloatRegister->successor(), $src1$$FloatRegister->successor());
7454     __ fcpys($dst$$FloatRegister, $src2$$FloatRegister);
7455   %}
7456   ins_pipe(faddD_reg_reg);
7457 %}
7458 
7459 // Convert integer in high half of a double register (in the lower half of
7460 // the double register file) to double
7461 instruct convI2D_regDHi_regD(regD dst, regD_low src) %{
7462   effect(DEF dst, USE src);
7463   size(4);
7464   format %{ "FSITOD  $dst,$src" %}
7465   ins_encode %{
7466     __ fsitod($dst$$FloatRegister, $src$$FloatRegister->successor());
7467   %}
7468   ins_pipe(fcvtLHi2D);
7469 %}
7470 
7471 // Add float double precision
7472 instruct addD_regD_regD(regD dst, regD src1, regD src2) %{
7473   effect(DEF dst, USE src1, USE src2);
7474   size(4);
7475   format %{ "FADDD  $dst,$src1,$src2" %}
7476   ins_encode %{
7477     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
7478   %}
7479   ins_pipe(faddD_reg_reg);
7480 %}
7481 
7482 // Sub float double precision
7483 instruct subD_regD_regD(regD dst, regD src1, regD src2) %{
7484   effect(DEF dst, USE src1, USE src2);
7485   size(4);
7486   format %{ "FSUBD  $dst,$src1,$src2" %}
7487   ins_encode %{
7488     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
7489   %}
7490   ins_pipe(faddD_reg_reg);
7491 %}
7492 
7493 // Mul float double precision
7494 instruct mulD_regD_regD(regD dst, regD src1, regD src2) %{
7495   effect(DEF dst, USE src1, USE src2);
7496   size(4);
7497   format %{ "FMULD  $dst,$src1,$src2" %}
7498   ins_encode %{
7499     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
7500   %}
7501   ins_pipe(fmulD_reg_reg);
7502 %}
7503 
7504 instruct regL_to_regD(regD dst, iRegL src) %{
7505   // No match rule to avoid chain rule match.
7506   effect(DEF dst, USE src);
7507   ins_cost(MEMORY_REF_COST);
7508   size(4);
7509   format %{ "FMDRR   $dst,$src\t! regL to regD" %}
7510   ins_encode %{
7511     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
7512   %}
7513   ins_pipe(ialu_reg_reg); // FIXME
7514 %}
7515 
7516 instruct regI_regI_to_regD(regD dst, iRegI src1, iRegI src2) %{
7517   // No match rule to avoid chain rule match.
7518   effect(DEF dst, USE src1, USE src2);
7519   ins_cost(MEMORY_REF_COST);
7520   size(4);
7521   format %{ "FMDRR   $dst,$src1,$src2\t! regI,regI to regD" %}
7522   ins_encode %{
7523     __ fmdrr($dst$$FloatRegister, $src1$$Register, $src2$$Register);
7524   %}
7525   ins_pipe(ialu_reg_reg); // FIXME
7526 %}
7527 
7528 instruct convL2D_reg_slow_fxtof(regD dst, iRegL src) %{
7529   match(Set dst (ConvL2D src));
7530   ins_cost(DEFAULT_COST*8 + MEMORY_REF_COST*6); // FIXME
7531 
7532   expand %{
7533     regD_low   tmpsrc;
7534     iRegI      ix43300000;
7535     iRegI      ix41f00000;
7536     iRegI      ix0;
7537     regD_low   dx43300000;
7538     regD       dx41f00000;
7539     regD       tmp1;
7540     regD_low   tmp2;
7541     regD       tmp3;
7542     regD       tmp4;
7543 
7544     regL_to_regD(tmpsrc, src);
7545 
7546     loadConI_x43300000(ix43300000);
7547     loadConI_x41f00000(ix41f00000);
7548     loadConI_x0(ix0);
7549 
7550     regI_regI_to_regD(dx43300000, ix0, ix43300000);
7551     regI_regI_to_regD(dx41f00000, ix0, ix41f00000);
7552 
7553     convI2D_regDHi_regD(tmp1, tmpsrc);
7554     regDHi_regDLo_to_regD(tmp2, dx43300000, tmpsrc);
7555     subD_regD_regD(tmp3, tmp2, dx43300000);
7556     mulD_regD_regD(tmp4, tmp1, dx41f00000);
7557     addD_regD_regD(dst, tmp3, tmp4);
7558   %}
7559 %}
7560 
7561 instruct convL2I_reg(iRegI dst, iRegL src) %{
7562   match(Set dst (ConvL2I src));
7563   size(4);
7564   format %{ "MOV    $dst,$src.lo\t! long->int" %}
7565   ins_encode %{
7566     __ mov($dst$$Register, $src$$Register);
7567   %}
7568   ins_pipe(ialu_move_reg_I_to_L);
7569 %}
7570 
7571 // Register Shift Right Immediate
7572 instruct shrL_reg_imm6_L2I(iRegI dst, iRegL src, immI_32_63 cnt) %{
7573   match(Set dst (ConvL2I (RShiftL src cnt)));
7574   size(4);
7575   format %{ "ASR    $dst,$src.hi,($cnt - 32)\t! long->int or mov if $cnt==32" %}
7576   ins_encode %{
7577     if ($cnt$$constant == 32) {
7578       __ mov($dst$$Register, $src$$Register->successor());
7579     } else {
7580       __ mov($dst$$Register, AsmOperand($src$$Register->successor(), asr, $cnt$$constant - 32));
7581     }
7582   %}
7583   ins_pipe(ialu_reg_imm);
7584 %}
7585 
7586 
7587 //----------Control Flow Instructions------------------------------------------
7588 // Compare Instructions
7589 // Compare Integers
7590 instruct compI_iReg(flagsReg icc, iRegI op1, iRegI op2) %{
7591   match(Set icc (CmpI op1 op2));
7592   effect( DEF icc, USE op1, USE op2 );
7593 
7594   size(4);
7595   format %{ "cmp_32 $op1,$op2\t! int" %}
7596   ins_encode %{
7597     __ cmp_32($op1$$Register, $op2$$Register);
7598   %}
7599   ins_pipe(ialu_cconly_reg_reg);
7600 %}
7601 
7602 #ifdef _LP64
7603 // Compare compressed pointers
7604 instruct compN_reg2(flagsRegU icc, iRegN op1, iRegN op2) %{
7605   match(Set icc (CmpN op1 op2));
7606   effect( DEF icc, USE op1, USE op2 );
7607 
7608   size(4);
7609   format %{ "cmp_32 $op1,$op2\t! int" %}
7610   ins_encode %{
7611     __ cmp_32($op1$$Register, $op2$$Register);
7612   %}
7613   ins_pipe(ialu_cconly_reg_reg);
7614 %}
7615 #endif
7616 
7617 instruct compU_iReg(flagsRegU icc, iRegI op1, iRegI op2) %{
7618   match(Set icc (CmpU op1 op2));
7619 
7620   size(4);
7621   format %{ "cmp_32 $op1,$op2\t! unsigned int" %}
7622   ins_encode %{
7623     __ cmp_32($op1$$Register, $op2$$Register);
7624   %}
7625   ins_pipe(ialu_cconly_reg_reg);
7626 %}
7627 
7628 instruct compI_iReg_immneg(flagsReg icc, iRegI op1, aimmIneg op2) %{
7629   match(Set icc (CmpI op1 op2));
7630   effect( DEF icc, USE op1 );
7631 
7632   size(4);
7633   format %{ "cmn_32 $op1,-$op2\t! int" %}
7634   ins_encode %{
7635     __ cmn_32($op1$$Register, -$op2$$constant);
7636   %}
7637   ins_pipe(ialu_cconly_reg_imm);
7638 %}
7639 
7640 instruct compI_iReg_imm(flagsReg icc, iRegI op1, aimmI op2) %{
7641   match(Set icc (CmpI op1 op2));
7642   effect( DEF icc, USE op1 );
7643 
7644   size(4);
7645   format %{ "cmp_32 $op1,$op2\t! int" %}
7646   ins_encode %{
7647     __ cmp_32($op1$$Register, $op2$$constant);
7648   %}
7649   ins_pipe(ialu_cconly_reg_imm);
7650 %}
7651 
7652 instruct testI_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immI0 zero ) %{
7653   match(Set icc (CmpI (AndI op1 op2) zero));
7654   size(4);
7655   format %{ "tst_32 $op2,$op1" %}
7656 
7657   ins_encode %{
7658     __ tst_32($op1$$Register, $op2$$Register);
7659   %}
7660   ins_pipe(ialu_cconly_reg_reg_zero);
7661 %}
7662 
7663 instruct testshlI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
7664   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
7665   size(4);
7666   format %{ "TST   $op2,$op1<<$op3" %}
7667 
7668   ins_encode %{
7669     __ tst($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$Register));
7670   %}
7671   ins_pipe(ialu_cconly_reg_reg_zero);
7672 %}
7673 
7674 instruct testshlI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
7675   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
7676   size(4);
7677   format %{ "tst_32 $op2,$op1<<$op3" %}
7678 
7679   ins_encode %{
7680     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$constant));
7681   %}
7682   ins_pipe(ialu_cconly_reg_reg_zero);
7683 %}
7684 
7685 instruct testsarI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
7686   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
7687   size(4);
7688   format %{ "TST   $op2,$op1<<$op3" %}
7689 
7690   ins_encode %{
7691     __ tst($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$Register));
7692   %}
7693   ins_pipe(ialu_cconly_reg_reg_zero);
7694 %}
7695 
7696 instruct testsarI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
7697   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
7698   size(4);
7699   format %{ "tst_32 $op2,$op1<<$op3" %}
7700 
7701   ins_encode %{
7702     __ tst_32($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$constant));
7703   %}
7704   ins_pipe(ialu_cconly_reg_reg_zero);
7705 %}
7706 
7707 instruct testshrI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
7708   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
7709   size(4);
7710   format %{ "TST   $op2,$op1<<$op3" %}
7711 
7712   ins_encode %{
7713     __ tst($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$Register));
7714   %}
7715   ins_pipe(ialu_cconly_reg_reg_zero);
7716 %}
7717 
7718 instruct testshrI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
7719   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
7720   size(4);
7721   format %{ "tst_32 $op2,$op1<<$op3" %}
7722 
7723   ins_encode %{
7724     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$constant));
7725   %}
7726   ins_pipe(ialu_cconly_reg_reg_zero);
7727 %}
7728 
7729 instruct testI_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, limmI op2, immI0 zero ) %{
7730   match(Set icc (CmpI (AndI op1 op2) zero));
7731   size(4);
7732   format %{ "tst_32 $op2,$op1" %}
7733 
7734   ins_encode %{
7735     __ tst_32($op1$$Register, $op2$$constant);
7736   %}
7737   ins_pipe(ialu_cconly_reg_imm_zero);
7738 %}
7739 
7740 instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
7741   match(Set xcc (CmpL op1 op2));
7742   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
7743 
7744   size(8);
7745   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! long\n\t"
7746             "SBCS    $tmp,$op1.hi,$op2.hi" %}
7747   ins_encode %{
7748     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
7749     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
7750   %}
7751   ins_pipe(ialu_cconly_reg_reg);
7752 %}
7753 
7754 instruct compUL_reg_reg_LTGE(flagsRegUL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
7755   match(Set xcc (CmpUL op1 op2));
7756   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
7757 
7758   size(8);
7759   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! unsigned long\n\t"
7760             "SBCS    $tmp,$op1.hi,$op2.hi" %}
7761   ins_encode %{
7762     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
7763     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
7764   %}
7765   ins_pipe(ialu_cconly_reg_reg);
7766 %}
7767 
7768 instruct compL_reg_reg_EQNE(flagsRegL_EQNE xcc, iRegL op1, iRegL op2) %{
7769   match(Set xcc (CmpL op1 op2));
7770   effect( DEF xcc, USE op1, USE op2 );
7771 
7772   size(8);
7773   format %{ "TEQ    $op1.hi,$op2.hi\t\t! long\n\t"
7774             "TEQ.eq $op1.lo,$op2.lo" %}
7775   ins_encode %{
7776     __ teq($op1$$Register->successor(), $op2$$Register->successor());
7777     __ teq($op1$$Register, $op2$$Register, eq);
7778   %}
7779   ins_pipe(ialu_cconly_reg_reg);
7780 %}
7781 
7782 instruct compL_reg_reg_LEGT(flagsRegL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
7783   match(Set xcc (CmpL op1 op2));
7784   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
7785 
7786   size(8);
7787   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! long\n\t"
7788             "SBCS    $tmp,$op2.hi,$op1.hi" %}
7789   ins_encode %{
7790     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
7791     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
7792   %}
7793   ins_pipe(ialu_cconly_reg_reg);
7794 %}
7795 
7796 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7797 // (hi($con$$constant), lo($con$$constant)) becomes
7798 instruct compL_reg_con_LTGE(flagsRegL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
7799   match(Set xcc (CmpL op1 con));
7800   effect( DEF xcc, USE op1, USE con, TEMP tmp );
7801 
7802   size(8);
7803   format %{ "SUBS    $tmp,$op1.low,$con\t\t! long\n\t"
7804             "SBCS    $tmp,$op1.hi,0" %}
7805   ins_encode %{
7806     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
7807     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
7808   %}
7809 
7810   ins_pipe(ialu_cconly_reg_reg);
7811 %}
7812 
7813 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7814 // (hi($con$$constant), lo($con$$constant)) becomes
7815 instruct compL_reg_con_EQNE(flagsRegL_EQNE xcc, iRegL op1, immLlowRot con) %{
7816   match(Set xcc (CmpL op1 con));
7817   effect( DEF xcc, USE op1, USE con );
7818 
7819   size(8);
7820   format %{ "TEQ    $op1.hi,0\t\t! long\n\t"
7821             "TEQ.eq $op1.lo,$con" %}
7822   ins_encode %{
7823     __ teq($op1$$Register->successor(), 0);
7824     __ teq($op1$$Register, $con$$constant, eq);
7825   %}
7826 
7827   ins_pipe(ialu_cconly_reg_reg);
7828 %}
7829 
7830 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7831 // (hi($con$$constant), lo($con$$constant)) becomes
7832 instruct compL_reg_con_LEGT(flagsRegL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
7833   match(Set xcc (CmpL op1 con));
7834   effect( DEF xcc, USE op1, USE con, TEMP tmp );
7835 
7836   size(8);
7837   format %{ "RSBS    $tmp,$op1.low,$con\t\t! long\n\t"
7838             "RSCS    $tmp,$op1.hi,0" %}
7839   ins_encode %{
7840     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
7841     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
7842   %}
7843 
7844   ins_pipe(ialu_cconly_reg_reg);
7845 %}
7846 
7847 instruct compUL_reg_reg_EQNE(flagsRegUL_EQNE xcc, iRegL op1, iRegL op2) %{
7848   match(Set xcc (CmpUL op1 op2));
7849   effect(DEF xcc, USE op1, USE op2);
7850 
7851   size(8);
7852   format %{ "TEQ    $op1.hi,$op2.hi\t\t! unsigned long\n\t"
7853             "TEQ.eq $op1.lo,$op2.lo" %}
7854   ins_encode %{
7855     __ teq($op1$$Register->successor(), $op2$$Register->successor());
7856     __ teq($op1$$Register, $op2$$Register, eq);
7857   %}
7858   ins_pipe(ialu_cconly_reg_reg);
7859 %}
7860 
7861 instruct compUL_reg_reg_LEGT(flagsRegUL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
7862   match(Set xcc (CmpUL op1 op2));
7863   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
7864 
7865   size(8);
7866   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! unsigned long\n\t"
7867             "SBCS    $tmp,$op2.hi,$op1.hi" %}
7868   ins_encode %{
7869     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
7870     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
7871   %}
7872   ins_pipe(ialu_cconly_reg_reg);
7873 %}
7874 
7875 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7876 // (hi($con$$constant), lo($con$$constant)) becomes
7877 instruct compUL_reg_con_LTGE(flagsRegUL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
7878   match(Set xcc (CmpUL op1 con));
7879   effect(DEF xcc, USE op1, USE con, TEMP tmp);
7880 
7881   size(8);
7882   format %{ "SUBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
7883             "SBCS    $tmp,$op1.hi,0" %}
7884   ins_encode %{
7885     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
7886     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
7887   %}
7888 
7889   ins_pipe(ialu_cconly_reg_reg);
7890 %}
7891 
7892 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7893 // (hi($con$$constant), lo($con$$constant)) becomes
7894 instruct compUL_reg_con_EQNE(flagsRegUL_EQNE xcc, iRegL op1, immLlowRot con) %{
7895   match(Set xcc (CmpUL op1 con));
7896   effect(DEF xcc, USE op1, USE con);
7897 
7898   size(8);
7899   format %{ "TEQ    $op1.hi,0\t\t! unsigned long\n\t"
7900             "TEQ.eq $op1.lo,$con" %}
7901   ins_encode %{
7902     __ teq($op1$$Register->successor(), 0);
7903     __ teq($op1$$Register, $con$$constant, eq);
7904   %}
7905 
7906   ins_pipe(ialu_cconly_reg_reg);
7907 %}
7908 
7909 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7910 // (hi($con$$constant), lo($con$$constant)) becomes
7911 instruct compUL_reg_con_LEGT(flagsRegUL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
7912   match(Set xcc (CmpUL op1 con));
7913   effect(DEF xcc, USE op1, USE con, TEMP tmp);
7914 
7915   size(8);
7916   format %{ "RSBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
7917             "RSCS    $tmp,$op1.hi,0" %}
7918   ins_encode %{
7919     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
7920     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
7921   %}
7922 
7923   ins_pipe(ialu_cconly_reg_reg);
7924 %}
7925 
7926 /* instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ */
7927 /*   match(Set xcc (CmpL (AndL op1 op2) zero)); */
7928 /*   ins_encode %{ */
7929 /*     __ stop("testL_reg_reg unimplemented"); */
7930 /*   %} */
7931 /*   ins_pipe(ialu_cconly_reg_reg); */
7932 /* %} */
7933 
7934 /* // useful for checking the alignment of a pointer: */
7935 /* instruct testL_reg_con(flagsRegL xcc, iRegL op1, immLlowRot con, immL0 zero) %{ */
7936 /*   match(Set xcc (CmpL (AndL op1 con) zero)); */
7937 /*   ins_encode %{ */
7938 /*     __ stop("testL_reg_con unimplemented"); */
7939 /*   %} */
7940 /*   ins_pipe(ialu_cconly_reg_reg); */
7941 /* %} */
7942 
7943 instruct compU_iReg_imm(flagsRegU icc, iRegI op1, aimmU31 op2 ) %{
7944   match(Set icc (CmpU op1 op2));
7945 
7946   size(4);
7947   format %{ "cmp_32 $op1,$op2\t! unsigned" %}
7948   ins_encode %{
7949     __ cmp_32($op1$$Register, $op2$$constant);
7950   %}
7951   ins_pipe(ialu_cconly_reg_imm);
7952 %}
7953 
7954 // Compare Pointers
7955 instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{
7956   match(Set pcc (CmpP op1 op2));
7957 
7958   size(4);
7959   format %{ "CMP    $op1,$op2\t! ptr" %}
7960   ins_encode %{
7961     __ cmp($op1$$Register, $op2$$Register);
7962   %}
7963   ins_pipe(ialu_cconly_reg_reg);
7964 %}
7965 
7966 instruct compP_iRegP_imm(flagsRegP pcc, iRegP op1, aimmP op2 ) %{
7967   match(Set pcc (CmpP op1 op2));
7968 
7969   size(4);
7970   format %{ "CMP    $op1,$op2\t! ptr" %}
7971   ins_encode %{
7972     assert($op2$$constant == 0 || _opnds[2]->constant_reloc() == relocInfo::none, "reloc in cmp?");
7973     __ cmp($op1$$Register, $op2$$constant);
7974   %}
7975   ins_pipe(ialu_cconly_reg_imm);
7976 %}
7977 
7978 //----------Max and Min--------------------------------------------------------
7979 // Min Instructions
7980 // Conditional move for min
7981 instruct cmovI_reg_lt( iRegI op2, iRegI op1, flagsReg icc ) %{
7982   effect( USE_DEF op2, USE op1, USE icc );
7983 
7984   size(4);
7985   format %{ "MOV.lt  $op2,$op1\t! min" %}
7986   ins_encode %{
7987     __ mov($op2$$Register, $op1$$Register, lt);
7988   %}
7989   ins_pipe(ialu_reg_flags);
7990 %}
7991 
7992 // Min Register with Register.
7993 instruct minI_eReg(iRegI op1, iRegI op2) %{
7994   match(Set op2 (MinI op1 op2));
7995   ins_cost(DEFAULT_COST*2);
7996   expand %{
7997     flagsReg icc;
7998     compI_iReg(icc,op1,op2);
7999     cmovI_reg_lt(op2,op1,icc);
8000   %}
8001 %}
8002 
8003 // Max Instructions
8004 // Conditional move for max
8005 instruct cmovI_reg_gt( iRegI op2, iRegI op1, flagsReg icc ) %{
8006   effect( USE_DEF op2, USE op1, USE icc );
8007   format %{ "MOV.gt  $op2,$op1\t! max" %}
8008   ins_encode %{
8009     __ mov($op2$$Register, $op1$$Register, gt);
8010   %}
8011   ins_pipe(ialu_reg_flags);
8012 %}
8013 
8014 // Max Register with Register
8015 instruct maxI_eReg(iRegI op1, iRegI op2) %{
8016   match(Set op2 (MaxI op1 op2));
8017   ins_cost(DEFAULT_COST*2);
8018   expand %{
8019     flagsReg icc;
8020     compI_iReg(icc,op1,op2);
8021     cmovI_reg_gt(op2,op1,icc);
8022   %}
8023 %}
8024 
8025 
8026 //----------Float Compares----------------------------------------------------
8027 // Compare floating, generate condition code
8028 instruct cmpF_cc(flagsRegF fcc, flagsReg icc, regF src1, regF src2) %{
8029   match(Set icc (CmpF src1 src2));
8030   effect(KILL fcc);
8031 
8032   size(8);
8033   format %{ "FCMPs  $src1,$src2\n\t"
8034             "FMSTAT" %}
8035   ins_encode %{
8036     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
8037     __ fmstat();
8038   %}
8039   ins_pipe(faddF_fcc_reg_reg_zero);
8040 %}
8041 
8042 instruct cmpF0_cc(flagsRegF fcc, flagsReg icc, regF src1, immF0 src2) %{
8043   match(Set icc (CmpF src1 src2));
8044   effect(KILL fcc);
8045 
8046   size(8);
8047   format %{ "FCMPs  $src1,$src2\n\t"
8048             "FMSTAT" %}
8049   ins_encode %{
8050     __ fcmpzs($src1$$FloatRegister);
8051     __ fmstat();
8052   %}
8053   ins_pipe(faddF_fcc_reg_reg_zero);
8054 %}
8055 
8056 instruct cmpD_cc(flagsRegF fcc, flagsReg icc, regD src1, regD src2) %{
8057   match(Set icc (CmpD src1 src2));
8058   effect(KILL fcc);
8059 
8060   size(8);
8061   format %{ "FCMPd  $src1,$src2 \n\t"
8062             "FMSTAT" %}
8063   ins_encode %{
8064     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
8065     __ fmstat();
8066   %}
8067   ins_pipe(faddD_fcc_reg_reg_zero);
8068 %}
8069 
8070 instruct cmpD0_cc(flagsRegF fcc, flagsReg icc, regD src1, immD0 src2) %{
8071   match(Set icc (CmpD src1 src2));
8072   effect(KILL fcc);
8073 
8074   size(8);
8075   format %{ "FCMPZd  $src1,$src2 \n\t"
8076             "FMSTAT" %}
8077   ins_encode %{
8078     __ fcmpzd($src1$$FloatRegister);
8079     __ fmstat();
8080   %}
8081   ins_pipe(faddD_fcc_reg_reg_zero);
8082 %}
8083 
8084 // Compare floating, generate -1,0,1
8085 instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsRegF fcc) %{
8086   match(Set dst (CmpF3 src1 src2));
8087   effect(KILL fcc);
8088   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
8089   size(20);
8090   // same number of instructions as code using conditional moves but
8091   // doesn't kill integer condition register
8092   format %{ "FCMPs  $dst,$src1,$src2 \n\t"
8093             "VMRS   $dst, FPSCR \n\t"
8094             "OR     $dst, $dst, 0x08000000 \n\t"
8095             "EOR    $dst, $dst, $dst << 3 \n\t"
8096             "MOV    $dst, $dst >> 30" %}
8097   ins_encode %{
8098     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
8099     __ floating_cmp($dst$$Register);
8100   %}
8101   ins_pipe( floating_cmp );
8102 %}
8103 
8104 instruct cmpF0_reg(iRegI dst, regF src1, immF0 src2, flagsRegF fcc) %{
8105   match(Set dst (CmpF3 src1 src2));
8106   effect(KILL fcc);
8107   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
8108   size(20);
8109   // same number of instructions as code using conditional moves but
8110   // doesn't kill integer condition register
8111   format %{ "FCMPZs $dst,$src1,$src2 \n\t"
8112             "VMRS   $dst, FPSCR \n\t"
8113             "OR     $dst, $dst, 0x08000000 \n\t"
8114             "EOR    $dst, $dst, $dst << 3 \n\t"
8115             "MOV    $dst, $dst >> 30" %}
8116   ins_encode %{
8117     __ fcmpzs($src1$$FloatRegister);
8118     __ floating_cmp($dst$$Register);
8119   %}
8120   ins_pipe( floating_cmp );
8121 %}
8122 
8123 instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsRegF fcc) %{
8124   match(Set dst (CmpD3 src1 src2));
8125   effect(KILL fcc);
8126   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
8127   size(20);
8128   // same number of instructions as code using conditional moves but
8129   // doesn't kill integer condition register
8130   format %{ "FCMPd  $dst,$src1,$src2 \n\t"
8131             "VMRS   $dst, FPSCR \n\t"
8132             "OR     $dst, $dst, 0x08000000 \n\t"
8133             "EOR    $dst, $dst, $dst << 3 \n\t"
8134             "MOV    $dst, $dst >> 30" %}
8135   ins_encode %{
8136     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
8137     __ floating_cmp($dst$$Register);
8138   %}
8139   ins_pipe( floating_cmp );
8140 %}
8141 
8142 instruct cmpD0_reg(iRegI dst, regD src1, immD0 src2, flagsRegF fcc) %{
8143   match(Set dst (CmpD3 src1 src2));
8144   effect(KILL fcc);
8145   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
8146   size(20);
8147   // same number of instructions as code using conditional moves but
8148   // doesn't kill integer condition register
8149   format %{ "FCMPZd $dst,$src1,$src2 \n\t"
8150             "VMRS   $dst, FPSCR \n\t"
8151             "OR     $dst, $dst, 0x08000000 \n\t"
8152             "EOR    $dst, $dst, $dst << 3 \n\t"
8153             "MOV    $dst, $dst >> 30" %}
8154   ins_encode %{
8155     __ fcmpzd($src1$$FloatRegister);
8156     __ floating_cmp($dst$$Register);
8157   %}
8158   ins_pipe( floating_cmp );
8159 %}
8160 
8161 //----------Branches---------------------------------------------------------
8162 // Jump
8163 // (compare 'operand indIndex' and 'instruct addP_reg_reg' above)
8164 // FIXME
8165 instruct jumpXtnd(iRegX switch_val, iRegP tmp) %{
8166   match(Jump switch_val);
8167   effect(TEMP tmp);
8168   ins_cost(350);
8169   format %{  "ADD    $tmp, $constanttablebase, $switch_val\n\t"
8170              "LDR    $tmp,[$tmp + $constantoffset]\n\t"
8171              "BX     $tmp" %}
8172   size(20);
8173   ins_encode %{
8174     Register table_reg;
8175     Register label_reg = $tmp$$Register;
8176     if (constant_offset() == 0) {
8177       table_reg = $constanttablebase;
8178       __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
8179     } else {
8180       table_reg = $tmp$$Register;
8181       int offset = $constantoffset;
8182       if (is_memoryP(offset)) {
8183         __ add(table_reg, $constanttablebase, $switch_val$$Register);
8184         __ ldr(label_reg, Address(table_reg, offset));
8185       } else {
8186         __ mov_slow(table_reg, $constantoffset);
8187         __ add(table_reg, $constanttablebase, table_reg);
8188         __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
8189       }
8190     }
8191     __ jump(label_reg); // ldr + b better than ldr to PC for branch predictor?
8192     //    __ ldr(PC, Address($table$$Register, $switch_val$$Register));
8193   %}
8194   ins_pipe(ialu_reg_reg);
8195 %}
8196 
8197 // // Direct Branch.
8198 instruct branch(label labl) %{
8199   match(Goto);
8200   effect(USE labl);
8201 
8202   size(4);
8203   ins_cost(BRANCH_COST);
8204   format %{ "B     $labl" %}
8205   ins_encode %{
8206     __ b(*($labl$$label));
8207   %}
8208   ins_pipe(br);
8209 %}
8210 
8211 // Conditional Direct Branch
8212 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{
8213   match(If cmp icc);
8214   effect(USE labl);
8215 
8216   size(4);
8217   ins_cost(BRANCH_COST);
8218   format %{ "B$cmp   $icc,$labl" %}
8219   ins_encode %{
8220     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8221   %}
8222   ins_pipe(br_cc);
8223 %}
8224 
8225 #ifdef ARM
8226 instruct branchCon_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, label labl) %{
8227   match(If cmp icc);
8228   effect(USE labl);
8229   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);
8230 
8231   size(4);
8232   ins_cost(BRANCH_COST);
8233   format %{ "B$cmp   $icc,$labl" %}
8234   ins_encode %{
8235     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8236   %}
8237   ins_pipe(br_cc);
8238 %}
8239 #endif
8240 
8241 
8242 instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{
8243   match(If cmp icc);
8244   effect(USE labl);
8245 
8246   size(4);
8247   ins_cost(BRANCH_COST);
8248   format %{ "B$cmp  $icc,$labl" %}
8249   ins_encode %{
8250     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8251   %}
8252   ins_pipe(br_cc);
8253 %}
8254 
8255 instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{
8256   match(If cmp pcc);
8257   effect(USE labl);
8258 
8259   size(4);
8260   ins_cost(BRANCH_COST);
8261   format %{ "B$cmp  $pcc,$labl" %}
8262   ins_encode %{
8263     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8264   %}
8265   ins_pipe(br_cc);
8266 %}
8267 
8268 instruct branchConL_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, label labl) %{
8269   match(If cmp xcc);
8270   effect(USE labl);
8271   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8272 
8273   size(4);
8274   ins_cost(BRANCH_COST);
8275   format %{ "B$cmp  $xcc,$labl" %}
8276   ins_encode %{
8277     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8278   %}
8279   ins_pipe(br_cc);
8280 %}
8281 
8282 instruct branchConL_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, label labl) %{
8283   match(If cmp xcc);
8284   effect(USE labl);
8285   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8286 
8287   size(4);
8288   ins_cost(BRANCH_COST);
8289   format %{ "B$cmp  $xcc,$labl" %}
8290   ins_encode %{
8291     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8292   %}
8293   ins_pipe(br_cc);
8294 %}
8295 
8296 instruct branchConL_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, label labl) %{
8297   match(If cmp xcc);
8298   effect(USE labl);
8299   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le );
8300 
8301   size(4);
8302   ins_cost(BRANCH_COST);
8303   format %{ "B$cmp  $xcc,$labl" %}
8304   ins_encode %{
8305     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8306   %}
8307   ins_pipe(br_cc);
8308 %}
8309 
8310 instruct branchConUL_LTGE(cmpOpUL cmp, flagsRegUL_LTGE xcc, label labl) %{
8311   match(If cmp xcc);
8312   effect(USE labl);
8313   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
8314 
8315   size(4);
8316   ins_cost(BRANCH_COST);
8317   format %{ "B$cmp  $xcc,$labl" %}
8318   ins_encode %{
8319     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8320   %}
8321   ins_pipe(br_cc);
8322 %}
8323 
8324 instruct branchConUL_EQNE(cmpOpUL cmp, flagsRegUL_EQNE xcc, label labl) %{
8325   match(If cmp xcc);
8326   effect(USE labl);
8327   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
8328 
8329   size(4);
8330   ins_cost(BRANCH_COST);
8331   format %{ "B$cmp  $xcc,$labl" %}
8332   ins_encode %{
8333     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8334   %}
8335   ins_pipe(br_cc);
8336 %}
8337 
8338 instruct branchConUL_LEGT(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, label labl) %{
8339   match(If cmp xcc);
8340   effect(USE labl);
8341   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le);
8342 
8343   size(4);
8344   ins_cost(BRANCH_COST);
8345   format %{ "B$cmp  $xcc,$labl" %}
8346   ins_encode %{
8347     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8348   %}
8349   ins_pipe(br_cc);
8350 %}
8351 
8352 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
8353   match(CountedLoopEnd cmp icc);
8354   effect(USE labl);
8355 
8356   size(4);
8357   ins_cost(BRANCH_COST);
8358   format %{ "B$cmp   $icc,$labl\t! Loop end" %}
8359   ins_encode %{
8360     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8361   %}
8362   ins_pipe(br_cc);
8363 %}
8364 
8365 // instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{
8366 //   match(CountedLoopEnd cmp icc);
8367 //   ins_pipe(br_cc);
8368 // %}
8369 
8370 // ============================================================================
8371 // Long Compare
8372 //
8373 // Currently we hold longs in 2 registers.  Comparing such values efficiently
8374 // is tricky.  The flavor of compare used depends on whether we are testing
8375 // for LT, LE, or EQ.  For a simple LT test we can check just the sign bit.
8376 // The GE test is the negated LT test.  The LE test can be had by commuting
8377 // the operands (yielding a GE test) and then negating; negate again for the
8378 // GT test.  The EQ test is done by ORcc'ing the high and low halves, and the
8379 // NE test is negated from that.
8380 
8381 // Due to a shortcoming in the ADLC, it mixes up expressions like:
8382 // (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)).  Note the
8383 // difference between 'Y' and '0L'.  The tree-matches for the CmpI sections
8384 // are collapsed internally in the ADLC's dfa-gen code.  The match for
8385 // (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the
8386 // foo match ends up with the wrong leaf.  One fix is to not match both
8387 // reg-reg and reg-zero forms of long-compare.  This is unfortunate because
8388 // both forms beat the trinary form of long-compare and both are very useful
8389 // on Intel which has so few registers.
8390 
8391 // instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{
8392 //   match(If cmp xcc);
8393 //   ins_pipe(br_cc);
8394 // %}
8395 
8396 // Manifest a CmpL3 result in an integer register.  Very painful.
8397 // This is the test to avoid.
8398 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
8399   match(Set dst (CmpL3 src1 src2) );
8400   effect( KILL ccr );
8401   ins_cost(6*DEFAULT_COST); // FIXME
8402   size(32);
8403   format %{
8404       "CMP    $src1.hi, $src2.hi\t\t! long\n"
8405     "\tMOV.gt $dst, 1\n"
8406     "\tmvn.lt $dst, 0\n"
8407     "\tB.ne   done\n"
8408     "\tSUBS   $dst, $src1.lo, $src2.lo\n"
8409     "\tMOV.hi $dst, 1\n"
8410     "\tmvn.lo $dst, 0\n"
8411     "done:"     %}
8412   ins_encode %{
8413     Label done;
8414     __ cmp($src1$$Register->successor(), $src2$$Register->successor());
8415     __ mov($dst$$Register, 1, gt);
8416     __ mvn($dst$$Register, 0, lt);
8417     __ b(done, ne);
8418     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
8419     __ mov($dst$$Register, 1, hi);
8420     __ mvn($dst$$Register, 0, lo);
8421     __ bind(done);
8422   %}
8423   ins_pipe(cmpL_reg);
8424 %}
8425 
8426 // Conditional move
8427 instruct cmovLL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, iRegL src) %{
8428   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
8429   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8430 
8431   ins_cost(150);
8432   size(8);
8433   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
8434             "MOV$cmp  $dst,$src.hi" %}
8435   ins_encode %{
8436     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8437     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
8438   %}
8439   ins_pipe(ialu_reg);
8440 %}
8441 
8442 instruct cmovLL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, iRegL src) %{
8443   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
8444   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8445 
8446   ins_cost(150);
8447   size(8);
8448   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
8449             "MOV$cmp  $dst,$src.hi" %}
8450   ins_encode %{
8451     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8452     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
8453   %}
8454   ins_pipe(ialu_reg);
8455 %}
8456 
8457 instruct cmovLL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, iRegL src) %{
8458   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
8459   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8460 
8461   ins_cost(150);
8462   size(8);
8463   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
8464             "MOV$cmp  $dst,$src.hi" %}
8465   ins_encode %{
8466     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8467     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
8468   %}
8469   ins_pipe(ialu_reg);
8470 %}
8471 
8472 instruct cmovLL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, immL0 src) %{
8473   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
8474   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8475   ins_cost(140);
8476   size(8);
8477   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
8478             "MOV$cmp  $dst,0" %}
8479   ins_encode %{
8480     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
8481     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
8482   %}
8483   ins_pipe(ialu_imm);
8484 %}
8485 
8486 instruct cmovLL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, immL0 src) %{
8487   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
8488   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8489   ins_cost(140);
8490   size(8);
8491   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
8492             "MOV$cmp  $dst,0" %}
8493   ins_encode %{
8494     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
8495     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
8496   %}
8497   ins_pipe(ialu_imm);
8498 %}
8499 
8500 instruct cmovLL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, immL0 src) %{
8501   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
8502   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8503   ins_cost(140);
8504   size(8);
8505   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
8506             "MOV$cmp  $dst,0" %}
8507   ins_encode %{
8508     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
8509     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
8510   %}
8511   ins_pipe(ialu_imm);
8512 %}
8513 
8514 instruct cmovIL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, iRegI src) %{
8515   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
8516   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8517 
8518   ins_cost(150);
8519   size(4);
8520   format %{ "MOV$cmp  $dst,$src" %}
8521   ins_encode %{
8522     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8523   %}
8524   ins_pipe(ialu_reg);
8525 %}
8526 
8527 instruct cmovIL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, iRegI src) %{
8528   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
8529   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8530 
8531   ins_cost(150);
8532   size(4);
8533   format %{ "MOV$cmp  $dst,$src" %}
8534   ins_encode %{
8535     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8536   %}
8537   ins_pipe(ialu_reg);
8538 %}
8539 
8540 instruct cmovIL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, iRegI src) %{
8541   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
8542   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8543 
8544   ins_cost(150);
8545   size(4);
8546   format %{ "MOV$cmp  $dst,$src" %}
8547   ins_encode %{
8548     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8549   %}
8550   ins_pipe(ialu_reg);
8551 %}
8552 
8553 instruct cmovIL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immI16 src) %{
8554   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
8555   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8556 
8557   ins_cost(140);
8558   format %{ "MOVW$cmp  $dst,$src" %}
8559   ins_encode %{
8560     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
8561   %}
8562   ins_pipe(ialu_imm);
8563 %}
8564 
8565 instruct cmovIL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, immI16 src) %{
8566   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
8567   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8568 
8569   ins_cost(140);
8570   format %{ "MOVW$cmp  $dst,$src" %}
8571   ins_encode %{
8572     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
8573   %}
8574   ins_pipe(ialu_imm);
8575 %}
8576 
8577 instruct cmovIL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immI16 src) %{
8578   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
8579   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8580 
8581   ins_cost(140);
8582   format %{ "MOVW$cmp  $dst,$src" %}
8583   ins_encode %{
8584     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
8585   %}
8586   ins_pipe(ialu_imm);
8587 %}
8588 
8589 instruct cmovPL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, iRegP src) %{
8590   match(Set dst (CMoveP (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(150);
8594   size(4);
8595   format %{ "MOV$cmp  $dst,$src" %}
8596   ins_encode %{
8597     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8598   %}
8599   ins_pipe(ialu_reg);
8600 %}
8601 
8602 instruct cmovPL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, iRegP src) %{
8603   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
8604   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8605 
8606   ins_cost(150);
8607   size(4);
8608   format %{ "MOV$cmp  $dst,$src" %}
8609   ins_encode %{
8610     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8611   %}
8612   ins_pipe(ialu_reg);
8613 %}
8614 
8615 instruct cmovPL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, iRegP src) %{
8616   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
8617   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8618 
8619   ins_cost(150);
8620   size(4);
8621   format %{ "MOV$cmp  $dst,$src" %}
8622   ins_encode %{
8623     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8624   %}
8625   ins_pipe(ialu_reg);
8626 %}
8627 
8628 instruct cmovPL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, immP0 src) %{
8629   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
8630   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8631 
8632   ins_cost(140);
8633   format %{ "MOVW$cmp  $dst,$src" %}
8634   ins_encode %{
8635     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
8636   %}
8637   ins_pipe(ialu_imm);
8638 %}
8639 
8640 instruct cmovPL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, immP0 src) %{
8641   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
8642   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8643 
8644   ins_cost(140);
8645   format %{ "MOVW$cmp  $dst,$src" %}
8646   ins_encode %{
8647     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
8648   %}
8649   ins_pipe(ialu_imm);
8650 %}
8651 
8652 instruct cmovPL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, immP0 src) %{
8653   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
8654   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8655 
8656   ins_cost(140);
8657   format %{ "MOVW$cmp  $dst,$src" %}
8658   ins_encode %{
8659     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
8660   %}
8661   ins_pipe(ialu_imm);
8662 %}
8663 
8664 instruct cmovFL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regF dst, regF src) %{
8665   match(Set dst (CMoveF (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   ins_cost(150);
8668   size(4);
8669   format %{ "FCPYS$cmp $dst,$src" %}
8670   ins_encode %{
8671     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
8672   %}
8673   ins_pipe(int_conditional_float_move);
8674 %}
8675 
8676 instruct cmovFL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regF dst, regF src) %{
8677   match(Set dst (CMoveF (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   ins_cost(150);
8680   size(4);
8681   format %{ "FCPYS$cmp $dst,$src" %}
8682   ins_encode %{
8683     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
8684   %}
8685   ins_pipe(int_conditional_float_move);
8686 %}
8687 
8688 instruct cmovFL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regF dst, regF src) %{
8689   match(Set dst (CMoveF (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   ins_cost(150);
8692   size(4);
8693   format %{ "FCPYS$cmp $dst,$src" %}
8694   ins_encode %{
8695     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
8696   %}
8697   ins_pipe(int_conditional_float_move);
8698 %}
8699 
8700 instruct cmovDL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regD dst, regD src) %{
8701   match(Set dst (CMoveD (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 
8704   ins_cost(150);
8705   size(4);
8706   format %{ "FCPYD$cmp $dst,$src" %}
8707   ins_encode %{
8708     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
8709   %}
8710   ins_pipe(int_conditional_float_move);
8711 %}
8712 
8713 instruct cmovDL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regD dst, regD src) %{
8714   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
8715   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8716 
8717   ins_cost(150);
8718   size(4);
8719   format %{ "FCPYD$cmp $dst,$src" %}
8720   ins_encode %{
8721     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
8722   %}
8723   ins_pipe(int_conditional_float_move);
8724 %}
8725 
8726 instruct cmovDL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regD dst, regD src) %{
8727   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
8728   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8729 
8730   ins_cost(150);
8731   size(4);
8732   format %{ "FCPYD$cmp $dst,$src" %}
8733   ins_encode %{
8734     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
8735   %}
8736   ins_pipe(int_conditional_float_move);
8737 %}
8738 
8739 // ============================================================================
8740 // Safepoint Instruction
8741 // rather than KILL R12, it would be better to use any reg as
8742 // TEMP. Can't do that at this point because it crashes the compiler
8743 instruct safePoint_poll(iRegP poll, R12RegI tmp, flagsReg icc) %{
8744   match(SafePoint poll);
8745   effect(USE poll, KILL tmp, KILL icc);
8746 
8747   size(4);
8748   format %{ "LDR   $tmp,[$poll]\t! Safepoint: poll for GC" %}
8749   ins_encode %{
8750     __ relocate(relocInfo::poll_type);
8751     __ ldr($tmp$$Register, Address($poll$$Register));
8752   %}
8753   ins_pipe(loadPollP);
8754 %}
8755 
8756 
8757 // ============================================================================
8758 // Call Instructions
8759 // Call Java Static Instruction
8760 instruct CallStaticJavaDirect( method meth ) %{
8761   match(CallStaticJava);
8762   predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke());
8763   effect(USE meth);
8764 
8765   ins_cost(CALL_COST);
8766   format %{ "CALL,static ==> " %}
8767   ins_encode( Java_Static_Call( meth ), call_epilog );
8768   ins_pipe(simple_call);
8769 %}
8770 
8771 // Call Java Static Instruction (method handle version)
8772 instruct CallStaticJavaHandle( method meth ) %{
8773   match(CallStaticJava);
8774   predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke());
8775   effect(USE meth);
8776   // FP is saved by all callees (for interpreter stack correction).
8777   // We use it here for a similar purpose, in {preserve,restore}_FP.
8778 
8779   ins_cost(CALL_COST);
8780   format %{ "CALL,static/MethodHandle ==> " %}
8781   ins_encode( preserve_SP, Java_Static_Call( meth ), restore_SP, call_epilog );
8782   ins_pipe(simple_call);
8783 %}
8784 
8785 // Call Java Dynamic Instruction
8786 instruct CallDynamicJavaDirect( method meth ) %{
8787   match(CallDynamicJava);
8788   effect(USE meth);
8789 
8790   ins_cost(CALL_COST);
8791   format %{ "MOV_OOP    (empty),R_R8\n\t"
8792             "CALL,dynamic  ; NOP ==> " %}
8793   ins_encode( Java_Dynamic_Call( meth ), call_epilog );
8794   ins_pipe(call);
8795 %}
8796 
8797 // Call Runtime Instruction
8798 instruct CallRuntimeDirect(method meth) %{
8799   match(CallRuntime);
8800   effect(USE meth);
8801   ins_cost(CALL_COST);
8802   format %{ "CALL,runtime" %}
8803   ins_encode( Java_To_Runtime( meth ),
8804               call_epilog );
8805   ins_pipe(simple_call);
8806 %}
8807 
8808 // Call runtime without safepoint - same as CallRuntime
8809 instruct CallLeafDirect(method meth) %{
8810   match(CallLeaf);
8811   effect(USE meth);
8812   ins_cost(CALL_COST);
8813   format %{ "CALL,runtime leaf" %}
8814   // TODO: ned save_last_PC here?
8815   ins_encode( Java_To_Runtime( meth ),
8816               call_epilog );
8817   ins_pipe(simple_call);
8818 %}
8819 
8820 // Call runtime without safepoint - same as CallLeaf
8821 instruct CallLeafNoFPDirect(method meth) %{
8822   match(CallLeafNoFP);
8823   effect(USE meth);
8824   ins_cost(CALL_COST);
8825   format %{ "CALL,runtime leaf nofp" %}
8826   // TODO: ned save_last_PC here?
8827   ins_encode( Java_To_Runtime( meth ),
8828               call_epilog );
8829   ins_pipe(simple_call);
8830 %}
8831 
8832 // Tail Call; Jump from runtime stub to Java code.
8833 // Also known as an 'interprocedural jump'.
8834 // Target of jump will eventually return to caller.
8835 // TailJump below removes the return address.
8836 instruct TailCalljmpInd(IPRegP jump_target, inline_cache_regP method_oop) %{
8837   match(TailCall jump_target method_oop );
8838 
8839   ins_cost(CALL_COST);
8840   format %{ "MOV    Rexception_pc, LR\n\t"
8841             "jump   $jump_target  \t! $method_oop holds method oop" %}
8842   ins_encode %{
8843     __ mov(Rexception_pc, LR);   // this is used only to call
8844                                  // StubRoutines::forward_exception_entry()
8845                                  // which expects PC of exception in
8846                                  // R5. FIXME?
8847     __ jump($jump_target$$Register);
8848   %}
8849   ins_pipe(tail_call);
8850 %}
8851 
8852 
8853 // Return Instruction
8854 instruct Ret() %{
8855   match(Return);
8856 
8857   format %{ "ret LR" %}
8858 
8859   ins_encode %{
8860     __ ret(LR);
8861   %}
8862 
8863   ins_pipe(br);
8864 %}
8865 
8866 
8867 // Tail Jump; remove the return address; jump to target.
8868 // TailCall above leaves the return address around.
8869 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
8870 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
8871 // "restore" before this instruction (in Epilogue), we need to materialize it
8872 // in %i0.
8873 instruct tailjmpInd(IPRegP jump_target, RExceptionRegP ex_oop) %{
8874   match( TailJump jump_target ex_oop );
8875   ins_cost(CALL_COST);
8876   format %{ "MOV    Rexception_pc, LR\n\t"
8877             "jump   $jump_target \t! $ex_oop holds exc. oop" %}
8878   ins_encode %{
8879     __ mov(Rexception_pc, LR);
8880     __ jump($jump_target$$Register);
8881   %}
8882   ins_pipe(tail_call);
8883 %}
8884 
8885 // Create exception oop: created by stack-crawling runtime code.
8886 // Created exception is now available to this handler, and is setup
8887 // just prior to jumping to this handler.  No code emitted.
8888 instruct CreateException( RExceptionRegP ex_oop )
8889 %{
8890   match(Set ex_oop (CreateEx));
8891   ins_cost(0);
8892 
8893   size(0);
8894   // use the following format syntax
8895   format %{ "! exception oop is in Rexception_obj; no code emitted" %}
8896   ins_encode();
8897   ins_pipe(empty);
8898 %}
8899 
8900 
8901 // Rethrow exception:
8902 // The exception oop will come in the first argument position.
8903 // Then JUMP (not call) to the rethrow stub code.
8904 instruct RethrowException()
8905 %{
8906   match(Rethrow);
8907   ins_cost(CALL_COST);
8908 
8909   // use the following format syntax
8910   format %{ "b    rethrow_stub" %}
8911   ins_encode %{
8912     Register scratch = R1_tmp;
8913     assert_different_registers(scratch, c_rarg0, LR);
8914     __ jump(OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type, scratch);
8915   %}
8916   ins_pipe(tail_call);
8917 %}
8918 
8919 
8920 // Die now
8921 instruct ShouldNotReachHere( )
8922 %{
8923   match(Halt);
8924   ins_cost(CALL_COST);
8925 
8926   size(4);
8927   // Use the following format syntax
8928   format %{ "ShouldNotReachHere" %}
8929   ins_encode %{
8930     __ udf(0xdead);
8931   %}
8932   ins_pipe(tail_call);
8933 %}
8934 
8935 // ============================================================================
8936 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
8937 // array for an instance of the superklass.  Set a hidden internal cache on a
8938 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
8939 // not zero for a miss or zero for a hit.  The encoding ALSO sets flags.
8940 instruct partialSubtypeCheck( R0RegP index, R1RegP sub, R2RegP super, flagsRegP pcc, LRRegP lr ) %{
8941   match(Set index (PartialSubtypeCheck sub super));
8942   effect( KILL pcc, KILL lr );
8943   ins_cost(DEFAULT_COST*10);
8944   format %{ "CALL   PartialSubtypeCheck" %}
8945   ins_encode %{
8946     __ call(StubRoutines::Arm::partial_subtype_check(), relocInfo::runtime_call_type);
8947   %}
8948   ins_pipe(partial_subtype_check_pipe);
8949 %}
8950 
8951 /* instruct partialSubtypeCheck_vs_zero( flagsRegP pcc, o1RegP sub, o2RegP super, immP0 zero, o0RegP idx, o7RegP o7 ) %{ */
8952 /*   match(Set pcc (CmpP (PartialSubtypeCheck sub super) zero)); */
8953 /*   ins_pipe(partial_subtype_check_pipe); */
8954 /* %} */
8955 
8956 
8957 // ============================================================================
8958 // inlined locking and unlocking
8959 
8960 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch )
8961 %{
8962   match(Set pcc (FastLock object box));
8963   predicate(!(UseBiasedLocking && !UseOptoBiasInlining));
8964 
8965   effect(TEMP scratch, TEMP scratch2);
8966   ins_cost(DEFAULT_COST*3);
8967 
8968   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2" %}
8969   ins_encode %{
8970     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
8971   %}
8972   ins_pipe(long_memory_op);
8973 %}
8974 
8975 instruct cmpFastLock_noBiasInline(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2,
8976                                   iRegP scratch, iRegP scratch3) %{
8977   match(Set pcc (FastLock object box));
8978   predicate(UseBiasedLocking && !UseOptoBiasInlining);
8979 
8980   effect(TEMP scratch, TEMP scratch2, TEMP scratch3);
8981   ins_cost(DEFAULT_COST*5);
8982 
8983   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2, $scratch3" %}
8984   ins_encode %{
8985     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register, $scratch3$$Register);
8986   %}
8987   ins_pipe(long_memory_op);
8988 %}
8989 
8990 
8991 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch ) %{
8992   match(Set pcc (FastUnlock object box));
8993   effect(TEMP scratch, TEMP scratch2);
8994   ins_cost(100);
8995 
8996   format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2" %}
8997   ins_encode %{
8998     __ fast_unlock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
8999   %}
9000   ins_pipe(long_memory_op);
9001 %}
9002 
9003 // Count and Base registers are fixed because the allocator cannot
9004 // kill unknown registers.  The encodings are generic.
9005 instruct clear_array(iRegX cnt, iRegP base, iRegI temp, iRegX zero, Universe dummy, flagsReg cpsr) %{
9006   match(Set dummy (ClearArray cnt base));
9007   effect(TEMP temp, TEMP zero, KILL cpsr);
9008   ins_cost(300);
9009   format %{ "MOV    $zero,0\n"
9010       "        MOV    $temp,$cnt\n"
9011       "loop:   SUBS   $temp,$temp,4\t! Count down a dword of bytes\n"
9012       "        STR.ge $zero,[$base+$temp]\t! delay slot"
9013       "        B.gt   loop\t\t! Clearing loop\n" %}
9014   ins_encode %{
9015     __ mov($zero$$Register, 0);
9016     __ mov($temp$$Register, $cnt$$Register);
9017     Label(loop);
9018     __ bind(loop);
9019     __ subs($temp$$Register, $temp$$Register, 4);
9020     __ str($zero$$Register, Address($base$$Register, $temp$$Register), ge);
9021     __ b(loop, gt);
9022   %}
9023   ins_pipe(long_memory_op);
9024 %}
9025 
9026 #ifdef XXX
9027 // FIXME: Why R0/R1/R2/R3?
9028 instruct string_compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result,
9029                         iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
9030   predicate(!CompactStrings);
9031   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
9032   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, TEMP tmp1, TEMP tmp2);
9033   ins_cost(300);
9034   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // TEMP $tmp1, $tmp2" %}
9035   ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result, tmp1, tmp2) );
9036 
9037   ins_pipe(long_memory_op);
9038 %}
9039 
9040 // FIXME: Why R0/R1/R2?
9041 instruct string_equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2,
9042                        flagsReg ccr) %{
9043   predicate(!CompactStrings);
9044   match(Set result (StrEquals (Binary str1 str2) cnt));
9045   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp1, TEMP tmp2, TEMP result, KILL ccr);
9046 
9047   ins_cost(300);
9048   format %{ "String Equals $str1,$str2,$cnt -> $result   // TEMP $tmp1, $tmp2" %}
9049   ins_encode( enc_String_Equals(str1, str2, cnt, result, tmp1, tmp2) );
9050   ins_pipe(long_memory_op);
9051 %}
9052 
9053 // FIXME: Why R0/R1?
9054 instruct array_equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result,
9055                       flagsReg ccr) %{
9056   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
9057   match(Set result (AryEq ary1 ary2));
9058   effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP result, KILL ccr);
9059 
9060   ins_cost(300);
9061   format %{ "Array Equals $ary1,$ary2 -> $result   // TEMP $tmp1,$tmp2,$tmp3" %}
9062   ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, result));
9063   ins_pipe(long_memory_op);
9064 %}
9065 #endif
9066 
9067 //---------- Zeros Count Instructions ------------------------------------------
9068 
9069 instruct countLeadingZerosI(iRegI dst, iRegI src) %{
9070   match(Set dst (CountLeadingZerosI src));
9071   size(4);
9072   format %{ "CLZ_32 $dst,$src" %}
9073   ins_encode %{
9074     __ clz_32($dst$$Register, $src$$Register);
9075   %}
9076   ins_pipe(ialu_reg);
9077 %}
9078 
9079 instruct countLeadingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
9080   match(Set dst (CountLeadingZerosL src));
9081   effect(TEMP tmp, TEMP dst, KILL ccr);
9082   size(16);
9083   format %{ "CLZ    $dst,$src.hi\n\t"
9084             "TEQ    $dst,32\n\t"
9085             "CLZ.eq $tmp,$src.lo\n\t"
9086             "ADD.eq $dst, $dst, $tmp\n\t" %}
9087   ins_encode %{
9088     __ clz($dst$$Register, $src$$Register->successor());
9089     __ teq($dst$$Register, 32);
9090     __ clz($tmp$$Register, $src$$Register, eq);
9091     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
9092   %}
9093   ins_pipe(ialu_reg);
9094 %}
9095 
9096 instruct countTrailingZerosI(iRegI dst, iRegI src, iRegI tmp) %{
9097   match(Set dst (CountTrailingZerosI src));
9098   effect(TEMP tmp);
9099   size(8);
9100   format %{ "RBIT_32 $tmp, $src\n\t"
9101             "CLZ_32  $dst,$tmp" %}
9102   ins_encode %{
9103     __ rbit_32($tmp$$Register, $src$$Register);
9104     __ clz_32($dst$$Register, $tmp$$Register);
9105   %}
9106   ins_pipe(ialu_reg);
9107 %}
9108 
9109 instruct countTrailingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
9110   match(Set dst (CountTrailingZerosL src));
9111   effect(TEMP tmp, TEMP dst, KILL ccr);
9112   size(24);
9113   format %{ "RBIT   $tmp,$src.lo\n\t"
9114             "CLZ    $dst,$tmp\n\t"
9115             "TEQ    $dst,32\n\t"
9116             "RBIT   $tmp,$src.hi\n\t"
9117             "CLZ.eq $tmp,$tmp\n\t"
9118             "ADD.eq $dst,$dst,$tmp\n\t" %}
9119   ins_encode %{
9120     __ rbit($tmp$$Register, $src$$Register);
9121     __ clz($dst$$Register, $tmp$$Register);
9122     __ teq($dst$$Register, 32);
9123     __ rbit($tmp$$Register, $src$$Register->successor());
9124     __ clz($tmp$$Register, $tmp$$Register, eq);
9125     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
9126   %}
9127   ins_pipe(ialu_reg);
9128 %}
9129 
9130 
9131 //---------- Population Count Instructions -------------------------------------
9132 
9133 instruct popCountI(iRegI dst, iRegI src, regD_low tmp) %{
9134   predicate(UsePopCountInstruction);
9135   match(Set dst (PopCountI src));
9136   effect(TEMP tmp);
9137 
9138   format %{ "FMSR       $tmp,$src\n\t"
9139             "VCNT.8     $tmp,$tmp\n\t"
9140             "VPADDL.U8  $tmp,$tmp\n\t"
9141             "VPADDL.U16 $tmp,$tmp\n\t"
9142             "FMRS       $dst,$tmp" %}
9143   size(20);
9144 
9145   ins_encode %{
9146     __ fmsr($tmp$$FloatRegister, $src$$Register);
9147     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
9148     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
9149     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
9150     __ fmrs($dst$$Register, $tmp$$FloatRegister);
9151   %}
9152   ins_pipe(ialu_reg); // FIXME
9153 %}
9154 
9155 // Note: Long.bitCount(long) returns an int.
9156 instruct popCountL(iRegI dst, iRegL src, regD_low tmp) %{
9157   predicate(UsePopCountInstruction);
9158   match(Set dst (PopCountL src));
9159   effect(TEMP tmp);
9160 
9161   format %{ "FMDRR       $tmp,$src.lo,$src.hi\n\t"
9162             "VCNT.8      $tmp,$tmp\n\t"
9163             "VPADDL.U8   $tmp,$tmp\n\t"
9164             "VPADDL.U16  $tmp,$tmp\n\t"
9165             "VPADDL.U32  $tmp,$tmp\n\t"
9166             "FMRS        $dst,$tmp" %}
9167 
9168   size(32);
9169 
9170   ins_encode %{
9171     __ fmdrr($tmp$$FloatRegister, $src$$Register, $src$$Register->successor());
9172     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
9173     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
9174     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
9175     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 32, 0);
9176     __ fmrs($dst$$Register, $tmp$$FloatRegister);
9177   %}
9178   ins_pipe(ialu_reg);
9179 %}
9180 
9181 
9182 // ============================================================================
9183 //------------Bytes reverse--------------------------------------------------
9184 
9185 instruct bytes_reverse_int(iRegI dst, iRegI src) %{
9186   match(Set dst (ReverseBytesI src));
9187 
9188   size(4);
9189   format %{ "REV32 $dst,$src" %}
9190   ins_encode %{
9191     __ rev($dst$$Register, $src$$Register);
9192   %}
9193   ins_pipe( iload_mem ); // FIXME
9194 %}
9195 
9196 instruct bytes_reverse_long(iRegL dst, iRegL src) %{
9197   match(Set dst (ReverseBytesL src));
9198   effect(TEMP dst);
9199   size(8);
9200   format %{ "REV $dst.lo,$src.lo\n\t"
9201             "REV $dst.hi,$src.hi" %}
9202   ins_encode %{
9203     __ rev($dst$$Register, $src$$Register->successor());
9204     __ rev($dst$$Register->successor(), $src$$Register);
9205   %}
9206   ins_pipe( iload_mem ); // FIXME
9207 %}
9208 
9209 instruct bytes_reverse_unsigned_short(iRegI dst, iRegI src) %{
9210   match(Set dst (ReverseBytesUS src));
9211   size(4);
9212   format %{ "REV16 $dst,$src" %}
9213   ins_encode %{
9214     __ rev16($dst$$Register, $src$$Register);
9215   %}
9216   ins_pipe( iload_mem ); // FIXME
9217 %}
9218 
9219 instruct bytes_reverse_short(iRegI dst, iRegI src) %{
9220   match(Set dst (ReverseBytesS src));
9221   size(4);
9222   format %{ "REVSH $dst,$src" %}
9223   ins_encode %{
9224     __ revsh($dst$$Register, $src$$Register);
9225   %}
9226   ins_pipe( iload_mem ); // FIXME
9227 %}
9228 
9229 
9230 // ====================VECTOR INSTRUCTIONS=====================================
9231 
9232 // Load Aligned Packed values into a Double Register
9233 instruct loadV8(vecD dst, memoryD mem) %{
9234   predicate(n->as_LoadVector()->memory_size() == 8);
9235   match(Set dst (LoadVector mem));
9236   ins_cost(MEMORY_REF_COST);
9237   size(4);
9238   format %{ "FLDD   $mem,$dst\t! load vector (8 bytes)" %}
9239   ins_encode %{
9240     __ ldr_double($dst$$FloatRegister, $mem$$Address);
9241   %}
9242   ins_pipe(floadD_mem);
9243 %}
9244 
9245 // Load Aligned Packed values into a Double Register Pair
9246 instruct loadV16(vecX dst, memoryvld mem) %{
9247   predicate(n->as_LoadVector()->memory_size() == 16);
9248   match(Set dst (LoadVector mem));
9249   ins_cost(MEMORY_REF_COST);
9250   size(4);
9251   format %{ "VLD1   $mem,$dst.Q\t! load vector (16 bytes)" %}
9252   ins_encode %{
9253     __ vld1($dst$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
9254   %}
9255   ins_pipe(floadD_mem); // FIXME
9256 %}
9257 
9258 // Store Vector in Double register to memory
9259 instruct storeV8(memoryD mem, vecD src) %{
9260   predicate(n->as_StoreVector()->memory_size() == 8);
9261   match(Set mem (StoreVector mem src));
9262   ins_cost(MEMORY_REF_COST);
9263   size(4);
9264   format %{ "FSTD   $src,$mem\t! store vector (8 bytes)" %}
9265   ins_encode %{
9266     __ str_double($src$$FloatRegister, $mem$$Address);
9267   %}
9268   ins_pipe(fstoreD_mem_reg);
9269 %}
9270 
9271 // Store Vector in Double Register Pair to memory
9272 instruct storeV16(memoryvld mem, vecX src) %{
9273   predicate(n->as_StoreVector()->memory_size() == 16);
9274   match(Set mem (StoreVector mem src));
9275   ins_cost(MEMORY_REF_COST);
9276   size(4);
9277   format %{ "VST1   $src,$mem\t! store vector (16 bytes)" %}
9278   ins_encode %{
9279     __ vst1($src$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
9280   %}
9281   ins_pipe(fstoreD_mem_reg); // FIXME
9282 %}
9283 
9284 // Replicate scalar to packed byte values in Double register
9285 instruct Repl8B_reg(vecD dst, iRegI src, iRegI tmp) %{
9286   predicate(n->as_Vector()->length() == 8);
9287   match(Set dst (ReplicateB src));
9288   ins_cost(DEFAULT_COST*4);
9289   effect(TEMP tmp);
9290   size(16);
9291 
9292   // FIXME: could use PKH instruction instead?
9293   format %{ "LSL      $tmp, $src, 24 \n\t"
9294             "OR       $tmp, $tmp, ($tmp >> 8) \n\t"
9295             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
9296             "FMDRR    $dst,$tmp,$tmp\t" %}
9297   ins_encode %{
9298     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 24));
9299     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 8));
9300     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
9301     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
9302   %}
9303   ins_pipe(ialu_reg); // FIXME
9304 %}
9305 
9306 // Replicate scalar to packed byte values in Double register
9307 instruct Repl8B_reg_simd(vecD dst, iRegI src) %{
9308   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9309   match(Set dst (ReplicateB src));
9310   size(4);
9311 
9312   format %{ "VDUP.8 $dst,$src\t" %}
9313   ins_encode %{
9314     bool quad = false;
9315     __ vdupI($dst$$FloatRegister, $src$$Register,
9316              MacroAssembler::VELEM_SIZE_8, quad);
9317   %}
9318   ins_pipe(ialu_reg); // FIXME
9319 %}
9320 
9321 // Replicate scalar to packed byte values in Double register pair
9322 instruct Repl16B_reg(vecX dst, iRegI src) %{
9323   predicate(n->as_Vector()->length_in_bytes() == 16);
9324   match(Set dst (ReplicateB src));
9325   size(4);
9326 
9327   format %{ "VDUP.8 $dst.Q,$src\t" %}
9328   ins_encode %{
9329     bool quad = true;
9330     __ vdupI($dst$$FloatRegister, $src$$Register,
9331              MacroAssembler::VELEM_SIZE_8, quad);
9332   %}
9333   ins_pipe(ialu_reg); // FIXME
9334 %}
9335 
9336 // Replicate scalar constant to packed byte values in Double register
9337 instruct Repl8B_immI(vecD dst, immI src, iRegI tmp) %{
9338   predicate(n->as_Vector()->length() == 8);
9339   match(Set dst (ReplicateB src));
9340   ins_cost(DEFAULT_COST*2);
9341   effect(TEMP tmp);
9342   size(12);
9343 
9344   format %{ "MOV      $tmp, Repl4($src))\n\t"
9345             "FMDRR    $dst,$tmp,$tmp\t" %}
9346   ins_encode( LdReplImmI(src, dst, tmp, (4), (1)) );
9347   ins_pipe(loadConFD); // FIXME
9348 %}
9349 
9350 // Replicate scalar constant to packed byte values in Double register
9351 // TODO: support negative constants with MVNI?
9352 instruct Repl8B_immU8(vecD dst, immU8 src) %{
9353   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9354   match(Set dst (ReplicateB src));
9355   size(4);
9356 
9357   format %{ "VMOV.U8  $dst,$src" %}
9358   ins_encode %{
9359     bool quad = false;
9360     __ vmovI($dst$$FloatRegister, $src$$constant,
9361              MacroAssembler::VELEM_SIZE_8, quad);
9362   %}
9363   ins_pipe(loadConFD); // FIXME
9364 %}
9365 
9366 // Replicate scalar constant to packed byte values in Double register pair
9367 instruct Repl16B_immU8(vecX dst, immU8 src) %{
9368   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
9369   match(Set dst (ReplicateB src));
9370   size(4);
9371 
9372   format %{ "VMOV.U8  $dst.Q,$src" %}
9373   ins_encode %{
9374     bool quad = true;
9375     __ vmovI($dst$$FloatRegister, $src$$constant,
9376              MacroAssembler::VELEM_SIZE_8, quad);
9377   %}
9378   ins_pipe(loadConFD); // FIXME
9379 %}
9380 
9381 // Replicate scalar to packed short/char values into Double register
9382 instruct Repl4S_reg(vecD dst, iRegI src, iRegI tmp) %{
9383   predicate(n->as_Vector()->length() == 4);
9384   match(Set dst (ReplicateS src));
9385   ins_cost(DEFAULT_COST*3);
9386   effect(TEMP tmp);
9387   size(12);
9388 
9389   // FIXME: could use PKH instruction instead?
9390   format %{ "LSL      $tmp, $src, 16 \n\t"
9391             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
9392             "FMDRR    $dst,$tmp,$tmp\t" %}
9393   ins_encode %{
9394     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 16));
9395     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
9396     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
9397   %}
9398   ins_pipe(ialu_reg); // FIXME
9399 %}
9400 
9401 // Replicate scalar to packed byte values in Double register
9402 instruct Repl4S_reg_simd(vecD dst, iRegI src) %{
9403   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9404   match(Set dst (ReplicateS src));
9405   size(4);
9406 
9407   format %{ "VDUP.16 $dst,$src\t" %}
9408   ins_encode %{
9409     bool quad = false;
9410     __ vdupI($dst$$FloatRegister, $src$$Register,
9411              MacroAssembler::VELEM_SIZE_16, quad);
9412   %}
9413   ins_pipe(ialu_reg); // FIXME
9414 %}
9415 
9416 // Replicate scalar to packed byte values in Double register pair
9417 instruct Repl8S_reg(vecX dst, iRegI src) %{
9418   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
9419   match(Set dst (ReplicateS src));
9420   size(4);
9421 
9422   format %{ "VDUP.16 $dst.Q,$src\t" %}
9423   ins_encode %{
9424     bool quad = true;
9425     __ vdupI($dst$$FloatRegister, $src$$Register,
9426              MacroAssembler::VELEM_SIZE_16, quad);
9427   %}
9428   ins_pipe(ialu_reg); // FIXME
9429 %}
9430 
9431 
9432 // Replicate scalar constant to packed short/char values in Double register
9433 instruct Repl4S_immI(vecD dst, immI src, iRegP tmp) %{
9434   predicate(n->as_Vector()->length() == 4);
9435   match(Set dst (ReplicateS src));
9436   effect(TEMP tmp);
9437   size(12);
9438   ins_cost(DEFAULT_COST*4); // FIXME
9439 
9440   format %{ "MOV      $tmp, Repl2($src))\n\t"
9441             "FMDRR    $dst,$tmp,$tmp\t" %}
9442   ins_encode( LdReplImmI(src, dst, tmp, (2), (2)) );
9443   ins_pipe(loadConFD); // FIXME
9444 %}
9445 
9446 // Replicate scalar constant to packed byte values in Double register
9447 instruct Repl4S_immU8(vecD dst, immU8 src) %{
9448   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9449   match(Set dst (ReplicateS src));
9450   size(4);
9451 
9452   format %{ "VMOV.U16  $dst,$src" %}
9453   ins_encode %{
9454     bool quad = false;
9455     __ vmovI($dst$$FloatRegister, $src$$constant,
9456              MacroAssembler::VELEM_SIZE_16, quad);
9457   %}
9458   ins_pipe(loadConFD); // FIXME
9459 %}
9460 
9461 // Replicate scalar constant to packed byte values in Double register pair
9462 instruct Repl8S_immU8(vecX dst, immU8 src) %{
9463   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
9464   match(Set dst (ReplicateS src));
9465   size(4);
9466 
9467   format %{ "VMOV.U16  $dst.Q,$src" %}
9468   ins_encode %{
9469     bool quad = true;
9470     __ vmovI($dst$$FloatRegister, $src$$constant,
9471              MacroAssembler::VELEM_SIZE_16, quad);
9472   %}
9473   ins_pipe(loadConFD); // FIXME
9474 %}
9475 
9476 // Replicate scalar to packed int values in Double register
9477 instruct Repl2I_reg(vecD dst, iRegI src) %{
9478   predicate(n->as_Vector()->length() == 2);
9479   match(Set dst (ReplicateI src));
9480   size(4);
9481 
9482   format %{ "FMDRR    $dst,$src,$src\t" %}
9483   ins_encode %{
9484     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
9485   %}
9486   ins_pipe(ialu_reg); // FIXME
9487 %}
9488 
9489 // Replicate scalar to packed int values in Double register pair
9490 instruct Repl4I_reg(vecX dst, iRegI src) %{
9491   predicate(n->as_Vector()->length() == 4);
9492   match(Set dst (ReplicateI src));
9493   ins_cost(DEFAULT_COST*2);
9494   size(8);
9495 
9496   format %{ "FMDRR    $dst.lo,$src,$src\n\t"
9497             "FMDRR    $dst.hi,$src,$src" %}
9498 
9499   ins_encode %{
9500     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
9501     __ fmdrr($dst$$FloatRegister->successor()->successor(),
9502              $src$$Register, $src$$Register);
9503   %}
9504   ins_pipe(ialu_reg); // FIXME
9505 %}
9506 
9507 // Replicate scalar to packed int values in Double register
9508 instruct Repl2I_reg_simd(vecD dst, iRegI src) %{
9509   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9510   match(Set dst (ReplicateI src));
9511   size(4);
9512 
9513   format %{ "VDUP.32 $dst.D,$src\t" %}
9514   ins_encode %{
9515     bool quad = false;
9516     __ vdupI($dst$$FloatRegister, $src$$Register,
9517              MacroAssembler::VELEM_SIZE_32, quad);
9518   %}
9519   ins_pipe(ialu_reg); // FIXME
9520 %}
9521 
9522 // Replicate scalar to packed int values in Double register pair
9523 instruct Repl4I_reg_simd(vecX dst, iRegI src) %{
9524   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
9525   match(Set dst (ReplicateI src));
9526   size(4);
9527 
9528   format %{ "VDUP.32 $dst.Q,$src\t" %}
9529   ins_encode %{
9530     bool quad = true;
9531     __ vdupI($dst$$FloatRegister, $src$$Register,
9532              MacroAssembler::VELEM_SIZE_32, quad);
9533   %}
9534   ins_pipe(ialu_reg); // FIXME
9535 %}
9536 
9537 
9538 // Replicate scalar zero constant to packed int values in Double register
9539 instruct Repl2I_immI(vecD dst, immI src, iRegI tmp) %{
9540   predicate(n->as_Vector()->length() == 2);
9541   match(Set dst (ReplicateI src));
9542   effect(TEMP tmp);
9543   size(12);
9544   ins_cost(DEFAULT_COST*4); // FIXME
9545 
9546   format %{ "MOV      $tmp, Repl1($src))\n\t"
9547             "FMDRR    $dst,$tmp,$tmp\t" %}
9548   ins_encode( LdReplImmI(src, dst, tmp, (1), (4)) );
9549   ins_pipe(loadConFD); // FIXME
9550 %}
9551 
9552 // Replicate scalar constant to packed byte values in Double register
9553 instruct Repl2I_immU8(vecD dst, immU8 src) %{
9554   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9555   match(Set dst (ReplicateI src));
9556   size(4);
9557 
9558   format %{ "VMOV.I32  $dst.D,$src" %}
9559   ins_encode %{
9560     bool quad = false;
9561     __ vmovI($dst$$FloatRegister, $src$$constant,
9562              MacroAssembler::VELEM_SIZE_32, quad);
9563   %}
9564   ins_pipe(loadConFD); // FIXME
9565 %}
9566 
9567 // Replicate scalar constant to packed byte values in Double register pair
9568 instruct Repl4I_immU8(vecX dst, immU8 src) %{
9569   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
9570   match(Set dst (ReplicateI src));
9571   size(4);
9572 
9573   format %{ "VMOV.I32  $dst.Q,$src" %}
9574   ins_encode %{
9575     bool quad = true;
9576     __ vmovI($dst$$FloatRegister, $src$$constant,
9577              MacroAssembler::VELEM_SIZE_32, quad);
9578   %}
9579   ins_pipe(loadConFD); // FIXME
9580 %}
9581 
9582 // Replicate scalar to packed byte values in Double register pair
9583 instruct Repl2L_reg(vecX dst, iRegL src) %{
9584   predicate(n->as_Vector()->length() == 2);
9585   match(Set dst (ReplicateL src));
9586   size(8);
9587   ins_cost(DEFAULT_COST*2); // FIXME
9588 
9589   format %{ "FMDRR $dst.D,$src.lo,$src.hi\t\n"
9590             "FMDRR $dst.D.next,$src.lo,$src.hi" %}
9591   ins_encode %{
9592     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
9593     __ fmdrr($dst$$FloatRegister->successor()->successor(),
9594              $src$$Register, $src$$Register->successor());
9595   %}
9596   ins_pipe(ialu_reg); // FIXME
9597 %}
9598 
9599 
9600 // Replicate scalar to packed float values in Double register
9601 instruct Repl2F_regI(vecD dst, iRegI src) %{
9602   predicate(n->as_Vector()->length() == 2);
9603   match(Set dst (ReplicateF src));
9604   size(4);
9605 
9606   format %{ "FMDRR    $dst.D,$src,$src\t" %}
9607   ins_encode %{
9608     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
9609   %}
9610   ins_pipe(ialu_reg); // FIXME
9611 %}
9612 
9613 // Replicate scalar to packed float values in Double register
9614 instruct Repl2F_reg_vfp(vecD dst, regF src) %{
9615   predicate(n->as_Vector()->length() == 2);
9616   match(Set dst (ReplicateF src));
9617   size(4*2);
9618   ins_cost(DEFAULT_COST*2); // FIXME
9619 
9620   expand %{
9621     iRegI tmp;
9622     MoveF2I_reg_reg(tmp, src);
9623     Repl2F_regI(dst,tmp);
9624   %}
9625 %}
9626 
9627 // Replicate scalar to packed float values in Double register
9628 instruct Repl2F_reg_simd(vecD dst, regF src) %{
9629   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9630   match(Set dst (ReplicateF src));
9631   size(4);
9632   ins_cost(DEFAULT_COST); // FIXME
9633 
9634   format %{ "VDUP.32  $dst.D,$src.D\t" %}
9635   ins_encode %{
9636     bool quad = false;
9637     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
9638   %}
9639   ins_pipe(ialu_reg); // FIXME
9640 %}
9641 
9642 // Replicate scalar to packed float values in Double register pair
9643 instruct Repl4F_reg(vecX dst, regF src, iRegI tmp) %{
9644   predicate(n->as_Vector()->length() == 4);
9645   match(Set dst (ReplicateF src));
9646   effect(TEMP tmp);
9647   size(4*3);
9648   ins_cost(DEFAULT_COST*3); // FIXME
9649 
9650   format %{ "FMRS     $tmp,$src\n\t"
9651             "FMDRR    $dst.D,$tmp,$tmp\n\t"
9652             "FMDRR    $dst.D.next,$tmp,$tmp\t" %}
9653   ins_encode %{
9654     __ fmrs($tmp$$Register, $src$$FloatRegister);
9655     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
9656     __ fmdrr($dst$$FloatRegister->successor()->successor(),
9657              $tmp$$Register, $tmp$$Register);
9658   %}
9659   ins_pipe(ialu_reg); // FIXME
9660 %}
9661 
9662 // Replicate scalar to packed float values in Double register pair
9663 instruct Repl4F_reg_simd(vecX dst, regF src) %{
9664   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
9665   match(Set dst (ReplicateF src));
9666   size(4);
9667   ins_cost(DEFAULT_COST); // FIXME
9668 
9669   format %{ "VDUP.32  $dst.Q,$src.D\t" %}
9670   ins_encode %{
9671     bool quad = true;
9672     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
9673   %}
9674   ins_pipe(ialu_reg); // FIXME
9675 %}
9676 
9677 // Replicate scalar zero constant to packed float values in Double register
9678 instruct Repl2F_immI(vecD dst, immF src, iRegI tmp) %{
9679   predicate(n->as_Vector()->length() == 2);
9680   match(Set dst (ReplicateF src));
9681   effect(TEMP tmp);
9682   size(12);
9683   ins_cost(DEFAULT_COST*4); // FIXME
9684 
9685   format %{ "MOV      $tmp, Repl1($src))\n\t"
9686             "FMDRR    $dst,$tmp,$tmp\t" %}
9687   ins_encode( LdReplImmF(src, dst, tmp) );
9688   ins_pipe(loadConFD); // FIXME
9689 %}
9690 
9691 // Replicate scalar to packed double float values in Double register pair
9692 instruct Repl2D_reg(vecX dst, regD src) %{
9693   predicate(n->as_Vector()->length() == 2);
9694   match(Set dst (ReplicateD src));
9695   size(4*2);
9696   ins_cost(DEFAULT_COST*2); // FIXME
9697 
9698   format %{ "FCPYD    $dst.D.a,$src\n\t"
9699             "FCPYD    $dst.D.b,$src\t" %}
9700   ins_encode %{
9701     FloatRegister dsta = $dst$$FloatRegister;
9702     FloatRegister src = $src$$FloatRegister;
9703     __ fcpyd(dsta, src);
9704     FloatRegister dstb = dsta->successor()->successor();
9705     __ fcpyd(dstb, src);
9706   %}
9707   ins_pipe(ialu_reg); // FIXME
9708 %}
9709 
9710 // ====================VECTOR ARITHMETIC=======================================
9711 
9712 // --------------------------------- ADD --------------------------------------
9713 
9714 // Bytes vector add
9715 instruct vadd8B_reg(vecD dst, vecD src1, vecD src2) %{
9716   predicate(n->as_Vector()->length() == 8);
9717   match(Set dst (AddVB src1 src2));
9718   format %{ "VADD.I8 $dst,$src1,$src2\t! add packed8B" %}
9719   size(4);
9720   ins_encode %{
9721     bool quad = false;
9722     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9723              MacroAssembler::VELEM_SIZE_8, quad);
9724   %}
9725   ins_pipe( ialu_reg_reg ); // FIXME
9726 %}
9727 
9728 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
9729   predicate(n->as_Vector()->length() == 16);
9730   match(Set dst (AddVB src1 src2));
9731   size(4);
9732   format %{ "VADD.I8 $dst.Q,$src1.Q,$src2.Q\t! add packed16B" %}
9733   ins_encode %{
9734     bool quad = true;
9735     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9736              MacroAssembler::VELEM_SIZE_8, quad);
9737   %}
9738   ins_pipe( ialu_reg_reg ); // FIXME
9739 %}
9740 
9741 // Shorts/Chars vector add
9742 instruct vadd4S_reg(vecD dst, vecD src1, vecD src2) %{
9743   predicate(n->as_Vector()->length() == 4);
9744   match(Set dst (AddVS src1 src2));
9745   size(4);
9746   format %{ "VADD.I16 $dst,$src1,$src2\t! add packed4S" %}
9747   ins_encode %{
9748     bool quad = false;
9749     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9750              MacroAssembler::VELEM_SIZE_16, quad);
9751   %}
9752   ins_pipe( ialu_reg_reg ); // FIXME
9753 %}
9754 
9755 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
9756   predicate(n->as_Vector()->length() == 8);
9757   match(Set dst (AddVS src1 src2));
9758   size(4);
9759   format %{ "VADD.I16 $dst.Q,$src1.Q,$src2.Q\t! add packed8S" %}
9760   ins_encode %{
9761     bool quad = true;
9762     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9763              MacroAssembler::VELEM_SIZE_16, quad);
9764   %}
9765   ins_pipe( ialu_reg_reg ); // FIXME
9766 %}
9767 
9768 // Integers vector add
9769 instruct vadd2I_reg(vecD dst, vecD src1, vecD src2) %{
9770   predicate(n->as_Vector()->length() == 2);
9771   match(Set dst (AddVI src1 src2));
9772   size(4);
9773   format %{ "VADD.I32 $dst.D,$src1.D,$src2.D\t! add packed2I" %}
9774   ins_encode %{
9775     bool quad = false;
9776     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9777              MacroAssembler::VELEM_SIZE_32, quad);
9778   %}
9779   ins_pipe( ialu_reg_reg ); // FIXME
9780 %}
9781 
9782 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
9783   predicate(n->as_Vector()->length() == 4);
9784   match(Set dst (AddVI src1 src2));
9785   size(4);
9786   format %{ "VADD.I32 $dst.Q,$src1.Q,$src2.Q\t! add packed4I" %}
9787   ins_encode %{
9788     bool quad = true;
9789     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9790              MacroAssembler::VELEM_SIZE_32, quad);
9791   %}
9792   ins_pipe( ialu_reg_reg ); // FIXME
9793 %}
9794 
9795 // Longs vector add
9796 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
9797   predicate(n->as_Vector()->length() == 2);
9798   match(Set dst (AddVL src1 src2));
9799   size(4);
9800   format %{ "VADD.I64 $dst.Q,$src1.Q,$src2.Q\t! add packed2L" %}
9801   ins_encode %{
9802     bool quad = true;
9803     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9804              MacroAssembler::VELEM_SIZE_64, quad);
9805   %}
9806   ins_pipe( ialu_reg_reg ); // FIXME
9807 %}
9808 
9809 // Floats vector add
9810 instruct vadd2F_reg(vecD dst, vecD src1, vecD src2) %{
9811   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
9812   match(Set dst (AddVF src1 src2));
9813   size(4);
9814   format %{ "VADD.F32 $dst,$src1,$src2\t! add packed2F" %}
9815   ins_encode %{
9816     bool quad = false;
9817     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9818              MacroAssembler::VFA_SIZE_F32, quad);
9819   %}
9820   ins_pipe( faddD_reg_reg ); // FIXME
9821 %}
9822 
9823 instruct vadd2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
9824   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
9825   match(Set dst (AddVF src1 src2));
9826   ins_cost(DEFAULT_COST*2); // FIXME
9827 
9828   size(4*2);
9829   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
9830             "FADDS  $dst.b,$src1.b,$src2.b" %}
9831   ins_encode %{
9832     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9833     __ add_float($dst$$FloatRegister->successor(),
9834              $src1$$FloatRegister->successor(),
9835              $src2$$FloatRegister->successor());
9836   %}
9837 
9838   ins_pipe(faddF_reg_reg); // FIXME
9839 %}
9840 
9841 instruct vadd4F_reg_simd(vecX dst, vecX src1, vecX src2) %{
9842   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
9843   match(Set dst (AddVF src1 src2));
9844   size(4);
9845   format %{ "VADD.F32 $dst.Q,$src1.Q,$src2.Q\t! add packed4F" %}
9846   ins_encode %{
9847     bool quad = true;
9848     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9849              MacroAssembler::VFA_SIZE_F32, quad);
9850   %}
9851   ins_pipe( faddD_reg_reg ); // FIXME
9852 %}
9853 
9854 instruct vadd4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
9855   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
9856   match(Set dst (AddVF src1 src2));
9857   size(4*4);
9858   ins_cost(DEFAULT_COST*4); // FIXME
9859 
9860   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
9861             "FADDS  $dst.b,$src1.b,$src2.b\n\t"
9862             "FADDS  $dst.c,$src1.c,$src2.c\n\t"
9863             "FADDS  $dst.d,$src1.d,$src2.d" %}
9864 
9865   ins_encode %{
9866     FloatRegister dsta = $dst$$FloatRegister;
9867     FloatRegister src1a = $src1$$FloatRegister;
9868     FloatRegister src2a = $src2$$FloatRegister;
9869     __ add_float(dsta, src1a, src2a);
9870     FloatRegister dstb = dsta->successor();
9871     FloatRegister src1b = src1a->successor();
9872     FloatRegister src2b = src2a->successor();
9873     __ add_float(dstb, src1b, src2b);
9874     FloatRegister dstc = dstb->successor();
9875     FloatRegister src1c = src1b->successor();
9876     FloatRegister src2c = src2b->successor();
9877     __ add_float(dstc, src1c, src2c);
9878     FloatRegister dstd = dstc->successor();
9879     FloatRegister src1d = src1c->successor();
9880     FloatRegister src2d = src2c->successor();
9881     __ add_float(dstd, src1d, src2d);
9882   %}
9883 
9884   ins_pipe(faddF_reg_reg); // FIXME
9885 %}
9886 
9887 instruct vadd2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
9888   predicate(n->as_Vector()->length() == 2);
9889   match(Set dst (AddVD src1 src2));
9890   size(4*2);
9891   ins_cost(DEFAULT_COST*2); // FIXME
9892 
9893   format %{ "FADDD  $dst.a,$src1.a,$src2.a\n\t"
9894             "FADDD  $dst.b,$src1.b,$src2.b" %}
9895 
9896   ins_encode %{
9897     FloatRegister dsta = $dst$$FloatRegister;
9898     FloatRegister src1a = $src1$$FloatRegister;
9899     FloatRegister src2a = $src2$$FloatRegister;
9900     __ add_double(dsta, src1a, src2a);
9901     FloatRegister dstb = dsta->successor()->successor();
9902     FloatRegister src1b = src1a->successor()->successor();
9903     FloatRegister src2b = src2a->successor()->successor();
9904     __ add_double(dstb, src1b, src2b);
9905   %}
9906 
9907   ins_pipe(faddF_reg_reg); // FIXME
9908 %}
9909 
9910 
9911 // Bytes vector sub
9912 instruct vsub8B_reg(vecD dst, vecD src1, vecD src2) %{
9913   predicate(n->as_Vector()->length() == 8);
9914   match(Set dst (SubVB src1 src2));
9915   size(4);
9916   format %{ "VSUB.I8 $dst,$src1,$src2\t! sub packed8B" %}
9917   ins_encode %{
9918     bool quad = false;
9919     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9920              MacroAssembler::VELEM_SIZE_8, quad);
9921   %}
9922   ins_pipe( ialu_reg_reg ); // FIXME
9923 %}
9924 
9925 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
9926   predicate(n->as_Vector()->length() == 16);
9927   match(Set dst (SubVB src1 src2));
9928   size(4);
9929   format %{ "VSUB.I8 $dst.Q,$src1.Q,$src2.Q\t! sub packed16B" %}
9930   ins_encode %{
9931     bool quad = true;
9932     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9933              MacroAssembler::VELEM_SIZE_8, quad);
9934   %}
9935   ins_pipe( ialu_reg_reg ); // FIXME
9936 %}
9937 
9938 // Shorts/Chars vector sub
9939 instruct vsub4S_reg(vecD dst, vecD src1, vecD src2) %{
9940   predicate(n->as_Vector()->length() == 4);
9941   match(Set dst (SubVS src1 src2));
9942   size(4);
9943   format %{ "VSUB.I16 $dst,$src1,$src2\t! sub packed4S" %}
9944   ins_encode %{
9945     bool quad = false;
9946     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9947              MacroAssembler::VELEM_SIZE_16, quad);
9948   %}
9949   ins_pipe( ialu_reg_reg ); // FIXME
9950 %}
9951 
9952 instruct vsub16S_reg(vecX dst, vecX src1, vecX src2) %{
9953   predicate(n->as_Vector()->length() == 8);
9954   match(Set dst (SubVS src1 src2));
9955   size(4);
9956   format %{ "VSUB.I16 $dst.Q,$src1.Q,$src2.Q\t! sub packed8S" %}
9957   ins_encode %{
9958     bool quad = true;
9959     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9960              MacroAssembler::VELEM_SIZE_16, quad);
9961   %}
9962   ins_pipe( ialu_reg_reg ); // FIXME
9963 %}
9964 
9965 // Integers vector sub
9966 instruct vsub2I_reg(vecD dst, vecD src1, vecD src2) %{
9967   predicate(n->as_Vector()->length() == 2);
9968   match(Set dst (SubVI src1 src2));
9969   size(4);
9970   format %{ "VSUB.I32 $dst,$src1,$src2\t! sub packed2I" %}
9971   ins_encode %{
9972     bool quad = false;
9973     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9974              MacroAssembler::VELEM_SIZE_32, quad);
9975   %}
9976   ins_pipe( ialu_reg_reg ); // FIXME
9977 %}
9978 
9979 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
9980   predicate(n->as_Vector()->length() == 4);
9981   match(Set dst (SubVI src1 src2));
9982   size(4);
9983   format %{ "VSUB.I32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4I" %}
9984   ins_encode %{
9985     bool quad = true;
9986     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9987              MacroAssembler::VELEM_SIZE_32, quad);
9988   %}
9989   ins_pipe( ialu_reg_reg ); // FIXME
9990 %}
9991 
9992 // Longs vector sub
9993 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
9994   predicate(n->as_Vector()->length() == 2);
9995   match(Set dst (SubVL src1 src2));
9996   size(4);
9997   format %{ "VSUB.I64 $dst.Q,$src1.Q,$src2.Q\t! sub packed2L" %}
9998   ins_encode %{
9999     bool quad = true;
10000     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10001              MacroAssembler::VELEM_SIZE_64, quad);
10002   %}
10003   ins_pipe( ialu_reg_reg ); // FIXME
10004 %}
10005 
10006 // Floats vector sub
10007 instruct vsub2F_reg(vecD dst, vecD src1, vecD src2) %{
10008   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
10009   match(Set dst (SubVF src1 src2));
10010   size(4);
10011   format %{ "VSUB.F32 $dst,$src1,$src2\t! sub packed2F" %}
10012   ins_encode %{
10013     bool quad = false;
10014     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10015              MacroAssembler::VFA_SIZE_F32, quad);
10016   %}
10017   ins_pipe( faddF_reg_reg ); // FIXME
10018 %}
10019 
10020 instruct vsub2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10021   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
10022   match(Set dst (SubVF src1 src2));
10023   size(4*2);
10024   ins_cost(DEFAULT_COST*2); // FIXME
10025 
10026   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10027             "FSUBS  $dst.b,$src1.b,$src2.b" %}
10028 
10029   ins_encode %{
10030     FloatRegister dsta = $dst$$FloatRegister;
10031     FloatRegister src1a = $src1$$FloatRegister;
10032     FloatRegister src2a = $src2$$FloatRegister;
10033     __ sub_float(dsta, src1a, src2a);
10034     FloatRegister dstb = dsta->successor();
10035     FloatRegister src1b = src1a->successor();
10036     FloatRegister src2b = src2a->successor();
10037     __ sub_float(dstb, src1b, src2b);
10038   %}
10039 
10040   ins_pipe(faddF_reg_reg); // FIXME
10041 %}
10042 
10043 
10044 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
10045   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
10046   match(Set dst (SubVF src1 src2));
10047   size(4);
10048   format %{ "VSUB.F32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4F" %}
10049   ins_encode %{
10050     bool quad = true;
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 vsub4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10058   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
10059   match(Set dst (SubVF src1 src2));
10060   size(4*4);
10061   ins_cost(DEFAULT_COST*4); // FIXME
10062 
10063   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10064             "FSUBS  $dst.b,$src1.b,$src2.b\n\t"
10065             "FSUBS  $dst.c,$src1.c,$src2.c\n\t"
10066             "FSUBS  $dst.d,$src1.d,$src2.d" %}
10067 
10068   ins_encode %{
10069     FloatRegister dsta = $dst$$FloatRegister;
10070     FloatRegister src1a = $src1$$FloatRegister;
10071     FloatRegister src2a = $src2$$FloatRegister;
10072     __ sub_float(dsta, src1a, src2a);
10073     FloatRegister dstb = dsta->successor();
10074     FloatRegister src1b = src1a->successor();
10075     FloatRegister src2b = src2a->successor();
10076     __ sub_float(dstb, src1b, src2b);
10077     FloatRegister dstc = dstb->successor();
10078     FloatRegister src1c = src1b->successor();
10079     FloatRegister src2c = src2b->successor();
10080     __ sub_float(dstc, src1c, src2c);
10081     FloatRegister dstd = dstc->successor();
10082     FloatRegister src1d = src1c->successor();
10083     FloatRegister src2d = src2c->successor();
10084     __ sub_float(dstd, src1d, src2d);
10085   %}
10086 
10087   ins_pipe(faddF_reg_reg); // FIXME
10088 %}
10089 
10090 instruct vsub2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10091   predicate(n->as_Vector()->length() == 2);
10092   match(Set dst (SubVD src1 src2));
10093   size(4*2);
10094   ins_cost(DEFAULT_COST*2); // FIXME
10095 
10096   format %{ "FSUBD  $dst.a,$src1.a,$src2.a\n\t"
10097             "FSUBD  $dst.b,$src1.b,$src2.b" %}
10098 
10099   ins_encode %{
10100     FloatRegister dsta = $dst$$FloatRegister;
10101     FloatRegister src1a = $src1$$FloatRegister;
10102     FloatRegister src2a = $src2$$FloatRegister;
10103     __ sub_double(dsta, src1a, src2a);
10104     FloatRegister dstb = dsta->successor()->successor();
10105     FloatRegister src1b = src1a->successor()->successor();
10106     FloatRegister src2b = src2a->successor()->successor();
10107     __ sub_double(dstb, src1b, src2b);
10108   %}
10109 
10110   ins_pipe(faddF_reg_reg); // FIXME
10111 %}
10112 
10113 // Shorts/Chars vector mul
10114 instruct vmul4S_reg(vecD dst, vecD src1, vecD src2) %{
10115   predicate(n->as_Vector()->length() == 4);
10116   match(Set dst (MulVS src1 src2));
10117   size(4);
10118   format %{ "VMUL.I16 $dst,$src1,$src2\t! mul packed4S" %}
10119   ins_encode %{
10120     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10121              MacroAssembler::VELEM_SIZE_16, 0);
10122   %}
10123   ins_pipe( ialu_reg_reg ); // FIXME
10124 %}
10125 
10126 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2) %{
10127   predicate(n->as_Vector()->length() == 8);
10128   match(Set dst (MulVS src1 src2));
10129   size(4);
10130   format %{ "VMUL.I16 $dst.Q,$src1.Q,$src2.Q\t! mul packed8S" %}
10131   ins_encode %{
10132     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10133              MacroAssembler::VELEM_SIZE_16, 1);
10134   %}
10135   ins_pipe( ialu_reg_reg ); // FIXME
10136 %}
10137 
10138 // Integers vector mul
10139 instruct vmul2I_reg(vecD dst, vecD src1, vecD src2) %{
10140   predicate(n->as_Vector()->length() == 2);
10141   match(Set dst (MulVI src1 src2));
10142   size(4);
10143   format %{ "VMUL.I32 $dst,$src1,$src2\t! mul packed2I" %}
10144   ins_encode %{
10145     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10146              MacroAssembler::VELEM_SIZE_32, 0);
10147   %}
10148   ins_pipe( ialu_reg_reg ); // FIXME
10149 %}
10150 
10151 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
10152   predicate(n->as_Vector()->length() == 4);
10153   match(Set dst (MulVI src1 src2));
10154   size(4);
10155   format %{ "VMUL.I32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4I" %}
10156   ins_encode %{
10157     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10158              MacroAssembler::VELEM_SIZE_32, 1);
10159   %}
10160   ins_pipe( ialu_reg_reg ); // FIXME
10161 %}
10162 
10163 // Floats vector mul
10164 instruct vmul2F_reg(vecD dst, vecD src1, vecD src2) %{
10165   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
10166   match(Set dst (MulVF src1 src2));
10167   size(4);
10168   format %{ "VMUL.F32 $dst,$src1,$src2\t! mul packed2F" %}
10169   ins_encode %{
10170     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10171              MacroAssembler::VFA_SIZE_F32, 0);
10172   %}
10173   ins_pipe( fmulF_reg_reg ); // FIXME
10174 %}
10175 
10176 instruct vmul2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10177   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
10178   match(Set dst (MulVF src1 src2));
10179   size(4*2);
10180   ins_cost(DEFAULT_COST*2); // FIXME
10181 
10182   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10183             "FMULS  $dst.b,$src1.b,$src2.b" %}
10184   ins_encode %{
10185     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10186     __ mul_float($dst$$FloatRegister->successor(),
10187              $src1$$FloatRegister->successor(),
10188              $src2$$FloatRegister->successor());
10189   %}
10190 
10191   ins_pipe(fmulF_reg_reg); // FIXME
10192 %}
10193 
10194 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
10195   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
10196   match(Set dst (MulVF src1 src2));
10197   size(4);
10198   format %{ "VMUL.F32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4F" %}
10199   ins_encode %{
10200     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10201              MacroAssembler::VFA_SIZE_F32, 1);
10202   %}
10203   ins_pipe( fmulF_reg_reg ); // FIXME
10204 %}
10205 
10206 instruct vmul4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10207   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
10208   match(Set dst (MulVF src1 src2));
10209   size(4*4);
10210   ins_cost(DEFAULT_COST*4); // FIXME
10211 
10212   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10213             "FMULS  $dst.b,$src1.b,$src2.b\n\t"
10214             "FMULS  $dst.c,$src1.c,$src2.c\n\t"
10215             "FMULS  $dst.d,$src1.d,$src2.d" %}
10216 
10217   ins_encode %{
10218     FloatRegister dsta = $dst$$FloatRegister;
10219     FloatRegister src1a = $src1$$FloatRegister;
10220     FloatRegister src2a = $src2$$FloatRegister;
10221     __ mul_float(dsta, src1a, src2a);
10222     FloatRegister dstb = dsta->successor();
10223     FloatRegister src1b = src1a->successor();
10224     FloatRegister src2b = src2a->successor();
10225     __ mul_float(dstb, src1b, src2b);
10226     FloatRegister dstc = dstb->successor();
10227     FloatRegister src1c = src1b->successor();
10228     FloatRegister src2c = src2b->successor();
10229     __ mul_float(dstc, src1c, src2c);
10230     FloatRegister dstd = dstc->successor();
10231     FloatRegister src1d = src1c->successor();
10232     FloatRegister src2d = src2c->successor();
10233     __ mul_float(dstd, src1d, src2d);
10234   %}
10235 
10236   ins_pipe(fmulF_reg_reg); // FIXME
10237 %}
10238 
10239 instruct vmul2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10240   predicate(n->as_Vector()->length() == 2);
10241   match(Set dst (MulVD src1 src2));
10242   size(4*2);
10243   ins_cost(DEFAULT_COST*2); // FIXME
10244 
10245   format %{ "FMULD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10246             "FMULD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10247   ins_encode %{
10248     FloatRegister dsta = $dst$$FloatRegister;
10249     FloatRegister src1a = $src1$$FloatRegister;
10250     FloatRegister src2a = $src2$$FloatRegister;
10251     __ mul_double(dsta, src1a, src2a);
10252     FloatRegister dstb = dsta->successor()->successor();
10253     FloatRegister src1b = src1a->successor()->successor();
10254     FloatRegister src2b = src2a->successor()->successor();
10255     __ mul_double(dstb, src1b, src2b);
10256   %}
10257 
10258   ins_pipe(fmulD_reg_reg); // FIXME
10259 %}
10260 
10261 
10262 // Floats vector div
10263 instruct vdiv2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10264   predicate(n->as_Vector()->length() == 2);
10265   match(Set dst (DivVF src1 src2));
10266   size(4*2);
10267   ins_cost(DEFAULT_COST*2); // FIXME
10268 
10269   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10270             "FDIVS  $dst.b,$src1.b,$src2.b" %}
10271   ins_encode %{
10272     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10273     __ div_float($dst$$FloatRegister->successor(),
10274              $src1$$FloatRegister->successor(),
10275              $src2$$FloatRegister->successor());
10276   %}
10277 
10278   ins_pipe(fdivF_reg_reg); // FIXME
10279 %}
10280 
10281 instruct vdiv4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10282   predicate(n->as_Vector()->length() == 4);
10283   match(Set dst (DivVF src1 src2));
10284   size(4*4);
10285   ins_cost(DEFAULT_COST*4); // FIXME
10286 
10287   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10288             "FDIVS  $dst.b,$src1.b,$src2.b\n\t"
10289             "FDIVS  $dst.c,$src1.c,$src2.c\n\t"
10290             "FDIVS  $dst.d,$src1.d,$src2.d" %}
10291 
10292   ins_encode %{
10293     FloatRegister dsta = $dst$$FloatRegister;
10294     FloatRegister src1a = $src1$$FloatRegister;
10295     FloatRegister src2a = $src2$$FloatRegister;
10296     __ div_float(dsta, src1a, src2a);
10297     FloatRegister dstb = dsta->successor();
10298     FloatRegister src1b = src1a->successor();
10299     FloatRegister src2b = src2a->successor();
10300     __ div_float(dstb, src1b, src2b);
10301     FloatRegister dstc = dstb->successor();
10302     FloatRegister src1c = src1b->successor();
10303     FloatRegister src2c = src2b->successor();
10304     __ div_float(dstc, src1c, src2c);
10305     FloatRegister dstd = dstc->successor();
10306     FloatRegister src1d = src1c->successor();
10307     FloatRegister src2d = src2c->successor();
10308     __ div_float(dstd, src1d, src2d);
10309   %}
10310 
10311   ins_pipe(fdivF_reg_reg); // FIXME
10312 %}
10313 
10314 instruct vdiv2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10315   predicate(n->as_Vector()->length() == 2);
10316   match(Set dst (DivVD src1 src2));
10317   size(4*2);
10318   ins_cost(DEFAULT_COST*2); // FIXME
10319 
10320   format %{ "FDIVD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10321             "FDIVD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10322   ins_encode %{
10323     FloatRegister dsta = $dst$$FloatRegister;
10324     FloatRegister src1a = $src1$$FloatRegister;
10325     FloatRegister src2a = $src2$$FloatRegister;
10326     __ div_double(dsta, src1a, src2a);
10327     FloatRegister dstb = dsta->successor()->successor();
10328     FloatRegister src1b = src1a->successor()->successor();
10329     FloatRegister src2b = src2a->successor()->successor();
10330     __ div_double(dstb, src1b, src2b);
10331   %}
10332 
10333   ins_pipe(fdivD_reg_reg); // FIXME
10334 %}
10335 
10336 // --------------------------------- NEG --------------------------------------
10337 
10338 instruct vneg8B_reg(vecD dst, vecD src) %{
10339   predicate(n->as_Vector()->length_in_bytes() == 8);
10340   effect(DEF dst, USE src);
10341   size(4);
10342   ins_cost(DEFAULT_COST); // FIXME
10343   format %{ "VNEG.S8 $dst.D,$src.D\t! neg packed8B" %}
10344   ins_encode %{
10345     bool quad = false;
10346     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
10347               MacroAssembler::VELEM_SIZE_8, quad);
10348   %}
10349   ins_pipe( ialu_reg_reg ); // FIXME
10350 %}
10351 
10352 instruct vneg16B_reg(vecX dst, vecX src) %{
10353   predicate(n->as_Vector()->length_in_bytes() == 16);
10354   effect(DEF dst, USE src);
10355   size(4);
10356   ins_cost(DEFAULT_COST); // FIXME
10357   format %{ "VNEG.S8 $dst.Q,$src.Q\t! neg0 packed16B" %}
10358   ins_encode %{
10359     bool _float = false;
10360     bool quad = true;
10361     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
10362               MacroAssembler::VELEM_SIZE_8, quad);
10363   %}
10364   ins_pipe( ialu_reg_reg ); // FIXME
10365 %}
10366 
10367 // ------------------------------ Shift ---------------------------------------
10368 
10369 instruct vslcntD(vecD dst, iRegI cnt) %{
10370   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
10371   match(Set dst (LShiftCntV cnt));
10372   size(4);
10373   ins_cost(DEFAULT_COST); // FIXME
10374   expand %{
10375     Repl8B_reg_simd(dst, cnt);
10376   %}
10377 %}
10378 
10379 instruct vslcntX(vecX dst, iRegI cnt) %{
10380   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
10381   match(Set dst (LShiftCntV cnt));
10382   size(4);
10383   ins_cost(DEFAULT_COST); // FIXME
10384   expand %{
10385     Repl16B_reg(dst, cnt);
10386   %}
10387 %}
10388 
10389 // Low bits of vector "shift" elements are used, so it
10390 // doesn't matter if we treat it as ints or bytes here.
10391 instruct vsrcntD(vecD dst, iRegI cnt) %{
10392   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
10393   match(Set dst (RShiftCntV cnt));
10394   size(4*2);
10395   ins_cost(DEFAULT_COST*2); // FIXME
10396 
10397   format %{ "VDUP.8 $dst.D,$cnt\n\t"
10398             "VNEG.S8 $dst.D,$dst.D\t! neg packed8B" %}
10399   ins_encode %{
10400     bool quad = false;
10401     __ vdupI($dst$$FloatRegister, $cnt$$Register,
10402              MacroAssembler::VELEM_SIZE_8, quad);
10403     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
10404               MacroAssembler::VELEM_SIZE_8, quad);
10405   %}
10406   ins_pipe( ialu_reg_reg ); // FIXME
10407 %}
10408 
10409 instruct vsrcntX(vecX dst, iRegI cnt) %{
10410   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
10411   match(Set dst (RShiftCntV cnt));
10412   size(4*2);
10413   ins_cost(DEFAULT_COST*2); // FIXME
10414   format %{ "VDUP.8 $dst.Q,$cnt\n\t"
10415             "VNEG.S8 $dst.Q,$dst.Q\t! neg packed16B" %}
10416   ins_encode %{
10417     bool quad = true;
10418     __ vdupI($dst$$FloatRegister, $cnt$$Register,
10419              MacroAssembler::VELEM_SIZE_8, quad);
10420     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
10421               MacroAssembler::VELEM_SIZE_8, quad);
10422   %}
10423   ins_pipe( ialu_reg_reg ); // FIXME
10424 %}
10425 
10426 // Byte vector logical left/right shift based on sign
10427 instruct vsh8B_reg(vecD dst, vecD src, vecD shift) %{
10428   predicate(n->as_Vector()->length() == 8);
10429   effect(DEF dst, USE src, USE shift);
10430   size(4);
10431   ins_cost(DEFAULT_COST); // FIXME
10432   format %{
10433     "VSHL.U8 $dst.D,$src.D,$shift.D\t! logical left/right shift packed8B"
10434   %}
10435   ins_encode %{
10436     bool quad = false;
10437     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10438               MacroAssembler::VELEM_SIZE_8, quad);
10439   %}
10440   ins_pipe( ialu_reg_reg ); // FIXME
10441 %}
10442 
10443 instruct vsh16B_reg(vecX dst, vecX src, vecX shift) %{
10444   predicate(n->as_Vector()->length() == 16);
10445   effect(DEF dst, USE src, USE shift);
10446   size(4);
10447   ins_cost(DEFAULT_COST); // FIXME
10448   format %{
10449     "VSHL.U8 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed16B"
10450   %}
10451   ins_encode %{
10452     bool quad = true;
10453     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10454               MacroAssembler::VELEM_SIZE_8, quad);
10455   %}
10456   ins_pipe( ialu_reg_reg ); // FIXME
10457 %}
10458 
10459 // Shorts/Char vector logical left/right shift based on sign
10460 instruct vsh4S_reg(vecD dst, vecD src, vecD shift) %{
10461   predicate(n->as_Vector()->length() == 4);
10462   effect(DEF dst, USE src, USE shift);
10463   size(4);
10464   ins_cost(DEFAULT_COST); // FIXME
10465   format %{
10466     "VSHL.U16 $dst.D,$src.D,$shift.D\t! logical left/right shift packed4S"
10467   %}
10468   ins_encode %{
10469     bool quad = false;
10470     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10471               MacroAssembler::VELEM_SIZE_16, quad);
10472   %}
10473   ins_pipe( ialu_reg_reg ); // FIXME
10474 %}
10475 
10476 instruct vsh8S_reg(vecX dst, vecX src, vecX shift) %{
10477   predicate(n->as_Vector()->length() == 8);
10478   effect(DEF dst, USE src, USE shift);
10479   size(4);
10480   ins_cost(DEFAULT_COST); // FIXME
10481   format %{
10482     "VSHL.U16 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed8S"
10483   %}
10484   ins_encode %{
10485     bool quad = true;
10486     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10487               MacroAssembler::VELEM_SIZE_16, quad);
10488   %}
10489   ins_pipe( ialu_reg_reg ); // FIXME
10490 %}
10491 
10492 // Integers vector logical left/right shift based on sign
10493 instruct vsh2I_reg(vecD dst, vecD src, vecD shift) %{
10494   predicate(n->as_Vector()->length() == 2);
10495   effect(DEF dst, USE src, USE shift);
10496   size(4);
10497   ins_cost(DEFAULT_COST); // FIXME
10498   format %{
10499     "VSHL.U32 $dst.D,$src.D,$shift.D\t! logical left/right shift packed2I"
10500   %}
10501   ins_encode %{
10502     bool quad = false;
10503     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10504               MacroAssembler::VELEM_SIZE_32, quad);
10505   %}
10506   ins_pipe( ialu_reg_reg ); // FIXME
10507 %}
10508 
10509 instruct vsh4I_reg(vecX dst, vecX src, vecX shift) %{
10510   predicate(n->as_Vector()->length() == 4);
10511   effect(DEF dst, USE src, USE shift);
10512   size(4);
10513   ins_cost(DEFAULT_COST); // FIXME
10514   format %{
10515     "VSHL.U32 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed4I"
10516   %}
10517   ins_encode %{
10518     bool quad = true;
10519     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10520               MacroAssembler::VELEM_SIZE_32, quad);
10521   %}
10522   ins_pipe( ialu_reg_reg ); // FIXME
10523 %}
10524 
10525 // Longs vector logical left/right shift based on sign
10526 instruct vsh2L_reg(vecX dst, vecX src, vecX shift) %{
10527   predicate(n->as_Vector()->length() == 2);
10528   effect(DEF dst, USE src, USE shift);
10529   size(4);
10530   ins_cost(DEFAULT_COST); // FIXME
10531   format %{
10532     "VSHL.U64 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed2L"
10533   %}
10534   ins_encode %{
10535     bool quad = true;
10536     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10537               MacroAssembler::VELEM_SIZE_64, quad);
10538   %}
10539   ins_pipe( ialu_reg_reg ); // FIXME
10540 %}
10541 
10542 // ------------------------------ LeftShift -----------------------------------
10543 
10544 // Byte vector left shift
10545 instruct vsl8B_reg(vecD dst, vecD src, vecD shift) %{
10546   predicate(n->as_Vector()->length() == 8);
10547   match(Set dst (LShiftVB src shift));
10548   size(4*1);
10549   ins_cost(DEFAULT_COST*1); // FIXME
10550   expand %{
10551     vsh8B_reg(dst, src, shift);
10552   %}
10553 %}
10554 
10555 instruct vsl16B_reg(vecX dst, vecX src, vecX shift) %{
10556   predicate(n->as_Vector()->length() == 16);
10557   match(Set dst (LShiftVB src shift));
10558   size(4*1);
10559   ins_cost(DEFAULT_COST*1); // FIXME
10560   expand %{
10561     vsh16B_reg(dst, src, shift);
10562   %}
10563 %}
10564 
10565 instruct vsl8B_immI(vecD dst, vecD src, immI shift) %{
10566   predicate(n->as_Vector()->length() == 8);
10567   match(Set dst (LShiftVB src shift));
10568   size(4);
10569   ins_cost(DEFAULT_COST); // FIXME
10570   format %{
10571     "VSHL.I8 $dst.D,$src.D,$shift\t! logical left shift packed8B"
10572   %}
10573   ins_encode %{
10574     bool quad = false;
10575     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10576              quad);
10577   %}
10578   ins_pipe( ialu_reg_reg ); // FIXME
10579 %}
10580 
10581 instruct vsl16B_immI(vecX dst, vecX src, immI shift) %{
10582   predicate(n->as_Vector()->length() == 16);
10583   match(Set dst (LShiftVB src shift));
10584   size(4);
10585   ins_cost(DEFAULT_COST); // FIXME
10586   format %{
10587     "VSHL.I8 $dst.Q,$src.Q,$shift\t! logical left shift packed16B"
10588   %}
10589   ins_encode %{
10590     bool quad = true;
10591     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10592              quad);
10593   %}
10594   ins_pipe( ialu_reg_reg ); // FIXME
10595 %}
10596 
10597 // Shorts/Chars vector logical left/right shift
10598 instruct vsl4S_reg(vecD dst, vecD src, vecD shift) %{
10599   predicate(n->as_Vector()->length() == 4);
10600   match(Set dst (LShiftVS src shift));
10601   match(Set dst (URShiftVS src shift));
10602   size(4*1);
10603   ins_cost(DEFAULT_COST*1); // FIXME
10604   expand %{
10605     vsh4S_reg(dst, src, shift);
10606   %}
10607 %}
10608 
10609 instruct vsl8S_reg(vecX dst, vecX src, vecX shift) %{
10610   predicate(n->as_Vector()->length() == 8);
10611   match(Set dst (LShiftVS src shift));
10612   match(Set dst (URShiftVS src shift));
10613   size(4*1);
10614   ins_cost(DEFAULT_COST*1); // FIXME
10615   expand %{
10616     vsh8S_reg(dst, src, shift);
10617   %}
10618 %}
10619 
10620 instruct vsl4S_immI(vecD dst, vecD src, immI shift) %{
10621   predicate(n->as_Vector()->length() == 4);
10622   match(Set dst (LShiftVS src shift));
10623   size(4);
10624   ins_cost(DEFAULT_COST); // FIXME
10625   format %{
10626     "VSHL.I16 $dst.D,$src.D,$shift\t! logical left shift packed4S"
10627   %}
10628   ins_encode %{
10629     bool quad = false;
10630     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10631              quad);
10632   %}
10633   ins_pipe( ialu_reg_reg ); // FIXME
10634 %}
10635 
10636 instruct vsl8S_immI(vecX dst, vecX src, immI shift) %{
10637   predicate(n->as_Vector()->length() == 8);
10638   match(Set dst (LShiftVS src shift));
10639   size(4);
10640   ins_cost(DEFAULT_COST); // FIXME
10641   format %{
10642     "VSHL.I16 $dst.Q,$src.Q,$shift\t! logical left shift packed8S"
10643   %}
10644   ins_encode %{
10645     bool quad = true;
10646     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10647              quad);
10648   %}
10649   ins_pipe( ialu_reg_reg ); // FIXME
10650 %}
10651 
10652 // Integers vector logical left/right shift
10653 instruct vsl2I_reg(vecD dst, vecD src, vecD shift) %{
10654   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10655   match(Set dst (LShiftVI src shift));
10656   match(Set dst (URShiftVI src shift));
10657   size(4*1);
10658   ins_cost(DEFAULT_COST*1); // FIXME
10659   expand %{
10660     vsh2I_reg(dst, src, shift);
10661   %}
10662 %}
10663 
10664 instruct vsl4I_reg(vecX dst, vecX src, vecX shift) %{
10665   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10666   match(Set dst (LShiftVI src shift));
10667   match(Set dst (URShiftVI src shift));
10668   size(4*1);
10669   ins_cost(DEFAULT_COST*1); // FIXME
10670   expand %{
10671     vsh4I_reg(dst, src, shift);
10672   %}
10673 %}
10674 
10675 instruct vsl2I_immI(vecD dst, vecD src, immI shift) %{
10676   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10677   match(Set dst (LShiftVI src shift));
10678   size(4);
10679   ins_cost(DEFAULT_COST); // FIXME
10680   format %{
10681     "VSHL.I32 $dst.D,$src.D,$shift\t! logical left shift packed2I"
10682   %}
10683   ins_encode %{
10684     bool quad = false;
10685     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10686              quad);
10687   %}
10688   ins_pipe( ialu_reg_reg ); // FIXME
10689 %}
10690 
10691 instruct vsl4I_immI(vecX dst, vecX src, immI shift) %{
10692   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10693   match(Set dst (LShiftVI src shift));
10694   size(4);
10695   ins_cost(DEFAULT_COST); // FIXME
10696   format %{
10697     "VSHL.I32 $dst.Q,$src.Q,$shift\t! logical left shift packed4I"
10698   %}
10699   ins_encode %{
10700     bool quad = true;
10701     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10702              quad);
10703   %}
10704   ins_pipe( ialu_reg_reg ); // FIXME
10705 %}
10706 
10707 // Longs vector logical left/right shift
10708 instruct vsl2L_reg(vecX dst, vecX src, vecX shift) %{
10709   predicate(n->as_Vector()->length() == 2);
10710   match(Set dst (LShiftVL src shift));
10711   match(Set dst (URShiftVL src shift));
10712   size(4*1);
10713   ins_cost(DEFAULT_COST*1); // FIXME
10714   expand %{
10715     vsh2L_reg(dst, src, shift);
10716   %}
10717 %}
10718 
10719 instruct vsl2L_immI(vecX dst, vecX src, immI shift) %{
10720   predicate(n->as_Vector()->length() == 2);
10721   match(Set dst (LShiftVL src shift));
10722   size(4);
10723   ins_cost(DEFAULT_COST); // FIXME
10724   format %{
10725     "VSHL.I64 $dst.Q,$src.Q,$shift\t! logical left shift packed2L"
10726   %}
10727   ins_encode %{
10728     bool quad = true;
10729     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
10730              quad);
10731   %}
10732   ins_pipe( ialu_reg_reg ); // FIXME
10733 %}
10734 
10735 // ----------------------- LogicalRightShift -----------------------------------
10736 
10737 // Bytes/Shorts vector logical right shift produces incorrect Java result
10738 // for negative data because java code convert short value into int with
10739 // sign extension before a shift.
10740 
10741 // Chars vector logical right shift
10742 instruct vsrl4S_immI(vecD dst, vecD src, immI shift) %{
10743   predicate(n->as_Vector()->length() == 4);
10744   match(Set dst (URShiftVS src shift));
10745   size(4);
10746   ins_cost(DEFAULT_COST); // FIXME
10747   format %{
10748     "VSHR.U16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
10749   %}
10750   ins_encode %{
10751     bool quad = false;
10752     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10753              quad);
10754   %}
10755   ins_pipe( ialu_reg_reg ); // FIXME
10756 %}
10757 
10758 instruct vsrl8S_immI(vecX dst, vecX src, immI shift) %{
10759   predicate(n->as_Vector()->length() == 8);
10760   match(Set dst (URShiftVS src shift));
10761   size(4);
10762   ins_cost(DEFAULT_COST); // FIXME
10763   format %{
10764     "VSHR.U16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
10765   %}
10766   ins_encode %{
10767     bool quad = true;
10768     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10769              quad);
10770   %}
10771   ins_pipe( ialu_reg_reg ); // FIXME
10772 %}
10773 
10774 // Integers vector logical right shift
10775 instruct vsrl2I_immI(vecD dst, vecD src, immI shift) %{
10776   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10777   match(Set dst (URShiftVI src shift));
10778   size(4);
10779   ins_cost(DEFAULT_COST); // FIXME
10780   format %{
10781     "VSHR.U32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
10782   %}
10783   ins_encode %{
10784     bool quad = false;
10785     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10786              quad);
10787   %}
10788   ins_pipe( ialu_reg_reg ); // FIXME
10789 %}
10790 
10791 instruct vsrl4I_immI(vecX dst, vecX src, immI shift) %{
10792   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10793   match(Set dst (URShiftVI src shift));
10794   size(4);
10795   ins_cost(DEFAULT_COST); // FIXME
10796   format %{
10797     "VSHR.U32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
10798   %}
10799   ins_encode %{
10800     bool quad = true;
10801     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10802              quad);
10803   %}
10804   ins_pipe( ialu_reg_reg ); // FIXME
10805 %}
10806 
10807 // Longs vector logical right shift
10808 instruct vsrl2L_immI(vecX dst, vecX src, immI shift) %{
10809   predicate(n->as_Vector()->length() == 2);
10810   match(Set dst (URShiftVL src shift));
10811   size(4);
10812   ins_cost(DEFAULT_COST); // FIXME
10813   format %{
10814     "VSHR.U64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
10815   %}
10816   ins_encode %{
10817     bool quad = true;
10818     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
10819              quad);
10820   %}
10821   ins_pipe( ialu_reg_reg ); // FIXME
10822 %}
10823 
10824 // ------------------- ArithmeticRightShift -----------------------------------
10825 
10826 // Bytes vector arithmetic left/right shift based on sign
10827 instruct vsha8B_reg(vecD dst, vecD src, vecD shift) %{
10828   predicate(n->as_Vector()->length() == 8);
10829   effect(DEF dst, USE src, USE shift);
10830   size(4);
10831   ins_cost(DEFAULT_COST); // FIXME
10832   format %{
10833     "VSHL.S8 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed8B"
10834   %}
10835   ins_encode %{
10836     bool quad = false;
10837     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10838               MacroAssembler::VELEM_SIZE_8, quad);
10839   %}
10840   ins_pipe( ialu_reg_reg ); // FIXME
10841 %}
10842 
10843 instruct vsha16B_reg(vecX dst, vecX src, vecX shift) %{
10844   predicate(n->as_Vector()->length() == 16);
10845   effect(DEF dst, USE src, USE shift);
10846   size(4);
10847   ins_cost(DEFAULT_COST); // FIXME
10848   format %{
10849     "VSHL.S8 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed16B"
10850   %}
10851   ins_encode %{
10852     bool quad = true;
10853     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10854               MacroAssembler::VELEM_SIZE_8, quad);
10855   %}
10856   ins_pipe( ialu_reg_reg ); // FIXME
10857 %}
10858 
10859 // Shorts vector arithmetic left/right shift based on sign
10860 instruct vsha4S_reg(vecD dst, vecD src, vecD shift) %{
10861   predicate(n->as_Vector()->length() == 4);
10862   effect(DEF dst, USE src, USE shift);
10863   size(4);
10864   ins_cost(DEFAULT_COST); // FIXME
10865   format %{
10866     "VSHL.S16 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed4S"
10867   %}
10868   ins_encode %{
10869     bool quad = false;
10870     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10871               MacroAssembler::VELEM_SIZE_16, quad);
10872   %}
10873   ins_pipe( ialu_reg_reg ); // FIXME
10874 %}
10875 
10876 instruct vsha8S_reg(vecX dst, vecX src, vecX shift) %{
10877   predicate(n->as_Vector()->length() == 8);
10878   effect(DEF dst, USE src, USE shift);
10879   size(4);
10880   ins_cost(DEFAULT_COST); // FIXME
10881   format %{
10882     "VSHL.S16 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed8S"
10883   %}
10884   ins_encode %{
10885     bool quad = true;
10886     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10887               MacroAssembler::VELEM_SIZE_16, quad);
10888   %}
10889   ins_pipe( ialu_reg_reg ); // FIXME
10890 %}
10891 
10892 // Integers vector arithmetic left/right shift based on sign
10893 instruct vsha2I_reg(vecD dst, vecD src, vecD shift) %{
10894   predicate(n->as_Vector()->length() == 2);
10895   effect(DEF dst, USE src, USE shift);
10896   size(4);
10897   ins_cost(DEFAULT_COST); // FIXME
10898   format %{
10899     "VSHL.S32 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed2I"
10900   %}
10901   ins_encode %{
10902     bool quad = false;
10903     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10904               MacroAssembler::VELEM_SIZE_32, quad);
10905   %}
10906   ins_pipe( ialu_reg_reg ); // FIXME
10907 %}
10908 
10909 instruct vsha4I_reg(vecX dst, vecX src, vecX shift) %{
10910   predicate(n->as_Vector()->length() == 4);
10911   effect(DEF dst, USE src, USE shift);
10912   size(4);
10913   ins_cost(DEFAULT_COST); // FIXME
10914   format %{
10915     "VSHL.S32 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed4I"
10916   %}
10917   ins_encode %{
10918     bool quad = true;
10919     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10920               MacroAssembler::VELEM_SIZE_32, quad);
10921   %}
10922   ins_pipe( ialu_reg_reg ); // FIXME
10923 %}
10924 
10925 // Longs vector arithmetic left/right shift based on sign
10926 instruct vsha2L_reg(vecX dst, vecX src, vecX shift) %{
10927   predicate(n->as_Vector()->length() == 2);
10928   effect(DEF dst, USE src, USE shift);
10929   size(4);
10930   ins_cost(DEFAULT_COST); // FIXME
10931   format %{
10932     "VSHL.S64 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed2L"
10933   %}
10934   ins_encode %{
10935     bool quad = true;
10936     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10937               MacroAssembler::VELEM_SIZE_64, quad);
10938   %}
10939   ins_pipe( ialu_reg_reg ); // FIXME
10940 %}
10941 
10942 // Byte vector arithmetic right shift
10943 
10944 instruct vsra8B_reg(vecD dst, vecD src, vecD shift) %{
10945   predicate(n->as_Vector()->length() == 8);
10946   match(Set dst (RShiftVB src shift));
10947   size(4);
10948   ins_cost(DEFAULT_COST); // FIXME
10949   expand %{
10950     vsha8B_reg(dst, src, shift);
10951   %}
10952 %}
10953 
10954 instruct vsrl16B_reg(vecX dst, vecX src, vecX shift) %{
10955   predicate(n->as_Vector()->length() == 16);
10956   match(Set dst (RShiftVB src shift));
10957   size(4);
10958   ins_cost(DEFAULT_COST); // FIXME
10959   expand %{
10960     vsha16B_reg(dst, src, shift);
10961   %}
10962 %}
10963 
10964 instruct vsrl8B_immI(vecD dst, vecD src, immI shift) %{
10965   predicate(n->as_Vector()->length() == 8);
10966   match(Set dst (RShiftVB src shift));
10967   size(4);
10968   ins_cost(DEFAULT_COST); // FIXME
10969   format %{
10970     "VSHR.S8 $dst.D,$src.D,$shift\t! logical right shift packed8B"
10971   %}
10972   ins_encode %{
10973     bool quad = false;
10974     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10975              quad);
10976   %}
10977   ins_pipe( ialu_reg_reg ); // FIXME
10978 %}
10979 
10980 instruct vsrl16B_immI(vecX dst, vecX src, immI shift) %{
10981   predicate(n->as_Vector()->length() == 16);
10982   match(Set dst (RShiftVB src shift));
10983   size(4);
10984   ins_cost(DEFAULT_COST); // FIXME
10985   format %{
10986     "VSHR.S8 $dst.Q,$src.Q,$shift\t! logical right shift packed16B"
10987   %}
10988   ins_encode %{
10989     bool quad = true;
10990     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10991              quad);
10992   %}
10993   ins_pipe( ialu_reg_reg ); // FIXME
10994 %}
10995 
10996 // Shorts vector arithmetic right shift
10997 instruct vsra4S_reg(vecD dst, vecD src, vecD shift) %{
10998   predicate(n->as_Vector()->length() == 4);
10999   match(Set dst (RShiftVS src shift));
11000   size(4);
11001   ins_cost(DEFAULT_COST); // FIXME
11002   expand %{
11003     vsha4S_reg(dst, src, shift);
11004   %}
11005 %}
11006 
11007 instruct vsra8S_reg(vecX dst, vecX src, vecX shift) %{
11008   predicate(n->as_Vector()->length() == 8);
11009   match(Set dst (RShiftVS src shift));
11010   size(4);
11011   ins_cost(DEFAULT_COST); // FIXME
11012   expand %{
11013     vsha8S_reg(dst, src, shift);
11014   %}
11015 %}
11016 
11017 instruct vsra4S_immI(vecD dst, vecD src, immI shift) %{
11018   predicate(n->as_Vector()->length() == 4);
11019   match(Set dst (RShiftVS src shift));
11020   size(4);
11021   ins_cost(DEFAULT_COST); // FIXME
11022   format %{
11023     "VSHR.S16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
11024   %}
11025   ins_encode %{
11026     bool quad = false;
11027     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
11028              quad);
11029   %}
11030   ins_pipe( ialu_reg_reg ); // FIXME
11031 %}
11032 
11033 instruct vsra8S_immI(vecX dst, vecX src, immI shift) %{
11034   predicate(n->as_Vector()->length() == 8);
11035   match(Set dst (RShiftVS src shift));
11036   size(4);
11037   ins_cost(DEFAULT_COST); // FIXME
11038   format %{
11039     "VSHR.S16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
11040   %}
11041   ins_encode %{
11042     bool quad = true;
11043     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
11044              quad);
11045   %}
11046   ins_pipe( ialu_reg_reg ); // FIXME
11047 %}
11048 
11049 // Integers vector arithmetic right shift
11050 instruct vsra2I_reg(vecD dst, vecD src, vecD shift) %{
11051   predicate(n->as_Vector()->length() == 2);
11052   match(Set dst (RShiftVI src shift));
11053   size(4);
11054   ins_cost(DEFAULT_COST); // FIXME
11055   expand %{
11056     vsha2I_reg(dst, src, shift);
11057   %}
11058 %}
11059 
11060 instruct vsra4I_reg(vecX dst, vecX src, vecX shift) %{
11061   predicate(n->as_Vector()->length() == 4);
11062   match(Set dst (RShiftVI src shift));
11063   size(4);
11064   ins_cost(DEFAULT_COST); // FIXME
11065   expand %{
11066     vsha4I_reg(dst, src, shift);
11067   %}
11068 %}
11069 
11070 instruct vsra2I_immI(vecD dst, vecD src, immI shift) %{
11071   predicate(n->as_Vector()->length() == 2);
11072   match(Set dst (RShiftVI src shift));
11073   size(4);
11074   ins_cost(DEFAULT_COST); // FIXME
11075   format %{
11076     "VSHR.S32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
11077   %}
11078   ins_encode %{
11079     bool quad = false;
11080     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11081              quad);
11082   %}
11083   ins_pipe( ialu_reg_reg ); // FIXME
11084 %}
11085 
11086 instruct vsra4I_immI(vecX dst, vecX src, immI shift) %{
11087   predicate(n->as_Vector()->length() == 4);
11088   match(Set dst (RShiftVI src shift));
11089   size(4);
11090   ins_cost(DEFAULT_COST); // FIXME
11091   format %{
11092     "VSHR.S32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
11093   %}
11094   ins_encode %{
11095     bool quad = true;
11096     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11097              quad);
11098   %}
11099   ins_pipe( ialu_reg_reg ); // FIXME
11100 %}
11101 
11102 // Longs vector arithmetic right shift
11103 instruct vsra2L_reg(vecX dst, vecX src, vecX shift) %{
11104   predicate(n->as_Vector()->length() == 2);
11105   match(Set dst (RShiftVL src shift));
11106   size(4);
11107   ins_cost(DEFAULT_COST); // FIXME
11108   expand %{
11109     vsha2L_reg(dst, src, shift);
11110   %}
11111 %}
11112 
11113 instruct vsra2L_immI(vecX dst, vecX src, immI shift) %{
11114   predicate(n->as_Vector()->length() == 2);
11115   match(Set dst (RShiftVL src shift));
11116   size(4);
11117   ins_cost(DEFAULT_COST); // FIXME
11118   format %{
11119     "VSHR.S64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
11120   %}
11121   ins_encode %{
11122     bool quad = true;
11123     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
11124              quad);
11125   %}
11126   ins_pipe( ialu_reg_reg ); // FIXME
11127 %}
11128 
11129 // --------------------------------- AND --------------------------------------
11130 
11131 instruct vandD(vecD dst, vecD src1, vecD src2) %{
11132   predicate(n->as_Vector()->length_in_bytes() == 8);
11133   match(Set dst (AndV src1 src2));
11134   format %{ "VAND    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11135   ins_encode %{
11136     bool quad = false;
11137     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11138              quad);
11139   %}
11140   ins_pipe( ialu_reg_reg ); // FIXME
11141 %}
11142 
11143 instruct vandX(vecX dst, vecX src1, vecX src2) %{
11144   predicate(n->as_Vector()->length_in_bytes() == 16);
11145   match(Set dst (AndV src1 src2));
11146   format %{ "VAND    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11147   ins_encode %{
11148     bool quad = true;
11149     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11150              quad);
11151   %}
11152   ins_pipe( ialu_reg_reg ); // FIXME
11153 %}
11154 
11155 // --------------------------------- OR ---------------------------------------
11156 
11157 instruct vorD(vecD dst, vecD src1, vecD src2) %{
11158   predicate(n->as_Vector()->length_in_bytes() == 8);
11159   match(Set dst (OrV src1 src2));
11160   format %{ "VOR     $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11161   ins_encode %{
11162     bool quad = false;
11163     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11164             quad);
11165   %}
11166   ins_pipe( ialu_reg_reg ); // FIXME
11167 %}
11168 
11169 instruct vorX(vecX dst, vecX src1, vecX src2) %{
11170   predicate(n->as_Vector()->length_in_bytes() == 16);
11171   match(Set dst (OrV src1 src2));
11172   format %{ "VOR     $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11173   ins_encode %{
11174     bool quad = true;
11175     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11176             quad);
11177   %}
11178   ins_pipe( ialu_reg_reg ); // FIXME
11179 %}
11180 
11181 // --------------------------------- XOR --------------------------------------
11182 
11183 instruct vxorD(vecD dst, vecD src1, vecD src2) %{
11184   predicate(n->as_Vector()->length_in_bytes() == 8);
11185   match(Set dst (XorV src1 src2));
11186   format %{ "VXOR    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11187   ins_encode %{
11188     bool quad = false;
11189     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11190              quad);
11191   %}
11192   ins_pipe( ialu_reg_reg ); // FIXME
11193 %}
11194 
11195 instruct vxorX(vecX dst, vecX src1, vecX src2) %{
11196   predicate(n->as_Vector()->length_in_bytes() == 16);
11197   match(Set dst (XorV src1 src2));
11198   format %{ "VXOR    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11199   ins_encode %{
11200     bool quad = true;
11201     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11202              quad);
11203   %}
11204   ins_pipe( ialu_reg_reg ); // FIXME
11205 %}
11206 
11207 
11208 //----------PEEPHOLE RULES-----------------------------------------------------
11209 // These must follow all instruction definitions as they use the names
11210 // defined in the instructions definitions.
11211 //
11212 // peepmatch ( root_instr_name [preceding_instruction]* );
11213 //
11214 // peepconstraint %{
11215 // (instruction_number.operand_name relational_op instruction_number.operand_name
11216 //  [, ...] );
11217 // // instruction numbers are zero-based using left to right order in peepmatch
11218 //
11219 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
11220 // // provide an instruction_number.operand_name for each operand that appears
11221 // // in the replacement instruction's match rule
11222 //
11223 // ---------VM FLAGS---------------------------------------------------------
11224 //
11225 // All peephole optimizations can be turned off using -XX:-OptoPeephole
11226 //
11227 // Each peephole rule is given an identifying number starting with zero and
11228 // increasing by one in the order seen by the parser.  An individual peephole
11229 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
11230 // on the command-line.
11231 //
11232 // ---------CURRENT LIMITATIONS----------------------------------------------
11233 //
11234 // Only match adjacent instructions in same basic block
11235 // Only equality constraints
11236 // Only constraints between operands, not (0.dest_reg == EAX_enc)
11237 // Only one replacement instruction
11238 //
11239 // ---------EXAMPLE----------------------------------------------------------
11240 //
11241 // // pertinent parts of existing instructions in architecture description
11242 // instruct movI(eRegI dst, eRegI src) %{
11243 //   match(Set dst (CopyI src));
11244 // %}
11245 //
11246 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
11247 //   match(Set dst (AddI dst src));
11248 //   effect(KILL cr);
11249 // %}
11250 //
11251 // // Change (inc mov) to lea
11252 // peephole %{
11253 //   // increment preceeded by register-register move
11254 //   peepmatch ( incI_eReg movI );
11255 //   // require that the destination register of the increment
11256 //   // match the destination register of the move
11257 //   peepconstraint ( 0.dst == 1.dst );
11258 //   // construct a replacement instruction that sets
11259 //   // the destination to ( move's source register + one )
11260 //   peepreplace ( incI_eReg_immI1( 0.dst 1.src 0.src ) );
11261 // %}
11262 //
11263 
11264 // // Change load of spilled value to only a spill
11265 // instruct storeI(memory mem, eRegI src) %{
11266 //   match(Set mem (StoreI mem src));
11267 // %}
11268 //
11269 // instruct loadI(eRegI dst, memory mem) %{
11270 //   match(Set dst (LoadI mem));
11271 // %}
11272 //
11273 // peephole %{
11274 //   peepmatch ( loadI storeI );
11275 //   peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
11276 //   peepreplace ( storeI( 1.mem 1.mem 1.src ) );
11277 // %}
11278 
11279 //----------SMARTSPILL RULES---------------------------------------------------
11280 // These must follow all instruction definitions as they use the names
11281 // defined in the instructions definitions.
11282 //
11283 // ARM will probably not have any of these rules due to RISC instruction set.
11284 
11285 //----------PIPELINE-----------------------------------------------------------
11286 // Rules which define the behavior of the target architectures pipeline.