Skip to content

New math intrinsics #65

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: riscv
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 156 additions & 17 deletions src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,94 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist
// End of helpers

address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
switch (kind) {
case Interpreter::java_lang_math_sin :
case Interpreter::java_lang_math_cos :
case Interpreter::java_lang_math_tan :
case Interpreter::java_lang_math_sqrt :
case Interpreter::java_lang_math_log :
case Interpreter::java_lang_math_log10:
case Interpreter::java_lang_math_pow :
case Interpreter::java_lang_math_exp :
case Interpreter::java_lang_math_minF :
case Interpreter::java_lang_math_maxF :
case Interpreter::java_lang_math_minD :
case Interpreter::java_lang_math_maxD :
case Interpreter::java_lang_math_absF :
case Interpreter::java_lang_math_abs :
case Interpreter::java_lang_math_fmaF :
case Interpreter::java_lang_math_fmaD : return generate_math_entry_float(kind);
case Interpreter::java_lang_math_min :
case Interpreter::java_lang_math_minL :
case Interpreter::java_lang_math_max :
case Interpreter::java_lang_math_maxL :
case Interpreter::java_lang_math_absI :
case Interpreter::java_lang_math_absL : return generate_math_entry_int(kind);
default: ShouldNotReachHere();
}
}

address TemplateInterpreterGenerator::generate_math_entry_int(AbstractInterpreter::MethodKind kind) {

int num_args = 1;
bool is_long = false;

// RISCV64 specific:
switch (kind) {
case Interpreter::java_lang_math_minL:
case Interpreter::java_lang_math_maxL: is_long = true;
case Interpreter::java_lang_math_min :
case Interpreter::java_lang_math_max : num_args = 2; break;
case Interpreter::java_lang_math_absL: is_long = true; break;
case Interpreter::java_lang_math_absI: break;
default: ShouldNotReachHere();
}

address entry = __ pc();

// Load arguments
assert(num_args <= 8, "passed in registers");
if (is_long) {
int offset = (2 * num_args - 1) * Interpreter::stackElementSize;
for (int i = 0; i < num_args; ++i) {
__ ld(as_Register(R10_ARG0->encoding() + i), R23_esp, offset);
offset -= 2 * Interpreter::stackElementSize;
}
} else {
int offset = num_args * Interpreter::stackElementSize;
for (int i = 0; i < num_args; ++i) {
__ lw(as_Register(R10_ARG0->encoding() + i), R23_esp, offset);
offset -= Interpreter::stackElementSize;
}
}

Label ret;

// If branch happens, the result is equal to the value in R10_ARG0 (same register as R10_RET1).
switch (kind) {
case Interpreter::java_lang_math_min :
case Interpreter::java_lang_math_minL: __ blt(R10_ARG0, R11_ARG1, ret); __ mv(R10_RET1, R11_ARG1); break;
case Interpreter::java_lang_math_max :
case Interpreter::java_lang_math_maxL: __ bge(R10_ARG0, R11_ARG1, ret); __ mv(R10_RET1, R11_ARG1); break;
case Interpreter::java_lang_math_absI:
case Interpreter::java_lang_math_absL: __ blt(R0_ZERO, R10_ARG0, ret); __ neg(R10_RET1, R10_ARG0); break;
default: ShouldNotReachHere();
}

__ bind(ret);

// Restore caller sp for c2i case (from compiled) and for resized sender frame (from interpreted).
__ mv(R2_SP, R21_sender_SP);
__ ret();



__ flush();

return entry;
}

address TemplateInterpreterGenerator::generate_math_entry_float(AbstractInterpreter::MethodKind kind) {

// Decide what to do: Use same platform specific instructions and runtime calls as compilers.
bool use_instruction = false;
Expand All @@ -1072,6 +1160,11 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
// RISCV64 specific:
switch (kind) {
case Interpreter::java_lang_math_sqrt:
case Interpreter::java_lang_math_minF:
case Interpreter::java_lang_math_minD:
case Interpreter::java_lang_math_maxF:
case Interpreter::java_lang_math_maxD:
case Interpreter::java_lang_math_absF:
case Interpreter::java_lang_math_abs : use_instruction = true; break;
case Interpreter::java_lang_math_fmaF:
case Interpreter::java_lang_math_fmaD: use_instruction = UseFMA; break;
Expand All @@ -1082,14 +1175,19 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
case Interpreter::java_lang_math_sin : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsin); break;
case Interpreter::java_lang_math_cos : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dcos); break;
case Interpreter::java_lang_math_tan : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dtan); break;
case Interpreter::java_lang_math_abs : /* run interpreted */ break;
case Interpreter::java_lang_math_sqrt : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsqrt); break;
case Interpreter::java_lang_math_log : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog); break;
case Interpreter::java_lang_math_log10: runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10); break;
case Interpreter::java_lang_math_pow : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dpow); num_args = 2; break;
case Interpreter::java_lang_math_exp : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dexp); break;
case Interpreter::java_lang_math_minF :
case Interpreter::java_lang_math_maxF : /* run interpreted */ num_args = 2; double_precision = false; break;
case Interpreter::java_lang_math_minD :
case Interpreter::java_lang_math_maxD : /* run interpreted */ num_args = 2; break;
case Interpreter::java_lang_math_absF : /* run interpreted */ double_precision = false; break;
case Interpreter::java_lang_math_abs : /* run interpreted */ break;
case Interpreter::java_lang_math_fmaF : /* run interpreted */ num_args = 3; double_precision = false; break;
case Interpreter::java_lang_math_fmaD : /* run interpreted */ num_args = 3; break;
case Interpreter::java_lang_math_fmaD : /* run interpreted */ num_args = 3; break;
default: ShouldNotReachHere();
}

Expand All @@ -1116,31 +1214,72 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M

int rm = Assembler::RNE;

Register Rscratch1 = R5_scratch1;
Label Lnan1;
Label Lnan2;

if (use_instruction) {
if (double_precision) {
switch (kind) {
case Interpreter::java_lang_math_sqrt: __ fsqrtd(F10_RET, F10_ARG0, rm); break;
case Interpreter::java_lang_math_abs: __ fsgnjxd(F10_RET, F10_ARG0, F10_ARG0); break;
case Interpreter::java_lang_math_fmaD: __ fmaddd(F10_RET, F10_ARG0, F11_ARG1, F12_ARG2, rm); break;
default: ShouldNotReachHere();
}
} else {
switch (kind) {
case Interpreter::java_lang_math_abs: __ fsgnjxs(F10_RET, F10_ARG0, F10_ARG0); break;
case Interpreter::java_lang_math_fmaF: __ fmadds(F10_RET, F10_ARG0, F11_ARG1, F12_ARG2, rm); break;
default: ShouldNotReachHere();
}
switch (kind) {
case Interpreter::java_lang_math_minF:
case Interpreter::java_lang_math_maxF:
__ fclasss(Rscratch1, F10_ARG0); // set bit 8 or 9 if NaN
__ srli(Rscratch1, Rscratch1, 8);
__ bnez(Rscratch1, Lnan1);
__ fclasss(Rscratch1, F11_ARG1); // set bit 8 or 9 if NaN
__ srli(Rscratch1, Rscratch1, 8);
__ bnez(Rscratch1, Lnan2);
break;
case Interpreter::java_lang_math_minD:
case Interpreter::java_lang_math_maxD:
__ fclassd(Rscratch1, F10_ARG0); // set bit 8 or 9 if NaN
__ srli(Rscratch1, Rscratch1, 8);
__ bnez(Rscratch1, Lnan1);
__ fclassd(Rscratch1, F11_ARG1); // set bit 8 or 9 if NaN
__ srli(Rscratch1, Rscratch1, 8);
__ bnez(Rscratch1, Lnan2);
break;
default: break;
}
switch (kind) {
case Interpreter::java_lang_math_sqrt: __ fsqrtd(F10_RET, F10_ARG0, rm); break;
case Interpreter::java_lang_math_minD: __ fmind(F10_RET, F10_ARG0, F11_ARG1); break;
case Interpreter::java_lang_math_maxD: __ fmaxd(F10_RET, F10_ARG0, F11_ARG1); break;
case Interpreter::java_lang_math_abs : __ fsgnjxd(F10_RET, F10_ARG0, F10_ARG0); break;
case Interpreter::java_lang_math_fmaD: __ fmaddd(F10_RET, F10_ARG0, F11_ARG1, F12_ARG2, rm); break;
case Interpreter::java_lang_math_minF: __ fmins(F10_RET, F10_ARG0, F11_ARG1); break;
case Interpreter::java_lang_math_maxF: __ fmaxs(F10_RET, F10_ARG0, F11_ARG1); break;
case Interpreter::java_lang_math_absF: __ fsgnjxs(F10_RET, F10_ARG0, F10_ARG0); break;
case Interpreter::java_lang_math_fmaF: __ fmadds(F10_RET, F10_ARG0, F11_ARG1, F12_ARG2, rm); break;
default: ShouldNotReachHere();
}
} else {
__ sd(R1_RA, R8_FP, _ijava_state(saved_ra));
__ call_VM_leaf(runtime_entry);
__ ld(R1_RA, R8_FP, _ijava_state(saved_ra));
}
}

// Restore caller sp for c2i case (from compiled) and for resized sender frame (from interpreted).
__ mv(R2_SP, R21_sender_SP);
__ ret();

__ bind(Lnan1);
if (double_precision) {
__ fmvd(F10_RET, F10_ARG0);
} else {
__ fmvs(F10_RET, F10_ARG0);
}
__ mv(R2_SP, R21_sender_SP);
__ ret();

__ bind(Lnan2);
if (double_precision) {
__ fmvd(F10_RET, F11_ARG1);
} else {
__ fmvs(F10_RET, F11_ARG1);
}
__ mv(R2_SP, R21_sender_SP);
__ ret();


__ flush();

return entry;
Expand Down
8 changes: 8 additions & 0 deletions src/hotspot/share/classfile/vmSymbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,10 @@ bool vmIntrinsics::is_disabled_by_flags(vmIntrinsics::ID id) {
case vmIntrinsics::_dpow:
case vmIntrinsics::_dlog10:
case vmIntrinsics::_datan2:
#ifdef RISCV
case vmIntrinsics::_minL:
case vmIntrinsics::_maxL:
#endif
case vmIntrinsics::_min:
case vmIntrinsics::_max:
case vmIntrinsics::_floatToIntBits:
Expand Down Expand Up @@ -1051,6 +1055,10 @@ void vmIntrinsics::verify_method(ID actual_id, Method* m) {
if (declared_id == _none && actual_id != _none && mk == vmSymbols::java_lang_StrictMath()) {
// Here are a few special cases in StrictMath not declared in vmSymbols.hpp.
switch (actual_id) {
#ifdef RISCV
case _minL:
case _maxL:
#endif
case _min:
case _max:
case _dsqrt:
Expand Down
2 changes: 2 additions & 0 deletions src/hotspot/share/classfile/vmSymbols.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,8 @@
do_intrinsic(_dlog10, java_lang_Math, log10_name, double_double_signature, F_S) \
do_intrinsic(_dpow, java_lang_Math, pow_name, double2_double_signature, F_S) \
do_intrinsic(_dexp, java_lang_Math, exp_name, double_double_signature, F_S) \
do_intrinsic(_minL, java_lang_Math, min_name, long2_long_signature, F_S) \
do_intrinsic(_maxL, java_lang_Math, max_name, long2_long_signature, F_S) \
do_intrinsic(_min, java_lang_Math, min_name, int2_int_signature, F_S) \
do_intrinsic(_max, java_lang_Math, max_name, int2_int_signature, F_S) \
Comment on lines 807 to 808
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to preserve original identifiers even if we would have min and minL. Various shared code could depend on names (JIT compilers for example)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restored _min/_max and abs symbols.

do_intrinsic(_addExactI, java_lang_Math, addExact_name, int2_int_signature, F_S) \
Expand Down
26 changes: 26 additions & 0 deletions src/hotspot/share/interpreter/abstractInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,19 @@ AbstractInterpreter::MethodKind AbstractInterpreter::method_kind(const methodHan
case vmIntrinsics::_dsin : return java_lang_math_sin ;
case vmIntrinsics::_dcos : return java_lang_math_cos ;
case vmIntrinsics::_dtan : return java_lang_math_tan ;
#ifdef RISCV
case vmIntrinsics::_min : return java_lang_math_min ;
case vmIntrinsics::_minL : return java_lang_math_minL ;
case vmIntrinsics::_minF : return java_lang_math_minF ;
case vmIntrinsics::_minD : return java_lang_math_minD ;
case vmIntrinsics::_max : return java_lang_math_max ;
case vmIntrinsics::_maxL : return java_lang_math_maxL ;
case vmIntrinsics::_maxF : return java_lang_math_maxF ;
case vmIntrinsics::_maxD : return java_lang_math_maxD ;
case vmIntrinsics::_iabs : return java_lang_math_absI ;
case vmIntrinsics::_labs : return java_lang_math_absL ;
case vmIntrinsics::_fabs : return java_lang_math_absF ;
#endif
case vmIntrinsics::_dabs : return java_lang_math_abs ;
case vmIntrinsics::_dsqrt : return java_lang_math_sqrt ;
case vmIntrinsics::_dlog : return java_lang_math_log ;
Expand Down Expand Up @@ -301,6 +314,19 @@ void AbstractInterpreter::print_method_kind(MethodKind kind) {
case java_lang_math_sin : tty->print("java_lang_math_sin" ); break;
case java_lang_math_cos : tty->print("java_lang_math_cos" ); break;
case java_lang_math_tan : tty->print("java_lang_math_tan" ); break;
#ifdef RISCV
case java_lang_math_min : tty->print("java_lang_math_minI" ); break;
case java_lang_math_minL : tty->print("java_lang_math_minL" ); break;
case java_lang_math_minF : tty->print("java_lang_math_minF" ); break;
case java_lang_math_minD : tty->print("java_lang_math_minD" ); break;
case java_lang_math_max : tty->print("java_lang_math_maxI" ); break;
case java_lang_math_maxL : tty->print("java_lang_math_maxL" ); break;
case java_lang_math_maxF : tty->print("java_lang_math_maxF" ); break;
case java_lang_math_maxD : tty->print("java_lang_math_maxD" ); break;
case java_lang_math_absI : tty->print("java_lang_math_absI" ); break;
case java_lang_math_absL : tty->print("java_lang_math_absL" ); break;
case java_lang_math_absF : tty->print("java_lang_math_absF" ); break;
#endif
case java_lang_math_abs : tty->print("java_lang_math_abs" ); break;
case java_lang_math_sqrt : tty->print("java_lang_math_sqrt" ); break;
case java_lang_math_log : tty->print("java_lang_math_log" ); break;
Expand Down
13 changes: 13 additions & 0 deletions src/hotspot/share/interpreter/abstractInterpreter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,19 @@ class AbstractInterpreter: AllStatic {
java_lang_math_sin, // implementation of java.lang.Math.sin (x)
java_lang_math_cos, // implementation of java.lang.Math.cos (x)
java_lang_math_tan, // implementation of java.lang.Math.tan (x)
#ifdef RISCV
java_lang_math_min, // implementation of java.lang.Math.min (x, y)
java_lang_math_minL, // implementation of java.lang.Math.max (x, y)
java_lang_math_minF, // implementation of java.lang.Math.min (x, y)
java_lang_math_minD, // implementation of java.lang.Math.min (x, y)
java_lang_math_max, // implementation of java.lang.Math.max (x, y)
java_lang_math_maxL, // implementation of java.lang.Math.max (x, y)
java_lang_math_maxF, // implementation of java.lang.Math.max (x, y)
java_lang_math_maxD, // implementation of java.lang.Math.max (x, y)
java_lang_math_absI, // implementation of java.lang.Math.abs (x)
java_lang_math_absL, // implementation of java.lang.Math.abs (x)
java_lang_math_absF, // implementation of java.lang.Math.abs (x)
#endif
java_lang_math_abs, // implementation of java.lang.Math.abs (x)
java_lang_math_sqrt, // implementation of java.lang.Math.sqrt (x)
java_lang_math_log, // implementation of java.lang.Math.log (x)
Expand Down
26 changes: 26 additions & 0 deletions src/hotspot/share/interpreter/templateInterpreterGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,19 @@ void TemplateInterpreterGenerator::generate_all() {
method_entry(java_lang_math_sin )
method_entry(java_lang_math_cos )
method_entry(java_lang_math_tan )
#ifdef RISCV
method_entry(java_lang_math_min )
method_entry(java_lang_math_minL )
method_entry(java_lang_math_minF )
method_entry(java_lang_math_minD )
method_entry(java_lang_math_max )
method_entry(java_lang_math_maxL )
method_entry(java_lang_math_maxF )
method_entry(java_lang_math_maxD )
method_entry(java_lang_math_absI )
method_entry(java_lang_math_absL )
method_entry(java_lang_math_absF )
#endif
method_entry(java_lang_math_abs )
method_entry(java_lang_math_sqrt )
method_entry(java_lang_math_log )
Expand Down Expand Up @@ -422,6 +435,19 @@ address TemplateInterpreterGenerator::generate_method_entry(
case Interpreter::java_lang_math_sin : // fall thru
case Interpreter::java_lang_math_cos : // fall thru
case Interpreter::java_lang_math_tan : // fall thru
#ifdef RISCV
case Interpreter::java_lang_math_min : // fall thru
case Interpreter::java_lang_math_minL : // fall thru
case Interpreter::java_lang_math_minF : // fall thru
case Interpreter::java_lang_math_minD : // fall thru
case Interpreter::java_lang_math_max : // fall thru
case Interpreter::java_lang_math_maxL : // fall thru
case Interpreter::java_lang_math_maxF : // fall thru
case Interpreter::java_lang_math_maxD : // fall thru
case Interpreter::java_lang_math_absI : // fall thru
case Interpreter::java_lang_math_absL : // fall thru
case Interpreter::java_lang_math_absF : // fall thru
#endif
case Interpreter::java_lang_math_abs : // fall thru
case Interpreter::java_lang_math_log : // fall thru
case Interpreter::java_lang_math_log10 : // fall thru
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ class TemplateInterpreterGenerator: public AbstractInterpreterGenerator {
#ifdef RISCV
void lock_method(Register Rflags, Register Rscratch1, Register Rscratch2, bool flags_preloaded=false);
void generate_fixed_frame(bool native_call, Register Rsize_of_parameters, Register Rsize_of_locals);
address generate_math_entry_float(AbstractInterpreter::MethodKind kind);
address generate_math_entry_int(AbstractInterpreter::MethodKind kind);
#endif // RISCV

public:
Expand Down
4 changes: 4 additions & 0 deletions src/hotspot/share/opto/c2compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,10 @@ bool C2Compiler::is_intrinsic_supported(const methodHandle& method, bool is_virt
case vmIntrinsics::_dlog:
case vmIntrinsics::_dlog10:
case vmIntrinsics::_dpow:
#ifdef RISCV
case vmIntrinsics::_minL:
case vmIntrinsics::_maxL:
#endif
case vmIntrinsics::_min:
case vmIntrinsics::_max:
case vmIntrinsics::_arraycopy:
Expand Down
6 changes: 4 additions & 2 deletions src/hotspot/share/opto/library_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -544,9 +544,11 @@ bool LibraryCallKit::try_to_inline(int predicate) {
case vmIntrinsics::_dlog10:
case vmIntrinsics::_dpow: return inline_math_native(intrinsic_id());

// FIXME_RISCV: add _minL and _maxL
case vmIntrinsics::_min:
case vmIntrinsics::_max: return inline_min_max(intrinsic_id());


case vmIntrinsics::_notify:
case vmIntrinsics::_notifyAll:
return inline_notify(intrinsic_id());
Expand Down Expand Up @@ -2177,9 +2179,9 @@ LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) {
// And they would interfere, anyway, with 'if' optimizations
// and with CMoveI canonical forms.
switch (id) {
case vmIntrinsics::_min:
case vmIntrinsics::_min: // FIXME_RISCV: add _minL
result_val = _gvn.transform(new (C, 3) MinINode(x,y)); break;
case vmIntrinsics::_max:
case vmIntrinsics::_max: // FIXME_RISCV: add _maxL
result_val = _gvn.transform(new (C, 3) MaxINode(x,y)); break;
default:
ShouldNotReachHere();
Expand Down
Loading