/hg/icedtea6: Math inlines for ARM.

aph at icedtea.classpath.org aph at icedtea.classpath.org
Wed Feb 22 07:40:41 PST 2012


changeset 01123e3102cc in /hg/icedtea6
details: http://icedtea.classpath.org/hg/icedtea6?cmd=changeset;node=01123e3102cc
author: aph
date: Wed Feb 22 15:36:29 2012 +0000

	Math inlines for ARM. 2012-02-22 Andrew Haley <aph at redhat.com>

	 * arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp
	(handle_special_method, jstack_to_vfp, vfp_to_jstack): New
	functions. (Thumb2_codegen): Call handle_special_method.
	(t_vop_ops): Add VSQRT. (T_VMOVD_VFP_TOVFP): New macro.
	(vmov_reg_d_VFP_to_VFP): New function.


diffstat:

 ChangeLog                                   |   10 ++
 arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp |  138 +++++++++++++++++++++++++++-
 2 files changed, 147 insertions(+), 1 deletions(-)

diffs (206 lines):

diff -r e77e59c08299 -r 01123e3102cc ChangeLog
--- a/ChangeLog	Mon Feb 20 16:03:08 2012 +0000
+++ b/ChangeLog	Wed Feb 22 15:36:29 2012 +0000
@@ -1,3 +1,13 @@
+2012-02-22  Andrew Haley  <aph at redhat.com>
+
+	* arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp
+        (handle_special_method, jstack_to_vfp, vfp_to_jstack): New
+        functions.
+        (Thumb2_codegen): Call handle_special_method.
+        (t_vop_ops): Add VSQRT.
+        (T_VMOVD_VFP_TOVFP): New macro.
+        (vmov_reg_d_VFP_to_VFP): New function.
+
 2012-02-20  Andrew Haley  <aph at redhat.com>
 
 	PR584:
diff -r e77e59c08299 -r 01123e3102cc arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp
--- a/arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp	Mon Feb 20 16:03:08 2012 +0000
+++ b/arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp	Wed Feb 22 15:36:29 2012 +0000
@@ -1557,7 +1557,7 @@
   } while (!(bc_stackinfo[bci] & BC_BRANCH_TARGET));
   return 0;
 }
-#endif // ZOMBIT_DETECTION
+#endif // ZOMBIE_DETECTION
 
 void Thumb2_RegAlloc(Thumb2_Info *jinfo)
 {
@@ -1991,12 +1991,14 @@
 #define VP_SUB	1
 #define VP_MUL	2
 #define VP_DIV	3
+#define VP_SQRT 4
 
 static const unsigned t_vop_ops[] = {
 	0xee300a00,			// VADD
 	0xee300a40,			// VSUB
 	0xee200a00,			// VMUL
 	0xee800a00,			// VDIV
+	0xeeb10bc0			// VSQRT
 };
 
 #define VP_REG(op)	t_vop_ops[op]
@@ -2162,6 +2164,9 @@
 #define T_VMOVD_TOVFP(dst, src_lo, src_hi) \
   (0xec400b10 | ((src_lo) << 12) | ((src_hi) << 16) | (((dst) & 0x10)<<(5-4)) | ((dst) & 0x0f))
 
+// VFP reg to VFP re move.
+#define T_VMOVD_VFP_TOVFP(dst, src) (0xeeb00b40 | (((dst) & 0x0f) << 12) | ((src) & 0x0f))
+
 #define T_VOP_REG_S(op, dst, lho, rho)	((op) |				\
 		(((dst) & 1) << 22) | (((dst) & 0x1e) << (12-1)) | 	\
 		(((lho) & 1) << 7) | (((lho) & 0x1e) << (16-1))	 |	\
@@ -2730,6 +2735,11 @@
   return out_16x2(codebuf, T_VMOVD_TOVFP(dst, src_lo, src_hi));
 }
 
+int vmov_reg_d_VFP_to_VFP(CodeBuf *codebuf, u32 dst, u32 src)
+{
+  return out_16x2(codebuf, T_VMOVD_VFP_TOVFP(dst, src));
+}
+
 int vmov_reg_d_toARM(CodeBuf *codebuf, u32 dst_lo, u32 dst_hi, u32 src)
 {
   return out_16x2(codebuf, T_VMOVD_TOARM(dst_lo, dst_hi, src));
@@ -4976,6 +4986,128 @@
 
 extern "C" void _ZN18InterpreterRuntime18register_finalizerEP10JavaThreadP7oopDesc(void);
 
+// Push VFP_REG to the java stack.
+static void vfp_to_jstack(Thumb2_Info *jinfo, int vfp_reg) {
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned r_lo, r_hi;
+  r_hi = PUSH(jstack, JSTACK_REG(jstack));
+  r_lo = PUSH(jstack, JSTACK_REG(jstack));
+  vmov_reg_d_toARM(jinfo->codebuf, r_lo, r_hi, vfp_reg);
+}
+
+// Pop the java stack to VFP_REG .
+static void jstack_to_vfp(Thumb2_Info *jinfo, int vfp_reg) {
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned r_lo, r_hi;
+  Thumb2_Fill(jinfo, 2);
+  r_lo = POP(jstack);
+  r_hi = POP(jstack);
+  vmov_reg_d_toVFP(jinfo->codebuf, vfp_reg, r_lo, r_hi);
+  Thumb2_Flush(jinfo);
+}
+
+// Expand a call to a "special" method.  These are usually inlines of
+// java.lang.Math methods.  Return true if the inlining succeeded.
+static bool handle_special_method(methodOop callee, Thumb2_Info *jinfo) {
+#ifdef __ARM_PCS_VFP
+  Thumb2_Stack *jstack = jinfo->jstack;
+
+  const char *entry_name;
+
+  unsigned loc1 = 0;
+
+  switch (Interpreter::method_kind(callee)) {
+  case Interpreter::java_lang_math_abs:
+   {
+      unsigned r_lo, r_hi;
+
+      Thumb2_Fill(jinfo, 2);
+      r_lo = POP(jstack);
+      r_hi = POP(jstack);
+      dop_imm_s(jinfo->codebuf, DP_BIC, r_hi, r_hi, 0x80000000, 0);
+      PUSH(jstack, r_hi);
+      PUSH(jstack, r_lo);
+
+      return true;
+    }
+
+  case Interpreter::java_lang_math_sin:
+    entry_name = "Java_java_lang_StrictMath_sin";
+    break;
+
+  case Interpreter::java_lang_math_cos:
+    entry_name = "Java_java_lang_StrictMath_cos";
+    break;
+
+  case Interpreter::java_lang_math_tan:
+    entry_name = "Java_java_lang_StrictMath_tan";
+    break;
+
+  case Interpreter::java_lang_math_sqrt:
+    {
+      void *entry_point = dlsym(NULL, "Java_java_lang_StrictMath_sqrt");
+      if (! entry_point)
+	return false;
+
+      unsigned r_lo, r_hi, r_res_lo, r_res_hi;
+
+      // Make sure that canonical NaNs are returned, as per the spec.
+      //
+      // Generate:
+      // vsqrt.f64 d0, d1
+      // vcmp.f64 d0, d0
+      // vmrs APSR_nzcv, fpscr
+      // beq.n 0f
+      // vmov.f64 d0, d1
+      // blx Java_java_lang_StrictMath_sqrt
+      // 0:
+      jstack_to_vfp(jinfo, VFP_D1);
+      vop_reg_d(jinfo->codebuf, VP_SQRT, VFP_D0, 0, VFP_D1);
+      vcmp_reg_d(jinfo->codebuf, VFP_D0, VFP_D0, 0);
+      vmrs(jinfo->codebuf, ARM_PC);
+      int loc = forward_16(jinfo->codebuf);
+      vmov_reg_d_VFP_to_VFP(jinfo->codebuf, VFP_D0, VFP_D1);
+      // FIXME: The JNI StrictMath routines don't use the JNIEnv *env
+      // parameter, so it's arguably pointless to pass it here.
+      add_imm(jinfo->codebuf, ARM_R0, Rthread, THREAD_JNI_ENVIRONMENT);
+      blx(jinfo->codebuf, (unsigned)entry_point);
+      bcc_patch(jinfo->codebuf, COND_EQ, loc);
+      vfp_to_jstack(jinfo, VFP_D0);
+
+      return true;
+    }
+
+  case Interpreter::java_lang_math_log:
+    entry_name = "Java_java_lang_StrictMath_log";
+    break;
+
+  case Interpreter::java_lang_math_log10:
+    entry_name = "Java_java_lang_StrictMath_log10";
+    break;
+
+  default:
+    return false;
+  }
+
+  void *entry_point = dlsym(NULL, entry_name);
+  if (! entry_point)
+    return false;
+
+  unsigned r_lo, r_hi, r_res_lo, r_res_hi;
+
+  jstack_to_vfp(jinfo, VFP_D0);
+  // FIXME: The JNI StrictMath routines don't use the JNIEnv *env
+  // parameter, so it's arguably pointless to pass it here.
+  add_imm(jinfo->codebuf, ARM_R0, Rthread, THREAD_JNI_ENVIRONMENT);
+  blx(jinfo->codebuf, (unsigned)entry_point);
+  vfp_to_jstack(jinfo, VFP_D0);
+
+  return true;
+#else
+  return false;
+#endif // __ARM_PCS_VFP
+}
+
 void Thumb2_codegen(Thumb2_Info *jinfo, unsigned start)
 {
   unsigned code_size = jinfo->code_size;
@@ -6044,6 +6176,10 @@
 	}
 
 	callee = (methodOop)cache->f1();
+
+	if (handle_special_method(callee, jinfo))
+	  break;
+
 	if (callee->is_accessor()) {
 	  u1 *code = callee->code_base();
 	  int index = GET_NATIVE_U2(&code[2]);



More information about the distro-pkg-dev mailing list