< prev index next >
src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp
Print this page
rev 12409 : 8171244: PPC64: Make interpreter's math entries consistent with C1 and C2 and support FMA
Reviewed-by:
*** 1132,1168 ****
}
// End of helpers
address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
! if (!Interpreter::math_entry_available(kind)) {
! NOT_PRODUCT(__ should_not_reach_here();)
! return NULL;
}
address entry = __ pc();
! __ lfd(F1_RET, Interpreter::stackElementSize, R15_esp);
// Pop c2i arguments (if any) off when we return.
#ifdef ASSERT
__ ld(R9_ARG7, 0, R1_SP);
__ ld(R10_ARG8, 0, R21_sender_SP);
__ cmpd(CCR0, R9_ARG7, R10_ARG8);
__ asm_assert_eq("backlink", 0x545);
#endif // ASSERT
__ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started.
! if (kind == Interpreter::java_lang_math_sqrt) {
! __ fsqrt(F1_RET, F1_RET);
! } else if (kind == Interpreter::java_lang_math_abs) {
! __ fabs(F1_RET, F1_RET);
} else {
! ShouldNotReachHere();
}
- // And we're done.
__ blr();
__ flush();
return entry;
--- 1132,1225 ----
}
// End of helpers
address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
!
! // Decide what to do: Use same platform specific instructions and runtime calls as compilers.
! bool use_instruction = false;
! address runtime_entry = NULL;
! int num_args = 1;
! bool double_precision = true;
!
! // PPC64 specific:
! switch (kind) {
! case Interpreter::java_lang_math_sqrt: use_instruction = VM_Version::has_fsqrt(); break;
! case Interpreter::java_lang_math_abs: use_instruction = true; break;
! case Interpreter::java_lang_math_fmaF:
! case Interpreter::java_lang_math_fmaD: use_instruction = UseFMA; break;
! default: break; // Fall back to runtime call.
! }
!
! switch (kind) {
! case Interpreter::java_lang_math_sin : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsin); break;
! case Interpreter::java_lang_math_cos : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dcos); break;
! case Interpreter::java_lang_math_tan : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dtan); break;
! case Interpreter::java_lang_math_abs : /* run interpreted */ break;
! case Interpreter::java_lang_math_sqrt : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsqrt); break;
! case Interpreter::java_lang_math_log : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog); break;
! case Interpreter::java_lang_math_log10: runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10); break;
! case Interpreter::java_lang_math_pow : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dpow); num_args = 2; break;
! case Interpreter::java_lang_math_exp : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dexp); break;
! case Interpreter::java_lang_math_fmaF : /* run interpreted */ num_args = 3; double_precision = false; break;
! case Interpreter::java_lang_math_fmaD : /* run interpreted */ num_args = 3; break;
! default: ShouldNotReachHere();
}
+ // Use normal entry if neither instruction nor runtime call is used.
+ if (!use_instruction && runtime_entry == NULL) return NULL;
+
address entry = __ pc();
! // Load arguments
! if (double_precision) {
! int offset = (2 * num_args - 1) * Interpreter::stackElementSize;
! for (int i = 0; i < num_args; ++i) {
! __ lfd(as_FloatRegister(F1_ARG1->encoding() + i), offset, R15_esp);
! offset -= 2 * Interpreter::stackElementSize;
! }
! } else {
! int offset = num_args * Interpreter::stackElementSize;
! for (int i = 0; i < num_args; ++i) {
! __ lfs(as_FloatRegister(F1_ARG1->encoding() + i), offset, R15_esp);
! offset -= Interpreter::stackElementSize;
! }
! }
// Pop c2i arguments (if any) off when we return.
#ifdef ASSERT
__ ld(R9_ARG7, 0, R1_SP);
__ ld(R10_ARG8, 0, R21_sender_SP);
__ cmpd(CCR0, R9_ARG7, R10_ARG8);
__ asm_assert_eq("backlink", 0x545);
#endif // ASSERT
__ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started.
! if (use_instruction) {
! switch (kind) {
! case Interpreter::java_lang_math_sqrt: __ fsqrt(F1_RET, F1); break;
! case Interpreter::java_lang_math_abs: __ fabs(F1_RET, F1); break;
! case Interpreter::java_lang_math_fmaF: __ fmadds(F1_RET, F1, F2, F3); break;
! case Interpreter::java_lang_math_fmaD: __ fmadd(F1_RET, F1, F2, F3); break;
! default: ShouldNotReachHere(); break;
! }
} else {
! // Comment: Can use tail call if the unextended frame is always C ABI compliant:
! //__ load_const_optimized(R12_scratch2, runtime_entry, R0);
! //__ call_c_and_return_to_caller(R12_scratch2);
!
! // Push a new C frame and save LR.
! __ save_LR_CR(R0);
! __ push_frame_reg_args(0, R11_scratch1);
!
! __ call_VM_leaf(runtime_entry);
!
! // Pop the C frame and restore LR.
! __ pop_frame();
! __ restore_LR_CR(R0);
}
__ blr();
__ flush();
return entry;
< prev index next >