8204289: AARCH64: enable math intrinsics usage in interpreter and C1

Reviewed-by: aph, dsamersoff
This commit is contained in:
Dmitrij Pochepko 2018-06-25 16:31:18 +03:00
parent 854207f875
commit 703073a564
3 changed files with 144 additions and 61 deletions

View File

@ -745,6 +745,14 @@ LIR_Opr LIRGenerator::atomic_add(BasicType type, LIR_Opr addr, LIRItem& value) {
}
void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), "wrong type");
if (x->id() == vmIntrinsics::_dexp || x->id() == vmIntrinsics::_dlog ||
x->id() == vmIntrinsics::_dpow || x->id() == vmIntrinsics::_dcos ||
x->id() == vmIntrinsics::_dsin || x->id() == vmIntrinsics::_dtan ||
x->id() == vmIntrinsics::_dlog10) {
do_LibmIntrinsic(x);
return;
}
switch (x->id()) {
case vmIntrinsics::_dabs:
case vmIntrinsics::_dsqrt: {
@ -754,63 +762,102 @@ void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
LIR_Opr dst = rlock_result(x);
switch (x->id()) {
case vmIntrinsics::_dsqrt: {
__ sqrt(value.result(), dst, LIR_OprFact::illegalOpr);
break;
case vmIntrinsics::_dsqrt: {
__ sqrt(value.result(), dst, LIR_OprFact::illegalOpr);
break;
}
case vmIntrinsics::_dabs: {
__ abs(value.result(), dst, LIR_OprFact::illegalOpr);
break;
}
}
case vmIntrinsics::_dabs: {
__ abs(value.result(), dst, LIR_OprFact::illegalOpr);
break;
}
}
break;
}
case vmIntrinsics::_dlog10: // fall through
case vmIntrinsics::_dlog: // fall through
case vmIntrinsics::_dsin: // fall through
case vmIntrinsics::_dtan: // fall through
case vmIntrinsics::_dcos: // fall through
case vmIntrinsics::_dexp: {
assert(x->number_of_arguments() == 1, "wrong type");
address runtime_entry = NULL;
switch (x->id()) {
case vmIntrinsics::_dsin:
runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsin);
break;
case vmIntrinsics::_dcos:
runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dcos);
break;
case vmIntrinsics::_dtan:
runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dtan);
break;
case vmIntrinsics::_dlog:
runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog);
break;
case vmIntrinsics::_dlog10:
runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10);
break;
case vmIntrinsics::_dexp:
runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dexp);
break;
default:
ShouldNotReachHere();
}
LIR_Opr result = call_runtime(x->argument_at(0), runtime_entry, x->type(), NULL);
set_result(x, result);
break;
}
case vmIntrinsics::_dpow: {
assert(x->number_of_arguments() == 2, "wrong type");
address runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dpow);
LIR_Opr result = call_runtime(x->argument_at(0), x->argument_at(1), runtime_entry, x->type(), NULL);
set_result(x, result);
break;
}
}
}
void LIRGenerator::do_LibmIntrinsic(Intrinsic* x) {
LIRItem value(x->argument_at(0), this);
value.set_destroys_register();
LIR_Opr calc_result = rlock_result(x);
LIR_Opr result_reg = result_register_for(x->type());
CallingConvention* cc = NULL;
if (x->id() == vmIntrinsics::_dpow) {
LIRItem value1(x->argument_at(1), this);
value1.set_destroys_register();
BasicTypeList signature(2);
signature.append(T_DOUBLE);
signature.append(T_DOUBLE);
cc = frame_map()->c_calling_convention(&signature);
value.load_item_force(cc->at(0));
value1.load_item_force(cc->at(1));
} else {
BasicTypeList signature(1);
signature.append(T_DOUBLE);
cc = frame_map()->c_calling_convention(&signature);
value.load_item_force(cc->at(0));
}
switch (x->id()) {
case vmIntrinsics::_dexp:
if (StubRoutines::dexp() != NULL) {
__ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args());
} else {
__ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dexp), getThreadTemp(), result_reg, cc->args());
}
break;
case vmIntrinsics::_dlog:
if (StubRoutines::dlog() != NULL) {
__ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args());
} else {
__ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args());
}
break;
case vmIntrinsics::_dlog10:
if (StubRoutines::dlog10() != NULL) {
__ call_runtime_leaf(StubRoutines::dlog10(), getThreadTemp(), result_reg, cc->args());
} else {
__ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog10), getThreadTemp(), result_reg, cc->args());
}
break;
case vmIntrinsics::_dpow:
if (StubRoutines::dpow() != NULL) {
__ call_runtime_leaf(StubRoutines::dpow(), getThreadTemp(), result_reg, cc->args());
} else {
__ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dpow), getThreadTemp(), result_reg, cc->args());
}
break;
case vmIntrinsics::_dsin:
if (StubRoutines::dsin() != NULL) {
__ call_runtime_leaf(StubRoutines::dsin(), getThreadTemp(), result_reg, cc->args());
} else {
__ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), getThreadTemp(), result_reg, cc->args());
}
break;
case vmIntrinsics::_dcos:
if (StubRoutines::dcos() != NULL) {
__ call_runtime_leaf(StubRoutines::dcos(), getThreadTemp(), result_reg, cc->args());
} else {
__ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), getThreadTemp(), result_reg, cc->args());
}
break;
case vmIntrinsics::_dtan:
if (StubRoutines::dtan() != NULL) {
__ call_runtime_leaf(StubRoutines::dtan(), getThreadTemp(), result_reg, cc->args());
} else {
__ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtan), getThreadTemp(), result_reg, cc->args());
}
break;
default: ShouldNotReachHere();
}
__ move(result_reg, calc_result);
}
void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
assert(x->number_of_arguments() == 5, "wrong type");

View File

@ -5068,9 +5068,17 @@ class StubGenerator: public StubCodeGenerator {
StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C();
}
StubRoutines::_dlog = generate_dlog();
StubRoutines::_dsin = generate_dsin_dcos(/* isCos = */ false);
StubRoutines::_dcos = generate_dsin_dcos(/* isCos = */ true);
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog)) {
StubRoutines::_dlog = generate_dlog();
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin)) {
StubRoutines::_dsin = generate_dsin_dcos(/* isCos = */ false);
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos)) {
StubRoutines::_dcos = generate_dsin_dcos(/* isCos = */ true);
}
}
void generate_all() {

View File

@ -247,26 +247,54 @@ void TemplateInterpreterGenerator::generate_transcendental_entry(AbstractInterpr
address fn;
switch (kind) {
case Interpreter::java_lang_math_sin :
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dsin);
if (StubRoutines::dsin() == NULL) {
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dsin);
} else {
fn = CAST_FROM_FN_PTR(address, StubRoutines::dsin());
}
break;
case Interpreter::java_lang_math_cos :
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dcos);
if (StubRoutines::dcos() == NULL) {
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dcos);
} else {
fn = CAST_FROM_FN_PTR(address, StubRoutines::dcos());
}
break;
case Interpreter::java_lang_math_tan :
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dtan);
if (StubRoutines::dtan() == NULL) {
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dtan);
} else {
fn = CAST_FROM_FN_PTR(address, StubRoutines::dtan());
}
break;
case Interpreter::java_lang_math_log :
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dlog);
if (StubRoutines::dlog() == NULL) {
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dlog);
} else {
fn = CAST_FROM_FN_PTR(address, StubRoutines::dlog());
}
break;
case Interpreter::java_lang_math_log10 :
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10);
if (StubRoutines::dlog10() == NULL) {
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10);
} else {
fn = CAST_FROM_FN_PTR(address, StubRoutines::dlog10());
}
break;
case Interpreter::java_lang_math_exp :
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dexp);
if (StubRoutines::dexp() == NULL) {
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dexp);
} else {
fn = CAST_FROM_FN_PTR(address, StubRoutines::dexp());
}
break;
case Interpreter::java_lang_math_pow :
fpargs = 2;
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dpow);
if (StubRoutines::dpow() == NULL) {
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dpow);
} else {
fn = CAST_FROM_FN_PTR(address, StubRoutines::dpow());
}
break;
default:
ShouldNotReachHere();