< prev index next >
src/share/vm/opto/library_call.cpp
Print this page
@@ -324,10 +324,12 @@
bool inline_updateBytesCRC32();
bool inline_updateByteBufferCRC32();
bool inline_multiplyToLen();
bool inline_squareToLen();
bool inline_mulAdd();
+ bool inline_montgomeryMultiply();
+ bool inline_montgomerySquare();
bool inline_profileBoolean();
};
@@ -535,10 +537,17 @@
case vmIntrinsics::_mulAdd:
if (!UseMulAddIntrinsic) 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;
// these two require the predicated logic
predicates = 1;
@@ -941,10 +950,15 @@
return inline_squareToLen();
case vmIntrinsics::_mulAdd:
return inline_mulAdd();
+ case vmIntrinsics::_montgomeryMultiply:
+ return inline_montgomeryMultiply();
+ case vmIntrinsics::_montgomerySquare:
+ return inline_montgomerySquare();
+
case vmIntrinsics::_encodeISOArray:
return inline_encodeISOArray();
case vmIntrinsics::_updateCRC32:
return inline_updateCRC32();
@@ -5781,15 +5795,16 @@
}
const char* stubName = "multiplyToLen";
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);
const TypeAryPtr* top_x = x_type->isa_aryptr();
const TypeAryPtr* top_y = y_type->isa_aryptr();
@@ -5964,10 +5979,125 @@
Node* result = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms));
set_result(result);
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.
* int java.util.zip.CRC32.update(int crc, int b)
*/
< prev index next >