2614 load_ptr_contents(a, tmp);
2615
2616 #ifdef ASSERT
2617 tst(tmp);
2618 breakpoint_trap(zero, xcc);
2619 #endif
2620
2621 if (offset != 0)
2622 add(tmp, offset, tmp);
2623
2624 return RegisterOrConstant(tmp);
2625 }
2626
2627
2628 void MacroAssembler::regcon_inc_ptr( RegisterOrConstant& dest, RegisterOrConstant src, Register temp ) {
2629 assert(dest.register_or_noreg() != G0, "lost side effect");
2630 if ((src.is_constant() && src.as_constant() == 0) ||
2631 (src.is_register() && src.as_register() == G0)) {
2632 // do nothing
2633 } else if (dest.is_register()) {
2634 add(dest.as_register(), ensure_rs2(src, temp), dest.as_register());
2635 } else if (src.is_constant()) {
2636 intptr_t res = dest.as_constant() + src.as_constant();
2637 dest = RegisterOrConstant(res); // side effect seen by caller
2638 } else {
2639 assert(temp != noreg, "cannot handle constant += register");
2640 add(src.as_register(), ensure_rs2(dest, temp), temp);
2641 dest = RegisterOrConstant(temp); // side effect seen by caller
2642 }
2643 }
2644
2645 void MacroAssembler::regcon_sll_ptr( RegisterOrConstant& dest, RegisterOrConstant src, Register temp ) {
2646 assert(dest.register_or_noreg() != G0, "lost side effect");
2647 if (!is_simm13(src.constant_or_zero()))
2648 src = (src.as_constant() & 0xFF);
2649 if ((src.is_constant() && src.as_constant() == 0) ||
2650 (src.is_register() && src.as_register() == G0)) {
2651 // do nothing
2652 } else if (dest.is_register()) {
2653 sll_ptr(dest.as_register(), src, dest.as_register());
2654 } else if (src.is_constant()) {
2655 intptr_t res = dest.as_constant() << src.as_constant();
2656 dest = RegisterOrConstant(res); // side effect seen by caller
2657 } else {
2658 assert(temp != noreg, "cannot handle constant <<= register");
2659 set(dest.as_constant(), temp);
2660 sll_ptr(temp, src, temp);
2693 if (round_to_unit != 0) {
2694 // hoist first instruction of round_to(scan_temp, BytesPerLong):
2695 itb_offset += round_to_unit - wordSize;
2696 }
2697 int itb_scale = exact_log2(vtableEntry::size() * wordSize);
2698 sll(scan_temp, itb_scale, scan_temp);
2699 add(scan_temp, itb_offset, scan_temp);
2700 if (round_to_unit != 0) {
2701 // Round up to align_object_offset boundary
2702 // see code for instanceKlass::start_of_itable!
2703 // Was: round_to(scan_temp, BytesPerLong);
2704 // Hoisted: add(scan_temp, BytesPerLong-1, scan_temp);
2705 and3(scan_temp, -round_to_unit, scan_temp);
2706 }
2707 add(recv_klass, scan_temp, scan_temp);
2708
2709 // Adjust recv_klass by scaled itable_index, so we can free itable_index.
2710 RegisterOrConstant itable_offset = itable_index;
2711 regcon_sll_ptr(itable_offset, exact_log2(itableMethodEntry::size() * wordSize));
2712 regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes());
2713 add(recv_klass, ensure_rs2(itable_offset, sethi_temp), recv_klass);
2714
2715 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
2716 // if (scan->interface() == intf) {
2717 // result = (klass + scan->offset() + itable_index);
2718 // }
2719 // }
2720 Label search, found_method;
2721
2722 for (int peel = 1; peel >= 0; peel--) {
2723 // %%%% Could load both offset and interface in one ldx, if they were
2724 // in the opposite order. This would save a load.
2725 ld_ptr(scan_temp, itableOffsetEntry::interface_offset_in_bytes(), method_result);
2726
2727 // Check that this entry is non-null. A null entry means that
2728 // the receiver class doesn't implement the interface, and wasn't the
2729 // same as when the caller was compiled.
2730 bpr(Assembler::rc_z, false, Assembler::pn, method_result, L_no_such_interface);
2731 delayed()->cmp(method_result, intf_klass);
2732
2733 if (peel) {
|
2614 load_ptr_contents(a, tmp);
2615
2616 #ifdef ASSERT
2617 tst(tmp);
2618 breakpoint_trap(zero, xcc);
2619 #endif
2620
2621 if (offset != 0)
2622 add(tmp, offset, tmp);
2623
2624 return RegisterOrConstant(tmp);
2625 }
2626
2627
2628 void MacroAssembler::regcon_inc_ptr( RegisterOrConstant& dest, RegisterOrConstant src, Register temp ) {
2629 assert(dest.register_or_noreg() != G0, "lost side effect");
2630 if ((src.is_constant() && src.as_constant() == 0) ||
2631 (src.is_register() && src.as_register() == G0)) {
2632 // do nothing
2633 } else if (dest.is_register()) {
2634 add(dest.as_register(), ensure_simm13_or_reg(src, temp), dest.as_register());
2635 } else if (src.is_constant()) {
2636 intptr_t res = dest.as_constant() + src.as_constant();
2637 dest = RegisterOrConstant(res); // side effect seen by caller
2638 } else {
2639 assert(temp != noreg, "cannot handle constant += register");
2640 add(src.as_register(), ensure_simm13_or_reg(dest, temp), temp);
2641 dest = RegisterOrConstant(temp); // side effect seen by caller
2642 }
2643 }
2644
2645 void MacroAssembler::regcon_sll_ptr( RegisterOrConstant& dest, RegisterOrConstant src, Register temp ) {
2646 assert(dest.register_or_noreg() != G0, "lost side effect");
2647 if (!is_simm13(src.constant_or_zero()))
2648 src = (src.as_constant() & 0xFF);
2649 if ((src.is_constant() && src.as_constant() == 0) ||
2650 (src.is_register() && src.as_register() == G0)) {
2651 // do nothing
2652 } else if (dest.is_register()) {
2653 sll_ptr(dest.as_register(), src, dest.as_register());
2654 } else if (src.is_constant()) {
2655 intptr_t res = dest.as_constant() << src.as_constant();
2656 dest = RegisterOrConstant(res); // side effect seen by caller
2657 } else {
2658 assert(temp != noreg, "cannot handle constant <<= register");
2659 set(dest.as_constant(), temp);
2660 sll_ptr(temp, src, temp);
2693 if (round_to_unit != 0) {
2694 // hoist first instruction of round_to(scan_temp, BytesPerLong):
2695 itb_offset += round_to_unit - wordSize;
2696 }
2697 int itb_scale = exact_log2(vtableEntry::size() * wordSize);
2698 sll(scan_temp, itb_scale, scan_temp);
2699 add(scan_temp, itb_offset, scan_temp);
2700 if (round_to_unit != 0) {
2701 // Round up to align_object_offset boundary
2702 // see code for instanceKlass::start_of_itable!
2703 // Was: round_to(scan_temp, BytesPerLong);
2704 // Hoisted: add(scan_temp, BytesPerLong-1, scan_temp);
2705 and3(scan_temp, -round_to_unit, scan_temp);
2706 }
2707 add(recv_klass, scan_temp, scan_temp);
2708
2709 // Adjust recv_klass by scaled itable_index, so we can free itable_index.
2710 RegisterOrConstant itable_offset = itable_index;
2711 regcon_sll_ptr(itable_offset, exact_log2(itableMethodEntry::size() * wordSize));
2712 regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes());
2713 add(recv_klass, ensure_simm13_or_reg(itable_offset, sethi_temp), recv_klass);
2714
2715 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
2716 // if (scan->interface() == intf) {
2717 // result = (klass + scan->offset() + itable_index);
2718 // }
2719 // }
2720 Label search, found_method;
2721
2722 for (int peel = 1; peel >= 0; peel--) {
2723 // %%%% Could load both offset and interface in one ldx, if they were
2724 // in the opposite order. This would save a load.
2725 ld_ptr(scan_temp, itableOffsetEntry::interface_offset_in_bytes(), method_result);
2726
2727 // Check that this entry is non-null. A null entry means that
2728 // the receiver class doesn't implement the interface, and wasn't the
2729 // same as when the caller was compiled.
2730 bpr(Assembler::rc_z, false, Assembler::pn, method_result, L_no_such_interface);
2731 delayed()->cmp(method_result, intf_klass);
2732
2733 if (peel) {
|