145 |
141 |
146 // Reload method, it may have moved. |
142 // Reload method, it may have moved. |
147 #ifdef CC_INTERP |
143 #ifdef CC_INTERP |
148 __ ld(R19_method, state_(_method)); |
144 __ ld(R19_method, state_(_method)); |
149 #else |
145 #else |
150 __ unimplemented("slow signature handler 1"); |
146 __ ld(R19_method, 0, target_sp); |
|
147 __ ld(R19_method, _ijava_state_neg(method), R19_method); |
151 #endif |
148 #endif |
152 |
149 |
153 // Get the result handler. |
150 // Get the result handler. |
154 __ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::get_result_handler), R16_thread, R19_method); |
151 __ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::get_result_handler), R16_thread, R19_method); |
155 |
152 |
156 // Reload method, it may have moved. |
153 // Reload method, it may have moved. |
157 #ifdef CC_INTERP |
154 #ifdef CC_INTERP |
158 __ ld(R19_method, state_(_method)); |
155 __ ld(R19_method, state_(_method)); |
159 #else |
156 #else |
160 __ unimplemented("slow signature handler 2"); |
157 __ ld(R19_method, 0, target_sp); |
|
158 __ ld(R19_method, _ijava_state_neg(method), R19_method); |
161 #endif |
159 #endif |
162 |
160 |
163 { |
161 { |
164 Label L; |
162 Label L; |
165 // test if static |
163 // test if static |
584 __ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started. |
588 __ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started. |
585 |
589 |
586 // Load from branch table and dispatch (volatile case: one instruction ahead) |
590 // Load from branch table and dispatch (volatile case: one instruction ahead) |
587 __ sldi(Rflags, Rflags, LogBytesPerWord); |
591 __ sldi(Rflags, Rflags, LogBytesPerWord); |
588 __ cmpwi(CCR6, Rscratch, 1); // volatile? |
592 __ cmpwi(CCR6, Rscratch, 1); // volatile? |
589 __ sldi(Rscratch, Rscratch, exact_log2(BytesPerInstWord)); // volatile ? size of 1 instruction : 0 |
593 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { |
|
594 __ sldi(Rscratch, Rscratch, exact_log2(BytesPerInstWord)); // volatile ? size of 1 instruction : 0 |
|
595 } |
590 __ ldx(Rbtable, Rbtable, Rflags); |
596 __ ldx(Rbtable, Rbtable, Rflags); |
591 |
597 |
592 __ subf(Rbtable, Rscratch, Rbtable); // point to volatile/non-volatile entry point |
598 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { |
|
599 __ subf(Rbtable, Rscratch, Rbtable); // point to volatile/non-volatile entry point |
|
600 } |
593 __ mtctr(Rbtable); |
601 __ mtctr(Rbtable); |
594 __ bctr(); |
602 __ bctr(); |
595 |
603 |
596 #ifdef ASSERT |
604 #ifdef ASSERT |
597 __ bind(LFlagInvalid); |
605 __ bind(LFlagInvalid); |
603 all_uninitialized = all_uninitialized && (branch_table[i] == NULL); |
611 all_uninitialized = all_uninitialized && (branch_table[i] == NULL); |
604 all_initialized = all_initialized && (branch_table[i] != NULL); |
612 all_initialized = all_initialized && (branch_table[i] != NULL); |
605 } |
613 } |
606 assert(all_uninitialized != all_initialized, "consistency"); // either or |
614 assert(all_uninitialized != all_initialized, "consistency"); // either or |
607 |
615 |
608 __ sync(); // volatile entry point (one instruction before non-volatile_entry point) |
616 __ fence(); // volatile entry point (one instruction before non-volatile_entry point) |
609 if (branch_table[vtos] == 0) branch_table[vtos] = __ pc(); // non-volatile_entry point |
617 if (branch_table[vtos] == 0) branch_table[vtos] = __ pc(); // non-volatile_entry point |
610 if (branch_table[dtos] == 0) branch_table[dtos] = __ pc(); // non-volatile_entry point |
618 if (branch_table[dtos] == 0) branch_table[dtos] = __ pc(); // non-volatile_entry point |
611 if (branch_table[ftos] == 0) branch_table[ftos] = __ pc(); // non-volatile_entry point |
619 if (branch_table[ftos] == 0) branch_table[ftos] = __ pc(); // non-volatile_entry point |
612 __ stop("unexpected type", 0x6551); |
620 __ stop("unexpected type", 0x6551); |
613 #endif |
621 #endif |
614 |
622 |
615 if (branch_table[itos] == 0) { // generate only once |
623 if (branch_table[itos] == 0) { // generate only once |
616 __ align(32, 28, 28); // align load |
624 __ align(32, 28, 28); // align load |
617 __ sync(); // volatile entry point (one instruction before non-volatile_entry point) |
625 __ fence(); // volatile entry point (one instruction before non-volatile_entry point) |
618 branch_table[itos] = __ pc(); // non-volatile_entry point |
626 branch_table[itos] = __ pc(); // non-volatile_entry point |
619 __ lwax(R3_RET, Rclass_or_obj, Roffset); |
627 __ lwax(R3_RET, Rclass_or_obj, Roffset); |
620 __ beq(CCR6, Lacquire); |
628 __ beq(CCR6, Lacquire); |
621 __ blr(); |
629 __ blr(); |
622 } |
630 } |
623 |
631 |
624 if (branch_table[ltos] == 0) { // generate only once |
632 if (branch_table[ltos] == 0) { // generate only once |
625 __ align(32, 28, 28); // align load |
633 __ align(32, 28, 28); // align load |
626 __ sync(); // volatile entry point (one instruction before non-volatile_entry point) |
634 __ fence(); // volatile entry point (one instruction before non-volatile_entry point) |
627 branch_table[ltos] = __ pc(); // non-volatile_entry point |
635 branch_table[ltos] = __ pc(); // non-volatile_entry point |
628 __ ldx(R3_RET, Rclass_or_obj, Roffset); |
636 __ ldx(R3_RET, Rclass_or_obj, Roffset); |
629 __ beq(CCR6, Lacquire); |
637 __ beq(CCR6, Lacquire); |
630 __ blr(); |
638 __ blr(); |
631 } |
639 } |
632 |
640 |
633 if (branch_table[btos] == 0) { // generate only once |
641 if (branch_table[btos] == 0) { // generate only once |
634 __ align(32, 28, 28); // align load |
642 __ align(32, 28, 28); // align load |
635 __ sync(); // volatile entry point (one instruction before non-volatile_entry point) |
643 __ fence(); // volatile entry point (one instruction before non-volatile_entry point) |
636 branch_table[btos] = __ pc(); // non-volatile_entry point |
644 branch_table[btos] = __ pc(); // non-volatile_entry point |
637 __ lbzx(R3_RET, Rclass_or_obj, Roffset); |
645 __ lbzx(R3_RET, Rclass_or_obj, Roffset); |
638 __ extsb(R3_RET, R3_RET); |
646 __ extsb(R3_RET, R3_RET); |
639 __ beq(CCR6, Lacquire); |
647 __ beq(CCR6, Lacquire); |
640 __ blr(); |
648 __ blr(); |
641 } |
649 } |
642 |
650 |
643 if (branch_table[ctos] == 0) { // generate only once |
651 if (branch_table[ctos] == 0) { // generate only once |
644 __ align(32, 28, 28); // align load |
652 __ align(32, 28, 28); // align load |
645 __ sync(); // volatile entry point (one instruction before non-volatile_entry point) |
653 __ fence(); // volatile entry point (one instruction before non-volatile_entry point) |
646 branch_table[ctos] = __ pc(); // non-volatile_entry point |
654 branch_table[ctos] = __ pc(); // non-volatile_entry point |
647 __ lhzx(R3_RET, Rclass_or_obj, Roffset); |
655 __ lhzx(R3_RET, Rclass_or_obj, Roffset); |
648 __ beq(CCR6, Lacquire); |
656 __ beq(CCR6, Lacquire); |
649 __ blr(); |
657 __ blr(); |
650 } |
658 } |
651 |
659 |
652 if (branch_table[stos] == 0) { // generate only once |
660 if (branch_table[stos] == 0) { // generate only once |
653 __ align(32, 28, 28); // align load |
661 __ align(32, 28, 28); // align load |
654 __ sync(); // volatile entry point (one instruction before non-volatile_entry point) |
662 __ fence(); // volatile entry point (one instruction before non-volatile_entry point) |
655 branch_table[stos] = __ pc(); // non-volatile_entry point |
663 branch_table[stos] = __ pc(); // non-volatile_entry point |
656 __ lhax(R3_RET, Rclass_or_obj, Roffset); |
664 __ lhax(R3_RET, Rclass_or_obj, Roffset); |
657 __ beq(CCR6, Lacquire); |
665 __ beq(CCR6, Lacquire); |
658 __ blr(); |
666 __ blr(); |
659 } |
667 } |
660 |
668 |
661 if (branch_table[atos] == 0) { // generate only once |
669 if (branch_table[atos] == 0) { // generate only once |
662 __ align(32, 28, 28); // align load |
670 __ align(32, 28, 28); // align load |
663 __ sync(); // volatile entry point (one instruction before non-volatile_entry point) |
671 __ fence(); // volatile entry point (one instruction before non-volatile_entry point) |
664 branch_table[atos] = __ pc(); // non-volatile_entry point |
672 branch_table[atos] = __ pc(); // non-volatile_entry point |
665 __ load_heap_oop(R3_RET, (RegisterOrConstant)Roffset, Rclass_or_obj); |
673 __ load_heap_oop(R3_RET, (RegisterOrConstant)Roffset, Rclass_or_obj); |
666 __ verify_oop(R3_RET); |
674 __ verify_oop(R3_RET); |
667 //__ dcbt(R3_RET); // prefetch |
675 //__ dcbt(R3_RET); // prefetch |
668 __ beq(CCR6, Lacquire); |
676 __ beq(CCR6, Lacquire); |