comparison src/cpu/x86/vm/x86_64.ad @ 986:62001a362ce9

6827605: new String intrinsics may prevent EA scalar replacement 6875866: Intrinsic for String.indexOf() is broken on x86 with SSE4.2 Summary: Modify String intrinsic methods to pass char[] pointers instead of string oops. Reviewed-by: never
author kvn
date Mon, 14 Sep 2009 12:14:20 -0700
parents 18a08a7e16b5
children 148e5441d916
comparison
equal deleted inserted replaced
985:685e959d09ea 986:62001a362ce9
3699 masm.nop(); // avoid branch to branch 3699 masm.nop(); // avoid branch to branch
3700 } 3700 }
3701 } 3701 }
3702 %} 3702 %}
3703 3703
3704 enc_class enc_String_Compare(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2,
3705 rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result) %{
3706 Label RCX_GOOD_LABEL, LENGTH_DIFF_LABEL,
3707 POP_LABEL, DONE_LABEL, CONT_LABEL,
3708 WHILE_HEAD_LABEL;
3709 MacroAssembler masm(&cbuf);
3710
3711 XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);
3712 XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg);
3713
3714 // Get the first character position in both strings
3715 // [8] char array, [12] offset, [16] count
3716 int value_offset = java_lang_String::value_offset_in_bytes();
3717 int offset_offset = java_lang_String::offset_offset_in_bytes();
3718 int count_offset = java_lang_String::count_offset_in_bytes();
3719 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
3720
3721 masm.load_heap_oop(rax, Address(rsi, value_offset));
3722 masm.movl(rcx, Address(rsi, offset_offset));
3723 masm.lea(rax, Address(rax, rcx, Address::times_2, base_offset));
3724 masm.load_heap_oop(rbx, Address(rdi, value_offset));
3725 masm.movl(rcx, Address(rdi, offset_offset));
3726 masm.lea(rbx, Address(rbx, rcx, Address::times_2, base_offset));
3727
3728 // Compute the minimum of the string lengths(rsi) and the
3729 // difference of the string lengths (stack)
3730
3731 // do the conditional move stuff
3732 masm.movl(rdi, Address(rdi, count_offset));
3733 masm.movl(rsi, Address(rsi, count_offset));
3734 masm.movl(rcx, rdi);
3735 masm.subl(rdi, rsi);
3736 masm.push(rdi);
3737 masm.cmov(Assembler::lessEqual, rsi, rcx);
3738
3739 // Is the minimum length zero?
3740 masm.bind(RCX_GOOD_LABEL);
3741 masm.testl(rsi, rsi);
3742 masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
3743
3744 // Load first characters
3745 masm.load_unsigned_short(rcx, Address(rbx, 0));
3746 masm.load_unsigned_short(rdi, Address(rax, 0));
3747
3748 // Compare first characters
3749 masm.subl(rcx, rdi);
3750 masm.jcc(Assembler::notZero, POP_LABEL);
3751 masm.decrementl(rsi);
3752 masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
3753
3754 {
3755 // Check after comparing first character to see if strings are equivalent
3756 Label LSkip2;
3757 // Check if the strings start at same location
3758 masm.cmpptr(rbx, rax);
3759 masm.jccb(Assembler::notEqual, LSkip2);
3760
3761 // Check if the length difference is zero (from stack)
3762 masm.cmpl(Address(rsp, 0), 0x0);
3763 masm.jcc(Assembler::equal, LENGTH_DIFF_LABEL);
3764
3765 // Strings might not be equivalent
3766 masm.bind(LSkip2);
3767 }
3768
3769 // Advance to next character
3770 masm.addptr(rax, 2);
3771 masm.addptr(rbx, 2);
3772
3773 if (UseSSE42Intrinsics) {
3774 // With SSE4.2, use double quad vector compare
3775 Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL;
3776 // Setup to compare 16-byte vectors
3777 masm.movl(rdi, rsi);
3778 masm.andl(rsi, 0xfffffff8); // rsi holds the vector count
3779 masm.andl(rdi, 0x00000007); // rdi holds the tail count
3780 masm.testl(rsi, rsi);
3781 masm.jccb(Assembler::zero, COMPARE_TAIL);
3782
3783 masm.lea(rax, Address(rax, rsi, Address::times_2));
3784 masm.lea(rbx, Address(rbx, rsi, Address::times_2));
3785 masm.negptr(rsi);
3786
3787 masm.bind(COMPARE_VECTORS);
3788 masm.movdqu(tmp1Reg, Address(rax, rsi, Address::times_2));
3789 masm.movdqu(tmp2Reg, Address(rbx, rsi, Address::times_2));
3790 masm.pxor(tmp1Reg, tmp2Reg);
3791 masm.ptest(tmp1Reg, tmp1Reg);
3792 masm.jccb(Assembler::notZero, VECTOR_NOT_EQUAL);
3793 masm.addptr(rsi, 8);
3794 masm.jcc(Assembler::notZero, COMPARE_VECTORS);
3795 masm.jmpb(COMPARE_TAIL);
3796
3797 // Mismatched characters in the vectors
3798 masm.bind(VECTOR_NOT_EQUAL);
3799 masm.lea(rax, Address(rax, rsi, Address::times_2));
3800 masm.lea(rbx, Address(rbx, rsi, Address::times_2));
3801 masm.movl(rdi, 8);
3802
3803 // Compare tail (< 8 chars), or rescan last vectors to
3804 // find 1st mismatched characters
3805 masm.bind(COMPARE_TAIL);
3806 masm.testl(rdi, rdi);
3807 masm.jccb(Assembler::zero, LENGTH_DIFF_LABEL);
3808 masm.movl(rsi, rdi);
3809 // Fallthru to tail compare
3810 }
3811
3812 // Shift RAX and RBX to the end of the arrays, negate min
3813 masm.lea(rax, Address(rax, rsi, Address::times_2, 0));
3814 masm.lea(rbx, Address(rbx, rsi, Address::times_2, 0));
3815 masm.negptr(rsi);
3816
3817 // Compare the rest of the characters
3818 masm.bind(WHILE_HEAD_LABEL);
3819 masm.load_unsigned_short(rcx, Address(rbx, rsi, Address::times_2, 0));
3820 masm.load_unsigned_short(rdi, Address(rax, rsi, Address::times_2, 0));
3821 masm.subl(rcx, rdi);
3822 masm.jccb(Assembler::notZero, POP_LABEL);
3823 masm.increment(rsi);
3824 masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL);
3825
3826 // Strings are equal up to min length. Return the length difference.
3827 masm.bind(LENGTH_DIFF_LABEL);
3828 masm.pop(rcx);
3829 masm.jmpb(DONE_LABEL);
3830
3831 // Discard the stored length difference
3832 masm.bind(POP_LABEL);
3833 masm.addptr(rsp, 8);
3834
3835 // That's it
3836 masm.bind(DONE_LABEL);
3837 %}
3838
3839 enc_class enc_String_IndexOf(rsi_RegP str1, rdi_RegP str2, regD tmp1, rax_RegI tmp2,
3840 rcx_RegI tmp3, rdx_RegI tmp4, rbx_RegI result) %{
3841 // SSE4.2 version
3842 Label LOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR,
3843 SCAN_SUBSTR, RET_NEG_ONE, RET_NOT_FOUND, CLEANUP, DONE;
3844 MacroAssembler masm(&cbuf);
3845
3846 XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);
3847
3848 // Get the first character position in both strings
3849 // [8] char array, [12] offset, [16] count
3850 int value_offset = java_lang_String::value_offset_in_bytes();
3851 int offset_offset = java_lang_String::offset_offset_in_bytes();
3852 int count_offset = java_lang_String::count_offset_in_bytes();
3853 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
3854
3855 // Get counts for string and substr
3856 masm.movl(rdx, Address(rsi, count_offset));
3857 masm.movl(rax, Address(rdi, count_offset));
3858 // Check for substr count > string count
3859 masm.cmpl(rax, rdx);
3860 masm.jcc(Assembler::greater, RET_NEG_ONE);
3861
3862 // Start the indexOf operation
3863 // Get start addr of string
3864 masm.load_heap_oop(rbx, Address(rsi, value_offset));
3865 masm.movl(rcx, Address(rsi, offset_offset));
3866 masm.lea(rsi, Address(rbx, rcx, Address::times_2, base_offset));
3867 masm.push(rsi);
3868
3869 // Get start addr of substr
3870 masm.load_heap_oop(rbx, Address(rdi, value_offset));
3871 masm.movl(rcx, Address(rdi, offset_offset));
3872 masm.lea(rdi, Address(rbx, rcx, Address::times_2, base_offset));
3873 masm.push(rdi);
3874 masm.push(rax);
3875 masm.jmpb(PREP_FOR_SCAN);
3876
3877 // Substr count saved at sp
3878 // Substr saved at sp+8
3879 // String saved at sp+16
3880
3881 // Prep to load substr for scan
3882 masm.bind(LOAD_SUBSTR);
3883 masm.movptr(rdi, Address(rsp, 8));
3884 masm.movl(rax, Address(rsp, 0));
3885
3886 // Load substr
3887 masm.bind(PREP_FOR_SCAN);
3888 masm.movdqu(tmp1Reg, Address(rdi, 0));
3889 masm.addq(rdx, 8); // prime the loop
3890 masm.subptr(rsi, 16);
3891
3892 // Scan string for substr in 16-byte vectors
3893 masm.bind(SCAN_TO_SUBSTR);
3894 masm.subq(rdx, 8);
3895 masm.addptr(rsi, 16);
3896 masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
3897 masm.jcc(Assembler::above, SCAN_TO_SUBSTR);
3898 masm.jccb(Assembler::aboveEqual, RET_NOT_FOUND);
3899
3900 // Fallthru: found a potential substr
3901
3902 //Make sure string is still long enough
3903 masm.subl(rdx, rcx);
3904 masm.cmpl(rdx, rax);
3905 masm.jccb(Assembler::negative, RET_NOT_FOUND);
3906 // Compute start addr of substr
3907 masm.lea(rsi, Address(rsi, rcx, Address::times_2));
3908 masm.movptr(rbx, rsi);
3909
3910 // Compare potential substr
3911 masm.addq(rdx, 8); // prime the loop
3912 masm.addq(rax, 8);
3913 masm.subptr(rsi, 16);
3914 masm.subptr(rdi, 16);
3915
3916 // Scan 16-byte vectors of string and substr
3917 masm.bind(SCAN_SUBSTR);
3918 masm.subq(rax, 8);
3919 masm.subq(rdx, 8);
3920 masm.addptr(rsi, 16);
3921 masm.addptr(rdi, 16);
3922 masm.movdqu(tmp1Reg, Address(rdi, 0));
3923 masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
3924 masm.jcc(Assembler::noOverflow, LOAD_SUBSTR); // OF == 0
3925 masm.jcc(Assembler::positive, SCAN_SUBSTR); // SF == 0
3926
3927 // Compute substr offset
3928 masm.movptr(rsi, Address(rsp, 16));
3929 masm.subptr(rbx, rsi);
3930 masm.shrl(rbx, 1);
3931 masm.jmpb(CLEANUP);
3932
3933 masm.bind(RET_NEG_ONE);
3934 masm.movl(rbx, -1);
3935 masm.jmpb(DONE);
3936
3937 masm.bind(RET_NOT_FOUND);
3938 masm.movl(rbx, -1);
3939
3940 masm.bind(CLEANUP);
3941 masm.addptr(rsp, 24);
3942
3943 masm.bind(DONE);
3944 %}
3945
3946 enc_class enc_String_Equals(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2,
3947 rbx_RegI tmp3, rcx_RegI tmp2, rax_RegI result) %{
3948 Label RET_TRUE, RET_FALSE, DONE, COMPARE_VECTORS, COMPARE_CHAR;
3949 MacroAssembler masm(&cbuf);
3950
3951 XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);
3952 XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg);
3953
3954 int value_offset = java_lang_String::value_offset_in_bytes();
3955 int offset_offset = java_lang_String::offset_offset_in_bytes();
3956 int count_offset = java_lang_String::count_offset_in_bytes();
3957 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
3958
3959 // does source == target string?
3960 masm.cmpptr(rdi, rsi);
3961 masm.jcc(Assembler::equal, RET_TRUE);
3962
3963 // get and compare counts
3964 masm.movl(rcx, Address(rdi, count_offset));
3965 masm.movl(rax, Address(rsi, count_offset));
3966 masm.cmpl(rcx, rax);
3967 masm.jcc(Assembler::notEqual, RET_FALSE);
3968 masm.testl(rax, rax);
3969 masm.jcc(Assembler::zero, RET_TRUE);
3970
3971 // get source string offset and value
3972 masm.load_heap_oop(rbx, Address(rsi, value_offset));
3973 masm.movl(rax, Address(rsi, offset_offset));
3974 masm.lea(rsi, Address(rbx, rax, Address::times_2, base_offset));
3975
3976 // get compare string offset and value
3977 masm.load_heap_oop(rbx, Address(rdi, value_offset));
3978 masm.movl(rax, Address(rdi, offset_offset));
3979 masm.lea(rdi, Address(rbx, rax, Address::times_2, base_offset));
3980
3981 // Set byte count
3982 masm.shll(rcx, 1);
3983 masm.movl(rax, rcx);
3984
3985 if (UseSSE42Intrinsics) {
3986 // With SSE4.2, use double quad vector compare
3987 Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
3988 // Compare 16-byte vectors
3989 masm.andl(rcx, 0xfffffff0); // vector count (in bytes)
3990 masm.andl(rax, 0x0000000e); // tail count (in bytes)
3991 masm.testl(rcx, rcx);
3992 masm.jccb(Assembler::zero, COMPARE_TAIL);
3993 masm.lea(rdi, Address(rdi, rcx, Address::times_1));
3994 masm.lea(rsi, Address(rsi, rcx, Address::times_1));
3995 masm.negptr(rcx);
3996
3997 masm.bind(COMPARE_WIDE_VECTORS);
3998 masm.movdqu(tmp1Reg, Address(rdi, rcx, Address::times_1));
3999 masm.movdqu(tmp2Reg, Address(rsi, rcx, Address::times_1));
4000 masm.pxor(tmp1Reg, tmp2Reg);
4001 masm.ptest(tmp1Reg, tmp1Reg);
4002 masm.jccb(Assembler::notZero, RET_FALSE);
4003 masm.addptr(rcx, 16);
4004 masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
4005 masm.bind(COMPARE_TAIL);
4006 masm.movl(rcx, rax);
4007 // Fallthru to tail compare
4008 }
4009
4010 // Compare 4-byte vectors
4011 masm.andl(rcx, 0xfffffffc); // vector count (in bytes)
4012 masm.andl(rax, 0x00000002); // tail char (in bytes)
4013 masm.testl(rcx, rcx);
4014 masm.jccb(Assembler::zero, COMPARE_CHAR);
4015 masm.lea(rdi, Address(rdi, rcx, Address::times_1));
4016 masm.lea(rsi, Address(rsi, rcx, Address::times_1));
4017 masm.negptr(rcx);
4018
4019 masm.bind(COMPARE_VECTORS);
4020 masm.movl(rbx, Address(rdi, rcx, Address::times_1));
4021 masm.cmpl(rbx, Address(rsi, rcx, Address::times_1));
4022 masm.jccb(Assembler::notEqual, RET_FALSE);
4023 masm.addptr(rcx, 4);
4024 masm.jcc(Assembler::notZero, COMPARE_VECTORS);
4025
4026 // Compare trailing char (final 2 bytes), if any
4027 masm.bind(COMPARE_CHAR);
4028 masm.testl(rax, rax);
4029 masm.jccb(Assembler::zero, RET_TRUE);
4030 masm.load_unsigned_short(rbx, Address(rdi, 0));
4031 masm.load_unsigned_short(rcx, Address(rsi, 0));
4032 masm.cmpl(rbx, rcx);
4033 masm.jccb(Assembler::notEqual, RET_FALSE);
4034
4035 masm.bind(RET_TRUE);
4036 masm.movl(rax, 1); // return true
4037 masm.jmpb(DONE);
4038
4039 masm.bind(RET_FALSE);
4040 masm.xorl(rax, rax); // return false
4041
4042 masm.bind(DONE);
4043 %}
4044
4045 enc_class enc_Array_Equals(rdi_RegP ary1, rsi_RegP ary2, regD tmp1, regD tmp2,
4046 rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result) %{
4047 Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;
4048 MacroAssembler masm(&cbuf);
4049
4050 XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);
4051 XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg);
4052 Register ary1Reg = as_Register($ary1$$reg);
4053 Register ary2Reg = as_Register($ary2$$reg);
4054 Register tmp3Reg = as_Register($tmp3$$reg);
4055 Register tmp4Reg = as_Register($tmp4$$reg);
4056 Register resultReg = as_Register($result$$reg);
4057
4058 int length_offset = arrayOopDesc::length_offset_in_bytes();
4059 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
4060
4061 // Check the input args
4062 masm.cmpq(ary1Reg, ary2Reg);
4063 masm.jcc(Assembler::equal, TRUE_LABEL);
4064 masm.testq(ary1Reg, ary1Reg);
4065 masm.jcc(Assembler::zero, FALSE_LABEL);
4066 masm.testq(ary2Reg, ary2Reg);
4067 masm.jcc(Assembler::zero, FALSE_LABEL);
4068
4069 // Check the lengths
4070 masm.movl(tmp4Reg, Address(ary1Reg, length_offset));
4071 masm.movl(resultReg, Address(ary2Reg, length_offset));
4072 masm.cmpl(tmp4Reg, resultReg);
4073 masm.jcc(Assembler::notEqual, FALSE_LABEL);
4074 masm.testl(resultReg, resultReg);
4075 masm.jcc(Assembler::zero, TRUE_LABEL);
4076
4077 //load array address
4078 masm.lea(ary1Reg, Address(ary1Reg, base_offset));
4079 masm.lea(ary2Reg, Address(ary2Reg, base_offset));
4080
4081 //set byte count
4082 masm.shll(tmp4Reg, 1);
4083 masm.movl(resultReg,tmp4Reg);
4084
4085 if (UseSSE42Intrinsics){
4086 // With SSE4.2, use double quad vector compare
4087 Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
4088 // Compare 16-byte vectors
4089 masm.andl(tmp4Reg, 0xfffffff0); // vector count (in bytes)
4090 masm.andl(resultReg, 0x0000000e); // tail count (in bytes)
4091 masm.testl(tmp4Reg, tmp4Reg);
4092 masm.jccb(Assembler::zero, COMPARE_TAIL);
4093 masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
4094 masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
4095 masm.negptr(tmp4Reg);
4096
4097 masm.bind(COMPARE_WIDE_VECTORS);
4098 masm.movdqu(tmp1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
4099 masm.movdqu(tmp2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
4100 masm.pxor(tmp1Reg, tmp2Reg);
4101 masm.ptest(tmp1Reg, tmp1Reg);
4102
4103 masm.jccb(Assembler::notZero, FALSE_LABEL);
4104 masm.addptr(tmp4Reg, 16);
4105 masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
4106 masm.bind(COMPARE_TAIL);
4107 masm.movl(tmp4Reg, resultReg);
4108 // Fallthru to tail compare
4109 }
4110
4111 // Compare 4-byte vectors
4112 masm.andl(tmp4Reg, 0xfffffffc); // vector count (in bytes)
4113 masm.andl(resultReg, 0x00000002); // tail char (in bytes)
4114 masm.testl(tmp4Reg, tmp4Reg); //if tmp2 == 0, only compare char
4115 masm.jccb(Assembler::zero, COMPARE_CHAR);
4116 masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
4117 masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
4118 masm.negptr(tmp4Reg);
4119
4120 masm.bind(COMPARE_VECTORS);
4121 masm.movl(tmp3Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
4122 masm.cmpl(tmp3Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
4123 masm.jccb(Assembler::notEqual, FALSE_LABEL);
4124 masm.addptr(tmp4Reg, 4);
4125 masm.jcc(Assembler::notZero, COMPARE_VECTORS);
4126
4127 // Compare trailing char (final 2 bytes), if any
4128 masm.bind(COMPARE_CHAR);
4129 masm.testl(resultReg, resultReg);
4130 masm.jccb(Assembler::zero, TRUE_LABEL);
4131 masm.load_unsigned_short(tmp3Reg, Address(ary1Reg, 0));
4132 masm.load_unsigned_short(tmp4Reg, Address(ary2Reg, 0));
4133 masm.cmpl(tmp3Reg, tmp4Reg);
4134 masm.jccb(Assembler::notEqual, FALSE_LABEL);
4135
4136 masm.bind(TRUE_LABEL);
4137 masm.movl(resultReg, 1); // return true
4138 masm.jmpb(DONE);
4139
4140 masm.bind(FALSE_LABEL);
4141 masm.xorl(resultReg, resultReg); // return false
4142
4143 // That's it
4144 masm.bind(DONE);
4145 %}
4146 3704
4147 enc_class enc_rethrow() 3705 enc_class enc_rethrow()
4148 %{ 3706 %{
4149 cbuf.set_inst_mark(); 3707 cbuf.set_inst_mark();
4150 emit_opcode(cbuf, 0xE9); // jmp entry 3708 emit_opcode(cbuf, 0xE9); // jmp entry
12094 ins_encode(opc_reg_reg(0x33, RAX, RAX), // xorl %eax, %eax 11652 ins_encode(opc_reg_reg(0x33, RAX, RAX), // xorl %eax, %eax
12095 Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos 11653 Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos
12096 ins_pipe(pipe_slow); 11654 ins_pipe(pipe_slow);
12097 %} 11655 %}
12098 11656
12099 instruct string_compare(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2, 11657 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rbx_RegI cnt2,
12100 rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result, rFlagsReg cr) 11658 rax_RegI result, regD tmp1, regD tmp2, rFlagsReg cr)
12101 %{ 11659 %{
12102 match(Set result (StrComp str1 str2)); 11660 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
12103 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr); 11661 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
12104 //ins_cost(300); 11662
12105 11663 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1, $tmp2" %}
12106 format %{ "String Compare $str1, $str2 -> $result // XXX KILL RAX, RBX" %} 11664 ins_encode %{
12107 ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, tmp3, tmp4, result) ); 11665 __ string_compare($str1$$Register, $str2$$Register,
11666 $cnt1$$Register, $cnt2$$Register, $result$$Register,
11667 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
11668 %}
12108 ins_pipe( pipe_slow ); 11669 ins_pipe( pipe_slow );
12109 %} 11670 %}
12110 11671
12111 instruct string_indexof(rsi_RegP str1, rdi_RegP str2, regD tmp1, rax_RegI tmp2, 11672 instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
12112 rcx_RegI tmp3, rdx_RegI tmp4, rbx_RegI result, rFlagsReg cr) 11673 rbx_RegI result, regD tmp1, rcx_RegI tmp2, rFlagsReg cr)
12113 %{ 11674 %{
12114 predicate(UseSSE42Intrinsics); 11675 predicate(UseSSE42Intrinsics);
12115 match(Set result (StrIndexOf str1 str2)); 11676 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
12116 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr); 11677 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp2, KILL cr);
12117 11678
12118 format %{ "String IndexOf $str1,$str2 -> $result // KILL RAX, RCX, RDX" %} 11679 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1, $tmp2" %}
12119 ins_encode( enc_String_IndexOf(str1, str2, tmp1, tmp2, tmp3, tmp4, result) ); 11680 ins_encode %{
11681 __ string_indexof($str1$$Register, $str2$$Register,
11682 $cnt1$$Register, $cnt2$$Register, $result$$Register,
11683 $tmp1$$XMMRegister, $tmp2$$Register);
11684 %}
12120 ins_pipe( pipe_slow ); 11685 ins_pipe( pipe_slow );
12121 %} 11686 %}
12122 11687
12123 // fast string equals 11688 // fast string equals
12124 instruct string_equals(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2, rbx_RegI tmp3, 11689 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result,
12125 rcx_RegI tmp4, rax_RegI result, rFlagsReg cr) 11690 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr)
12126 %{ 11691 %{
12127 match(Set result (StrEquals str1 str2)); 11692 match(Set result (StrEquals (Binary str1 str2) cnt));
12128 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr); 11693 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
12129 11694
12130 format %{ "String Equals $str1,$str2 -> $result // KILL RBX, RCX" %} 11695 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %}
12131 ins_encode( enc_String_Equals(str1, str2, tmp1, tmp2, tmp3, tmp4, result) ); 11696 ins_encode %{
11697 __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
11698 $cnt$$Register, $result$$Register, $tmp3$$Register,
11699 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
11700 %}
12132 ins_pipe( pipe_slow ); 11701 ins_pipe( pipe_slow );
12133 %} 11702 %}
12134 11703
12135 // fast array equals 11704 // fast array equals
12136 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, regD tmp1, regD tmp2, rax_RegI tmp3, 11705 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
12137 rbx_RegI tmp4, rcx_RegI result, rFlagsReg cr) 11706 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
12138 %{ 11707 %{
12139 match(Set result (AryEq ary1 ary2)); 11708 match(Set result (AryEq ary1 ary2));
12140 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11709 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
12141 //ins_cost(300); 11710 //ins_cost(300);
12142 11711
12143 format %{ "Array Equals $ary1,$ary2 -> $result // KILL RAX, RBX" %} 11712 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
12144 ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, tmp4, result) ); 11713 ins_encode %{
11714 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
11715 $tmp3$$Register, $result$$Register, $tmp4$$Register,
11716 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
11717 %}
12145 ins_pipe( pipe_slow ); 11718 ins_pipe( pipe_slow );
12146 %} 11719 %}
12147 11720
12148 //----------Control Flow Instructions------------------------------------------ 11721 //----------Control Flow Instructions------------------------------------------
12149 // Signed compare Instructions 11722 // Signed compare Instructions