--- old/src/share/vm/opto/library_call.cpp 2016-02-12 21:05:53.653756527 +0300 +++ new/src/share/vm/opto/library_call.cpp 2016-02-12 21:05:53.515752789 +0300 @@ -324,6 +324,8 @@ bool inline_updateBytesCRC32(); bool inline_updateByteBufferCRC32(); bool inline_multiplyToLen(); + bool inline_montgomeryMultiply(); + bool inline_montgomerySquare(); bool inline_profileBoolean(); }; @@ -527,6 +529,13 @@ if (!UseMultiplyToLenIntrinsic) return NULL; break; + case vmIntrinsics::_montgomeryMultiply: + if (!UseMontgomeryMultiplyIntrinsic) return NULL; + break; + case vmIntrinsics::_montgomerySquare: + if (!UseMontgomerySquareIntrinsic) return NULL; + break; + case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt: case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt: if (!UseAESIntrinsics) return NULL; @@ -927,6 +936,11 @@ case vmIntrinsics::_multiplyToLen: return inline_multiplyToLen(); + case vmIntrinsics::_montgomeryMultiply: + return inline_montgomeryMultiply(); + case vmIntrinsics::_montgomerySquare: + return inline_montgomerySquare(); + case vmIntrinsics::_encodeISOArray: return inline_encodeISOArray(); @@ -5767,11 +5781,12 @@ assert(callee()->signature()->size() == 5, "multiplyToLen has 5 parameters"); - Node* x = argument(1); - Node* xlen = argument(2); - Node* y = argument(3); - Node* ylen = argument(4); - Node* z = argument(5); + // no receiver because it is a static method + Node* x = argument(0); + Node* xlen = argument(1); + Node* y = argument(2); + Node* ylen = argument(3); + Node* z = argument(4); const Type* x_type = x->Value(&_gvn); const Type* y_type = y->Value(&_gvn); @@ -5856,6 +5871,121 @@ return true; } +//-------------inline_montgomeryMultiply----------------------------------- +bool LibraryCallKit::inline_montgomeryMultiply() { + address stubAddr = StubRoutines::montgomeryMultiply(); + if (stubAddr == NULL) { + return false; // Intrinsic's stub is not implemented on this platform + } + + assert(UseMontgomeryMultiplyIntrinsic, "not implemented on this platform"); + const char* stubName = "montgomery_square"; + + assert(callee()->signature()->size() == 7, "montgomeryMultiply has 7 parameters"); + + Node* a = argument(0); + Node* b = argument(1); + Node* n = argument(2); + Node* len = argument(3); + Node* inv = argument(4); + Node* m = argument(6); + + const Type* a_type = a->Value(&_gvn); + const TypeAryPtr* top_a = a_type->isa_aryptr(); + const Type* b_type = b->Value(&_gvn); + const TypeAryPtr* top_b = b_type->isa_aryptr(); + const Type* n_type = a->Value(&_gvn); + const TypeAryPtr* top_n = n_type->isa_aryptr(); + const Type* m_type = a->Value(&_gvn); + const TypeAryPtr* top_m = m_type->isa_aryptr(); + if (top_a == NULL || top_a->klass() == NULL || + top_b == NULL || top_b->klass() == NULL || + top_n == NULL || top_n->klass() == NULL || + top_m == NULL || top_m->klass() == NULL) { + // failed array check + return false; + } + + BasicType a_elem = a_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + BasicType b_elem = b_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + BasicType n_elem = n_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + BasicType m_elem = m_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + if (a_elem != T_INT || b_elem != T_INT || n_elem != T_INT || m_elem != T_INT) { + return false; + } + + // Make the call + { + Node* a_start = array_element_address(a, intcon(0), a_elem); + Node* b_start = array_element_address(b, intcon(0), b_elem); + Node* n_start = array_element_address(n, intcon(0), n_elem); + Node* m_start = array_element_address(m, intcon(0), m_elem); + + Node* call = make_runtime_call(RC_LEAF, + OptoRuntime::montgomeryMultiply_Type(), + stubAddr, stubName, TypePtr::BOTTOM, + a_start, b_start, n_start, len, inv, top(), + m_start); + set_result(m); + } + + return true; +} + +bool LibraryCallKit::inline_montgomerySquare() { + address stubAddr = StubRoutines::montgomerySquare(); + if (stubAddr == NULL) { + return false; // Intrinsic's stub is not implemented on this platform + } + + assert(UseMontgomerySquareIntrinsic, "not implemented on this platform"); + const char* stubName = "montgomery_square"; + + assert(callee()->signature()->size() == 6, "montgomerySquare has 6 parameters"); + + Node* a = argument(0); + Node* n = argument(1); + Node* len = argument(2); + Node* inv = argument(3); + Node* m = argument(5); + + const Type* a_type = a->Value(&_gvn); + const TypeAryPtr* top_a = a_type->isa_aryptr(); + const Type* n_type = a->Value(&_gvn); + const TypeAryPtr* top_n = n_type->isa_aryptr(); + const Type* m_type = a->Value(&_gvn); + const TypeAryPtr* top_m = m_type->isa_aryptr(); + if (top_a == NULL || top_a->klass() == NULL || + top_n == NULL || top_n->klass() == NULL || + top_m == NULL || top_m->klass() == NULL) { + // failed array check + return false; + } + + BasicType a_elem = a_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + BasicType n_elem = n_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + BasicType m_elem = m_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + if (a_elem != T_INT || n_elem != T_INT || m_elem != T_INT) { + return false; + } + + // Make the call + { + Node* a_start = array_element_address(a, intcon(0), a_elem); + Node* n_start = array_element_address(n, intcon(0), n_elem); + Node* m_start = array_element_address(m, intcon(0), m_elem); + + Node* call = make_runtime_call(RC_LEAF, + OptoRuntime::montgomerySquare_Type(), + stubAddr, stubName, TypePtr::BOTTOM, + a_start, n_start, len, inv, top(), + m_start); + set_result(m); + } + + return true; +} + /** * Calculate CRC32 for byte.