< prev index next >

src/share/vm/opto/library_call.cpp

Print this page




1659 
1660 //--------------------------round_double_node--------------------------------
1661 // Round a double node if necessary.
1662 Node* LibraryCallKit::round_double_node(Node* n) {
1663   if (Matcher::strict_fp_requires_explicit_rounding && UseSSE <= 1)
1664     n = _gvn.transform(new RoundDoubleNode(0, n));
1665   return n;
1666 }
1667 
1668 //------------------------------inline_math-----------------------------------
1669 // public static double Math.abs(double)
1670 // public static double Math.sqrt(double)
1671 // public static double Math.log(double)
1672 // public static double Math.log10(double)
1673 bool LibraryCallKit::inline_math(vmIntrinsics::ID id) {
1674   Node* arg = round_double_node(argument(0));
1675   Node* n = NULL;
1676   switch (id) {
1677   case vmIntrinsics::_dabs:   n = new AbsDNode(                arg);  break;
1678   case vmIntrinsics::_dsqrt:  n = new SqrtDNode(C, control(),  arg);  break;
1679   case vmIntrinsics::_dlog10: n = new Log10DNode(C, control(), arg);  break;
1680   default:  fatal_unexpected_iid(id);  break;
1681   }
1682   set_result(_gvn.transform(n));
1683   return true;
1684 }
1685 
1686 //------------------------------inline_trig----------------------------------
1687 // Inline sin/cos/tan instructions, if possible.  If rounding is required, do
1688 // argument reduction which will turn into a fast/slow diamond.
1689 bool LibraryCallKit::inline_trig(vmIntrinsics::ID id) {
1690   Node* arg = round_double_node(argument(0));
1691   Node* n = NULL;
1692 
1693   switch (id) {
1694   case vmIntrinsics::_dtan:  n = new TanDNode(C, control(), arg);  break;
1695   default:  fatal_unexpected_iid(id);  break;
1696   }
1697   n = _gvn.transform(n);
1698 
1699   // Rounding required?  Check for argument reduction!
1700   if (Matcher::strict_fp_requires_explicit_rounding) {
1701     static const double     pi_4 =  0.7853981633974483;
1702     static const double neg_pi_4 = -0.7853981633974483;
1703     // pi/2 in 80-bit extended precision
1704     // static const unsigned char pi_2_bits_x[] = {0x35,0xc2,0x68,0x21,0xa2,0xda,0x0f,0xc9,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00};
1705     // -pi/2 in 80-bit extended precision
1706     // static const unsigned char neg_pi_2_bits_x[] = {0x35,0xc2,0x68,0x21,0xa2,0xda,0x0f,0xc9,0xff,0xbf,0x00,0x00,0x00,0x00,0x00,0x00};
1707     // Cutoff value for using this argument reduction technique
1708     //static const double    pi_2_minus_epsilon =  1.564660403643354;
1709     //static const double neg_pi_2_plus_epsilon = -1.564660403643354;
1710 
1711     // Pseudocode for sin:
1712     // if (x <= Math.PI / 4.0) {
1713     //   if (x >= -Math.PI / 4.0) return  fsin(x);
1714     //   if (x >= -Math.PI / 2.0) return -fcos(x + Math.PI / 2.0);
1715     // } else {
1716     //   if (x <=  Math.PI / 2.0) return  fcos(x - Math.PI / 2.0);


1794   assert(value_top == top(), "second value must be top");
1795 #endif
1796 
1797   set_result(value);
1798   return true;
1799 }
1800 
1801 //------------------------------inline_math_native-----------------------------
1802 bool LibraryCallKit::inline_math_native(vmIntrinsics::ID id) {
1803 #define FN_PTR(f) CAST_FROM_FN_PTR(address, f)
1804   switch (id) {
1805     // These intrinsics are not properly supported on all hardware
1806   case vmIntrinsics::_dsin:
1807     return StubRoutines::dsin() != NULL ?
1808       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dsin(), "dsin") :
1809       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dsin),   "SIN");
1810   case vmIntrinsics::_dcos:
1811     return StubRoutines::dcos() != NULL ?
1812       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dcos(), "dcos") :
1813       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dcos),   "COS");
1814   case vmIntrinsics::_dtan:   return Matcher::has_match_rule(Op_TanD)   ? inline_trig(id) :


1815     runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dtan),   "TAN");
1816 
1817   case vmIntrinsics::_dlog:
1818     return StubRoutines::dlog() != NULL ?
1819       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dlog(), "dlog") :
1820       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog),   "LOG");
1821   case vmIntrinsics::_dlog10: return Matcher::has_match_rule(Op_Log10D) ? inline_math(id) :


1822     runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog10), "LOG10");
1823 
1824     // These intrinsics are supported on all hardware
1825   case vmIntrinsics::_dsqrt:  return Matcher::match_rule_supported(Op_SqrtD) ? inline_math(id) : false;
1826   case vmIntrinsics::_dabs:   return Matcher::has_match_rule(Op_AbsD)   ? inline_math(id) : false;
1827 
1828   case vmIntrinsics::_dexp:
1829     return StubRoutines::dexp() != NULL ?
1830       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dexp(),  "dexp") :
1831       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dexp),  "EXP");
1832   case vmIntrinsics::_dpow:
1833     return StubRoutines::dpow() != NULL ?
1834       runtime_math(OptoRuntime::Math_DD_D_Type(), StubRoutines::dpow(), "dpow") :
1835       runtime_math(OptoRuntime::Math_DD_D_Type(), FN_PTR(SharedRuntime::dpow),  "POW");
1836 #undef FN_PTR
1837 
1838    // These intrinsics are not yet correctly implemented
1839   case vmIntrinsics::_datan2:
1840     return false;
1841 




1659 
1660 //--------------------------round_double_node--------------------------------
1661 // Round a double node if necessary.
1662 Node* LibraryCallKit::round_double_node(Node* n) {
1663   if (Matcher::strict_fp_requires_explicit_rounding && UseSSE <= 1)
1664     n = _gvn.transform(new RoundDoubleNode(0, n));
1665   return n;
1666 }
1667 
1668 //------------------------------inline_math-----------------------------------
1669 // public static double Math.abs(double)
1670 // public static double Math.sqrt(double)
1671 // public static double Math.log(double)
1672 // public static double Math.log10(double)
1673 bool LibraryCallKit::inline_math(vmIntrinsics::ID id) {
1674   Node* arg = round_double_node(argument(0));
1675   Node* n = NULL;
1676   switch (id) {
1677   case vmIntrinsics::_dabs:   n = new AbsDNode(                arg);  break;
1678   case vmIntrinsics::_dsqrt:  n = new SqrtDNode(C, control(),  arg);  break;

1679   default:  fatal_unexpected_iid(id);  break;
1680   }
1681   set_result(_gvn.transform(n));
1682   return true;
1683 }
1684 
1685 //------------------------------inline_trig----------------------------------
1686 // Inline sin/cos/tan instructions, if possible.  If rounding is required, do
1687 // argument reduction which will turn into a fast/slow diamond.
1688 bool LibraryCallKit::inline_trig(vmIntrinsics::ID id) {
1689   Node* arg = round_double_node(argument(0));
1690   Node* n = NULL;
1691 




1692   n = _gvn.transform(n);
1693 
1694   // Rounding required?  Check for argument reduction!
1695   if (Matcher::strict_fp_requires_explicit_rounding) {
1696     static const double     pi_4 =  0.7853981633974483;
1697     static const double neg_pi_4 = -0.7853981633974483;
1698     // pi/2 in 80-bit extended precision
1699     // static const unsigned char pi_2_bits_x[] = {0x35,0xc2,0x68,0x21,0xa2,0xda,0x0f,0xc9,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00};
1700     // -pi/2 in 80-bit extended precision
1701     // static const unsigned char neg_pi_2_bits_x[] = {0x35,0xc2,0x68,0x21,0xa2,0xda,0x0f,0xc9,0xff,0xbf,0x00,0x00,0x00,0x00,0x00,0x00};
1702     // Cutoff value for using this argument reduction technique
1703     //static const double    pi_2_minus_epsilon =  1.564660403643354;
1704     //static const double neg_pi_2_plus_epsilon = -1.564660403643354;
1705 
1706     // Pseudocode for sin:
1707     // if (x <= Math.PI / 4.0) {
1708     //   if (x >= -Math.PI / 4.0) return  fsin(x);
1709     //   if (x >= -Math.PI / 2.0) return -fcos(x + Math.PI / 2.0);
1710     // } else {
1711     //   if (x <=  Math.PI / 2.0) return  fcos(x - Math.PI / 2.0);


1789   assert(value_top == top(), "second value must be top");
1790 #endif
1791 
1792   set_result(value);
1793   return true;
1794 }
1795 
1796 //------------------------------inline_math_native-----------------------------
1797 bool LibraryCallKit::inline_math_native(vmIntrinsics::ID id) {
1798 #define FN_PTR(f) CAST_FROM_FN_PTR(address, f)
1799   switch (id) {
1800     // These intrinsics are not properly supported on all hardware
1801   case vmIntrinsics::_dsin:
1802     return StubRoutines::dsin() != NULL ?
1803       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dsin(), "dsin") :
1804       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dsin),   "SIN");
1805   case vmIntrinsics::_dcos:
1806     return StubRoutines::dcos() != NULL ?
1807       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dcos(), "dcos") :
1808       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dcos),   "COS");
1809   case vmIntrinsics::_dtan:
1810     return StubRoutines::dtan() != NULL ?
1811       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dtan(), "dtan") :
1812       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dtan), "TAN");

1813   case vmIntrinsics::_dlog:
1814     return StubRoutines::dlog() != NULL ?
1815       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dlog(), "dlog") :
1816       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog),   "LOG");
1817   case vmIntrinsics::_dlog10:
1818     return StubRoutines::dlog10() != NULL ?
1819       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dlog10(), "dlog10") :
1820       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog10), "LOG10");
1821 
1822     // These intrinsics are supported on all hardware
1823   case vmIntrinsics::_dsqrt:  return Matcher::match_rule_supported(Op_SqrtD) ? inline_math(id) : false;
1824   case vmIntrinsics::_dabs:   return Matcher::has_match_rule(Op_AbsD)   ? inline_math(id) : false;
1825 
1826   case vmIntrinsics::_dexp:
1827     return StubRoutines::dexp() != NULL ?
1828       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dexp(),  "dexp") :
1829       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dexp),  "EXP");
1830   case vmIntrinsics::_dpow:
1831     return StubRoutines::dpow() != NULL ?
1832       runtime_math(OptoRuntime::Math_DD_D_Type(), StubRoutines::dpow(), "dpow") :
1833       runtime_math(OptoRuntime::Math_DD_D_Type(), FN_PTR(SharedRuntime::dpow),  "POW");
1834 #undef FN_PTR
1835 
1836    // These intrinsics are not yet correctly implemented
1837   case vmIntrinsics::_datan2:
1838     return false;
1839 


< prev index next >