< prev index next >

src/cpu/ppc/vm/ppc.ad

Print this page
rev 7616 : 8068503: ppc64: Encode/Decode nodes for disjoint cOops mode
   1 //
   2 // Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
   3 // Copyright 2012, 2014 SAP AG. All rights reserved.
   4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5 //
   6 // This code is free software; you can redistribute it and/or modify it
   7 // under the terms of the GNU General Public License version 2 only, as
   8 // published by the Free Software Foundation.
   9 //
  10 // This code is distributed in the hope that it will be useful, but WITHOUT
  11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13 // version 2 for more details (a copy is included in the LICENSE file that
  14 // accompanied this code).
  15 //
  16 // You should have received a copy of the GNU General Public License version
  17 // 2 along with this work; if not, write to the Free Software Foundation,
  18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19 //
  20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21 // or visit www.oracle.com if you need additional information or have any
  22 // questions.
  23 //


2681     assert(nodes->length() >= 1, "must have created at least 1 node");
2682     assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
2683   %}
2684 
2685   enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{
2686     // TODO: PPC port $archOpcode(ppc64Opcode_ld);
2687 
2688     MacroAssembler _masm(&cbuf);
2689     int toc_offset = 0;
2690 
2691     if (!ra_->C->in_scratch_emit_size()) {
2692       intptr_t val = $src$$constant;
2693       relocInfo::relocType constant_reloc = $src->constant_reloc();  // src
2694       address const_toc_addr;
2695       if (constant_reloc == relocInfo::oop_type) {
2696         // Create an oop constant and a corresponding relocation.
2697         AddressLiteral a = __ allocate_oop_address((jobject)val);
2698         const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2699         __ relocate(a.rspec());
2700       } else if (constant_reloc == relocInfo::metadata_type) {
2701         AddressLiteral a = __ allocate_metadata_address((Metadata *)val);
2702         const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2703         __ relocate(a.rspec());
2704       } else {
2705         // Create a non-oop constant, no relocation needed.
2706         const_toc_addr = __ long_constant((jlong)$src$$constant);
2707       }
2708 
2709       // Get the constant's TOC offset.
2710       toc_offset = __ offset_to_method_toc(const_toc_addr);
2711     }
2712 
2713     __ ld($dst$$Register, toc_offset, $toc$$Register);
2714   %}
2715 
2716   enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{
2717     // TODO: PPC port $archOpcode(ppc64Opcode_addis);
2718 
2719     MacroAssembler _masm(&cbuf);
2720     if (!ra_->C->in_scratch_emit_size()) {
2721       intptr_t val = $src$$constant;
2722       relocInfo::relocType constant_reloc = $src->constant_reloc();  // src
2723       address const_toc_addr;
2724       if (constant_reloc == relocInfo::oop_type) {
2725         // Create an oop constant and a corresponding relocation.
2726         AddressLiteral a = __ allocate_oop_address((jobject)val);
2727         const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2728         __ relocate(a.rspec());
2729       } else if (constant_reloc == relocInfo::metadata_type) {
2730         AddressLiteral a = __ allocate_metadata_address((Metadata *)val);
2731         const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2732         __ relocate(a.rspec());
2733       } else {  // non-oop pointers, e.g. card mark base, heap top
2734         // Create a non-oop constant, no relocation needed.
2735         const_toc_addr = __ long_constant((jlong)$src$$constant);
2736       }
2737 
2738       // Get the constant's TOC offset.
2739       const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2740       // Store the toc offset of the constant.
2741       ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset;
2742     }
2743 
2744     __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2745   %}
2746 
2747   // Postalloc expand emitter for loading a ptr constant from the method's TOC.
2748   // Enc_class needed as consttanttablebase is not supported by postalloc
2749   // expand.
2750   enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{


6012   ins_pipe(pipe_class_default);
6013 %}
6014 
6015 // Needed to postalloc expand loadConN: ConN is loaded as ConI
6016 // leaving the upper 32 bits with sign-extension bits.
6017 // This clears these bits: dst = src & 0xFFFFFFFF.
6018 // TODO: Eventually call this maskN_regN_FFFFFFFF.
6019 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{
6020   effect(DEF dst, USE src);
6021   predicate(false);
6022 
6023   format %{ "MASK    $dst, $src, 0xFFFFFFFF" %} // mask
6024   size(4);
6025   ins_encode %{
6026     // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6027     __ clrldi($dst$$Register, $src$$Register, 0x20);
6028   %}
6029   ins_pipe(pipe_class_default);
6030 %}
6031 














6032 // Loading ConN must be postalloc expanded so that edges between
6033 // the nodes are safe. They may not interfere with a safepoint.
6034 // GL TODO: This needs three instructions: better put this into the constant pool.
6035 instruct loadConN_Ex(iRegNdst dst, immN src) %{
6036   match(Set dst src);
6037   ins_cost(DEFAULT_COST*2);
6038 
6039   format %{ "LoadN   $dst, $src \t// postalloc expanded" %} // mask
6040   postalloc_expand %{
6041     MachNode *m1 = new loadConN_hiNode();
6042     MachNode *m2 = new loadConN_loNode();
6043     MachNode *m3 = new clearMs32bNode();
6044     m1->add_req(NULL);
6045     m2->add_req(NULL, m1);
6046     m3->add_req(NULL, m2);
6047     m1->_opnds[0] = op_dst;
6048     m1->_opnds[1] = op_src;
6049     m2->_opnds[0] = op_dst;
6050     m2->_opnds[1] = op_dst;
6051     m2->_opnds[2] = op_src;


6707   %}
6708   ins_pipe(pipe_class_default);
6709 %}
6710 
6711 // Power 7 can use isel instruction
6712 instruct cond_set_0_oop(iRegNdst dst, flagsReg crx, iRegPsrc src1) %{
6713   // The match rule is needed to make it a 'MachTypeNode'!
6714   match(Set dst (EncodeP (Binary crx src1)));
6715   predicate(false);
6716 
6717   format %{ "CMOVE   $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %}
6718   size(4);
6719   ins_encode %{
6720     // This is a Power7 instruction for which no machine description exists.
6721     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6722     __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6723   %}
6724   ins_pipe(pipe_class_default);
6725 %}
6726 
6727 // base != 0
6728 // 32G aligned narrow oop base.
6729 instruct encodeP_32GAligned(iRegNdst dst, iRegPsrc src) %{
6730   match(Set dst (EncodeP src));
6731   predicate(false /* TODO: PPC port Universe::narrow_oop_base_disjoint()*/);
6732 
6733   format %{ "EXTRDI  $dst, $src, #32, #3 \t// encode with 32G aligned base" %}
6734   size(4);
6735   ins_encode %{
6736     // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6737     __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32);
6738   %}
6739   ins_pipe(pipe_class_default);
6740 %}
6741 
6742 // shift != 0, base != 0
6743 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{
6744   match(Set dst (EncodeP src));
6745   effect(TEMP crx);
6746   predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull &&
6747             Universe::narrow_oop_shift() != 0 &&
6748             true /* TODO: PPC port Universe::narrow_oop_base_overlaps()*/);
6749 
6750   format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %}
6751   postalloc_expand( postalloc_expand_encode_oop(dst, src, crx));
6752 %}
6753 
6754 // shift != 0, base != 0
6755 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{
6756   match(Set dst (EncodeP src));
6757   predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull &&
6758             Universe::narrow_oop_shift() != 0 &&
6759             true /* TODO: PPC port Universe::narrow_oop_base_overlaps()*/);
6760 
6761   format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %}
6762   postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) );
6763 %}
6764 
6765 // shift != 0, base == 0
6766 // TODO: This is the same as encodeP_shift. Merge!
6767 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{
6768   match(Set dst (EncodeP src));
6769   predicate(Universe::narrow_oop_shift() != 0 &&
6770             Universe::narrow_oop_base() ==0);
6771 
6772   format %{ "SRDI    $dst, $src, #3 \t// encodeP, $src != NULL" %}
6773   size(4);
6774   ins_encode %{
6775     // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6776     __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f);
6777   %}
6778   ins_pipe(pipe_class_default);
6779 %}


6859   match(Set dst (DecodeN (Binary crx src1)));
6860   predicate(false);
6861 
6862   format %{ "CMOVE   $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %}
6863   size(4);
6864   ins_encode %{
6865     // This is a Power7 instruction for which no machine description exists.
6866     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6867     __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6868   %}
6869   ins_pipe(pipe_class_default);
6870 %}
6871 
6872 //  shift != 0, base != 0
6873 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6874   match(Set dst (DecodeN src));
6875   predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6876              n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6877             Universe::narrow_oop_shift() != 0 &&
6878             Universe::narrow_oop_base() != 0);

6879   effect(TEMP crx);
6880 
6881   format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %}
6882   postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) );
6883 %}
6884 
6885 // shift != 0, base == 0
6886 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{
6887   match(Set dst (DecodeN src));
6888   predicate(Universe::narrow_oop_shift() != 0 &&
6889             Universe::narrow_oop_base() == 0);
6890 
6891   format %{ "SLDI    $dst, $src, #3 \t// DecodeN (zerobased)" %}
6892   size(4);
6893   ins_encode %{
6894     // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
6895     __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift());
6896   %}
6897   ins_pipe(pipe_class_default);
6898 %}
6899 




































































































6900 // src != 0, shift != 0, base != 0
6901 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{
6902   match(Set dst (DecodeN src));
6903   predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6904              n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6905             Universe::narrow_oop_shift() != 0 &&
6906             Universe::narrow_oop_base() != 0);

6907 
6908   format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %}
6909   postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src));
6910 %}
6911 
6912 // Compressed OOPs with narrow_oop_shift == 0.
6913 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{
6914   match(Set dst (DecodeN src));
6915   predicate(Universe::narrow_oop_shift() == 0);
6916   ins_cost(DEFAULT_COST);
6917 
6918   format %{ "MR      $dst, $src \t// DecodeN (unscaled)" %}
6919   // variable size, 0 or 4.
6920   ins_encode %{
6921     // TODO: PPC port $archOpcode(ppc64Opcode_or);
6922     __ mr_if_needed($dst$$Register, $src$$Register);
6923   %}
6924   ins_pipe(pipe_class_default);
6925 %}
6926 


6956     __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift());
6957   %}
6958   ins_pipe(pipe_class_default);
6959 %}
6960 
6961 // Add node for expand.
6962 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6963   // The match rule is needed to make it a 'MachTypeNode'!
6964   match(Set dst (EncodePKlass (Binary base src)));
6965   predicate(false);
6966 
6967   format %{ "SUB     $dst, $base, $src \t// encode" %}
6968   size(4);
6969   ins_encode %{
6970     // TODO: PPC port $archOpcode(ppc64Opcode_subf);
6971     __ subf($dst$$Register, $base$$Register, $src$$Register);
6972   %}
6973   ins_pipe(pipe_class_default);
6974 %}
6975 
6976 // base != 0
6977 // 32G aligned narrow oop base.
6978 instruct encodePKlass_32GAligned(iRegNdst dst, iRegPsrc src) %{
6979   match(Set dst (EncodePKlass src));
6980   predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/);
6981 
6982   format %{ "EXTRDI  $dst, $src, #32, #3 \t// encode with 32G aligned base" %}
6983   size(4);
6984   ins_encode %{
6985     // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6986     __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32);
6987   %}
6988   ins_pipe(pipe_class_default);
6989 %}
6990 
6991 // shift != 0, base != 0
6992 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{
6993   match(Set dst (EncodePKlass (Binary base src)));
6994   predicate(false);
6995 
6996   format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6997   postalloc_expand %{
6998     encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode();
6999     n1->add_req(n_region, n_base, n_src);
7000     n1->_opnds[0] = op_dst;
7001     n1->_opnds[1] = op_base;
7002     n1->_opnds[2] = op_src;


7469   ins_pipe(pipe_class_default);
7470 %}
7471 
7472 //----------Conditional_store--------------------------------------------------
7473 // Conditional-store of the updated heap-top.
7474 // Used during allocation of the shared heap.
7475 // Sets flags (EQ) on success. Implemented with a CASA on Sparc.
7476 
7477 // As compareAndSwapL, but return flag register instead of boolean value in
7478 // int register.
7479 // Used by sun/misc/AtomicLongCSImpl.java.
7480 // Mem_ptr must be a memory operand, else this node does not get
7481 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node
7482 // can be rematerialized which leads to errors.
7483 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal) %{
7484   match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal)));
7485   format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %}
7486   ins_encode %{
7487     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7488     __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register,
7489                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7490                 noreg, NULL, true);
7491   %}
7492   ins_pipe(pipe_class_default);
7493 %}
7494 
7495 // As compareAndSwapP, but return flag register instead of boolean value in
7496 // int register.
7497 // This instruction is matched if UseTLAB is off.
7498 // Mem_ptr must be a memory operand, else this node does not get
7499 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node
7500 // can be rematerialized which leads to errors.
7501 instruct storePConditional_regP_regP_regP(flagsReg crx, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{
7502   match(Set crx (StorePConditional mem_ptr (Binary oldVal newVal)));
7503   format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %}
7504   ins_encode %{
7505     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7506     __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register,
7507                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7508                 noreg, NULL, true);
7509   %}


10459   size(4);
10460   ins_encode %{
10461     // TODO: PPC port $archOpcode(ppc64Opcode_tdi);
10462     if ($cmp$$cmpcode == 0xA) {
10463       __ trap_null_check($value$$Register);
10464     } else {
10465       // Both successors are uncommon traps, probability is 0.
10466       // Node got flipped during fixup flow.
10467       assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
10468       __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
10469     }
10470   %}
10471   ins_pipe(pipe_class_trap);
10472 %}
10473 
10474 // Compare narrow oops.
10475 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{
10476   match(Set crx (CmpN src1 src2));
10477 
10478   size(4);
10479   ins_cost(DEFAULT_COST);
10480   format %{ "CMPLW   $crx, $src1, $src2 \t// compressed ptr" %}
10481   ins_encode %{
10482     // TODO: PPC port $archOpcode(ppc64Opcode_cmpl);
10483     __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10484   %}
10485   ins_pipe(pipe_class_compare);
10486 %}
10487 
10488 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{
10489   match(Set crx (CmpN src1 src2));
10490   // Make this more expensive than zeroCheckN_iReg_imm0.
10491   ins_cost(DEFAULT_COST);
10492 
10493   format %{ "CMPLWI  $crx, $src1, $src2 \t// compressed ptr" %}
10494   size(4);
10495   ins_encode %{
10496     // TODO: PPC port $archOpcode(ppc64Opcode_cmpli);
10497     __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10498   %}
10499   ins_pipe(pipe_class_compare);
10500 %}
10501 
10502 // Implicit zero checks (more implicit null checks).
10503 // No constant pool entries required.
10504 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{
10505   match(If cmp (CmpP value zero));
10506   effect(USE labl);
10507   predicate(TrapBasedNullChecks &&
10508             _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
10509             _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
10510             Matcher::branches_to_uncommon_trap(_leaf));

10511 
10512   ins_is_TrapBasedCheckNode(true);
10513 
10514   format %{ "TDI     $value $cmp $zero \t// ZeroCheckP => trap $labl" %}
10515   size(4);
10516   ins_encode %{
10517     // TODO: PPC port $archOpcode(ppc64Opcode_tdi);
10518     if ($cmp$$cmpcode == 0xA) {
10519       __ trap_null_check($value$$Register);
10520     } else {
10521       // Both successors are uncommon traps, probability is 0.
10522       // Node got flipped during fixup flow.
10523       assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
10524       __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
10525     }
10526   %}
10527   ins_pipe(pipe_class_trap);
10528 %}
10529 
10530 // Compare Pointers


10872   format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
10873   size(8); // worst case
10874   ins_encode( enc_bc_short_far(crx, cmp, labl) );
10875   ins_pipe(pipe_class_default);
10876 %}
10877 
10878 // ============================================================================
10879 // Java runtime operations, intrinsics and other complex operations.
10880 
10881 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
10882 // array for an instance of the superklass. Set a hidden internal cache on a
10883 // hit (cache is checked with exposed code in gen_subtype_check()). Return
10884 // not zero for a miss or zero for a hit. The encoding ALSO sets flags.
10885 //
10886 // GL TODO: Improve this.
10887 // - result should not be a TEMP
10888 // - Add match rule as on sparc avoiding additional Cmp.
10889 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass,
10890                              iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{
10891   match(Set result (PartialSubtypeCheck subklass superklass));
10892   effect(TEMP result, TEMP tmp_klass, TEMP tmp_arrayptr);
10893   ins_cost(DEFAULT_COST*10);
10894 
10895   format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
10896   ins_encode %{
10897     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
10898     __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register,
10899                                      $tmp_klass$$Register, NULL, $result$$Register);
10900   %}
10901   ins_pipe(pipe_class_default);
10902 %}
10903 
10904 // inlined locking and unlocking
10905 
10906 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
10907   match(Set crx (FastLock oop box));
10908   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
10909   // TODO PPC port predicate(!UseNewFastLockPPC64 || UseBiasedLocking);
10910 
10911   format %{ "FASTLOCK  $oop, $box, $tmp1, $tmp2, $tmp3" %}
10912   ins_encode %{


10983 // Match needle into immediate operands: no loadConP node needed. Saves one
10984 // register and two instructions over string_indexOf_imm1Node.
10985 //
10986 // Assumes register result differs from all input registers.
10987 //
10988 // Preserves registers haystack, haycnt
10989 // Kills     registers tmp1, tmp2
10990 // Defines   registers result
10991 //
10992 // Use dst register classes if register gets killed, as it is the case for tmp registers!
10993 //
10994 // Unfortunately this does not match too often. In many situations the AddP is used
10995 // by several nodes, even several StrIndexOf nodes, breaking the match tree.
10996 instruct string_indexOf_imm1_char(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
10997                                   immP needleImm, immL offsetImm, immI_1 needlecntImm,
10998                                   iRegIdst tmp1, iRegIdst tmp2,
10999                                   flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11000   predicate(SpecialStringIndexOf);  // type check implicit by parameter type, See Matcher::match_rule_supported
11001   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11002 
11003   effect(TEMP result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1);
11004 
11005   ins_cost(150);
11006   format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11007             "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11008 
11009   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted
11010   ins_encode %{
11011     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11012     immPOper *needleOper = (immPOper *)$needleImm;
11013     const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11014     ciTypeArray* needle_values = t->const_oop()->as_type_array();  // Pointer to live char *
11015 
11016     __ string_indexof_1($result$$Register,
11017                         $haystack$$Register, $haycnt$$Register,
11018                         R0, needle_values->char_at(0),
11019                         $tmp1$$Register, $tmp2$$Register);
11020   %}
11021   ins_pipe(pipe_class_compare);
11022 %}
11023 
11024 // String_IndexOf for needle of length 1.
11025 //
11026 // Special case requires less registers and emits less instructions.
11027 //
11028 // Assumes register result differs from all input registers.
11029 //
11030 // Preserves registers haystack, haycnt
11031 // Kills     registers tmp1, tmp2, needle
11032 // Defines   registers result
11033 //
11034 // Use dst register classes if register gets killed, as it is the case for tmp registers!
11035 instruct string_indexOf_imm1(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11036                              rscratch2RegP needle, immI_1 needlecntImm,
11037                              iRegIdst tmp1, iRegIdst tmp2,
11038                              flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11039   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11040   effect(USE_KILL needle, /* TDEF needle, */ TEMP result,
11041          TEMP tmp1, TEMP tmp2);
11042   // Required for EA: check if it is still a type_array.
11043   predicate(SpecialStringIndexOf && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11044             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11045   ins_cost(180);
11046 
11047   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11048 
11049   format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11050             " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11051   ins_encode %{
11052     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11053     Node *ndl = in(operand_index($needle));  // The node that defines needle.
11054     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11055     guarantee(needle_values, "sanity");
11056     if (needle_values != NULL) {
11057       __ string_indexof_1($result$$Register,
11058                           $haystack$$Register, $haycnt$$Register,
11059                           R0, needle_values->char_at(0),
11060                           $tmp1$$Register, $tmp2$$Register);


11067   %}
11068   ins_pipe(pipe_class_compare);
11069 %}
11070 
11071 // String_IndexOf.
11072 //
11073 // Length of needle as immediate. This saves instruction loading constant needle
11074 // length.
11075 // @@@ TODO Specify rules for length < 8 or so, and roll out comparison of needle
11076 // completely or do it in vector instruction. This should save registers for
11077 // needlecnt and needle.
11078 //
11079 // Assumes register result differs from all input registers.
11080 // Overwrites haycnt, needlecnt.
11081 // Use dst register classes if register gets killed, as it is the case for tmp registers!
11082 instruct string_indexOf_imm(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11083                             iRegPsrc needle, uimmI15 needlecntImm,
11084                             iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11085                             flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6) %{
11086   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11087   effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP result,
11088          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6);
11089   // Required for EA: check if it is still a type_array.
11090   predicate(SpecialStringIndexOf && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11091             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11092   ins_cost(250);
11093 
11094   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11095 
11096   format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11097             " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11098   ins_encode %{
11099     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11100     Node *ndl = in(operand_index($needle));  // The node that defines needle.
11101     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11102 
11103     __ string_indexof($result$$Register,
11104                       $haystack$$Register, $haycnt$$Register,
11105                       $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11106                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register);
11107   %}
11108   ins_pipe(pipe_class_compare);
11109 %}
11110 
11111 // StrIndexOf node.
11112 //
11113 // Assumes register result differs from all input registers.
11114 // Overwrites haycnt, needlecnt.
11115 // Use dst register classes if register gets killed, as it is the case for tmp registers!
11116 instruct string_indexOf(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11117                         iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11118                         flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6) %{
11119   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11120   effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11121          TEMP result,
11122          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6);
11123   predicate(SpecialStringIndexOf);  // See Matcher::match_rule_supported.
11124   ins_cost(300);
11125 
11126   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11127 
11128   format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11129              " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11130   ins_encode %{
11131     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11132     __ string_indexof($result$$Register,
11133                       $haystack$$Register, $haycnt$$Register,
11134                       $needle$$Register, NULL, $needlecnt$$Register, 0,  // needlecnt not constant.
11135                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register);
11136   %}
11137   ins_pipe(pipe_class_compare);
11138 %}
11139 
11140 // String equals with immediate.
11141 instruct string_equals_imm(iRegPsrc str1, iRegPsrc str2, uimmI15 cntImm, iRegIdst result,
11142                            iRegPdst tmp1, iRegPdst tmp2,
11143                            flagsRegCR0 cr0, flagsRegCR6 cr6, regCTR ctr) %{
11144   match(Set result (StrEquals (Binary str1 str2) cntImm));
11145   effect(TEMP result, TEMP tmp1, TEMP tmp2,
11146          KILL cr0, KILL cr6, KILL ctr);
11147   predicate(SpecialStringEquals);  // See Matcher::match_rule_supported.
11148   ins_cost(250);
11149 
11150   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11151 
11152   format %{ "String Equals SCL [0..$cntImm]($str1),[0..$cntImm]($str2)"
11153             " -> $result \t// KILL $cr0, $cr6, $ctr, TEMP $result, $tmp1, $tmp2" %}
11154   ins_encode %{
11155     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11156     __ char_arrays_equalsImm($str1$$Register, $str2$$Register, $cntImm$$constant,
11157                              $result$$Register, $tmp1$$Register, $tmp2$$Register);
11158   %}
11159   ins_pipe(pipe_class_compare);
11160 %}
11161 
11162 // String equals.
11163 // Use dst register classes if register gets killed, as it is the case for TEMP operands!
11164 instruct string_equals(iRegPsrc str1, iRegPsrc str2, iRegIsrc cnt, iRegIdst result,
11165                        iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3, iRegPdst tmp4, iRegPdst tmp5,
11166                        flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11167   match(Set result (StrEquals (Binary str1 str2) cnt));
11168   effect(TEMP result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11169          KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11170   predicate(SpecialStringEquals);  // See Matcher::match_rule_supported.
11171   ins_cost(300);
11172 
11173   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11174 
11175   format %{ "String Equals [0..$cnt]($str1),[0..$cnt]($str2) -> $result"
11176             " \t// KILL $cr0, $cr1, $cr6, $ctr, TEMP $result, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11177   ins_encode %{
11178     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11179     __ char_arrays_equals($str1$$Register, $str2$$Register, $cnt$$Register, $result$$Register,
11180                           $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
11181   %}
11182   ins_pipe(pipe_class_compare);
11183 %}
11184 
11185 // String compare.
11186 // Char[] pointers are passed in.
11187 // Use dst register classes if register gets killed, as it is the case for TEMP operands!
11188 instruct string_compare(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11189                         iRegPdst tmp, flagsRegCR0 cr0, regCTR ctr) %{
11190   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11191   effect(USE_KILL cnt1, USE_KILL cnt2, USE_KILL str1, USE_KILL str2, TEMP result, TEMP tmp, KILL cr0, KILL ctr);
11192   ins_cost(300);
11193 
11194   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11195 
11196   format %{ "String Compare $str1[0..$cnt1], $str2[0..$cnt2] -> $result"
11197             " \t// TEMP $tmp, $result KILLs $str1, $cnt1, $str2, $cnt2, $cr0, $ctr" %}
11198   ins_encode %{
11199     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11200     __ string_compare($str1$$Register, $str2$$Register, $cnt1$$Register, $cnt2$$Register,
11201                       $result$$Register, $tmp$$Register);
11202   %}
11203   ins_pipe(pipe_class_compare);
11204 %}
11205 
11206 //---------- Min/Max Instructions ---------------------------------------------
11207 
11208 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
11209   match(Set dst (MinI src1 src2));
11210   ins_cost(DEFAULT_COST*6);
11211 


   1 //
   2 // Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
   3 // Copyright 2012, 2015 SAP AG. All rights reserved.
   4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5 //
   6 // This code is free software; you can redistribute it and/or modify it
   7 // under the terms of the GNU General Public License version 2 only, as
   8 // published by the Free Software Foundation.
   9 //
  10 // This code is distributed in the hope that it will be useful, but WITHOUT
  11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13 // version 2 for more details (a copy is included in the LICENSE file that
  14 // accompanied this code).
  15 //
  16 // You should have received a copy of the GNU General Public License version
  17 // 2 along with this work; if not, write to the Free Software Foundation,
  18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19 //
  20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21 // or visit www.oracle.com if you need additional information or have any
  22 // questions.
  23 //


2681     assert(nodes->length() >= 1, "must have created at least 1 node");
2682     assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
2683   %}
2684 
2685   enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{
2686     // TODO: PPC port $archOpcode(ppc64Opcode_ld);
2687 
2688     MacroAssembler _masm(&cbuf);
2689     int toc_offset = 0;
2690 
2691     if (!ra_->C->in_scratch_emit_size()) {
2692       intptr_t val = $src$$constant;
2693       relocInfo::relocType constant_reloc = $src->constant_reloc();  // src
2694       address const_toc_addr;
2695       if (constant_reloc == relocInfo::oop_type) {
2696         // Create an oop constant and a corresponding relocation.
2697         AddressLiteral a = __ allocate_oop_address((jobject)val);
2698         const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2699         __ relocate(a.rspec());
2700       } else if (constant_reloc == relocInfo::metadata_type) {
2701         AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2702         const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2703         __ relocate(a.rspec());
2704       } else {
2705         // Create a non-oop constant, no relocation needed.
2706         const_toc_addr = __ long_constant((jlong)$src$$constant);
2707       }
2708 
2709       // Get the constant's TOC offset.
2710       toc_offset = __ offset_to_method_toc(const_toc_addr);
2711     }
2712 
2713     __ ld($dst$$Register, toc_offset, $toc$$Register);
2714   %}
2715 
2716   enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{
2717     // TODO: PPC port $archOpcode(ppc64Opcode_addis);
2718 
2719     MacroAssembler _masm(&cbuf);
2720     if (!ra_->C->in_scratch_emit_size()) {
2721       intptr_t val = $src$$constant;
2722       relocInfo::relocType constant_reloc = $src->constant_reloc();  // src
2723       address const_toc_addr;
2724       if (constant_reloc == relocInfo::oop_type) {
2725         // Create an oop constant and a corresponding relocation.
2726         AddressLiteral a = __ allocate_oop_address((jobject)val);
2727         const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2728         __ relocate(a.rspec());
2729       } else if (constant_reloc == relocInfo::metadata_type) {
2730         AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2731         const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2732         __ relocate(a.rspec());
2733       } else {  // non-oop pointers, e.g. card mark base, heap top
2734         // Create a non-oop constant, no relocation needed.
2735         const_toc_addr = __ long_constant((jlong)$src$$constant);
2736       }
2737 
2738       // Get the constant's TOC offset.
2739       const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2740       // Store the toc offset of the constant.
2741       ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset;
2742     }
2743 
2744     __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2745   %}
2746 
2747   // Postalloc expand emitter for loading a ptr constant from the method's TOC.
2748   // Enc_class needed as consttanttablebase is not supported by postalloc
2749   // expand.
2750   enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{


6012   ins_pipe(pipe_class_default);
6013 %}
6014 
6015 // Needed to postalloc expand loadConN: ConN is loaded as ConI
6016 // leaving the upper 32 bits with sign-extension bits.
6017 // This clears these bits: dst = src & 0xFFFFFFFF.
6018 // TODO: Eventually call this maskN_regN_FFFFFFFF.
6019 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{
6020   effect(DEF dst, USE src);
6021   predicate(false);
6022 
6023   format %{ "MASK    $dst, $src, 0xFFFFFFFF" %} // mask
6024   size(4);
6025   ins_encode %{
6026     // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6027     __ clrldi($dst$$Register, $src$$Register, 0x20);
6028   %}
6029   ins_pipe(pipe_class_default);
6030 %}
6031 
6032 // Optimize DecodeN for disjoint base.
6033 // Load base of compressed oops into a register
6034 instruct loadBase(iRegLdst dst) %{
6035   effect(DEF dst);
6036 
6037   format %{ "MR      $dst, r30_heapbase" %}
6038   size(4);
6039   ins_encode %{
6040     // TODO: PPC port $archOpcode(ppc64Opcode_or);
6041     __ mr($dst$$Register, R30);
6042   %}
6043   ins_pipe(pipe_class_default);
6044 %}
6045 
6046 // Loading ConN must be postalloc expanded so that edges between
6047 // the nodes are safe. They may not interfere with a safepoint.
6048 // GL TODO: This needs three instructions: better put this into the constant pool.
6049 instruct loadConN_Ex(iRegNdst dst, immN src) %{
6050   match(Set dst src);
6051   ins_cost(DEFAULT_COST*2);
6052 
6053   format %{ "LoadN   $dst, $src \t// postalloc expanded" %} // mask
6054   postalloc_expand %{
6055     MachNode *m1 = new loadConN_hiNode();
6056     MachNode *m2 = new loadConN_loNode();
6057     MachNode *m3 = new clearMs32bNode();
6058     m1->add_req(NULL);
6059     m2->add_req(NULL, m1);
6060     m3->add_req(NULL, m2);
6061     m1->_opnds[0] = op_dst;
6062     m1->_opnds[1] = op_src;
6063     m2->_opnds[0] = op_dst;
6064     m2->_opnds[1] = op_dst;
6065     m2->_opnds[2] = op_src;


6721   %}
6722   ins_pipe(pipe_class_default);
6723 %}
6724 
6725 // Power 7 can use isel instruction
6726 instruct cond_set_0_oop(iRegNdst dst, flagsReg crx, iRegPsrc src1) %{
6727   // The match rule is needed to make it a 'MachTypeNode'!
6728   match(Set dst (EncodeP (Binary crx src1)));
6729   predicate(false);
6730 
6731   format %{ "CMOVE   $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %}
6732   size(4);
6733   ins_encode %{
6734     // This is a Power7 instruction for which no machine description exists.
6735     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6736     __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6737   %}
6738   ins_pipe(pipe_class_default);
6739 %}
6740 
6741 // Disjoint narrow oop base.
6742 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{

6743   match(Set dst (EncodeP src));
6744   predicate(Universe::narrow_oop_base_disjoint());
6745 
6746   format %{ "EXTRDI  $dst, $src, #32, #3 \t// encode with disjoint base" %}
6747   size(4);
6748   ins_encode %{
6749     // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6750     __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32);
6751   %}
6752   ins_pipe(pipe_class_default);
6753 %}
6754 
6755 // shift != 0, base != 0
6756 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{
6757   match(Set dst (EncodeP src));
6758   effect(TEMP crx);
6759   predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull &&
6760             Universe::narrow_oop_shift() != 0 &&
6761             Universe::narrow_oop_base_overlaps());
6762 
6763   format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %}
6764   postalloc_expand( postalloc_expand_encode_oop(dst, src, crx));
6765 %}
6766 
6767 // shift != 0, base != 0
6768 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{
6769   match(Set dst (EncodeP src));
6770   predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull &&
6771             Universe::narrow_oop_shift() != 0 &&
6772             Universe::narrow_oop_base_overlaps());
6773 
6774   format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %}
6775   postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) );
6776 %}
6777 
6778 // shift != 0, base == 0
6779 // TODO: This is the same as encodeP_shift. Merge!
6780 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{
6781   match(Set dst (EncodeP src));
6782   predicate(Universe::narrow_oop_shift() != 0 &&
6783             Universe::narrow_oop_base() ==0);
6784 
6785   format %{ "SRDI    $dst, $src, #3 \t// encodeP, $src != NULL" %}
6786   size(4);
6787   ins_encode %{
6788     // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6789     __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f);
6790   %}
6791   ins_pipe(pipe_class_default);
6792 %}


6872   match(Set dst (DecodeN (Binary crx src1)));
6873   predicate(false);
6874 
6875   format %{ "CMOVE   $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %}
6876   size(4);
6877   ins_encode %{
6878     // This is a Power7 instruction for which no machine description exists.
6879     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6880     __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6881   %}
6882   ins_pipe(pipe_class_default);
6883 %}
6884 
6885 //  shift != 0, base != 0
6886 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6887   match(Set dst (DecodeN src));
6888   predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6889              n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6890             Universe::narrow_oop_shift() != 0 &&
6891             Universe::narrow_oop_base() != 0);
6892   ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex.
6893   effect(TEMP crx);
6894 
6895   format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %}
6896   postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) );
6897 %}
6898 
6899 // shift != 0, base == 0
6900 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{
6901   match(Set dst (DecodeN src));
6902   predicate(Universe::narrow_oop_shift() != 0 &&
6903             Universe::narrow_oop_base() == 0);
6904 
6905   format %{ "SLDI    $dst, $src, #3 \t// DecodeN (zerobased)" %}
6906   size(4);
6907   ins_encode %{
6908     // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
6909     __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift());
6910   %}
6911   ins_pipe(pipe_class_default);
6912 %}
6913 
6914 // Optimize DecodeN for disjoint base.
6915 // Shift narrow oop and or it into register that already contains the heap base.
6916 // Base == dst must hold, and is assured by construction in postaloc_expand.
6917 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{
6918   match(Set dst (DecodeN src));
6919   effect(TEMP base);
6920   predicate(false);
6921 
6922   format %{ "RLDIMI  $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %}
6923   size(4);
6924   ins_encode %{
6925     // TODO: PPC port $archOpcode(ppc64Opcode_rldimi);
6926     __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift());
6927   %}
6928   ins_pipe(pipe_class_default);
6929 %}
6930 
6931 // Optimize DecodeN for disjoint base.
6932 // This node requires only one cycle on the critical path.
6933 // We must postalloc_expand as we can not express use_def effects where
6934 // the used register is L and the def'ed register P.
6935 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{
6936   match(Set dst (DecodeN src));
6937   effect(TEMP_DEF dst);
6938   predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6939              n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6940             Universe::narrow_oop_base_disjoint());
6941   ins_cost(DEFAULT_COST);
6942 
6943   format %{ "MOV     $dst, R30 \t\n"
6944             "RLDIMI  $dst, $src, shift, 32-shift \t// decode with disjoint base" %}
6945   postalloc_expand %{
6946     loadBaseNode *n1 = new loadBaseNode();
6947     n1->add_req(NULL);
6948     n1->_opnds[0] = op_dst;
6949 
6950     decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6951     n2->add_req(n_region, n_src, n1);
6952     n2->_opnds[0] = op_dst;
6953     n2->_opnds[1] = op_src;
6954     n2->_opnds[2] = op_dst;
6955     n2->_bottom_type = _bottom_type;
6956 
6957     ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6958     ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6959 
6960     nodes->push(n1);
6961     nodes->push(n2);
6962   %}
6963 %}
6964 
6965 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6966   match(Set dst (DecodeN src));
6967   effect(TEMP_DEF dst, TEMP crx);
6968   predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6969              n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6970             Universe::narrow_oop_base_disjoint() && VM_Version::has_isel());
6971   ins_cost(3 * DEFAULT_COST);
6972 
6973   format %{ "DecodeN  $dst, $src \t// decode with disjoint base using isel" %}
6974   postalloc_expand %{
6975     loadBaseNode *n1 = new loadBaseNode();
6976     n1->add_req(NULL);
6977     n1->_opnds[0] = op_dst;
6978 
6979     cmpN_reg_imm0Node *n_compare  = new cmpN_reg_imm0Node();
6980     n_compare->add_req(n_region, n_src);
6981     n_compare->_opnds[0] = op_crx;
6982     n_compare->_opnds[1] = op_src;
6983     n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
6984     
6985     decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6986     n2->add_req(n_region, n_src, n1);
6987     n2->_opnds[0] = op_dst;
6988     n2->_opnds[1] = op_src;
6989     n2->_opnds[2] = op_dst;
6990     n2->_bottom_type = _bottom_type;
6991 
6992     cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
6993     n_cond_set->add_req(n_region, n_compare, n2);
6994     n_cond_set->_opnds[0] = op_dst;
6995     n_cond_set->_opnds[1] = op_crx;
6996     n_cond_set->_opnds[2] = op_dst;
6997     n_cond_set->_bottom_type = _bottom_type;
6998 
6999     assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
7000     ra_->set_oop(n_cond_set, true);
7001     
7002     ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7003     ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
7004     ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7005     ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
7006 
7007     nodes->push(n1);
7008     nodes->push(n_compare);
7009     nodes->push(n2);
7010     nodes->push(n_cond_set);
7011   %}
7012 %}
7013 
7014 // src != 0, shift != 0, base != 0
7015 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{
7016   match(Set dst (DecodeN src));
7017   predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
7018              n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
7019             Universe::narrow_oop_shift() != 0 &&
7020             Universe::narrow_oop_base() != 0);
7021   ins_cost(2 * DEFAULT_COST);
7022 
7023   format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %}
7024   postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src));
7025 %}
7026 
7027 // Compressed OOPs with narrow_oop_shift == 0.
7028 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{
7029   match(Set dst (DecodeN src));
7030   predicate(Universe::narrow_oop_shift() == 0);
7031   ins_cost(DEFAULT_COST);
7032 
7033   format %{ "MR      $dst, $src \t// DecodeN (unscaled)" %}
7034   // variable size, 0 or 4.
7035   ins_encode %{
7036     // TODO: PPC port $archOpcode(ppc64Opcode_or);
7037     __ mr_if_needed($dst$$Register, $src$$Register);
7038   %}
7039   ins_pipe(pipe_class_default);
7040 %}
7041 


7071     __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift());
7072   %}
7073   ins_pipe(pipe_class_default);
7074 %}
7075 
7076 // Add node for expand.
7077 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
7078   // The match rule is needed to make it a 'MachTypeNode'!
7079   match(Set dst (EncodePKlass (Binary base src)));
7080   predicate(false);
7081 
7082   format %{ "SUB     $dst, $base, $src \t// encode" %}
7083   size(4);
7084   ins_encode %{
7085     // TODO: PPC port $archOpcode(ppc64Opcode_subf);
7086     __ subf($dst$$Register, $base$$Register, $src$$Register);
7087   %}
7088   ins_pipe(pipe_class_default);
7089 %}
7090 
7091 // Disjoint narrow oop base.
7092 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{

7093   match(Set dst (EncodePKlass src));
7094   predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/);
7095 
7096   format %{ "EXTRDI  $dst, $src, #32, #3 \t// encode with disjoint base" %}
7097   size(4);
7098   ins_encode %{
7099     // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
7100     __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32);
7101   %}
7102   ins_pipe(pipe_class_default);
7103 %}
7104 
7105 // shift != 0, base != 0
7106 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{
7107   match(Set dst (EncodePKlass (Binary base src)));
7108   predicate(false);
7109 
7110   format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
7111   postalloc_expand %{
7112     encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode();
7113     n1->add_req(n_region, n_base, n_src);
7114     n1->_opnds[0] = op_dst;
7115     n1->_opnds[1] = op_base;
7116     n1->_opnds[2] = op_src;


7583   ins_pipe(pipe_class_default);
7584 %}
7585 
7586 //----------Conditional_store--------------------------------------------------
7587 // Conditional-store of the updated heap-top.
7588 // Used during allocation of the shared heap.
7589 // Sets flags (EQ) on success. Implemented with a CASA on Sparc.
7590 
7591 // As compareAndSwapL, but return flag register instead of boolean value in
7592 // int register.
7593 // Used by sun/misc/AtomicLongCSImpl.java.
7594 // Mem_ptr must be a memory operand, else this node does not get
7595 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node
7596 // can be rematerialized which leads to errors.
7597 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal) %{
7598   match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal)));
7599   format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %}
7600   ins_encode %{
7601     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7602     __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register,
7603                 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(),
7604                 noreg, NULL, true);
7605   %}
7606   ins_pipe(pipe_class_default);
7607 %}
7608 
7609 // As compareAndSwapP, but return flag register instead of boolean value in
7610 // int register.
7611 // This instruction is matched if UseTLAB is off.
7612 // Mem_ptr must be a memory operand, else this node does not get
7613 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node
7614 // can be rematerialized which leads to errors.
7615 instruct storePConditional_regP_regP_regP(flagsReg crx, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{
7616   match(Set crx (StorePConditional mem_ptr (Binary oldVal newVal)));
7617   format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %}
7618   ins_encode %{
7619     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7620     __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register,
7621                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7622                 noreg, NULL, true);
7623   %}


10573   size(4);
10574   ins_encode %{
10575     // TODO: PPC port $archOpcode(ppc64Opcode_tdi);
10576     if ($cmp$$cmpcode == 0xA) {
10577       __ trap_null_check($value$$Register);
10578     } else {
10579       // Both successors are uncommon traps, probability is 0.
10580       // Node got flipped during fixup flow.
10581       assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
10582       __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
10583     }
10584   %}
10585   ins_pipe(pipe_class_trap);
10586 %}
10587 
10588 // Compare narrow oops.
10589 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{
10590   match(Set crx (CmpN src1 src2));
10591 
10592   size(4);
10593   ins_cost(2);
10594   format %{ "CMPLW   $crx, $src1, $src2 \t// compressed ptr" %}
10595   ins_encode %{
10596     // TODO: PPC port $archOpcode(ppc64Opcode_cmpl);
10597     __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
10598   %}
10599   ins_pipe(pipe_class_compare);
10600 %}
10601 
10602 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{
10603   match(Set crx (CmpN src1 src2));
10604   // Make this more expensive than zeroCheckN_iReg_imm0.
10605   ins_cost(2);
10606 
10607   format %{ "CMPLWI  $crx, $src1, $src2 \t// compressed ptr" %}
10608   size(4);
10609   ins_encode %{
10610     // TODO: PPC port $archOpcode(ppc64Opcode_cmpli);
10611     __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10612   %}
10613   ins_pipe(pipe_class_compare);
10614 %}
10615 
10616 // Implicit zero checks (more implicit null checks).
10617 // No constant pool entries required.
10618 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{
10619   match(If cmp (CmpP value zero));
10620   effect(USE labl);
10621   predicate(TrapBasedNullChecks &&
10622             _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
10623             _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
10624             Matcher::branches_to_uncommon_trap(_leaf));
10625   ins_cost(1); // Should not be cheaper than zeroCheckN.
10626 
10627   ins_is_TrapBasedCheckNode(true);
10628 
10629   format %{ "TDI     $value $cmp $zero \t// ZeroCheckP => trap $labl" %}
10630   size(4);
10631   ins_encode %{
10632     // TODO: PPC port $archOpcode(ppc64Opcode_tdi);
10633     if ($cmp$$cmpcode == 0xA) {
10634       __ trap_null_check($value$$Register);
10635     } else {
10636       // Both successors are uncommon traps, probability is 0.
10637       // Node got flipped during fixup flow.
10638       assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
10639       __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
10640     }
10641   %}
10642   ins_pipe(pipe_class_trap);
10643 %}
10644 
10645 // Compare Pointers


10987   format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
10988   size(8); // worst case
10989   ins_encode( enc_bc_short_far(crx, cmp, labl) );
10990   ins_pipe(pipe_class_default);
10991 %}
10992 
10993 // ============================================================================
10994 // Java runtime operations, intrinsics and other complex operations.
10995 
10996 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
10997 // array for an instance of the superklass. Set a hidden internal cache on a
10998 // hit (cache is checked with exposed code in gen_subtype_check()). Return
10999 // not zero for a miss or zero for a hit. The encoding ALSO sets flags.
11000 //
11001 // GL TODO: Improve this.
11002 // - result should not be a TEMP
11003 // - Add match rule as on sparc avoiding additional Cmp.
11004 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass,
11005                              iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{
11006   match(Set result (PartialSubtypeCheck subklass superklass));
11007   effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr);
11008   ins_cost(DEFAULT_COST*10);
11009 
11010   format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
11011   ins_encode %{
11012     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11013     __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register,
11014                                      $tmp_klass$$Register, NULL, $result$$Register);
11015   %}
11016   ins_pipe(pipe_class_default);
11017 %}
11018 
11019 // inlined locking and unlocking
11020 
11021 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
11022   match(Set crx (FastLock oop box));
11023   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
11024   // TODO PPC port predicate(!UseNewFastLockPPC64 || UseBiasedLocking);
11025 
11026   format %{ "FASTLOCK  $oop, $box, $tmp1, $tmp2, $tmp3" %}
11027   ins_encode %{


11098 // Match needle into immediate operands: no loadConP node needed. Saves one
11099 // register and two instructions over string_indexOf_imm1Node.
11100 //
11101 // Assumes register result differs from all input registers.
11102 //
11103 // Preserves registers haystack, haycnt
11104 // Kills     registers tmp1, tmp2
11105 // Defines   registers result
11106 //
11107 // Use dst register classes if register gets killed, as it is the case for tmp registers!
11108 //
11109 // Unfortunately this does not match too often. In many situations the AddP is used
11110 // by several nodes, even several StrIndexOf nodes, breaking the match tree.
11111 instruct string_indexOf_imm1_char(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11112                                   immP needleImm, immL offsetImm, immI_1 needlecntImm,
11113                                   iRegIdst tmp1, iRegIdst tmp2,
11114                                   flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11115   predicate(SpecialStringIndexOf);  // type check implicit by parameter type, See Matcher::match_rule_supported
11116   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11117 
11118   effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1);
11119 
11120   ins_cost(150);
11121   format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11122             "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11123 
11124   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted
11125   ins_encode %{
11126     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11127     immPOper *needleOper = (immPOper *)$needleImm;
11128     const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11129     ciTypeArray* needle_values = t->const_oop()->as_type_array();  // Pointer to live char *
11130 
11131     __ string_indexof_1($result$$Register,
11132                         $haystack$$Register, $haycnt$$Register,
11133                         R0, needle_values->char_at(0),
11134                         $tmp1$$Register, $tmp2$$Register);
11135   %}
11136   ins_pipe(pipe_class_compare);
11137 %}
11138 
11139 // String_IndexOf for needle of length 1.
11140 //
11141 // Special case requires less registers and emits less instructions.
11142 //
11143 // Assumes register result differs from all input registers.
11144 //
11145 // Preserves registers haystack, haycnt
11146 // Kills     registers tmp1, tmp2, needle
11147 // Defines   registers result
11148 //
11149 // Use dst register classes if register gets killed, as it is the case for tmp registers!
11150 instruct string_indexOf_imm1(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11151                              rscratch2RegP needle, immI_1 needlecntImm,
11152                              iRegIdst tmp1, iRegIdst tmp2,
11153                              flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11154   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11155   effect(USE_KILL needle, /* TDEF needle, */ TEMP_DEF result,
11156          TEMP tmp1, TEMP tmp2);
11157   // Required for EA: check if it is still a type_array.
11158   predicate(SpecialStringIndexOf && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11159             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11160   ins_cost(180);
11161 
11162   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11163 
11164   format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11165             " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11166   ins_encode %{
11167     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11168     Node *ndl = in(operand_index($needle));  // The node that defines needle.
11169     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11170     guarantee(needle_values, "sanity");
11171     if (needle_values != NULL) {
11172       __ string_indexof_1($result$$Register,
11173                           $haystack$$Register, $haycnt$$Register,
11174                           R0, needle_values->char_at(0),
11175                           $tmp1$$Register, $tmp2$$Register);


11182   %}
11183   ins_pipe(pipe_class_compare);
11184 %}
11185 
11186 // String_IndexOf.
11187 //
11188 // Length of needle as immediate. This saves instruction loading constant needle
11189 // length.
11190 // @@@ TODO Specify rules for length < 8 or so, and roll out comparison of needle
11191 // completely or do it in vector instruction. This should save registers for
11192 // needlecnt and needle.
11193 //
11194 // Assumes register result differs from all input registers.
11195 // Overwrites haycnt, needlecnt.
11196 // Use dst register classes if register gets killed, as it is the case for tmp registers!
11197 instruct string_indexOf_imm(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11198                             iRegPsrc needle, uimmI15 needlecntImm,
11199                             iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11200                             flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6) %{
11201   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11202   effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11203          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6);
11204   // Required for EA: check if it is still a type_array.
11205   predicate(SpecialStringIndexOf && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11206             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11207   ins_cost(250);
11208 
11209   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11210 
11211   format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11212             " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11213   ins_encode %{
11214     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11215     Node *ndl = in(operand_index($needle));  // The node that defines needle.
11216     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11217 
11218     __ string_indexof($result$$Register,
11219                       $haystack$$Register, $haycnt$$Register,
11220                       $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11221                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register);
11222   %}
11223   ins_pipe(pipe_class_compare);
11224 %}
11225 
11226 // StrIndexOf node.
11227 //
11228 // Assumes register result differs from all input registers.
11229 // Overwrites haycnt, needlecnt.
11230 // Use dst register classes if register gets killed, as it is the case for tmp registers!
11231 instruct string_indexOf(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11232                         iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11233                         flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6) %{
11234   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11235   effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11236          TEMP_DEF result,
11237          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6);
11238   predicate(SpecialStringIndexOf);  // See Matcher::match_rule_supported.
11239   ins_cost(300);
11240 
11241   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11242 
11243   format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11244              " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11245   ins_encode %{
11246     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11247     __ string_indexof($result$$Register,
11248                       $haystack$$Register, $haycnt$$Register,
11249                       $needle$$Register, NULL, $needlecnt$$Register, 0,  // needlecnt not constant.
11250                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register);
11251   %}
11252   ins_pipe(pipe_class_compare);
11253 %}
11254 
11255 // String equals with immediate.
11256 instruct string_equals_imm(iRegPsrc str1, iRegPsrc str2, uimmI15 cntImm, iRegIdst result,
11257                            iRegPdst tmp1, iRegPdst tmp2,
11258                            flagsRegCR0 cr0, flagsRegCR6 cr6, regCTR ctr) %{
11259   match(Set result (StrEquals (Binary str1 str2) cntImm));
11260   effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2,
11261          KILL cr0, KILL cr6, KILL ctr);
11262   predicate(SpecialStringEquals);  // See Matcher::match_rule_supported.
11263   ins_cost(250);
11264 
11265   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11266 
11267   format %{ "String Equals SCL [0..$cntImm]($str1),[0..$cntImm]($str2)"
11268             " -> $result \t// KILL $cr0, $cr6, $ctr, TEMP $result, $tmp1, $tmp2" %}
11269   ins_encode %{
11270     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11271     __ char_arrays_equalsImm($str1$$Register, $str2$$Register, $cntImm$$constant,
11272                              $result$$Register, $tmp1$$Register, $tmp2$$Register);
11273   %}
11274   ins_pipe(pipe_class_compare);
11275 %}
11276 
11277 // String equals.
11278 // Use dst register classes if register gets killed, as it is the case for TEMP operands!
11279 instruct string_equals(iRegPsrc str1, iRegPsrc str2, iRegIsrc cnt, iRegIdst result,
11280                        iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3, iRegPdst tmp4, iRegPdst tmp5,
11281                        flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11282   match(Set result (StrEquals (Binary str1 str2) cnt));
11283   effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11284          KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11285   predicate(SpecialStringEquals);  // See Matcher::match_rule_supported.
11286   ins_cost(300);
11287 
11288   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11289 
11290   format %{ "String Equals [0..$cnt]($str1),[0..$cnt]($str2) -> $result"
11291             " \t// KILL $cr0, $cr1, $cr6, $ctr, TEMP $result, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11292   ins_encode %{
11293     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11294     __ char_arrays_equals($str1$$Register, $str2$$Register, $cnt$$Register, $result$$Register,
11295                           $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
11296   %}
11297   ins_pipe(pipe_class_compare);
11298 %}
11299 
11300 // String compare.
11301 // Char[] pointers are passed in.
11302 // Use dst register classes if register gets killed, as it is the case for TEMP operands!
11303 instruct string_compare(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11304                         iRegPdst tmp, flagsRegCR0 cr0, regCTR ctr) %{
11305   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11306   effect(USE_KILL cnt1, USE_KILL cnt2, USE_KILL str1, USE_KILL str2, TEMP_DEF result, TEMP tmp, KILL cr0, KILL ctr);
11307   ins_cost(300);
11308 
11309   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11310 
11311   format %{ "String Compare $str1[0..$cnt1], $str2[0..$cnt2] -> $result"
11312             " \t// TEMP $tmp, $result KILLs $str1, $cnt1, $str2, $cnt2, $cr0, $ctr" %}
11313   ins_encode %{
11314     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11315     __ string_compare($str1$$Register, $str2$$Register, $cnt1$$Register, $cnt2$$Register,
11316                       $result$$Register, $tmp$$Register);
11317   %}
11318   ins_pipe(pipe_class_compare);
11319 %}
11320 
11321 //---------- Min/Max Instructions ---------------------------------------------
11322 
11323 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
11324   match(Set dst (MinI src1 src2));
11325   ins_cost(DEFAULT_COST*6);
11326 


< prev index next >