< 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>


 497       break;
 498     }
 499     case Bytecodes::_l2i: {
 500       __ mr_if_needed(dst->as_register(), src->as_register_lo()); // high bits are garbage
 501       break;
 502     }
 503     case Bytecodes::_i2b: {
 504       __ extsb(dst->as_register(), src->as_register());
 505       break;
 506     }
 507     case Bytecodes::_i2c: {
 508       __ clrldi(dst->as_register(), src->as_register(), 64-16);
 509       break;
 510     }
 511     case Bytecodes::_i2s: {
 512       __ extsh(dst->as_register(), src->as_register());
 513       break;
 514     }
 515     case Bytecodes::_i2d:
 516     case Bytecodes::_l2d: {
 517       __ fcfid(dst->as_double_reg(), src->as_double_reg()); // via mem














 518       break;
 519     }
 520     case Bytecodes::_i2f: {


 521       FloatRegister rdst = dst->as_float_reg();
 522       FloatRegister rsrc = src->as_double_reg(); // via mem











 523       if (VM_Version::has_fcfids()) {
 524         __ fcfids(rdst, rsrc);
 525       } else {

 526         __ fcfid(rdst, rsrc);
 527         __ frsp(rdst, rdst);
 528       }
 529       break;
 530     }
 531     case Bytecodes::_l2f: { // >= Power7
 532       assert(VM_Version::has_fcfids(), "fcfid+frsp needs fixup code to avoid rounding incompatibility");
 533       __ fcfids(dst->as_float_reg(), src->as_double_reg()); // via mem
 534       break;
 535     }
 536     case Bytecodes::_f2d: {
 537       __ fmr_if_needed(dst->as_double_reg(), src->as_float_reg());
 538       break;
 539     }
 540     case Bytecodes::_d2f: {
 541       __ frsp(dst->as_float_reg(), src->as_double_reg());
 542       break;
 543     }
 544     case Bytecodes::_d2i:
 545     case Bytecodes::_f2i: {

 546       FloatRegister rsrc = (code == Bytecodes::_d2i) ? src->as_double_reg() : src->as_float_reg();
 547       Address       addr = frame_map()->address_for_slot(dst->double_stack_ix());
 548       Label L;
 549       // Result must be 0 if value is NaN; test by comparing value to itself.
 550       __ fcmpu(CCR0, rsrc, rsrc);

 551       __ li(R0, 0); // 0 in case of NAN
 552       __ std(R0, addr.disp(), addr.base());



 553       __ bso(CCR0, L);
 554       __ fctiwz(rsrc, rsrc); // USE_KILL

 555       __ stfd(rsrc, addr.disp(), addr.base());



 556       __ bind(L);
 557       break;
 558     }
 559     case Bytecodes::_d2l:
 560     case Bytecodes::_f2l: {

 561       FloatRegister rsrc = (code == Bytecodes::_d2l) ? src->as_double_reg() : src->as_float_reg();
 562       Address       addr = frame_map()->address_for_slot(dst->double_stack_ix());
 563       Label L;
 564       // Result must be 0 if value is NaN; test by comparing value to itself.
 565       __ fcmpu(CCR0, rsrc, rsrc);

 566       __ li(R0, 0); // 0 in case of NAN
 567       __ std(R0, addr.disp(), addr.base());



 568       __ bso(CCR0, L);
 569       __ fctidz(rsrc, rsrc); // USE_KILL

 570       __ stfd(rsrc, addr.disp(), addr.base());



 571       __ bind(L);
 572       break;
 573     }
 574 
 575     default: ShouldNotReachHere();
 576   }
 577 }
 578 
 579 
 580 void LIR_Assembler::align_call(LIR_Code) {
 581   // do nothing since all instructions are word aligned on ppc
 582 }
 583 
 584 
 585 bool LIR_Assembler::emit_trampoline_stub_for_call(address target, Register Rtoc) {
 586   int start_offset = __ offset();
 587   // Put the entry point as a constant into the constant pool.
 588   const address entry_point_toc_addr   = __ address_constant(target, RelocationHolder::none);
 589   if (entry_point_toc_addr == NULL) {
 590     bailout("const section overflow");




 497       break;
 498     }
 499     case Bytecodes::_l2i: {
 500       __ mr_if_needed(dst->as_register(), src->as_register_lo()); // high bits are garbage
 501       break;
 502     }
 503     case Bytecodes::_i2b: {
 504       __ extsb(dst->as_register(), src->as_register());
 505       break;
 506     }
 507     case Bytecodes::_i2c: {
 508       __ clrldi(dst->as_register(), src->as_register(), 64-16);
 509       break;
 510     }
 511     case Bytecodes::_i2s: {
 512       __ extsh(dst->as_register(), src->as_register());
 513       break;
 514     }
 515     case Bytecodes::_i2d:
 516     case Bytecodes::_l2d: {
 517       bool src_in_memory = !VM_Version::has_mtfprd();
 518       FloatRegister rdst = dst->as_double_reg();
 519       FloatRegister rsrc;
 520       if (src_in_memory) {
 521         rsrc = src->as_double_reg(); // via mem
 522       } else {
 523         // move src to dst register
 524         if (code == Bytecodes::_i2d) {
 525           __ mtfprwa(rdst, src->as_register());
 526         } else {
 527           __ mtfprd(rdst, src->as_register_lo());
 528         }
 529         rsrc = rdst;
 530       }
 531       __ fcfid(rdst, rsrc);
 532       break;
 533     }
 534     case Bytecodes::_i2f:
 535     case Bytecodes::_l2f: {
 536       bool src_in_memory = !VM_Version::has_mtfprd();
 537       FloatRegister rdst = dst->as_float_reg();
 538       FloatRegister rsrc;
 539       if (src_in_memory) {
 540         rsrc = src->as_double_reg(); // via mem
 541       } else {
 542         // move src to dst register
 543         if (code == Bytecodes::_i2f) {
 544           __ mtfprwa(rdst, src->as_register());
 545         } else {
 546           __ mtfprd(rdst, src->as_register_lo());
 547         }
 548         rsrc = rdst;
 549       }
 550       if (VM_Version::has_fcfids()) {
 551         __ fcfids(rdst, rsrc);
 552       } else {
 553         assert(code == Bytecodes::_i2f, "fcfid+frsp needs fixup code to avoid rounding incompatibility");
 554         __ fcfid(rdst, rsrc);
 555         __ frsp(rdst, rdst);
 556       }
 557       break;
 558     }





 559     case Bytecodes::_f2d: {
 560       __ fmr_if_needed(dst->as_double_reg(), src->as_float_reg());
 561       break;
 562     }
 563     case Bytecodes::_d2f: {
 564       __ frsp(dst->as_float_reg(), src->as_double_reg());
 565       break;
 566     }
 567     case Bytecodes::_d2i:
 568     case Bytecodes::_f2i: {
 569       bool dst_in_memory = !VM_Version::has_mtfprd();
 570       FloatRegister rsrc = (code == Bytecodes::_d2i) ? src->as_double_reg() : src->as_float_reg();
 571       Address       addr = dst_in_memory ? frame_map()->address_for_slot(dst->double_stack_ix()) : NULL;
 572       Label L;
 573       // Result must be 0 if value is NaN; test by comparing value to itself.
 574       __ fcmpu(CCR0, rsrc, rsrc);
 575       if (dst_in_memory) {
 576         __ li(R0, 0); // 0 in case of NAN
 577         __ std(R0, addr.disp(), addr.base());
 578       } else {
 579         __ li(dst->as_register(), 0);
 580       }
 581       __ bso(CCR0, L);
 582       __ fctiwz(rsrc, rsrc); // USE_KILL
 583       if (dst_in_memory) {
 584         __ stfd(rsrc, addr.disp(), addr.base());
 585       } else {
 586         __ mffprd(dst->as_register(), rsrc);
 587       }
 588       __ bind(L);
 589       break;
 590     }
 591     case Bytecodes::_d2l:
 592     case Bytecodes::_f2l: {
 593       bool dst_in_memory = !VM_Version::has_mtfprd();
 594       FloatRegister rsrc = (code == Bytecodes::_d2l) ? src->as_double_reg() : src->as_float_reg();
 595       Address       addr = dst_in_memory ? frame_map()->address_for_slot(dst->double_stack_ix()) : NULL;
 596       Label L;
 597       // Result must be 0 if value is NaN; test by comparing value to itself.
 598       __ fcmpu(CCR0, rsrc, rsrc);
 599       if (dst_in_memory) {
 600         __ li(R0, 0); // 0 in case of NAN
 601         __ std(R0, addr.disp(), addr.base());
 602       } else {
 603         __ li(dst->as_register_lo(), 0);
 604       }
 605       __ bso(CCR0, L);
 606       __ fctidz(rsrc, rsrc); // USE_KILL
 607       if (dst_in_memory) {
 608         __ stfd(rsrc, addr.disp(), addr.base());
 609       } else {
 610         __ mffprd(dst->as_register_lo(), rsrc);
 611       }
 612       __ bind(L);
 613       break;
 614     }
 615 
 616     default: ShouldNotReachHere();
 617   }
 618 }
 619 
 620 
 621 void LIR_Assembler::align_call(LIR_Code) {
 622   // do nothing since all instructions are word aligned on ppc
 623 }
 624 
 625 
 626 bool LIR_Assembler::emit_trampoline_stub_for_call(address target, Register Rtoc) {
 627   int start_offset = __ offset();
 628   // Put the entry point as a constant into the constant pool.
 629   const address entry_point_toc_addr   = __ address_constant(target, RelocationHolder::none);
 630   if (entry_point_toc_addr == NULL) {
 631     bailout("const section overflow");


< prev index next >