Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
3757fbff
D
dragonwell8_hotspot
项目概览
openanolis
/
dragonwell8_hotspot
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_hotspot
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
3757fbff
编写于
2月 09, 2011
作者:
N
never
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
7016474: string compare intrinsic improvements
Reviewed-by: kvn
上级
af33efa8
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
100 addition
and
50 deletion
+100
-50
src/cpu/x86/vm/assembler_x86.cpp
src/cpu/x86/vm/assembler_x86.cpp
+86
-39
src/cpu/x86/vm/assembler_x86.hpp
src/cpu/x86/vm/assembler_x86.hpp
+4
-1
src/cpu/x86/vm/x86_32.ad
src/cpu/x86/vm/x86_32.ad
+5
-5
src/cpu/x86/vm/x86_64.ad
src/cpu/x86/vm/x86_64.ad
+5
-5
未找到文件。
src/cpu/x86/vm/assembler_x86.cpp
浏览文件 @
3757fbff
...
...
@@ -2349,6 +2349,17 @@ void Assembler::prefix(Prefix p) {
a_byte
(
p
);
}
void
Assembler
::
por
(
XMMRegister
dst
,
XMMRegister
src
)
{
NOT_LP64
(
assert
(
VM_Version
::
supports_sse2
(),
""
));
emit_byte
(
0x66
);
int
encode
=
prefix_and_encode
(
dst
->
encoding
(),
src
->
encoding
());
emit_byte
(
0x0F
);
emit_byte
(
0xEB
);
emit_byte
(
0xC0
|
encode
);
}
void
Assembler
::
pshufd
(
XMMRegister
dst
,
XMMRegister
src
,
int
mode
)
{
assert
(
isByte
(
mode
),
"invalid value"
);
NOT_LP64
(
assert
(
VM_Version
::
supports_sse2
(),
""
));
...
...
@@ -8655,7 +8666,7 @@ void MacroAssembler::string_indexof(Register str1, Register str2,
// Compare strings.
void
MacroAssembler
::
string_compare
(
Register
str1
,
Register
str2
,
Register
cnt1
,
Register
cnt2
,
Register
result
,
XMMRegister
vec1
,
XMMRegister
vec2
)
{
XMMRegister
vec1
)
{
Label
LENGTH_DIFF_LABEL
,
POP_LABEL
,
DONE_LABEL
,
WHILE_HEAD_LABEL
;
// Compute the minimum of the string lengths and the
...
...
@@ -8702,62 +8713,85 @@ void MacroAssembler::string_compare(Register str1, Register str2,
bind
(
LSkip2
);
}
// Advance to next character
addptr
(
str1
,
2
);
addptr
(
str2
,
2
);
Address
::
ScaleFactor
scale
=
Address
::
times_2
;
int
stride
=
8
;
// Advance to next element
addptr
(
str1
,
16
/
stride
);
addptr
(
str2
,
16
/
stride
);
if
(
UseSSE42Intrinsics
)
{
// With SSE4.2, use double quad vector compare
Label
COMPARE_VECTORS
,
VECTOR_NOT_EQUAL
,
COMPARE_TAIL
;
Label
COMPARE_WIDE_VECTORS
,
VECTOR_NOT_EQUAL
,
COMPARE_TAIL
;
int
pcmpmask
=
0x19
;
// Setup to compare 16-byte vectors
movl
(
cnt1
,
cnt2
);
andl
(
cnt2
,
0xfffffff8
);
// cnt2 holds the vector count
andl
(
cnt1
,
0x00000007
);
// cnt1 holds the tail count
testl
(
cnt2
,
cnt2
);
movl
(
result
,
cnt2
);
andl
(
cnt2
,
~
(
stride
-
1
));
// cnt2 holds the vector count
jccb
(
Assembler
::
zero
,
COMPARE_TAIL
);
lea
(
str2
,
Address
(
str2
,
cnt2
,
Address
::
times_2
));
lea
(
str1
,
Address
(
str1
,
cnt2
,
Address
::
times_2
));
negptr
(
cnt2
);
lea
(
str1
,
Address
(
str1
,
result
,
scale
));
lea
(
str2
,
Address
(
str2
,
result
,
scale
));
negptr
(
result
);
// pcmpestri
// inputs:
// vec1- substring
// rax - negative string length (elements count)
// mem - scaned string
// rdx - string length (elements count)
// pcmpmask - cmp mode: 11000 (string compare with negated result)
// + 00 (unsigned bytes) or + 01 (unsigned shorts)
// outputs:
// rcx - first mismatched element index
assert
(
result
==
rax
&&
cnt2
==
rdx
&&
cnt1
==
rcx
,
"pcmpestri"
);
bind
(
COMPARE_VECTORS
);
movdqu
(
vec1
,
Address
(
str1
,
cnt2
,
Address
::
times_2
));
movdqu
(
vec2
,
Address
(
str2
,
cnt2
,
Address
::
times_2
));
pxor
(
vec1
,
vec2
);
ptest
(
vec1
,
vec1
);
jccb
(
Assembler
::
notZero
,
VECTOR_NOT_EQUAL
);
addptr
(
cnt2
,
8
);
jcc
(
Assembler
::
notZero
,
COMPARE_VECTORS
);
jmpb
(
COMPARE_TAIL
);
bind
(
COMPARE_WIDE_VECTORS
);
movdqu
(
vec1
,
Address
(
str1
,
result
,
scale
));
pcmpestri
(
vec1
,
Address
(
str2
,
result
,
scale
),
pcmpmask
);
// After pcmpestri cnt1(rcx) contains mismatched element index
jccb
(
Assembler
::
below
,
VECTOR_NOT_EQUAL
);
// CF==1
addptr
(
result
,
stride
);
subptr
(
cnt2
,
stride
);
jccb
(
Assembler
::
notZero
,
COMPARE_WIDE_VECTORS
);
// compare wide vectors tail
testl
(
result
,
result
);
jccb
(
Assembler
::
zero
,
LENGTH_DIFF_LABEL
);
movl
(
cnt2
,
stride
);
movl
(
result
,
stride
);
negptr
(
result
);
movdqu
(
vec1
,
Address
(
str1
,
result
,
scale
));
pcmpestri
(
vec1
,
Address
(
str2
,
result
,
scale
),
pcmpmask
);
jccb
(
Assembler
::
aboveEqual
,
LENGTH_DIFF_LABEL
);
// Mismatched characters in the vectors
bind
(
VECTOR_NOT_EQUAL
);
lea
(
str1
,
Address
(
str1
,
cnt2
,
Address
::
times_2
));
lea
(
str2
,
Address
(
str2
,
cnt2
,
Address
::
times_2
));
movl
(
cnt1
,
8
);
// Compare tail (< 8 chars), or rescan last vectors to
// find 1st mismatched characters
bind
(
COMPARE_TAIL
);
testl
(
cnt1
,
cnt1
);
jccb
(
Assembler
::
zero
,
LENGTH_DIFF_LABEL
);
movl
(
cnt2
,
cnt1
);
addptr
(
result
,
cnt1
);
movptr
(
cnt2
,
result
);
load_unsigned_short
(
result
,
Address
(
str1
,
cnt2
,
scale
));
load_unsigned_short
(
cnt1
,
Address
(
str2
,
cnt2
,
scale
));
subl
(
result
,
cnt1
);
jmpb
(
POP_LABEL
);
bind
(
COMPARE_TAIL
);
// limit is zero
movl
(
cnt2
,
result
);
// Fallthru to tail compare
}
// Shift str2 and str1 to the end of the arrays, negate min
lea
(
str1
,
Address
(
str1
,
cnt2
,
Address
::
times_2
,
0
));
lea
(
str2
,
Address
(
str2
,
cnt2
,
Address
::
times_2
,
0
));
lea
(
str1
,
Address
(
str1
,
cnt2
,
scale
,
0
));
lea
(
str2
,
Address
(
str2
,
cnt2
,
scale
,
0
));
negptr
(
cnt2
);
// Compare the rest of the character
s
// Compare the rest of the element
s
bind
(
WHILE_HEAD_LABEL
);
load_unsigned_short
(
result
,
Address
(
str1
,
cnt2
,
Address
::
times_2
,
0
));
load_unsigned_short
(
cnt1
,
Address
(
str2
,
cnt2
,
Address
::
times_2
,
0
));
load_unsigned_short
(
result
,
Address
(
str1
,
cnt2
,
scale
,
0
));
load_unsigned_short
(
cnt1
,
Address
(
str2
,
cnt2
,
scale
,
0
));
subl
(
result
,
cnt1
);
jccb
(
Assembler
::
notZero
,
POP_LABEL
);
increment
(
cnt2
);
jcc
(
Assembler
::
notZero
,
WHILE_HEAD_LABEL
);
jcc
b
(
Assembler
::
notZero
,
WHILE_HEAD_LABEL
);
// Strings are equal up to min length. Return the length difference.
bind
(
LENGTH_DIFF_LABEL
);
...
...
@@ -8766,7 +8800,7 @@ void MacroAssembler::string_compare(Register str1, Register str2,
// Discard the stored length difference
bind
(
POP_LABEL
);
addptr
(
rsp
,
wordSize
);
pop
(
cnt1
);
// That's it
bind
(
DONE_LABEL
);
...
...
@@ -8814,6 +8848,7 @@ void MacroAssembler::char_arrays_equals(bool is_array_equ, Register ary1, Regist
if
(
UseSSE42Intrinsics
)
{
// With SSE4.2, use double quad vector compare
Label
COMPARE_WIDE_VECTORS
,
COMPARE_TAIL
;
// Compare 16-byte vectors
andl
(
result
,
0x0000000e
);
// tail count (in bytes)
andl
(
limit
,
0xfffffff0
);
// vector count (in bytes)
...
...
@@ -8827,11 +8862,23 @@ void MacroAssembler::char_arrays_equals(bool is_array_equ, Register ary1, Regist
movdqu
(
vec1
,
Address
(
ary1
,
limit
,
Address
::
times_1
));
movdqu
(
vec2
,
Address
(
ary2
,
limit
,
Address
::
times_1
));
pxor
(
vec1
,
vec2
);
ptest
(
vec1
,
vec1
);
jccb
(
Assembler
::
notZero
,
FALSE_LABEL
);
addptr
(
limit
,
16
);
jcc
(
Assembler
::
notZero
,
COMPARE_WIDE_VECTORS
);
testl
(
result
,
result
);
jccb
(
Assembler
::
zero
,
TRUE_LABEL
);
movdqu
(
vec1
,
Address
(
ary1
,
result
,
Address
::
times_1
,
-
16
));
movdqu
(
vec2
,
Address
(
ary2
,
result
,
Address
::
times_1
,
-
16
));
pxor
(
vec1
,
vec2
);
ptest
(
vec1
,
vec1
);
jccb
(
Assembler
::
notZero
,
FALSE_LABEL
);
jmpb
(
TRUE_LABEL
);
bind
(
COMPARE_TAIL
);
// limit is zero
movl
(
limit
,
result
);
// Fallthru to tail compare
...
...
src/cpu/x86/vm/assembler_x86.hpp
浏览文件 @
3757fbff
...
...
@@ -1277,6 +1277,9 @@ private:
void
prefetcht2
(
Address
src
);
void
prefetchw
(
Address
src
);
// POR - Bitwise logical OR
void
por
(
XMMRegister
dst
,
XMMRegister
src
);
// Shuffle Packed Doublewords
void
pshufd
(
XMMRegister
dst
,
XMMRegister
src
,
int
mode
);
void
pshufd
(
XMMRegister
dst
,
Address
src
,
int
mode
);
...
...
@@ -2294,7 +2297,7 @@ public:
// Compare strings.
void
string_compare
(
Register
str1
,
Register
str2
,
Register
cnt1
,
Register
cnt2
,
Register
result
,
XMMRegister
vec1
,
XMMRegister
vec2
);
XMMRegister
vec1
);
// Compare char[] arrays.
void
char_arrays_equals
(
bool
is_array_equ
,
Register
ary1
,
Register
ary2
,
...
...
src/cpu/x86/vm/x86_32.ad
浏览文件 @
3757fbff
...
...
@@ -12629,16 +12629,16 @@ instruct rep_stos(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy, eFlag
ins_pipe( pipe_slow );
%}
instruct string_compare(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, e
B
XRegI cnt2,
eAXRegI result, regXD tmp1,
regXD tmp2,
eFlagsReg cr) %{
instruct string_compare(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, e
D
XRegI cnt2,
eAXRegI result, regXD tmp1, eFlagsReg cr) %{
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP tmp1,
TEMP tmp2,
USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
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
, $tmp2
" %}
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
, $tmp2$$XMMRegister
);
$tmp1$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
...
...
src/cpu/x86/vm/x86_64.ad
浏览文件 @
3757fbff
...
...
@@ -11583,17 +11583,17 @@ instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
ins_pipe(pipe_slow);
%}
instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, r
b
x_RegI cnt2,
rax_RegI result, regD tmp1, r
egD tmp2, r
FlagsReg cr)
instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, r
d
x_RegI cnt2,
rax_RegI result, regD tmp1, rFlagsReg cr)
%{
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP tmp1,
TEMP tmp2,
USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
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
, $tmp2
" %}
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
, $tmp2$$XMMRegister
);
$tmp1$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录