< prev index next >

src/cpu/x86/vm/templateInterpreterGenerator_x86_64.cpp

Print this page

        

@@ -24,15 +24,159 @@
 
 #include "precompiled.hpp"
 #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)
  */
 address TemplateInterpreterGenerator::generate_CRC32_update_entry() {

@@ -191,5 +335,87 @@
     return entry;
   }
 
   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;
+}
< prev index next >