1351
1352 //--------------------------round_double_node--------------------------------
1353 // Round a double node if necessary.
1354 Node* LibraryCallKit::round_double_node(Node* n) {
1355 if (Matcher::strict_fp_requires_explicit_rounding && UseSSE <= 1)
1356 n = _gvn.transform(new RoundDoubleNode(0, n));
1357 return n;
1358 }
1359
1360 //------------------------------inline_math-----------------------------------
1361 // public static double Math.abs(double)
1362 // public static double Math.sqrt(double)
1363 // public static double Math.log(double)
1364 // public static double Math.log10(double)
1365 bool LibraryCallKit::inline_math(vmIntrinsics::ID id) {
1366 Node* arg = round_double_node(argument(0));
1367 Node* n;
1368 switch (id) {
1369 case vmIntrinsics::_dabs: n = new AbsDNode( arg); break;
1370 case vmIntrinsics::_dsqrt: n = new SqrtDNode(C, control(), arg); break;
1371 case vmIntrinsics::_dlog: n = new LogDNode(C, control(), arg); break;
1372 case vmIntrinsics::_dlog10: n = new Log10DNode(C, control(), arg); break;
1373 default: fatal_unexpected_iid(id); break;
1374 }
1375 set_result(_gvn.transform(n));
1376 return true;
1377 }
1378
1379 //------------------------------inline_trig----------------------------------
1380 // Inline sin/cos/tan instructions, if possible. If rounding is required, do
1381 // argument reduction which will turn into a fast/slow diamond.
1382 bool LibraryCallKit::inline_trig(vmIntrinsics::ID id) {
1383 Node* arg = round_double_node(argument(0));
1384 Node* n = NULL;
1385
1386 switch (id) {
1387 case vmIntrinsics::_dsin: n = new SinDNode(C, control(), arg); break;
1388 case vmIntrinsics::_dcos: n = new CosDNode(C, control(), arg); break;
1389 case vmIntrinsics::_dtan: n = new TanDNode(C, control(), arg); break;
1390 default: fatal_unexpected_iid(id); break;
1391 }
1735 Node* value_top = _gvn.transform(new ProjNode(trig, TypeFunc::Parms+1));
1736 assert(value_top == top(), "second value must be top");
1737 #endif
1738
1739 set_result(value);
1740 return true;
1741 }
1742
1743 //------------------------------inline_math_native-----------------------------
1744 bool LibraryCallKit::inline_math_native(vmIntrinsics::ID id) {
1745 #define FN_PTR(f) CAST_FROM_FN_PTR(address, f)
1746 switch (id) {
1747 // These intrinsics are not properly supported on all hardware
1748 case vmIntrinsics::_dcos: return Matcher::has_match_rule(Op_CosD) ? inline_trig(id) :
1749 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dcos), "COS");
1750 case vmIntrinsics::_dsin: return Matcher::has_match_rule(Op_SinD) ? inline_trig(id) :
1751 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dsin), "SIN");
1752 case vmIntrinsics::_dtan: return Matcher::has_match_rule(Op_TanD) ? inline_trig(id) :
1753 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dtan), "TAN");
1754
1755 case vmIntrinsics::_dlog: return Matcher::has_match_rule(Op_LogD) ? inline_math(id) :
1756 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog), "LOG");
1757 case vmIntrinsics::_dlog10: return Matcher::has_match_rule(Op_Log10D) ? inline_math(id) :
1758 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog10), "LOG10");
1759
1760 // These intrinsics are supported on all hardware
1761 case vmIntrinsics::_dsqrt: return Matcher::match_rule_supported(Op_SqrtD) ? inline_math(id) : false;
1762 case vmIntrinsics::_dabs: return Matcher::has_match_rule(Op_AbsD) ? inline_math(id) : false;
1763
1764 case vmIntrinsics::_dexp:
1765 return StubRoutines::dexp() != NULL ?
1766 runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dexp(), "dexp") :
1767 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dexp), "EXP");
1768 case vmIntrinsics::_dpow: return Matcher::has_match_rule(Op_PowD) ? inline_pow() :
1769 runtime_math(OptoRuntime::Math_DD_D_Type(), FN_PTR(SharedRuntime::dpow), "POW");
1770 #undef FN_PTR
1771
1772 // These intrinsics are not yet correctly implemented
1773 case vmIntrinsics::_datan2:
1774 return false;
1775
|
1351
1352 //--------------------------round_double_node--------------------------------
1353 // Round a double node if necessary.
1354 Node* LibraryCallKit::round_double_node(Node* n) {
1355 if (Matcher::strict_fp_requires_explicit_rounding && UseSSE <= 1)
1356 n = _gvn.transform(new RoundDoubleNode(0, n));
1357 return n;
1358 }
1359
1360 //------------------------------inline_math-----------------------------------
1361 // public static double Math.abs(double)
1362 // public static double Math.sqrt(double)
1363 // public static double Math.log(double)
1364 // public static double Math.log10(double)
1365 bool LibraryCallKit::inline_math(vmIntrinsics::ID id) {
1366 Node* arg = round_double_node(argument(0));
1367 Node* n;
1368 switch (id) {
1369 case vmIntrinsics::_dabs: n = new AbsDNode( arg); break;
1370 case vmIntrinsics::_dsqrt: n = new SqrtDNode(C, control(), arg); break;
1371 case vmIntrinsics::_dlog10: n = new Log10DNode(C, control(), arg); break;
1372 default: fatal_unexpected_iid(id); break;
1373 }
1374 set_result(_gvn.transform(n));
1375 return true;
1376 }
1377
1378 //------------------------------inline_trig----------------------------------
1379 // Inline sin/cos/tan instructions, if possible. If rounding is required, do
1380 // argument reduction which will turn into a fast/slow diamond.
1381 bool LibraryCallKit::inline_trig(vmIntrinsics::ID id) {
1382 Node* arg = round_double_node(argument(0));
1383 Node* n = NULL;
1384
1385 switch (id) {
1386 case vmIntrinsics::_dsin: n = new SinDNode(C, control(), arg); break;
1387 case vmIntrinsics::_dcos: n = new CosDNode(C, control(), arg); break;
1388 case vmIntrinsics::_dtan: n = new TanDNode(C, control(), arg); break;
1389 default: fatal_unexpected_iid(id); break;
1390 }
1734 Node* value_top = _gvn.transform(new ProjNode(trig, TypeFunc::Parms+1));
1735 assert(value_top == top(), "second value must be top");
1736 #endif
1737
1738 set_result(value);
1739 return true;
1740 }
1741
1742 //------------------------------inline_math_native-----------------------------
1743 bool LibraryCallKit::inline_math_native(vmIntrinsics::ID id) {
1744 #define FN_PTR(f) CAST_FROM_FN_PTR(address, f)
1745 switch (id) {
1746 // These intrinsics are not properly supported on all hardware
1747 case vmIntrinsics::_dcos: return Matcher::has_match_rule(Op_CosD) ? inline_trig(id) :
1748 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dcos), "COS");
1749 case vmIntrinsics::_dsin: return Matcher::has_match_rule(Op_SinD) ? inline_trig(id) :
1750 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dsin), "SIN");
1751 case vmIntrinsics::_dtan: return Matcher::has_match_rule(Op_TanD) ? inline_trig(id) :
1752 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dtan), "TAN");
1753
1754 case vmIntrinsics::_dlog:
1755 return StubRoutines::dlog() != NULL ?
1756 runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dlog(), "dlog") :
1757 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog), "LOG");
1758 case vmIntrinsics::_dlog10: return Matcher::has_match_rule(Op_Log10D) ? inline_math(id) :
1759 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog10), "LOG10");
1760
1761 // These intrinsics are supported on all hardware
1762 case vmIntrinsics::_dsqrt: return Matcher::match_rule_supported(Op_SqrtD) ? inline_math(id) : false;
1763 case vmIntrinsics::_dabs: return Matcher::has_match_rule(Op_AbsD) ? inline_math(id) : false;
1764
1765 case vmIntrinsics::_dexp:
1766 return StubRoutines::dexp() != NULL ?
1767 runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dexp(), "dexp") :
1768 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dexp), "EXP");
1769 case vmIntrinsics::_dpow: return Matcher::has_match_rule(Op_PowD) ? inline_pow() :
1770 runtime_math(OptoRuntime::Math_DD_D_Type(), FN_PTR(SharedRuntime::dpow), "POW");
1771 #undef FN_PTR
1772
1773 // These intrinsics are not yet correctly implemented
1774 case vmIntrinsics::_datan2:
1775 return false;
1776
|