--- a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_64.cpp Tue Jan 12 16:01:54 2016 +0100
+++ b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_64.cpp Tue Jan 12 13:14:41 2016 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,11 +26,155 @@
#include "asm/macroAssembler.hpp"
#include "interpreter/interp_masm.hpp"
#include "interpreter/interpreter.hpp"
+#include "interpreter/interpreterRuntime.hpp"
#include "interpreter/templateInterpreterGenerator.hpp"
#include "runtime/arguments.hpp"
#define __ _masm->
+#ifdef _WIN64
+address TemplateInterpreterGenerator::generate_slow_signature_handler() {
+ address entry = __ pc();
+
+ // rbx: method
+ // r14: pointer to locals
+ // c_rarg3: first stack arg - wordSize
+ __ mov(c_rarg3, rsp);
+ // adjust rsp
+ __ subptr(rsp, 4 * wordSize);
+ __ call_VM(noreg,
+ CAST_FROM_FN_PTR(address,
+ InterpreterRuntime::slow_signature_handler),
+ rbx, r14, c_rarg3);
+
+ // rax: result handler
+
+ // Stack layout:
+ // rsp: 3 integer or float args (if static first is unused)
+ // 1 float/double identifiers
+ // return address
+ // stack args
+ // garbage
+ // expression stack bottom
+ // bcp (NULL)
+ // ...
+
+ // Do FP first so we can use c_rarg3 as temp
+ __ movl(c_rarg3, Address(rsp, 3 * wordSize)); // float/double identifiers
+
+ for ( int i= 0; i < Argument::n_int_register_parameters_c-1; i++ ) {
+ XMMRegister floatreg = as_XMMRegister(i+1);
+ Label isfloatordouble, isdouble, next;
+
+ __ testl(c_rarg3, 1 << (i*2)); // Float or Double?
+ __ jcc(Assembler::notZero, isfloatordouble);
+
+ // Do Int register here
+ switch ( i ) {
+ case 0:
+ __ movl(rscratch1, Address(rbx, Method::access_flags_offset()));
+ __ testl(rscratch1, JVM_ACC_STATIC);
+ __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0));
+ break;
+ case 1:
+ __ movptr(c_rarg2, Address(rsp, wordSize));
+ break;
+ case 2:
+ __ movptr(c_rarg3, Address(rsp, 2 * wordSize));
+ break;
+ default:
+ break;
+ }
+
+ __ jmp (next);
+
+ __ bind(isfloatordouble);
+ __ testl(c_rarg3, 1 << ((i*2)+1)); // Double?
+ __ jcc(Assembler::notZero, isdouble);
+
+// Do Float Here
+ __ movflt(floatreg, Address(rsp, i * wordSize));
+ __ jmp(next);
+
+// Do Double here
+ __ bind(isdouble);
+ __ movdbl(floatreg, Address(rsp, i * wordSize));
+
+ __ bind(next);
+ }
+
+
+ // restore rsp
+ __ addptr(rsp, 4 * wordSize);
+
+ __ ret(0);
+
+ return entry;
+}
+#else
+address TemplateInterpreterGenerator::generate_slow_signature_handler() {
+ address entry = __ pc();
+
+ // rbx: method
+ // r14: pointer to locals
+ // c_rarg3: first stack arg - wordSize
+ __ mov(c_rarg3, rsp);
+ // adjust rsp
+ __ subptr(rsp, 14 * wordSize);
+ __ call_VM(noreg,
+ CAST_FROM_FN_PTR(address,
+ InterpreterRuntime::slow_signature_handler),
+ rbx, r14, c_rarg3);
+
+ // rax: result handler
+
+ // Stack layout:
+ // rsp: 5 integer args (if static first is unused)
+ // 1 float/double identifiers
+ // 8 double args
+ // return address
+ // stack args
+ // garbage
+ // expression stack bottom
+ // bcp (NULL)
+ // ...
+
+ // Do FP first so we can use c_rarg3 as temp
+ __ movl(c_rarg3, Address(rsp, 5 * wordSize)); // float/double identifiers
+
+ for (int i = 0; i < Argument::n_float_register_parameters_c; i++) {
+ const XMMRegister r = as_XMMRegister(i);
+
+ Label d, done;
+
+ __ testl(c_rarg3, 1 << i);
+ __ jcc(Assembler::notZero, d);
+ __ movflt(r, Address(rsp, (6 + i) * wordSize));
+ __ jmp(done);
+ __ bind(d);
+ __ movdbl(r, Address(rsp, (6 + i) * wordSize));
+ __ bind(done);
+ }
+
+ // Now handle integrals. Only do c_rarg1 if not static.
+ __ movl(c_rarg3, Address(rbx, Method::access_flags_offset()));
+ __ testl(c_rarg3, JVM_ACC_STATIC);
+ __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0));
+
+ __ movptr(c_rarg2, Address(rsp, wordSize));
+ __ movptr(c_rarg3, Address(rsp, 2 * wordSize));
+ __ movptr(c_rarg4, Address(rsp, 3 * wordSize));
+ __ movptr(c_rarg5, Address(rsp, 4 * wordSize));
+
+ // restore rsp
+ __ addptr(rsp, 14 * wordSize);
+
+ __ ret(0);
+
+ return entry;
+}
+#endif // __WIN64
+
/**
* Method entry for static native methods:
* int java.util.zip.CRC32.update(int crc, int b)
@@ -193,3 +337,85 @@
return NULL;
}
+
+//
+// Various method entries
+//
+
+address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
+
+ // rbx,: Method*
+ // rcx: scratrch
+ // r13: sender sp
+
+ if (!InlineIntrinsics) return NULL; // Generate a vanilla entry
+
+ address entry_point = __ pc();
+
+ // These don't need a safepoint check because they aren't virtually
+ // callable. We won't enter these intrinsics from compiled code.
+ // If in the future we added an intrinsic which was virtually callable
+ // we'd have to worry about how to safepoint so that this code is used.
+
+ // mathematical functions inlined by compiler
+ // (interpreter must provide identical implementation
+ // in order to avoid monotonicity bugs when switching
+ // from interpreter to compiler in the middle of some
+ // computation)
+ //
+ // stack: [ ret adr ] <-- rsp
+ // [ lo(arg) ]
+ // [ hi(arg) ]
+ //
+
+
+ if (kind == Interpreter::java_lang_math_sqrt) {
+ __ sqrtsd(xmm0, Address(rsp, wordSize));
+ } else if (kind == Interpreter::java_lang_math_exp) {
+ __ movdbl(xmm0, Address(rsp, wordSize));
+ __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dexp())));
+ } else if (kind == Interpreter::java_lang_math_log) {
+ __ movdbl(xmm0, Address(rsp, wordSize));
+ __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog())));
+ } else {
+ __ fld_d(Address(rsp, wordSize));
+ switch (kind) {
+ case Interpreter::java_lang_math_sin :
+ __ trigfunc('s');
+ break;
+ case Interpreter::java_lang_math_cos :
+ __ trigfunc('c');
+ break;
+ case Interpreter::java_lang_math_tan :
+ __ trigfunc('t');
+ break;
+ case Interpreter::java_lang_math_abs:
+ __ fabs();
+ break;
+ case Interpreter::java_lang_math_log10:
+ __ flog10();
+ break;
+ case Interpreter::java_lang_math_pow:
+ __ fld_d(Address(rsp, 3*wordSize)); // second argument (one
+ // empty stack slot)
+ __ pow_with_fallback(0);
+ break;
+ default :
+ ShouldNotReachHere();
+ }
+
+ // return double result in xmm0 for interpreter and compilers.
+ __ subptr(rsp, 2*wordSize);
+ // Round to 64bit precision
+ __ fstp_d(Address(rsp, 0));
+ __ movdbl(xmm0, Address(rsp, 0));
+ __ addptr(rsp, 2*wordSize);
+ }
+
+
+ __ pop(rax);
+ __ mov(rsp, r13);
+ __ jmp(rax);
+
+ return entry_point;
+}