276 bool inline_aescrypt_Block(vmIntrinsics::ID id);
277 bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id);
278 Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
279 Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
280 Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object);
281 bool inline_sha_implCompress(vmIntrinsics::ID id);
282 bool inline_digestBase_implCompressMB(int predicate);
283 bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA,
284 bool long_state, address stubAddr, const char *stubName,
285 Node* src_start, Node* ofs, Node* limit);
286 Node* get_state_from_sha_object(Node *sha_object);
287 Node* get_state_from_sha5_object(Node *sha_object);
288 Node* inline_digestBase_implCompressMB_predicate(int predicate);
289 bool inline_encodeISOArray();
290 bool inline_updateCRC32();
291 bool inline_updateBytesCRC32();
292 bool inline_updateByteBufferCRC32();
293 bool inline_multiplyToLen();
294 bool inline_squareToLen();
295 bool inline_mulAdd();
296
297 bool inline_profileBoolean();
298 bool inline_isCompileConstant();
299 };
300
301
302 //---------------------------make_vm_intrinsic----------------------------
303 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
304 vmIntrinsics::ID id = m->intrinsic_id();
305 assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
306
307 ccstr disable_intr = NULL;
308
309 if ((DisableIntrinsic[0] != '\0'
310 && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) ||
311 (method_has_option_value("DisableIntrinsic", disable_intr)
312 && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL)) {
313 // disabled by a user request on the command line:
314 // example: -XX:DisableIntrinsic=_hashCode,_getClass
315 return NULL;
487 break;
488 #endif
489
490 case vmIntrinsics::_aescrypt_encryptBlock:
491 case vmIntrinsics::_aescrypt_decryptBlock:
492 if (!UseAESIntrinsics) return NULL;
493 break;
494
495 case vmIntrinsics::_multiplyToLen:
496 if (!UseMultiplyToLenIntrinsic) return NULL;
497 break;
498
499 case vmIntrinsics::_squareToLen:
500 if (!UseSquareToLenIntrinsic) return NULL;
501 break;
502
503 case vmIntrinsics::_mulAdd:
504 if (!UseMulAddIntrinsic) return NULL;
505 break;
506
507 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
508 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
509 if (!UseAESIntrinsics) return NULL;
510 // these two require the predicated logic
511 predicates = 1;
512 break;
513
514 case vmIntrinsics::_sha_implCompress:
515 if (!UseSHA1Intrinsics) return NULL;
516 break;
517
518 case vmIntrinsics::_sha2_implCompress:
519 if (!UseSHA256Intrinsics) return NULL;
520 break;
521
522 case vmIntrinsics::_sha5_implCompress:
523 if (!UseSHA512Intrinsics) return NULL;
524 break;
525
526 case vmIntrinsics::_digestBase_implCompressMB:
912 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
913 return inline_cipherBlockChaining_AESCrypt(intrinsic_id());
914
915 case vmIntrinsics::_sha_implCompress:
916 case vmIntrinsics::_sha2_implCompress:
917 case vmIntrinsics::_sha5_implCompress:
918 return inline_sha_implCompress(intrinsic_id());
919
920 case vmIntrinsics::_digestBase_implCompressMB:
921 return inline_digestBase_implCompressMB(predicate);
922
923 case vmIntrinsics::_multiplyToLen:
924 return inline_multiplyToLen();
925
926 case vmIntrinsics::_squareToLen:
927 return inline_squareToLen();
928
929 case vmIntrinsics::_mulAdd:
930 return inline_mulAdd();
931
932 case vmIntrinsics::_encodeISOArray:
933 return inline_encodeISOArray();
934
935 case vmIntrinsics::_updateCRC32:
936 return inline_updateCRC32();
937 case vmIntrinsics::_updateBytesCRC32:
938 return inline_updateBytesCRC32();
939 case vmIntrinsics::_updateByteBufferCRC32:
940 return inline_updateByteBufferCRC32();
941
942 case vmIntrinsics::_profileBoolean:
943 return inline_profileBoolean();
944 case vmIntrinsics::_isCompileConstant:
945 return inline_isCompileConstant();
946
947 default:
948 // If you get here, it may be that someone has added a new intrinsic
949 // to the list in vmSymbols.hpp without implementing it here.
950 #ifndef PRODUCT
951 if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) {
5216 Node* enc = new EncodeISOArrayNode(control(), memory(mtype), src_start, dst_start, length);
5217 enc = _gvn.transform(enc);
5218 Node* res_mem = _gvn.transform(new SCMemProjNode(enc));
5219 set_memory(res_mem, mtype);
5220 set_result(enc);
5221 return true;
5222 }
5223
5224 //-------------inline_multiplyToLen-----------------------------------
5225 bool LibraryCallKit::inline_multiplyToLen() {
5226 assert(UseMultiplyToLenIntrinsic, "not implementated on this platform");
5227
5228 address stubAddr = StubRoutines::multiplyToLen();
5229 if (stubAddr == NULL) {
5230 return false; // Intrinsic's stub is not implemented on this platform
5231 }
5232 const char* stubName = "multiplyToLen";
5233
5234 assert(callee()->signature()->size() == 5, "multiplyToLen has 5 parameters");
5235
5236 Node* x = argument(1);
5237 Node* xlen = argument(2);
5238 Node* y = argument(3);
5239 Node* ylen = argument(4);
5240 Node* z = argument(5);
5241
5242 const Type* x_type = x->Value(&_gvn);
5243 const Type* y_type = y->Value(&_gvn);
5244 const TypeAryPtr* top_x = x_type->isa_aryptr();
5245 const TypeAryPtr* top_y = y_type->isa_aryptr();
5246 if (top_x == NULL || top_x->klass() == NULL ||
5247 top_y == NULL || top_y->klass() == NULL) {
5248 // failed array check
5249 return false;
5250 }
5251
5252 BasicType x_elem = x_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
5253 BasicType y_elem = y_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
5254 if (x_elem != T_INT || y_elem != T_INT) {
5255 return false;
5256 }
5257
5258 // Set the original stack and the reexecute bit for the interpreter to reexecute
5259 // the bytecode that invokes BigInteger.multiplyToLen() if deoptimization happens
5260 // on the return from z array allocation in runtime.
5399 BasicType out_elem = out_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
5400 BasicType in_elem = in_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
5401 if (out_elem != T_INT || in_elem != T_INT) {
5402 return false;
5403 }
5404
5405 Node* outlen = load_array_length(out);
5406 Node* new_offset = _gvn.transform(new SubINode(outlen, offset));
5407 Node* out_start = array_element_address(out, intcon(0), out_elem);
5408 Node* in_start = array_element_address(in, intcon(0), in_elem);
5409
5410 Node* call = make_runtime_call(RC_LEAF|RC_NO_FP,
5411 OptoRuntime::mulAdd_Type(),
5412 stubAddr, stubName, TypePtr::BOTTOM,
5413 out_start,in_start, new_offset, len, k);
5414 Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
5415 set_result(result);
5416 return true;
5417 }
5418
5419
5420 /**
5421 * Calculate CRC32 for byte.
5422 * int java.util.zip.CRC32.update(int crc, int b)
5423 */
5424 bool LibraryCallKit::inline_updateCRC32() {
5425 assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support");
5426 assert(callee()->signature()->size() == 2, "update has 2 parameters");
5427 // no receiver since it is static method
5428 Node* crc = argument(0); // type: int
5429 Node* b = argument(1); // type: int
5430
5431 /*
5432 * int c = ~ crc;
5433 * b = timesXtoThe32[(b ^ c) & 0xFF];
5434 * b = b ^ (c >>> 8);
5435 * crc = ~b;
5436 */
5437
5438 Node* M1 = intcon(-1);
|
276 bool inline_aescrypt_Block(vmIntrinsics::ID id);
277 bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id);
278 Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
279 Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
280 Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object);
281 bool inline_sha_implCompress(vmIntrinsics::ID id);
282 bool inline_digestBase_implCompressMB(int predicate);
283 bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA,
284 bool long_state, address stubAddr, const char *stubName,
285 Node* src_start, Node* ofs, Node* limit);
286 Node* get_state_from_sha_object(Node *sha_object);
287 Node* get_state_from_sha5_object(Node *sha_object);
288 Node* inline_digestBase_implCompressMB_predicate(int predicate);
289 bool inline_encodeISOArray();
290 bool inline_updateCRC32();
291 bool inline_updateBytesCRC32();
292 bool inline_updateByteBufferCRC32();
293 bool inline_multiplyToLen();
294 bool inline_squareToLen();
295 bool inline_mulAdd();
296 bool inline_montgomeryMultiply();
297 bool inline_montgomerySquare();
298
299 bool inline_profileBoolean();
300 bool inline_isCompileConstant();
301 };
302
303
304 //---------------------------make_vm_intrinsic----------------------------
305 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
306 vmIntrinsics::ID id = m->intrinsic_id();
307 assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
308
309 ccstr disable_intr = NULL;
310
311 if ((DisableIntrinsic[0] != '\0'
312 && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) ||
313 (method_has_option_value("DisableIntrinsic", disable_intr)
314 && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL)) {
315 // disabled by a user request on the command line:
316 // example: -XX:DisableIntrinsic=_hashCode,_getClass
317 return NULL;
489 break;
490 #endif
491
492 case vmIntrinsics::_aescrypt_encryptBlock:
493 case vmIntrinsics::_aescrypt_decryptBlock:
494 if (!UseAESIntrinsics) return NULL;
495 break;
496
497 case vmIntrinsics::_multiplyToLen:
498 if (!UseMultiplyToLenIntrinsic) return NULL;
499 break;
500
501 case vmIntrinsics::_squareToLen:
502 if (!UseSquareToLenIntrinsic) return NULL;
503 break;
504
505 case vmIntrinsics::_mulAdd:
506 if (!UseMulAddIntrinsic) return NULL;
507 break;
508
509 case vmIntrinsics::_montgomeryMultiply:
510 if (!UseMontgomeryMultiplyIntrinsic) return NULL;
511 break;
512 case vmIntrinsics::_montgomerySquare:
513 if (!UseMontgomerySquareIntrinsic) return NULL;
514 break;
515
516 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
517 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
518 if (!UseAESIntrinsics) return NULL;
519 // these two require the predicated logic
520 predicates = 1;
521 break;
522
523 case vmIntrinsics::_sha_implCompress:
524 if (!UseSHA1Intrinsics) return NULL;
525 break;
526
527 case vmIntrinsics::_sha2_implCompress:
528 if (!UseSHA256Intrinsics) return NULL;
529 break;
530
531 case vmIntrinsics::_sha5_implCompress:
532 if (!UseSHA512Intrinsics) return NULL;
533 break;
534
535 case vmIntrinsics::_digestBase_implCompressMB:
921 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
922 return inline_cipherBlockChaining_AESCrypt(intrinsic_id());
923
924 case vmIntrinsics::_sha_implCompress:
925 case vmIntrinsics::_sha2_implCompress:
926 case vmIntrinsics::_sha5_implCompress:
927 return inline_sha_implCompress(intrinsic_id());
928
929 case vmIntrinsics::_digestBase_implCompressMB:
930 return inline_digestBase_implCompressMB(predicate);
931
932 case vmIntrinsics::_multiplyToLen:
933 return inline_multiplyToLen();
934
935 case vmIntrinsics::_squareToLen:
936 return inline_squareToLen();
937
938 case vmIntrinsics::_mulAdd:
939 return inline_mulAdd();
940
941 case vmIntrinsics::_montgomeryMultiply:
942 return inline_montgomeryMultiply();
943 case vmIntrinsics::_montgomerySquare:
944 return inline_montgomerySquare();
945
946 case vmIntrinsics::_encodeISOArray:
947 return inline_encodeISOArray();
948
949 case vmIntrinsics::_updateCRC32:
950 return inline_updateCRC32();
951 case vmIntrinsics::_updateBytesCRC32:
952 return inline_updateBytesCRC32();
953 case vmIntrinsics::_updateByteBufferCRC32:
954 return inline_updateByteBufferCRC32();
955
956 case vmIntrinsics::_profileBoolean:
957 return inline_profileBoolean();
958 case vmIntrinsics::_isCompileConstant:
959 return inline_isCompileConstant();
960
961 default:
962 // If you get here, it may be that someone has added a new intrinsic
963 // to the list in vmSymbols.hpp without implementing it here.
964 #ifndef PRODUCT
965 if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) {
5230 Node* enc = new EncodeISOArrayNode(control(), memory(mtype), src_start, dst_start, length);
5231 enc = _gvn.transform(enc);
5232 Node* res_mem = _gvn.transform(new SCMemProjNode(enc));
5233 set_memory(res_mem, mtype);
5234 set_result(enc);
5235 return true;
5236 }
5237
5238 //-------------inline_multiplyToLen-----------------------------------
5239 bool LibraryCallKit::inline_multiplyToLen() {
5240 assert(UseMultiplyToLenIntrinsic, "not implementated on this platform");
5241
5242 address stubAddr = StubRoutines::multiplyToLen();
5243 if (stubAddr == NULL) {
5244 return false; // Intrinsic's stub is not implemented on this platform
5245 }
5246 const char* stubName = "multiplyToLen";
5247
5248 assert(callee()->signature()->size() == 5, "multiplyToLen has 5 parameters");
5249
5250 // no receiver because it is a static method
5251 Node* x = argument(0);
5252 Node* xlen = argument(1);
5253 Node* y = argument(2);
5254 Node* ylen = argument(3);
5255 Node* z = argument(4);
5256
5257 const Type* x_type = x->Value(&_gvn);
5258 const Type* y_type = y->Value(&_gvn);
5259 const TypeAryPtr* top_x = x_type->isa_aryptr();
5260 const TypeAryPtr* top_y = y_type->isa_aryptr();
5261 if (top_x == NULL || top_x->klass() == NULL ||
5262 top_y == NULL || top_y->klass() == NULL) {
5263 // failed array check
5264 return false;
5265 }
5266
5267 BasicType x_elem = x_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
5268 BasicType y_elem = y_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
5269 if (x_elem != T_INT || y_elem != T_INT) {
5270 return false;
5271 }
5272
5273 // Set the original stack and the reexecute bit for the interpreter to reexecute
5274 // the bytecode that invokes BigInteger.multiplyToLen() if deoptimization happens
5275 // on the return from z array allocation in runtime.
5414 BasicType out_elem = out_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
5415 BasicType in_elem = in_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
5416 if (out_elem != T_INT || in_elem != T_INT) {
5417 return false;
5418 }
5419
5420 Node* outlen = load_array_length(out);
5421 Node* new_offset = _gvn.transform(new SubINode(outlen, offset));
5422 Node* out_start = array_element_address(out, intcon(0), out_elem);
5423 Node* in_start = array_element_address(in, intcon(0), in_elem);
5424
5425 Node* call = make_runtime_call(RC_LEAF|RC_NO_FP,
5426 OptoRuntime::mulAdd_Type(),
5427 stubAddr, stubName, TypePtr::BOTTOM,
5428 out_start,in_start, new_offset, len, k);
5429 Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
5430 set_result(result);
5431 return true;
5432 }
5433
5434 //-------------inline_montgomeryMultiply-----------------------------------
5435 bool LibraryCallKit::inline_montgomeryMultiply() {
5436 address stubAddr = StubRoutines::montgomeryMultiply();
5437 if (stubAddr == NULL) {
5438 return false; // Intrinsic's stub is not implemented on this platform
5439 }
5440
5441 assert(UseMontgomeryMultiplyIntrinsic, "not implemented on this platform");
5442 const char* stubName = "montgomery_square";
5443
5444 assert(callee()->signature()->size() == 7, "montgomeryMultiply has 7 parameters");
5445
5446 Node* a = argument(0);
5447 Node* b = argument(1);
5448 Node* n = argument(2);
5449 Node* len = argument(3);
5450 Node* inv = argument(4);
5451 Node* m = argument(6);
5452
5453 const Type* a_type = a->Value(&_gvn);
5454 const TypeAryPtr* top_a = a_type->isa_aryptr();
5455 const Type* b_type = b->Value(&_gvn);
5456 const TypeAryPtr* top_b = b_type->isa_aryptr();
5457 const Type* n_type = a->Value(&_gvn);
5458 const TypeAryPtr* top_n = n_type->isa_aryptr();
5459 const Type* m_type = a->Value(&_gvn);
5460 const TypeAryPtr* top_m = m_type->isa_aryptr();
5461 if (top_a == NULL || top_a->klass() == NULL ||
5462 top_b == NULL || top_b->klass() == NULL ||
5463 top_n == NULL || top_n->klass() == NULL ||
5464 top_m == NULL || top_m->klass() == NULL) {
5465 // failed array check
5466 return false;
5467 }
5468
5469 BasicType a_elem = a_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
5470 BasicType b_elem = b_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
5471 BasicType n_elem = n_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
5472 BasicType m_elem = m_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
5473 if (a_elem != T_INT || b_elem != T_INT || n_elem != T_INT || m_elem != T_INT) {
5474 return false;
5475 }
5476
5477 // Make the call
5478 {
5479 Node* a_start = array_element_address(a, intcon(0), a_elem);
5480 Node* b_start = array_element_address(b, intcon(0), b_elem);
5481 Node* n_start = array_element_address(n, intcon(0), n_elem);
5482 Node* m_start = array_element_address(m, intcon(0), m_elem);
5483
5484 Node* call = make_runtime_call(RC_LEAF,
5485 OptoRuntime::montgomeryMultiply_Type(),
5486 stubAddr, stubName, TypePtr::BOTTOM,
5487 a_start, b_start, n_start, len, inv, top(),
5488 m_start);
5489 set_result(m);
5490 }
5491
5492 return true;
5493 }
5494
5495 bool LibraryCallKit::inline_montgomerySquare() {
5496 address stubAddr = StubRoutines::montgomerySquare();
5497 if (stubAddr == NULL) {
5498 return false; // Intrinsic's stub is not implemented on this platform
5499 }
5500
5501 assert(UseMontgomerySquareIntrinsic, "not implemented on this platform");
5502 const char* stubName = "montgomery_square";
5503
5504 assert(callee()->signature()->size() == 6, "montgomerySquare has 6 parameters");
5505
5506 Node* a = argument(0);
5507 Node* n = argument(1);
5508 Node* len = argument(2);
5509 Node* inv = argument(3);
5510 Node* m = argument(5);
5511
5512 const Type* a_type = a->Value(&_gvn);
5513 const TypeAryPtr* top_a = a_type->isa_aryptr();
5514 const Type* n_type = a->Value(&_gvn);
5515 const TypeAryPtr* top_n = n_type->isa_aryptr();
5516 const Type* m_type = a->Value(&_gvn);
5517 const TypeAryPtr* top_m = m_type->isa_aryptr();
5518 if (top_a == NULL || top_a->klass() == NULL ||
5519 top_n == NULL || top_n->klass() == NULL ||
5520 top_m == NULL || top_m->klass() == NULL) {
5521 // failed array check
5522 return false;
5523 }
5524
5525 BasicType a_elem = a_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
5526 BasicType n_elem = n_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
5527 BasicType m_elem = m_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
5528 if (a_elem != T_INT || n_elem != T_INT || m_elem != T_INT) {
5529 return false;
5530 }
5531
5532 // Make the call
5533 {
5534 Node* a_start = array_element_address(a, intcon(0), a_elem);
5535 Node* n_start = array_element_address(n, intcon(0), n_elem);
5536 Node* m_start = array_element_address(m, intcon(0), m_elem);
5537
5538 Node* call = make_runtime_call(RC_LEAF,
5539 OptoRuntime::montgomerySquare_Type(),
5540 stubAddr, stubName, TypePtr::BOTTOM,
5541 a_start, n_start, len, inv, top(),
5542 m_start);
5543 set_result(m);
5544 }
5545
5546 return true;
5547 }
5548
5549
5550 /**
5551 * Calculate CRC32 for byte.
5552 * int java.util.zip.CRC32.update(int crc, int b)
5553 */
5554 bool LibraryCallKit::inline_updateCRC32() {
5555 assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support");
5556 assert(callee()->signature()->size() == 2, "update has 2 parameters");
5557 // no receiver since it is static method
5558 Node* crc = argument(0); // type: int
5559 Node* b = argument(1); // type: int
5560
5561 /*
5562 * int c = ~ crc;
5563 * b = timesXtoThe32[(b ^ c) & 0xFF];
5564 * b = b ^ (c >>> 8);
5565 * crc = ~b;
5566 */
5567
5568 Node* M1 = intcon(-1);
|