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 instruct castLL( iRegL dst ) %{
5280   match(Set dst (CastLL dst));
5281   format %{ "! castLL of $dst" %}
5282   ins_encode( /*empty encoding*/ );
5283   ins_cost(0);
5284   ins_pipe(empty);
5285 %}
5286 
5287 //----------Arithmetic Instructions--------------------------------------------
5288 // Addition Instructions
5289 // Register Addition
5290 instruct addI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
5291   match(Set dst (AddI src1 src2));
5292 
5293   size(4);
5294   format %{ "add_32 $dst,$src1,$src2\t! int" %}
5295   ins_encode %{
5296     __ add_32($dst$$Register, $src1$$Register, $src2$$Register);
5297   %}
5298   ins_pipe(ialu_reg_reg);
5299 %}
5300 
5301 instruct addshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5302   match(Set dst (AddI (LShiftI src1 src2) src3));
5303 
5304   size(4);
5305   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
5306   ins_encode %{
5307     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
5308   %}
5309   ins_pipe(ialu_reg_reg);
5310 %}
5311 
5312 
5313 instruct addshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
5314   match(Set dst (AddI (LShiftI src1 src2) src3));
5315 
5316   size(4);
5317   format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
5318   ins_encode %{
5319     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
5320   %}
5321   ins_pipe(ialu_reg_reg);
5322 %}
5323 
5324 instruct addsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5325   match(Set dst (AddI (RShiftI src1 src2) src3));
5326 
5327   size(4);
5328   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
5329   ins_encode %{
5330     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
5331   %}
5332   ins_pipe(ialu_reg_reg);
5333 %}
5334 
5335 instruct addsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
5336   match(Set dst (AddI (RShiftI src1 src2) src3));
5337 
5338   size(4);
5339   format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
5340   ins_encode %{
5341     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
5342   %}
5343   ins_pipe(ialu_reg_reg);
5344 %}
5345 
5346 instruct addshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5347   match(Set dst (AddI (URShiftI src1 src2) src3));
5348 
5349   size(4);
5350   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
5351   ins_encode %{
5352     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
5353   %}
5354   ins_pipe(ialu_reg_reg);
5355 %}
5356 
5357 instruct addshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
5358   match(Set dst (AddI (URShiftI src1 src2) src3));
5359 
5360   size(4);
5361   format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
5362   ins_encode %{
5363     __ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
5364   %}
5365   ins_pipe(ialu_reg_reg);
5366 %}
5367 
5368 // Immediate Addition
5369 instruct addI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
5370   match(Set dst (AddI src1 src2));
5371 
5372   size(4);
5373   format %{ "add_32 $dst,$src1,$src2\t! int" %}
5374   ins_encode %{
5375     __ add_32($dst$$Register, $src1$$Register, $src2$$constant);
5376   %}
5377   ins_pipe(ialu_reg_imm);
5378 %}
5379 
5380 // Pointer Register Addition
5381 instruct addP_reg_reg(iRegP dst, iRegP src1, iRegX src2) %{
5382   match(Set dst (AddP src1 src2));
5383 
5384   size(4);
5385   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
5386   ins_encode %{
5387     __ add($dst$$Register, $src1$$Register, $src2$$Register);
5388   %}
5389   ins_pipe(ialu_reg_reg);
5390 %}
5391 
5392 
5393 // shifted iRegX operand
5394 operand shiftedX(iRegX src2, shimmX src3) %{
5395 //constraint(ALLOC_IN_RC(sp_ptr_reg));
5396   match(LShiftX src2 src3);
5397 
5398   op_cost(1);
5399   format %{ "$src2 << $src3" %}
5400   interface(MEMORY_INTER) %{
5401     base($src2);
5402     index(0xff);
5403     scale($src3);
5404     disp(0x0);
5405   %}
5406 %}
5407 
5408 instruct addshlP_reg_reg_imm(iRegP dst, iRegP src1, shiftedX src2) %{
5409   match(Set dst (AddP src1 src2));
5410 
5411   ins_cost(DEFAULT_COST * 3/2);
5412   size(4);
5413   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
5414   ins_encode %{
5415     Register base = reg_to_register_object($src2$$base);
5416     __ add($dst$$Register, $src1$$Register, AsmOperand(base, lsl, $src2$$scale));
5417   %}
5418   ins_pipe(ialu_reg_reg);
5419 %}
5420 
5421 // Pointer Immediate Addition
5422 instruct addP_reg_aimmX(iRegP dst, iRegP src1, aimmX src2) %{
5423   match(Set dst (AddP src1 src2));
5424 
5425   size(4);
5426   format %{ "ADD    $dst,$src1,$src2\t! ptr" %}
5427   ins_encode %{
5428     __ add($dst$$Register, $src1$$Register, $src2$$constant);
5429   %}
5430   ins_pipe(ialu_reg_imm);
5431 %}
5432 
5433 // Long Addition
5434 instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg ccr) %{
5435   match(Set dst (AddL src1 src2));
5436   effect(KILL ccr);
5437   size(8);
5438   format %{ "ADDS    $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
5439             "ADC     $dst.hi,$src1.hi,$src2.hi" %}
5440   ins_encode %{
5441     __ adds($dst$$Register, $src1$$Register, $src2$$Register);
5442     __ adc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
5443   %}
5444   ins_pipe(ialu_reg_reg);
5445 %}
5446 
5447 // TODO
5448 
5449 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
5450 // (hi($con$$constant), lo($con$$constant)) becomes
5451 instruct addL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg ccr) %{
5452   match(Set dst (AddL src1 con));
5453   effect(KILL ccr);
5454   size(8);
5455   format %{ "ADDS    $dst.lo,$src1.lo,$con\t! long\n\t"
5456             "ADC     $dst.hi,$src1.hi,0" %}
5457   ins_encode %{
5458     __ adds($dst$$Register, $src1$$Register, $con$$constant);
5459     __ adc($dst$$Register->successor(), $src1$$Register->successor(), 0);
5460   %}
5461   ins_pipe(ialu_reg_imm);
5462 %}
5463 
5464 //----------Conditional_store--------------------------------------------------
5465 // Conditional-store of the updated heap-top.
5466 // Used during allocation of the shared heap.
5467 // Sets flags (EQ) on success.
5468 
5469 // LoadP-locked.
5470 instruct loadPLocked(iRegP dst, memoryex mem) %{
5471   match(Set dst (LoadPLocked mem));
5472   size(4);
5473   format %{ "LDREX  $dst,$mem" %}
5474   ins_encode %{
5475     __ ldrex($dst$$Register,$mem$$Address);
5476   %}
5477   ins_pipe(iload_mem);
5478 %}
5479 
5480 instruct storePConditional( memoryex heap_top_ptr, iRegP oldval, iRegP newval, iRegI tmp, flagsRegP pcc ) %{
5481   predicate(_kids[1]->_kids[0]->_leaf->Opcode() == Op_LoadPLocked); // only works in conjunction with a LoadPLocked node
5482   match(Set pcc (StorePConditional heap_top_ptr (Binary oldval newval)));
5483   effect( TEMP tmp );
5484   size(8);
5485   format %{ "STREX  $tmp,$newval,$heap_top_ptr\n\t"
5486             "CMP    $tmp, 0" %}
5487   ins_encode %{
5488     __ strex($tmp$$Register, $newval$$Register, $heap_top_ptr$$Address);
5489     __ cmp($tmp$$Register, 0);
5490   %}
5491   ins_pipe( long_memory_op );
5492 %}
5493 
5494 // Conditional-store of an intx value.
5495 instruct storeXConditional( memoryex mem, iRegX oldval, iRegX newval, iRegX tmp, flagsReg icc ) %{
5496   match(Set icc (StoreIConditional mem (Binary oldval newval)));
5497   effect( TEMP tmp );
5498   size(28);
5499   format %{ "loop: \n\t"
5500             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem], DOESN'T set $newval=[$mem] in any case\n\t"
5501             "XORS     $tmp,$tmp, $oldval\n\t"
5502             "STREX.eq $tmp, $newval, $mem\n\t"
5503             "CMP.eq   $tmp, 1 \n\t"
5504             "B.eq     loop \n\t"
5505             "TEQ      $tmp, 0\n\t"
5506             "membar   LoadStore|LoadLoad" %}
5507   ins_encode %{
5508     Label loop;
5509     __ bind(loop);
5510     __ ldrex($tmp$$Register, $mem$$Address);
5511     __ eors($tmp$$Register, $tmp$$Register, $oldval$$Register);
5512     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
5513     __ cmp($tmp$$Register, 1, eq);
5514     __ b(loop, eq);
5515     __ teq($tmp$$Register, 0);
5516     // used by biased locking only. Requires a membar.
5517     __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadStore | MacroAssembler::LoadLoad), noreg);
5518   %}
5519   ins_pipe( long_memory_op );
5520 %}
5521 
5522 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
5523 
5524 instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegLd newval, iRegI res, iRegLd tmp, flagsReg ccr ) %{
5525   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
5526   effect( KILL ccr, TEMP tmp);
5527   size(32);
5528   format %{ "loop: \n\t"
5529             "LDREXD   $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
5530             "CMP      $tmp.lo, $oldval.lo\n\t"
5531             "CMP.eq   $tmp.hi, $oldval.hi\n\t"
5532             "STREXD.eq $tmp, $newval, $mem\n\t"
5533             "MOV.ne   $tmp, 0 \n\t"
5534             "XORS.eq  $tmp,$tmp, 1 \n\t"
5535             "B.eq     loop \n\t"
5536             "MOV      $res, $tmp" %}
5537   ins_encode %{
5538     Label loop;
5539     __ bind(loop);
5540     __ ldrexd($tmp$$Register, $mem$$Address);
5541     __ cmp($tmp$$Register, $oldval$$Register);
5542     __ cmp($tmp$$Register->successor(), $oldval$$Register->successor(), eq);
5543     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address, eq);
5544     __ mov($tmp$$Register, 0, ne);
5545     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
5546     __ b(loop, eq);
5547     __ mov($res$$Register, $tmp$$Register);
5548   %}
5549   ins_pipe( long_memory_op );
5550 %}
5551 
5552 
5553 instruct compareAndSwapI_bool(memoryex mem, iRegI oldval, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
5554   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
5555   effect( KILL ccr, TEMP tmp);
5556   size(28);
5557   format %{ "loop: \n\t"
5558             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
5559             "CMP      $tmp, $oldval\n\t"
5560             "STREX.eq $tmp, $newval, $mem\n\t"
5561             "MOV.ne   $tmp, 0 \n\t"
5562             "XORS.eq  $tmp,$tmp, 1 \n\t"
5563             "B.eq     loop \n\t"
5564             "MOV      $res, $tmp" %}
5565 
5566   ins_encode %{
5567     Label loop;
5568     __ bind(loop);
5569     __ ldrex($tmp$$Register,$mem$$Address);
5570     __ cmp($tmp$$Register, $oldval$$Register);
5571     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
5572     __ mov($tmp$$Register, 0, ne);
5573     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
5574     __ b(loop, eq);
5575     __ mov($res$$Register, $tmp$$Register);
5576   %}
5577   ins_pipe( long_memory_op );
5578 %}
5579 
5580 instruct compareAndSwapP_bool(memoryex mem, iRegP oldval, iRegP newval, iRegI res, iRegI tmp, flagsReg ccr ) %{
5581   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
5582   effect( KILL ccr, TEMP tmp);
5583   size(28);
5584   format %{ "loop: \n\t"
5585             "LDREX    $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
5586             "CMP      $tmp, $oldval\n\t"
5587             "STREX.eq $tmp, $newval, $mem\n\t"
5588             "MOV.ne   $tmp, 0 \n\t"
5589             "EORS.eq  $tmp,$tmp, 1 \n\t"
5590             "B.eq     loop \n\t"
5591             "MOV      $res, $tmp" %}
5592 
5593   ins_encode %{
5594     Label loop;
5595     __ bind(loop);
5596     __ ldrex($tmp$$Register,$mem$$Address);
5597     __ cmp($tmp$$Register, $oldval$$Register);
5598     __ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
5599     __ mov($tmp$$Register, 0, ne);
5600     __ eors($tmp$$Register, $tmp$$Register, 1, eq);
5601     __ b(loop, eq);
5602     __ mov($res$$Register, $tmp$$Register);
5603   %}
5604   ins_pipe( long_memory_op );
5605 %}
5606 
5607 instruct xaddI_aimmI_no_res(memoryex mem, aimmI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
5608   predicate(n->as_LoadStore()->result_not_used());
5609   match(Set dummy (GetAndAddI mem add));
5610   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
5611   size(20);
5612   format %{ "loop: \n\t"
5613             "LDREX    $tmp1, $mem\n\t"
5614             "ADD      $tmp1, $tmp1, $add\n\t"
5615             "STREX    $tmp2, $tmp1, $mem\n\t"
5616             "CMP      $tmp2, 0 \n\t"
5617             "B.ne     loop \n\t" %}
5618 
5619   ins_encode %{
5620     Label loop;
5621     __ bind(loop);
5622     __ ldrex($tmp1$$Register,$mem$$Address);
5623     __ add($tmp1$$Register, $tmp1$$Register, $add$$constant);
5624     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5625     __ cmp($tmp2$$Register, 0);
5626     __ b(loop, ne);
5627   %}
5628   ins_pipe( long_memory_op );
5629 %}
5630 
5631 instruct xaddI_reg_no_res(memoryex mem, iRegI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
5632   predicate(n->as_LoadStore()->result_not_used());
5633   match(Set dummy (GetAndAddI mem add));
5634   effect(KILL ccr, TEMP tmp1, TEMP tmp2);
5635   size(20);
5636   format %{ "loop: \n\t"
5637             "LDREX    $tmp1, $mem\n\t"
5638             "ADD      $tmp1, $tmp1, $add\n\t"
5639             "STREX    $tmp2, $tmp1, $mem\n\t"
5640             "CMP      $tmp2, 0 \n\t"
5641             "B.ne     loop \n\t" %}
5642 
5643   ins_encode %{
5644     Label loop;
5645     __ bind(loop);
5646     __ ldrex($tmp1$$Register,$mem$$Address);
5647     __ add($tmp1$$Register, $tmp1$$Register, $add$$Register);
5648     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5649     __ cmp($tmp2$$Register, 0);
5650     __ b(loop, ne);
5651   %}
5652   ins_pipe( long_memory_op );
5653 %}
5654 
5655 instruct xaddI_aimmI(memoryex mem, aimmI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
5656   match(Set res (GetAndAddI mem add));
5657   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
5658   size(20);
5659   format %{ "loop: \n\t"
5660             "LDREX    $res, $mem\n\t"
5661             "ADD      $tmp1, $res, $add\n\t"
5662             "STREX    $tmp2, $tmp1, $mem\n\t"
5663             "CMP      $tmp2, 0 \n\t"
5664             "B.ne     loop \n\t" %}
5665 
5666   ins_encode %{
5667     Label loop;
5668     __ bind(loop);
5669     __ ldrex($res$$Register,$mem$$Address);
5670     __ add($tmp1$$Register, $res$$Register, $add$$constant);
5671     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5672     __ cmp($tmp2$$Register, 0);
5673     __ b(loop, ne);
5674   %}
5675   ins_pipe( long_memory_op );
5676 %}
5677 
5678 instruct xaddI_reg(memoryex mem, iRegI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
5679   match(Set res (GetAndAddI mem add));
5680   effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
5681   size(20);
5682   format %{ "loop: \n\t"
5683             "LDREX    $res, $mem\n\t"
5684             "ADD      $tmp1, $res, $add\n\t"
5685             "STREX    $tmp2, $tmp1, $mem\n\t"
5686             "CMP      $tmp2, 0 \n\t"
5687             "B.ne     loop \n\t" %}
5688 
5689   ins_encode %{
5690     Label loop;
5691     __ bind(loop);
5692     __ ldrex($res$$Register,$mem$$Address);
5693     __ add($tmp1$$Register, $res$$Register, $add$$Register);
5694     __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5695     __ cmp($tmp2$$Register, 0);
5696     __ b(loop, ne);
5697   %}
5698   ins_pipe( long_memory_op );
5699 %}
5700 
5701 instruct xaddL_reg_no_res(memoryex mem, iRegL add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
5702   predicate(n->as_LoadStore()->result_not_used());
5703   match(Set dummy (GetAndAddL mem add));
5704   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
5705   size(24);
5706   format %{ "loop: \n\t"
5707             "LDREXD   $tmp1, $mem\n\t"
5708             "ADDS     $tmp1.lo, $tmp1.lo, $add.lo\n\t"
5709             "ADC      $tmp1.hi, $tmp1.hi, $add.hi\n\t"
5710             "STREXD   $tmp2, $tmp1, $mem\n\t"
5711             "CMP      $tmp2, 0 \n\t"
5712             "B.ne     loop \n\t" %}
5713 
5714   ins_encode %{
5715     Label loop;
5716     __ bind(loop);
5717     __ ldrexd($tmp1$$Register, $mem$$Address);
5718     __ adds($tmp1$$Register, $tmp1$$Register, $add$$Register);
5719     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), $add$$Register->successor());
5720     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5721     __ cmp($tmp2$$Register, 0);
5722     __ b(loop, ne);
5723   %}
5724   ins_pipe( long_memory_op );
5725 %}
5726 
5727 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
5728 // (hi($con$$constant), lo($con$$constant)) becomes
5729 instruct xaddL_immRot_no_res(memoryex mem, immLlowRot add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
5730   predicate(n->as_LoadStore()->result_not_used());
5731   match(Set dummy (GetAndAddL mem add));
5732   effect( KILL ccr, TEMP tmp1, TEMP tmp2);
5733   size(24);
5734   format %{ "loop: \n\t"
5735             "LDREXD   $tmp1, $mem\n\t"
5736             "ADDS     $tmp1.lo, $tmp1.lo, $add\n\t"
5737             "ADC      $tmp1.hi, $tmp1.hi, 0\n\t"
5738             "STREXD   $tmp2, $tmp1, $mem\n\t"
5739             "CMP      $tmp2, 0 \n\t"
5740             "B.ne     loop \n\t" %}
5741 
5742   ins_encode %{
5743     Label loop;
5744     __ bind(loop);
5745     __ ldrexd($tmp1$$Register, $mem$$Address);
5746     __ adds($tmp1$$Register, $tmp1$$Register, $add$$constant);
5747     __ adc($tmp1$$Register->successor(), $tmp1$$Register->successor(), 0);
5748     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5749     __ cmp($tmp2$$Register, 0);
5750     __ b(loop, ne);
5751   %}
5752   ins_pipe( long_memory_op );
5753 %}
5754 
5755 instruct xaddL_reg(memoryex mem, iRegL add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
5756   match(Set res (GetAndAddL mem add));
5757   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
5758   size(24);
5759   format %{ "loop: \n\t"
5760             "LDREXD   $res, $mem\n\t"
5761             "ADDS     $tmp1.lo, $res.lo, $add.lo\n\t"
5762             "ADC      $tmp1.hi, $res.hi, $add.hi\n\t"
5763             "STREXD   $tmp2, $tmp1, $mem\n\t"
5764             "CMP      $tmp2, 0 \n\t"
5765             "B.ne     loop \n\t" %}
5766 
5767   ins_encode %{
5768     Label loop;
5769     __ bind(loop);
5770     __ ldrexd($res$$Register, $mem$$Address);
5771     __ adds($tmp1$$Register, $res$$Register, $add$$Register);
5772     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), $add$$Register->successor());
5773     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5774     __ cmp($tmp2$$Register, 0);
5775     __ b(loop, ne);
5776   %}
5777   ins_pipe( long_memory_op );
5778 %}
5779 
5780 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
5781 // (hi($con$$constant), lo($con$$constant)) becomes
5782 instruct xaddL_immRot(memoryex mem, immLlowRot add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
5783   match(Set res (GetAndAddL mem add));
5784   effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
5785   size(24);
5786   format %{ "loop: \n\t"
5787             "LDREXD   $res, $mem\n\t"
5788             "ADDS     $tmp1.lo, $res.lo, $add\n\t"
5789             "ADC      $tmp1.hi, $res.hi, 0\n\t"
5790             "STREXD   $tmp2, $tmp1, $mem\n\t"
5791             "CMP      $tmp2, 0 \n\t"
5792             "B.ne     loop \n\t" %}
5793 
5794   ins_encode %{
5795     Label loop;
5796     __ bind(loop);
5797     __ ldrexd($res$$Register, $mem$$Address);
5798     __ adds($tmp1$$Register, $res$$Register, $add$$constant);
5799     __ adc($tmp1$$Register->successor(), $res$$Register->successor(), 0);
5800     __ strexd($tmp2$$Register, $tmp1$$Register, $mem$$Address);
5801     __ cmp($tmp2$$Register, 0);
5802     __ b(loop, ne);
5803   %}
5804   ins_pipe( long_memory_op );
5805 %}
5806 
5807 instruct xchgI(memoryex mem, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr) %{
5808   match(Set res (GetAndSetI mem newval));
5809   effect(KILL ccr, TEMP tmp, TEMP res);
5810   size(16);
5811   format %{ "loop: \n\t"
5812             "LDREX    $res, $mem\n\t"
5813             "STREX    $tmp, $newval, $mem\n\t"
5814             "CMP      $tmp, 0 \n\t"
5815             "B.ne     loop \n\t" %}
5816 
5817   ins_encode %{
5818     Label loop;
5819     __ bind(loop);
5820     __ ldrex($res$$Register,$mem$$Address);
5821     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
5822     __ cmp($tmp$$Register, 0);
5823     __ b(loop, ne);
5824   %}
5825   ins_pipe( long_memory_op );
5826 %}
5827 
5828 instruct xchgL(memoryex mem, iRegLd newval, iRegLd res, iRegI tmp, flagsReg ccr) %{
5829   match(Set res (GetAndSetL mem newval));
5830   effect( KILL ccr, TEMP tmp, TEMP res);
5831   size(16);
5832   format %{ "loop: \n\t"
5833             "LDREXD   $res, $mem\n\t"
5834             "STREXD   $tmp, $newval, $mem\n\t"
5835             "CMP      $tmp, 0 \n\t"
5836             "B.ne     loop \n\t" %}
5837 
5838   ins_encode %{
5839     Label loop;
5840     __ bind(loop);
5841     __ ldrexd($res$$Register, $mem$$Address);
5842     __ strexd($tmp$$Register, $newval$$Register, $mem$$Address);
5843     __ cmp($tmp$$Register, 0);
5844     __ b(loop, ne);
5845   %}
5846   ins_pipe( long_memory_op );
5847 %}
5848 
5849 instruct xchgP(memoryex mem, iRegP newval, iRegP res, iRegI tmp, flagsReg ccr) %{
5850   match(Set res (GetAndSetP mem newval));
5851   effect(KILL ccr, TEMP tmp, TEMP res);
5852   size(16);
5853   format %{ "loop: \n\t"
5854             "LDREX    $res, $mem\n\t"
5855             "STREX    $tmp, $newval, $mem\n\t"
5856             "CMP      $tmp, 0 \n\t"
5857             "B.ne     loop \n\t" %}
5858 
5859   ins_encode %{
5860     Label loop;
5861     __ bind(loop);
5862     __ ldrex($res$$Register,$mem$$Address);
5863     __ strex($tmp$$Register, $newval$$Register, $mem$$Address);
5864     __ cmp($tmp$$Register, 0);
5865     __ b(loop, ne);
5866   %}
5867   ins_pipe( long_memory_op );
5868 %}
5869 
5870 //---------------------
5871 // Subtraction Instructions
5872 // Register Subtraction
5873 instruct subI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
5874   match(Set dst (SubI src1 src2));
5875 
5876   size(4);
5877   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
5878   ins_encode %{
5879     __ sub_32($dst$$Register, $src1$$Register, $src2$$Register);
5880   %}
5881   ins_pipe(ialu_reg_reg);
5882 %}
5883 
5884 instruct subshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5885   match(Set dst (SubI src1 (LShiftI src2 src3)));
5886 
5887   size(4);
5888   format %{ "SUB    $dst,$src1,$src2<<$src3" %}
5889   ins_encode %{
5890     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
5891   %}
5892   ins_pipe(ialu_reg_reg);
5893 %}
5894 
5895 instruct subshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
5896   match(Set dst (SubI src1 (LShiftI src2 src3)));
5897 
5898   size(4);
5899   format %{ "sub_32 $dst,$src1,$src2<<$src3\t! int" %}
5900   ins_encode %{
5901     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
5902   %}
5903   ins_pipe(ialu_reg_reg);
5904 %}
5905 
5906 instruct subsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5907   match(Set dst (SubI src1 (RShiftI src2 src3)));
5908 
5909   size(4);
5910   format %{ "SUB    $dst,$src1,$src2>>$src3" %}
5911   ins_encode %{
5912     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
5913   %}
5914   ins_pipe(ialu_reg_reg);
5915 %}
5916 
5917 instruct subsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
5918   match(Set dst (SubI src1 (RShiftI src2 src3)));
5919 
5920   size(4);
5921   format %{ "sub_32 $dst,$src1,$src2>>$src3\t! int" %}
5922   ins_encode %{
5923     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
5924   %}
5925   ins_pipe(ialu_reg_reg);
5926 %}
5927 
5928 instruct subshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5929   match(Set dst (SubI src1 (URShiftI src2 src3)));
5930 
5931   size(4);
5932   format %{ "SUB    $dst,$src1,$src2>>>$src3" %}
5933   ins_encode %{
5934     __ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
5935   %}
5936   ins_pipe(ialu_reg_reg);
5937 %}
5938 
5939 instruct subshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
5940   match(Set dst (SubI src1 (URShiftI src2 src3)));
5941 
5942   size(4);
5943   format %{ "sub_32 $dst,$src1,$src2>>>$src3\t! int" %}
5944   ins_encode %{
5945     __ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
5946   %}
5947   ins_pipe(ialu_reg_reg);
5948 %}
5949 
5950 instruct rsbshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5951   match(Set dst (SubI (LShiftI src1 src2) src3));
5952 
5953   size(4);
5954   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
5955   ins_encode %{
5956     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
5957   %}
5958   ins_pipe(ialu_reg_reg);
5959 %}
5960 
5961 instruct rsbshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
5962   match(Set dst (SubI (LShiftI src1 src2) src3));
5963 
5964   size(4);
5965   format %{ "RSB    $dst,$src3,$src1<<$src2" %}
5966   ins_encode %{
5967     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
5968   %}
5969   ins_pipe(ialu_reg_reg);
5970 %}
5971 
5972 instruct rsbsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5973   match(Set dst (SubI (RShiftI src1 src2) src3));
5974 
5975   size(4);
5976   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
5977   ins_encode %{
5978     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
5979   %}
5980   ins_pipe(ialu_reg_reg);
5981 %}
5982 
5983 instruct rsbsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
5984   match(Set dst (SubI (RShiftI src1 src2) src3));
5985 
5986   size(4);
5987   format %{ "RSB    $dst,$src3,$src1>>$src2" %}
5988   ins_encode %{
5989     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
5990   %}
5991   ins_pipe(ialu_reg_reg);
5992 %}
5993 
5994 instruct rsbshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
5995   match(Set dst (SubI (URShiftI src1 src2) src3));
5996 
5997   size(4);
5998   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
5999   ins_encode %{
6000     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
6001   %}
6002   ins_pipe(ialu_reg_reg);
6003 %}
6004 
6005 instruct rsbshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
6006   match(Set dst (SubI (URShiftI src1 src2) src3));
6007 
6008   size(4);
6009   format %{ "RSB    $dst,$src3,$src1>>>$src2" %}
6010   ins_encode %{
6011     __ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
6012   %}
6013   ins_pipe(ialu_reg_reg);
6014 %}
6015 
6016 // Immediate Subtraction
6017 instruct subI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
6018   match(Set dst (SubI src1 src2));
6019 
6020   size(4);
6021   format %{ "sub_32 $dst,$src1,$src2\t! int" %}
6022   ins_encode %{
6023     __ sub_32($dst$$Register, $src1$$Register, $src2$$constant);
6024   %}
6025   ins_pipe(ialu_reg_imm);
6026 %}
6027 
6028 instruct subI_reg_immRotneg(iRegI dst, iRegI src1, aimmIneg src2) %{
6029   match(Set dst (AddI src1 src2));
6030 
6031   size(4);
6032   format %{ "sub_32 $dst,$src1,-($src2)\t! int" %}
6033   ins_encode %{
6034     __ sub_32($dst$$Register, $src1$$Register, -$src2$$constant);
6035   %}
6036   ins_pipe(ialu_reg_imm);
6037 %}
6038 
6039 instruct subI_immRot_reg(iRegI dst, immIRot src1, iRegI src2) %{
6040   match(Set dst (SubI src1 src2));
6041 
6042   size(4);
6043   format %{ "RSB    $dst,$src2,src1" %}
6044   ins_encode %{
6045     __ rsb($dst$$Register, $src2$$Register, $src1$$constant);
6046   %}
6047   ins_pipe(ialu_zero_reg);
6048 %}
6049 
6050 // Register Subtraction
6051 instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg icc ) %{
6052   match(Set dst (SubL src1 src2));
6053   effect (KILL icc);
6054 
6055   size(8);
6056   format %{ "SUBS   $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
6057             "SBC    $dst.hi,$src1.hi,$src2.hi" %}
6058   ins_encode %{
6059     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
6060     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
6061   %}
6062   ins_pipe(ialu_reg_reg);
6063 %}
6064 
6065 // TODO
6066 
6067 // Immediate Subtraction
6068 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6069 // (hi($con$$constant), lo($con$$constant)) becomes
6070 instruct subL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg icc) %{
6071   match(Set dst (SubL src1 con));
6072   effect (KILL icc);
6073 
6074   size(8);
6075   format %{ "SUB    $dst.lo,$src1.lo,$con\t! long\n\t"
6076             "SBC    $dst.hi,$src1.hi,0" %}
6077   ins_encode %{
6078     __ subs($dst$$Register, $src1$$Register, $con$$constant);
6079     __ sbc($dst$$Register->successor(), $src1$$Register->successor(), 0);
6080   %}
6081   ins_pipe(ialu_reg_imm);
6082 %}
6083 
6084 // Long negation
6085 instruct negL_reg_reg(iRegL dst, immL0 zero, iRegL src2, flagsReg icc) %{
6086   match(Set dst (SubL zero src2));
6087   effect (KILL icc);
6088 
6089   size(8);
6090   format %{ "RSBS   $dst.lo,$src2.lo,0\t! long\n\t"
6091             "RSC    $dst.hi,$src2.hi,0" %}
6092   ins_encode %{
6093     __ rsbs($dst$$Register, $src2$$Register, 0);
6094     __ rsc($dst$$Register->successor(), $src2$$Register->successor(), 0);
6095   %}
6096   ins_pipe(ialu_zero_reg);
6097 %}
6098 
6099 // Multiplication Instructions
6100 // Integer Multiplication
6101 // Register Multiplication
6102 instruct mulI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6103   match(Set dst (MulI src1 src2));
6104 
6105   size(4);
6106   format %{ "mul_32 $dst,$src1,$src2" %}
6107   ins_encode %{
6108     __ mul_32($dst$$Register, $src1$$Register, $src2$$Register);
6109   %}
6110   ins_pipe(imul_reg_reg);
6111 %}
6112 
6113 instruct mulL_lo1_hi2(iRegL dst, iRegL src1, iRegL src2) %{
6114   effect(DEF dst, USE src1, USE src2);
6115   size(4);
6116   format %{ "MUL  $dst.hi,$src1.lo,$src2.hi\t! long" %}
6117   ins_encode %{
6118     __ mul($dst$$Register->successor(), $src1$$Register, $src2$$Register->successor());
6119   %}
6120   ins_pipe(imul_reg_reg);
6121 %}
6122 
6123 instruct mulL_hi1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
6124   effect(USE_DEF dst, USE src1, USE src2);
6125   size(8);
6126   format %{ "MLA  $dst.hi,$src1.hi,$src2.lo,$dst.hi\t! long\n\t"
6127             "MOV  $dst.lo, 0"%}
6128   ins_encode %{
6129     __ mla($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register, $dst$$Register->successor());
6130     __ mov($dst$$Register, 0);
6131   %}
6132   ins_pipe(imul_reg_reg);
6133 %}
6134 
6135 instruct mulL_lo1_lo2(iRegL dst, iRegL src1, iRegL src2) %{
6136   effect(USE_DEF dst, USE src1, USE src2);
6137   size(4);
6138   format %{ "UMLAL  $dst.lo,$dst.hi,$src1,$src2\t! long" %}
6139   ins_encode %{
6140     __ umlal($dst$$Register, $dst$$Register->successor(), $src1$$Register, $src2$$Register);
6141   %}
6142   ins_pipe(imul_reg_reg);
6143 %}
6144 
6145 instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
6146   match(Set dst (MulL src1 src2));
6147 
6148   expand %{
6149     mulL_lo1_hi2(dst, src1, src2);
6150     mulL_hi1_lo2(dst, src1, src2);
6151     mulL_lo1_lo2(dst, src1, src2);
6152   %}
6153 %}
6154 
6155 // Integer Division
6156 // Register Division
6157 instruct divI_reg_reg(R1RegI dst, R0RegI src1, R2RegI src2, LRRegP lr, flagsReg ccr) %{
6158   match(Set dst (DivI src1 src2));
6159   effect( KILL ccr, KILL src1, KILL src2, KILL lr);
6160   ins_cost((2+71)*DEFAULT_COST);
6161 
6162   format %{ "DIV   $dst,$src1,$src2 ! call to StubRoutines::Arm::idiv_irem_entry()" %}
6163   ins_encode %{
6164     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
6165   %}
6166   ins_pipe(sdiv_reg_reg);
6167 %}
6168 
6169 // Register Long Division
6170 instruct divL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
6171   match(Set dst (DivL src1 src2));
6172   effect(CALL);
6173   ins_cost(DEFAULT_COST*71);
6174   format %{ "DIVL  $src1,$src2,$dst\t! long ! call to SharedRuntime::ldiv" %}
6175   ins_encode %{
6176     address target = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);
6177     __ call(target, relocInfo::runtime_call_type);
6178   %}
6179   ins_pipe(divL_reg_reg);
6180 %}
6181 
6182 // Integer Remainder
6183 // Register Remainder
6184 instruct modI_reg_reg(R0RegI dst, R0RegI src1, R2RegI src2, R1RegI temp, LRRegP lr, flagsReg ccr ) %{
6185   match(Set dst (ModI src1 src2));
6186   effect( KILL ccr, KILL temp, KILL src2, KILL lr);
6187 
6188   format %{ "MODI   $dst,$src1,$src2\t ! call to StubRoutines::Arm::idiv_irem_entry" %}
6189   ins_encode %{
6190     __ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
6191   %}
6192   ins_pipe(sdiv_reg_reg);
6193 %}
6194 
6195 // Register Long Remainder
6196 instruct modL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
6197   match(Set dst (ModL src1 src2));
6198   effect(CALL);
6199   ins_cost(MEMORY_REF_COST); // FIXME
6200   format %{ "modL    $dst,$src1,$src2\t ! call to SharedRuntime::lrem" %}
6201   ins_encode %{
6202     address target = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
6203     __ call(target, relocInfo::runtime_call_type);
6204   %}
6205   ins_pipe(divL_reg_reg);
6206 %}
6207 
6208 // Integer Shift Instructions
6209 
6210 // Register Shift Left
6211 instruct shlI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6212   match(Set dst (LShiftI src1 src2));
6213 
6214   size(4);
6215   format %{ "LSL  $dst,$src1,$src2 \n\t" %}
6216   ins_encode %{
6217     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
6218   %}
6219   ins_pipe(ialu_reg_reg);
6220 %}
6221 
6222 // Register Shift Left Immediate
6223 instruct shlI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
6224   match(Set dst (LShiftI src1 src2));
6225 
6226   size(4);
6227   format %{ "LSL    $dst,$src1,$src2\t! int" %}
6228   ins_encode %{
6229     __ logical_shift_left($dst$$Register, $src1$$Register, $src2$$constant);
6230   %}
6231   ins_pipe(ialu_reg_imm);
6232 %}
6233 
6234 instruct shlL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
6235   effect(USE_DEF dst, USE src1, USE src2);
6236   size(4);
6237   format %{"OR  $dst.hi,$dst.hi,($src1.hi << $src2)"  %}
6238   ins_encode %{
6239     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$Register));
6240   %}
6241   ins_pipe(ialu_reg_reg);
6242 %}
6243 
6244 instruct shlL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
6245   effect(USE_DEF dst, USE src1, USE src2);
6246   size(4);
6247   format %{ "LSL  $dst.lo,$src1.lo,$src2 \n\t" %}
6248   ins_encode %{
6249     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
6250   %}
6251   ins_pipe(ialu_reg_reg);
6252 %}
6253 
6254 instruct shlL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
6255   effect(DEF dst, USE src1, USE src2, KILL ccr);
6256   size(16);
6257   format %{ "SUBS  $dst.hi,$src2,32 \n\t"
6258             "LSLpl $dst.hi,$src1.lo,$dst.hi \n\t"
6259             "RSBmi $dst.hi,$dst.hi,0 \n\t"
6260             "LSRmi $dst.hi,$src1.lo,$dst.hi" %}
6261 
6262   ins_encode %{
6263     // $src1$$Register and $dst$$Register->successor() can't be the same
6264     __ subs($dst$$Register->successor(), $src2$$Register, 32);
6265     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $dst$$Register->successor()), pl);
6266     __ rsb($dst$$Register->successor(), $dst$$Register->successor(), 0, mi);
6267     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsr, $dst$$Register->successor()), mi);
6268   %}
6269   ins_pipe(ialu_reg_reg);
6270 %}
6271 
6272 instruct shlL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
6273   match(Set dst (LShiftL src1 src2));
6274 
6275   expand %{
6276     flagsReg ccr;
6277     shlL_reg_reg_overlap(dst, src1, src2, ccr);
6278     shlL_reg_reg_merge_hi(dst, src1, src2);
6279     shlL_reg_reg_merge_lo(dst, src1, src2);
6280   %}
6281 %}
6282 
6283 // Register Shift Left Immediate
6284 instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
6285   match(Set dst (LShiftL src1 src2));
6286 
6287   size(8);
6288   format %{ "LSL   $dst.hi,$src1.lo,$src2-32\t! or mov if $src2==32\n\t"
6289             "MOV   $dst.lo, 0" %}
6290   ins_encode %{
6291     if ($src2$$constant == 32) {
6292       __ mov($dst$$Register->successor(), $src1$$Register);
6293     } else {
6294       __ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsl, $src2$$constant-32));
6295     }
6296     __ mov($dst$$Register, 0);
6297   %}
6298   ins_pipe(ialu_reg_imm);
6299 %}
6300 
6301 instruct shlL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
6302   match(Set dst (LShiftL src1 src2));
6303 
6304   size(12);
6305   format %{ "LSL   $dst.hi,$src1.lo,$src2\n\t"
6306             "OR    $dst.hi, $dst.hi, $src1.lo >> 32-$src2\n\t"
6307             "LSL   $dst.lo,$src1.lo,$src2" %}
6308   ins_encode %{
6309     // The order of the following 3 instructions matters: src1.lo and
6310     // dst.hi can't overlap but src.hi and dst.hi can.
6311     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsl, $src2$$constant));
6312     __ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register, lsr, 32-$src2$$constant));
6313     __ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
6314   %}
6315   ins_pipe(ialu_reg_imm);
6316 %}
6317 
6318 // Register Arithmetic Shift Right
6319 instruct sarI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6320   match(Set dst (RShiftI src1 src2));
6321   size(4);
6322   format %{ "ASR    $dst,$src1,$src2\t! int" %}
6323   ins_encode %{
6324     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
6325   %}
6326   ins_pipe(ialu_reg_reg);
6327 %}
6328 
6329 // Register Arithmetic Shift Right Immediate
6330 instruct sarI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
6331   match(Set dst (RShiftI src1 src2));
6332 
6333   size(4);
6334   format %{ "ASR    $dst,$src1,$src2" %}
6335   ins_encode %{
6336     __ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
6337   %}
6338   ins_pipe(ialu_reg_imm);
6339 %}
6340 
6341 // Register Shift Right Arithmetic Long
6342 instruct sarL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
6343   effect(USE_DEF dst, USE src1, USE src2);
6344   size(4);
6345   format %{ "OR  $dst.lo,$dst.lo,($src1.lo >> $src2)"  %}
6346   ins_encode %{
6347     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
6348   %}
6349   ins_pipe(ialu_reg_reg);
6350 %}
6351 
6352 instruct sarL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
6353   effect(USE_DEF dst, USE src1, USE src2);
6354   size(4);
6355   format %{ "ASR  $dst.hi,$src1.hi,$src2 \n\t" %}
6356   ins_encode %{
6357     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$Register));
6358   %}
6359   ins_pipe(ialu_reg_reg);
6360 %}
6361 
6362 instruct sarL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
6363   effect(DEF dst, USE src1, USE src2, KILL ccr);
6364   size(16);
6365   format %{ "SUBS  $dst.lo,$src2,32 \n\t"
6366             "ASRpl $dst.lo,$src1.hi,$dst.lo \n\t"
6367             "RSBmi $dst.lo,$dst.lo,0 \n\t"
6368             "LSLmi $dst.lo,$src1.hi,$dst.lo" %}
6369 
6370   ins_encode %{
6371     // $src1$$Register->successor() and $dst$$Register can't be the same
6372     __ subs($dst$$Register, $src2$$Register, 32);
6373     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $dst$$Register), pl);
6374     __ rsb($dst$$Register, $dst$$Register, 0, mi);
6375     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
6376   %}
6377   ins_pipe(ialu_reg_reg);
6378 %}
6379 
6380 instruct sarL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
6381   match(Set dst (RShiftL src1 src2));
6382 
6383   expand %{
6384     flagsReg ccr;
6385     sarL_reg_reg_overlap(dst, src1, src2, ccr);
6386     sarL_reg_reg_merge_lo(dst, src1, src2);
6387     sarL_reg_reg_merge_hi(dst, src1, src2);
6388   %}
6389 %}
6390 
6391 // Register Shift Left Immediate
6392 instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
6393   match(Set dst (RShiftL src1 src2));
6394 
6395   size(8);
6396   format %{ "ASR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
6397             "ASR   $dst.hi,$src1.hi, $src2" %}
6398   ins_encode %{
6399     if ($src2$$constant == 32) {
6400       __ mov($dst$$Register, $src1$$Register->successor());
6401     } else{
6402       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), asr, $src2$$constant-32));
6403     }
6404     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, 0));
6405   %}
6406 
6407   ins_pipe(ialu_reg_imm);
6408 %}
6409 
6410 instruct sarL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
6411   match(Set dst (RShiftL src1 src2));
6412   size(12);
6413   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
6414             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
6415             "ASR   $dst.hi,$src1.hi,$src2" %}
6416   ins_encode %{
6417     // The order of the following 3 instructions matters: src1.lo and
6418     // dst.hi can't overlap but src.hi and dst.hi can.
6419     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
6420     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
6421     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$constant));
6422   %}
6423   ins_pipe(ialu_reg_imm);
6424 %}
6425 
6426 // Register Shift Right
6427 instruct shrI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6428   match(Set dst (URShiftI src1 src2));
6429   size(4);
6430   format %{ "LSR    $dst,$src1,$src2\t! int" %}
6431   ins_encode %{
6432     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
6433   %}
6434   ins_pipe(ialu_reg_reg);
6435 %}
6436 
6437 // Register Shift Right Immediate
6438 instruct shrI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
6439   match(Set dst (URShiftI src1 src2));
6440 
6441   size(4);
6442   format %{ "LSR    $dst,$src1,$src2" %}
6443   ins_encode %{
6444     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
6445   %}
6446   ins_pipe(ialu_reg_imm);
6447 %}
6448 
6449 // Register Shift Right
6450 instruct shrL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
6451   effect(USE_DEF dst, USE src1, USE src2);
6452   size(4);
6453   format %{ "OR   $dst.lo,$dst,($src1.lo >>> $src2)"  %}
6454   ins_encode %{
6455     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
6456   %}
6457   ins_pipe(ialu_reg_reg);
6458 %}
6459 
6460 instruct shrL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
6461   effect(USE_DEF dst, USE src1, USE src2);
6462   size(4);
6463   format %{ "LSR  $dst.hi,$src1.hi,$src2 \n\t" %}
6464   ins_encode %{
6465     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$Register));
6466   %}
6467   ins_pipe(ialu_reg_reg);
6468 %}
6469 
6470 instruct shrL_reg_reg_overlap(iRegL dst, iRegL src1, iRegI src2, flagsReg ccr) %{
6471   effect(DEF dst, USE src1, USE src2, KILL ccr);
6472   size(16);
6473   format %{ "SUBS  $dst,$src2,32 \n\t"
6474             "LSRpl $dst,$src1.hi,$dst \n\t"
6475             "RSBmi $dst,$dst,0 \n\t"
6476             "LSLmi $dst,$src1.hi,$dst" %}
6477 
6478   ins_encode %{
6479     // $src1$$Register->successor() and $dst$$Register can't be the same
6480     __ subs($dst$$Register, $src2$$Register, 32);
6481     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $dst$$Register), pl);
6482     __ rsb($dst$$Register, $dst$$Register, 0, mi);
6483     __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
6484   %}
6485   ins_pipe(ialu_reg_reg);
6486 %}
6487 
6488 instruct shrL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
6489   match(Set dst (URShiftL src1 src2));
6490 
6491   expand %{
6492     flagsReg ccr;
6493     shrL_reg_reg_overlap(dst, src1, src2, ccr);
6494     shrL_reg_reg_merge_lo(dst, src1, src2);
6495     shrL_reg_reg_merge_hi(dst, src1, src2);
6496   %}
6497 %}
6498 
6499 // Register Shift Right Immediate
6500 instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
6501   match(Set dst (URShiftL src1 src2));
6502 
6503   size(8);
6504   format %{ "LSR   $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
6505             "MOV   $dst.hi, 0" %}
6506   ins_encode %{
6507     if ($src2$$constant == 32) {
6508       __ mov($dst$$Register, $src1$$Register->successor());
6509     } else {
6510       __ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsr, $src2$$constant-32));
6511     }
6512     __ mov($dst$$Register->successor(), 0);
6513   %}
6514 
6515   ins_pipe(ialu_reg_imm);
6516 %}
6517 
6518 instruct shrL_reg_imm5(iRegL dst, iRegL src1, immU5 src2) %{
6519   match(Set dst (URShiftL src1 src2));
6520 
6521   size(12);
6522   format %{ "LSR   $dst.lo,$src1.lo,$src2\n\t"
6523             "OR    $dst.lo, $dst.lo, $src1.hi << 32-$src2\n\t"
6524             "LSR   $dst.hi,$src1.hi,$src2" %}
6525   ins_encode %{
6526     // The order of the following 3 instructions matters: src1.lo and
6527     // dst.hi can't overlap but src.hi and dst.hi can.
6528     __ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
6529     __ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
6530     __ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$constant));
6531   %}
6532   ins_pipe(ialu_reg_imm);
6533 %}
6534 
6535 
6536 instruct shrP_reg_imm5(iRegX dst, iRegP src1, immU5 src2) %{
6537   match(Set dst (URShiftI (CastP2X src1) src2));
6538   size(4);
6539   format %{ "LSR    $dst,$src1,$src2\t! Cast ptr $src1 to int and shift" %}
6540   ins_encode %{
6541     __ logical_shift_right($dst$$Register, $src1$$Register, $src2$$constant);
6542   %}
6543   ins_pipe(ialu_reg_imm);
6544 %}
6545 
6546 //----------Floating Point Arithmetic Instructions-----------------------------
6547 
6548 //  Add float single precision
6549 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
6550   match(Set dst (AddF src1 src2));
6551 
6552   size(4);
6553   format %{ "FADDS  $dst,$src1,$src2" %}
6554   ins_encode %{
6555     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6556   %}
6557 
6558   ins_pipe(faddF_reg_reg);
6559 %}
6560 
6561 //  Add float double precision
6562 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
6563   match(Set dst (AddD src1 src2));
6564 
6565   size(4);
6566   format %{ "FADDD  $dst,$src1,$src2" %}
6567   ins_encode %{
6568     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6569   %}
6570 
6571   ins_pipe(faddD_reg_reg);
6572 %}
6573 
6574 //  Sub float single precision
6575 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
6576   match(Set dst (SubF src1 src2));
6577 
6578   size(4);
6579   format %{ "FSUBS  $dst,$src1,$src2" %}
6580   ins_encode %{
6581     __ sub_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6582   %}
6583   ins_pipe(faddF_reg_reg);
6584 %}
6585 
6586 //  Sub float double precision
6587 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
6588   match(Set dst (SubD src1 src2));
6589 
6590   size(4);
6591   format %{ "FSUBD  $dst,$src1,$src2" %}
6592   ins_encode %{
6593     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6594   %}
6595   ins_pipe(faddD_reg_reg);
6596 %}
6597 
6598 //  Mul float single precision
6599 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
6600   match(Set dst (MulF src1 src2));
6601 
6602   size(4);
6603   format %{ "FMULS  $dst,$src1,$src2" %}
6604   ins_encode %{
6605     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6606   %}
6607 
6608   ins_pipe(fmulF_reg_reg);
6609 %}
6610 
6611 //  Mul float double precision
6612 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
6613   match(Set dst (MulD src1 src2));
6614 
6615   size(4);
6616   format %{ "FMULD  $dst,$src1,$src2" %}
6617   ins_encode %{
6618     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6619   %}
6620 
6621   ins_pipe(fmulD_reg_reg);
6622 %}
6623 
6624 //  Div float single precision
6625 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
6626   match(Set dst (DivF src1 src2));
6627 
6628   size(4);
6629   format %{ "FDIVS  $dst,$src1,$src2" %}
6630   ins_encode %{
6631     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6632   %}
6633 
6634   ins_pipe(fdivF_reg_reg);
6635 %}
6636 
6637 //  Div float double precision
6638 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
6639   match(Set dst (DivD src1 src2));
6640 
6641   size(4);
6642   format %{ "FDIVD  $dst,$src1,$src2" %}
6643   ins_encode %{
6644     __ div_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
6645   %}
6646 
6647   ins_pipe(fdivD_reg_reg);
6648 %}
6649 
6650 //  Absolute float double precision
6651 instruct absD_reg(regD dst, regD src) %{
6652   match(Set dst (AbsD src));
6653 
6654   size(4);
6655   format %{ "FABSd  $dst,$src" %}
6656   ins_encode %{
6657     __ abs_double($dst$$FloatRegister, $src$$FloatRegister);
6658   %}
6659   ins_pipe(faddD_reg);
6660 %}
6661 
6662 //  Absolute float single precision
6663 instruct absF_reg(regF dst, regF src) %{
6664   match(Set dst (AbsF src));
6665   format %{ "FABSs  $dst,$src" %}
6666   ins_encode %{
6667     __ abs_float($dst$$FloatRegister, $src$$FloatRegister);
6668   %}
6669   ins_pipe(faddF_reg);
6670 %}
6671 
6672 instruct negF_reg(regF dst, regF src) %{
6673   match(Set dst (NegF src));
6674 
6675   size(4);
6676   format %{ "FNEGs  $dst,$src" %}
6677   ins_encode %{
6678     __ neg_float($dst$$FloatRegister, $src$$FloatRegister);
6679   %}
6680   ins_pipe(faddF_reg);
6681 %}
6682 
6683 instruct negD_reg(regD dst, regD src) %{
6684   match(Set dst (NegD src));
6685 
6686   format %{ "FNEGd  $dst,$src" %}
6687   ins_encode %{
6688     __ neg_double($dst$$FloatRegister, $src$$FloatRegister);
6689   %}
6690   ins_pipe(faddD_reg);
6691 %}
6692 
6693 //  Sqrt float double precision
6694 instruct sqrtF_reg_reg(regF dst, regF src) %{
6695   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
6696 
6697   size(4);
6698   format %{ "FSQRTS $dst,$src" %}
6699   ins_encode %{
6700     __ sqrt_float($dst$$FloatRegister, $src$$FloatRegister);
6701   %}
6702   ins_pipe(fdivF_reg_reg);
6703 %}
6704 
6705 //  Sqrt float double precision
6706 instruct sqrtD_reg_reg(regD dst, regD src) %{
6707   match(Set dst (SqrtD src));
6708 
6709   size(4);
6710   format %{ "FSQRTD $dst,$src" %}
6711   ins_encode %{
6712     __ sqrt_double($dst$$FloatRegister, $src$$FloatRegister);
6713   %}
6714   ins_pipe(fdivD_reg_reg);
6715 %}
6716 
6717 //----------Logical Instructions-----------------------------------------------
6718 // And Instructions
6719 // Register And
6720 instruct andI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6721   match(Set dst (AndI src1 src2));
6722 
6723   size(4);
6724   format %{ "and_32 $dst,$src1,$src2" %}
6725   ins_encode %{
6726     __ and_32($dst$$Register, $src1$$Register, $src2$$Register);
6727   %}
6728   ins_pipe(ialu_reg_reg);
6729 %}
6730 
6731 instruct andshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6732   match(Set dst (AndI src1 (LShiftI src2 src3)));
6733 
6734   size(4);
6735   format %{ "AND    $dst,$src1,$src2<<$src3" %}
6736   ins_encode %{
6737     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
6738   %}
6739   ins_pipe(ialu_reg_reg);
6740 %}
6741 
6742 instruct andshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6743   match(Set dst (AndI src1 (LShiftI src2 src3)));
6744 
6745   size(4);
6746   format %{ "and_32 $dst,$src1,$src2<<$src3" %}
6747   ins_encode %{
6748     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
6749   %}
6750   ins_pipe(ialu_reg_reg);
6751 %}
6752 
6753 instruct andsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6754   match(Set dst (AndI src1 (RShiftI src2 src3)));
6755 
6756   size(4);
6757   format %{ "AND    $dst,$src1,$src2>>$src3" %}
6758   ins_encode %{
6759     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
6760   %}
6761   ins_pipe(ialu_reg_reg);
6762 %}
6763 
6764 instruct andsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6765   match(Set dst (AndI src1 (RShiftI src2 src3)));
6766 
6767   size(4);
6768   format %{ "and_32 $dst,$src1,$src2>>$src3" %}
6769   ins_encode %{
6770     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
6771   %}
6772   ins_pipe(ialu_reg_reg);
6773 %}
6774 
6775 instruct andshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6776   match(Set dst (AndI src1 (URShiftI src2 src3)));
6777 
6778   size(4);
6779   format %{ "AND    $dst,$src1,$src2>>>$src3" %}
6780   ins_encode %{
6781     __ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
6782   %}
6783   ins_pipe(ialu_reg_reg);
6784 %}
6785 
6786 instruct andshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6787   match(Set dst (AndI src1 (URShiftI src2 src3)));
6788 
6789   size(4);
6790   format %{ "and_32 $dst,$src1,$src2>>>$src3" %}
6791   ins_encode %{
6792     __ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
6793   %}
6794   ins_pipe(ialu_reg_reg);
6795 %}
6796 
6797 // Immediate And
6798 instruct andI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
6799   match(Set dst (AndI src1 src2));
6800 
6801   size(4);
6802   format %{ "and_32 $dst,$src1,$src2\t! int" %}
6803   ins_encode %{
6804     __ and_32($dst$$Register, $src1$$Register, $src2$$constant);
6805   %}
6806   ins_pipe(ialu_reg_imm);
6807 %}
6808 
6809 instruct andI_reg_limmn(iRegI dst, iRegI src1, limmIn src2) %{
6810   match(Set dst (AndI src1 src2));
6811 
6812   size(4);
6813   format %{ "bic    $dst,$src1,~$src2\t! int" %}
6814   ins_encode %{
6815     __ bic($dst$$Register, $src1$$Register, ~$src2$$constant);
6816   %}
6817   ins_pipe(ialu_reg_imm);
6818 %}
6819 
6820 // Register And Long
6821 instruct andL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
6822   match(Set dst (AndL src1 src2));
6823 
6824   ins_cost(DEFAULT_COST);
6825   size(8);
6826   format %{ "AND    $dst,$src1,$src2\t! long" %}
6827   ins_encode %{
6828     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
6829     __ andr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
6830   %}
6831   ins_pipe(ialu_reg_reg);
6832 %}
6833 
6834 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6835 // (hi($con$$constant), lo($con$$constant)) becomes
6836 instruct andL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
6837   match(Set dst (AndL src1 con));
6838   ins_cost(DEFAULT_COST);
6839   size(8);
6840   format %{ "AND    $dst,$src1,$con\t! long" %}
6841   ins_encode %{
6842     __ andr($dst$$Register, $src1$$Register, $con$$constant);
6843     __ andr($dst$$Register->successor(), $src1$$Register->successor(), 0);
6844   %}
6845   ins_pipe(ialu_reg_imm);
6846 %}
6847 
6848 // Or Instructions
6849 // Register Or
6850 instruct orI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6851   match(Set dst (OrI src1 src2));
6852 
6853   size(4);
6854   format %{ "orr_32 $dst,$src1,$src2\t! int" %}
6855   ins_encode %{
6856     __ orr_32($dst$$Register, $src1$$Register, $src2$$Register);
6857   %}
6858   ins_pipe(ialu_reg_reg);
6859 %}
6860 
6861 instruct orshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6862   match(Set dst (OrI src1 (LShiftI src2 src3)));
6863 
6864   size(4);
6865   format %{ "OR    $dst,$src1,$src2<<$src3" %}
6866   ins_encode %{
6867     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
6868   %}
6869   ins_pipe(ialu_reg_reg);
6870 %}
6871 
6872 instruct orshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6873   match(Set dst (OrI src1 (LShiftI src2 src3)));
6874 
6875   size(4);
6876   format %{ "orr_32 $dst,$src1,$src2<<$src3" %}
6877   ins_encode %{
6878     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
6879   %}
6880   ins_pipe(ialu_reg_reg);
6881 %}
6882 
6883 instruct orsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6884   match(Set dst (OrI src1 (RShiftI src2 src3)));
6885 
6886   size(4);
6887   format %{ "OR    $dst,$src1,$src2>>$src3" %}
6888   ins_encode %{
6889     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
6890   %}
6891   ins_pipe(ialu_reg_reg);
6892 %}
6893 
6894 instruct orsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6895   match(Set dst (OrI src1 (RShiftI src2 src3)));
6896 
6897   size(4);
6898   format %{ "orr_32 $dst,$src1,$src2>>$src3" %}
6899   ins_encode %{
6900     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
6901   %}
6902   ins_pipe(ialu_reg_reg);
6903 %}
6904 
6905 instruct orshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6906   match(Set dst (OrI src1 (URShiftI src2 src3)));
6907 
6908   size(4);
6909   format %{ "OR    $dst,$src1,$src2>>>$src3" %}
6910   ins_encode %{
6911     __ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
6912   %}
6913   ins_pipe(ialu_reg_reg);
6914 %}
6915 
6916 instruct orshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
6917   match(Set dst (OrI src1 (URShiftI src2 src3)));
6918 
6919   size(4);
6920   format %{ "orr_32 $dst,$src1,$src2>>>$src3" %}
6921   ins_encode %{
6922     __ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
6923   %}
6924   ins_pipe(ialu_reg_reg);
6925 %}
6926 
6927 // Immediate Or
6928 instruct orI_reg_limm(iRegI dst, iRegI src1, limmI src2) %{
6929   match(Set dst (OrI src1 src2));
6930 
6931   size(4);
6932   format %{ "orr_32  $dst,$src1,$src2" %}
6933   ins_encode %{
6934     __ orr_32($dst$$Register, $src1$$Register, $src2$$constant);
6935   %}
6936   ins_pipe(ialu_reg_imm);
6937 %}
6938 // TODO: orn_32 with limmIn
6939 
6940 // Register Or Long
6941 instruct orL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
6942   match(Set dst (OrL src1 src2));
6943 
6944   ins_cost(DEFAULT_COST);
6945   size(8);
6946   format %{ "OR     $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
6947             "OR     $dst.hi,$src1.hi,$src2.hi" %}
6948   ins_encode %{
6949     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
6950     __ orr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
6951   %}
6952   ins_pipe(ialu_reg_reg);
6953 %}
6954 
6955 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
6956 // (hi($con$$constant), lo($con$$constant)) becomes
6957 instruct orL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
6958   match(Set dst (OrL src1 con));
6959   ins_cost(DEFAULT_COST);
6960   size(8);
6961   format %{ "OR     $dst.lo,$src1.lo,$con\t! long\n\t"
6962             "OR     $dst.hi,$src1.hi,$con" %}
6963   ins_encode %{
6964     __ orr($dst$$Register, $src1$$Register, $con$$constant);
6965     __ orr($dst$$Register->successor(), $src1$$Register->successor(), 0);
6966   %}
6967   ins_pipe(ialu_reg_imm);
6968 %}
6969 
6970 #ifdef TODO
6971 // Use SPRegP to match Rthread (TLS register) without spilling.
6972 // Use store_ptr_RegP to match Rthread (TLS register) without spilling.
6973 // Use sp_ptr_RegP to match Rthread (TLS register) without spilling.
6974 instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
6975   match(Set dst (OrI src1 (CastP2X src2)));
6976   size(4);
6977   format %{ "OR     $dst,$src1,$src2" %}
6978   ins_encode %{
6979     __ orr($dst$$Register, $src1$$Register, $src2$$Register);
6980   %}
6981   ins_pipe(ialu_reg_reg);
6982 %}
6983 #endif
6984 
6985 // Xor Instructions
6986 // Register Xor
6987 instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
6988   match(Set dst (XorI src1 src2));
6989 
6990   size(4);
6991   format %{ "eor_32 $dst,$src1,$src2" %}
6992   ins_encode %{
6993     __ eor_32($dst$$Register, $src1$$Register, $src2$$Register);
6994   %}
6995   ins_pipe(ialu_reg_reg);
6996 %}
6997 
6998 instruct xorshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
6999   match(Set dst (XorI src1 (LShiftI src2 src3)));
7000 
7001   size(4);
7002   format %{ "XOR    $dst,$src1,$src2<<$src3" %}
7003   ins_encode %{
7004     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
7005   %}
7006   ins_pipe(ialu_reg_reg);
7007 %}
7008 
7009 instruct xorshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
7010   match(Set dst (XorI src1 (LShiftI src2 src3)));
7011 
7012   size(4);
7013   format %{ "eor_32 $dst,$src1,$src2<<$src3" %}
7014   ins_encode %{
7015     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
7016   %}
7017   ins_pipe(ialu_reg_reg);
7018 %}
7019 
7020 instruct xorsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
7021   match(Set dst (XorI src1 (RShiftI src2 src3)));
7022 
7023   size(4);
7024   format %{ "XOR    $dst,$src1,$src2>>$src3" %}
7025   ins_encode %{
7026     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
7027   %}
7028   ins_pipe(ialu_reg_reg);
7029 %}
7030 
7031 instruct xorsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
7032   match(Set dst (XorI src1 (RShiftI src2 src3)));
7033 
7034   size(4);
7035   format %{ "eor_32 $dst,$src1,$src2>>$src3" %}
7036   ins_encode %{
7037     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
7038   %}
7039   ins_pipe(ialu_reg_reg);
7040 %}
7041 
7042 instruct xorshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
7043   match(Set dst (XorI src1 (URShiftI src2 src3)));
7044 
7045   size(4);
7046   format %{ "XOR    $dst,$src1,$src2>>>$src3" %}
7047   ins_encode %{
7048     __ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
7049   %}
7050   ins_pipe(ialu_reg_reg);
7051 %}
7052 
7053 instruct xorshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
7054   match(Set dst (XorI src1 (URShiftI src2 src3)));
7055 
7056   size(4);
7057   format %{ "eor_32 $dst,$src1,$src2>>>$src3" %}
7058   ins_encode %{
7059     __ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
7060   %}
7061   ins_pipe(ialu_reg_reg);
7062 %}
7063 
7064 // Immediate Xor
7065 instruct xorI_reg_imm(iRegI dst, iRegI src1, limmI src2) %{
7066   match(Set dst (XorI src1 src2));
7067 
7068   size(4);
7069   format %{ "eor_32 $dst,$src1,$src2" %}
7070   ins_encode %{
7071     __ eor_32($dst$$Register, $src1$$Register, $src2$$constant);
7072   %}
7073   ins_pipe(ialu_reg_imm);
7074 %}
7075 
7076 // Register Xor Long
7077 instruct xorL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
7078   match(Set dst (XorL src1 src2));
7079   ins_cost(DEFAULT_COST);
7080   size(8);
7081   format %{ "XOR     $dst.hi,$src1.hi,$src2.hi\t! long\n\t"
7082             "XOR     $dst.lo,$src1.lo,$src2.lo\t! long" %}
7083   ins_encode %{
7084     __ eor($dst$$Register, $src1$$Register, $src2$$Register);
7085     __ eor($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
7086   %}
7087   ins_pipe(ialu_reg_reg);
7088 %}
7089 
7090 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7091 // (hi($con$$constant), lo($con$$constant)) becomes
7092 instruct xorL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
7093   match(Set dst (XorL src1 con));
7094   ins_cost(DEFAULT_COST);
7095   size(8);
7096   format %{ "XOR     $dst.hi,$src1.hi,$con\t! long\n\t"
7097             "XOR     $dst.lo,$src1.lo,0\t! long" %}
7098   ins_encode %{
7099     __ eor($dst$$Register, $src1$$Register, $con$$constant);
7100     __ eor($dst$$Register->successor(), $src1$$Register->successor(), 0);
7101   %}
7102   ins_pipe(ialu_reg_imm);
7103 %}
7104 
7105 //----------Convert to Boolean-------------------------------------------------
7106 instruct convI2B( iRegI dst, iRegI src, flagsReg ccr ) %{
7107   match(Set dst (Conv2B src));
7108   effect(KILL ccr);
7109   size(12);
7110   ins_cost(DEFAULT_COST*2);
7111   format %{ "TST    $src,$src \n\t"
7112             "MOV    $dst, 0   \n\t"
7113             "MOV.ne $dst, 1" %}
7114   ins_encode %{ // FIXME: can do better?
7115     __ tst($src$$Register, $src$$Register);
7116     __ mov($dst$$Register, 0);
7117     __ mov($dst$$Register, 1, ne);
7118   %}
7119   ins_pipe(ialu_reg_ialu);
7120 %}
7121 
7122 instruct convP2B( iRegI dst, iRegP src, flagsReg ccr ) %{
7123   match(Set dst (Conv2B src));
7124   effect(KILL ccr);
7125   size(12);
7126   ins_cost(DEFAULT_COST*2);
7127   format %{ "TST    $src,$src \n\t"
7128             "MOV    $dst, 0   \n\t"
7129             "MOV.ne $dst, 1" %}
7130   ins_encode %{
7131     __ tst($src$$Register, $src$$Register);
7132     __ mov($dst$$Register, 0);
7133     __ mov($dst$$Register, 1, ne);
7134   %}
7135   ins_pipe(ialu_reg_ialu);
7136 %}
7137 
7138 instruct cmpLTMask_reg_reg( iRegI dst, iRegI p, iRegI q, flagsReg ccr ) %{
7139   match(Set dst (CmpLTMask p q));
7140   effect( KILL ccr );
7141   ins_cost(DEFAULT_COST*3);
7142   format %{ "CMP    $p,$q\n\t"
7143             "MOV    $dst, #0\n\t"
7144             "MOV.lt $dst, #-1" %}
7145   ins_encode %{
7146     __ cmp($p$$Register, $q$$Register);
7147     __ mov($dst$$Register, 0);
7148     __ mvn($dst$$Register, 0, lt);
7149   %}
7150   ins_pipe(ialu_reg_reg_ialu);
7151 %}
7152 
7153 instruct cmpLTMask_reg_imm( iRegI dst, iRegI p, aimmI q, flagsReg ccr ) %{
7154   match(Set dst (CmpLTMask p q));
7155   effect( KILL ccr );
7156   ins_cost(DEFAULT_COST*3);
7157   format %{ "CMP    $p,$q\n\t"
7158             "MOV    $dst, #0\n\t"
7159             "MOV.lt $dst, #-1" %}
7160   ins_encode %{
7161     __ cmp($p$$Register, $q$$constant);
7162     __ mov($dst$$Register, 0);
7163     __ mvn($dst$$Register, 0, lt);
7164   %}
7165   ins_pipe(ialu_reg_reg_ialu);
7166 %}
7167 
7168 instruct cadd_cmpLTMask3( iRegI p, iRegI q, iRegI y, iRegI z, flagsReg ccr ) %{
7169   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
7170   effect( KILL ccr );
7171   ins_cost(DEFAULT_COST*2);
7172   format %{ "CMP    $p,$q\n\t"
7173             "ADD.lt $z,$y,$z" %}
7174   ins_encode %{
7175     __ cmp($p$$Register, $q$$Register);
7176     __ add($z$$Register, $y$$Register, $z$$Register, lt);
7177   %}
7178   ins_pipe( cadd_cmpltmask );
7179 %}
7180 
7181 // FIXME: remove unused "dst"
7182 instruct cadd_cmpLTMask4( iRegI dst, iRegI p, aimmI q, iRegI y, iRegI z, flagsReg ccr ) %{
7183   match(Set z (AddI (AndI (CmpLTMask p q) y) z));
7184   effect( KILL ccr );
7185   ins_cost(DEFAULT_COST*2);
7186   format %{ "CMP    $p,$q\n\t"
7187             "ADD.lt $z,$y,$z" %}
7188   ins_encode %{
7189     __ cmp($p$$Register, $q$$constant);
7190     __ add($z$$Register, $y$$Register, $z$$Register, lt);
7191   %}
7192   ins_pipe( cadd_cmpltmask );
7193 %}
7194 
7195 instruct cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, flagsReg ccr ) %{
7196   match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
7197   effect( KILL ccr );
7198   ins_cost(DEFAULT_COST*2);
7199   format %{ "SUBS   $p,$p,$q\n\t"
7200             "ADD.lt $p,$y,$p" %}
7201   ins_encode %{
7202     __ subs($p$$Register, $p$$Register, $q$$Register);
7203     __ add($p$$Register, $y$$Register, $p$$Register, lt);
7204   %}
7205   ins_pipe( cadd_cmpltmask );
7206 %}
7207 
7208 //----------Arithmetic Conversion Instructions---------------------------------
7209 // The conversions operations are all Alpha sorted.  Please keep it that way!
7210 
7211 instruct convD2F_reg(regF dst, regD src) %{
7212   match(Set dst (ConvD2F src));
7213   size(4);
7214   format %{ "FCVTSD  $dst,$src" %}
7215   ins_encode %{
7216     __ convert_d2f($dst$$FloatRegister, $src$$FloatRegister);
7217   %}
7218   ins_pipe(fcvtD2F);
7219 %}
7220 
7221 // Convert a double to an int in a float register.
7222 // If the double is a NAN, stuff a zero in instead.
7223 
7224 instruct convD2I_reg_reg(iRegI dst, regD src, regF tmp) %{
7225   match(Set dst (ConvD2I src));
7226   effect( TEMP tmp );
7227   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
7228   format %{ "FTOSIZD  $tmp,$src\n\t"
7229             "FMRS     $dst, $tmp" %}
7230   ins_encode %{
7231     __ ftosizd($tmp$$FloatRegister, $src$$FloatRegister);
7232     __ fmrs($dst$$Register, $tmp$$FloatRegister);
7233   %}
7234   ins_pipe(fcvtD2I);
7235 %}
7236 
7237 // Convert a double to a long in a double register.
7238 // If the double is a NAN, stuff a zero in instead.
7239 
7240 // Double to Long conversion
7241 instruct convD2L_reg(R0R1RegL dst, regD src) %{
7242   match(Set dst (ConvD2L src));
7243   effect(CALL);
7244   ins_cost(MEMORY_REF_COST); // FIXME
7245   format %{ "convD2L    $dst,$src\t ! call to SharedRuntime::d2l" %}
7246   ins_encode %{
7247 #ifndef __ABI_HARD__
7248     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
7249 #else
7250     if ($src$$FloatRegister != D0) {
7251       __ mov_double(D0, $src$$FloatRegister);
7252     }
7253 #endif
7254     address target = CAST_FROM_FN_PTR(address, SharedRuntime::d2l);
7255     __ call(target, relocInfo::runtime_call_type);
7256   %}
7257   ins_pipe(fcvtD2L);
7258 %}
7259 
7260 instruct convF2D_reg(regD dst, regF src) %{
7261   match(Set dst (ConvF2D src));
7262   size(4);
7263   format %{ "FCVTDS  $dst,$src" %}
7264   ins_encode %{
7265     __ convert_f2d($dst$$FloatRegister, $src$$FloatRegister);
7266   %}
7267   ins_pipe(fcvtF2D);
7268 %}
7269 
7270 instruct convF2I_reg_reg(iRegI dst, regF src, regF tmp) %{
7271   match(Set dst (ConvF2I src));
7272   effect( TEMP tmp );
7273   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
7274   size(8);
7275   format %{ "FTOSIZS  $tmp,$src\n\t"
7276             "FMRS     $dst, $tmp" %}
7277   ins_encode %{
7278     __ ftosizs($tmp$$FloatRegister, $src$$FloatRegister);
7279     __ fmrs($dst$$Register, $tmp$$FloatRegister);
7280   %}
7281   ins_pipe(fcvtF2I);
7282 %}
7283 
7284 // Float to Long conversion
7285 instruct convF2L_reg(R0R1RegL dst, regF src, R0RegI arg1) %{
7286   match(Set dst (ConvF2L src));
7287   ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
7288   effect(CALL);
7289   format %{ "convF2L  $dst,$src\t! call to SharedRuntime::f2l" %}
7290   ins_encode %{
7291 #ifndef __ABI_HARD__
7292     __ fmrs($arg1$$Register, $src$$FloatRegister);
7293 #else
7294     if($src$$FloatRegister != S0) {
7295       __ mov_float(S0, $src$$FloatRegister);
7296     }
7297 #endif
7298     address target = CAST_FROM_FN_PTR(address, SharedRuntime::f2l);
7299     __ call(target, relocInfo::runtime_call_type);
7300   %}
7301   ins_pipe(fcvtF2L);
7302 %}
7303 
7304 instruct convI2D_reg_reg(iRegI src, regD_low dst) %{
7305   match(Set dst (ConvI2D src));
7306   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
7307   size(8);
7308   format %{ "FMSR     $dst,$src \n\t"
7309             "FSITOD   $dst $dst"%}
7310   ins_encode %{
7311       __ fmsr($dst$$FloatRegister, $src$$Register);
7312       __ fsitod($dst$$FloatRegister, $dst$$FloatRegister);
7313   %}
7314   ins_pipe(fcvtI2D);
7315 %}
7316 
7317 instruct convI2F_reg_reg( regF dst, iRegI src ) %{
7318   match(Set dst (ConvI2F src));
7319   ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
7320   size(8);
7321   format %{ "FMSR     $dst,$src \n\t"
7322             "FSITOS   $dst, $dst"%}
7323   ins_encode %{
7324       __ fmsr($dst$$FloatRegister, $src$$Register);
7325       __ fsitos($dst$$FloatRegister, $dst$$FloatRegister);
7326   %}
7327   ins_pipe(fcvtI2F);
7328 %}
7329 
7330 instruct convI2L_reg(iRegL dst, iRegI src) %{
7331   match(Set dst (ConvI2L src));
7332   size(8);
7333   format %{ "MOV    $dst.lo, $src \n\t"
7334             "ASR    $dst.hi,$src,31\t! int->long" %}
7335   ins_encode %{
7336     __ mov($dst$$Register, $src$$Register);
7337     __ mov($dst$$Register->successor(), AsmOperand($src$$Register, asr, 31));
7338   %}
7339   ins_pipe(ialu_reg_reg);
7340 %}
7341 
7342 // Zero-extend convert int to long
7343 instruct convI2L_reg_zex(iRegL dst, iRegI src, immL_32bits mask ) %{
7344   match(Set dst (AndL (ConvI2L src) mask) );
7345   size(8);
7346   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend int to long\n\t"
7347             "MOV    $dst.hi, 0"%}
7348   ins_encode %{
7349     __ mov($dst$$Register, $src$$Register);
7350     __ mov($dst$$Register->successor(), 0);
7351   %}
7352   ins_pipe(ialu_reg_reg);
7353 %}
7354 
7355 // Zero-extend long
7356 instruct zerox_long(iRegL dst, iRegL src, immL_32bits mask ) %{
7357   match(Set dst (AndL src mask) );
7358   size(8);
7359   format %{ "MOV    $dst.lo,$src.lo\t! zero-extend long\n\t"
7360             "MOV    $dst.hi, 0"%}
7361   ins_encode %{
7362     __ mov($dst$$Register, $src$$Register);
7363     __ mov($dst$$Register->successor(), 0);
7364   %}
7365   ins_pipe(ialu_reg_reg);
7366 %}
7367 
7368 instruct MoveF2I_reg_reg(iRegI dst, regF src) %{
7369   match(Set dst (MoveF2I src));
7370   effect(DEF dst, USE src);
7371   ins_cost(MEMORY_REF_COST); // FIXME
7372 
7373   size(4);
7374   format %{ "FMRS   $dst,$src\t! MoveF2I" %}
7375   ins_encode %{
7376     __ fmrs($dst$$Register, $src$$FloatRegister);
7377   %}
7378   ins_pipe(iload_mem); // FIXME
7379 %}
7380 
7381 instruct MoveI2F_reg_reg(regF dst, iRegI src) %{
7382   match(Set dst (MoveI2F src));
7383   ins_cost(MEMORY_REF_COST); // FIXME
7384 
7385   size(4);
7386   format %{ "FMSR   $dst,$src\t! MoveI2F" %}
7387   ins_encode %{
7388     __ fmsr($dst$$FloatRegister, $src$$Register);
7389   %}
7390   ins_pipe(iload_mem); // FIXME
7391 %}
7392 
7393 instruct MoveD2L_reg_reg(iRegL dst, regD src) %{
7394   match(Set dst (MoveD2L src));
7395   effect(DEF dst, USE src);
7396   ins_cost(MEMORY_REF_COST); // FIXME
7397 
7398   size(4);
7399   format %{ "FMRRD    $dst,$src\t! MoveD2L" %}
7400   ins_encode %{
7401     __ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
7402   %}
7403   ins_pipe(iload_mem); // FIXME
7404 %}
7405 
7406 instruct MoveL2D_reg_reg(regD dst, iRegL src) %{
7407   match(Set dst (MoveL2D src));
7408   effect(DEF dst, USE src);
7409   ins_cost(MEMORY_REF_COST); // FIXME
7410 
7411   size(4);
7412   format %{ "FMDRR   $dst,$src\t! MoveL2D" %}
7413   ins_encode %{
7414     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
7415   %}
7416   ins_pipe(ialu_reg_reg); // FIXME
7417 %}
7418 
7419 //-----------
7420 // Long to Double conversion
7421 
7422 // Magic constant, 0x43300000
7423 instruct loadConI_x43300000(iRegI dst) %{
7424   effect(DEF dst);
7425   size(8);
7426   format %{ "MOV_SLOW  $dst,0x43300000\t! 2^52" %}
7427   ins_encode %{
7428     __ mov_slow($dst$$Register, 0x43300000);
7429   %}
7430   ins_pipe(ialu_none);
7431 %}
7432 
7433 // Magic constant, 0x41f00000
7434 instruct loadConI_x41f00000(iRegI dst) %{
7435   effect(DEF dst);
7436   size(8);
7437   format %{ "MOV_SLOW  $dst, 0x41f00000\t! 2^32" %}
7438   ins_encode %{
7439     __ mov_slow($dst$$Register, 0x41f00000);
7440   %}
7441   ins_pipe(ialu_none);
7442 %}
7443 
7444 instruct loadConI_x0(iRegI dst) %{
7445   effect(DEF dst);
7446   size(4);
7447   format %{ "MOV  $dst, 0x0\t! 0" %}
7448   ins_encode %{
7449     __ mov($dst$$Register, 0);
7450   %}
7451   ins_pipe(ialu_none);
7452 %}
7453 
7454 // Construct a double from two float halves
7455 instruct regDHi_regDLo_to_regD(regD_low dst, regD_low src1, regD_low src2) %{
7456   effect(DEF dst, USE src1, USE src2);
7457   size(8);
7458   format %{ "FCPYS  $dst.hi,$src1.hi\n\t"
7459             "FCPYS  $dst.lo,$src2.lo" %}
7460   ins_encode %{
7461     __ fcpys($dst$$FloatRegister->successor(), $src1$$FloatRegister->successor());
7462     __ fcpys($dst$$FloatRegister, $src2$$FloatRegister);
7463   %}
7464   ins_pipe(faddD_reg_reg);
7465 %}
7466 
7467 // Convert integer in high half of a double register (in the lower half of
7468 // the double register file) to double
7469 instruct convI2D_regDHi_regD(regD dst, regD_low src) %{
7470   effect(DEF dst, USE src);
7471   size(4);
7472   format %{ "FSITOD  $dst,$src" %}
7473   ins_encode %{
7474     __ fsitod($dst$$FloatRegister, $src$$FloatRegister->successor());
7475   %}
7476   ins_pipe(fcvtLHi2D);
7477 %}
7478 
7479 // Add float double precision
7480 instruct addD_regD_regD(regD dst, regD src1, regD src2) %{
7481   effect(DEF dst, USE src1, USE src2);
7482   size(4);
7483   format %{ "FADDD  $dst,$src1,$src2" %}
7484   ins_encode %{
7485     __ add_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
7486   %}
7487   ins_pipe(faddD_reg_reg);
7488 %}
7489 
7490 // Sub float double precision
7491 instruct subD_regD_regD(regD dst, regD src1, regD src2) %{
7492   effect(DEF dst, USE src1, USE src2);
7493   size(4);
7494   format %{ "FSUBD  $dst,$src1,$src2" %}
7495   ins_encode %{
7496     __ sub_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
7497   %}
7498   ins_pipe(faddD_reg_reg);
7499 %}
7500 
7501 // Mul float double precision
7502 instruct mulD_regD_regD(regD dst, regD src1, regD src2) %{
7503   effect(DEF dst, USE src1, USE src2);
7504   size(4);
7505   format %{ "FMULD  $dst,$src1,$src2" %}
7506   ins_encode %{
7507     __ mul_double($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
7508   %}
7509   ins_pipe(fmulD_reg_reg);
7510 %}
7511 
7512 instruct regL_to_regD(regD dst, iRegL src) %{
7513   // No match rule to avoid chain rule match.
7514   effect(DEF dst, USE src);
7515   ins_cost(MEMORY_REF_COST);
7516   size(4);
7517   format %{ "FMDRR   $dst,$src\t! regL to regD" %}
7518   ins_encode %{
7519     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
7520   %}
7521   ins_pipe(ialu_reg_reg); // FIXME
7522 %}
7523 
7524 instruct regI_regI_to_regD(regD dst, iRegI src1, iRegI src2) %{
7525   // No match rule to avoid chain rule match.
7526   effect(DEF dst, USE src1, USE src2);
7527   ins_cost(MEMORY_REF_COST);
7528   size(4);
7529   format %{ "FMDRR   $dst,$src1,$src2\t! regI,regI to regD" %}
7530   ins_encode %{
7531     __ fmdrr($dst$$FloatRegister, $src1$$Register, $src2$$Register);
7532   %}
7533   ins_pipe(ialu_reg_reg); // FIXME
7534 %}
7535 
7536 instruct convL2D_reg_slow_fxtof(regD dst, iRegL src) %{
7537   match(Set dst (ConvL2D src));
7538   ins_cost(DEFAULT_COST*8 + MEMORY_REF_COST*6); // FIXME
7539 
7540   expand %{
7541     regD_low   tmpsrc;
7542     iRegI      ix43300000;
7543     iRegI      ix41f00000;
7544     iRegI      ix0;
7545     regD_low   dx43300000;
7546     regD       dx41f00000;
7547     regD       tmp1;
7548     regD_low   tmp2;
7549     regD       tmp3;
7550     regD       tmp4;
7551 
7552     regL_to_regD(tmpsrc, src);
7553 
7554     loadConI_x43300000(ix43300000);
7555     loadConI_x41f00000(ix41f00000);
7556     loadConI_x0(ix0);
7557 
7558     regI_regI_to_regD(dx43300000, ix0, ix43300000);
7559     regI_regI_to_regD(dx41f00000, ix0, ix41f00000);
7560 
7561     convI2D_regDHi_regD(tmp1, tmpsrc);
7562     regDHi_regDLo_to_regD(tmp2, dx43300000, tmpsrc);
7563     subD_regD_regD(tmp3, tmp2, dx43300000);
7564     mulD_regD_regD(tmp4, tmp1, dx41f00000);
7565     addD_regD_regD(dst, tmp3, tmp4);
7566   %}
7567 %}
7568 
7569 instruct convL2I_reg(iRegI dst, iRegL src) %{
7570   match(Set dst (ConvL2I src));
7571   size(4);
7572   format %{ "MOV    $dst,$src.lo\t! long->int" %}
7573   ins_encode %{
7574     __ mov($dst$$Register, $src$$Register);
7575   %}
7576   ins_pipe(ialu_move_reg_I_to_L);
7577 %}
7578 
7579 // Register Shift Right Immediate
7580 instruct shrL_reg_imm6_L2I(iRegI dst, iRegL src, immI_32_63 cnt) %{
7581   match(Set dst (ConvL2I (RShiftL src cnt)));
7582   size(4);
7583   format %{ "ASR    $dst,$src.hi,($cnt - 32)\t! long->int or mov if $cnt==32" %}
7584   ins_encode %{
7585     if ($cnt$$constant == 32) {
7586       __ mov($dst$$Register, $src$$Register->successor());
7587     } else {
7588       __ mov($dst$$Register, AsmOperand($src$$Register->successor(), asr, $cnt$$constant - 32));
7589     }
7590   %}
7591   ins_pipe(ialu_reg_imm);
7592 %}
7593 
7594 
7595 //----------Control Flow Instructions------------------------------------------
7596 // Compare Instructions
7597 // Compare Integers
7598 instruct compI_iReg(flagsReg icc, iRegI op1, iRegI op2) %{
7599   match(Set icc (CmpI op1 op2));
7600   effect( DEF icc, USE op1, USE op2 );
7601 
7602   size(4);
7603   format %{ "cmp_32 $op1,$op2\t! int" %}
7604   ins_encode %{
7605     __ cmp_32($op1$$Register, $op2$$Register);
7606   %}
7607   ins_pipe(ialu_cconly_reg_reg);
7608 %}
7609 
7610 #ifdef _LP64
7611 // Compare compressed pointers
7612 instruct compN_reg2(flagsRegU icc, iRegN op1, iRegN op2) %{
7613   match(Set icc (CmpN op1 op2));
7614   effect( DEF icc, USE op1, USE op2 );
7615 
7616   size(4);
7617   format %{ "cmp_32 $op1,$op2\t! int" %}
7618   ins_encode %{
7619     __ cmp_32($op1$$Register, $op2$$Register);
7620   %}
7621   ins_pipe(ialu_cconly_reg_reg);
7622 %}
7623 #endif
7624 
7625 instruct compU_iReg(flagsRegU icc, iRegI op1, iRegI op2) %{
7626   match(Set icc (CmpU op1 op2));
7627 
7628   size(4);
7629   format %{ "cmp_32 $op1,$op2\t! unsigned int" %}
7630   ins_encode %{
7631     __ cmp_32($op1$$Register, $op2$$Register);
7632   %}
7633   ins_pipe(ialu_cconly_reg_reg);
7634 %}
7635 
7636 instruct compI_iReg_immneg(flagsReg icc, iRegI op1, aimmIneg op2) %{
7637   match(Set icc (CmpI op1 op2));
7638   effect( DEF icc, USE op1 );
7639 
7640   size(4);
7641   format %{ "cmn_32 $op1,-$op2\t! int" %}
7642   ins_encode %{
7643     __ cmn_32($op1$$Register, -$op2$$constant);
7644   %}
7645   ins_pipe(ialu_cconly_reg_imm);
7646 %}
7647 
7648 instruct compI_iReg_imm(flagsReg icc, iRegI op1, aimmI op2) %{
7649   match(Set icc (CmpI op1 op2));
7650   effect( DEF icc, USE op1 );
7651 
7652   size(4);
7653   format %{ "cmp_32 $op1,$op2\t! int" %}
7654   ins_encode %{
7655     __ cmp_32($op1$$Register, $op2$$constant);
7656   %}
7657   ins_pipe(ialu_cconly_reg_imm);
7658 %}
7659 
7660 instruct testI_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immI0 zero ) %{
7661   match(Set icc (CmpI (AndI op1 op2) zero));
7662   size(4);
7663   format %{ "tst_32 $op2,$op1" %}
7664 
7665   ins_encode %{
7666     __ tst_32($op1$$Register, $op2$$Register);
7667   %}
7668   ins_pipe(ialu_cconly_reg_reg_zero);
7669 %}
7670 
7671 instruct testshlI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
7672   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
7673   size(4);
7674   format %{ "TST   $op2,$op1<<$op3" %}
7675 
7676   ins_encode %{
7677     __ tst($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$Register));
7678   %}
7679   ins_pipe(ialu_cconly_reg_reg_zero);
7680 %}
7681 
7682 instruct testshlI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
7683   match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
7684   size(4);
7685   format %{ "tst_32 $op2,$op1<<$op3" %}
7686 
7687   ins_encode %{
7688     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$constant));
7689   %}
7690   ins_pipe(ialu_cconly_reg_reg_zero);
7691 %}
7692 
7693 instruct testsarI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
7694   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
7695   size(4);
7696   format %{ "TST   $op2,$op1<<$op3" %}
7697 
7698   ins_encode %{
7699     __ tst($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$Register));
7700   %}
7701   ins_pipe(ialu_cconly_reg_reg_zero);
7702 %}
7703 
7704 instruct testsarI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
7705   match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
7706   size(4);
7707   format %{ "tst_32 $op2,$op1<<$op3" %}
7708 
7709   ins_encode %{
7710     __ tst_32($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$constant));
7711   %}
7712   ins_pipe(ialu_cconly_reg_reg_zero);
7713 %}
7714 
7715 instruct testshrI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
7716   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
7717   size(4);
7718   format %{ "TST   $op2,$op1<<$op3" %}
7719 
7720   ins_encode %{
7721     __ tst($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$Register));
7722   %}
7723   ins_pipe(ialu_cconly_reg_reg_zero);
7724 %}
7725 
7726 instruct testshrI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
7727   match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
7728   size(4);
7729   format %{ "tst_32 $op2,$op1<<$op3" %}
7730 
7731   ins_encode %{
7732     __ tst_32($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$constant));
7733   %}
7734   ins_pipe(ialu_cconly_reg_reg_zero);
7735 %}
7736 
7737 instruct testI_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, limmI op2, immI0 zero ) %{
7738   match(Set icc (CmpI (AndI op1 op2) zero));
7739   size(4);
7740   format %{ "tst_32 $op2,$op1" %}
7741 
7742   ins_encode %{
7743     __ tst_32($op1$$Register, $op2$$constant);
7744   %}
7745   ins_pipe(ialu_cconly_reg_imm_zero);
7746 %}
7747 
7748 instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
7749   match(Set xcc (CmpL op1 op2));
7750   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
7751 
7752   size(8);
7753   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! long\n\t"
7754             "SBCS    $tmp,$op1.hi,$op2.hi" %}
7755   ins_encode %{
7756     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
7757     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
7758   %}
7759   ins_pipe(ialu_cconly_reg_reg);
7760 %}
7761 
7762 instruct compUL_reg_reg_LTGE(flagsRegUL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
7763   match(Set xcc (CmpUL op1 op2));
7764   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
7765 
7766   size(8);
7767   format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! unsigned long\n\t"
7768             "SBCS    $tmp,$op1.hi,$op2.hi" %}
7769   ins_encode %{
7770     __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
7771     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
7772   %}
7773   ins_pipe(ialu_cconly_reg_reg);
7774 %}
7775 
7776 instruct compL_reg_reg_EQNE(flagsRegL_EQNE xcc, iRegL op1, iRegL op2) %{
7777   match(Set xcc (CmpL op1 op2));
7778   effect( DEF xcc, USE op1, USE op2 );
7779 
7780   size(8);
7781   format %{ "TEQ    $op1.hi,$op2.hi\t\t! long\n\t"
7782             "TEQ.eq $op1.lo,$op2.lo" %}
7783   ins_encode %{
7784     __ teq($op1$$Register->successor(), $op2$$Register->successor());
7785     __ teq($op1$$Register, $op2$$Register, eq);
7786   %}
7787   ins_pipe(ialu_cconly_reg_reg);
7788 %}
7789 
7790 instruct compL_reg_reg_LEGT(flagsRegL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
7791   match(Set xcc (CmpL op1 op2));
7792   effect( DEF xcc, USE op1, USE op2, TEMP tmp );
7793 
7794   size(8);
7795   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! long\n\t"
7796             "SBCS    $tmp,$op2.hi,$op1.hi" %}
7797   ins_encode %{
7798     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
7799     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
7800   %}
7801   ins_pipe(ialu_cconly_reg_reg);
7802 %}
7803 
7804 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7805 // (hi($con$$constant), lo($con$$constant)) becomes
7806 instruct compL_reg_con_LTGE(flagsRegL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
7807   match(Set xcc (CmpL op1 con));
7808   effect( DEF xcc, USE op1, USE con, TEMP tmp );
7809 
7810   size(8);
7811   format %{ "SUBS    $tmp,$op1.low,$con\t\t! long\n\t"
7812             "SBCS    $tmp,$op1.hi,0" %}
7813   ins_encode %{
7814     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
7815     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
7816   %}
7817 
7818   ins_pipe(ialu_cconly_reg_reg);
7819 %}
7820 
7821 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7822 // (hi($con$$constant), lo($con$$constant)) becomes
7823 instruct compL_reg_con_EQNE(flagsRegL_EQNE xcc, iRegL op1, immLlowRot con) %{
7824   match(Set xcc (CmpL op1 con));
7825   effect( DEF xcc, USE op1, USE con );
7826 
7827   size(8);
7828   format %{ "TEQ    $op1.hi,0\t\t! long\n\t"
7829             "TEQ.eq $op1.lo,$con" %}
7830   ins_encode %{
7831     __ teq($op1$$Register->successor(), 0);
7832     __ teq($op1$$Register, $con$$constant, eq);
7833   %}
7834 
7835   ins_pipe(ialu_cconly_reg_reg);
7836 %}
7837 
7838 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7839 // (hi($con$$constant), lo($con$$constant)) becomes
7840 instruct compL_reg_con_LEGT(flagsRegL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
7841   match(Set xcc (CmpL op1 con));
7842   effect( DEF xcc, USE op1, USE con, TEMP tmp );
7843 
7844   size(8);
7845   format %{ "RSBS    $tmp,$op1.low,$con\t\t! long\n\t"
7846             "RSCS    $tmp,$op1.hi,0" %}
7847   ins_encode %{
7848     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
7849     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
7850   %}
7851 
7852   ins_pipe(ialu_cconly_reg_reg);
7853 %}
7854 
7855 instruct compUL_reg_reg_EQNE(flagsRegUL_EQNE xcc, iRegL op1, iRegL op2) %{
7856   match(Set xcc (CmpUL op1 op2));
7857   effect(DEF xcc, USE op1, USE op2);
7858 
7859   size(8);
7860   format %{ "TEQ    $op1.hi,$op2.hi\t\t! unsigned long\n\t"
7861             "TEQ.eq $op1.lo,$op2.lo" %}
7862   ins_encode %{
7863     __ teq($op1$$Register->successor(), $op2$$Register->successor());
7864     __ teq($op1$$Register, $op2$$Register, eq);
7865   %}
7866   ins_pipe(ialu_cconly_reg_reg);
7867 %}
7868 
7869 instruct compUL_reg_reg_LEGT(flagsRegUL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
7870   match(Set xcc (CmpUL op1 op2));
7871   effect(DEF xcc, USE op1, USE op2, TEMP tmp);
7872 
7873   size(8);
7874   format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! unsigned long\n\t"
7875             "SBCS    $tmp,$op2.hi,$op1.hi" %}
7876   ins_encode %{
7877     __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
7878     __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
7879   %}
7880   ins_pipe(ialu_cconly_reg_reg);
7881 %}
7882 
7883 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7884 // (hi($con$$constant), lo($con$$constant)) becomes
7885 instruct compUL_reg_con_LTGE(flagsRegUL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
7886   match(Set xcc (CmpUL op1 con));
7887   effect(DEF xcc, USE op1, USE con, TEMP tmp);
7888 
7889   size(8);
7890   format %{ "SUBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
7891             "SBCS    $tmp,$op1.hi,0" %}
7892   ins_encode %{
7893     __ subs($tmp$$Register, $op1$$Register, $con$$constant);
7894     __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
7895   %}
7896 
7897   ins_pipe(ialu_cconly_reg_reg);
7898 %}
7899 
7900 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7901 // (hi($con$$constant), lo($con$$constant)) becomes
7902 instruct compUL_reg_con_EQNE(flagsRegUL_EQNE xcc, iRegL op1, immLlowRot con) %{
7903   match(Set xcc (CmpUL op1 con));
7904   effect(DEF xcc, USE op1, USE con);
7905 
7906   size(8);
7907   format %{ "TEQ    $op1.hi,0\t\t! unsigned long\n\t"
7908             "TEQ.eq $op1.lo,$con" %}
7909   ins_encode %{
7910     __ teq($op1$$Register->successor(), 0);
7911     __ teq($op1$$Register, $con$$constant, eq);
7912   %}
7913 
7914   ins_pipe(ialu_cconly_reg_reg);
7915 %}
7916 
7917 // TODO: try immLRot2 instead, (0, $con$$constant) becomes
7918 // (hi($con$$constant), lo($con$$constant)) becomes
7919 instruct compUL_reg_con_LEGT(flagsRegUL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
7920   match(Set xcc (CmpUL op1 con));
7921   effect(DEF xcc, USE op1, USE con, TEMP tmp);
7922 
7923   size(8);
7924   format %{ "RSBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
7925             "RSCS    $tmp,$op1.hi,0" %}
7926   ins_encode %{
7927     __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
7928     __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
7929   %}
7930 
7931   ins_pipe(ialu_cconly_reg_reg);
7932 %}
7933 
7934 /* instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ */
7935 /*   match(Set xcc (CmpL (AndL op1 op2) zero)); */
7936 /*   ins_encode %{ */
7937 /*     __ stop("testL_reg_reg unimplemented"); */
7938 /*   %} */
7939 /*   ins_pipe(ialu_cconly_reg_reg); */
7940 /* %} */
7941 
7942 /* // useful for checking the alignment of a pointer: */
7943 /* instruct testL_reg_con(flagsRegL xcc, iRegL op1, immLlowRot con, immL0 zero) %{ */
7944 /*   match(Set xcc (CmpL (AndL op1 con) zero)); */
7945 /*   ins_encode %{ */
7946 /*     __ stop("testL_reg_con unimplemented"); */
7947 /*   %} */
7948 /*   ins_pipe(ialu_cconly_reg_reg); */
7949 /* %} */
7950 
7951 instruct compU_iReg_imm(flagsRegU icc, iRegI op1, aimmU31 op2 ) %{
7952   match(Set icc (CmpU op1 op2));
7953 
7954   size(4);
7955   format %{ "cmp_32 $op1,$op2\t! unsigned" %}
7956   ins_encode %{
7957     __ cmp_32($op1$$Register, $op2$$constant);
7958   %}
7959   ins_pipe(ialu_cconly_reg_imm);
7960 %}
7961 
7962 // Compare Pointers
7963 instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{
7964   match(Set pcc (CmpP op1 op2));
7965 
7966   size(4);
7967   format %{ "CMP    $op1,$op2\t! ptr" %}
7968   ins_encode %{
7969     __ cmp($op1$$Register, $op2$$Register);
7970   %}
7971   ins_pipe(ialu_cconly_reg_reg);
7972 %}
7973 
7974 instruct compP_iRegP_imm(flagsRegP pcc, iRegP op1, aimmP op2 ) %{
7975   match(Set pcc (CmpP op1 op2));
7976 
7977   size(4);
7978   format %{ "CMP    $op1,$op2\t! ptr" %}
7979   ins_encode %{
7980     assert($op2$$constant == 0 || _opnds[2]->constant_reloc() == relocInfo::none, "reloc in cmp?");
7981     __ cmp($op1$$Register, $op2$$constant);
7982   %}
7983   ins_pipe(ialu_cconly_reg_imm);
7984 %}
7985 
7986 //----------Max and Min--------------------------------------------------------
7987 // Min Instructions
7988 // Conditional move for min
7989 instruct cmovI_reg_lt( iRegI op2, iRegI op1, flagsReg icc ) %{
7990   effect( USE_DEF op2, USE op1, USE icc );
7991 
7992   size(4);
7993   format %{ "MOV.lt  $op2,$op1\t! min" %}
7994   ins_encode %{
7995     __ mov($op2$$Register, $op1$$Register, lt);
7996   %}
7997   ins_pipe(ialu_reg_flags);
7998 %}
7999 
8000 // Min Register with Register.
8001 instruct minI_eReg(iRegI op1, iRegI op2) %{
8002   match(Set op2 (MinI op1 op2));
8003   ins_cost(DEFAULT_COST*2);
8004   expand %{
8005     flagsReg icc;
8006     compI_iReg(icc,op1,op2);
8007     cmovI_reg_lt(op2,op1,icc);
8008   %}
8009 %}
8010 
8011 // Max Instructions
8012 // Conditional move for max
8013 instruct cmovI_reg_gt( iRegI op2, iRegI op1, flagsReg icc ) %{
8014   effect( USE_DEF op2, USE op1, USE icc );
8015   format %{ "MOV.gt  $op2,$op1\t! max" %}
8016   ins_encode %{
8017     __ mov($op2$$Register, $op1$$Register, gt);
8018   %}
8019   ins_pipe(ialu_reg_flags);
8020 %}
8021 
8022 // Max Register with Register
8023 instruct maxI_eReg(iRegI op1, iRegI op2) %{
8024   match(Set op2 (MaxI op1 op2));
8025   ins_cost(DEFAULT_COST*2);
8026   expand %{
8027     flagsReg icc;
8028     compI_iReg(icc,op1,op2);
8029     cmovI_reg_gt(op2,op1,icc);
8030   %}
8031 %}
8032 
8033 
8034 //----------Float Compares----------------------------------------------------
8035 // Compare floating, generate condition code
8036 instruct cmpF_cc(flagsRegF fcc, flagsReg icc, regF src1, regF src2) %{
8037   match(Set icc (CmpF src1 src2));
8038   effect(KILL fcc);
8039 
8040   size(8);
8041   format %{ "FCMPs  $src1,$src2\n\t"
8042             "FMSTAT" %}
8043   ins_encode %{
8044     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
8045     __ fmstat();
8046   %}
8047   ins_pipe(faddF_fcc_reg_reg_zero);
8048 %}
8049 
8050 instruct cmpF0_cc(flagsRegF fcc, flagsReg icc, regF src1, immF0 src2) %{
8051   match(Set icc (CmpF src1 src2));
8052   effect(KILL fcc);
8053 
8054   size(8);
8055   format %{ "FCMPs  $src1,$src2\n\t"
8056             "FMSTAT" %}
8057   ins_encode %{
8058     __ fcmpzs($src1$$FloatRegister);
8059     __ fmstat();
8060   %}
8061   ins_pipe(faddF_fcc_reg_reg_zero);
8062 %}
8063 
8064 instruct cmpD_cc(flagsRegF fcc, flagsReg icc, regD src1, regD src2) %{
8065   match(Set icc (CmpD src1 src2));
8066   effect(KILL fcc);
8067 
8068   size(8);
8069   format %{ "FCMPd  $src1,$src2 \n\t"
8070             "FMSTAT" %}
8071   ins_encode %{
8072     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
8073     __ fmstat();
8074   %}
8075   ins_pipe(faddD_fcc_reg_reg_zero);
8076 %}
8077 
8078 instruct cmpD0_cc(flagsRegF fcc, flagsReg icc, regD src1, immD0 src2) %{
8079   match(Set icc (CmpD src1 src2));
8080   effect(KILL fcc);
8081 
8082   size(8);
8083   format %{ "FCMPZd  $src1,$src2 \n\t"
8084             "FMSTAT" %}
8085   ins_encode %{
8086     __ fcmpzd($src1$$FloatRegister);
8087     __ fmstat();
8088   %}
8089   ins_pipe(faddD_fcc_reg_reg_zero);
8090 %}
8091 
8092 // Compare floating, generate -1,0,1
8093 instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsRegF fcc) %{
8094   match(Set dst (CmpF3 src1 src2));
8095   effect(KILL fcc);
8096   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
8097   size(20);
8098   // same number of instructions as code using conditional moves but
8099   // doesn't kill integer condition register
8100   format %{ "FCMPs  $dst,$src1,$src2 \n\t"
8101             "VMRS   $dst, FPSCR \n\t"
8102             "OR     $dst, $dst, 0x08000000 \n\t"
8103             "EOR    $dst, $dst, $dst << 3 \n\t"
8104             "MOV    $dst, $dst >> 30" %}
8105   ins_encode %{
8106     __ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
8107     __ floating_cmp($dst$$Register);
8108   %}
8109   ins_pipe( floating_cmp );
8110 %}
8111 
8112 instruct cmpF0_reg(iRegI dst, regF src1, immF0 src2, flagsRegF fcc) %{
8113   match(Set dst (CmpF3 src1 src2));
8114   effect(KILL fcc);
8115   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
8116   size(20);
8117   // same number of instructions as code using conditional moves but
8118   // doesn't kill integer condition register
8119   format %{ "FCMPZs $dst,$src1,$src2 \n\t"
8120             "VMRS   $dst, FPSCR \n\t"
8121             "OR     $dst, $dst, 0x08000000 \n\t"
8122             "EOR    $dst, $dst, $dst << 3 \n\t"
8123             "MOV    $dst, $dst >> 30" %}
8124   ins_encode %{
8125     __ fcmpzs($src1$$FloatRegister);
8126     __ floating_cmp($dst$$Register);
8127   %}
8128   ins_pipe( floating_cmp );
8129 %}
8130 
8131 instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsRegF fcc) %{
8132   match(Set dst (CmpD3 src1 src2));
8133   effect(KILL fcc);
8134   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
8135   size(20);
8136   // same number of instructions as code using conditional moves but
8137   // doesn't kill integer condition register
8138   format %{ "FCMPd  $dst,$src1,$src2 \n\t"
8139             "VMRS   $dst, FPSCR \n\t"
8140             "OR     $dst, $dst, 0x08000000 \n\t"
8141             "EOR    $dst, $dst, $dst << 3 \n\t"
8142             "MOV    $dst, $dst >> 30" %}
8143   ins_encode %{
8144     __ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
8145     __ floating_cmp($dst$$Register);
8146   %}
8147   ins_pipe( floating_cmp );
8148 %}
8149 
8150 instruct cmpD0_reg(iRegI dst, regD src1, immD0 src2, flagsRegF fcc) %{
8151   match(Set dst (CmpD3 src1 src2));
8152   effect(KILL fcc);
8153   ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
8154   size(20);
8155   // same number of instructions as code using conditional moves but
8156   // doesn't kill integer condition register
8157   format %{ "FCMPZd $dst,$src1,$src2 \n\t"
8158             "VMRS   $dst, FPSCR \n\t"
8159             "OR     $dst, $dst, 0x08000000 \n\t"
8160             "EOR    $dst, $dst, $dst << 3 \n\t"
8161             "MOV    $dst, $dst >> 30" %}
8162   ins_encode %{
8163     __ fcmpzd($src1$$FloatRegister);
8164     __ floating_cmp($dst$$Register);
8165   %}
8166   ins_pipe( floating_cmp );
8167 %}
8168 
8169 //----------Branches---------------------------------------------------------
8170 // Jump
8171 // (compare 'operand indIndex' and 'instruct addP_reg_reg' above)
8172 // FIXME
8173 instruct jumpXtnd(iRegX switch_val, iRegP tmp) %{
8174   match(Jump switch_val);
8175   effect(TEMP tmp);
8176   ins_cost(350);
8177   format %{  "ADD    $tmp, $constanttablebase, $switch_val\n\t"
8178              "LDR    $tmp,[$tmp + $constantoffset]\n\t"
8179              "BX     $tmp" %}
8180   size(20);
8181   ins_encode %{
8182     Register table_reg;
8183     Register label_reg = $tmp$$Register;
8184     if (constant_offset() == 0) {
8185       table_reg = $constanttablebase;
8186       __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
8187     } else {
8188       table_reg = $tmp$$Register;
8189       int offset = $constantoffset;
8190       if (is_memoryP(offset)) {
8191         __ add(table_reg, $constanttablebase, $switch_val$$Register);
8192         __ ldr(label_reg, Address(table_reg, offset));
8193       } else {
8194         __ mov_slow(table_reg, $constantoffset);
8195         __ add(table_reg, $constanttablebase, table_reg);
8196         __ ldr(label_reg, Address(table_reg, $switch_val$$Register));
8197       }
8198     }
8199     __ jump(label_reg); // ldr + b better than ldr to PC for branch predictor?
8200     //    __ ldr(PC, Address($table$$Register, $switch_val$$Register));
8201   %}
8202   ins_pipe(ialu_reg_reg);
8203 %}
8204 
8205 // // Direct Branch.
8206 instruct branch(label labl) %{
8207   match(Goto);
8208   effect(USE labl);
8209 
8210   size(4);
8211   ins_cost(BRANCH_COST);
8212   format %{ "B     $labl" %}
8213   ins_encode %{
8214     __ b(*($labl$$label));
8215   %}
8216   ins_pipe(br);
8217 %}
8218 
8219 // Conditional Direct Branch
8220 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{
8221   match(If cmp icc);
8222   effect(USE labl);
8223 
8224   size(4);
8225   ins_cost(BRANCH_COST);
8226   format %{ "B$cmp   $icc,$labl" %}
8227   ins_encode %{
8228     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8229   %}
8230   ins_pipe(br_cc);
8231 %}
8232 
8233 #ifdef ARM
8234 instruct branchCon_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, label labl) %{
8235   match(If cmp icc);
8236   effect(USE labl);
8237   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);
8238 
8239   size(4);
8240   ins_cost(BRANCH_COST);
8241   format %{ "B$cmp   $icc,$labl" %}
8242   ins_encode %{
8243     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8244   %}
8245   ins_pipe(br_cc);
8246 %}
8247 #endif
8248 
8249 
8250 instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{
8251   match(If cmp icc);
8252   effect(USE labl);
8253 
8254   size(4);
8255   ins_cost(BRANCH_COST);
8256   format %{ "B$cmp  $icc,$labl" %}
8257   ins_encode %{
8258     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8259   %}
8260   ins_pipe(br_cc);
8261 %}
8262 
8263 instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{
8264   match(If cmp pcc);
8265   effect(USE labl);
8266 
8267   size(4);
8268   ins_cost(BRANCH_COST);
8269   format %{ "B$cmp  $pcc,$labl" %}
8270   ins_encode %{
8271     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8272   %}
8273   ins_pipe(br_cc);
8274 %}
8275 
8276 instruct branchConL_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, label labl) %{
8277   match(If cmp xcc);
8278   effect(USE labl);
8279   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8280 
8281   size(4);
8282   ins_cost(BRANCH_COST);
8283   format %{ "B$cmp  $xcc,$labl" %}
8284   ins_encode %{
8285     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8286   %}
8287   ins_pipe(br_cc);
8288 %}
8289 
8290 instruct branchConL_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, label labl) %{
8291   match(If cmp xcc);
8292   effect(USE labl);
8293   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8294 
8295   size(4);
8296   ins_cost(BRANCH_COST);
8297   format %{ "B$cmp  $xcc,$labl" %}
8298   ins_encode %{
8299     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8300   %}
8301   ins_pipe(br_cc);
8302 %}
8303 
8304 instruct branchConL_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, label labl) %{
8305   match(If cmp xcc);
8306   effect(USE labl);
8307   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le );
8308 
8309   size(4);
8310   ins_cost(BRANCH_COST);
8311   format %{ "B$cmp  $xcc,$labl" %}
8312   ins_encode %{
8313     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8314   %}
8315   ins_pipe(br_cc);
8316 %}
8317 
8318 instruct branchConUL_LTGE(cmpOpUL cmp, flagsRegUL_LTGE xcc, label labl) %{
8319   match(If cmp xcc);
8320   effect(USE labl);
8321   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
8322 
8323   size(4);
8324   ins_cost(BRANCH_COST);
8325   format %{ "B$cmp  $xcc,$labl" %}
8326   ins_encode %{
8327     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8328   %}
8329   ins_pipe(br_cc);
8330 %}
8331 
8332 instruct branchConUL_EQNE(cmpOpUL cmp, flagsRegUL_EQNE xcc, label labl) %{
8333   match(If cmp xcc);
8334   effect(USE labl);
8335   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
8336 
8337   size(4);
8338   ins_cost(BRANCH_COST);
8339   format %{ "B$cmp  $xcc,$labl" %}
8340   ins_encode %{
8341     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8342   %}
8343   ins_pipe(br_cc);
8344 %}
8345 
8346 instruct branchConUL_LEGT(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, label labl) %{
8347   match(If cmp xcc);
8348   effect(USE labl);
8349   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le);
8350 
8351   size(4);
8352   ins_cost(BRANCH_COST);
8353   format %{ "B$cmp  $xcc,$labl" %}
8354   ins_encode %{
8355     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8356   %}
8357   ins_pipe(br_cc);
8358 %}
8359 
8360 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
8361   match(CountedLoopEnd cmp icc);
8362   effect(USE labl);
8363 
8364   size(4);
8365   ins_cost(BRANCH_COST);
8366   format %{ "B$cmp   $icc,$labl\t! Loop end" %}
8367   ins_encode %{
8368     __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
8369   %}
8370   ins_pipe(br_cc);
8371 %}
8372 
8373 // instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{
8374 //   match(CountedLoopEnd cmp icc);
8375 //   ins_pipe(br_cc);
8376 // %}
8377 
8378 // ============================================================================
8379 // Long Compare
8380 //
8381 // Currently we hold longs in 2 registers.  Comparing such values efficiently
8382 // is tricky.  The flavor of compare used depends on whether we are testing
8383 // for LT, LE, or EQ.  For a simple LT test we can check just the sign bit.
8384 // The GE test is the negated LT test.  The LE test can be had by commuting
8385 // the operands (yielding a GE test) and then negating; negate again for the
8386 // GT test.  The EQ test is done by ORcc'ing the high and low halves, and the
8387 // NE test is negated from that.
8388 
8389 // Due to a shortcoming in the ADLC, it mixes up expressions like:
8390 // (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)).  Note the
8391 // difference between 'Y' and '0L'.  The tree-matches for the CmpI sections
8392 // are collapsed internally in the ADLC's dfa-gen code.  The match for
8393 // (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the
8394 // foo match ends up with the wrong leaf.  One fix is to not match both
8395 // reg-reg and reg-zero forms of long-compare.  This is unfortunate because
8396 // both forms beat the trinary form of long-compare and both are very useful
8397 // on Intel which has so few registers.
8398 
8399 // instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{
8400 //   match(If cmp xcc);
8401 //   ins_pipe(br_cc);
8402 // %}
8403 
8404 // Manifest a CmpL3 result in an integer register.  Very painful.
8405 // This is the test to avoid.
8406 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
8407   match(Set dst (CmpL3 src1 src2) );
8408   effect( KILL ccr );
8409   ins_cost(6*DEFAULT_COST); // FIXME
8410   size(32);
8411   format %{
8412       "CMP    $src1.hi, $src2.hi\t\t! long\n"
8413     "\tMOV.gt $dst, 1\n"
8414     "\tmvn.lt $dst, 0\n"
8415     "\tB.ne   done\n"
8416     "\tSUBS   $dst, $src1.lo, $src2.lo\n"
8417     "\tMOV.hi $dst, 1\n"
8418     "\tmvn.lo $dst, 0\n"
8419     "done:"     %}
8420   ins_encode %{
8421     Label done;
8422     __ cmp($src1$$Register->successor(), $src2$$Register->successor());
8423     __ mov($dst$$Register, 1, gt);
8424     __ mvn($dst$$Register, 0, lt);
8425     __ b(done, ne);
8426     __ subs($dst$$Register, $src1$$Register, $src2$$Register);
8427     __ mov($dst$$Register, 1, hi);
8428     __ mvn($dst$$Register, 0, lo);
8429     __ bind(done);
8430   %}
8431   ins_pipe(cmpL_reg);
8432 %}
8433 
8434 // Conditional move
8435 instruct cmovLL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, iRegL src) %{
8436   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
8437   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8438 
8439   ins_cost(150);
8440   size(8);
8441   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
8442             "MOV$cmp  $dst,$src.hi" %}
8443   ins_encode %{
8444     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8445     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
8446   %}
8447   ins_pipe(ialu_reg);
8448 %}
8449 
8450 instruct cmovLL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, iRegL src) %{
8451   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
8452   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8453 
8454   ins_cost(150);
8455   size(8);
8456   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
8457             "MOV$cmp  $dst,$src.hi" %}
8458   ins_encode %{
8459     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8460     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
8461   %}
8462   ins_pipe(ialu_reg);
8463 %}
8464 
8465 instruct cmovLL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, iRegL src) %{
8466   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
8467   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8468 
8469   ins_cost(150);
8470   size(8);
8471   format %{ "MOV$cmp  $dst.lo,$src.lo\t! long\n\t"
8472             "MOV$cmp  $dst,$src.hi" %}
8473   ins_encode %{
8474     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8475     __ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
8476   %}
8477   ins_pipe(ialu_reg);
8478 %}
8479 
8480 instruct cmovLL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, immL0 src) %{
8481   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
8482   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8483   ins_cost(140);
8484   size(8);
8485   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
8486             "MOV$cmp  $dst,0" %}
8487   ins_encode %{
8488     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
8489     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
8490   %}
8491   ins_pipe(ialu_imm);
8492 %}
8493 
8494 instruct cmovLL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, immL0 src) %{
8495   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
8496   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8497   ins_cost(140);
8498   size(8);
8499   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
8500             "MOV$cmp  $dst,0" %}
8501   ins_encode %{
8502     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
8503     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
8504   %}
8505   ins_pipe(ialu_imm);
8506 %}
8507 
8508 instruct cmovLL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, immL0 src) %{
8509   match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
8510   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8511   ins_cost(140);
8512   size(8);
8513   format %{ "MOV$cmp  $dst.lo,0\t! long\n\t"
8514             "MOV$cmp  $dst,0" %}
8515   ins_encode %{
8516     __ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
8517     __ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
8518   %}
8519   ins_pipe(ialu_imm);
8520 %}
8521 
8522 instruct cmovIL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, iRegI src) %{
8523   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
8524   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8525 
8526   ins_cost(150);
8527   size(4);
8528   format %{ "MOV$cmp  $dst,$src" %}
8529   ins_encode %{
8530     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8531   %}
8532   ins_pipe(ialu_reg);
8533 %}
8534 
8535 instruct cmovIL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, iRegI src) %{
8536   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
8537   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8538 
8539   ins_cost(150);
8540   size(4);
8541   format %{ "MOV$cmp  $dst,$src" %}
8542   ins_encode %{
8543     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8544   %}
8545   ins_pipe(ialu_reg);
8546 %}
8547 
8548 instruct cmovIL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, iRegI src) %{
8549   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
8550   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8551 
8552   ins_cost(150);
8553   size(4);
8554   format %{ "MOV$cmp  $dst,$src" %}
8555   ins_encode %{
8556     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8557   %}
8558   ins_pipe(ialu_reg);
8559 %}
8560 
8561 instruct cmovIL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immI16 src) %{
8562   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
8563   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8564 
8565   ins_cost(140);
8566   format %{ "MOVW$cmp  $dst,$src" %}
8567   ins_encode %{
8568     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
8569   %}
8570   ins_pipe(ialu_imm);
8571 %}
8572 
8573 instruct cmovIL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, immI16 src) %{
8574   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
8575   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8576 
8577   ins_cost(140);
8578   format %{ "MOVW$cmp  $dst,$src" %}
8579   ins_encode %{
8580     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
8581   %}
8582   ins_pipe(ialu_imm);
8583 %}
8584 
8585 instruct cmovIL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immI16 src) %{
8586   match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
8587   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8588 
8589   ins_cost(140);
8590   format %{ "MOVW$cmp  $dst,$src" %}
8591   ins_encode %{
8592     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
8593   %}
8594   ins_pipe(ialu_imm);
8595 %}
8596 
8597 instruct cmovPL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, iRegP src) %{
8598   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
8599   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8600 
8601   ins_cost(150);
8602   size(4);
8603   format %{ "MOV$cmp  $dst,$src" %}
8604   ins_encode %{
8605     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8606   %}
8607   ins_pipe(ialu_reg);
8608 %}
8609 
8610 instruct cmovPL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, iRegP src) %{
8611   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
8612   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8613 
8614   ins_cost(150);
8615   size(4);
8616   format %{ "MOV$cmp  $dst,$src" %}
8617   ins_encode %{
8618     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8619   %}
8620   ins_pipe(ialu_reg);
8621 %}
8622 
8623 instruct cmovPL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, iRegP src) %{
8624   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
8625   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8626 
8627   ins_cost(150);
8628   size(4);
8629   format %{ "MOV$cmp  $dst,$src" %}
8630   ins_encode %{
8631     __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
8632   %}
8633   ins_pipe(ialu_reg);
8634 %}
8635 
8636 instruct cmovPL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, immP0 src) %{
8637   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
8638   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8639 
8640   ins_cost(140);
8641   format %{ "MOVW$cmp  $dst,$src" %}
8642   ins_encode %{
8643     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
8644   %}
8645   ins_pipe(ialu_imm);
8646 %}
8647 
8648 instruct cmovPL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, immP0 src) %{
8649   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
8650   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8651 
8652   ins_cost(140);
8653   format %{ "MOVW$cmp  $dst,$src" %}
8654   ins_encode %{
8655     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
8656   %}
8657   ins_pipe(ialu_imm);
8658 %}
8659 
8660 instruct cmovPL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, immP0 src) %{
8661   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
8662   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8663 
8664   ins_cost(140);
8665   format %{ "MOVW$cmp  $dst,$src" %}
8666   ins_encode %{
8667     __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
8668   %}
8669   ins_pipe(ialu_imm);
8670 %}
8671 
8672 instruct cmovFL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regF dst, regF src) %{
8673   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
8674   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8675   ins_cost(150);
8676   size(4);
8677   format %{ "FCPYS$cmp $dst,$src" %}
8678   ins_encode %{
8679     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
8680   %}
8681   ins_pipe(int_conditional_float_move);
8682 %}
8683 
8684 instruct cmovFL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regF dst, regF src) %{
8685   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
8686   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8687   ins_cost(150);
8688   size(4);
8689   format %{ "FCPYS$cmp $dst,$src" %}
8690   ins_encode %{
8691     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
8692   %}
8693   ins_pipe(int_conditional_float_move);
8694 %}
8695 
8696 instruct cmovFL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regF dst, regF src) %{
8697   match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src)));
8698   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8699   ins_cost(150);
8700   size(4);
8701   format %{ "FCPYS$cmp $dst,$src" %}
8702   ins_encode %{
8703     __ fcpys($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
8704   %}
8705   ins_pipe(int_conditional_float_move);
8706 %}
8707 
8708 instruct cmovDL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regD dst, regD src) %{
8709   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
8710   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
8711 
8712   ins_cost(150);
8713   size(4);
8714   format %{ "FCPYD$cmp $dst,$src" %}
8715   ins_encode %{
8716     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
8717   %}
8718   ins_pipe(int_conditional_float_move);
8719 %}
8720 
8721 instruct cmovDL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regD dst, regD src) %{
8722   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
8723   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
8724 
8725   ins_cost(150);
8726   size(4);
8727   format %{ "FCPYD$cmp $dst,$src" %}
8728   ins_encode %{
8729     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
8730   %}
8731   ins_pipe(int_conditional_float_move);
8732 %}
8733 
8734 instruct cmovDL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regD dst, regD src) %{
8735   match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src)));
8736   predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
8737 
8738   ins_cost(150);
8739   size(4);
8740   format %{ "FCPYD$cmp $dst,$src" %}
8741   ins_encode %{
8742     __ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
8743   %}
8744   ins_pipe(int_conditional_float_move);
8745 %}
8746 
8747 // ============================================================================
8748 // Safepoint Instruction
8749 // rather than KILL R12, it would be better to use any reg as
8750 // TEMP. Can't do that at this point because it crashes the compiler
8751 instruct safePoint_poll(iRegP poll, R12RegI tmp, flagsReg icc) %{
8752   match(SafePoint poll);
8753   effect(USE poll, KILL tmp, KILL icc);
8754 
8755   size(4);
8756   format %{ "LDR   $tmp,[$poll]\t! Safepoint: poll for GC" %}
8757   ins_encode %{
8758     __ relocate(relocInfo::poll_type);
8759     __ ldr($tmp$$Register, Address($poll$$Register));
8760   %}
8761   ins_pipe(loadPollP);
8762 %}
8763 
8764 
8765 // ============================================================================
8766 // Call Instructions
8767 // Call Java Static Instruction
8768 instruct CallStaticJavaDirect( method meth ) %{
8769   match(CallStaticJava);
8770   predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke());
8771   effect(USE meth);
8772 
8773   ins_cost(CALL_COST);
8774   format %{ "CALL,static ==> " %}
8775   ins_encode( Java_Static_Call( meth ), call_epilog );
8776   ins_pipe(simple_call);
8777 %}
8778 
8779 // Call Java Static Instruction (method handle version)
8780 instruct CallStaticJavaHandle( method meth ) %{
8781   match(CallStaticJava);
8782   predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke());
8783   effect(USE meth);
8784   // FP is saved by all callees (for interpreter stack correction).
8785   // We use it here for a similar purpose, in {preserve,restore}_FP.
8786 
8787   ins_cost(CALL_COST);
8788   format %{ "CALL,static/MethodHandle ==> " %}
8789   ins_encode( preserve_SP, Java_Static_Call( meth ), restore_SP, call_epilog );
8790   ins_pipe(simple_call);
8791 %}
8792 
8793 // Call Java Dynamic Instruction
8794 instruct CallDynamicJavaDirect( method meth ) %{
8795   match(CallDynamicJava);
8796   effect(USE meth);
8797 
8798   ins_cost(CALL_COST);
8799   format %{ "MOV_OOP    (empty),R_R8\n\t"
8800             "CALL,dynamic  ; NOP ==> " %}
8801   ins_encode( Java_Dynamic_Call( meth ), call_epilog );
8802   ins_pipe(call);
8803 %}
8804 
8805 // Call Runtime Instruction
8806 instruct CallRuntimeDirect(method meth) %{
8807   match(CallRuntime);
8808   effect(USE meth);
8809   ins_cost(CALL_COST);
8810   format %{ "CALL,runtime" %}
8811   ins_encode( Java_To_Runtime( meth ),
8812               call_epilog );
8813   ins_pipe(simple_call);
8814 %}
8815 
8816 // Call runtime without safepoint - same as CallRuntime
8817 instruct CallLeafDirect(method meth) %{
8818   match(CallLeaf);
8819   effect(USE meth);
8820   ins_cost(CALL_COST);
8821   format %{ "CALL,runtime leaf" %}
8822   // TODO: ned save_last_PC here?
8823   ins_encode( Java_To_Runtime( meth ),
8824               call_epilog );
8825   ins_pipe(simple_call);
8826 %}
8827 
8828 // Call runtime without safepoint - same as CallLeaf
8829 instruct CallLeafNoFPDirect(method meth) %{
8830   match(CallLeafNoFP);
8831   effect(USE meth);
8832   ins_cost(CALL_COST);
8833   format %{ "CALL,runtime leaf nofp" %}
8834   // TODO: ned save_last_PC here?
8835   ins_encode( Java_To_Runtime( meth ),
8836               call_epilog );
8837   ins_pipe(simple_call);
8838 %}
8839 
8840 // Tail Call; Jump from runtime stub to Java code.
8841 // Also known as an 'interprocedural jump'.
8842 // Target of jump will eventually return to caller.
8843 // TailJump below removes the return address.
8844 instruct TailCalljmpInd(IPRegP jump_target, inline_cache_regP method_oop) %{
8845   match(TailCall jump_target method_oop );
8846 
8847   ins_cost(CALL_COST);
8848   format %{ "MOV    Rexception_pc, LR\n\t"
8849             "jump   $jump_target  \t! $method_oop holds method oop" %}
8850   ins_encode %{
8851     __ mov(Rexception_pc, LR);   // this is used only to call
8852                                  // StubRoutines::forward_exception_entry()
8853                                  // which expects PC of exception in
8854                                  // R5. FIXME?
8855     __ jump($jump_target$$Register);
8856   %}
8857   ins_pipe(tail_call);
8858 %}
8859 
8860 
8861 // Return Instruction
8862 instruct Ret() %{
8863   match(Return);
8864 
8865   format %{ "ret LR" %}
8866 
8867   ins_encode %{
8868     __ ret(LR);
8869   %}
8870 
8871   ins_pipe(br);
8872 %}
8873 
8874 
8875 // Tail Jump; remove the return address; jump to target.
8876 // TailCall above leaves the return address around.
8877 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
8878 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
8879 // "restore" before this instruction (in Epilogue), we need to materialize it
8880 // in %i0.
8881 instruct tailjmpInd(IPRegP jump_target, RExceptionRegP ex_oop) %{
8882   match( TailJump jump_target ex_oop );
8883   ins_cost(CALL_COST);
8884   format %{ "MOV    Rexception_pc, LR\n\t"
8885             "jump   $jump_target \t! $ex_oop holds exc. oop" %}
8886   ins_encode %{
8887     __ mov(Rexception_pc, LR);
8888     __ jump($jump_target$$Register);
8889   %}
8890   ins_pipe(tail_call);
8891 %}
8892 
8893 // Create exception oop: created by stack-crawling runtime code.
8894 // Created exception is now available to this handler, and is setup
8895 // just prior to jumping to this handler.  No code emitted.
8896 instruct CreateException( RExceptionRegP ex_oop )
8897 %{
8898   match(Set ex_oop (CreateEx));
8899   ins_cost(0);
8900 
8901   size(0);
8902   // use the following format syntax
8903   format %{ "! exception oop is in Rexception_obj; no code emitted" %}
8904   ins_encode();
8905   ins_pipe(empty);
8906 %}
8907 
8908 
8909 // Rethrow exception:
8910 // The exception oop will come in the first argument position.
8911 // Then JUMP (not call) to the rethrow stub code.
8912 instruct RethrowException()
8913 %{
8914   match(Rethrow);
8915   ins_cost(CALL_COST);
8916 
8917   // use the following format syntax
8918   format %{ "b    rethrow_stub" %}
8919   ins_encode %{
8920     Register scratch = R1_tmp;
8921     assert_different_registers(scratch, c_rarg0, LR);
8922     __ jump(OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type, scratch);
8923   %}
8924   ins_pipe(tail_call);
8925 %}
8926 
8927 
8928 // Die now
8929 instruct ShouldNotReachHere( )
8930 %{
8931   match(Halt);
8932   ins_cost(CALL_COST);
8933 
8934   size(4);
8935   // Use the following format syntax
8936   format %{ "ShouldNotReachHere" %}
8937   ins_encode %{
8938     __ udf(0xdead);
8939   %}
8940   ins_pipe(tail_call);
8941 %}
8942 
8943 // ============================================================================
8944 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
8945 // array for an instance of the superklass.  Set a hidden internal cache on a
8946 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
8947 // not zero for a miss or zero for a hit.  The encoding ALSO sets flags.
8948 instruct partialSubtypeCheck( R0RegP index, R1RegP sub, R2RegP super, flagsRegP pcc, LRRegP lr ) %{
8949   match(Set index (PartialSubtypeCheck sub super));
8950   effect( KILL pcc, KILL lr );
8951   ins_cost(DEFAULT_COST*10);
8952   format %{ "CALL   PartialSubtypeCheck" %}
8953   ins_encode %{
8954     __ call(StubRoutines::Arm::partial_subtype_check(), relocInfo::runtime_call_type);
8955   %}
8956   ins_pipe(partial_subtype_check_pipe);
8957 %}
8958 
8959 /* instruct partialSubtypeCheck_vs_zero( flagsRegP pcc, o1RegP sub, o2RegP super, immP0 zero, o0RegP idx, o7RegP o7 ) %{ */
8960 /*   match(Set pcc (CmpP (PartialSubtypeCheck sub super) zero)); */
8961 /*   ins_pipe(partial_subtype_check_pipe); */
8962 /* %} */
8963 
8964 
8965 // ============================================================================
8966 // inlined locking and unlocking
8967 
8968 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch )
8969 %{
8970   match(Set pcc (FastLock object box));
8971   predicate(!(UseBiasedLocking && !UseOptoBiasInlining));
8972 
8973   effect(TEMP scratch, TEMP scratch2);
8974   ins_cost(DEFAULT_COST*3);
8975 
8976   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2" %}
8977   ins_encode %{
8978     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
8979   %}
8980   ins_pipe(long_memory_op);
8981 %}
8982 
8983 instruct cmpFastLock_noBiasInline(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2,
8984                                   iRegP scratch, iRegP scratch3) %{
8985   match(Set pcc (FastLock object box));
8986   predicate(UseBiasedLocking && !UseOptoBiasInlining);
8987 
8988   effect(TEMP scratch, TEMP scratch2, TEMP scratch3);
8989   ins_cost(DEFAULT_COST*5);
8990 
8991   format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2, $scratch3" %}
8992   ins_encode %{
8993     __ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register, $scratch3$$Register);
8994   %}
8995   ins_pipe(long_memory_op);
8996 %}
8997 
8998 
8999 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch ) %{
9000   match(Set pcc (FastUnlock object box));
9001   effect(TEMP scratch, TEMP scratch2);
9002   ins_cost(100);
9003 
9004   format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2" %}
9005   ins_encode %{
9006     __ fast_unlock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
9007   %}
9008   ins_pipe(long_memory_op);
9009 %}
9010 
9011 // Count and Base registers are fixed because the allocator cannot
9012 // kill unknown registers.  The encodings are generic.
9013 instruct clear_array(iRegX cnt, iRegP base, iRegI temp, iRegX zero, Universe dummy, flagsReg cpsr) %{
9014   match(Set dummy (ClearArray cnt base));
9015   effect(TEMP temp, TEMP zero, KILL cpsr);
9016   ins_cost(300);
9017   format %{ "MOV    $zero,0\n"
9018       "        MOV    $temp,$cnt\n"
9019       "loop:   SUBS   $temp,$temp,4\t! Count down a dword of bytes\n"
9020       "        STR.ge $zero,[$base+$temp]\t! delay slot"
9021       "        B.gt   loop\t\t! Clearing loop\n" %}
9022   ins_encode %{
9023     __ mov($zero$$Register, 0);
9024     __ mov($temp$$Register, $cnt$$Register);
9025     Label(loop);
9026     __ bind(loop);
9027     __ subs($temp$$Register, $temp$$Register, 4);
9028     __ str($zero$$Register, Address($base$$Register, $temp$$Register), ge);
9029     __ b(loop, gt);
9030   %}
9031   ins_pipe(long_memory_op);
9032 %}
9033 
9034 #ifdef XXX
9035 // FIXME: Why R0/R1/R2/R3?
9036 instruct string_compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result,
9037                         iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
9038   predicate(!CompactStrings);
9039   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
9040   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, TEMP tmp1, TEMP tmp2);
9041   ins_cost(300);
9042   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // TEMP $tmp1, $tmp2" %}
9043   ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result, tmp1, tmp2) );
9044 
9045   ins_pipe(long_memory_op);
9046 %}
9047 
9048 // FIXME: Why R0/R1/R2?
9049 instruct string_equals(R0RegP str1, R1RegP str2, R2RegI cnt, iRegI result, iRegI tmp1, iRegI tmp2,
9050                        flagsReg ccr) %{
9051   predicate(!CompactStrings);
9052   match(Set result (StrEquals (Binary str1 str2) cnt));
9053   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp1, TEMP tmp2, TEMP result, KILL ccr);
9054 
9055   ins_cost(300);
9056   format %{ "String Equals $str1,$str2,$cnt -> $result   // TEMP $tmp1, $tmp2" %}
9057   ins_encode( enc_String_Equals(str1, str2, cnt, result, tmp1, tmp2) );
9058   ins_pipe(long_memory_op);
9059 %}
9060 
9061 // FIXME: Why R0/R1?
9062 instruct array_equals(R0RegP ary1, R1RegP ary2, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI result,
9063                       flagsReg ccr) %{
9064   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
9065   match(Set result (AryEq ary1 ary2));
9066   effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP result, KILL ccr);
9067 
9068   ins_cost(300);
9069   format %{ "Array Equals $ary1,$ary2 -> $result   // TEMP $tmp1,$tmp2,$tmp3" %}
9070   ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, result));
9071   ins_pipe(long_memory_op);
9072 %}
9073 #endif
9074 
9075 //---------- Zeros Count Instructions ------------------------------------------
9076 
9077 instruct countLeadingZerosI(iRegI dst, iRegI src) %{
9078   match(Set dst (CountLeadingZerosI src));
9079   size(4);
9080   format %{ "CLZ_32 $dst,$src" %}
9081   ins_encode %{
9082     __ clz_32($dst$$Register, $src$$Register);
9083   %}
9084   ins_pipe(ialu_reg);
9085 %}
9086 
9087 instruct countLeadingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
9088   match(Set dst (CountLeadingZerosL src));
9089   effect(TEMP tmp, TEMP dst, KILL ccr);
9090   size(16);
9091   format %{ "CLZ    $dst,$src.hi\n\t"
9092             "TEQ    $dst,32\n\t"
9093             "CLZ.eq $tmp,$src.lo\n\t"
9094             "ADD.eq $dst, $dst, $tmp\n\t" %}
9095   ins_encode %{
9096     __ clz($dst$$Register, $src$$Register->successor());
9097     __ teq($dst$$Register, 32);
9098     __ clz($tmp$$Register, $src$$Register, eq);
9099     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
9100   %}
9101   ins_pipe(ialu_reg);
9102 %}
9103 
9104 instruct countTrailingZerosI(iRegI dst, iRegI src, iRegI tmp) %{
9105   match(Set dst (CountTrailingZerosI src));
9106   effect(TEMP tmp);
9107   size(8);
9108   format %{ "RBIT_32 $tmp, $src\n\t"
9109             "CLZ_32  $dst,$tmp" %}
9110   ins_encode %{
9111     __ rbit_32($tmp$$Register, $src$$Register);
9112     __ clz_32($dst$$Register, $tmp$$Register);
9113   %}
9114   ins_pipe(ialu_reg);
9115 %}
9116 
9117 instruct countTrailingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
9118   match(Set dst (CountTrailingZerosL src));
9119   effect(TEMP tmp, TEMP dst, KILL ccr);
9120   size(24);
9121   format %{ "RBIT   $tmp,$src.lo\n\t"
9122             "CLZ    $dst,$tmp\n\t"
9123             "TEQ    $dst,32\n\t"
9124             "RBIT   $tmp,$src.hi\n\t"
9125             "CLZ.eq $tmp,$tmp\n\t"
9126             "ADD.eq $dst,$dst,$tmp\n\t" %}
9127   ins_encode %{
9128     __ rbit($tmp$$Register, $src$$Register);
9129     __ clz($dst$$Register, $tmp$$Register);
9130     __ teq($dst$$Register, 32);
9131     __ rbit($tmp$$Register, $src$$Register->successor());
9132     __ clz($tmp$$Register, $tmp$$Register, eq);
9133     __ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
9134   %}
9135   ins_pipe(ialu_reg);
9136 %}
9137 
9138 
9139 //---------- Population Count Instructions -------------------------------------
9140 
9141 instruct popCountI(iRegI dst, iRegI src, regD_low tmp) %{
9142   predicate(UsePopCountInstruction);
9143   match(Set dst (PopCountI src));
9144   effect(TEMP tmp);
9145 
9146   format %{ "FMSR       $tmp,$src\n\t"
9147             "VCNT.8     $tmp,$tmp\n\t"
9148             "VPADDL.U8  $tmp,$tmp\n\t"
9149             "VPADDL.U16 $tmp,$tmp\n\t"
9150             "FMRS       $dst,$tmp" %}
9151   size(20);
9152 
9153   ins_encode %{
9154     __ fmsr($tmp$$FloatRegister, $src$$Register);
9155     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
9156     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
9157     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
9158     __ fmrs($dst$$Register, $tmp$$FloatRegister);
9159   %}
9160   ins_pipe(ialu_reg); // FIXME
9161 %}
9162 
9163 // Note: Long.bitCount(long) returns an int.
9164 instruct popCountL(iRegI dst, iRegL src, regD_low tmp) %{
9165   predicate(UsePopCountInstruction);
9166   match(Set dst (PopCountL src));
9167   effect(TEMP tmp);
9168 
9169   format %{ "FMDRR       $tmp,$src.lo,$src.hi\n\t"
9170             "VCNT.8      $tmp,$tmp\n\t"
9171             "VPADDL.U8   $tmp,$tmp\n\t"
9172             "VPADDL.U16  $tmp,$tmp\n\t"
9173             "VPADDL.U32  $tmp,$tmp\n\t"
9174             "FMRS        $dst,$tmp" %}
9175 
9176   size(32);
9177 
9178   ins_encode %{
9179     __ fmdrr($tmp$$FloatRegister, $src$$Register, $src$$Register->successor());
9180     __ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister);
9181     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 8, 0);
9182     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
9183     __ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 32, 0);
9184     __ fmrs($dst$$Register, $tmp$$FloatRegister);
9185   %}
9186   ins_pipe(ialu_reg);
9187 %}
9188 
9189 
9190 // ============================================================================
9191 //------------Bytes reverse--------------------------------------------------
9192 
9193 instruct bytes_reverse_int(iRegI dst, iRegI src) %{
9194   match(Set dst (ReverseBytesI src));
9195 
9196   size(4);
9197   format %{ "REV32 $dst,$src" %}
9198   ins_encode %{
9199     __ rev($dst$$Register, $src$$Register);
9200   %}
9201   ins_pipe( iload_mem ); // FIXME
9202 %}
9203 
9204 instruct bytes_reverse_long(iRegL dst, iRegL src) %{
9205   match(Set dst (ReverseBytesL src));
9206   effect(TEMP dst);
9207   size(8);
9208   format %{ "REV $dst.lo,$src.lo\n\t"
9209             "REV $dst.hi,$src.hi" %}
9210   ins_encode %{
9211     __ rev($dst$$Register, $src$$Register->successor());
9212     __ rev($dst$$Register->successor(), $src$$Register);
9213   %}
9214   ins_pipe( iload_mem ); // FIXME
9215 %}
9216 
9217 instruct bytes_reverse_unsigned_short(iRegI dst, iRegI src) %{
9218   match(Set dst (ReverseBytesUS src));
9219   size(4);
9220   format %{ "REV16 $dst,$src" %}
9221   ins_encode %{
9222     __ rev16($dst$$Register, $src$$Register);
9223   %}
9224   ins_pipe( iload_mem ); // FIXME
9225 %}
9226 
9227 instruct bytes_reverse_short(iRegI dst, iRegI src) %{
9228   match(Set dst (ReverseBytesS src));
9229   size(4);
9230   format %{ "REVSH $dst,$src" %}
9231   ins_encode %{
9232     __ revsh($dst$$Register, $src$$Register);
9233   %}
9234   ins_pipe( iload_mem ); // FIXME
9235 %}
9236 
9237 
9238 // ====================VECTOR INSTRUCTIONS=====================================
9239 
9240 // Load Aligned Packed values into a Double Register
9241 instruct loadV8(vecD dst, memoryD mem) %{
9242   predicate(n->as_LoadVector()->memory_size() == 8);
9243   match(Set dst (LoadVector mem));
9244   ins_cost(MEMORY_REF_COST);
9245   size(4);
9246   format %{ "FLDD   $mem,$dst\t! load vector (8 bytes)" %}
9247   ins_encode %{
9248     __ ldr_double($dst$$FloatRegister, $mem$$Address);
9249   %}
9250   ins_pipe(floadD_mem);
9251 %}
9252 
9253 // Load Aligned Packed values into a Double Register Pair
9254 instruct loadV16(vecX dst, memoryvld mem) %{
9255   predicate(n->as_LoadVector()->memory_size() == 16);
9256   match(Set dst (LoadVector mem));
9257   ins_cost(MEMORY_REF_COST);
9258   size(4);
9259   format %{ "VLD1   $mem,$dst.Q\t! load vector (16 bytes)" %}
9260   ins_encode %{
9261     __ vld1($dst$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
9262   %}
9263   ins_pipe(floadD_mem); // FIXME
9264 %}
9265 
9266 // Store Vector in Double register to memory
9267 instruct storeV8(memoryD mem, vecD src) %{
9268   predicate(n->as_StoreVector()->memory_size() == 8);
9269   match(Set mem (StoreVector mem src));
9270   ins_cost(MEMORY_REF_COST);
9271   size(4);
9272   format %{ "FSTD   $src,$mem\t! store vector (8 bytes)" %}
9273   ins_encode %{
9274     __ str_double($src$$FloatRegister, $mem$$Address);
9275   %}
9276   ins_pipe(fstoreD_mem_reg);
9277 %}
9278 
9279 // Store Vector in Double Register Pair to memory
9280 instruct storeV16(memoryvld mem, vecX src) %{
9281   predicate(n->as_StoreVector()->memory_size() == 16);
9282   match(Set mem (StoreVector mem src));
9283   ins_cost(MEMORY_REF_COST);
9284   size(4);
9285   format %{ "VST1   $src,$mem\t! store vector (16 bytes)" %}
9286   ins_encode %{
9287     __ vst1($src$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
9288   %}
9289   ins_pipe(fstoreD_mem_reg); // FIXME
9290 %}
9291 
9292 // Replicate scalar to packed byte values in Double register
9293 instruct Repl8B_reg(vecD dst, iRegI src, iRegI tmp) %{
9294   predicate(n->as_Vector()->length() == 8);
9295   match(Set dst (ReplicateB src));
9296   ins_cost(DEFAULT_COST*4);
9297   effect(TEMP tmp);
9298   size(16);
9299 
9300   // FIXME: could use PKH instruction instead?
9301   format %{ "LSL      $tmp, $src, 24 \n\t"
9302             "OR       $tmp, $tmp, ($tmp >> 8) \n\t"
9303             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
9304             "FMDRR    $dst,$tmp,$tmp\t" %}
9305   ins_encode %{
9306     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 24));
9307     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 8));
9308     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
9309     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
9310   %}
9311   ins_pipe(ialu_reg); // FIXME
9312 %}
9313 
9314 // Replicate scalar to packed byte values in Double register
9315 instruct Repl8B_reg_simd(vecD dst, iRegI src) %{
9316   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9317   match(Set dst (ReplicateB src));
9318   size(4);
9319 
9320   format %{ "VDUP.8 $dst,$src\t" %}
9321   ins_encode %{
9322     bool quad = false;
9323     __ vdupI($dst$$FloatRegister, $src$$Register,
9324              MacroAssembler::VELEM_SIZE_8, quad);
9325   %}
9326   ins_pipe(ialu_reg); // FIXME
9327 %}
9328 
9329 // Replicate scalar to packed byte values in Double register pair
9330 instruct Repl16B_reg(vecX dst, iRegI src) %{
9331   predicate(n->as_Vector()->length_in_bytes() == 16);
9332   match(Set dst (ReplicateB src));
9333   size(4);
9334 
9335   format %{ "VDUP.8 $dst.Q,$src\t" %}
9336   ins_encode %{
9337     bool quad = true;
9338     __ vdupI($dst$$FloatRegister, $src$$Register,
9339              MacroAssembler::VELEM_SIZE_8, quad);
9340   %}
9341   ins_pipe(ialu_reg); // FIXME
9342 %}
9343 
9344 // Replicate scalar constant to packed byte values in Double register
9345 instruct Repl8B_immI(vecD dst, immI src, iRegI tmp) %{
9346   predicate(n->as_Vector()->length() == 8);
9347   match(Set dst (ReplicateB src));
9348   ins_cost(DEFAULT_COST*2);
9349   effect(TEMP tmp);
9350   size(12);
9351 
9352   format %{ "MOV      $tmp, Repl4($src))\n\t"
9353             "FMDRR    $dst,$tmp,$tmp\t" %}
9354   ins_encode( LdReplImmI(src, dst, tmp, (4), (1)) );
9355   ins_pipe(loadConFD); // FIXME
9356 %}
9357 
9358 // Replicate scalar constant to packed byte values in Double register
9359 // TODO: support negative constants with MVNI?
9360 instruct Repl8B_immU8(vecD dst, immU8 src) %{
9361   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9362   match(Set dst (ReplicateB src));
9363   size(4);
9364 
9365   format %{ "VMOV.U8  $dst,$src" %}
9366   ins_encode %{
9367     bool quad = false;
9368     __ vmovI($dst$$FloatRegister, $src$$constant,
9369              MacroAssembler::VELEM_SIZE_8, quad);
9370   %}
9371   ins_pipe(loadConFD); // FIXME
9372 %}
9373 
9374 // Replicate scalar constant to packed byte values in Double register pair
9375 instruct Repl16B_immU8(vecX dst, immU8 src) %{
9376   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
9377   match(Set dst (ReplicateB src));
9378   size(4);
9379 
9380   format %{ "VMOV.U8  $dst.Q,$src" %}
9381   ins_encode %{
9382     bool quad = true;
9383     __ vmovI($dst$$FloatRegister, $src$$constant,
9384              MacroAssembler::VELEM_SIZE_8, quad);
9385   %}
9386   ins_pipe(loadConFD); // FIXME
9387 %}
9388 
9389 // Replicate scalar to packed short/char values into Double register
9390 instruct Repl4S_reg(vecD dst, iRegI src, iRegI tmp) %{
9391   predicate(n->as_Vector()->length() == 4);
9392   match(Set dst (ReplicateS src));
9393   ins_cost(DEFAULT_COST*3);
9394   effect(TEMP tmp);
9395   size(12);
9396 
9397   // FIXME: could use PKH instruction instead?
9398   format %{ "LSL      $tmp, $src, 16 \n\t"
9399             "OR       $tmp, $tmp, ($tmp >> 16) \n\t"
9400             "FMDRR    $dst,$tmp,$tmp\t" %}
9401   ins_encode %{
9402     __ mov($tmp$$Register, AsmOperand($src$$Register, lsl, 16));
9403     __ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
9404     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
9405   %}
9406   ins_pipe(ialu_reg); // FIXME
9407 %}
9408 
9409 // Replicate scalar to packed byte values in Double register
9410 instruct Repl4S_reg_simd(vecD dst, iRegI src) %{
9411   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9412   match(Set dst (ReplicateS src));
9413   size(4);
9414 
9415   format %{ "VDUP.16 $dst,$src\t" %}
9416   ins_encode %{
9417     bool quad = false;
9418     __ vdupI($dst$$FloatRegister, $src$$Register,
9419              MacroAssembler::VELEM_SIZE_16, quad);
9420   %}
9421   ins_pipe(ialu_reg); // FIXME
9422 %}
9423 
9424 // Replicate scalar to packed byte values in Double register pair
9425 instruct Repl8S_reg(vecX dst, iRegI src) %{
9426   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
9427   match(Set dst (ReplicateS src));
9428   size(4);
9429 
9430   format %{ "VDUP.16 $dst.Q,$src\t" %}
9431   ins_encode %{
9432     bool quad = true;
9433     __ vdupI($dst$$FloatRegister, $src$$Register,
9434              MacroAssembler::VELEM_SIZE_16, quad);
9435   %}
9436   ins_pipe(ialu_reg); // FIXME
9437 %}
9438 
9439 
9440 // Replicate scalar constant to packed short/char values in Double register
9441 instruct Repl4S_immI(vecD dst, immI src, iRegP tmp) %{
9442   predicate(n->as_Vector()->length() == 4);
9443   match(Set dst (ReplicateS src));
9444   effect(TEMP tmp);
9445   size(12);
9446   ins_cost(DEFAULT_COST*4); // FIXME
9447 
9448   format %{ "MOV      $tmp, Repl2($src))\n\t"
9449             "FMDRR    $dst,$tmp,$tmp\t" %}
9450   ins_encode( LdReplImmI(src, dst, tmp, (2), (2)) );
9451   ins_pipe(loadConFD); // FIXME
9452 %}
9453 
9454 // Replicate scalar constant to packed byte values in Double register
9455 instruct Repl4S_immU8(vecD dst, immU8 src) %{
9456   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9457   match(Set dst (ReplicateS src));
9458   size(4);
9459 
9460   format %{ "VMOV.U16  $dst,$src" %}
9461   ins_encode %{
9462     bool quad = false;
9463     __ vmovI($dst$$FloatRegister, $src$$constant,
9464              MacroAssembler::VELEM_SIZE_16, quad);
9465   %}
9466   ins_pipe(loadConFD); // FIXME
9467 %}
9468 
9469 // Replicate scalar constant to packed byte values in Double register pair
9470 instruct Repl8S_immU8(vecX dst, immU8 src) %{
9471   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
9472   match(Set dst (ReplicateS src));
9473   size(4);
9474 
9475   format %{ "VMOV.U16  $dst.Q,$src" %}
9476   ins_encode %{
9477     bool quad = true;
9478     __ vmovI($dst$$FloatRegister, $src$$constant,
9479              MacroAssembler::VELEM_SIZE_16, quad);
9480   %}
9481   ins_pipe(loadConFD); // FIXME
9482 %}
9483 
9484 // Replicate scalar to packed int values in Double register
9485 instruct Repl2I_reg(vecD dst, iRegI src) %{
9486   predicate(n->as_Vector()->length() == 2);
9487   match(Set dst (ReplicateI src));
9488   size(4);
9489 
9490   format %{ "FMDRR    $dst,$src,$src\t" %}
9491   ins_encode %{
9492     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
9493   %}
9494   ins_pipe(ialu_reg); // FIXME
9495 %}
9496 
9497 // Replicate scalar to packed int values in Double register pair
9498 instruct Repl4I_reg(vecX dst, iRegI src) %{
9499   predicate(n->as_Vector()->length() == 4);
9500   match(Set dst (ReplicateI src));
9501   ins_cost(DEFAULT_COST*2);
9502   size(8);
9503 
9504   format %{ "FMDRR    $dst.lo,$src,$src\n\t"
9505             "FMDRR    $dst.hi,$src,$src" %}
9506 
9507   ins_encode %{
9508     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
9509     __ fmdrr($dst$$FloatRegister->successor()->successor(),
9510              $src$$Register, $src$$Register);
9511   %}
9512   ins_pipe(ialu_reg); // FIXME
9513 %}
9514 
9515 // Replicate scalar to packed int values in Double register
9516 instruct Repl2I_reg_simd(vecD dst, iRegI src) %{
9517   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9518   match(Set dst (ReplicateI src));
9519   size(4);
9520 
9521   format %{ "VDUP.32 $dst.D,$src\t" %}
9522   ins_encode %{
9523     bool quad = false;
9524     __ vdupI($dst$$FloatRegister, $src$$Register,
9525              MacroAssembler::VELEM_SIZE_32, quad);
9526   %}
9527   ins_pipe(ialu_reg); // FIXME
9528 %}
9529 
9530 // Replicate scalar to packed int values in Double register pair
9531 instruct Repl4I_reg_simd(vecX dst, iRegI src) %{
9532   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
9533   match(Set dst (ReplicateI src));
9534   size(4);
9535 
9536   format %{ "VDUP.32 $dst.Q,$src\t" %}
9537   ins_encode %{
9538     bool quad = true;
9539     __ vdupI($dst$$FloatRegister, $src$$Register,
9540              MacroAssembler::VELEM_SIZE_32, quad);
9541   %}
9542   ins_pipe(ialu_reg); // FIXME
9543 %}
9544 
9545 
9546 // Replicate scalar zero constant to packed int values in Double register
9547 instruct Repl2I_immI(vecD dst, immI src, iRegI tmp) %{
9548   predicate(n->as_Vector()->length() == 2);
9549   match(Set dst (ReplicateI src));
9550   effect(TEMP tmp);
9551   size(12);
9552   ins_cost(DEFAULT_COST*4); // FIXME
9553 
9554   format %{ "MOV      $tmp, Repl1($src))\n\t"
9555             "FMDRR    $dst,$tmp,$tmp\t" %}
9556   ins_encode( LdReplImmI(src, dst, tmp, (1), (4)) );
9557   ins_pipe(loadConFD); // FIXME
9558 %}
9559 
9560 // Replicate scalar constant to packed byte values in Double register
9561 instruct Repl2I_immU8(vecD dst, immU8 src) %{
9562   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9563   match(Set dst (ReplicateI src));
9564   size(4);
9565 
9566   format %{ "VMOV.I32  $dst.D,$src" %}
9567   ins_encode %{
9568     bool quad = false;
9569     __ vmovI($dst$$FloatRegister, $src$$constant,
9570              MacroAssembler::VELEM_SIZE_32, quad);
9571   %}
9572   ins_pipe(loadConFD); // FIXME
9573 %}
9574 
9575 // Replicate scalar constant to packed byte values in Double register pair
9576 instruct Repl4I_immU8(vecX dst, immU8 src) %{
9577   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
9578   match(Set dst (ReplicateI src));
9579   size(4);
9580 
9581   format %{ "VMOV.I32  $dst.Q,$src" %}
9582   ins_encode %{
9583     bool quad = true;
9584     __ vmovI($dst$$FloatRegister, $src$$constant,
9585              MacroAssembler::VELEM_SIZE_32, quad);
9586   %}
9587   ins_pipe(loadConFD); // FIXME
9588 %}
9589 
9590 // Replicate scalar to packed byte values in Double register pair
9591 instruct Repl2L_reg(vecX dst, iRegL src) %{
9592   predicate(n->as_Vector()->length() == 2);
9593   match(Set dst (ReplicateL src));
9594   size(8);
9595   ins_cost(DEFAULT_COST*2); // FIXME
9596 
9597   format %{ "FMDRR $dst.D,$src.lo,$src.hi\t\n"
9598             "FMDRR $dst.D.next,$src.lo,$src.hi" %}
9599   ins_encode %{
9600     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
9601     __ fmdrr($dst$$FloatRegister->successor()->successor(),
9602              $src$$Register, $src$$Register->successor());
9603   %}
9604   ins_pipe(ialu_reg); // FIXME
9605 %}
9606 
9607 
9608 // Replicate scalar to packed float values in Double register
9609 instruct Repl2F_regI(vecD dst, iRegI src) %{
9610   predicate(n->as_Vector()->length() == 2);
9611   match(Set dst (ReplicateF src));
9612   size(4);
9613 
9614   format %{ "FMDRR    $dst.D,$src,$src\t" %}
9615   ins_encode %{
9616     __ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register);
9617   %}
9618   ins_pipe(ialu_reg); // FIXME
9619 %}
9620 
9621 // Replicate scalar to packed float values in Double register
9622 instruct Repl2F_reg_vfp(vecD dst, regF src) %{
9623   predicate(n->as_Vector()->length() == 2);
9624   match(Set dst (ReplicateF src));
9625   size(4*2);
9626   ins_cost(DEFAULT_COST*2); // FIXME
9627 
9628   expand %{
9629     iRegI tmp;
9630     MoveF2I_reg_reg(tmp, src);
9631     Repl2F_regI(dst,tmp);
9632   %}
9633 %}
9634 
9635 // Replicate scalar to packed float values in Double register
9636 instruct Repl2F_reg_simd(vecD dst, regF src) %{
9637   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
9638   match(Set dst (ReplicateF src));
9639   size(4);
9640   ins_cost(DEFAULT_COST); // FIXME
9641 
9642   format %{ "VDUP.32  $dst.D,$src.D\t" %}
9643   ins_encode %{
9644     bool quad = false;
9645     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
9646   %}
9647   ins_pipe(ialu_reg); // FIXME
9648 %}
9649 
9650 // Replicate scalar to packed float values in Double register pair
9651 instruct Repl4F_reg(vecX dst, regF src, iRegI tmp) %{
9652   predicate(n->as_Vector()->length() == 4);
9653   match(Set dst (ReplicateF src));
9654   effect(TEMP tmp);
9655   size(4*3);
9656   ins_cost(DEFAULT_COST*3); // FIXME
9657 
9658   format %{ "FMRS     $tmp,$src\n\t"
9659             "FMDRR    $dst.D,$tmp,$tmp\n\t"
9660             "FMDRR    $dst.D.next,$tmp,$tmp\t" %}
9661   ins_encode %{
9662     __ fmrs($tmp$$Register, $src$$FloatRegister);
9663     __ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
9664     __ fmdrr($dst$$FloatRegister->successor()->successor(),
9665              $tmp$$Register, $tmp$$Register);
9666   %}
9667   ins_pipe(ialu_reg); // FIXME
9668 %}
9669 
9670 // Replicate scalar to packed float values in Double register pair
9671 instruct Repl4F_reg_simd(vecX dst, regF src) %{
9672   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
9673   match(Set dst (ReplicateF src));
9674   size(4);
9675   ins_cost(DEFAULT_COST); // FIXME
9676 
9677   format %{ "VDUP.32  $dst.Q,$src.D\t" %}
9678   ins_encode %{
9679     bool quad = true;
9680     __ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
9681   %}
9682   ins_pipe(ialu_reg); // FIXME
9683 %}
9684 
9685 // Replicate scalar zero constant to packed float values in Double register
9686 instruct Repl2F_immI(vecD dst, immF src, iRegI tmp) %{
9687   predicate(n->as_Vector()->length() == 2);
9688   match(Set dst (ReplicateF src));
9689   effect(TEMP tmp);
9690   size(12);
9691   ins_cost(DEFAULT_COST*4); // FIXME
9692 
9693   format %{ "MOV      $tmp, Repl1($src))\n\t"
9694             "FMDRR    $dst,$tmp,$tmp\t" %}
9695   ins_encode( LdReplImmF(src, dst, tmp) );
9696   ins_pipe(loadConFD); // FIXME
9697 %}
9698 
9699 // Replicate scalar to packed double float values in Double register pair
9700 instruct Repl2D_reg(vecX dst, regD src) %{
9701   predicate(n->as_Vector()->length() == 2);
9702   match(Set dst (ReplicateD src));
9703   size(4*2);
9704   ins_cost(DEFAULT_COST*2); // FIXME
9705 
9706   format %{ "FCPYD    $dst.D.a,$src\n\t"
9707             "FCPYD    $dst.D.b,$src\t" %}
9708   ins_encode %{
9709     FloatRegister dsta = $dst$$FloatRegister;
9710     FloatRegister src = $src$$FloatRegister;
9711     __ fcpyd(dsta, src);
9712     FloatRegister dstb = dsta->successor()->successor();
9713     __ fcpyd(dstb, src);
9714   %}
9715   ins_pipe(ialu_reg); // FIXME
9716 %}
9717 
9718 // ====================VECTOR ARITHMETIC=======================================
9719 
9720 // --------------------------------- ADD --------------------------------------
9721 
9722 // Bytes vector add
9723 instruct vadd8B_reg(vecD dst, vecD src1, vecD src2) %{
9724   predicate(n->as_Vector()->length() == 8);
9725   match(Set dst (AddVB src1 src2));
9726   format %{ "VADD.I8 $dst,$src1,$src2\t! add packed8B" %}
9727   size(4);
9728   ins_encode %{
9729     bool quad = false;
9730     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9731              MacroAssembler::VELEM_SIZE_8, quad);
9732   %}
9733   ins_pipe( ialu_reg_reg ); // FIXME
9734 %}
9735 
9736 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
9737   predicate(n->as_Vector()->length() == 16);
9738   match(Set dst (AddVB src1 src2));
9739   size(4);
9740   format %{ "VADD.I8 $dst.Q,$src1.Q,$src2.Q\t! add packed16B" %}
9741   ins_encode %{
9742     bool quad = true;
9743     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9744              MacroAssembler::VELEM_SIZE_8, quad);
9745   %}
9746   ins_pipe( ialu_reg_reg ); // FIXME
9747 %}
9748 
9749 // Shorts/Chars vector add
9750 instruct vadd4S_reg(vecD dst, vecD src1, vecD src2) %{
9751   predicate(n->as_Vector()->length() == 4);
9752   match(Set dst (AddVS src1 src2));
9753   size(4);
9754   format %{ "VADD.I16 $dst,$src1,$src2\t! add packed4S" %}
9755   ins_encode %{
9756     bool quad = false;
9757     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9758              MacroAssembler::VELEM_SIZE_16, quad);
9759   %}
9760   ins_pipe( ialu_reg_reg ); // FIXME
9761 %}
9762 
9763 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
9764   predicate(n->as_Vector()->length() == 8);
9765   match(Set dst (AddVS src1 src2));
9766   size(4);
9767   format %{ "VADD.I16 $dst.Q,$src1.Q,$src2.Q\t! add packed8S" %}
9768   ins_encode %{
9769     bool quad = true;
9770     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9771              MacroAssembler::VELEM_SIZE_16, quad);
9772   %}
9773   ins_pipe( ialu_reg_reg ); // FIXME
9774 %}
9775 
9776 // Integers vector add
9777 instruct vadd2I_reg(vecD dst, vecD src1, vecD src2) %{
9778   predicate(n->as_Vector()->length() == 2);
9779   match(Set dst (AddVI src1 src2));
9780   size(4);
9781   format %{ "VADD.I32 $dst.D,$src1.D,$src2.D\t! add packed2I" %}
9782   ins_encode %{
9783     bool quad = false;
9784     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9785              MacroAssembler::VELEM_SIZE_32, quad);
9786   %}
9787   ins_pipe( ialu_reg_reg ); // FIXME
9788 %}
9789 
9790 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
9791   predicate(n->as_Vector()->length() == 4);
9792   match(Set dst (AddVI src1 src2));
9793   size(4);
9794   format %{ "VADD.I32 $dst.Q,$src1.Q,$src2.Q\t! add packed4I" %}
9795   ins_encode %{
9796     bool quad = true;
9797     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9798              MacroAssembler::VELEM_SIZE_32, quad);
9799   %}
9800   ins_pipe( ialu_reg_reg ); // FIXME
9801 %}
9802 
9803 // Longs vector add
9804 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
9805   predicate(n->as_Vector()->length() == 2);
9806   match(Set dst (AddVL src1 src2));
9807   size(4);
9808   format %{ "VADD.I64 $dst.Q,$src1.Q,$src2.Q\t! add packed2L" %}
9809   ins_encode %{
9810     bool quad = true;
9811     __ vaddI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9812              MacroAssembler::VELEM_SIZE_64, quad);
9813   %}
9814   ins_pipe( ialu_reg_reg ); // FIXME
9815 %}
9816 
9817 // Floats vector add
9818 instruct vadd2F_reg(vecD dst, vecD src1, vecD src2) %{
9819   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
9820   match(Set dst (AddVF src1 src2));
9821   size(4);
9822   format %{ "VADD.F32 $dst,$src1,$src2\t! add packed2F" %}
9823   ins_encode %{
9824     bool quad = false;
9825     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9826              MacroAssembler::VFA_SIZE_F32, quad);
9827   %}
9828   ins_pipe( faddD_reg_reg ); // FIXME
9829 %}
9830 
9831 instruct vadd2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
9832   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
9833   match(Set dst (AddVF src1 src2));
9834   ins_cost(DEFAULT_COST*2); // FIXME
9835 
9836   size(4*2);
9837   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
9838             "FADDS  $dst.b,$src1.b,$src2.b" %}
9839   ins_encode %{
9840     __ add_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9841     __ add_float($dst$$FloatRegister->successor(),
9842              $src1$$FloatRegister->successor(),
9843              $src2$$FloatRegister->successor());
9844   %}
9845 
9846   ins_pipe(faddF_reg_reg); // FIXME
9847 %}
9848 
9849 instruct vadd4F_reg_simd(vecX dst, vecX src1, vecX src2) %{
9850   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
9851   match(Set dst (AddVF src1 src2));
9852   size(4);
9853   format %{ "VADD.F32 $dst.Q,$src1.Q,$src2.Q\t! add packed4F" %}
9854   ins_encode %{
9855     bool quad = true;
9856     __ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9857              MacroAssembler::VFA_SIZE_F32, quad);
9858   %}
9859   ins_pipe( faddD_reg_reg ); // FIXME
9860 %}
9861 
9862 instruct vadd4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
9863   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
9864   match(Set dst (AddVF src1 src2));
9865   size(4*4);
9866   ins_cost(DEFAULT_COST*4); // FIXME
9867 
9868   format %{ "FADDS  $dst.a,$src1.a,$src2.a\n\t"
9869             "FADDS  $dst.b,$src1.b,$src2.b\n\t"
9870             "FADDS  $dst.c,$src1.c,$src2.c\n\t"
9871             "FADDS  $dst.d,$src1.d,$src2.d" %}
9872 
9873   ins_encode %{
9874     FloatRegister dsta = $dst$$FloatRegister;
9875     FloatRegister src1a = $src1$$FloatRegister;
9876     FloatRegister src2a = $src2$$FloatRegister;
9877     __ add_float(dsta, src1a, src2a);
9878     FloatRegister dstb = dsta->successor();
9879     FloatRegister src1b = src1a->successor();
9880     FloatRegister src2b = src2a->successor();
9881     __ add_float(dstb, src1b, src2b);
9882     FloatRegister dstc = dstb->successor();
9883     FloatRegister src1c = src1b->successor();
9884     FloatRegister src2c = src2b->successor();
9885     __ add_float(dstc, src1c, src2c);
9886     FloatRegister dstd = dstc->successor();
9887     FloatRegister src1d = src1c->successor();
9888     FloatRegister src2d = src2c->successor();
9889     __ add_float(dstd, src1d, src2d);
9890   %}
9891 
9892   ins_pipe(faddF_reg_reg); // FIXME
9893 %}
9894 
9895 instruct vadd2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
9896   predicate(n->as_Vector()->length() == 2);
9897   match(Set dst (AddVD src1 src2));
9898   size(4*2);
9899   ins_cost(DEFAULT_COST*2); // FIXME
9900 
9901   format %{ "FADDD  $dst.a,$src1.a,$src2.a\n\t"
9902             "FADDD  $dst.b,$src1.b,$src2.b" %}
9903 
9904   ins_encode %{
9905     FloatRegister dsta = $dst$$FloatRegister;
9906     FloatRegister src1a = $src1$$FloatRegister;
9907     FloatRegister src2a = $src2$$FloatRegister;
9908     __ add_double(dsta, src1a, src2a);
9909     FloatRegister dstb = dsta->successor()->successor();
9910     FloatRegister src1b = src1a->successor()->successor();
9911     FloatRegister src2b = src2a->successor()->successor();
9912     __ add_double(dstb, src1b, src2b);
9913   %}
9914 
9915   ins_pipe(faddF_reg_reg); // FIXME
9916 %}
9917 
9918 
9919 // Bytes vector sub
9920 instruct vsub8B_reg(vecD dst, vecD src1, vecD src2) %{
9921   predicate(n->as_Vector()->length() == 8);
9922   match(Set dst (SubVB src1 src2));
9923   size(4);
9924   format %{ "VSUB.I8 $dst,$src1,$src2\t! sub packed8B" %}
9925   ins_encode %{
9926     bool quad = false;
9927     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9928              MacroAssembler::VELEM_SIZE_8, quad);
9929   %}
9930   ins_pipe( ialu_reg_reg ); // FIXME
9931 %}
9932 
9933 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
9934   predicate(n->as_Vector()->length() == 16);
9935   match(Set dst (SubVB src1 src2));
9936   size(4);
9937   format %{ "VSUB.I8 $dst.Q,$src1.Q,$src2.Q\t! sub packed16B" %}
9938   ins_encode %{
9939     bool quad = true;
9940     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9941              MacroAssembler::VELEM_SIZE_8, quad);
9942   %}
9943   ins_pipe( ialu_reg_reg ); // FIXME
9944 %}
9945 
9946 // Shorts/Chars vector sub
9947 instruct vsub4S_reg(vecD dst, vecD src1, vecD src2) %{
9948   predicate(n->as_Vector()->length() == 4);
9949   match(Set dst (SubVS src1 src2));
9950   size(4);
9951   format %{ "VSUB.I16 $dst,$src1,$src2\t! sub packed4S" %}
9952   ins_encode %{
9953     bool quad = false;
9954     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9955              MacroAssembler::VELEM_SIZE_16, quad);
9956   %}
9957   ins_pipe( ialu_reg_reg ); // FIXME
9958 %}
9959 
9960 instruct vsub16S_reg(vecX dst, vecX src1, vecX src2) %{
9961   predicate(n->as_Vector()->length() == 8);
9962   match(Set dst (SubVS src1 src2));
9963   size(4);
9964   format %{ "VSUB.I16 $dst.Q,$src1.Q,$src2.Q\t! sub packed8S" %}
9965   ins_encode %{
9966     bool quad = true;
9967     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9968              MacroAssembler::VELEM_SIZE_16, quad);
9969   %}
9970   ins_pipe( ialu_reg_reg ); // FIXME
9971 %}
9972 
9973 // Integers vector sub
9974 instruct vsub2I_reg(vecD dst, vecD src1, vecD src2) %{
9975   predicate(n->as_Vector()->length() == 2);
9976   match(Set dst (SubVI src1 src2));
9977   size(4);
9978   format %{ "VSUB.I32 $dst,$src1,$src2\t! sub packed2I" %}
9979   ins_encode %{
9980     bool quad = false;
9981     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9982              MacroAssembler::VELEM_SIZE_32, quad);
9983   %}
9984   ins_pipe( ialu_reg_reg ); // FIXME
9985 %}
9986 
9987 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
9988   predicate(n->as_Vector()->length() == 4);
9989   match(Set dst (SubVI src1 src2));
9990   size(4);
9991   format %{ "VSUB.I32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4I" %}
9992   ins_encode %{
9993     bool quad = true;
9994     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
9995              MacroAssembler::VELEM_SIZE_32, quad);
9996   %}
9997   ins_pipe( ialu_reg_reg ); // FIXME
9998 %}
9999 
10000 // Longs vector sub
10001 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
10002   predicate(n->as_Vector()->length() == 2);
10003   match(Set dst (SubVL src1 src2));
10004   size(4);
10005   format %{ "VSUB.I64 $dst.Q,$src1.Q,$src2.Q\t! sub packed2L" %}
10006   ins_encode %{
10007     bool quad = true;
10008     __ vsubI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10009              MacroAssembler::VELEM_SIZE_64, quad);
10010   %}
10011   ins_pipe( ialu_reg_reg ); // FIXME
10012 %}
10013 
10014 // Floats vector sub
10015 instruct vsub2F_reg(vecD dst, vecD src1, vecD src2) %{
10016   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
10017   match(Set dst (SubVF src1 src2));
10018   size(4);
10019   format %{ "VSUB.F32 $dst,$src1,$src2\t! sub packed2F" %}
10020   ins_encode %{
10021     bool quad = false;
10022     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10023              MacroAssembler::VFA_SIZE_F32, quad);
10024   %}
10025   ins_pipe( faddF_reg_reg ); // FIXME
10026 %}
10027 
10028 instruct vsub2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10029   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
10030   match(Set dst (SubVF src1 src2));
10031   size(4*2);
10032   ins_cost(DEFAULT_COST*2); // FIXME
10033 
10034   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10035             "FSUBS  $dst.b,$src1.b,$src2.b" %}
10036 
10037   ins_encode %{
10038     FloatRegister dsta = $dst$$FloatRegister;
10039     FloatRegister src1a = $src1$$FloatRegister;
10040     FloatRegister src2a = $src2$$FloatRegister;
10041     __ sub_float(dsta, src1a, src2a);
10042     FloatRegister dstb = dsta->successor();
10043     FloatRegister src1b = src1a->successor();
10044     FloatRegister src2b = src2a->successor();
10045     __ sub_float(dstb, src1b, src2b);
10046   %}
10047 
10048   ins_pipe(faddF_reg_reg); // FIXME
10049 %}
10050 
10051 
10052 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
10053   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
10054   match(Set dst (SubVF src1 src2));
10055   size(4);
10056   format %{ "VSUB.F32 $dst.Q,$src1.Q,$src2.Q\t! sub packed4F" %}
10057   ins_encode %{
10058     bool quad = true;
10059     __ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10060              MacroAssembler::VFA_SIZE_F32, quad);
10061   %}
10062   ins_pipe( faddF_reg_reg ); // FIXME
10063 %}
10064 
10065 instruct vsub4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10066   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
10067   match(Set dst (SubVF src1 src2));
10068   size(4*4);
10069   ins_cost(DEFAULT_COST*4); // FIXME
10070 
10071   format %{ "FSUBS  $dst.a,$src1.a,$src2.a\n\t"
10072             "FSUBS  $dst.b,$src1.b,$src2.b\n\t"
10073             "FSUBS  $dst.c,$src1.c,$src2.c\n\t"
10074             "FSUBS  $dst.d,$src1.d,$src2.d" %}
10075 
10076   ins_encode %{
10077     FloatRegister dsta = $dst$$FloatRegister;
10078     FloatRegister src1a = $src1$$FloatRegister;
10079     FloatRegister src2a = $src2$$FloatRegister;
10080     __ sub_float(dsta, src1a, src2a);
10081     FloatRegister dstb = dsta->successor();
10082     FloatRegister src1b = src1a->successor();
10083     FloatRegister src2b = src2a->successor();
10084     __ sub_float(dstb, src1b, src2b);
10085     FloatRegister dstc = dstb->successor();
10086     FloatRegister src1c = src1b->successor();
10087     FloatRegister src2c = src2b->successor();
10088     __ sub_float(dstc, src1c, src2c);
10089     FloatRegister dstd = dstc->successor();
10090     FloatRegister src1d = src1c->successor();
10091     FloatRegister src2d = src2c->successor();
10092     __ sub_float(dstd, src1d, src2d);
10093   %}
10094 
10095   ins_pipe(faddF_reg_reg); // FIXME
10096 %}
10097 
10098 instruct vsub2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10099   predicate(n->as_Vector()->length() == 2);
10100   match(Set dst (SubVD src1 src2));
10101   size(4*2);
10102   ins_cost(DEFAULT_COST*2); // FIXME
10103 
10104   format %{ "FSUBD  $dst.a,$src1.a,$src2.a\n\t"
10105             "FSUBD  $dst.b,$src1.b,$src2.b" %}
10106 
10107   ins_encode %{
10108     FloatRegister dsta = $dst$$FloatRegister;
10109     FloatRegister src1a = $src1$$FloatRegister;
10110     FloatRegister src2a = $src2$$FloatRegister;
10111     __ sub_double(dsta, src1a, src2a);
10112     FloatRegister dstb = dsta->successor()->successor();
10113     FloatRegister src1b = src1a->successor()->successor();
10114     FloatRegister src2b = src2a->successor()->successor();
10115     __ sub_double(dstb, src1b, src2b);
10116   %}
10117 
10118   ins_pipe(faddF_reg_reg); // FIXME
10119 %}
10120 
10121 // Shorts/Chars vector mul
10122 instruct vmul4S_reg(vecD dst, vecD src1, vecD src2) %{
10123   predicate(n->as_Vector()->length() == 4);
10124   match(Set dst (MulVS src1 src2));
10125   size(4);
10126   format %{ "VMUL.I16 $dst,$src1,$src2\t! mul packed4S" %}
10127   ins_encode %{
10128     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10129              MacroAssembler::VELEM_SIZE_16, 0);
10130   %}
10131   ins_pipe( ialu_reg_reg ); // FIXME
10132 %}
10133 
10134 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2) %{
10135   predicate(n->as_Vector()->length() == 8);
10136   match(Set dst (MulVS src1 src2));
10137   size(4);
10138   format %{ "VMUL.I16 $dst.Q,$src1.Q,$src2.Q\t! mul packed8S" %}
10139   ins_encode %{
10140     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10141              MacroAssembler::VELEM_SIZE_16, 1);
10142   %}
10143   ins_pipe( ialu_reg_reg ); // FIXME
10144 %}
10145 
10146 // Integers vector mul
10147 instruct vmul2I_reg(vecD dst, vecD src1, vecD src2) %{
10148   predicate(n->as_Vector()->length() == 2);
10149   match(Set dst (MulVI src1 src2));
10150   size(4);
10151   format %{ "VMUL.I32 $dst,$src1,$src2\t! mul packed2I" %}
10152   ins_encode %{
10153     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10154              MacroAssembler::VELEM_SIZE_32, 0);
10155   %}
10156   ins_pipe( ialu_reg_reg ); // FIXME
10157 %}
10158 
10159 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
10160   predicate(n->as_Vector()->length() == 4);
10161   match(Set dst (MulVI src1 src2));
10162   size(4);
10163   format %{ "VMUL.I32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4I" %}
10164   ins_encode %{
10165     __ vmulI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10166              MacroAssembler::VELEM_SIZE_32, 1);
10167   %}
10168   ins_pipe( ialu_reg_reg ); // FIXME
10169 %}
10170 
10171 // Floats vector mul
10172 instruct vmul2F_reg(vecD dst, vecD src1, vecD src2) %{
10173   predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
10174   match(Set dst (MulVF src1 src2));
10175   size(4);
10176   format %{ "VMUL.F32 $dst,$src1,$src2\t! mul packed2F" %}
10177   ins_encode %{
10178     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10179              MacroAssembler::VFA_SIZE_F32, 0);
10180   %}
10181   ins_pipe( fmulF_reg_reg ); // FIXME
10182 %}
10183 
10184 instruct vmul2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10185   predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
10186   match(Set dst (MulVF src1 src2));
10187   size(4*2);
10188   ins_cost(DEFAULT_COST*2); // FIXME
10189 
10190   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10191             "FMULS  $dst.b,$src1.b,$src2.b" %}
10192   ins_encode %{
10193     __ mul_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10194     __ mul_float($dst$$FloatRegister->successor(),
10195              $src1$$FloatRegister->successor(),
10196              $src2$$FloatRegister->successor());
10197   %}
10198 
10199   ins_pipe(fmulF_reg_reg); // FIXME
10200 %}
10201 
10202 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
10203   predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
10204   match(Set dst (MulVF src1 src2));
10205   size(4);
10206   format %{ "VMUL.F32 $dst.Q,$src1.Q,$src2.Q\t! mul packed4F" %}
10207   ins_encode %{
10208     __ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
10209              MacroAssembler::VFA_SIZE_F32, 1);
10210   %}
10211   ins_pipe( fmulF_reg_reg ); // FIXME
10212 %}
10213 
10214 instruct vmul4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10215   predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
10216   match(Set dst (MulVF src1 src2));
10217   size(4*4);
10218   ins_cost(DEFAULT_COST*4); // FIXME
10219 
10220   format %{ "FMULS  $dst.a,$src1.a,$src2.a\n\t"
10221             "FMULS  $dst.b,$src1.b,$src2.b\n\t"
10222             "FMULS  $dst.c,$src1.c,$src2.c\n\t"
10223             "FMULS  $dst.d,$src1.d,$src2.d" %}
10224 
10225   ins_encode %{
10226     FloatRegister dsta = $dst$$FloatRegister;
10227     FloatRegister src1a = $src1$$FloatRegister;
10228     FloatRegister src2a = $src2$$FloatRegister;
10229     __ mul_float(dsta, src1a, src2a);
10230     FloatRegister dstb = dsta->successor();
10231     FloatRegister src1b = src1a->successor();
10232     FloatRegister src2b = src2a->successor();
10233     __ mul_float(dstb, src1b, src2b);
10234     FloatRegister dstc = dstb->successor();
10235     FloatRegister src1c = src1b->successor();
10236     FloatRegister src2c = src2b->successor();
10237     __ mul_float(dstc, src1c, src2c);
10238     FloatRegister dstd = dstc->successor();
10239     FloatRegister src1d = src1c->successor();
10240     FloatRegister src2d = src2c->successor();
10241     __ mul_float(dstd, src1d, src2d);
10242   %}
10243 
10244   ins_pipe(fmulF_reg_reg); // FIXME
10245 %}
10246 
10247 instruct vmul2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10248   predicate(n->as_Vector()->length() == 2);
10249   match(Set dst (MulVD src1 src2));
10250   size(4*2);
10251   ins_cost(DEFAULT_COST*2); // FIXME
10252 
10253   format %{ "FMULD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10254             "FMULD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10255   ins_encode %{
10256     FloatRegister dsta = $dst$$FloatRegister;
10257     FloatRegister src1a = $src1$$FloatRegister;
10258     FloatRegister src2a = $src2$$FloatRegister;
10259     __ mul_double(dsta, src1a, src2a);
10260     FloatRegister dstb = dsta->successor()->successor();
10261     FloatRegister src1b = src1a->successor()->successor();
10262     FloatRegister src2b = src2a->successor()->successor();
10263     __ mul_double(dstb, src1b, src2b);
10264   %}
10265 
10266   ins_pipe(fmulD_reg_reg); // FIXME
10267 %}
10268 
10269 
10270 // Floats vector div
10271 instruct vdiv2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
10272   predicate(n->as_Vector()->length() == 2);
10273   match(Set dst (DivVF src1 src2));
10274   size(4*2);
10275   ins_cost(DEFAULT_COST*2); // FIXME
10276 
10277   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10278             "FDIVS  $dst.b,$src1.b,$src2.b" %}
10279   ins_encode %{
10280     __ div_float($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10281     __ div_float($dst$$FloatRegister->successor(),
10282              $src1$$FloatRegister->successor(),
10283              $src2$$FloatRegister->successor());
10284   %}
10285 
10286   ins_pipe(fdivF_reg_reg); // FIXME
10287 %}
10288 
10289 instruct vdiv4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10290   predicate(n->as_Vector()->length() == 4);
10291   match(Set dst (DivVF src1 src2));
10292   size(4*4);
10293   ins_cost(DEFAULT_COST*4); // FIXME
10294 
10295   format %{ "FDIVS  $dst.a,$src1.a,$src2.a\n\t"
10296             "FDIVS  $dst.b,$src1.b,$src2.b\n\t"
10297             "FDIVS  $dst.c,$src1.c,$src2.c\n\t"
10298             "FDIVS  $dst.d,$src1.d,$src2.d" %}
10299 
10300   ins_encode %{
10301     FloatRegister dsta = $dst$$FloatRegister;
10302     FloatRegister src1a = $src1$$FloatRegister;
10303     FloatRegister src2a = $src2$$FloatRegister;
10304     __ div_float(dsta, src1a, src2a);
10305     FloatRegister dstb = dsta->successor();
10306     FloatRegister src1b = src1a->successor();
10307     FloatRegister src2b = src2a->successor();
10308     __ div_float(dstb, src1b, src2b);
10309     FloatRegister dstc = dstb->successor();
10310     FloatRegister src1c = src1b->successor();
10311     FloatRegister src2c = src2b->successor();
10312     __ div_float(dstc, src1c, src2c);
10313     FloatRegister dstd = dstc->successor();
10314     FloatRegister src1d = src1c->successor();
10315     FloatRegister src2d = src2c->successor();
10316     __ div_float(dstd, src1d, src2d);
10317   %}
10318 
10319   ins_pipe(fdivF_reg_reg); // FIXME
10320 %}
10321 
10322 instruct vdiv2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
10323   predicate(n->as_Vector()->length() == 2);
10324   match(Set dst (DivVD src1 src2));
10325   size(4*2);
10326   ins_cost(DEFAULT_COST*2); // FIXME
10327 
10328   format %{ "FDIVD  $dst.D.a,$src1.D.a,$src2.D.a\n\t"
10329             "FDIVD  $dst.D.b,$src1.D.b,$src2.D.b" %}
10330   ins_encode %{
10331     FloatRegister dsta = $dst$$FloatRegister;
10332     FloatRegister src1a = $src1$$FloatRegister;
10333     FloatRegister src2a = $src2$$FloatRegister;
10334     __ div_double(dsta, src1a, src2a);
10335     FloatRegister dstb = dsta->successor()->successor();
10336     FloatRegister src1b = src1a->successor()->successor();
10337     FloatRegister src2b = src2a->successor()->successor();
10338     __ div_double(dstb, src1b, src2b);
10339   %}
10340 
10341   ins_pipe(fdivD_reg_reg); // FIXME
10342 %}
10343 
10344 // --------------------------------- NEG --------------------------------------
10345 
10346 instruct vneg8B_reg(vecD dst, vecD src) %{
10347   predicate(n->as_Vector()->length_in_bytes() == 8);
10348   effect(DEF dst, USE src);
10349   size(4);
10350   ins_cost(DEFAULT_COST); // FIXME
10351   format %{ "VNEG.S8 $dst.D,$src.D\t! neg packed8B" %}
10352   ins_encode %{
10353     bool quad = false;
10354     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
10355               MacroAssembler::VELEM_SIZE_8, quad);
10356   %}
10357   ins_pipe( ialu_reg_reg ); // FIXME
10358 %}
10359 
10360 instruct vneg16B_reg(vecX dst, vecX src) %{
10361   predicate(n->as_Vector()->length_in_bytes() == 16);
10362   effect(DEF dst, USE src);
10363   size(4);
10364   ins_cost(DEFAULT_COST); // FIXME
10365   format %{ "VNEG.S8 $dst.Q,$src.Q\t! neg0 packed16B" %}
10366   ins_encode %{
10367     bool _float = false;
10368     bool quad = true;
10369     __ vnegI($dst$$FloatRegister, $src$$FloatRegister,
10370               MacroAssembler::VELEM_SIZE_8, quad);
10371   %}
10372   ins_pipe( ialu_reg_reg ); // FIXME
10373 %}
10374 
10375 // ------------------------------ Shift ---------------------------------------
10376 
10377 instruct vslcntD(vecD dst, iRegI cnt) %{
10378   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
10379   match(Set dst (LShiftCntV cnt));
10380   size(4);
10381   ins_cost(DEFAULT_COST); // FIXME
10382   expand %{
10383     Repl8B_reg_simd(dst, cnt);
10384   %}
10385 %}
10386 
10387 instruct vslcntX(vecX dst, iRegI cnt) %{
10388   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
10389   match(Set dst (LShiftCntV cnt));
10390   size(4);
10391   ins_cost(DEFAULT_COST); // FIXME
10392   expand %{
10393     Repl16B_reg(dst, cnt);
10394   %}
10395 %}
10396 
10397 // Low bits of vector "shift" elements are used, so it
10398 // doesn't matter if we treat it as ints or bytes here.
10399 instruct vsrcntD(vecD dst, iRegI cnt) %{
10400   predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
10401   match(Set dst (RShiftCntV cnt));
10402   size(4*2);
10403   ins_cost(DEFAULT_COST*2); // FIXME
10404 
10405   format %{ "VDUP.8 $dst.D,$cnt\n\t"
10406             "VNEG.S8 $dst.D,$dst.D\t! neg packed8B" %}
10407   ins_encode %{
10408     bool quad = false;
10409     __ vdupI($dst$$FloatRegister, $cnt$$Register,
10410              MacroAssembler::VELEM_SIZE_8, quad);
10411     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
10412               MacroAssembler::VELEM_SIZE_8, quad);
10413   %}
10414   ins_pipe( ialu_reg_reg ); // FIXME
10415 %}
10416 
10417 instruct vsrcntX(vecX dst, iRegI cnt) %{
10418   predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
10419   match(Set dst (RShiftCntV cnt));
10420   size(4*2);
10421   ins_cost(DEFAULT_COST*2); // FIXME
10422   format %{ "VDUP.8 $dst.Q,$cnt\n\t"
10423             "VNEG.S8 $dst.Q,$dst.Q\t! neg packed16B" %}
10424   ins_encode %{
10425     bool quad = true;
10426     __ vdupI($dst$$FloatRegister, $cnt$$Register,
10427              MacroAssembler::VELEM_SIZE_8, quad);
10428     __ vnegI($dst$$FloatRegister, $dst$$FloatRegister,
10429               MacroAssembler::VELEM_SIZE_8, quad);
10430   %}
10431   ins_pipe( ialu_reg_reg ); // FIXME
10432 %}
10433 
10434 // Byte vector logical left/right shift based on sign
10435 instruct vsh8B_reg(vecD dst, vecD src, vecD shift) %{
10436   predicate(n->as_Vector()->length() == 8);
10437   effect(DEF dst, USE src, USE shift);
10438   size(4);
10439   ins_cost(DEFAULT_COST); // FIXME
10440   format %{
10441     "VSHL.U8 $dst.D,$src.D,$shift.D\t! logical left/right shift packed8B"
10442   %}
10443   ins_encode %{
10444     bool quad = false;
10445     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10446               MacroAssembler::VELEM_SIZE_8, quad);
10447   %}
10448   ins_pipe( ialu_reg_reg ); // FIXME
10449 %}
10450 
10451 instruct vsh16B_reg(vecX dst, vecX src, vecX shift) %{
10452   predicate(n->as_Vector()->length() == 16);
10453   effect(DEF dst, USE src, USE shift);
10454   size(4);
10455   ins_cost(DEFAULT_COST); // FIXME
10456   format %{
10457     "VSHL.U8 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed16B"
10458   %}
10459   ins_encode %{
10460     bool quad = true;
10461     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10462               MacroAssembler::VELEM_SIZE_8, quad);
10463   %}
10464   ins_pipe( ialu_reg_reg ); // FIXME
10465 %}
10466 
10467 // Shorts/Char vector logical left/right shift based on sign
10468 instruct vsh4S_reg(vecD dst, vecD src, vecD shift) %{
10469   predicate(n->as_Vector()->length() == 4);
10470   effect(DEF dst, USE src, USE shift);
10471   size(4);
10472   ins_cost(DEFAULT_COST); // FIXME
10473   format %{
10474     "VSHL.U16 $dst.D,$src.D,$shift.D\t! logical left/right shift packed4S"
10475   %}
10476   ins_encode %{
10477     bool quad = false;
10478     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10479               MacroAssembler::VELEM_SIZE_16, quad);
10480   %}
10481   ins_pipe( ialu_reg_reg ); // FIXME
10482 %}
10483 
10484 instruct vsh8S_reg(vecX dst, vecX src, vecX shift) %{
10485   predicate(n->as_Vector()->length() == 8);
10486   effect(DEF dst, USE src, USE shift);
10487   size(4);
10488   ins_cost(DEFAULT_COST); // FIXME
10489   format %{
10490     "VSHL.U16 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed8S"
10491   %}
10492   ins_encode %{
10493     bool quad = true;
10494     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10495               MacroAssembler::VELEM_SIZE_16, quad);
10496   %}
10497   ins_pipe( ialu_reg_reg ); // FIXME
10498 %}
10499 
10500 // Integers vector logical left/right shift based on sign
10501 instruct vsh2I_reg(vecD dst, vecD src, vecD shift) %{
10502   predicate(n->as_Vector()->length() == 2);
10503   effect(DEF dst, USE src, USE shift);
10504   size(4);
10505   ins_cost(DEFAULT_COST); // FIXME
10506   format %{
10507     "VSHL.U32 $dst.D,$src.D,$shift.D\t! logical left/right shift packed2I"
10508   %}
10509   ins_encode %{
10510     bool quad = false;
10511     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10512               MacroAssembler::VELEM_SIZE_32, quad);
10513   %}
10514   ins_pipe( ialu_reg_reg ); // FIXME
10515 %}
10516 
10517 instruct vsh4I_reg(vecX dst, vecX src, vecX shift) %{
10518   predicate(n->as_Vector()->length() == 4);
10519   effect(DEF dst, USE src, USE shift);
10520   size(4);
10521   ins_cost(DEFAULT_COST); // FIXME
10522   format %{
10523     "VSHL.U32 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed4I"
10524   %}
10525   ins_encode %{
10526     bool quad = true;
10527     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10528               MacroAssembler::VELEM_SIZE_32, quad);
10529   %}
10530   ins_pipe( ialu_reg_reg ); // FIXME
10531 %}
10532 
10533 // Longs vector logical left/right shift based on sign
10534 instruct vsh2L_reg(vecX dst, vecX src, vecX shift) %{
10535   predicate(n->as_Vector()->length() == 2);
10536   effect(DEF dst, USE src, USE shift);
10537   size(4);
10538   ins_cost(DEFAULT_COST); // FIXME
10539   format %{
10540     "VSHL.U64 $dst.Q,$src.Q,$shift.Q\t! logical left/right shift packed2L"
10541   %}
10542   ins_encode %{
10543     bool quad = true;
10544     __ vshlUI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10545               MacroAssembler::VELEM_SIZE_64, quad);
10546   %}
10547   ins_pipe( ialu_reg_reg ); // FIXME
10548 %}
10549 
10550 // ------------------------------ LeftShift -----------------------------------
10551 
10552 // Byte vector left shift
10553 instruct vsl8B_reg(vecD dst, vecD src, vecD shift) %{
10554   predicate(n->as_Vector()->length() == 8);
10555   match(Set dst (LShiftVB src shift));
10556   size(4*1);
10557   ins_cost(DEFAULT_COST*1); // FIXME
10558   expand %{
10559     vsh8B_reg(dst, src, shift);
10560   %}
10561 %}
10562 
10563 instruct vsl16B_reg(vecX dst, vecX src, vecX shift) %{
10564   predicate(n->as_Vector()->length() == 16);
10565   match(Set dst (LShiftVB src shift));
10566   size(4*1);
10567   ins_cost(DEFAULT_COST*1); // FIXME
10568   expand %{
10569     vsh16B_reg(dst, src, shift);
10570   %}
10571 %}
10572 
10573 instruct vsl8B_immI(vecD dst, vecD src, immI shift) %{
10574   predicate(n->as_Vector()->length() == 8);
10575   match(Set dst (LShiftVB src shift));
10576   size(4);
10577   ins_cost(DEFAULT_COST); // FIXME
10578   format %{
10579     "VSHL.I8 $dst.D,$src.D,$shift\t! logical left shift packed8B"
10580   %}
10581   ins_encode %{
10582     bool quad = false;
10583     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10584              quad);
10585   %}
10586   ins_pipe( ialu_reg_reg ); // FIXME
10587 %}
10588 
10589 instruct vsl16B_immI(vecX dst, vecX src, immI shift) %{
10590   predicate(n->as_Vector()->length() == 16);
10591   match(Set dst (LShiftVB src shift));
10592   size(4);
10593   ins_cost(DEFAULT_COST); // FIXME
10594   format %{
10595     "VSHL.I8 $dst.Q,$src.Q,$shift\t! logical left shift packed16B"
10596   %}
10597   ins_encode %{
10598     bool quad = true;
10599     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10600              quad);
10601   %}
10602   ins_pipe( ialu_reg_reg ); // FIXME
10603 %}
10604 
10605 // Shorts/Chars vector logical left/right shift
10606 instruct vsl4S_reg(vecD dst, vecD src, vecD shift) %{
10607   predicate(n->as_Vector()->length() == 4);
10608   match(Set dst (LShiftVS src shift));
10609   match(Set dst (URShiftVS src shift));
10610   size(4*1);
10611   ins_cost(DEFAULT_COST*1); // FIXME
10612   expand %{
10613     vsh4S_reg(dst, src, shift);
10614   %}
10615 %}
10616 
10617 instruct vsl8S_reg(vecX dst, vecX src, vecX shift) %{
10618   predicate(n->as_Vector()->length() == 8);
10619   match(Set dst (LShiftVS src shift));
10620   match(Set dst (URShiftVS src shift));
10621   size(4*1);
10622   ins_cost(DEFAULT_COST*1); // FIXME
10623   expand %{
10624     vsh8S_reg(dst, src, shift);
10625   %}
10626 %}
10627 
10628 instruct vsl4S_immI(vecD dst, vecD src, immI shift) %{
10629   predicate(n->as_Vector()->length() == 4);
10630   match(Set dst (LShiftVS src shift));
10631   size(4);
10632   ins_cost(DEFAULT_COST); // FIXME
10633   format %{
10634     "VSHL.I16 $dst.D,$src.D,$shift\t! logical left shift packed4S"
10635   %}
10636   ins_encode %{
10637     bool quad = false;
10638     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10639              quad);
10640   %}
10641   ins_pipe( ialu_reg_reg ); // FIXME
10642 %}
10643 
10644 instruct vsl8S_immI(vecX dst, vecX src, immI shift) %{
10645   predicate(n->as_Vector()->length() == 8);
10646   match(Set dst (LShiftVS src shift));
10647   size(4);
10648   ins_cost(DEFAULT_COST); // FIXME
10649   format %{
10650     "VSHL.I16 $dst.Q,$src.Q,$shift\t! logical left shift packed8S"
10651   %}
10652   ins_encode %{
10653     bool quad = true;
10654     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10655              quad);
10656   %}
10657   ins_pipe( ialu_reg_reg ); // FIXME
10658 %}
10659 
10660 // Integers vector logical left/right shift
10661 instruct vsl2I_reg(vecD dst, vecD src, vecD shift) %{
10662   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10663   match(Set dst (LShiftVI src shift));
10664   match(Set dst (URShiftVI src shift));
10665   size(4*1);
10666   ins_cost(DEFAULT_COST*1); // FIXME
10667   expand %{
10668     vsh2I_reg(dst, src, shift);
10669   %}
10670 %}
10671 
10672 instruct vsl4I_reg(vecX dst, vecX src, vecX shift) %{
10673   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10674   match(Set dst (LShiftVI src shift));
10675   match(Set dst (URShiftVI src shift));
10676   size(4*1);
10677   ins_cost(DEFAULT_COST*1); // FIXME
10678   expand %{
10679     vsh4I_reg(dst, src, shift);
10680   %}
10681 %}
10682 
10683 instruct vsl2I_immI(vecD dst, vecD src, immI shift) %{
10684   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10685   match(Set dst (LShiftVI src shift));
10686   size(4);
10687   ins_cost(DEFAULT_COST); // FIXME
10688   format %{
10689     "VSHL.I32 $dst.D,$src.D,$shift\t! logical left shift packed2I"
10690   %}
10691   ins_encode %{
10692     bool quad = false;
10693     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10694              quad);
10695   %}
10696   ins_pipe( ialu_reg_reg ); // FIXME
10697 %}
10698 
10699 instruct vsl4I_immI(vecX dst, vecX src, immI shift) %{
10700   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10701   match(Set dst (LShiftVI src shift));
10702   size(4);
10703   ins_cost(DEFAULT_COST); // FIXME
10704   format %{
10705     "VSHL.I32 $dst.Q,$src.Q,$shift\t! logical left shift packed4I"
10706   %}
10707   ins_encode %{
10708     bool quad = true;
10709     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10710              quad);
10711   %}
10712   ins_pipe( ialu_reg_reg ); // FIXME
10713 %}
10714 
10715 // Longs vector logical left/right shift
10716 instruct vsl2L_reg(vecX dst, vecX src, vecX shift) %{
10717   predicate(n->as_Vector()->length() == 2);
10718   match(Set dst (LShiftVL src shift));
10719   match(Set dst (URShiftVL src shift));
10720   size(4*1);
10721   ins_cost(DEFAULT_COST*1); // FIXME
10722   expand %{
10723     vsh2L_reg(dst, src, shift);
10724   %}
10725 %}
10726 
10727 instruct vsl2L_immI(vecX dst, vecX src, immI shift) %{
10728   predicate(n->as_Vector()->length() == 2);
10729   match(Set dst (LShiftVL src shift));
10730   size(4);
10731   ins_cost(DEFAULT_COST); // FIXME
10732   format %{
10733     "VSHL.I64 $dst.Q,$src.Q,$shift\t! logical left shift packed2L"
10734   %}
10735   ins_encode %{
10736     bool quad = true;
10737     __ vshli($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
10738              quad);
10739   %}
10740   ins_pipe( ialu_reg_reg ); // FIXME
10741 %}
10742 
10743 // ----------------------- LogicalRightShift -----------------------------------
10744 
10745 // Bytes/Shorts vector logical right shift produces incorrect Java result
10746 // for negative data because java code convert short value into int with
10747 // sign extension before a shift.
10748 
10749 // Chars vector logical right shift
10750 instruct vsrl4S_immI(vecD dst, vecD src, immI shift) %{
10751   predicate(n->as_Vector()->length() == 4);
10752   match(Set dst (URShiftVS src shift));
10753   size(4);
10754   ins_cost(DEFAULT_COST); // FIXME
10755   format %{
10756     "VSHR.U16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
10757   %}
10758   ins_encode %{
10759     bool quad = false;
10760     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10761              quad);
10762   %}
10763   ins_pipe( ialu_reg_reg ); // FIXME
10764 %}
10765 
10766 instruct vsrl8S_immI(vecX dst, vecX src, immI shift) %{
10767   predicate(n->as_Vector()->length() == 8);
10768   match(Set dst (URShiftVS src shift));
10769   size(4);
10770   ins_cost(DEFAULT_COST); // FIXME
10771   format %{
10772     "VSHR.U16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
10773   %}
10774   ins_encode %{
10775     bool quad = true;
10776     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
10777              quad);
10778   %}
10779   ins_pipe( ialu_reg_reg ); // FIXME
10780 %}
10781 
10782 // Integers vector logical right shift
10783 instruct vsrl2I_immI(vecD dst, vecD src, immI shift) %{
10784   predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
10785   match(Set dst (URShiftVI src shift));
10786   size(4);
10787   ins_cost(DEFAULT_COST); // FIXME
10788   format %{
10789     "VSHR.U32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
10790   %}
10791   ins_encode %{
10792     bool quad = false;
10793     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10794              quad);
10795   %}
10796   ins_pipe( ialu_reg_reg ); // FIXME
10797 %}
10798 
10799 instruct vsrl4I_immI(vecX dst, vecX src, immI shift) %{
10800   predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd());
10801   match(Set dst (URShiftVI src shift));
10802   size(4);
10803   ins_cost(DEFAULT_COST); // FIXME
10804   format %{
10805     "VSHR.U32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
10806   %}
10807   ins_encode %{
10808     bool quad = true;
10809     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
10810              quad);
10811   %}
10812   ins_pipe( ialu_reg_reg ); // FIXME
10813 %}
10814 
10815 // Longs vector logical right shift
10816 instruct vsrl2L_immI(vecX dst, vecX src, immI shift) %{
10817   predicate(n->as_Vector()->length() == 2);
10818   match(Set dst (URShiftVL src shift));
10819   size(4);
10820   ins_cost(DEFAULT_COST); // FIXME
10821   format %{
10822     "VSHR.U64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
10823   %}
10824   ins_encode %{
10825     bool quad = true;
10826     __ vshrUI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
10827              quad);
10828   %}
10829   ins_pipe( ialu_reg_reg ); // FIXME
10830 %}
10831 
10832 // ------------------- ArithmeticRightShift -----------------------------------
10833 
10834 // Bytes vector arithmetic left/right shift based on sign
10835 instruct vsha8B_reg(vecD dst, vecD src, vecD shift) %{
10836   predicate(n->as_Vector()->length() == 8);
10837   effect(DEF dst, USE src, USE shift);
10838   size(4);
10839   ins_cost(DEFAULT_COST); // FIXME
10840   format %{
10841     "VSHL.S8 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed8B"
10842   %}
10843   ins_encode %{
10844     bool quad = false;
10845     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10846               MacroAssembler::VELEM_SIZE_8, quad);
10847   %}
10848   ins_pipe( ialu_reg_reg ); // FIXME
10849 %}
10850 
10851 instruct vsha16B_reg(vecX dst, vecX src, vecX shift) %{
10852   predicate(n->as_Vector()->length() == 16);
10853   effect(DEF dst, USE src, USE shift);
10854   size(4);
10855   ins_cost(DEFAULT_COST); // FIXME
10856   format %{
10857     "VSHL.S8 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed16B"
10858   %}
10859   ins_encode %{
10860     bool quad = true;
10861     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10862               MacroAssembler::VELEM_SIZE_8, quad);
10863   %}
10864   ins_pipe( ialu_reg_reg ); // FIXME
10865 %}
10866 
10867 // Shorts vector arithmetic left/right shift based on sign
10868 instruct vsha4S_reg(vecD dst, vecD src, vecD shift) %{
10869   predicate(n->as_Vector()->length() == 4);
10870   effect(DEF dst, USE src, USE shift);
10871   size(4);
10872   ins_cost(DEFAULT_COST); // FIXME
10873   format %{
10874     "VSHL.S16 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed4S"
10875   %}
10876   ins_encode %{
10877     bool quad = false;
10878     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10879               MacroAssembler::VELEM_SIZE_16, quad);
10880   %}
10881   ins_pipe( ialu_reg_reg ); // FIXME
10882 %}
10883 
10884 instruct vsha8S_reg(vecX dst, vecX src, vecX shift) %{
10885   predicate(n->as_Vector()->length() == 8);
10886   effect(DEF dst, USE src, USE shift);
10887   size(4);
10888   ins_cost(DEFAULT_COST); // FIXME
10889   format %{
10890     "VSHL.S16 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed8S"
10891   %}
10892   ins_encode %{
10893     bool quad = true;
10894     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10895               MacroAssembler::VELEM_SIZE_16, quad);
10896   %}
10897   ins_pipe( ialu_reg_reg ); // FIXME
10898 %}
10899 
10900 // Integers vector arithmetic left/right shift based on sign
10901 instruct vsha2I_reg(vecD dst, vecD src, vecD shift) %{
10902   predicate(n->as_Vector()->length() == 2);
10903   effect(DEF dst, USE src, USE shift);
10904   size(4);
10905   ins_cost(DEFAULT_COST); // FIXME
10906   format %{
10907     "VSHL.S32 $dst.D,$src.D,$shift.D\t! arithmetic right shift packed2I"
10908   %}
10909   ins_encode %{
10910     bool quad = false;
10911     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10912               MacroAssembler::VELEM_SIZE_32, quad);
10913   %}
10914   ins_pipe( ialu_reg_reg ); // FIXME
10915 %}
10916 
10917 instruct vsha4I_reg(vecX dst, vecX src, vecX shift) %{
10918   predicate(n->as_Vector()->length() == 4);
10919   effect(DEF dst, USE src, USE shift);
10920   size(4);
10921   ins_cost(DEFAULT_COST); // FIXME
10922   format %{
10923     "VSHL.S32 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed4I"
10924   %}
10925   ins_encode %{
10926     bool quad = true;
10927     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10928               MacroAssembler::VELEM_SIZE_32, quad);
10929   %}
10930   ins_pipe( ialu_reg_reg ); // FIXME
10931 %}
10932 
10933 // Longs vector arithmetic left/right shift based on sign
10934 instruct vsha2L_reg(vecX dst, vecX src, vecX shift) %{
10935   predicate(n->as_Vector()->length() == 2);
10936   effect(DEF dst, USE src, USE shift);
10937   size(4);
10938   ins_cost(DEFAULT_COST); // FIXME
10939   format %{
10940     "VSHL.S64 $dst.Q,$src.Q,$shift.Q\t! arithmetic right shift packed2L"
10941   %}
10942   ins_encode %{
10943     bool quad = true;
10944     __ vshlSI($dst$$FloatRegister, $shift$$FloatRegister, $src$$FloatRegister,
10945               MacroAssembler::VELEM_SIZE_64, quad);
10946   %}
10947   ins_pipe( ialu_reg_reg ); // FIXME
10948 %}
10949 
10950 // Byte vector arithmetic right shift
10951 
10952 instruct vsra8B_reg(vecD dst, vecD src, vecD shift) %{
10953   predicate(n->as_Vector()->length() == 8);
10954   match(Set dst (RShiftVB src shift));
10955   size(4);
10956   ins_cost(DEFAULT_COST); // FIXME
10957   expand %{
10958     vsha8B_reg(dst, src, shift);
10959   %}
10960 %}
10961 
10962 instruct vsrl16B_reg(vecX dst, vecX src, vecX shift) %{
10963   predicate(n->as_Vector()->length() == 16);
10964   match(Set dst (RShiftVB src shift));
10965   size(4);
10966   ins_cost(DEFAULT_COST); // FIXME
10967   expand %{
10968     vsha16B_reg(dst, src, shift);
10969   %}
10970 %}
10971 
10972 instruct vsrl8B_immI(vecD dst, vecD src, immI shift) %{
10973   predicate(n->as_Vector()->length() == 8);
10974   match(Set dst (RShiftVB src shift));
10975   size(4);
10976   ins_cost(DEFAULT_COST); // FIXME
10977   format %{
10978     "VSHR.S8 $dst.D,$src.D,$shift\t! logical right shift packed8B"
10979   %}
10980   ins_encode %{
10981     bool quad = false;
10982     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10983              quad);
10984   %}
10985   ins_pipe( ialu_reg_reg ); // FIXME
10986 %}
10987 
10988 instruct vsrl16B_immI(vecX dst, vecX src, immI shift) %{
10989   predicate(n->as_Vector()->length() == 16);
10990   match(Set dst (RShiftVB src shift));
10991   size(4);
10992   ins_cost(DEFAULT_COST); // FIXME
10993   format %{
10994     "VSHR.S8 $dst.Q,$src.Q,$shift\t! logical right shift packed16B"
10995   %}
10996   ins_encode %{
10997     bool quad = true;
10998     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 8, $shift$$constant,
10999              quad);
11000   %}
11001   ins_pipe( ialu_reg_reg ); // FIXME
11002 %}
11003 
11004 // Shorts vector arithmetic right shift
11005 instruct vsra4S_reg(vecD dst, vecD src, vecD shift) %{
11006   predicate(n->as_Vector()->length() == 4);
11007   match(Set dst (RShiftVS src shift));
11008   size(4);
11009   ins_cost(DEFAULT_COST); // FIXME
11010   expand %{
11011     vsha4S_reg(dst, src, shift);
11012   %}
11013 %}
11014 
11015 instruct vsra8S_reg(vecX dst, vecX src, vecX shift) %{
11016   predicate(n->as_Vector()->length() == 8);
11017   match(Set dst (RShiftVS src shift));
11018   size(4);
11019   ins_cost(DEFAULT_COST); // FIXME
11020   expand %{
11021     vsha8S_reg(dst, src, shift);
11022   %}
11023 %}
11024 
11025 instruct vsra4S_immI(vecD dst, vecD src, immI shift) %{
11026   predicate(n->as_Vector()->length() == 4);
11027   match(Set dst (RShiftVS src shift));
11028   size(4);
11029   ins_cost(DEFAULT_COST); // FIXME
11030   format %{
11031     "VSHR.S16 $dst.D,$src.D,$shift\t! logical right shift packed4S"
11032   %}
11033   ins_encode %{
11034     bool quad = false;
11035     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
11036              quad);
11037   %}
11038   ins_pipe( ialu_reg_reg ); // FIXME
11039 %}
11040 
11041 instruct vsra8S_immI(vecX dst, vecX src, immI shift) %{
11042   predicate(n->as_Vector()->length() == 8);
11043   match(Set dst (RShiftVS src shift));
11044   size(4);
11045   ins_cost(DEFAULT_COST); // FIXME
11046   format %{
11047     "VSHR.S16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S"
11048   %}
11049   ins_encode %{
11050     bool quad = true;
11051     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 16, $shift$$constant,
11052              quad);
11053   %}
11054   ins_pipe( ialu_reg_reg ); // FIXME
11055 %}
11056 
11057 // Integers vector arithmetic right shift
11058 instruct vsra2I_reg(vecD dst, vecD src, vecD shift) %{
11059   predicate(n->as_Vector()->length() == 2);
11060   match(Set dst (RShiftVI src shift));
11061   size(4);
11062   ins_cost(DEFAULT_COST); // FIXME
11063   expand %{
11064     vsha2I_reg(dst, src, shift);
11065   %}
11066 %}
11067 
11068 instruct vsra4I_reg(vecX dst, vecX src, vecX shift) %{
11069   predicate(n->as_Vector()->length() == 4);
11070   match(Set dst (RShiftVI src shift));
11071   size(4);
11072   ins_cost(DEFAULT_COST); // FIXME
11073   expand %{
11074     vsha4I_reg(dst, src, shift);
11075   %}
11076 %}
11077 
11078 instruct vsra2I_immI(vecD dst, vecD src, immI shift) %{
11079   predicate(n->as_Vector()->length() == 2);
11080   match(Set dst (RShiftVI src shift));
11081   size(4);
11082   ins_cost(DEFAULT_COST); // FIXME
11083   format %{
11084     "VSHR.S32 $dst.D,$src.D,$shift\t! logical right shift packed2I"
11085   %}
11086   ins_encode %{
11087     bool quad = false;
11088     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11089              quad);
11090   %}
11091   ins_pipe( ialu_reg_reg ); // FIXME
11092 %}
11093 
11094 instruct vsra4I_immI(vecX dst, vecX src, immI shift) %{
11095   predicate(n->as_Vector()->length() == 4);
11096   match(Set dst (RShiftVI src shift));
11097   size(4);
11098   ins_cost(DEFAULT_COST); // FIXME
11099   format %{
11100     "VSHR.S32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I"
11101   %}
11102   ins_encode %{
11103     bool quad = true;
11104     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 32, $shift$$constant,
11105              quad);
11106   %}
11107   ins_pipe( ialu_reg_reg ); // FIXME
11108 %}
11109 
11110 // Longs vector arithmetic right shift
11111 instruct vsra2L_reg(vecX dst, vecX src, vecX shift) %{
11112   predicate(n->as_Vector()->length() == 2);
11113   match(Set dst (RShiftVL src shift));
11114   size(4);
11115   ins_cost(DEFAULT_COST); // FIXME
11116   expand %{
11117     vsha2L_reg(dst, src, shift);
11118   %}
11119 %}
11120 
11121 instruct vsra2L_immI(vecX dst, vecX src, immI shift) %{
11122   predicate(n->as_Vector()->length() == 2);
11123   match(Set dst (RShiftVL src shift));
11124   size(4);
11125   ins_cost(DEFAULT_COST); // FIXME
11126   format %{
11127     "VSHR.S64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L"
11128   %}
11129   ins_encode %{
11130     bool quad = true;
11131     __ vshrSI($dst$$FloatRegister, $src$$FloatRegister, 64, $shift$$constant,
11132              quad);
11133   %}
11134   ins_pipe( ialu_reg_reg ); // FIXME
11135 %}
11136 
11137 // --------------------------------- AND --------------------------------------
11138 
11139 instruct vandD(vecD dst, vecD src1, vecD src2) %{
11140   predicate(n->as_Vector()->length_in_bytes() == 8);
11141   match(Set dst (AndV src1 src2));
11142   format %{ "VAND    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11143   ins_encode %{
11144     bool quad = false;
11145     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11146              quad);
11147   %}
11148   ins_pipe( ialu_reg_reg ); // FIXME
11149 %}
11150 
11151 instruct vandX(vecX dst, vecX src1, vecX src2) %{
11152   predicate(n->as_Vector()->length_in_bytes() == 16);
11153   match(Set dst (AndV src1 src2));
11154   format %{ "VAND    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11155   ins_encode %{
11156     bool quad = true;
11157     __ vandI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11158              quad);
11159   %}
11160   ins_pipe( ialu_reg_reg ); // FIXME
11161 %}
11162 
11163 // --------------------------------- OR ---------------------------------------
11164 
11165 instruct vorD(vecD dst, vecD src1, vecD src2) %{
11166   predicate(n->as_Vector()->length_in_bytes() == 8);
11167   match(Set dst (OrV src1 src2));
11168   format %{ "VOR     $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11169   ins_encode %{
11170     bool quad = false;
11171     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11172             quad);
11173   %}
11174   ins_pipe( ialu_reg_reg ); // FIXME
11175 %}
11176 
11177 instruct vorX(vecX dst, vecX src1, vecX src2) %{
11178   predicate(n->as_Vector()->length_in_bytes() == 16);
11179   match(Set dst (OrV src1 src2));
11180   format %{ "VOR     $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11181   ins_encode %{
11182     bool quad = true;
11183     __ vorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11184             quad);
11185   %}
11186   ins_pipe( ialu_reg_reg ); // FIXME
11187 %}
11188 
11189 // --------------------------------- XOR --------------------------------------
11190 
11191 instruct vxorD(vecD dst, vecD src1, vecD src2) %{
11192   predicate(n->as_Vector()->length_in_bytes() == 8);
11193   match(Set dst (XorV src1 src2));
11194   format %{ "VXOR    $dst.D,$src1.D,$src2.D\t! and vectors (8 bytes)" %}
11195   ins_encode %{
11196     bool quad = false;
11197     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11198              quad);
11199   %}
11200   ins_pipe( ialu_reg_reg ); // FIXME
11201 %}
11202 
11203 instruct vxorX(vecX dst, vecX src1, vecX src2) %{
11204   predicate(n->as_Vector()->length_in_bytes() == 16);
11205   match(Set dst (XorV src1 src2));
11206   format %{ "VXOR    $dst.Q,$src1.Q,$src2.Q\t! and vectors (16 bytes)" %}
11207   ins_encode %{
11208     bool quad = true;
11209     __ vxorI($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
11210              quad);
11211   %}
11212   ins_pipe( ialu_reg_reg ); // FIXME
11213 %}
11214 
11215 
11216 //----------PEEPHOLE RULES-----------------------------------------------------
11217 // These must follow all instruction definitions as they use the names
11218 // defined in the instructions definitions.
11219 //
11220 // peepmatch ( root_instr_name [preceding_instruction]* );
11221 //
11222 // peepconstraint %{
11223 // (instruction_number.operand_name relational_op instruction_number.operand_name
11224 //  [, ...] );
11225 // // instruction numbers are zero-based using left to right order in peepmatch
11226 //
11227 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
11228 // // provide an instruction_number.operand_name for each operand that appears
11229 // // in the replacement instruction's match rule
11230 //
11231 // ---------VM FLAGS---------------------------------------------------------
11232 //
11233 // All peephole optimizations can be turned off using -XX:-OptoPeephole
11234 //
11235 // Each peephole rule is given an identifying number starting with zero and
11236 // increasing by one in the order seen by the parser.  An individual peephole
11237 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
11238 // on the command-line.
11239 //
11240 // ---------CURRENT LIMITATIONS----------------------------------------------
11241 //
11242 // Only match adjacent instructions in same basic block
11243 // Only equality constraints
11244 // Only constraints between operands, not (0.dest_reg == EAX_enc)
11245 // Only one replacement instruction
11246 //
11247 // ---------EXAMPLE----------------------------------------------------------
11248 //
11249 // // pertinent parts of existing instructions in architecture description
11250 // instruct movI(eRegI dst, eRegI src) %{
11251 //   match(Set dst (CopyI src));
11252 // %}
11253 //
11254 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
11255 //   match(Set dst (AddI dst src));
11256 //   effect(KILL cr);
11257 // %}
11258 //
11259 // // Change (inc mov) to lea
11260 // peephole %{
11261 //   // increment preceeded by register-register move
11262 //   peepmatch ( incI_eReg movI );
11263 //   // require that the destination register of the increment
11264 //   // match the destination register of the move
11265 //   peepconstraint ( 0.dst == 1.dst );
11266 //   // construct a replacement instruction that sets
11267 //   // the destination to ( move's source register + one )
11268 //   peepreplace ( incI_eReg_immI1( 0.dst 1.src 0.src ) );
11269 // %}
11270 //
11271 
11272 // // Change load of spilled value to only a spill
11273 // instruct storeI(memory mem, eRegI src) %{
11274 //   match(Set mem (StoreI mem src));
11275 // %}
11276 //
11277 // instruct loadI(eRegI dst, memory mem) %{
11278 //   match(Set dst (LoadI mem));
11279 // %}
11280 //
11281 // peephole %{
11282 //   peepmatch ( loadI storeI );
11283 //   peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
11284 //   peepreplace ( storeI( 1.mem 1.mem 1.src ) );
11285 // %}
11286 
11287 //----------SMARTSPILL RULES---------------------------------------------------
11288 // These must follow all instruction definitions as they use the names
11289 // defined in the instructions definitions.
11290 //
11291 // ARM will probably not have any of these rules due to RISC instruction set.
11292 
11293 //----------PIPELINE-----------------------------------------------------------
11294 // Rules which define the behavior of the target architectures pipeline.