Mercurial > hg > graal-jvmci-8
comparison src/share/vm/opto/library_call.cpp @ 23886:5601e440e5e7
8130150: Implement BigInteger.montgomeryMultiply intrinsic
Reviewed-by: kvn, mdoerr
author | vkempik |
---|---|
date | Fri, 04 Mar 2016 16:15:48 +0300 |
parents | 51c505229e71 |
children | a96cf90239c6 |
comparison
equal
deleted
inserted
replaced
23885:51c505229e71 | 23886:5601e440e5e7 |
---|---|
324 bool inline_updateBytesCRC32(); | 324 bool inline_updateBytesCRC32(); |
325 bool inline_updateByteBufferCRC32(); | 325 bool inline_updateByteBufferCRC32(); |
326 bool inline_multiplyToLen(); | 326 bool inline_multiplyToLen(); |
327 bool inline_squareToLen(); | 327 bool inline_squareToLen(); |
328 bool inline_mulAdd(); | 328 bool inline_mulAdd(); |
329 bool inline_montgomeryMultiply(); | |
330 bool inline_montgomerySquare(); | |
329 | 331 |
330 bool inline_profileBoolean(); | 332 bool inline_profileBoolean(); |
331 }; | 333 }; |
332 | 334 |
333 | 335 |
535 | 537 |
536 case vmIntrinsics::_mulAdd: | 538 case vmIntrinsics::_mulAdd: |
537 if (!UseMulAddIntrinsic) return NULL; | 539 if (!UseMulAddIntrinsic) return NULL; |
538 break; | 540 break; |
539 | 541 |
542 case vmIntrinsics::_montgomeryMultiply: | |
543 if (!UseMontgomeryMultiplyIntrinsic) return NULL; | |
544 break; | |
545 case vmIntrinsics::_montgomerySquare: | |
546 if (!UseMontgomerySquareIntrinsic) return NULL; | |
547 break; | |
548 | |
540 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt: | 549 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt: |
541 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt: | 550 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt: |
542 if (!UseAESIntrinsics) return NULL; | 551 if (!UseAESIntrinsics) return NULL; |
543 // these two require the predicated logic | 552 // these two require the predicated logic |
544 predicates = 1; | 553 predicates = 1; |
940 case vmIntrinsics::_squareToLen: | 949 case vmIntrinsics::_squareToLen: |
941 return inline_squareToLen(); | 950 return inline_squareToLen(); |
942 | 951 |
943 case vmIntrinsics::_mulAdd: | 952 case vmIntrinsics::_mulAdd: |
944 return inline_mulAdd(); | 953 return inline_mulAdd(); |
954 | |
955 case vmIntrinsics::_montgomeryMultiply: | |
956 return inline_montgomeryMultiply(); | |
957 case vmIntrinsics::_montgomerySquare: | |
958 return inline_montgomerySquare(); | |
945 | 959 |
946 case vmIntrinsics::_encodeISOArray: | 960 case vmIntrinsics::_encodeISOArray: |
947 return inline_encodeISOArray(); | 961 return inline_encodeISOArray(); |
948 | 962 |
949 case vmIntrinsics::_updateCRC32: | 963 case vmIntrinsics::_updateCRC32: |
5781 } | 5795 } |
5782 const char* stubName = "multiplyToLen"; | 5796 const char* stubName = "multiplyToLen"; |
5783 | 5797 |
5784 assert(callee()->signature()->size() == 5, "multiplyToLen has 5 parameters"); | 5798 assert(callee()->signature()->size() == 5, "multiplyToLen has 5 parameters"); |
5785 | 5799 |
5786 Node* x = argument(1); | 5800 // no receiver because it is a static method |
5787 Node* xlen = argument(2); | 5801 Node* x = argument(0); |
5788 Node* y = argument(3); | 5802 Node* xlen = argument(1); |
5789 Node* ylen = argument(4); | 5803 Node* y = argument(2); |
5790 Node* z = argument(5); | 5804 Node* ylen = argument(3); |
5805 Node* z = argument(4); | |
5791 | 5806 |
5792 const Type* x_type = x->Value(&_gvn); | 5807 const Type* x_type = x->Value(&_gvn); |
5793 const Type* y_type = y->Value(&_gvn); | 5808 const Type* y_type = y->Value(&_gvn); |
5794 const TypeAryPtr* top_x = x_type->isa_aryptr(); | 5809 const TypeAryPtr* top_x = x_type->isa_aryptr(); |
5795 const TypeAryPtr* top_y = y_type->isa_aryptr(); | 5810 const TypeAryPtr* top_y = y_type->isa_aryptr(); |
5964 Node* result = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); | 5979 Node* result = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); |
5965 set_result(result); | 5980 set_result(result); |
5966 return true; | 5981 return true; |
5967 } | 5982 } |
5968 | 5983 |
5984 //-------------inline_montgomeryMultiply----------------------------------- | |
5985 bool LibraryCallKit::inline_montgomeryMultiply() { | |
5986 address stubAddr = StubRoutines::montgomeryMultiply(); | |
5987 if (stubAddr == NULL) { | |
5988 return false; // Intrinsic's stub is not implemented on this platform | |
5989 } | |
5990 | |
5991 assert(UseMontgomeryMultiplyIntrinsic, "not implemented on this platform"); | |
5992 const char* stubName = "montgomery_square"; | |
5993 | |
5994 assert(callee()->signature()->size() == 7, "montgomeryMultiply has 7 parameters"); | |
5995 | |
5996 Node* a = argument(0); | |
5997 Node* b = argument(1); | |
5998 Node* n = argument(2); | |
5999 Node* len = argument(3); | |
6000 Node* inv = argument(4); | |
6001 Node* m = argument(6); | |
6002 | |
6003 const Type* a_type = a->Value(&_gvn); | |
6004 const TypeAryPtr* top_a = a_type->isa_aryptr(); | |
6005 const Type* b_type = b->Value(&_gvn); | |
6006 const TypeAryPtr* top_b = b_type->isa_aryptr(); | |
6007 const Type* n_type = a->Value(&_gvn); | |
6008 const TypeAryPtr* top_n = n_type->isa_aryptr(); | |
6009 const Type* m_type = a->Value(&_gvn); | |
6010 const TypeAryPtr* top_m = m_type->isa_aryptr(); | |
6011 if (top_a == NULL || top_a->klass() == NULL || | |
6012 top_b == NULL || top_b->klass() == NULL || | |
6013 top_n == NULL || top_n->klass() == NULL || | |
6014 top_m == NULL || top_m->klass() == NULL) { | |
6015 // failed array check | |
6016 return false; | |
6017 } | |
6018 | |
6019 BasicType a_elem = a_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); | |
6020 BasicType b_elem = b_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); | |
6021 BasicType n_elem = n_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); | |
6022 BasicType m_elem = m_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); | |
6023 if (a_elem != T_INT || b_elem != T_INT || n_elem != T_INT || m_elem != T_INT) { | |
6024 return false; | |
6025 } | |
6026 | |
6027 // Make the call | |
6028 { | |
6029 Node* a_start = array_element_address(a, intcon(0), a_elem); | |
6030 Node* b_start = array_element_address(b, intcon(0), b_elem); | |
6031 Node* n_start = array_element_address(n, intcon(0), n_elem); | |
6032 Node* m_start = array_element_address(m, intcon(0), m_elem); | |
6033 | |
6034 Node* call = make_runtime_call(RC_LEAF, | |
6035 OptoRuntime::montgomeryMultiply_Type(), | |
6036 stubAddr, stubName, TypePtr::BOTTOM, | |
6037 a_start, b_start, n_start, len, inv, top(), | |
6038 m_start); | |
6039 set_result(m); | |
6040 } | |
6041 | |
6042 return true; | |
6043 } | |
6044 | |
6045 bool LibraryCallKit::inline_montgomerySquare() { | |
6046 address stubAddr = StubRoutines::montgomerySquare(); | |
6047 if (stubAddr == NULL) { | |
6048 return false; // Intrinsic's stub is not implemented on this platform | |
6049 } | |
6050 | |
6051 assert(UseMontgomerySquareIntrinsic, "not implemented on this platform"); | |
6052 const char* stubName = "montgomery_square"; | |
6053 | |
6054 assert(callee()->signature()->size() == 6, "montgomerySquare has 6 parameters"); | |
6055 | |
6056 Node* a = argument(0); | |
6057 Node* n = argument(1); | |
6058 Node* len = argument(2); | |
6059 Node* inv = argument(3); | |
6060 Node* m = argument(5); | |
6061 | |
6062 const Type* a_type = a->Value(&_gvn); | |
6063 const TypeAryPtr* top_a = a_type->isa_aryptr(); | |
6064 const Type* n_type = a->Value(&_gvn); | |
6065 const TypeAryPtr* top_n = n_type->isa_aryptr(); | |
6066 const Type* m_type = a->Value(&_gvn); | |
6067 const TypeAryPtr* top_m = m_type->isa_aryptr(); | |
6068 if (top_a == NULL || top_a->klass() == NULL || | |
6069 top_n == NULL || top_n->klass() == NULL || | |
6070 top_m == NULL || top_m->klass() == NULL) { | |
6071 // failed array check | |
6072 return false; | |
6073 } | |
6074 | |
6075 BasicType a_elem = a_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); | |
6076 BasicType n_elem = n_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); | |
6077 BasicType m_elem = m_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); | |
6078 if (a_elem != T_INT || n_elem != T_INT || m_elem != T_INT) { | |
6079 return false; | |
6080 } | |
6081 | |
6082 // Make the call | |
6083 { | |
6084 Node* a_start = array_element_address(a, intcon(0), a_elem); | |
6085 Node* n_start = array_element_address(n, intcon(0), n_elem); | |
6086 Node* m_start = array_element_address(m, intcon(0), m_elem); | |
6087 | |
6088 Node* call = make_runtime_call(RC_LEAF, | |
6089 OptoRuntime::montgomerySquare_Type(), | |
6090 stubAddr, stubName, TypePtr::BOTTOM, | |
6091 a_start, n_start, len, inv, top(), | |
6092 m_start); | |
6093 set_result(m); | |
6094 } | |
6095 | |
6096 return true; | |
6097 } | |
6098 | |
5969 | 6099 |
5970 /** | 6100 /** |
5971 * Calculate CRC32 for byte. | 6101 * Calculate CRC32 for byte. |
5972 * int java.util.zip.CRC32.update(int crc, int b) | 6102 * int java.util.zip.CRC32.update(int crc, int b) |
5973 */ | 6103 */ |