< prev index next >

src/cpu/ppc/vm/c1_LIRAssembler_ppc.cpp

Print this page
rev 13142 : 8181809: PPC64: Leverage mtfprd/mffprd on POWER8
Reviewed-by: mdoerr, simonis
Contributed-by: Matthew Brandyberry <mbrandy@linux.vnet.ibm.com>

@@ -512,64 +512,105 @@
       __ extsh(dst->as_register(), src->as_register());
       break;
     }
     case Bytecodes::_i2d:
     case Bytecodes::_l2d: {
-      __ fcfid(dst->as_double_reg(), src->as_double_reg()); // via mem
+      bool src_in_memory = !VM_Version::has_mtfprd();
+      FloatRegister rdst = dst->as_double_reg();
+      FloatRegister rsrc;
+      if (src_in_memory) {
+        rsrc = src->as_double_reg(); // via mem
+      } else {
+        // move src to dst register
+        if (code == Bytecodes::_i2d) {
+          __ mtfprwa(rdst, src->as_register());
+        } else {
+          __ mtfprd(rdst, src->as_register_lo());
+        }
+        rsrc = rdst;
+      }
+      __ fcfid(rdst, rsrc);
       break;
     }
-    case Bytecodes::_i2f: {
+    case Bytecodes::_i2f:
+    case Bytecodes::_l2f: {
+      bool src_in_memory = !VM_Version::has_mtfprd();
       FloatRegister rdst = dst->as_float_reg();
-      FloatRegister rsrc = src->as_double_reg(); // via mem
+      FloatRegister rsrc;
+      if (src_in_memory) {
+        rsrc = src->as_double_reg(); // via mem
+      } else {
+        // move src to dst register
+        if (code == Bytecodes::_i2f) {
+          __ mtfprwa(rdst, src->as_register());
+        } else {
+          __ mtfprd(rdst, src->as_register_lo());
+        }
+        rsrc = rdst;
+      }
       if (VM_Version::has_fcfids()) {
         __ fcfids(rdst, rsrc);
       } else {
+        assert(code == Bytecodes::_i2f, "fcfid+frsp needs fixup code to avoid rounding incompatibility");
         __ fcfid(rdst, rsrc);
         __ frsp(rdst, rdst);
       }
       break;
     }
-    case Bytecodes::_l2f: { // >= Power7
-      assert(VM_Version::has_fcfids(), "fcfid+frsp needs fixup code to avoid rounding incompatibility");
-      __ fcfids(dst->as_float_reg(), src->as_double_reg()); // via mem
-      break;
-    }
     case Bytecodes::_f2d: {
       __ fmr_if_needed(dst->as_double_reg(), src->as_float_reg());
       break;
     }
     case Bytecodes::_d2f: {
       __ frsp(dst->as_float_reg(), src->as_double_reg());
       break;
     }
     case Bytecodes::_d2i:
     case Bytecodes::_f2i: {
+      bool dst_in_memory = !VM_Version::has_mtfprd();
       FloatRegister rsrc = (code == Bytecodes::_d2i) ? src->as_double_reg() : src->as_float_reg();
-      Address       addr = frame_map()->address_for_slot(dst->double_stack_ix());
+      Address       addr = dst_in_memory ? frame_map()->address_for_slot(dst->double_stack_ix()) : NULL;
       Label L;
       // Result must be 0 if value is NaN; test by comparing value to itself.
       __ fcmpu(CCR0, rsrc, rsrc);
+      if (dst_in_memory) {
       __ li(R0, 0); // 0 in case of NAN
       __ std(R0, addr.disp(), addr.base());
+      } else {
+        __ li(dst->as_register(), 0);
+      }
       __ bso(CCR0, L);
       __ fctiwz(rsrc, rsrc); // USE_KILL
+      if (dst_in_memory) {
       __ stfd(rsrc, addr.disp(), addr.base());
+      } else {
+        __ mffprd(dst->as_register(), rsrc);
+      }
       __ bind(L);
       break;
     }
     case Bytecodes::_d2l:
     case Bytecodes::_f2l: {
+      bool dst_in_memory = !VM_Version::has_mtfprd();
       FloatRegister rsrc = (code == Bytecodes::_d2l) ? src->as_double_reg() : src->as_float_reg();
-      Address       addr = frame_map()->address_for_slot(dst->double_stack_ix());
+      Address       addr = dst_in_memory ? frame_map()->address_for_slot(dst->double_stack_ix()) : NULL;
       Label L;
       // Result must be 0 if value is NaN; test by comparing value to itself.
       __ fcmpu(CCR0, rsrc, rsrc);
+      if (dst_in_memory) {
       __ li(R0, 0); // 0 in case of NAN
       __ std(R0, addr.disp(), addr.base());
+      } else {
+        __ li(dst->as_register_lo(), 0);
+      }
       __ bso(CCR0, L);
       __ fctidz(rsrc, rsrc); // USE_KILL
+      if (dst_in_memory) {
       __ stfd(rsrc, addr.disp(), addr.base());
+      } else {
+        __ mffprd(dst->as_register_lo(), rsrc);
+      }
       __ bind(L);
       break;
     }
 
     default: ShouldNotReachHere();
< prev index next >