< prev index next >
src/cpu/x86/vm/x86_32.ad
Print this page
*** 11468,11487 ****
__ clear_mem($base$$Register, $cnt$$Register, $zero$$Register);
%}
ins_pipe( pipe_slow );
%}
! instruct string_compare(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2,
eAXRegI result, regD tmp1, eFlagsReg cr) %{
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
! format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
ins_encode %{
__ string_compare($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register, $result$$Register,
! $tmp1$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
// fast string equals
--- 11468,11533 ----
__ clear_mem($base$$Register, $cnt$$Register, $zero$$Register);
%}
ins_pipe( pipe_slow );
%}
! instruct string_compareL(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2,
eAXRegI result, regD tmp1, eFlagsReg cr) %{
+ predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
! format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
ins_encode %{
__ string_compare($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register, $result$$Register,
! $tmp1$$XMMRegister, StrIntrinsicNode::LL);
! %}
! ins_pipe( pipe_slow );
! %}
!
! instruct string_compareU(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2,
! eAXRegI result, regD tmp1, eFlagsReg cr) %{
! predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
! match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
! effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
!
! format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
! ins_encode %{
! __ string_compare($str1$$Register, $str2$$Register,
! $cnt1$$Register, $cnt2$$Register, $result$$Register,
! $tmp1$$XMMRegister, StrIntrinsicNode::UU);
! %}
! ins_pipe( pipe_slow );
! %}
!
! instruct string_compareLU(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2,
! eAXRegI result, regD tmp1, eFlagsReg cr) %{
! predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
! match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
! effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
!
! format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
! ins_encode %{
! __ string_compare($str1$$Register, $str2$$Register,
! $cnt1$$Register, $cnt2$$Register, $result$$Register,
! $tmp1$$XMMRegister, StrIntrinsicNode::LU);
! %}
! ins_pipe( pipe_slow );
! %}
!
! instruct string_compareUL(eSIRegP str1, eDXRegI cnt1, eDIRegP str2, eCXRegI cnt2,
! eAXRegI result, regD tmp1, eFlagsReg cr) %{
! predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
! match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
! effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
!
! format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
! ins_encode %{
! __ string_compare($str2$$Register, $str1$$Register,
! $cnt2$$Register, $cnt1$$Register, $result$$Register,
! $tmp1$$XMMRegister, StrIntrinsicNode::UL);
%}
ins_pipe( pipe_slow );
%}
// fast string equals
*** 11490,11567 ****
match(Set result (StrEquals (Binary str1 str2) cnt));
effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %}
ins_encode %{
! __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
$cnt$$Register, $result$$Register, $tmp3$$Register,
! $tmp1$$XMMRegister, $tmp2$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
// fast search of substring with known size.
! instruct string_indexof_con(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, immI int_cnt2,
eBXRegI result, regD vec, eAXRegI cnt2, eCXRegI tmp, eFlagsReg cr) %{
! predicate(UseSSE42Intrinsics);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
! format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %}
ins_encode %{
int icnt2 = (int)$int_cnt2$$constant;
if (icnt2 >= 8) {
// IndexOf for constant substrings with size >= 8 elements
// which don't need to be loaded through stack.
__ string_indexofC8($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
icnt2, $result$$Register,
! $vec$$XMMRegister, $tmp$$Register);
} else {
// Small strings are loaded through stack if they cross page boundary.
__ string_indexof($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
icnt2, $result$$Register,
! $vec$$XMMRegister, $tmp$$Register);
}
%}
ins_pipe( pipe_slow );
%}
! instruct string_indexof(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2,
eBXRegI result, regD vec, eCXRegI tmp, eFlagsReg cr) %{
! predicate(UseSSE42Intrinsics);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
! format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
ins_encode %{
__ string_indexof($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
(-1), $result$$Register,
! $vec$$XMMRegister, $tmp$$Register);
%}
ins_pipe( pipe_slow );
%}
// fast array equals
! instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI result,
regD tmp1, regD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr)
%{
match(Set result (AryEq ary1 ary2));
effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
//ins_cost(300);
! format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
ins_encode %{
! __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
$tmp3$$Register, $result$$Register, $tmp4$$Register,
$tmp1$$XMMRegister, $tmp2$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
// encode char[] to byte[] in ISO_8859_1
instruct encode_iso_array(eSIRegP src, eDIRegP dst, eDXRegI len,
regD tmp1, regD tmp2, regD tmp3, regD tmp4,
eCXRegI tmp5, eAXRegI result, eFlagsReg cr) %{
match(Set result (EncodeISOArray src (Binary dst len)));
--- 11536,11777 ----
match(Set result (StrEquals (Binary str1 str2) cnt));
effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %}
ins_encode %{
! __ arrays_equals(false, $str1$$Register, $str2$$Register,
$cnt$$Register, $result$$Register, $tmp3$$Register,
! $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */);
%}
+
ins_pipe( pipe_slow );
%}
// fast search of substring with known size.
! instruct string_indexof_conL(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, immI int_cnt2,
eBXRegI result, regD vec, eAXRegI cnt2, eCXRegI tmp, eFlagsReg cr) %{
! predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL));
! match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
! effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
!
! format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %}
! ins_encode %{
! int icnt2 = (int)$int_cnt2$$constant;
! if (icnt2 >= 16) {
! // IndexOf for constant substrings with size >= 16 elements
! // which don't need to be loaded through stack.
! __ string_indexofC8($str1$$Register, $str2$$Register,
! $cnt1$$Register, $cnt2$$Register,
! icnt2, $result$$Register,
! $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL);
! } else {
! // Small strings are loaded through stack if they cross page boundary.
! __ string_indexof($str1$$Register, $str2$$Register,
! $cnt1$$Register, $cnt2$$Register,
! icnt2, $result$$Register,
! $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL);
! }
! %}
! ins_pipe( pipe_slow );
! %}
!
! // fast search of substring with known size.
! instruct string_indexof_conU(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, immI int_cnt2,
! eBXRegI result, regD vec, eAXRegI cnt2, eCXRegI tmp, eFlagsReg cr) %{
! predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU));
! match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
! effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
!
! format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %}
! ins_encode %{
! int icnt2 = (int)$int_cnt2$$constant;
! if (icnt2 >= 8) {
! // IndexOf for constant substrings with size >= 8 elements
! // which don't need to be loaded through stack.
! __ string_indexofC8($str1$$Register, $str2$$Register,
! $cnt1$$Register, $cnt2$$Register,
! icnt2, $result$$Register,
! $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU);
! } else {
! // Small strings are loaded through stack if they cross page boundary.
! __ string_indexof($str1$$Register, $str2$$Register,
! $cnt1$$Register, $cnt2$$Register,
! icnt2, $result$$Register,
! $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU);
! }
! %}
! ins_pipe( pipe_slow );
! %}
!
! // fast search of substring with known size.
! instruct string_indexof_conUL(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, immI int_cnt2,
! eBXRegI result, regD vec, eAXRegI cnt2, eCXRegI tmp, eFlagsReg cr) %{
! predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL));
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
! format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %}
ins_encode %{
int icnt2 = (int)$int_cnt2$$constant;
if (icnt2 >= 8) {
// IndexOf for constant substrings with size >= 8 elements
// which don't need to be loaded through stack.
__ string_indexofC8($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
icnt2, $result$$Register,
! $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL);
} else {
// Small strings are loaded through stack if they cross page boundary.
__ string_indexof($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
icnt2, $result$$Register,
! $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL);
}
%}
ins_pipe( pipe_slow );
%}
! instruct string_indexofL(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2,
eBXRegI result, regD vec, eCXRegI tmp, eFlagsReg cr) %{
! predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL));
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
! format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
ins_encode %{
__ string_indexof($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
(-1), $result$$Register,
! $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL);
! %}
! ins_pipe( pipe_slow );
! %}
!
! instruct string_indexofU(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2,
! eBXRegI result, regD vec, eCXRegI tmp, eFlagsReg cr) %{
! predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU));
! match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
! effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
!
! format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
! ins_encode %{
! __ string_indexof($str1$$Register, $str2$$Register,
! $cnt1$$Register, $cnt2$$Register,
! (-1), $result$$Register,
! $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU);
! %}
! ins_pipe( pipe_slow );
! %}
!
! instruct string_indexofUL(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2,
! eBXRegI result, regD vec, eCXRegI tmp, eFlagsReg cr) %{
! predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL));
! match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
! effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
!
! format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
! ins_encode %{
! __ string_indexof($str1$$Register, $str2$$Register,
! $cnt1$$Register, $cnt2$$Register,
! (-1), $result$$Register,
! $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL);
! %}
! ins_pipe( pipe_slow );
! %}
!
! instruct string_indexofU_char(eDIRegP str1, eDXRegI cnt1, eAXRegI ch,
! eBXRegI result, regD vec1, regD vec2, regD vec3, eCXRegI tmp, eFlagsReg cr) %{
! predicate(UseSSE42Intrinsics);
! match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
! effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr);
! format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %}
! ins_encode %{
! __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register,
! $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register);
%}
ins_pipe( pipe_slow );
%}
// fast array equals
! instruct array_equalsB(eDIRegP ary1, eSIRegP ary2, eAXRegI result,
! regD tmp1, regD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr)
! %{
! predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
! match(Set result (AryEq ary1 ary2));
! effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
! //ins_cost(300);
!
! format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
! ins_encode %{
! __ arrays_equals(true, $ary1$$Register, $ary2$$Register,
! $tmp3$$Register, $result$$Register, $tmp4$$Register,
! $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */);
! %}
! ins_pipe( pipe_slow );
! %}
!
! instruct array_equalsC(eDIRegP ary1, eSIRegP ary2, eAXRegI result,
regD tmp1, regD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr)
%{
+ predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
match(Set result (AryEq ary1 ary2));
effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
//ins_cost(300);
! format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
ins_encode %{
! __ arrays_equals(true, $ary1$$Register, $ary2$$Register,
$tmp3$$Register, $result$$Register, $tmp4$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */);
+ %}
+ ins_pipe( pipe_slow );
+ %}
+
+ instruct has_negatives(eSIRegP ary1, eCXRegI len, eAXRegI result,
+ regD tmp1, regD tmp2, eBXRegI tmp3, eFlagsReg cr)
+ %{
+ match(Set result (HasNegatives ary1 len));
+ effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr);
+
+ format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %}
+ ins_encode %{
+ __ has_negatives($ary1$$Register, $len$$Register,
+ $result$$Register, $tmp3$$Register,
$tmp1$$XMMRegister, $tmp2$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
+ // fast char[] to byte[] compression
+ instruct string_compress(eSIRegP src, eDIRegP dst, eDXRegI len, regD tmp1, regD tmp2, regD tmp3, regD tmp4,
+ eCXRegI tmp5, eAXRegI result, eFlagsReg cr) %{
+ match(Set result (StrCompressedCopy src (Binary dst len)));
+ effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr);
+
+ format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %}
+ ins_encode %{
+ __ char_array_compress($src$$Register, $dst$$Register, $len$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister,
+ $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register);
+ %}
+ ins_pipe( pipe_slow );
+ %}
+
+ // fast byte[] to char[] inflation
+ instruct string_inflate(Universe dummy, eSIRegP src, eDIRegP dst, eDXRegI len,
+ regD tmp1, eCXRegI tmp2, eFlagsReg cr) %{
+ match(Set dummy (StrInflatedCopy src (Binary dst len)));
+ effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr);
+
+ format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %}
+ ins_encode %{
+ __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register,
+ $tmp1$$XMMRegister, $tmp2$$Register);
+ %}
+ ins_pipe( pipe_slow );
+ %}
+
// encode char[] to byte[] in ISO_8859_1
instruct encode_iso_array(eSIRegP src, eDIRegP dst, eDXRegI len,
regD tmp1, regD tmp2, regD tmp3, regD tmp4,
eCXRegI tmp5, eAXRegI result, eFlagsReg cr) %{
match(Set result (EncodeISOArray src (Binary dst len)));
< prev index next >