Merge
This commit is contained in:
commit
b6e48e6782
@ -1199,9 +1199,6 @@ reg_class gov_pr (
|
||||
// P7, non-allocatable, preserved with all elements preset to TRUE.
|
||||
);
|
||||
|
||||
reg_class p0_reg(P0);
|
||||
reg_class p1_reg(P1);
|
||||
|
||||
// Singleton class for condition codes
|
||||
reg_class int_flags(RFLAGS);
|
||||
|
||||
@ -5687,24 +5684,6 @@ operand pRegGov()
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
|
||||
operand pRegGov_P0()
|
||||
%{
|
||||
constraint(ALLOC_IN_RC(p0_reg));
|
||||
match(RegVectMask);
|
||||
op_cost(0);
|
||||
format %{ %}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
|
||||
operand pRegGov_P1()
|
||||
%{
|
||||
constraint(ALLOC_IN_RC(p1_reg));
|
||||
match(RegVectMask);
|
||||
op_cost(0);
|
||||
format %{ %}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
|
||||
// Flags register, used as output of signed compare instructions
|
||||
|
||||
// note that on AArch64 we also use this register as the output for
|
||||
@ -16683,7 +16662,7 @@ instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp,
|
||||
instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
|
||||
iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr)
|
||||
%{
|
||||
predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU));
|
||||
predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
|
||||
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
|
||||
effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
|
||||
|
||||
@ -16693,7 +16672,7 @@ instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 c
|
||||
__ string_compare($str1$$Register, $str2$$Register,
|
||||
$cnt1$$Register, $cnt2$$Register, $result$$Register,
|
||||
$tmp1$$Register, $tmp2$$Register,
|
||||
fnoreg, fnoreg, fnoreg, pnoreg, pnoreg, StrIntrinsicNode::UU);
|
||||
fnoreg, fnoreg, fnoreg, StrIntrinsicNode::UU);
|
||||
%}
|
||||
ins_pipe(pipe_class_memory);
|
||||
%}
|
||||
@ -16701,7 +16680,7 @@ instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 c
|
||||
instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
|
||||
iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr)
|
||||
%{
|
||||
predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL));
|
||||
predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
|
||||
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
|
||||
effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
|
||||
|
||||
@ -16710,7 +16689,7 @@ instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 c
|
||||
__ string_compare($str1$$Register, $str2$$Register,
|
||||
$cnt1$$Register, $cnt2$$Register, $result$$Register,
|
||||
$tmp1$$Register, $tmp2$$Register,
|
||||
fnoreg, fnoreg, fnoreg, pnoreg, pnoreg, StrIntrinsicNode::LL);
|
||||
fnoreg, fnoreg, fnoreg, StrIntrinsicNode::LL);
|
||||
%}
|
||||
ins_pipe(pipe_class_memory);
|
||||
%}
|
||||
@ -16719,7 +16698,7 @@ instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4
|
||||
iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
|
||||
vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr)
|
||||
%{
|
||||
predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL));
|
||||
predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
|
||||
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
|
||||
effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3,
|
||||
USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
|
||||
@ -16730,7 +16709,7 @@ instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4
|
||||
$cnt1$$Register, $cnt2$$Register, $result$$Register,
|
||||
$tmp1$$Register, $tmp2$$Register,
|
||||
$vtmp1$$FloatRegister, $vtmp2$$FloatRegister,
|
||||
$vtmp3$$FloatRegister, pnoreg, pnoreg, StrIntrinsicNode::UL);
|
||||
$vtmp3$$FloatRegister, StrIntrinsicNode::UL);
|
||||
%}
|
||||
ins_pipe(pipe_class_memory);
|
||||
%}
|
||||
@ -16739,7 +16718,7 @@ instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4
|
||||
iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
|
||||
vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr)
|
||||
%{
|
||||
predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU));
|
||||
predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
|
||||
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
|
||||
effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3,
|
||||
USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
|
||||
@ -16750,7 +16729,7 @@ instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4
|
||||
$cnt1$$Register, $cnt2$$Register, $result$$Register,
|
||||
$tmp1$$Register, $tmp2$$Register,
|
||||
$vtmp1$$FloatRegister, $vtmp2$$FloatRegister,
|
||||
$vtmp3$$FloatRegister, pnoreg, pnoreg, StrIntrinsicNode::LU);
|
||||
$vtmp3$$FloatRegister,StrIntrinsicNode::LU);
|
||||
%}
|
||||
ins_pipe(pipe_class_memory);
|
||||
%}
|
||||
|
@ -5573,105 +5573,6 @@ instruct stringU_indexof_char_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch,
|
||||
ins_pipe(pipe_class_memory);
|
||||
%}
|
||||
|
||||
// Intrisics for String.compareTo()
|
||||
|
||||
// Note that Z registers alias the corresponding NEON registers, we declare the vector operands of
|
||||
// these string_compare variants as NEON register type for convenience so that the prototype of
|
||||
// string_compare can be shared with all variants.
|
||||
|
||||
|
||||
instruct string_compareLL_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
|
||||
iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
|
||||
vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1,
|
||||
pRegGov_P1 pgtmp2, rFlagsReg cr)
|
||||
%{
|
||||
predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL));
|
||||
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
|
||||
effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2,
|
||||
USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
|
||||
|
||||
format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %}
|
||||
ins_encode %{
|
||||
// Count is in 8-bit bytes; non-Compact chars are 16 bits.
|
||||
__ string_compare($str1$$Register, $str2$$Register,
|
||||
$cnt1$$Register, $cnt2$$Register, $result$$Register,
|
||||
$tmp1$$Register, $tmp2$$Register,
|
||||
$vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg,
|
||||
as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg),
|
||||
StrIntrinsicNode::LL);
|
||||
%}
|
||||
ins_pipe(pipe_class_memory);
|
||||
%}
|
||||
|
||||
instruct string_compareLU_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
|
||||
iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
|
||||
vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1,
|
||||
pRegGov_P1 pgtmp2, rFlagsReg cr)
|
||||
%{
|
||||
predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU));
|
||||
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
|
||||
effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2,
|
||||
USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
|
||||
|
||||
format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %}
|
||||
ins_encode %{
|
||||
// Count is in 8-bit bytes; non-Compact chars are 16 bits.
|
||||
__ string_compare($str1$$Register, $str2$$Register,
|
||||
$cnt1$$Register, $cnt2$$Register, $result$$Register,
|
||||
$tmp1$$Register, $tmp2$$Register,
|
||||
$vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg,
|
||||
as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg),
|
||||
StrIntrinsicNode::LU);
|
||||
%}
|
||||
ins_pipe(pipe_class_memory);
|
||||
%}
|
||||
|
||||
instruct string_compareUL_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
|
||||
iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
|
||||
vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1,
|
||||
pRegGov_P1 pgtmp2, rFlagsReg cr)
|
||||
%{
|
||||
predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL));
|
||||
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
|
||||
effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2,
|
||||
USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
|
||||
|
||||
format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %}
|
||||
ins_encode %{
|
||||
// Count is in 8-bit bytes; non-Compact chars are 16 bits.
|
||||
__ string_compare($str1$$Register, $str2$$Register,
|
||||
$cnt1$$Register, $cnt2$$Register, $result$$Register,
|
||||
$tmp1$$Register, $tmp2$$Register,
|
||||
$vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg,
|
||||
as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg),
|
||||
StrIntrinsicNode::UL);
|
||||
%}
|
||||
ins_pipe(pipe_class_memory);
|
||||
%}
|
||||
|
||||
instruct string_compareUU_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
|
||||
iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
|
||||
vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1,
|
||||
pRegGov_P1 pgtmp2, rFlagsReg cr)
|
||||
%{
|
||||
predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU));
|
||||
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
|
||||
effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2,
|
||||
USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
|
||||
|
||||
format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %}
|
||||
ins_encode %{
|
||||
// Count is in 8-bit bytes; non-Compact chars are 16 bits.
|
||||
__ string_compare($str1$$Register, $str2$$Register,
|
||||
$cnt1$$Register, $cnt2$$Register, $result$$Register,
|
||||
$tmp1$$Register, $tmp2$$Register,
|
||||
$vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg,
|
||||
as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg),
|
||||
StrIntrinsicNode::UU);
|
||||
%}
|
||||
ins_pipe(pipe_class_memory);
|
||||
%}
|
||||
|
||||
// ---------------------------- Vector mask reductions ---------------------------
|
||||
instruct vmask_truecount(iRegINoSp dst, pReg src) %{
|
||||
predicate(UseSVE > 0 &&
|
||||
|
@ -3054,42 +3054,6 @@ dnl $1 $2 $3
|
||||
STRING_INDEXOF_CHAR(L, Latin1, true)
|
||||
STRING_INDEXOF_CHAR(U, UTF16, false)
|
||||
|
||||
// Intrisics for String.compareTo()
|
||||
|
||||
// Note that Z registers alias the corresponding NEON registers, we declare the vector operands of
|
||||
// these string_compare variants as NEON register type for convenience so that the prototype of
|
||||
// string_compare can be shared with all variants.
|
||||
|
||||
dnl
|
||||
define(`STRING_COMPARETO', `
|
||||
instruct string_compare$1_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
|
||||
iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
|
||||
vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1,
|
||||
pRegGov_P1 pgtmp2, rFlagsReg cr)
|
||||
%{
|
||||
predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::$1));
|
||||
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
|
||||
effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2,
|
||||
USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
|
||||
|
||||
format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %}
|
||||
ins_encode %{
|
||||
// Count is in 8-bit bytes; non-Compact chars are 16 bits.
|
||||
__ string_compare($str1$$Register, $str2$$Register,
|
||||
$cnt1$$Register, $cnt2$$Register, $result$$Register,
|
||||
$tmp1$$Register, $tmp2$$Register,
|
||||
$vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg,
|
||||
as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg),
|
||||
StrIntrinsicNode::$1);
|
||||
%}
|
||||
ins_pipe(pipe_class_memory);
|
||||
%}')dnl
|
||||
dnl $1
|
||||
STRING_COMPARETO(LL)
|
||||
STRING_COMPARETO(LU)
|
||||
STRING_COMPARETO(UL)
|
||||
STRING_COMPARETO(UU)
|
||||
|
||||
// ---------------------------- Vector mask reductions ---------------------------
|
||||
instruct vmask_truecount(iRegINoSp dst, pReg src) %{
|
||||
predicate(UseSVE > 0 &&
|
||||
|
@ -676,8 +676,7 @@ void C2_MacroAssembler::stringL_indexof_char(Register str1, Register cnt1,
|
||||
// Compare strings.
|
||||
void C2_MacroAssembler::string_compare(Register str1, Register str2,
|
||||
Register cnt1, Register cnt2, Register result, Register tmp1, Register tmp2,
|
||||
FloatRegister vtmp1, FloatRegister vtmp2, FloatRegister vtmp3,
|
||||
PRegister pgtmp1, PRegister pgtmp2, int ae) {
|
||||
FloatRegister vtmp1, FloatRegister vtmp2, FloatRegister vtmp3, int ae) {
|
||||
Label DONE, SHORT_LOOP, SHORT_STRING, SHORT_LAST, TAIL, STUB,
|
||||
DIFF, NEXT_WORD, SHORT_LOOP_TAIL, SHORT_LAST2, SHORT_LAST_INIT,
|
||||
SHORT_LOOP_START, TAIL_CHECK;
|
||||
|
@ -32,8 +32,7 @@
|
||||
void string_compare(Register str1, Register str2,
|
||||
Register cnt1, Register cnt2, Register result,
|
||||
Register tmp1, Register tmp2, FloatRegister vtmp1,
|
||||
FloatRegister vtmp2, FloatRegister vtmp3,
|
||||
PRegister pgtmp1, PRegister pgtmp2, int ae);
|
||||
FloatRegister vtmp2, FloatRegister vtmp3, int ae);
|
||||
|
||||
void string_indexof(Register str1, Register str2,
|
||||
Register cnt1, Register cnt2,
|
||||
|
@ -275,8 +275,6 @@ class PRegisterImpl: public AbstractRegisterImpl {
|
||||
REGISTER_IMPL_DECLARATION(PRegister, PRegisterImpl, PRegisterImpl::number_of_registers);
|
||||
|
||||
// The predicate registers of SVE.
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, pnoreg, (-1));
|
||||
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p0, ( 0));
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p1, ( 1));
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p2, ( 2));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -188,8 +188,6 @@ REGISTER_DEFINITION(FloatRegister, z29);
|
||||
REGISTER_DEFINITION(FloatRegister, z30);
|
||||
REGISTER_DEFINITION(FloatRegister, z31);
|
||||
|
||||
REGISTER_DEFINITION(PRegister, pnoreg);
|
||||
|
||||
REGISTER_DEFINITION(PRegister, p0);
|
||||
REGISTER_DEFINITION(PRegister, p1);
|
||||
REGISTER_DEFINITION(PRegister, p2);
|
||||
|
@ -5215,97 +5215,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
return start;
|
||||
}
|
||||
|
||||
enum string_compare_mode {
|
||||
LL,
|
||||
LU,
|
||||
UL,
|
||||
UU,
|
||||
};
|
||||
|
||||
// The following registers are declared in aarch64.ad
|
||||
// r0 = result
|
||||
// r1 = str1
|
||||
// r2 = cnt1
|
||||
// r3 = str2
|
||||
// r4 = cnt2
|
||||
// r10 = tmp1
|
||||
// r11 = tmp2
|
||||
// z0 = ztmp1
|
||||
// z1 = ztmp2
|
||||
// p0 = pgtmp1
|
||||
// p1 = pgtmp2
|
||||
address generate_compare_long_string_sve(string_compare_mode mode) {
|
||||
__ align(CodeEntryAlignment);
|
||||
address entry = __ pc();
|
||||
Register result = r0, str1 = r1, cnt1 = r2, str2 = r3, cnt2 = r4,
|
||||
tmp1 = r10, tmp2 = r11;
|
||||
|
||||
Label LOOP, MATCH, DONE, NOMATCH;
|
||||
Register vec_len = tmp1;
|
||||
Register idx = tmp2;
|
||||
// The minimum of the string lengths has been stored in cnt2.
|
||||
Register cnt = cnt2;
|
||||
FloatRegister ztmp1 = z0, ztmp2 = z1;
|
||||
PRegister pgtmp1 = p0, pgtmp2 = p1;
|
||||
|
||||
if (mode == LL) {
|
||||
__ sve_cntb(vec_len);
|
||||
} else {
|
||||
__ sve_cnth(vec_len);
|
||||
}
|
||||
|
||||
__ mov(idx, 0);
|
||||
__ sve_whilelt(pgtmp1, mode == LL ? __ B : __ H, idx, cnt);
|
||||
|
||||
__ bind(LOOP);
|
||||
switch (mode) {
|
||||
case LL:
|
||||
__ sve_ld1b(ztmp1, __ B, pgtmp1, Address(str1, idx));
|
||||
__ sve_ld1b(ztmp2, __ B, pgtmp1, Address(str2, idx));
|
||||
break;
|
||||
case LU:
|
||||
__ sve_ld1b(ztmp1, __ H, pgtmp1, Address(str1, idx));
|
||||
__ sve_ld1h(ztmp2, __ H, pgtmp1, Address(str2, idx, Address::lsl(1)));
|
||||
break;
|
||||
case UL:
|
||||
__ sve_ld1h(ztmp1, __ H, pgtmp1, Address(str1, idx, Address::lsl(1)));
|
||||
__ sve_ld1b(ztmp2, __ H, pgtmp1, Address(str2, idx));
|
||||
break;
|
||||
case UU:
|
||||
__ sve_ld1h(ztmp1, __ H, pgtmp1, Address(str1, idx, Address::lsl(1)));
|
||||
__ sve_ld1h(ztmp2, __ H, pgtmp1, Address(str2, idx, Address::lsl(1)));
|
||||
break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
__ add(idx, idx, vec_len);
|
||||
|
||||
// Compare strings.
|
||||
__ sve_cmp(Assembler::NE, pgtmp2, mode == LL ? __ B : __ H, pgtmp1, ztmp1, ztmp2);
|
||||
__ br(__ NE, MATCH);
|
||||
__ sve_whilelt(pgtmp1, mode == LL ? __ B : __ H, idx, cnt);
|
||||
__ br(__ LT, LOOP);
|
||||
|
||||
// The result has been computed in the caller prior to entering this stub.
|
||||
__ b(DONE);
|
||||
|
||||
__ bind(MATCH);
|
||||
|
||||
// Crop the vector to find its location.
|
||||
__ sve_brkb(pgtmp2, pgtmp1, pgtmp2, false /* isMerge */);
|
||||
|
||||
// Extract the first different characters of each string.
|
||||
__ sve_lasta(rscratch1, mode == LL ? __ B : __ H, pgtmp2, ztmp1);
|
||||
__ sve_lasta(rscratch2, mode == LL ? __ B : __ H, pgtmp2, ztmp2);
|
||||
|
||||
// Compute the difference of the first different characters.
|
||||
__ sub(result, rscratch1, rscratch2);
|
||||
|
||||
__ bind(DONE);
|
||||
__ ret(lr);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
// r0 = result
|
||||
// r1 = str1
|
||||
// r2 = cnt1
|
||||
@ -5428,7 +5337,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
}
|
||||
|
||||
void generate_compare_long_strings() {
|
||||
if (UseSVE == 0) {
|
||||
StubRoutines::aarch64::_compare_long_string_LL
|
||||
= generate_compare_long_string_same_encoding(true);
|
||||
StubRoutines::aarch64::_compare_long_string_UU
|
||||
@ -5437,16 +5345,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
= generate_compare_long_string_different_encoding(true);
|
||||
StubRoutines::aarch64::_compare_long_string_UL
|
||||
= generate_compare_long_string_different_encoding(false);
|
||||
} else {
|
||||
StubRoutines::aarch64::_compare_long_string_LL
|
||||
= generate_compare_long_string_sve(LL);
|
||||
StubRoutines::aarch64::_compare_long_string_UU
|
||||
= generate_compare_long_string_sve(UU);
|
||||
StubRoutines::aarch64::_compare_long_string_LU
|
||||
= generate_compare_long_string_sve(LU);
|
||||
StubRoutines::aarch64::_compare_long_string_UL
|
||||
= generate_compare_long_string_sve(UL);
|
||||
}
|
||||
}
|
||||
|
||||
// R0 = result
|
||||
|
@ -1,148 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, BELLSOFT. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.arm.benchmarks.intrinsics;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.CompilerControl;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Level;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Param;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
|
||||
import org.openjdk.jmh.infra.Blackhole;
|
||||
|
||||
/**
|
||||
* This benchmark modified from test/hotspot/jtreg/compiler/intrinsics/string/TestStringCompareToDifferentLength.java
|
||||
* This benchmark can be used to measure performance of compareTo() in
|
||||
* (Latin1, Latin1), (Latin1, UTF16), (UTF16, Latin1), and (UTF16, UTF16)
|
||||
* comparisons.
|
||||
*/
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
@State(Scope.Benchmark)
|
||||
@Measurement(iterations = 3, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
|
||||
@Warmup(iterations = 3, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public class StringCompareToDifferentLength {
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
public static class Input {
|
||||
@Param({"24", "36", "72", "128", "256", "512"})
|
||||
public int size;
|
||||
|
||||
@Param({"2"})
|
||||
public int delta;
|
||||
|
||||
int count = 100000;
|
||||
String longLatin1;
|
||||
String shortLatin1;
|
||||
String longUTF16FirstChar;
|
||||
String shortUTF16FirstChar;
|
||||
String longUTF16LastChar;
|
||||
String shortUTF16LastChar;
|
||||
|
||||
/**
|
||||
* Initialize. New array objects and set initial values.
|
||||
*/
|
||||
@Setup(Level.Trial)
|
||||
public void setup() throws Exception {
|
||||
char[] strsrc = new char[size + delta];
|
||||
// generate ASCII string
|
||||
for (int i = 0; i < size + delta; i++) {
|
||||
strsrc[i] = (char) ('a' + (i % 26));
|
||||
}
|
||||
|
||||
longLatin1 = new String(strsrc);
|
||||
shortLatin1 = longLatin1.substring(0, size);
|
||||
longUTF16LastChar = longLatin1.substring(0, longLatin1.length() - 1) + '\ubeef';
|
||||
longUTF16FirstChar = '\ubeef' + longLatin1.substring(1, longLatin1.length());
|
||||
shortUTF16LastChar = shortLatin1.substring(0, shortLatin1.length() - 1) + '\ubeef';
|
||||
shortUTF16FirstChar = longUTF16FirstChar.substring(0, size);
|
||||
}
|
||||
}
|
||||
|
||||
private int runCompareTo(String str2, String str1) {
|
||||
return str1.compareTo(str2);
|
||||
}
|
||||
|
||||
/**
|
||||
* latin1-latin1
|
||||
*/
|
||||
@Benchmark
|
||||
public void compareToLL(Input in, Blackhole blackhole) {
|
||||
int res = 0;
|
||||
for (int i = 0; i < in.count; ++i) {
|
||||
res += runCompareTo(in.longLatin1, in.shortLatin1);
|
||||
}
|
||||
blackhole.consume(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* UTF16-UTF16
|
||||
*/
|
||||
@Benchmark
|
||||
public void compareToUU(Input in, Blackhole blackhole) {
|
||||
int res = 0;
|
||||
for (int i = 0; i < in.count; ++i) {
|
||||
res += runCompareTo(in.longUTF16FirstChar, in.shortUTF16FirstChar);
|
||||
}
|
||||
blackhole.consume(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* latin1-UTF16
|
||||
*/
|
||||
@Benchmark
|
||||
public void compareToLU(Input in, Blackhole blackhole) {
|
||||
int res = 0;
|
||||
for (int i = 0; i < in.count; ++i) {
|
||||
res += runCompareTo(in.longUTF16LastChar, in.shortLatin1);
|
||||
}
|
||||
blackhole.consume(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* UTF16-latin1
|
||||
*/
|
||||
@Benchmark
|
||||
public void compareToUL(Input in, Blackhole blackhole) {
|
||||
int res = 0;
|
||||
for (int i = 0; i < in.count; ++i) {
|
||||
res += runCompareTo(in.longLatin1, in.shortUTF16LastChar);
|
||||
}
|
||||
blackhole.consume(res);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user