comparison src/cpu/x86/vm/x86_32.ad @ 1005:a2ad635573fb

Merge
author xlu
date Wed, 14 Oct 2009 12:40:20 -0700
parents 148e5441d916
children 97125851f396
comparison
equal deleted inserted replaced
1004:054afbef9081 1005:a2ad635573fb
377 // emit 32 bit value and construct relocation entry from RelocationHolder 377 // emit 32 bit value and construct relocation entry from RelocationHolder
378 void emit_d32_reloc(CodeBuffer &cbuf, int d32, RelocationHolder const& rspec, 378 void emit_d32_reloc(CodeBuffer &cbuf, int d32, RelocationHolder const& rspec,
379 int format) { 379 int format) {
380 #ifdef ASSERT 380 #ifdef ASSERT
381 if (rspec.reloc()->type() == relocInfo::oop_type && d32 != 0 && d32 != (int)Universe::non_oop_word()) { 381 if (rspec.reloc()->type() == relocInfo::oop_type && d32 != 0 && d32 != (int)Universe::non_oop_word()) {
382 assert(oop(d32)->is_oop() && oop(d32)->is_perm(), "cannot embed non-perm oops in code"); 382 assert(oop(d32)->is_oop() && (ScavengeRootsInCode || !oop(d32)->is_scavengable()), "cannot embed scavengable oops in code");
383 } 383 }
384 #endif 384 #endif
385 cbuf.relocate(cbuf.inst_mark(), rspec, format); 385 cbuf.relocate(cbuf.inst_mark(), rspec, format);
386 386
387 *((int *)(cbuf.code_end())) = d32; 387 *((int *)(cbuf.code_end())) = d32;
3699 // Avoid branch to branch on AMD processors 3699 // Avoid branch to branch on AMD processors
3700 if (EmitSync & 32768) { masm.nop() ; } 3700 if (EmitSync & 32768) { masm.nop() ; }
3701 } 3701 }
3702 %} 3702 %}
3703 3703
3704 enc_class enc_String_Compare(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
3705 eAXRegI tmp3, eBXRegI tmp4, eCXRegI result) %{
3706 Label ECX_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.movptr(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.movptr(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 if (VM_Version::supports_cmov()) {
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.cmovl(Assembler::lessEqual, rsi, rcx);
3738 } else {
3739 masm.movl(rdi, Address(rdi, count_offset));
3740 masm.movl(rcx, Address(rsi, count_offset));
3741 masm.movl(rsi, rdi);
3742 masm.subl(rdi, rcx);
3743 masm.push(rdi);
3744 masm.jccb(Assembler::lessEqual, ECX_GOOD_LABEL);
3745 masm.movl(rsi, rcx);
3746 // rsi holds min, rcx is unused
3747 }
3748
3749 // Is the minimum length zero?
3750 masm.bind(ECX_GOOD_LABEL);
3751 masm.testl(rsi, rsi);
3752 masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
3753
3754 // Load first characters
3755 masm.load_unsigned_short(rcx, Address(rbx, 0));
3756 masm.load_unsigned_short(rdi, Address(rax, 0));
3757
3758 // Compare first characters
3759 masm.subl(rcx, rdi);
3760 masm.jcc(Assembler::notZero, POP_LABEL);
3761 masm.decrementl(rsi);
3762 masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
3763
3764 {
3765 // Check after comparing first character to see if strings are equivalent
3766 Label LSkip2;
3767 // Check if the strings start at same location
3768 masm.cmpptr(rbx,rax);
3769 masm.jccb(Assembler::notEqual, LSkip2);
3770
3771 // Check if the length difference is zero (from stack)
3772 masm.cmpl(Address(rsp, 0), 0x0);
3773 masm.jcc(Assembler::equal, LENGTH_DIFF_LABEL);
3774
3775 // Strings might not be equivalent
3776 masm.bind(LSkip2);
3777 }
3778
3779 // Advance to next character
3780 masm.addptr(rax, 2);
3781 masm.addptr(rbx, 2);
3782
3783 if (UseSSE42Intrinsics) {
3784 // With SSE4.2, use double quad vector compare
3785 Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL;
3786 // Setup to compare 16-byte vectors
3787 masm.movl(rdi, rsi);
3788 masm.andl(rsi, 0xfffffff8); // rsi holds the vector count
3789 masm.andl(rdi, 0x00000007); // rdi holds the tail count
3790 masm.testl(rsi, rsi);
3791 masm.jccb(Assembler::zero, COMPARE_TAIL);
3792
3793 masm.lea(rax, Address(rax, rsi, Address::times_2));
3794 masm.lea(rbx, Address(rbx, rsi, Address::times_2));
3795 masm.negl(rsi);
3796
3797 masm.bind(COMPARE_VECTORS);
3798 masm.movdqu(tmp1Reg, Address(rax, rsi, Address::times_2));
3799 masm.movdqu(tmp2Reg, Address(rbx, rsi, Address::times_2));
3800 masm.pxor(tmp1Reg, tmp2Reg);
3801 masm.ptest(tmp1Reg, tmp1Reg);
3802 masm.jccb(Assembler::notZero, VECTOR_NOT_EQUAL);
3803 masm.addl(rsi, 8);
3804 masm.jcc(Assembler::notZero, COMPARE_VECTORS);
3805 masm.jmpb(COMPARE_TAIL);
3806
3807 // Mismatched characters in the vectors
3808 masm.bind(VECTOR_NOT_EQUAL);
3809 masm.lea(rax, Address(rax, rsi, Address::times_2));
3810 masm.lea(rbx, Address(rbx, rsi, Address::times_2));
3811 masm.movl(rdi, 8);
3812
3813 // Compare tail (< 8 chars), or rescan last vectors to
3814 // find 1st mismatched characters
3815 masm.bind(COMPARE_TAIL);
3816 masm.testl(rdi, rdi);
3817 masm.jccb(Assembler::zero, LENGTH_DIFF_LABEL);
3818 masm.movl(rsi, rdi);
3819 // Fallthru to tail compare
3820 }
3821
3822 //Shift rax, and rbx, to the end of the arrays, negate min
3823 masm.lea(rax, Address(rax, rsi, Address::times_2, 0));
3824 masm.lea(rbx, Address(rbx, rsi, Address::times_2, 0));
3825 masm.negl(rsi);
3826
3827 // Compare the rest of the characters
3828 masm.bind(WHILE_HEAD_LABEL);
3829 masm.load_unsigned_short(rcx, Address(rbx, rsi, Address::times_2, 0));
3830 masm.load_unsigned_short(rdi, Address(rax, rsi, Address::times_2, 0));
3831 masm.subl(rcx, rdi);
3832 masm.jccb(Assembler::notZero, POP_LABEL);
3833 masm.incrementl(rsi);
3834 masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL);
3835
3836 // Strings are equal up to min length. Return the length difference.
3837 masm.bind(LENGTH_DIFF_LABEL);
3838 masm.pop(rcx);
3839 masm.jmpb(DONE_LABEL);
3840
3841 // Discard the stored length difference
3842 masm.bind(POP_LABEL);
3843 masm.addptr(rsp, 4);
3844
3845 // That's it
3846 masm.bind(DONE_LABEL);
3847 %}
3848
3849 enc_class enc_String_Equals(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
3850 eBXRegI tmp3, eCXRegI tmp4, eAXRegI result) %{
3851 Label RET_TRUE, RET_FALSE, DONE, COMPARE_VECTORS, COMPARE_CHAR;
3852 MacroAssembler masm(&cbuf);
3853
3854 XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);
3855 XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg);
3856
3857 int value_offset = java_lang_String::value_offset_in_bytes();
3858 int offset_offset = java_lang_String::offset_offset_in_bytes();
3859 int count_offset = java_lang_String::count_offset_in_bytes();
3860 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
3861
3862 // does source == target string?
3863 masm.cmpptr(rdi, rsi);
3864 masm.jcc(Assembler::equal, RET_TRUE);
3865
3866 // get and compare counts
3867 masm.movl(rcx, Address(rdi, count_offset));
3868 masm.movl(rax, Address(rsi, count_offset));
3869 masm.cmpl(rcx, rax);
3870 masm.jcc(Assembler::notEqual, RET_FALSE);
3871 masm.testl(rax, rax);
3872 masm.jcc(Assembler::zero, RET_TRUE);
3873
3874 // get source string offset and value
3875 masm.movptr(rbx, Address(rsi, value_offset));
3876 masm.movl(rax, Address(rsi, offset_offset));
3877 masm.leal(rsi, Address(rbx, rax, Address::times_2, base_offset));
3878
3879 // get compare string offset and value
3880 masm.movptr(rbx, Address(rdi, value_offset));
3881 masm.movl(rax, Address(rdi, offset_offset));
3882 masm.leal(rdi, Address(rbx, rax, Address::times_2, base_offset));
3883
3884 // Set byte count
3885 masm.shll(rcx, 1);
3886 masm.movl(rax, rcx);
3887
3888 if (UseSSE42Intrinsics) {
3889 // With SSE4.2, use double quad vector compare
3890 Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
3891 // Compare 16-byte vectors
3892 masm.andl(rcx, 0xfffffff0); // vector count (in bytes)
3893 masm.andl(rax, 0x0000000e); // tail count (in bytes)
3894 masm.testl(rcx, rcx);
3895 masm.jccb(Assembler::zero, COMPARE_TAIL);
3896 masm.lea(rdi, Address(rdi, rcx, Address::times_1));
3897 masm.lea(rsi, Address(rsi, rcx, Address::times_1));
3898 masm.negl(rcx);
3899
3900 masm.bind(COMPARE_WIDE_VECTORS);
3901 masm.movdqu(tmp1Reg, Address(rdi, rcx, Address::times_1));
3902 masm.movdqu(tmp2Reg, Address(rsi, rcx, Address::times_1));
3903 masm.pxor(tmp1Reg, tmp2Reg);
3904 masm.ptest(tmp1Reg, tmp1Reg);
3905 masm.jccb(Assembler::notZero, RET_FALSE);
3906 masm.addl(rcx, 16);
3907 masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
3908 masm.bind(COMPARE_TAIL);
3909 masm.movl(rcx, rax);
3910 // Fallthru to tail compare
3911 }
3912
3913 // Compare 4-byte vectors
3914 masm.andl(rcx, 0xfffffffc); // vector count (in bytes)
3915 masm.andl(rax, 0x00000002); // tail char (in bytes)
3916 masm.testl(rcx, rcx);
3917 masm.jccb(Assembler::zero, COMPARE_CHAR);
3918 masm.lea(rdi, Address(rdi, rcx, Address::times_1));
3919 masm.lea(rsi, Address(rsi, rcx, Address::times_1));
3920 masm.negl(rcx);
3921
3922 masm.bind(COMPARE_VECTORS);
3923 masm.movl(rbx, Address(rdi, rcx, Address::times_1));
3924 masm.cmpl(rbx, Address(rsi, rcx, Address::times_1));
3925 masm.jccb(Assembler::notEqual, RET_FALSE);
3926 masm.addl(rcx, 4);
3927 masm.jcc(Assembler::notZero, COMPARE_VECTORS);
3928
3929 // Compare trailing char (final 2 bytes), if any
3930 masm.bind(COMPARE_CHAR);
3931 masm.testl(rax, rax);
3932 masm.jccb(Assembler::zero, RET_TRUE);
3933 masm.load_unsigned_short(rbx, Address(rdi, 0));
3934 masm.load_unsigned_short(rcx, Address(rsi, 0));
3935 masm.cmpl(rbx, rcx);
3936 masm.jccb(Assembler::notEqual, RET_FALSE);
3937
3938 masm.bind(RET_TRUE);
3939 masm.movl(rax, 1); // return true
3940 masm.jmpb(DONE);
3941
3942 masm.bind(RET_FALSE);
3943 masm.xorl(rax, rax); // return false
3944
3945 masm.bind(DONE);
3946 %}
3947
3948 enc_class enc_String_IndexOf(eSIRegP str1, eDIRegP str2, regXD tmp1, eAXRegI tmp2,
3949 eCXRegI tmp3, eDXRegI tmp4, eBXRegI result) %{
3950 // SSE4.2 version
3951 Label LOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR,
3952 SCAN_SUBSTR, RET_NEG_ONE, RET_NOT_FOUND, CLEANUP, DONE;
3953 MacroAssembler masm(&cbuf);
3954
3955 XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);
3956
3957 // Get the first character position in both strings
3958 // [8] char array, [12] offset, [16] count
3959 int value_offset = java_lang_String::value_offset_in_bytes();
3960 int offset_offset = java_lang_String::offset_offset_in_bytes();
3961 int count_offset = java_lang_String::count_offset_in_bytes();
3962 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
3963
3964 // Get counts for string and substr
3965 masm.movl(rdx, Address(rsi, count_offset));
3966 masm.movl(rax, Address(rdi, count_offset));
3967 // Check for substr count > string count
3968 masm.cmpl(rax, rdx);
3969 masm.jcc(Assembler::greater, RET_NEG_ONE);
3970
3971 // Start the indexOf operation
3972 // Get start addr of string
3973 masm.movptr(rbx, Address(rsi, value_offset));
3974 masm.movl(rcx, Address(rsi, offset_offset));
3975 masm.lea(rsi, Address(rbx, rcx, Address::times_2, base_offset));
3976 masm.push(rsi);
3977
3978 // Get start addr of substr
3979 masm.movptr(rbx, Address(rdi, value_offset));
3980 masm.movl(rcx, Address(rdi, offset_offset));
3981 masm.lea(rdi, Address(rbx, rcx, Address::times_2, base_offset));
3982 masm.push(rdi);
3983 masm.push(rax);
3984 masm.jmpb(PREP_FOR_SCAN);
3985
3986 // Substr count saved at sp
3987 // Substr saved at sp+4
3988 // String saved at sp+8
3989
3990 // Prep to load substr for scan
3991 masm.bind(LOAD_SUBSTR);
3992 masm.movptr(rdi, Address(rsp, 4));
3993 masm.movl(rax, Address(rsp, 0));
3994
3995 // Load substr
3996 masm.bind(PREP_FOR_SCAN);
3997 masm.movdqu(tmp1Reg, Address(rdi, 0));
3998 masm.addl(rdx, 8); // prime the loop
3999 masm.subptr(rsi, 16);
4000
4001 // Scan string for substr in 16-byte vectors
4002 masm.bind(SCAN_TO_SUBSTR);
4003 masm.subl(rdx, 8);
4004 masm.addptr(rsi, 16);
4005 masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
4006 masm.jcc(Assembler::above, SCAN_TO_SUBSTR); // CF == 0 && ZF == 0
4007 masm.jccb(Assembler::aboveEqual, RET_NOT_FOUND); // CF == 0
4008
4009 // Fallthru: found a potential substr
4010
4011 // Make sure string is still long enough
4012 masm.subl(rdx, rcx);
4013 masm.cmpl(rdx, rax);
4014 masm.jccb(Assembler::negative, RET_NOT_FOUND);
4015 // Compute start addr of substr
4016 masm.lea(rsi, Address(rsi, rcx, Address::times_2));
4017 masm.movptr(rbx, rsi);
4018
4019 // Compare potential substr
4020 masm.addl(rdx, 8); // prime the loop
4021 masm.addl(rax, 8);
4022 masm.subptr(rsi, 16);
4023 masm.subptr(rdi, 16);
4024
4025 // Scan 16-byte vectors of string and substr
4026 masm.bind(SCAN_SUBSTR);
4027 masm.subl(rax, 8);
4028 masm.subl(rdx, 8);
4029 masm.addptr(rsi, 16);
4030 masm.addptr(rdi, 16);
4031 masm.movdqu(tmp1Reg, Address(rdi, 0));
4032 masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
4033 masm.jcc(Assembler::noOverflow, LOAD_SUBSTR); // OF == 0
4034 masm.jcc(Assembler::positive, SCAN_SUBSTR); // SF == 0
4035
4036 // Compute substr offset
4037 masm.movptr(rsi, Address(rsp, 8));
4038 masm.subptr(rbx, rsi);
4039 masm.shrl(rbx, 1);
4040 masm.jmpb(CLEANUP);
4041
4042 masm.bind(RET_NEG_ONE);
4043 masm.movl(rbx, -1);
4044 masm.jmpb(DONE);
4045
4046 masm.bind(RET_NOT_FOUND);
4047 masm.movl(rbx, -1);
4048
4049 masm.bind(CLEANUP);
4050 masm.addptr(rsp, 12);
4051
4052 masm.bind(DONE);
4053 %}
4054
4055 enc_class enc_Array_Equals(eDIRegP ary1, eSIRegP ary2, regXD tmp1, regXD tmp2,
4056 eBXRegI tmp3, eDXRegI tmp4, eAXRegI result) %{
4057 Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;
4058 MacroAssembler masm(&cbuf);
4059
4060 XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);
4061 XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg);
4062 Register ary1Reg = as_Register($ary1$$reg);
4063 Register ary2Reg = as_Register($ary2$$reg);
4064 Register tmp3Reg = as_Register($tmp3$$reg);
4065 Register tmp4Reg = as_Register($tmp4$$reg);
4066 Register resultReg = as_Register($result$$reg);
4067
4068 int length_offset = arrayOopDesc::length_offset_in_bytes();
4069 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
4070
4071 // Check the input args
4072 masm.cmpptr(ary1Reg, ary2Reg);
4073 masm.jcc(Assembler::equal, TRUE_LABEL);
4074 masm.testptr(ary1Reg, ary1Reg);
4075 masm.jcc(Assembler::zero, FALSE_LABEL);
4076 masm.testptr(ary2Reg, ary2Reg);
4077 masm.jcc(Assembler::zero, FALSE_LABEL);
4078
4079 // Check the lengths
4080 masm.movl(tmp4Reg, Address(ary1Reg, length_offset));
4081 masm.movl(resultReg, Address(ary2Reg, length_offset));
4082 masm.cmpl(tmp4Reg, resultReg);
4083 masm.jcc(Assembler::notEqual, FALSE_LABEL);
4084 masm.testl(resultReg, resultReg);
4085 masm.jcc(Assembler::zero, TRUE_LABEL);
4086
4087 // Load array addrs
4088 masm.lea(ary1Reg, Address(ary1Reg, base_offset));
4089 masm.lea(ary2Reg, Address(ary2Reg, base_offset));
4090
4091 // Set byte count
4092 masm.shll(tmp4Reg, 1);
4093 masm.movl(resultReg, tmp4Reg);
4094
4095 if (UseSSE42Intrinsics) {
4096 // With SSE4.2, use double quad vector compare
4097 Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
4098 // Compare 16-byte vectors
4099 masm.andl(tmp4Reg, 0xfffffff0); // vector count (in bytes)
4100 masm.andl(resultReg, 0x0000000e); // tail count (in bytes)
4101 masm.testl(tmp4Reg, tmp4Reg);
4102 masm.jccb(Assembler::zero, COMPARE_TAIL);
4103 masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
4104 masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
4105 masm.negl(tmp4Reg);
4106
4107 masm.bind(COMPARE_WIDE_VECTORS);
4108 masm.movdqu(tmp1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
4109 masm.movdqu(tmp2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
4110 masm.pxor(tmp1Reg, tmp2Reg);
4111 masm.ptest(tmp1Reg, tmp1Reg);
4112
4113 masm.jccb(Assembler::notZero, FALSE_LABEL);
4114 masm.addl(tmp4Reg, 16);
4115 masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
4116 masm.bind(COMPARE_TAIL);
4117 masm.movl(tmp4Reg, resultReg);
4118 // Fallthru to tail compare
4119 }
4120
4121 // Compare 4-byte vectors
4122 masm.andl(tmp4Reg, 0xfffffffc); // vector count (in bytes)
4123 masm.andl(resultReg, 0x00000002); // tail char (in bytes)
4124 masm.testl(tmp4Reg, tmp4Reg);
4125 masm.jccb(Assembler::zero, COMPARE_CHAR);
4126 masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
4127 masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
4128 masm.negl(tmp4Reg);
4129
4130 masm.bind(COMPARE_VECTORS);
4131 masm.movl(tmp3Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
4132 masm.cmpl(tmp3Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
4133 masm.jccb(Assembler::notEqual, FALSE_LABEL);
4134 masm.addl(tmp4Reg, 4);
4135 masm.jcc(Assembler::notZero, COMPARE_VECTORS);
4136
4137 // Compare trailing char (final 2 bytes), if any
4138 masm.bind(COMPARE_CHAR);
4139 masm.testl(resultReg, resultReg);
4140 masm.jccb(Assembler::zero, TRUE_LABEL);
4141 masm.load_unsigned_short(tmp3Reg, Address(ary1Reg, 0));
4142 masm.load_unsigned_short(tmp4Reg, Address(ary2Reg, 0));
4143 masm.cmpl(tmp3Reg, tmp4Reg);
4144 masm.jccb(Assembler::notEqual, FALSE_LABEL);
4145
4146 masm.bind(TRUE_LABEL);
4147 masm.movl(resultReg, 1); // return true
4148 masm.jmpb(DONE);
4149
4150 masm.bind(FALSE_LABEL);
4151 masm.xorl(resultReg, resultReg); // return false
4152
4153 // That's it
4154 masm.bind(DONE);
4155 %}
4156 3704
4157 enc_class enc_pop_rdx() %{ 3705 enc_class enc_pop_rdx() %{
4158 emit_opcode(cbuf,0x5A); 3706 emit_opcode(cbuf,0x5A);
4159 %} 3707 %}
4160 3708
12716 OpcRegReg(0x33,EAX,EAX), 12264 OpcRegReg(0x33,EAX,EAX),
12717 Opcode(0xF3), Opcode(0xAB) ); 12265 Opcode(0xF3), Opcode(0xAB) );
12718 ins_pipe( pipe_slow ); 12266 ins_pipe( pipe_slow );
12719 %} 12267 %}
12720 12268
12721 instruct string_compare(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2, 12269 instruct string_compare(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eBXRegI cnt2,
12722 eAXRegI tmp3, eBXRegI tmp4, eCXRegI result, eFlagsReg cr) %{ 12270 eAXRegI result, regXD tmp1, regXD tmp2, eFlagsReg cr) %{
12723 match(Set result (StrComp str1 str2)); 12271 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
12724 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr); 12272 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
12725 //ins_cost(300); 12273
12726 12274 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1, $tmp2" %}
12727 format %{ "String Compare $str1,$str2 -> $result // KILL EAX, EBX" %} 12275 ins_encode %{
12728 ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, tmp3, tmp4, result) ); 12276 __ string_compare($str1$$Register, $str2$$Register,
12277 $cnt1$$Register, $cnt2$$Register, $result$$Register,
12278 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
12279 %}
12729 ins_pipe( pipe_slow ); 12280 ins_pipe( pipe_slow );
12730 %} 12281 %}
12731 12282
12732 // fast string equals 12283 // fast string equals
12733 instruct string_equals(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2, 12284 instruct string_equals(eDIRegP str1, eSIRegP str2, eCXRegI cnt, eAXRegI result,
12734 eBXRegI tmp3, eCXRegI tmp4, eAXRegI result, eFlagsReg cr) %{ 12285 regXD tmp1, regXD tmp2, eBXRegI tmp3, eFlagsReg cr) %{
12735 match(Set result (StrEquals str1 str2)); 12286 match(Set result (StrEquals (Binary str1 str2) cnt));
12736 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr); 12287 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
12737 12288
12738 format %{ "String Equals $str1,$str2 -> $result // KILL EBX, ECX" %} 12289 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %}
12739 ins_encode( enc_String_Equals(tmp1, tmp2, str1, str2, tmp3, tmp4, result) ); 12290 ins_encode %{
12740 ins_pipe( pipe_slow ); 12291 __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
12741 %} 12292 $cnt$$Register, $result$$Register, $tmp3$$Register,
12742 12293 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
12743 instruct string_indexof(eSIRegP str1, eDIRegP str2, regXD tmp1, eAXRegI tmp2, 12294 %}
12744 eCXRegI tmp3, eDXRegI tmp4, eBXRegI result, eFlagsReg cr) %{ 12295 ins_pipe( pipe_slow );
12296 %}
12297
12298 instruct string_indexof(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2,
12299 eBXRegI result, regXD tmp1, eCXRegI tmp2, eFlagsReg cr) %{
12745 predicate(UseSSE42Intrinsics); 12300 predicate(UseSSE42Intrinsics);
12746 match(Set result (StrIndexOf str1 str2)); 12301 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
12747 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr); 12302 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp2, KILL cr);
12748 12303
12749 format %{ "String IndexOf $str1,$str2 -> $result // KILL EAX, ECX, EDX" %} 12304 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp2, $tmp1" %}
12750 ins_encode( enc_String_IndexOf(str1, str2, tmp1, tmp2, tmp3, tmp4, result) ); 12305 ins_encode %{
12306 __ string_indexof($str1$$Register, $str2$$Register,
12307 $cnt1$$Register, $cnt2$$Register, $result$$Register,
12308 $tmp1$$XMMRegister, $tmp2$$Register);
12309 %}
12751 ins_pipe( pipe_slow ); 12310 ins_pipe( pipe_slow );
12752 %} 12311 %}
12753 12312
12754 // fast array equals 12313 // fast array equals
12755 instruct array_equals(eDIRegP ary1, eSIRegP ary2, regXD tmp1, regXD tmp2, eBXRegI tmp3, 12314 instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI result,
12756 eDXRegI tmp4, eAXRegI result, eFlagsReg cr) %{ 12315 regXD tmp1, regXD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr)
12316 %{
12757 match(Set result (AryEq ary1 ary2)); 12317 match(Set result (AryEq ary1 ary2));
12758 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12318 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
12759 //ins_cost(300); 12319 //ins_cost(300);
12760 12320
12761 format %{ "Array Equals $ary1,$ary2 -> $result // KILL EBX, EDX" %} 12321 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
12762 ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, tmp4, result) ); 12322 ins_encode %{
12323 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
12324 $tmp3$$Register, $result$$Register, $tmp4$$Register,
12325 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
12326 %}
12763 ins_pipe( pipe_slow ); 12327 ins_pipe( pipe_slow );
12764 %} 12328 %}
12765 12329
12766 //----------Control Flow Instructions------------------------------------------ 12330 //----------Control Flow Instructions------------------------------------------
12767 // Signed compare Instructions 12331 // Signed compare Instructions