mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8317971: RISC-V: implement copySignF/D and signumF/D intrinsics
Reviewed-by: fyang, vkempik
This commit is contained in:
parent
91442878b7
commit
5a97411f85
5 changed files with 90 additions and 1 deletions
|
@ -1653,6 +1653,38 @@ void C2_MacroAssembler::round_double_mode(FloatRegister dst, FloatRegister src,
|
||||||
bind(done);
|
bind(done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// According to Java SE specification, for floating-point signum operations, if
|
||||||
|
// on input we have NaN or +/-0.0 value we should return it,
|
||||||
|
// otherwise return +/- 1.0 using sign of input.
|
||||||
|
// one - gives us a floating-point 1.0 (got from matching rule)
|
||||||
|
// bool is_double - specifies single or double precision operations will be used.
|
||||||
|
void C2_MacroAssembler::signum_fp(FloatRegister dst, FloatRegister src, FloatRegister one, bool is_double) {
|
||||||
|
Register tmp1 = t0;
|
||||||
|
|
||||||
|
Label done;
|
||||||
|
|
||||||
|
is_double ? fclass_d(tmp1, src)
|
||||||
|
: fclass_s(tmp1, src);
|
||||||
|
|
||||||
|
is_double ? fmv_d(dst, src)
|
||||||
|
: fmv_s(dst, src);
|
||||||
|
|
||||||
|
//bitmask 0b1100011000 specifies this bits:
|
||||||
|
// 3 - src is -0
|
||||||
|
// 4 - src is +0
|
||||||
|
// 8 - src is signaling NaN
|
||||||
|
// 9 - src is a quiet NaN
|
||||||
|
andi(tmp1, tmp1, 0b1100011000);
|
||||||
|
|
||||||
|
bnez(tmp1, done);
|
||||||
|
|
||||||
|
// use floating-point 1.0 with a sign of input
|
||||||
|
is_double ? fsgnj_d(dst, one, src)
|
||||||
|
: fsgnj_s(dst, one, src);
|
||||||
|
|
||||||
|
bind(done);
|
||||||
|
}
|
||||||
|
|
||||||
void C2_MacroAssembler::element_compare(Register a1, Register a2, Register result, Register cnt, Register tmp1, Register tmp2,
|
void C2_MacroAssembler::element_compare(Register a1, Register a2, Register result, Register cnt, Register tmp1, Register tmp2,
|
||||||
VectorRegister vr1, VectorRegister vr2, VectorRegister vrs, bool islatin, Label &DONE) {
|
VectorRegister vr1, VectorRegister vr2, VectorRegister vrs, bool islatin, Label &DONE) {
|
||||||
Label loop;
|
Label loop;
|
||||||
|
|
|
@ -157,6 +157,9 @@
|
||||||
void round_double_mode(FloatRegister dst, FloatRegister src, int round_mode,
|
void round_double_mode(FloatRegister dst, FloatRegister src, int round_mode,
|
||||||
Register tmp1, Register tmp2, Register tmp3);
|
Register tmp1, Register tmp2, Register tmp3);
|
||||||
|
|
||||||
|
void signum_fp(FloatRegister dst, FloatRegister src, FloatRegister one,
|
||||||
|
bool is_double);
|
||||||
|
|
||||||
// intrinsic methods implemented by rvv instructions
|
// intrinsic methods implemented by rvv instructions
|
||||||
void string_equals_v(Register r1, Register r2,
|
void string_equals_v(Register r1, Register r2,
|
||||||
Register result, Register cnt1,
|
Register result, Register cnt1,
|
||||||
|
|
|
@ -7506,6 +7506,52 @@ instruct roundD_reg(fRegD dst, fRegD src, immI rmode, iRegLNoSp tmp1, iRegLNoSp
|
||||||
ins_pipe(pipe_class_default);
|
ins_pipe(pipe_class_default);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
// Copysign and signum intrinsics
|
||||||
|
|
||||||
|
instruct copySignD_reg(fRegD dst, fRegD src1, fRegD src2, immD zero) %{
|
||||||
|
match(Set dst (CopySignD src1 (Binary src2 zero)));
|
||||||
|
format %{ "CopySignD $dst $src1 $src2" %}
|
||||||
|
ins_encode %{
|
||||||
|
FloatRegister dst = as_FloatRegister($dst$$reg),
|
||||||
|
src1 = as_FloatRegister($src1$$reg),
|
||||||
|
src2 = as_FloatRegister($src2$$reg);
|
||||||
|
__ fsgnj_d(dst, src1, src2);
|
||||||
|
%}
|
||||||
|
ins_pipe(fp_dop_reg_reg_d);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct copySignF_reg(fRegF dst, fRegF src1, fRegF src2) %{
|
||||||
|
match(Set dst (CopySignF src1 src2));
|
||||||
|
format %{ "CopySignF $dst $src1 $src2" %}
|
||||||
|
ins_encode %{
|
||||||
|
FloatRegister dst = as_FloatRegister($dst$$reg),
|
||||||
|
src1 = as_FloatRegister($src1$$reg),
|
||||||
|
src2 = as_FloatRegister($src2$$reg);
|
||||||
|
__ fsgnj_s(dst, src1, src2);
|
||||||
|
%}
|
||||||
|
ins_pipe(fp_dop_reg_reg_s);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct signumD_reg(fRegD dst, fRegD src, immD zero, fRegD one) %{
|
||||||
|
match(Set dst (SignumD src (Binary zero one)));
|
||||||
|
format %{ "signumD $dst, $src" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ signum_fp(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
|
||||||
|
as_FloatRegister($one$$reg), true /* is_double */);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_class_default);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct signumF_reg(fRegF dst, fRegF src, immF zero, fRegF one) %{
|
||||||
|
match(Set dst (SignumF src (Binary zero one)));
|
||||||
|
format %{ "signumF $dst, $src" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ signum_fp(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
|
||||||
|
as_FloatRegister($one$$reg), false /* is_double */);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_class_default);
|
||||||
|
%}
|
||||||
|
|
||||||
// Arithmetic Instructions End
|
// Arithmetic Instructions End
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
|
@ -191,6 +191,14 @@ void VM_Version::initialize() {
|
||||||
FLAG_SET_DEFAULT(UseMD5Intrinsics, true);
|
FLAG_SET_DEFAULT(UseMD5Intrinsics, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FLAG_IS_DEFAULT(UseCopySignIntrinsic)) {
|
||||||
|
FLAG_SET_DEFAULT(UseCopySignIntrinsic, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FLAG_IS_DEFAULT(UseSignumIntrinsic)) {
|
||||||
|
FLAG_SET_DEFAULT(UseSignumIntrinsic, true);
|
||||||
|
}
|
||||||
|
|
||||||
if (UseRVV) {
|
if (UseRVV) {
|
||||||
if (!ext_V.enabled()) {
|
if (!ext_V.enabled()) {
|
||||||
warning("RVV is not supported on this CPU");
|
warning("RVV is not supported on this CPU");
|
||||||
|
|
|
@ -471,7 +471,7 @@ public class MathBench {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
public double sigNumDouble() {
|
public double signumDouble() {
|
||||||
return Math.signum(double4Dot1);
|
return Math.signum(double4Dot1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue