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 */