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");
|