8360559: Optimize Math.sinh for x86 64 bit platforms

Reviewed-by: sviswanathan, sparasa
This commit is contained in:
Mohamed Issa 2025-08-04 18:47:57 +00:00 committed by Sandhya Viswanathan
parent b5f450a599
commit 05f8a6fca8
26 changed files with 742 additions and 3 deletions

View file

@ -174,6 +174,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
break;
case Interpreter::java_lang_math_fmaD:
case Interpreter::java_lang_math_fmaF:
case Interpreter::java_lang_math_sinh:
case Interpreter::java_lang_math_tanh:
case Interpreter::java_lang_math_cbrt:
// TODO: Implement intrinsic

View file

@ -1089,6 +1089,7 @@ 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_sinh : /* run interpreted */ break;
case Interpreter::java_lang_math_tanh : /* run interpreted */ break;
case Interpreter::java_lang_math_cbrt : /* run interpreted */ break;
case Interpreter::java_lang_math_abs : /* run interpreted */ break;

View file

@ -1239,6 +1239,7 @@ 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_sinh : /* run interpreted */ break;
case Interpreter::java_lang_math_tanh : /* run interpreted */ break;
case Interpreter::java_lang_math_cbrt : /* run interpreted */ break;
case Interpreter::java_lang_math_abs : /* run interpreted */ break;

View file

@ -720,8 +720,8 @@ void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
if (x->id() == vmIntrinsics::_dexp || x->id() == vmIntrinsics::_dlog ||
x->id() == vmIntrinsics::_dpow || x->id() == vmIntrinsics::_dcos ||
x->id() == vmIntrinsics::_dsin || x->id() == vmIntrinsics::_dtan ||
x->id() == vmIntrinsics::_dlog10 || x->id() == vmIntrinsics::_dtanh ||
x->id() == vmIntrinsics::_dcbrt
x->id() == vmIntrinsics::_dlog10 || x->id() == vmIntrinsics::_dsinh ||
x->id() == vmIntrinsics::_dtanh || x->id() == vmIntrinsics::_dcbrt
) {
do_LibmIntrinsic(x);
return;
@ -835,6 +835,12 @@ void LIRGenerator::do_LibmIntrinsic(Intrinsic* x) {
__ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtan), getThreadTemp(), result_reg, cc->args());
}
break;
case vmIntrinsics::_dsinh:
assert(StubRoutines::dsinh() != nullptr, "sinh intrinsic not found");
if (StubRoutines::dsinh() != nullptr) {
__ call_runtime_leaf(StubRoutines::dsinh(), getThreadTemp(), result_reg, cc->args());
}
break;
case vmIntrinsics::_dtanh:
assert(StubRoutines::dtanh() != nullptr, "tanh intrinsic not found");
if (StubRoutines::dtanh() != nullptr) {

View file

@ -3689,6 +3689,9 @@ void StubGenerator::generate_libm_stubs() {
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtan)) {
StubRoutines::_dtan = generate_libmTan(); // from stubGenerator_x86_64_tan.cpp
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsinh)) {
StubRoutines::_dsinh = generate_libmSinh(); // from stubGenerator_x86_64_sinh.cpp
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtanh)) {
StubRoutines::_dtanh = generate_libmTanh(); // from stubGenerator_x86_64_tanh.cpp
}

View file

@ -555,6 +555,7 @@ class StubGenerator: public StubCodeGenerator {
address generate_libmSin();
address generate_libmCos();
address generate_libmTan();
address generate_libmSinh();
address generate_libmTanh();
address generate_libmCbrt();
address generate_libmExp();

View file

@ -0,0 +1,525 @@
/*
* Copyright (c) 2025, Intel Corporation. All rights reserved.
* Intel Math Library (LIBM) Source Code
*
* 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.
*
*/
#include "macroAssembler_x86.hpp"
#include "stubGenerator_x86_64.hpp"
/******************************************************************************/
// ALGORITHM DESCRIPTION
// ---------------------
//
// sinh(x)=(exp(x)-exp(-x))/2
//
// Let |x|=xH+xL (upper 26 bits, lower 27 bits)
// log2(e) rounded to 26 bits (high part) plus a double precision low part is
// L2EH+L2EL (upper 26, lower 53 bits)
//
// Let xH*L2EH=k+f+r`, where (k+f)*2^7=int(xH*L2EH*2^7),
// f=0.b1 b2 ... b7, k integer
// 2^f is approximated as Tp[f]+Dp[f], and 2^{-f} as Tn[f]+Dn[f]
// Tp stores the high 53 bits, Dp stores (2^f-Tp[f]) rounded to double precision
//
// e^|x|=2^{k+f}*2^r, r=r`+xL*L2EH+|x|*L2EL, |r|<2^{-8}+2^{-14},
// for |x| in [23/64,3*2^7)
// e^{-|x|}=2^{-k-f}*2^{-r}
//
// e^|x| is approximated as 2^k*Tp+2^k*Tp*c1*r(1+c2*r+..+c5*r^4)+2^k*Dp=
// =2^k*Tp+2^k*Tp*P15+2^k*Dp
// e^{-|x|} approximated as 2^{-k}*Tn-2^{-k}*Tn*c1*r(1-c2*r+..+c5*r^4)+2^{-k}*Dn
//
// For |x| in [1/8, 3*2^7), sinh(x) is formed as
// RN(2^k*Tp-2^{-k}*Tn)+2^k*Tp*P15-2^{-k}*Tn*P`15-2^{-k}*TnL-2^{-k}*Dn+2^k*Dp
//
// For x in (3*2^7, 3*2^8), sign(x)*(e^|x|)/2 is returned, and
// the result is checked for overflow.
//
// For |x|<23/64, a Taylor polynomial expansion is used (degree 13)
// To reduce rounding errors, the p3*x^3 term is computed as
// (p3*xh^3)_high+[(p3*xl*(3*x*xh+xl^2))+(p3*xh^3)_low],
// where x=xh+xl, (xh are the leading 17 bits of x), and
// (p3*xh^3)_high=RN(x+p3*xh^3)-x
//
// Error bound:
// 0.51 ulp
//
// Special cases:
// sinh(NaN) = quiet NaN, and raise invalid exception
// sinh(+/-INF) = +/-INF
// sinh(+/-0) = +/-0
/******************************************************************************/
ATTRIBUTE_ALIGNED(8) static const juint _HALFMASK[] =
{
0xF8000000UL, 0x7FFFFFFFUL
};
ATTRIBUTE_ALIGNED(16) static const juint _MASK3[] =
{
0x00000000UL, 0xFFFFFFF0UL, 0x00000000UL, 0xFFFFFFF0UL
};
ATTRIBUTE_ALIGNED(16) static const juint _L2E[] =
{
0x60000000UL, 0x40671547UL, 0xF85DDF44UL, 0x3EC4AE0BUL
};
ATTRIBUTE_ALIGNED(16) static const juint _Shifter[] =
{
0x00000000UL, 0x43380000UL, 0x00000000UL, 0xC3380000UL
};
ATTRIBUTE_ALIGNED(16) static const juint _cv[] =
{
0xD704A0C0UL, 0x3E3C6B08UL, 0xD704A0C0UL, 0xBE3C6B08UL, 0xFEFA39EFUL,
0x3F662E42UL, 0xFEFA39EFUL, 0xBF662E42UL, 0x7F907D8BUL, 0x3D9F8445UL,
0x7F907D8BUL, 0x3D9F8445UL, 0xFFAC83B4UL, 0x3ED47FD3UL, 0xFFAC83B4UL,
0x3ED47FD3UL, 0xFEFA39EFUL, 0x3F762E42UL, 0xFEFA39EFUL, 0x3F762E42UL
};
ATTRIBUTE_ALIGNED(16) static const juint _pv[] =
{
0x13A86D08UL, 0x3DE61246UL, 0xA556C732UL, 0x3EC71DE3UL, 0x11111111UL,
0x3F811111UL, 0x55555555UL, 0x3FC55555UL, 0x67F544E1UL, 0x3E5AE645UL,
0x1A01A019UL, 0x3F2A01A0UL
};
ATTRIBUTE_ALIGNED(16) static const juint _T2f[] =
{
0x00000000UL, 0x3FF00000UL, 0x00000000UL, 0x00000000UL, 0xA9FB3335UL, 0x3FF0163DUL,
0x9AB8CDB7UL, 0x3C9B6129UL, 0x3E778061UL, 0x3FF02C9AUL, 0x535B085DUL, 0xBC719083UL,
0xE86E7F85UL, 0x3FF04315UL, 0x1977C96EUL, 0xBC90A31CUL, 0xD3158574UL, 0x3FF059B0UL,
0xA475B465UL, 0x3C8D73E2UL, 0x29DDF6DEUL, 0x3FF0706BUL, 0xE2B13C27UL, 0xBC8C91DFUL,
0x18759BC8UL, 0x3FF08745UL, 0x4BB284FFUL, 0x3C6186BEUL, 0xCAC6F383UL, 0x3FF09E3EUL,
0x18316136UL, 0x3C914878UL, 0x6CF9890FUL, 0x3FF0B558UL, 0x4ADC610BUL, 0x3C98A62EUL,
0x2B7247F7UL, 0x3FF0CC92UL, 0x16E24F71UL, 0x3C901EDCUL, 0x32D3D1A2UL, 0x3FF0E3ECUL,
0x27C57B52UL, 0x3C403A17UL, 0xAFFED31BUL, 0x3FF0FB66UL, 0xC44EBD7BUL, 0xBC6B9BEDUL,
0xD0125B51UL, 0x3FF11301UL, 0x39449B3AUL, 0xBC96C510UL, 0xC06C31CCUL, 0x3FF12ABDUL,
0xB36CA5C7UL, 0xBC51B514UL, 0xAEA92DE0UL, 0x3FF1429AUL, 0x9AF1369EUL, 0xBC932FBFUL,
0xC8A58E51UL, 0x3FF15A98UL, 0xB9EEAB0AUL, 0x3C82406AUL, 0x3C7D517BUL, 0x3FF172B8UL,
0xB9D78A76UL, 0xBC819041UL, 0x388C8DEAUL, 0x3FF18AF9UL, 0xD1970F6CUL, 0xBC911023UL,
0xEB6FCB75UL, 0x3FF1A35BUL, 0x7B4968E4UL, 0x3C8E5B4CUL, 0x84045CD4UL, 0x3FF1BBE0UL,
0x352EF607UL, 0xBC995386UL, 0x3168B9AAUL, 0x3FF1D487UL, 0x00A2643CUL, 0x3C9E016EUL,
0x22FCD91DUL, 0x3FF1ED50UL, 0x027BB78CUL, 0xBC91DF98UL, 0x88628CD6UL, 0x3FF2063BUL,
0x814A8495UL, 0x3C8DC775UL, 0x917DDC96UL, 0x3FF21F49UL, 0x9494A5EEUL, 0x3C82A97EUL,
0x6E756238UL, 0x3FF2387AUL, 0xB6C70573UL, 0x3C99B07EUL, 0x4FB2A63FUL, 0x3FF251CEUL,
0xBEF4F4A4UL, 0x3C8AC155UL, 0x65E27CDDUL, 0x3FF26B45UL, 0x9940E9D9UL, 0x3C82BD33UL,
0xE1F56381UL, 0x3FF284DFUL, 0x8C3F0D7EUL, 0xBC9A4C3AUL, 0xF51FDEE1UL, 0x3FF29E9DUL,
0xAFAD1255UL, 0x3C8612E8UL, 0xD0DAD990UL, 0x3FF2B87FUL, 0xD6381AA4UL, 0xBC410ADCUL,
0xA6E4030BUL, 0x3FF2D285UL, 0x54DB41D5UL, 0x3C900247UL, 0xA93E2F56UL, 0x3FF2ECAFUL,
0x45D52383UL, 0x3C71CA0FUL, 0x0A31B715UL, 0x3FF306FEUL, 0xD23182E4UL, 0x3C86F46AUL,
0xFC4CD831UL, 0x3FF32170UL, 0x8E18047CUL, 0x3C8A9CE7UL, 0xB26416FFUL, 0x3FF33C08UL,
0x843659A6UL, 0x3C932721UL, 0x5F929FF1UL, 0x3FF356C5UL, 0x5C4E4628UL, 0xBC8B5CEEUL,
0x373AA9CBUL, 0x3FF371A7UL, 0xBF42EAE2UL, 0xBC963AEAUL, 0x6D05D866UL, 0x3FF38CAEUL,
0x3C9904BDUL, 0xBC9E958DUL, 0x34E59FF7UL, 0x3FF3A7DBUL, 0xD661F5E3UL, 0xBC75E436UL,
0xC313A8E5UL, 0x3FF3C32DUL, 0x375D29C3UL, 0xBC9EFFF8UL, 0x4C123422UL, 0x3FF3DEA6UL,
0x11F09EBCUL, 0x3C8ADA09UL, 0x04AC801CUL, 0x3FF3FA45UL, 0xF956F9F3UL, 0xBC97D023UL,
0x21F72E2AUL, 0x3FF4160AUL, 0x1C309278UL, 0xBC5EF369UL, 0xD950A897UL, 0x3FF431F5UL,
0xE35F7999UL, 0xBC81C7DDUL, 0x6061892DUL, 0x3FF44E08UL, 0x04EF80D0UL, 0x3C489B7AUL,
0xED1D0057UL, 0x3FF46A41UL, 0xD1648A76UL, 0x3C9C944BUL, 0xB5C13CD0UL, 0x3FF486A2UL,
0xB69062F0UL, 0x3C73C1A3UL, 0xF0D7D3DEUL, 0x3FF4A32AUL, 0xF3D1BE56UL, 0x3C99CB62UL,
0xD5362A27UL, 0x3FF4BFDAUL, 0xAFEC42E2UL, 0x3C7D4397UL, 0x99FDDD0DUL, 0x3FF4DCB2UL,
0xBC6A7833UL, 0x3C98ECDBUL, 0x769D2CA7UL, 0x3FF4F9B2UL, 0xD25957E3UL, 0xBC94B309UL,
0xA2CF6642UL, 0x3FF516DAUL, 0x69BD93EFUL, 0xBC8F7685UL, 0x569D4F82UL, 0x3FF5342BUL,
0x1DB13CADUL, 0xBC807ABEUL, 0xCA5D920FUL, 0x3FF551A4UL, 0xEFEDE59BUL, 0xBC8D689CUL,
0x36B527DAUL, 0x3FF56F47UL, 0x011D93ADUL, 0x3C99BB2CUL, 0xD497C7FDUL, 0x3FF58D12UL,
0x5B9A1DE8UL, 0x3C8295E1UL, 0xDD485429UL, 0x3FF5AB07UL, 0x054647ADUL, 0x3C96324CUL,
0x8A5946B7UL, 0x3FF5C926UL, 0x816986A2UL, 0x3C3C4B1BUL, 0x15AD2148UL, 0x3FF5E76FUL,
0x3080E65EUL, 0x3C9BA6F9UL, 0xB976DC09UL, 0x3FF605E1UL, 0x9B56DE47UL, 0xBC93E242UL,
0xB03A5585UL, 0x3FF6247EUL, 0x7E40B497UL, 0xBC9383C1UL, 0x34CCC320UL, 0x3FF64346UL,
0x759D8933UL, 0xBC8C483CUL, 0x82552225UL, 0x3FF66238UL, 0x87591C34UL, 0xBC9BB609UL,
0xD44CA973UL, 0x3FF68155UL, 0x44F73E65UL, 0x3C6038AEUL, 0x667F3BCDUL, 0x3FF6A09EUL,
0x13B26456UL, 0xBC9BDD34UL, 0x750BDABFUL, 0x3FF6C012UL, 0x67FF0B0DUL, 0xBC728956UL,
0x3C651A2FUL, 0x3FF6DFB2UL, 0x683C88ABUL, 0xBC6BBE3AUL, 0xF9519484UL, 0x3FF6FF7DUL,
0x25860EF6UL, 0xBC883C0FUL, 0xE8EC5F74UL, 0x3FF71F75UL, 0x86887A99UL, 0xBC816E47UL,
0x48A58174UL, 0x3FF73F9AUL, 0x6C65D53CUL, 0xBC90A8D9UL, 0x564267C9UL, 0x3FF75FEBUL,
0x57316DD3UL, 0xBC902459UL, 0x4FDE5D3FUL, 0x3FF78069UL, 0x0A02162DUL, 0x3C9866B8UL,
0x73EB0187UL, 0x3FF7A114UL, 0xEE04992FUL, 0xBC841577UL, 0x0130C132UL, 0x3FF7C1EDUL,
0xD1164DD6UL, 0x3C9F124CUL, 0x36CF4E62UL, 0x3FF7E2F3UL, 0xBA15797EUL, 0x3C705D02UL,
0x543E1A12UL, 0x3FF80427UL, 0x626D972BUL, 0xBC927C86UL, 0x994CCE13UL, 0x3FF82589UL,
0xD41532D8UL, 0xBC9D4C1DUL, 0x4623C7ADUL, 0x3FF8471AUL, 0xA341CDFBUL, 0xBC88D684UL,
0x9B4492EDUL, 0x3FF868D9UL, 0x9BD4F6BAUL, 0xBC9FC6F8UL, 0xD98A6699UL, 0x3FF88AC7UL,
0xF37CB53AUL, 0x3C9994C2UL, 0x422AA0DBUL, 0x3FF8ACE5UL, 0x56864B27UL, 0x3C96E9F1UL,
0x16B5448CUL, 0x3FF8CF32UL, 0x32E9E3AAUL, 0xBC70D55EUL, 0x99157736UL, 0x3FF8F1AEUL,
0xA2E3976CUL, 0x3C85CC13UL, 0x0B91FFC6UL, 0x3FF9145BUL, 0x2E582524UL, 0xBC9DD679UL,
0xB0CDC5E5UL, 0x3FF93737UL, 0x81B57EBCUL, 0xBC675FC7UL, 0xCBC8520FUL, 0x3FF95A44UL,
0x96A5F039UL, 0xBC764B7CUL, 0x9FDE4E50UL, 0x3FF97D82UL, 0x7C1B85D1UL, 0xBC9D185BUL,
0x70CA07BAUL, 0x3FF9A0F1UL, 0x91CEE632UL, 0xBC9173BDUL, 0x82A3F090UL, 0x3FF9C491UL,
0xB071F2BEUL, 0x3C7C7C46UL, 0x19E32323UL, 0x3FF9E863UL, 0x78E64C6EUL, 0x3C7824CAUL,
0x7B5DE565UL, 0x3FFA0C66UL, 0x5D1CD533UL, 0xBC935949UL, 0xEC4A2D33UL, 0x3FFA309BUL,
0x7DDC36ABUL, 0x3C96305CUL, 0xB23E255DUL, 0x3FFA5503UL, 0xDB8D41E1UL, 0xBC9D2F6EUL,
0x1330B358UL, 0x3FFA799EUL, 0xCAC563C7UL, 0x3C9BCB7EUL, 0x5579FDBFUL, 0x3FFA9E6BUL,
0x0EF7FD31UL, 0x3C90FAC9UL, 0xBFD3F37AUL, 0x3FFAC36BUL, 0xCAE76CD0UL, 0xBC8F9234UL,
0x995AD3ADUL, 0x3FFAE89FUL, 0x345DCC81UL, 0x3C97A1CDUL, 0x298DB666UL, 0x3FFB0E07UL,
0x4C80E425UL, 0xBC9BDEF5UL, 0xB84F15FBUL, 0x3FFB33A2UL, 0x3084D708UL, 0xBC62805EUL,
0x8DE5593AUL, 0x3FFB5972UL, 0xBBBA6DE3UL, 0xBC9C71DFUL, 0xF2FB5E47UL, 0x3FFB7F76UL,
0x7E54AC3BUL, 0xBC75584FUL, 0x30A1064AUL, 0x3FFBA5B0UL, 0x0E54292EUL, 0xBC9EFCD3UL,
0x904BC1D2UL, 0x3FFBCC1EUL, 0x7A2D9E84UL, 0x3C823DD0UL, 0x5BD71E09UL, 0x3FFBF2C2UL,
0x3F6B9C73UL, 0xBC9EFDCAUL, 0xDD85529CUL, 0x3FFC199BUL, 0x895048DDUL, 0x3C811065UL,
0x5FFFD07AUL, 0x3FFC40ABUL, 0xE083C60AUL, 0x3C9B4537UL, 0x2E57D14BUL, 0x3FFC67F1UL,
0xFF483CADUL, 0x3C92884DUL, 0x9406E7B5UL, 0x3FFC8F6DUL, 0x48805C44UL, 0x3C71ACBCUL,
0xDCEF9069UL, 0x3FFCB720UL, 0xD1E949DCUL, 0x3C7503CBUL, 0x555DC3FAUL, 0x3FFCDF0BUL,
0x53829D72UL, 0xBC8DD83BUL, 0x4A07897CUL, 0x3FFD072DUL, 0x43797A9CUL, 0xBC9CBC37UL,
0x080D89F2UL, 0x3FFD2F87UL, 0x719D8578UL, 0xBC9D487BUL, 0xDCFBA487UL, 0x3FFD5818UL,
0xD75B3707UL, 0x3C82ED02UL, 0x16C98398UL, 0x3FFD80E3UL, 0x8BEDDFE8UL, 0xBC911EC1UL,
0x03DB3285UL, 0x3FFDA9E6UL, 0x696DB532UL, 0x3C9C2300UL, 0xF301B460UL, 0x3FFDD321UL,
0x78F018C3UL, 0x3C92DA57UL, 0x337B9B5FUL, 0x3FFDFC97UL, 0x4F184B5CUL, 0xBC91A5CDUL,
0x14F5A129UL, 0x3FFE2646UL, 0x817A1496UL, 0xBC97B627UL, 0xE78B3FF6UL, 0x3FFE502EUL,
0x80A9CC8FUL, 0x3C839E89UL, 0xFBC74C83UL, 0x3FFE7A51UL, 0xCA0C8DE2UL, 0x3C92D522UL,
0xA2A490DAUL, 0x3FFEA4AFUL, 0x179C2893UL, 0xBC9E9C23UL, 0x2D8E67F1UL, 0x3FFECF48UL,
0xB411AD8CUL, 0xBC9C93F3UL, 0xEE615A27UL, 0x3FFEFA1BUL, 0x86A4B6B0UL, 0x3C9DC7F4UL,
0x376BBA97UL, 0x3FFF252BUL, 0xBF0D8E43UL, 0x3C93A1A5UL, 0x5B6E4540UL, 0x3FFF5076UL,
0x2DD8A18BUL, 0x3C99D3E1UL, 0xAD9CBE14UL, 0x3FFF7BFDUL, 0xD006350AUL, 0xBC9DBB12UL,
0x819E90D8UL, 0x3FFFA7C1UL, 0xF3A5931EUL, 0x3C874853UL, 0x2B8F71F1UL, 0x3FFFD3C2UL,
0x966579E7UL, 0x3C62EB74UL
};
ATTRIBUTE_ALIGNED(16) static const juint _T2_neg_f[] =
{
0x00000000UL, 0x3FF00000UL, 0x00000000UL, 0x00000000UL, 0x2B8F71F1UL, 0x3FEFD3C2UL,
0x966579E7UL, 0x3C52EB74UL, 0x819E90D8UL, 0x3FEFA7C1UL, 0xF3A5931EUL, 0x3C774853UL,
0xAD9CBE14UL, 0x3FEF7BFDUL, 0xD006350AUL, 0xBC8DBB12UL, 0x5B6E4540UL, 0x3FEF5076UL,
0x2DD8A18BUL, 0x3C89D3E1UL, 0x376BBA97UL, 0x3FEF252BUL, 0xBF0D8E43UL, 0x3C83A1A5UL,
0xEE615A27UL, 0x3FEEFA1BUL, 0x86A4B6B0UL, 0x3C8DC7F4UL, 0x2D8E67F1UL, 0x3FEECF48UL,
0xB411AD8CUL, 0xBC8C93F3UL, 0xA2A490DAUL, 0x3FEEA4AFUL, 0x179C2893UL, 0xBC8E9C23UL,
0xFBC74C83UL, 0x3FEE7A51UL, 0xCA0C8DE2UL, 0x3C82D522UL, 0xE78B3FF6UL, 0x3FEE502EUL,
0x80A9CC8FUL, 0x3C739E89UL, 0x14F5A129UL, 0x3FEE2646UL, 0x817A1496UL, 0xBC87B627UL,
0x337B9B5FUL, 0x3FEDFC97UL, 0x4F184B5CUL, 0xBC81A5CDUL, 0xF301B460UL, 0x3FEDD321UL,
0x78F018C3UL, 0x3C82DA57UL, 0x03DB3285UL, 0x3FEDA9E6UL, 0x696DB532UL, 0x3C8C2300UL,
0x16C98398UL, 0x3FED80E3UL, 0x8BEDDFE8UL, 0xBC811EC1UL, 0xDCFBA487UL, 0x3FED5818UL,
0xD75B3707UL, 0x3C72ED02UL, 0x080D89F2UL, 0x3FED2F87UL, 0x719D8578UL, 0xBC8D487BUL,
0x4A07897CUL, 0x3FED072DUL, 0x43797A9CUL, 0xBC8CBC37UL, 0x555DC3FAUL, 0x3FECDF0BUL,
0x53829D72UL, 0xBC7DD83BUL, 0xDCEF9069UL, 0x3FECB720UL, 0xD1E949DCUL, 0x3C6503CBUL,
0x9406E7B5UL, 0x3FEC8F6DUL, 0x48805C44UL, 0x3C61ACBCUL, 0x2E57D14BUL, 0x3FEC67F1UL,
0xFF483CADUL, 0x3C82884DUL, 0x5FFFD07AUL, 0x3FEC40ABUL, 0xE083C60AUL, 0x3C8B4537UL,
0xDD85529CUL, 0x3FEC199BUL, 0x895048DDUL, 0x3C711065UL, 0x5BD71E09UL, 0x3FEBF2C2UL,
0x3F6B9C73UL, 0xBC8EFDCAUL, 0x904BC1D2UL, 0x3FEBCC1EUL, 0x7A2D9E84UL, 0x3C723DD0UL,
0x30A1064AUL, 0x3FEBA5B0UL, 0x0E54292EUL, 0xBC8EFCD3UL, 0xF2FB5E47UL, 0x3FEB7F76UL,
0x7E54AC3BUL, 0xBC65584FUL, 0x8DE5593AUL, 0x3FEB5972UL, 0xBBBA6DE3UL, 0xBC8C71DFUL,
0xB84F15FBUL, 0x3FEB33A2UL, 0x3084D708UL, 0xBC52805EUL, 0x298DB666UL, 0x3FEB0E07UL,
0x4C80E425UL, 0xBC8BDEF5UL, 0x995AD3ADUL, 0x3FEAE89FUL, 0x345DCC81UL, 0x3C87A1CDUL,
0xBFD3F37AUL, 0x3FEAC36BUL, 0xCAE76CD0UL, 0xBC7F9234UL, 0x5579FDBFUL, 0x3FEA9E6BUL,
0x0EF7FD31UL, 0x3C80FAC9UL, 0x1330B358UL, 0x3FEA799EUL, 0xCAC563C7UL, 0x3C8BCB7EUL,
0xB23E255DUL, 0x3FEA5503UL, 0xDB8D41E1UL, 0xBC8D2F6EUL, 0xEC4A2D33UL, 0x3FEA309BUL,
0x7DDC36ABUL, 0x3C86305CUL, 0x7B5DE565UL, 0x3FEA0C66UL, 0x5D1CD533UL, 0xBC835949UL,
0x19E32323UL, 0x3FE9E863UL, 0x78E64C6EUL, 0x3C6824CAUL, 0x82A3F090UL, 0x3FE9C491UL,
0xB071F2BEUL, 0x3C6C7C46UL, 0x70CA07BAUL, 0x3FE9A0F1UL, 0x91CEE632UL, 0xBC8173BDUL,
0x9FDE4E50UL, 0x3FE97D82UL, 0x7C1B85D1UL, 0xBC8D185BUL, 0xCBC8520FUL, 0x3FE95A44UL,
0x96A5F039UL, 0xBC664B7CUL, 0xB0CDC5E5UL, 0x3FE93737UL, 0x81B57EBCUL, 0xBC575FC7UL,
0x0B91FFC6UL, 0x3FE9145BUL, 0x2E582524UL, 0xBC8DD679UL, 0x99157736UL, 0x3FE8F1AEUL,
0xA2E3976CUL, 0x3C75CC13UL, 0x16B5448CUL, 0x3FE8CF32UL, 0x32E9E3AAUL, 0xBC60D55EUL,
0x422AA0DBUL, 0x3FE8ACE5UL, 0x56864B27UL, 0x3C86E9F1UL, 0xD98A6699UL, 0x3FE88AC7UL,
0xF37CB53AUL, 0x3C8994C2UL, 0x9B4492EDUL, 0x3FE868D9UL, 0x9BD4F6BAUL, 0xBC8FC6F8UL,
0x4623C7ADUL, 0x3FE8471AUL, 0xA341CDFBUL, 0xBC78D684UL, 0x994CCE13UL, 0x3FE82589UL,
0xD41532D8UL, 0xBC8D4C1DUL, 0x543E1A12UL, 0x3FE80427UL, 0x626D972BUL, 0xBC827C86UL,
0x36CF4E62UL, 0x3FE7E2F3UL, 0xBA15797EUL, 0x3C605D02UL, 0x0130C132UL, 0x3FE7C1EDUL,
0xD1164DD6UL, 0x3C8F124CUL, 0x73EB0187UL, 0x3FE7A114UL, 0xEE04992FUL, 0xBC741577UL,
0x4FDE5D3FUL, 0x3FE78069UL, 0x0A02162DUL, 0x3C8866B8UL, 0x564267C9UL, 0x3FE75FEBUL,
0x57316DD3UL, 0xBC802459UL, 0x48A58174UL, 0x3FE73F9AUL, 0x6C65D53CUL, 0xBC80A8D9UL,
0xE8EC5F74UL, 0x3FE71F75UL, 0x86887A99UL, 0xBC716E47UL, 0xF9519484UL, 0x3FE6FF7DUL,
0x25860EF6UL, 0xBC783C0FUL, 0x3C651A2FUL, 0x3FE6DFB2UL, 0x683C88ABUL, 0xBC5BBE3AUL,
0x750BDABFUL, 0x3FE6C012UL, 0x67FF0B0DUL, 0xBC628956UL, 0x667F3BCDUL, 0x3FE6A09EUL,
0x13B26456UL, 0xBC8BDD34UL, 0xD44CA973UL, 0x3FE68155UL, 0x44F73E65UL, 0x3C5038AEUL,
0x82552225UL, 0x3FE66238UL, 0x87591C34UL, 0xBC8BB609UL, 0x34CCC320UL, 0x3FE64346UL,
0x759D8933UL, 0xBC7C483CUL, 0xB03A5585UL, 0x3FE6247EUL, 0x7E40B497UL, 0xBC8383C1UL,
0xB976DC09UL, 0x3FE605E1UL, 0x9B56DE47UL, 0xBC83E242UL, 0x15AD2148UL, 0x3FE5E76FUL,
0x3080E65EUL, 0x3C8BA6F9UL, 0x8A5946B7UL, 0x3FE5C926UL, 0x816986A2UL, 0x3C2C4B1BUL,
0xDD485429UL, 0x3FE5AB07UL, 0x054647ADUL, 0x3C86324CUL, 0xD497C7FDUL, 0x3FE58D12UL,
0x5B9A1DE8UL, 0x3C7295E1UL, 0x36B527DAUL, 0x3FE56F47UL, 0x011D93ADUL, 0x3C89BB2CUL,
0xCA5D920FUL, 0x3FE551A4UL, 0xEFEDE59BUL, 0xBC7D689CUL, 0x569D4F82UL, 0x3FE5342BUL,
0x1DB13CADUL, 0xBC707ABEUL, 0xA2CF6642UL, 0x3FE516DAUL, 0x69BD93EFUL, 0xBC7F7685UL,
0x769D2CA7UL, 0x3FE4F9B2UL, 0xD25957E3UL, 0xBC84B309UL, 0x99FDDD0DUL, 0x3FE4DCB2UL,
0xBC6A7833UL, 0x3C88ECDBUL, 0xD5362A27UL, 0x3FE4BFDAUL, 0xAFEC42E2UL, 0x3C6D4397UL,
0xF0D7D3DEUL, 0x3FE4A32AUL, 0xF3D1BE56UL, 0x3C89CB62UL, 0xB5C13CD0UL, 0x3FE486A2UL,
0xB69062F0UL, 0x3C63C1A3UL, 0xED1D0057UL, 0x3FE46A41UL, 0xD1648A76UL, 0x3C8C944BUL,
0x6061892DUL, 0x3FE44E08UL, 0x04EF80D0UL, 0x3C389B7AUL, 0xD950A897UL, 0x3FE431F5UL,
0xE35F7999UL, 0xBC71C7DDUL, 0x21F72E2AUL, 0x3FE4160AUL, 0x1C309278UL, 0xBC4EF369UL,
0x04AC801CUL, 0x3FE3FA45UL, 0xF956F9F3UL, 0xBC87D023UL, 0x4C123422UL, 0x3FE3DEA6UL,
0x11F09EBCUL, 0x3C7ADA09UL, 0xC313A8E5UL, 0x3FE3C32DUL, 0x375D29C3UL, 0xBC8EFFF8UL,
0x34E59FF7UL, 0x3FE3A7DBUL, 0xD661F5E3UL, 0xBC65E436UL, 0x6D05D866UL, 0x3FE38CAEUL,
0x3C9904BDUL, 0xBC8E958DUL, 0x373AA9CBUL, 0x3FE371A7UL, 0xBF42EAE2UL, 0xBC863AEAUL,
0x5F929FF1UL, 0x3FE356C5UL, 0x5C4E4628UL, 0xBC7B5CEEUL, 0xB26416FFUL, 0x3FE33C08UL,
0x843659A6UL, 0x3C832721UL, 0xFC4CD831UL, 0x3FE32170UL, 0x8E18047CUL, 0x3C7A9CE7UL,
0x0A31B715UL, 0x3FE306FEUL, 0xD23182E4UL, 0x3C76F46AUL, 0xA93E2F56UL, 0x3FE2ECAFUL,
0x45D52383UL, 0x3C61CA0FUL, 0xA6E4030BUL, 0x3FE2D285UL, 0x54DB41D5UL, 0x3C800247UL,
0xD0DAD990UL, 0x3FE2B87FUL, 0xD6381AA4UL, 0xBC310ADCUL, 0xF51FDEE1UL, 0x3FE29E9DUL,
0xAFAD1255UL, 0x3C7612E8UL, 0xE1F56381UL, 0x3FE284DFUL, 0x8C3F0D7EUL, 0xBC8A4C3AUL,
0x65E27CDDUL, 0x3FE26B45UL, 0x9940E9D9UL, 0x3C72BD33UL, 0x4FB2A63FUL, 0x3FE251CEUL,
0xBEF4F4A4UL, 0x3C7AC155UL, 0x6E756238UL, 0x3FE2387AUL, 0xB6C70573UL, 0x3C89B07EUL,
0x917DDC96UL, 0x3FE21F49UL, 0x9494A5EEUL, 0x3C72A97EUL, 0x88628CD6UL, 0x3FE2063BUL,
0x814A8495UL, 0x3C7DC775UL, 0x22FCD91DUL, 0x3FE1ED50UL, 0x027BB78CUL, 0xBC81DF98UL,
0x3168B9AAUL, 0x3FE1D487UL, 0x00A2643CUL, 0x3C8E016EUL, 0x84045CD4UL, 0x3FE1BBE0UL,
0x352EF607UL, 0xBC895386UL, 0xEB6FCB75UL, 0x3FE1A35BUL, 0x7B4968E4UL, 0x3C7E5B4CUL,
0x388C8DEAUL, 0x3FE18AF9UL, 0xD1970F6CUL, 0xBC811023UL, 0x3C7D517BUL, 0x3FE172B8UL,
0xB9D78A76UL, 0xBC719041UL, 0xC8A58E51UL, 0x3FE15A98UL, 0xB9EEAB0AUL, 0x3C72406AUL,
0xAEA92DE0UL, 0x3FE1429AUL, 0x9AF1369EUL, 0xBC832FBFUL, 0xC06C31CCUL, 0x3FE12ABDUL,
0xB36CA5C7UL, 0xBC41B514UL, 0xD0125B51UL, 0x3FE11301UL, 0x39449B3AUL, 0xBC86C510UL,
0xAFFED31BUL, 0x3FE0FB66UL, 0xC44EBD7BUL, 0xBC5B9BEDUL, 0x32D3D1A2UL, 0x3FE0E3ECUL,
0x27C57B52UL, 0x3C303A17UL, 0x2B7247F7UL, 0x3FE0CC92UL, 0x16E24F71UL, 0x3C801EDCUL,
0x6CF9890FUL, 0x3FE0B558UL, 0x4ADC610BUL, 0x3C88A62EUL, 0xCAC6F383UL, 0x3FE09E3EUL,
0x18316136UL, 0x3C814878UL, 0x18759BC8UL, 0x3FE08745UL, 0x4BB284FFUL, 0x3C5186BEUL,
0x29DDF6DEUL, 0x3FE0706BUL, 0xE2B13C27UL, 0xBC7C91DFUL, 0xD3158574UL, 0x3FE059B0UL,
0xA475B465UL, 0x3C7D73E2UL, 0xE86E7F85UL, 0x3FE04315UL, 0x1977C96EUL, 0xBC80A31CUL,
0x3E778061UL, 0x3FE02C9AUL, 0x535B085DUL, 0xBC619083UL, 0xA9FB3335UL, 0x3FE0163DUL,
0x9AB8CDB7UL, 0x3C8B6129UL
};
#define __ _masm->
address StubGenerator::generate_libmSinh() {
StubGenStubId stub_id = StubGenStubId::dsinh_id;
StubCodeMark mark(this, stub_id);
address start = __ pc();
Label L_2TAG_PACKET_0_0_2, L_2TAG_PACKET_1_0_2, L_2TAG_PACKET_3_0_2, L_2TAG_PACKET_4_0_2;
Label L_2TAG_PACKET_5_0_2, L_2TAG_PACKET_6_0_2;
Label B1_2, B1_5;
address HALFMASK = (address)_HALFMASK;
address MASK3 = (address)_MASK3;
address L2E = (address)_L2E;
address Shifter = (address)_Shifter;
address cv = (address)_cv;
address pv = (address)_pv;
address T2f = (address) _T2f;
address T2_neg_f = (address) _T2_neg_f;
__ enter(); // required for proper stackwalking of RuntimeStub frame
__ bind(B1_2);
__ xorpd(xmm4, xmm4);
__ movsd(xmm1, ExternalAddress(L2E), r11 /*rscratch*/);
__ movl(rax, 32768);
__ pinsrw(xmm4, rax, 3);
__ pextrw(rcx, xmm0, 3);
__ andnpd(xmm4, xmm0);
__ pshufd(xmm5, xmm4, 68);
__ movl(rdx, 32768);
__ andl(rdx, rcx);
__ andl(rcx, 32767);
__ subl(rcx, 16343);
__ cmpl(rcx, 177);
__ jcc(Assembler::aboveEqual, L_2TAG_PACKET_0_0_2); // Branch only if |x| is not in [23/64, 3*2^8)
__ movsd(xmm3, ExternalAddress(HALFMASK), r11 /*rscratch*/);
__ movsd(xmm2, ExternalAddress(L2E + 8), r11 /*rscratch*/);
__ movsd(xmm6, ExternalAddress(Shifter), r11 /*rscratch*/);
__ andpd(xmm3, xmm0);
__ subsd(xmm4, xmm3);
__ mulsd(xmm3, xmm1);
__ mulsd(xmm2, xmm5);
__ cvtsd2siq(rax, xmm3);
__ shll(rdx, 3);
__ orl(rax, rdx);
__ movq(xmm7, xmm3);
__ addsd(xmm3, xmm6);
__ mulsd(xmm1, xmm4);
__ xorpd(xmm5, xmm5);
__ subsd(xmm3, xmm6);
__ movapd(xmm4, ExternalAddress(cv), r11 /*rscratch*/);
__ addsd(xmm2, xmm1);
__ movapd(xmm6, ExternalAddress(cv + 16), r11 /*rscratch*/);
__ subsd(xmm7, xmm3);
__ movl(rdx, 32704);
__ pinsrw(xmm5, rdx, 3);
__ movapd(xmm1, ExternalAddress(cv + 32), r11 /*rscratch*/);
__ addsd(xmm2, xmm7);
__ movl(rdx, 127);
__ andl(rdx, rax);
__ addl(rdx, rdx);
__ shrl(rax, 3);
__ andl(rax, 65520);
__ addl(rax, 16352);
__ xorpd(xmm0, xmm0);
__ cmpl(rcx, 161);
__ jcc(Assembler::aboveEqual, L_2TAG_PACKET_1_0_2); // Branch only if |x| is not in [23/64, 3*2^7)
__ pshufd(xmm5, xmm5, 68);
__ pinsrw(xmm0, rax, 3);
__ pshufd(xmm0, xmm0, 68);
__ psubw(xmm5, xmm0);
__ lea(r8, ExternalAddress(T2f));
__ mulpd(xmm0, Address(r8, rdx, Address::times_8));
__ lea(r8, ExternalAddress(T2_neg_f));
__ mulpd(xmm5, Address(r8, rdx, Address::times_8));
__ pshufd(xmm3, xmm2, 68);
__ movapd(xmm7, ExternalAddress(cv + 48), r11 /*rscratch*/);
__ pshufd(xmm2, xmm2, 68);
__ mulpd(xmm3, xmm3);
__ mulpd(xmm4, xmm2);
__ mulpd(xmm6, xmm2);
__ mulpd(xmm2, ExternalAddress(cv + 64), r11 /*rscratch*/);
__ mulpd(xmm1, xmm3);
__ mulpd(xmm7, xmm3);
__ mulpd(xmm4, xmm3);
__ mulpd(xmm1, xmm3);
__ addpd(xmm6, xmm7);
__ movq(xmm7, xmm0);
__ addpd(xmm4, xmm1);
__ shufpd(xmm7, xmm5, 0);
__ subpd(xmm0, xmm5);
__ mulpd(xmm2, xmm7);
__ addpd(xmm4, xmm6);
__ subsd(xmm7, xmm0);
__ mulpd(xmm4, xmm2);
__ pshufd(xmm6, xmm0, 238);
__ subsd(xmm7, xmm5);
__ addpd(xmm4, xmm2);
__ addsd(xmm7, xmm6);
__ pshufd(xmm2, xmm4, 238);
__ addsd(xmm2, xmm7);
__ addsd(xmm2, xmm4);
__ addsd(xmm0, xmm2);
__ jmp(B1_5);
__ bind(L_2TAG_PACKET_1_0_2);
__ subl(rax, 16352);
__ movl(rcx, rax);
__ andl(rax, 32752);
__ shrl(rax, 1);
__ andl(rax, 65520);
__ subl(rcx, rax);
__ addl(rax, 16352);
__ pinsrw(xmm0, rax, 3);
__ pshufd(xmm0, xmm0, 68);
__ lea(r8, ExternalAddress(T2f));
__ mulpd(xmm0, Address(r8, rdx, Address::times_8));
__ pshufd(xmm3, xmm2, 68);
__ movsd(xmm7, ExternalAddress(cv + 48), r11 /*rscratch*/);
__ mulsd(xmm3, xmm3);
__ mulsd(xmm4, xmm2);
__ mulsd(xmm6, xmm2);
__ mulsd(xmm2, ExternalAddress(cv + 64), r11 /*rscratch*/);
__ mulsd(xmm1, xmm3);
__ mulsd(xmm7, xmm3);
__ mulsd(xmm4, xmm3);
__ addl(rcx, 16368);
__ pinsrw(xmm5, rcx, 3);
__ mulsd(xmm1, xmm3);
__ addsd(xmm6, xmm7);
__ addsd(xmm4, xmm1);
__ mulsd(xmm2, xmm0);
__ addsd(xmm4, xmm6);
__ mulsd(xmm4, xmm2);
__ pshufd(xmm6, xmm0, 238);
__ addsd(xmm4, xmm6);
__ addsd(xmm2, xmm4);
__ addsd(xmm0, xmm2);
__ mulsd(xmm0, xmm5);
__ jmp(B1_5);
__ bind(L_2TAG_PACKET_0_0_2);
__ addl(rcx, 16343);
__ cmpl(rcx, 16343);
__ jcc(Assembler::above, L_2TAG_PACKET_3_0_2); // Branch only if |x| > 23/64
__ cmpl(rcx, 15856);
__ jcc(Assembler::below, L_2TAG_PACKET_4_0_2); // Branch only if |x| < 2^-32
__ movapd(xmm1, ExternalAddress(pv), r11 /*rscratch*/);
__ pshufd(xmm6, xmm0, 68);
__ mulpd(xmm5, xmm5);
__ movapd(xmm2, ExternalAddress(pv + 16), r11 /*rscratch*/);
__ pshufd(xmm7, xmm0, 68);
__ movapd(xmm3, ExternalAddress(pv + 32), r11 /*rscratch*/);
__ pshufd(xmm4, xmm0, 68);
__ andpd(xmm6, ExternalAddress(MASK3), r11 /*rscratch*/);
__ mulpd(xmm1, xmm5);
__ mulsd(xmm2, xmm5);
__ subpd(xmm4, xmm6);
__ mulpd(xmm7, xmm5);
__ addpd(xmm1, xmm3);
__ pshufd(xmm3, xmm6, 68);
__ mulpd(xmm5, xmm5);
__ mulsd(xmm2, xmm7);
__ mulpd(xmm1, xmm7);
__ pshufd(xmm7, xmm0, 68);
__ mulsd(xmm6, xmm6);
__ addsd(xmm7, xmm7);
__ mulsd(xmm4, xmm4);
__ mulpd(xmm1, xmm5);
__ addsd(xmm7, xmm0);
__ mulsd(xmm6, xmm3);
__ mulsd(xmm7, xmm3);
__ pshufd(xmm3, xmm1, 238);
__ mulsd(xmm1, xmm5);
__ pshufd(xmm5, xmm4, 238);
__ addsd(xmm3, xmm2);
__ pshufd(xmm2, xmm2, 238);
__ addsd(xmm7, xmm4);
__ movq(xmm4, xmm0);
__ mulsd(xmm6, xmm2);
__ mulsd(xmm7, xmm5);
__ addsd(xmm0, xmm6);
__ mulsd(xmm7, xmm2);
__ subsd(xmm4, xmm0);
__ addsd(xmm1, xmm7);
__ addsd(xmm6, xmm4);
__ addsd(xmm1, xmm3);
__ addsd(xmm1, xmm6);
__ addsd(xmm0, xmm1);
__ jmp(B1_5);
__ bind(L_2TAG_PACKET_4_0_2);
__ cmpl(rcx, 16);
__ jcc(Assembler::aboveEqual, L_2TAG_PACKET_5_0_2); // Branch only if |x| is not denormalized
__ movq(xmm1, xmm0);
__ mulsd(xmm1, xmm1);
__ jmp(B1_5);
__ bind(L_2TAG_PACKET_5_0_2);
__ xorpd(xmm2, xmm2);
__ movl(rcx, 17392);
__ pinsrw(xmm2, rcx, 3);
__ xorpd(xmm3, xmm3);
__ movl(rdx, 15344);
__ pinsrw(xmm3, rdx, 3);
__ mulsd(xmm2, xmm0);
__ addsd(xmm0, xmm2);
__ mulsd(xmm0, xmm3);
__ jmp(B1_5);
__ bind(L_2TAG_PACKET_3_0_2);
__ cmpl(rcx, 32752);
__ jcc(Assembler::aboveEqual, L_2TAG_PACKET_6_0_2); // Branch only if |x| is INF or NaN
__ xorpd(xmm0, xmm0);
__ movl(rax, 32736);
__ pinsrw(xmm0, rax, 3);
__ orl(rax, rdx);
__ pinsrw(xmm1, rax, 3);
__ mulsd(xmm0, xmm1);
__ jmp(B1_5);
__ bind(L_2TAG_PACKET_6_0_2);
__ xorpd(xmm1, xmm1);
__ movl(rax, 32768);
__ pinsrw(xmm1, rax, 3);
__ andnpd(xmm1, xmm0);
__ mulsd(xmm0, xmm1);
__ bind(B1_5);
__ leave(); // required for proper stackwalking of RuntimeStub frame
__ ret(0);
return start;
}
#undef __

View file

@ -464,6 +464,13 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
} else {
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dtan));
}
} else if (kind == Interpreter::java_lang_math_sinh) {
if (StubRoutines::dsinh() != nullptr) {
__ movdbl(xmm0, Address(rsp, wordSize));
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dsinh())));
} else {
return nullptr; // Fallback to default implementation
}
} else if (kind == Interpreter::java_lang_math_tanh) {
if (StubRoutines::dtanh() != nullptr) {
__ movdbl(xmm0, Address(rsp, wordSize));

View file

@ -166,6 +166,7 @@ bool Compiler::is_intrinsic_supported(vmIntrinsics::ID id) {
case vmIntrinsics::_dcos:
case vmIntrinsics::_dtan:
#if defined(AMD64)
case vmIntrinsics::_dsinh:
case vmIntrinsics::_dtanh:
case vmIntrinsics::_dcbrt:
#endif

View file

@ -3296,6 +3296,7 @@ GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope)
case vmIntrinsics::_dsin : // fall through
case vmIntrinsics::_dcos : // fall through
case vmIntrinsics::_dtan : // fall through
case vmIntrinsics::_dsinh : // fall through
case vmIntrinsics::_dtanh : // fall through
case vmIntrinsics::_dcbrt : // fall through
case vmIntrinsics::_dlog : // fall through

View file

@ -2865,6 +2865,7 @@ void LIRGenerator::do_Intrinsic(Intrinsic* x) {
case vmIntrinsics::_dsqrt: // fall through
case vmIntrinsics::_dsqrt_strict: // fall through
case vmIntrinsics::_dtan: // fall through
case vmIntrinsics::_dsinh: // fall through
case vmIntrinsics::_dtanh: // fall through
case vmIntrinsics::_dsin : // fall through
case vmIntrinsics::_dcos : // fall through

View file

@ -362,6 +362,7 @@ const char* Runtime1::name_for_address(address entry) {
FUNCTION_CASE(entry, StubRoutines::dsin());
FUNCTION_CASE(entry, StubRoutines::dcos());
FUNCTION_CASE(entry, StubRoutines::dtan());
FUNCTION_CASE(entry, StubRoutines::dsinh());
FUNCTION_CASE(entry, StubRoutines::dtanh());
FUNCTION_CASE(entry, StubRoutines::dcbrt());

View file

@ -91,6 +91,7 @@ bool vmIntrinsics::preserves_state(vmIntrinsics::ID id) {
case vmIntrinsics::_dsin:
case vmIntrinsics::_dcos:
case vmIntrinsics::_dtan:
case vmIntrinsics::_dsinh:
case vmIntrinsics::_dtanh:
case vmIntrinsics::_dcbrt:
case vmIntrinsics::_dlog:
@ -144,6 +145,7 @@ bool vmIntrinsics::can_trap(vmIntrinsics::ID id) {
case vmIntrinsics::_dsin:
case vmIntrinsics::_dcos:
case vmIntrinsics::_dtan:
case vmIntrinsics::_dsinh:
case vmIntrinsics::_dtanh:
case vmIntrinsics::_dcbrt:
case vmIntrinsics::_dlog:
@ -314,6 +316,7 @@ bool vmIntrinsics::disabled_by_jvm_flags(vmIntrinsics::ID id) {
case vmIntrinsics::_fmaF:
if (!InlineMathNatives || !UseFMA) return true;
break;
case vmIntrinsics::_dsinh:
case vmIntrinsics::_dtanh:
case vmIntrinsics::_dcbrt:
if (!InlineMathNatives || !InlineIntrinsics) return true;

View file

@ -135,7 +135,8 @@ class methodHandle;
do_name(log_name,"log") do_name(log10_name,"log10") do_name(pow_name,"pow") \
do_name(exp_name,"exp") do_name(min_name,"min") do_name(max_name,"max") \
do_name(floor_name, "floor") do_name(ceil_name, "ceil") do_name(rint_name, "rint") \
do_name(round_name, "round") do_name(tanh_name,"tanh") do_name(cbrt_name,"cbrt") \
do_name(round_name, "round") do_name(sinh_name,"sinh") do_name(tanh_name,"tanh") \
do_name(cbrt_name,"cbrt") \
\
do_name(addExact_name,"addExact") \
do_name(decrementExact_name,"decrementExact") \
@ -161,6 +162,7 @@ class methodHandle;
do_intrinsic(_dcos, java_lang_Math, cos_name, double_double_signature, F_S) \
do_intrinsic(_dtan, java_lang_Math, tan_name, double_double_signature, F_S) \
do_intrinsic(_datan2, java_lang_Math, atan2_name, double2_double_signature, F_S) \
do_intrinsic(_dsinh, java_lang_Math, sinh_name, double_double_signature, F_S) \
do_intrinsic(_dtanh, java_lang_Math, tanh_name, double_double_signature, F_S) \
do_intrinsic(_dcbrt, java_lang_Math, cbrt_name, double_double_signature, F_S) \
do_intrinsic(_dsqrt, java_lang_Math, sqrt_name, double_double_signature, F_S) \

View file

@ -137,6 +137,7 @@ 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;
case vmIntrinsics::_dsinh: return java_lang_math_sinh;
case vmIntrinsics::_dtanh: return java_lang_math_tanh;
case vmIntrinsics::_dcbrt: return java_lang_math_cbrt;
case vmIntrinsics::_dabs: return java_lang_math_abs;
@ -199,6 +200,7 @@ vmIntrinsics::ID AbstractInterpreter::method_intrinsic(MethodKind kind) {
case java_lang_math_sin : return vmIntrinsics::_dsin;
case java_lang_math_cos : return vmIntrinsics::_dcos;
case java_lang_math_tan : return vmIntrinsics::_dtan;
case java_lang_math_sinh : return vmIntrinsics::_dsinh;
case java_lang_math_tanh : return vmIntrinsics::_dtanh;
case java_lang_math_cbrt : return vmIntrinsics::_dcbrt;
case java_lang_math_abs : return vmIntrinsics::_dabs;
@ -304,6 +306,7 @@ 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;
case java_lang_math_sinh : tty->print("java_lang_math_sinh" ); break;
case java_lang_math_tanh : tty->print("java_lang_math_tanh" ); break;
case java_lang_math_cbrt : tty->print("java_lang_math_cbrt" ); break;
case java_lang_math_abs : tty->print("java_lang_math_abs" ); break;

View file

@ -72,6 +72,7 @@ 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)
java_lang_math_sinh, // implementation of java.lang.Math.sinh (x)
java_lang_math_tanh, // implementation of java.lang.Math.tanh (x)
java_lang_math_cbrt, // implementation of java.lang.Math.cbrt (x)
java_lang_math_abs, // implementation of java.lang.Math.abs (x)
@ -152,6 +153,7 @@ class AbstractInterpreter: AllStatic {
case vmIntrinsics::_dsin : // fall thru
case vmIntrinsics::_dcos : // fall thru
case vmIntrinsics::_dtan : // fall thru
case vmIntrinsics::_dsinh : // fall thru
case vmIntrinsics::_dtanh : // fall thru
case vmIntrinsics::_dcbrt : // fall thru
case vmIntrinsics::_dabs : // fall thru

View file

@ -193,6 +193,7 @@ void TemplateInterpreterGenerator::generate_all() {
method_entry(java_lang_math_sin )
method_entry(java_lang_math_cos )
method_entry(java_lang_math_tan )
method_entry(java_lang_math_sinh )
method_entry(java_lang_math_tanh )
method_entry(java_lang_math_cbrt )
method_entry(java_lang_math_abs )
@ -454,6 +455,7 @@ address TemplateInterpreterGenerator::generate_intrinsic_entry(AbstractInterpret
case Interpreter::java_lang_math_sin : // fall thru
case Interpreter::java_lang_math_cos : // fall thru
case Interpreter::java_lang_math_tan : // fall thru
case Interpreter::java_lang_math_sinh : // fall thru
case Interpreter::java_lang_math_tanh : // fall thru
case Interpreter::java_lang_math_cbrt : // fall thru
case Interpreter::java_lang_math_abs : // fall thru

View file

@ -53,6 +53,7 @@ void ZeroInterpreterGenerator::generate_all() {
method_entry(java_lang_math_sin );
method_entry(java_lang_math_cos );
method_entry(java_lang_math_tan );
method_entry(java_lang_math_sinh );
method_entry(java_lang_math_tanh );
method_entry(java_lang_math_cbrt );
method_entry(java_lang_math_abs );
@ -96,6 +97,7 @@ address ZeroInterpreterGenerator::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
case Interpreter::java_lang_math_sinh : // fall thru
case Interpreter::java_lang_math_tanh : // fall thru
case Interpreter::java_lang_math_cbrt : // fall thru
case Interpreter::java_lang_math_abs : // fall thru

View file

@ -124,6 +124,7 @@ class CompilerToVM {
static address dsin;
static address dcos;
static address dtan;
static address dsinh;
static address dtanh;
static address dcbrt;
static address dexp;

View file

@ -144,6 +144,7 @@ int CompilerToVM::Data::sizeof_ZStoreBarrierEntry = sizeof(ZStoreBarrierEntry);
address CompilerToVM::Data::dsin;
address CompilerToVM::Data::dcos;
address CompilerToVM::Data::dtan;
address CompilerToVM::Data::dsinh;
address CompilerToVM::Data::dtanh;
address CompilerToVM::Data::dcbrt;
address CompilerToVM::Data::dexp;
@ -289,6 +290,7 @@ void CompilerToVM::Data::initialize(JVMCI_TRAPS) {
name = nullptr; \
}
SET_TRIGFUNC_OR_NULL(dsinh);
SET_TRIGFUNC_OR_NULL(dtanh);
SET_TRIGFUNC_OR_NULL(dcbrt);
SET_TRIGFUNC_OR_NULL(crc_table_addr);

View file

@ -141,6 +141,7 @@
static_field(CompilerToVM::Data, dsin, address) \
static_field(CompilerToVM::Data, dcos, address) \
static_field(CompilerToVM::Data, dtan, address) \
static_field(CompilerToVM::Data, dsinh, address) \
static_field(CompilerToVM::Data, dtanh, address) \
static_field(CompilerToVM::Data, dcbrt, address) \
static_field(CompilerToVM::Data, dexp, address) \

View file

@ -615,6 +615,7 @@ bool C2Compiler::is_intrinsic_supported(vmIntrinsics::ID id) {
case vmIntrinsics::_dsin:
case vmIntrinsics::_dcos:
case vmIntrinsics::_dtan:
case vmIntrinsics::_dsinh:
case vmIntrinsics::_dtanh:
case vmIntrinsics::_dcbrt:
case vmIntrinsics::_dabs:

View file

@ -245,6 +245,7 @@ bool LibraryCallKit::try_to_inline(int predicate) {
case vmIntrinsics::_dsin:
case vmIntrinsics::_dcos:
case vmIntrinsics::_dtan:
case vmIntrinsics::_dsinh:
case vmIntrinsics::_dtanh:
case vmIntrinsics::_dcbrt:
case vmIntrinsics::_dabs:
@ -1886,6 +1887,9 @@ bool LibraryCallKit::inline_math_native(vmIntrinsics::ID id) {
return StubRoutines::dtan() != nullptr ?
runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dtan(), "dtan") :
runtime_math(OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dtan), "TAN");
case vmIntrinsics::_dsinh:
return StubRoutines::dsinh() != nullptr ?
runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dsinh(), "dsinh") : false;
case vmIntrinsics::_dtanh:
return StubRoutines::dtanh() != nullptr ?
runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dtanh(), "dtanh") : false;

View file

@ -672,6 +672,8 @@
do_entry(initial, dcos, dcos, dcos) \
do_stub(initial, dtan) \
do_entry(initial, dtan, dtan, dtan) \
do_stub(initial, dsinh) \
do_entry(initial, dsinh, dsinh, dsinh) \
do_stub(initial, dtanh) \
do_entry(initial, dtanh, dtanh, dtanh) \
do_stub(initial, dcbrt) \

View file

@ -2672,6 +2672,7 @@ public final class Math {
* @return The hyperbolic sine of {@code x}.
* @since 1.5
*/
@IntrinsicCandidate
public static double sinh(double x) {
return StrictMath.sinh(x);
}

View file

@ -0,0 +1,164 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. 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 org.openjdk.bench.java.lang;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
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.Level;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.annotations.OperationsPerInvocation;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.Random;
public class SinhPerf {
@Warmup(iterations = 3, time = 5, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 4, time = 5, timeUnit = TimeUnit.MILLISECONDS)
@Fork(2)
@BenchmarkMode(Mode.Throughput)
@State(Scope.Thread)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public static class SinhPerfRanges {
public static int sinhInputCount = 2048;
@Param({"0", "1", "2", "3", "4"})
public int sinhRangeIndex;
public double [] sinhPosRandInputs;
public double [] sinhNegRandInputs;
public int sinhInputIndex = 0;
public double sinhRangeInputs[][] = { {0.0, 0x1.0P-28},
{0x1.0P-28, 22.0},
{22.0, Math.log(Double.MAX_VALUE)},
{Math.log(Double.MAX_VALUE), Double.longBitsToDouble(0x408633CE8FB9F87DL)},
{Double.longBitsToDouble(0x408633CE8FB9F87DL), Double.MAX_VALUE} };
@Setup
public void setupValues() {
Random random = new Random(1023);
// Fill the positive and negative sinh vectors with random values
sinhPosRandInputs = new double[sinhInputCount];
sinhNegRandInputs = new double[sinhInputCount];
for (int i = 0; i < sinhInputCount; i++) {
double sinhLowerBound = sinhRangeInputs[sinhRangeIndex][0];
double sinhUpperBound = sinhRangeInputs[sinhRangeIndex][1];
sinhPosRandInputs[i] = random.nextDouble(sinhLowerBound, sinhUpperBound);
sinhNegRandInputs[i] = random.nextDouble(-sinhUpperBound, -sinhLowerBound);
}
}
@Benchmark
@OperationsPerInvocation(2048)
public double sinhPosRangeDouble() {
double res = 0.0;
for (int i = 0; i < sinhInputCount; i++) {
res += Math.sinh(sinhPosRandInputs[i]);
}
return res;
}
@Benchmark
@OperationsPerInvocation(2048)
public double sinhNegRangeDouble() {
double res = 0.0;
for (int i = 0; i < sinhInputCount; i++) {
res += Math.sinh(sinhNegRandInputs[i]);
}
return res;
}
}
@Warmup(iterations = 3, time = 5, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 4, time = 5, timeUnit = TimeUnit.SECONDS)
@Fork(2)
@BenchmarkMode(Mode.Throughput)
@State(Scope.Thread)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public static class SinhPerfConstant {
public static final double constDoubleTiny = 0x1.0P-30;
public static final double constDoubleSmall = 0x1.0P-27;
public static final double constDouble21 = 21.0;
public static final double constDouble23 = 23.0;
public static final double constDoubleLarge = Math.log(Double.MAX_VALUE) + 0.5;
public static final double constDoubleOverflow = 0x1.0P10;
@Benchmark
public double sinhConstDoubleTiny() {
return Math.sinh(constDoubleTiny);
}
@Benchmark
public double sinhConstDoubleSmall() {
return Math.sinh(constDoubleSmall);
}
@Benchmark
public double sinhConstDouble21() {
return Math.sinh(constDouble21);
}
@Benchmark
public double sinhConstDouble23() {
return Math.sinh(constDouble23);
}
@Benchmark
public double sinhConstDoubleLarge() {
return Math.sinh(constDoubleLarge);
}
@Benchmark
public double sinhConstDoubleOverflow() {
return Math.sinh(constDoubleOverflow);
}
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(SinhPerfRanges.class.getSimpleName())
.build();
new Runner(opt).run();
opt = new OptionsBuilder()
.include(SinhPerfConstant.class.getSimpleName())
.build();
new Runner(opt).run();
}
}