diff src/share/vm/c1/c1_LIR.cpp @ 6084:6759698e3140

7133857: exp() and pow() should use the x87 ISA on x86 Summary: use x87 instructions to implement exp() and pow() in interpreter/c1/c2. Reviewed-by: kvn, never, twisti
author roland
date Tue, 15 May 2012 10:10:23 +0200
parents 701a83c86f28
children da91efe96a93
line wrap: on
line diff
--- a/src/share/vm/c1/c1_LIR.cpp	Mon May 14 09:36:00 2012 -0700
+++ b/src/share/vm/c1/c1_LIR.cpp	Tue May 15 10:10:23 2012 +0200
@@ -624,11 +624,13 @@
     {
       assert(op->as_Op2() != NULL, "must be");
       LIR_Op2* op2 = (LIR_Op2*)op;
+      assert(op2->_tmp2->is_illegal() && op2->_tmp3->is_illegal() &&
+             op2->_tmp4->is_illegal() && op2->_tmp5->is_illegal(), "not used");
 
       if (op2->_info)                     do_info(op2->_info);
       if (op2->_opr1->is_valid())         do_input(op2->_opr1);
       if (op2->_opr2->is_valid())         do_input(op2->_opr2);
-      if (op2->_tmp->is_valid())          do_temp(op2->_tmp);
+      if (op2->_tmp1->is_valid())         do_temp(op2->_tmp1);
       if (op2->_result->is_valid())       do_output(op2->_result);
 
       break;
@@ -641,7 +643,8 @@
       assert(op->as_Op2() != NULL, "must be");
       LIR_Op2* op2 = (LIR_Op2*)op;
 
-      assert(op2->_info == NULL && op2->_tmp->is_illegal(), "not used");
+      assert(op2->_info == NULL && op2->_tmp1->is_illegal() && op2->_tmp2->is_illegal() &&
+             op2->_tmp3->is_illegal() && op2->_tmp4->is_illegal() && op2->_tmp5->is_illegal(), "not used");
       assert(op2->_opr1->is_valid() && op2->_opr2->is_valid() && op2->_result->is_valid(), "used");
 
       do_input(op2->_opr1);
@@ -665,10 +668,12 @@
       assert(op2->_opr1->is_valid(), "used");
       assert(op2->_opr2->is_valid(), "used");
       assert(op2->_result->is_valid(), "used");
+      assert(op2->_tmp2->is_illegal() && op2->_tmp3->is_illegal() &&
+             op2->_tmp4->is_illegal() && op2->_tmp5->is_illegal(), "not used");
 
       do_input(op2->_opr1); do_temp(op2->_opr1);
       do_input(op2->_opr2); do_temp(op2->_opr2);
-      if (op2->_tmp->is_valid()) do_temp(op2->_tmp);
+      if (op2->_tmp1->is_valid()) do_temp(op2->_tmp1);
       do_output(op2->_result);
 
       break;
@@ -682,6 +687,8 @@
       if (op2->_opr1->is_valid())         do_temp(op2->_opr1);
       if (op2->_opr2->is_valid())         do_input(op2->_opr2); // exception object is input parameter
       assert(op2->_result->is_illegal(), "no result");
+      assert(op2->_tmp2->is_illegal() && op2->_tmp3->is_illegal() &&
+             op2->_tmp4->is_illegal() && op2->_tmp5->is_illegal(), "not used");
 
       break;
     }
@@ -702,7 +709,8 @@
     case lir_sin:
     case lir_cos:
     case lir_log:
-    case lir_log10: {
+    case lir_log10:
+    case lir_exp: {
       assert(op->as_Op2() != NULL, "must be");
       LIR_Op2* op2 = (LIR_Op2*)op;
 
@@ -711,16 +719,47 @@
       // Register input operand as temp to guarantee that it doesn't
       // overlap with the input.
       assert(op2->_info == NULL, "not used");
+      assert(op2->_tmp5->is_illegal(), "not used");
+      assert(op2->_tmp2->is_valid() == (op->code() == lir_exp), "not used");
+      assert(op2->_tmp3->is_valid() == (op->code() == lir_exp), "not used");
+      assert(op2->_tmp4->is_valid() == (op->code() == lir_exp), "not used");
       assert(op2->_opr1->is_valid(), "used");
       do_input(op2->_opr1); do_temp(op2->_opr1);
 
       if (op2->_opr2->is_valid())         do_temp(op2->_opr2);
-      if (op2->_tmp->is_valid())          do_temp(op2->_tmp);
+      if (op2->_tmp1->is_valid())         do_temp(op2->_tmp1);
+      if (op2->_tmp2->is_valid())         do_temp(op2->_tmp2);
+      if (op2->_tmp3->is_valid())         do_temp(op2->_tmp3);
+      if (op2->_tmp4->is_valid())         do_temp(op2->_tmp4);
       if (op2->_result->is_valid())       do_output(op2->_result);
 
       break;
     }
 
+    case lir_pow: {
+      assert(op->as_Op2() != NULL, "must be");
+      LIR_Op2* op2 = (LIR_Op2*)op;
+
+      // On x86 pow needs two temporary fpu stack slots: tmp1 and
+      // tmp2. Register input operands as temps to guarantee that it
+      // doesn't overlap with the temporary slots.
+      assert(op2->_info == NULL, "not used");
+      assert(op2->_opr1->is_valid() && op2->_opr2->is_valid(), "used");
+      assert(op2->_tmp1->is_valid() && op2->_tmp2->is_valid() && op2->_tmp3->is_valid()
+             && op2->_tmp4->is_valid() && op2->_tmp5->is_valid(), "used");
+      assert(op2->_result->is_valid(), "used");
+
+      do_input(op2->_opr1); do_temp(op2->_opr1);
+      do_input(op2->_opr2); do_temp(op2->_opr2);
+      do_temp(op2->_tmp1);
+      do_temp(op2->_tmp2);
+      do_temp(op2->_tmp3);
+      do_temp(op2->_tmp4);
+      do_temp(op2->_tmp5);
+      do_output(op2->_result);
+
+      break;
+    }
 
 // LIR_Op3
     case lir_idiv:
@@ -1670,6 +1709,8 @@
      case lir_tan:                   s = "tan";           break;
      case lir_log:                   s = "log";           break;
      case lir_log10:                 s = "log10";         break;
+     case lir_exp:                   s = "exp";           break;
+     case lir_pow:                   s = "pow";           break;
      case lir_logic_and:             s = "logic_and";     break;
      case lir_logic_or:              s = "logic_or";      break;
      case lir_logic_xor:             s = "logic_xor";     break;
@@ -1892,7 +1933,11 @@
   }
   in_opr1()->print(out);    out->print(" ");
   in_opr2()->print(out);    out->print(" ");
-  if (tmp_opr()->is_valid()) { tmp_opr()->print(out);    out->print(" "); }
+  if (tmp1_opr()->is_valid()) { tmp1_opr()->print(out);    out->print(" "); }
+  if (tmp2_opr()->is_valid()) { tmp2_opr()->print(out);    out->print(" "); }
+  if (tmp3_opr()->is_valid()) { tmp3_opr()->print(out);    out->print(" "); }
+  if (tmp4_opr()->is_valid()) { tmp4_opr()->print(out);    out->print(" "); }
+  if (tmp5_opr()->is_valid()) { tmp5_opr()->print(out);    out->print(" "); }
   result_opr()->print(out);
 }