< 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,575 **** __ 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 break; } ! case Bytecodes::_i2f: { FloatRegister rdst = dst->as_float_reg(); ! FloatRegister rsrc = src->as_double_reg(); // via mem if (VM_Version::has_fcfids()) { __ fcfids(rdst, rsrc); } else { __ 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: { FloatRegister rsrc = (code == Bytecodes::_d2i) ? src->as_double_reg() : src->as_float_reg(); ! Address addr = frame_map()->address_for_slot(dst->double_stack_ix()); Label L; // Result must be 0 if value is NaN; test by comparing value to itself. __ fcmpu(CCR0, rsrc, rsrc); __ li(R0, 0); // 0 in case of NAN __ std(R0, addr.disp(), addr.base()); __ bso(CCR0, L); __ fctiwz(rsrc, rsrc); // USE_KILL __ stfd(rsrc, addr.disp(), addr.base()); __ bind(L); break; } case Bytecodes::_d2l: case Bytecodes::_f2l: { FloatRegister rsrc = (code == Bytecodes::_d2l) ? src->as_double_reg() : src->as_float_reg(); ! Address addr = frame_map()->address_for_slot(dst->double_stack_ix()); Label L; // Result must be 0 if value is NaN; test by comparing value to itself. __ fcmpu(CCR0, rsrc, rsrc); __ li(R0, 0); // 0 in case of NAN __ std(R0, addr.disp(), addr.base()); __ bso(CCR0, L); __ fctidz(rsrc, rsrc); // USE_KILL __ stfd(rsrc, addr.disp(), addr.base()); __ bind(L); break; } default: ShouldNotReachHere(); --- 512,616 ---- __ extsh(dst->as_register(), src->as_register()); break; } case Bytecodes::_i2d: case Bytecodes::_l2d: { ! 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::_l2f: { ! bool src_in_memory = !VM_Version::has_mtfprd(); FloatRegister rdst = dst->as_float_reg(); ! 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::_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 = 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 = 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 >