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
|