1.1 --- a/src/share/vm/opto/library_call.cpp Mon Mar 21 14:58:37 2016 -0700 1.2 +++ b/src/share/vm/opto/library_call.cpp Wed Feb 17 13:40:12 2016 +0300 1.3 @@ -324,6 +324,8 @@ 1.4 bool inline_updateBytesCRC32(); 1.5 bool inline_updateByteBufferCRC32(); 1.6 bool inline_multiplyToLen(); 1.7 + bool inline_squareToLen(); 1.8 + bool inline_mulAdd(); 1.9 1.10 bool inline_profileBoolean(); 1.11 }; 1.12 @@ -527,6 +529,14 @@ 1.13 if (!UseMultiplyToLenIntrinsic) return NULL; 1.14 break; 1.15 1.16 + case vmIntrinsics::_squareToLen: 1.17 + if (!UseSquareToLenIntrinsic) return NULL; 1.18 + break; 1.19 + 1.20 + case vmIntrinsics::_mulAdd: 1.21 + if (!UseMulAddIntrinsic) return NULL; 1.22 + break; 1.23 + 1.24 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt: 1.25 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt: 1.26 if (!UseAESIntrinsics) return NULL; 1.27 @@ -927,6 +937,12 @@ 1.28 case vmIntrinsics::_multiplyToLen: 1.29 return inline_multiplyToLen(); 1.30 1.31 + case vmIntrinsics::_squareToLen: 1.32 + return inline_squareToLen(); 1.33 + 1.34 + case vmIntrinsics::_mulAdd: 1.35 + return inline_mulAdd(); 1.36 + 1.37 case vmIntrinsics::_encodeISOArray: 1.38 return inline_encodeISOArray(); 1.39 1.40 @@ -5856,6 +5872,100 @@ 1.41 return true; 1.42 } 1.43 1.44 +//-------------inline_squareToLen------------------------------------ 1.45 +bool LibraryCallKit::inline_squareToLen() { 1.46 + assert(UseSquareToLenIntrinsic, "not implementated on this platform"); 1.47 + 1.48 + address stubAddr = StubRoutines::squareToLen(); 1.49 + if (stubAddr == NULL) { 1.50 + return false; // Intrinsic's stub is not implemented on this platform 1.51 + } 1.52 + const char* stubName = "squareToLen"; 1.53 + 1.54 + assert(callee()->signature()->size() == 4, "implSquareToLen has 4 parameters"); 1.55 + 1.56 + Node* x = argument(0); 1.57 + Node* len = argument(1); 1.58 + Node* z = argument(2); 1.59 + Node* zlen = argument(3); 1.60 + 1.61 + const Type* x_type = x->Value(&_gvn); 1.62 + const Type* z_type = z->Value(&_gvn); 1.63 + const TypeAryPtr* top_x = x_type->isa_aryptr(); 1.64 + const TypeAryPtr* top_z = z_type->isa_aryptr(); 1.65 + if (top_x == NULL || top_x->klass() == NULL || 1.66 + top_z == NULL || top_z->klass() == NULL) { 1.67 + // failed array check 1.68 + return false; 1.69 + } 1.70 + 1.71 + BasicType x_elem = x_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 1.72 + BasicType z_elem = z_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 1.73 + if (x_elem != T_INT || z_elem != T_INT) { 1.74 + return false; 1.75 + } 1.76 + 1.77 + 1.78 + Node* x_start = array_element_address(x, intcon(0), x_elem); 1.79 + Node* z_start = array_element_address(z, intcon(0), z_elem); 1.80 + 1.81 + Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, 1.82 + OptoRuntime::squareToLen_Type(), 1.83 + stubAddr, stubName, TypePtr::BOTTOM, 1.84 + x_start, len, z_start, zlen); 1.85 + 1.86 + set_result(z); 1.87 + return true; 1.88 +} 1.89 + 1.90 +//-------------inline_mulAdd------------------------------------------ 1.91 +bool LibraryCallKit::inline_mulAdd() { 1.92 + assert(UseMulAddIntrinsic, "not implementated on this platform"); 1.93 + 1.94 + address stubAddr = StubRoutines::mulAdd(); 1.95 + if (stubAddr == NULL) { 1.96 + return false; // Intrinsic's stub is not implemented on this platform 1.97 + } 1.98 + const char* stubName = "mulAdd"; 1.99 + 1.100 + assert(callee()->signature()->size() == 5, "mulAdd has 5 parameters"); 1.101 + 1.102 + Node* out = argument(0); 1.103 + Node* in = argument(1); 1.104 + Node* offset = argument(2); 1.105 + Node* len = argument(3); 1.106 + Node* k = argument(4); 1.107 + 1.108 + const Type* out_type = out->Value(&_gvn); 1.109 + const Type* in_type = in->Value(&_gvn); 1.110 + const TypeAryPtr* top_out = out_type->isa_aryptr(); 1.111 + const TypeAryPtr* top_in = in_type->isa_aryptr(); 1.112 + if (top_out == NULL || top_out->klass() == NULL || 1.113 + top_in == NULL || top_in->klass() == NULL) { 1.114 + // failed array check 1.115 + return false; 1.116 + } 1.117 + 1.118 + BasicType out_elem = out_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 1.119 + BasicType in_elem = in_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 1.120 + if (out_elem != T_INT || in_elem != T_INT) { 1.121 + return false; 1.122 + } 1.123 + 1.124 + Node* outlen = load_array_length(out); 1.125 + Node* new_offset = _gvn.transform(new (C) SubINode(outlen, offset)); 1.126 + Node* out_start = array_element_address(out, intcon(0), out_elem); 1.127 + Node* in_start = array_element_address(in, intcon(0), in_elem); 1.128 + 1.129 + Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, 1.130 + OptoRuntime::mulAdd_Type(), 1.131 + stubAddr, stubName, TypePtr::BOTTOM, 1.132 + out_start,in_start, new_offset, len, k); 1.133 + Node* result = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); 1.134 + set_result(result); 1.135 + return true; 1.136 +} 1.137 + 1.138 1.139 /** 1.140 * Calculate CRC32 for byte.