Mercurial > hg > graal-compiler
comparison src/cpu/ppc/vm/stubGenerator_ppc.cpp @ 14684:e5e8aa897002
8035647: PPC64: Support for elf v2 abi.
Summary: ELFv2 ABI used by the little endian PowerPC64 on Linux.
Reviewed-by: kvn
Contributed-by: asmundak@google.com
author | goetz |
---|---|
date | Thu, 06 Mar 2014 10:55:28 -0800 |
parents | 0c521b3f32dd |
children | 58cf34613a72 |
comparison
equal
deleted
inserted
replaced
14682:84eafecdb9a9 | 14684:e5e8aa897002 |
---|---|
77 // Setup a new c frame, copy java arguments, call frame manager or | 77 // Setup a new c frame, copy java arguments, call frame manager or |
78 // native_entry, and process result. | 78 // native_entry, and process result. |
79 | 79 |
80 StubCodeMark mark(this, "StubRoutines", "call_stub"); | 80 StubCodeMark mark(this, "StubRoutines", "call_stub"); |
81 | 81 |
82 address start = __ emit_fd(); | 82 address start = __ function_entry(); |
83 | 83 |
84 // some sanity checks | 84 // some sanity checks |
85 assert((sizeof(frame::abi_48) % 16) == 0, "unaligned"); | 85 assert((sizeof(frame::abi_minframe) % 16) == 0, "unaligned"); |
86 assert((sizeof(frame::abi_112) % 16) == 0, "unaligned"); | 86 assert((sizeof(frame::abi_reg_args) % 16) == 0, "unaligned"); |
87 assert((sizeof(frame::spill_nonvolatiles) % 16) == 0, "unaligned"); | 87 assert((sizeof(frame::spill_nonvolatiles) % 16) == 0, "unaligned"); |
88 assert((sizeof(frame::parent_ijava_frame_abi) % 16) == 0, "unaligned"); | 88 assert((sizeof(frame::parent_ijava_frame_abi) % 16) == 0, "unaligned"); |
89 assert((sizeof(frame::entry_frame_locals) % 16) == 0, "unaligned"); | 89 assert((sizeof(frame::entry_frame_locals) % 16) == 0, "unaligned"); |
90 | 90 |
91 Register r_arg_call_wrapper_addr = R3; | 91 Register r_arg_call_wrapper_addr = R3; |
442 } | 442 } |
443 #endif | 443 #endif |
444 | 444 |
445 // Save LR/CR and copy exception pc (LR) into R4_ARG2. | 445 // Save LR/CR and copy exception pc (LR) into R4_ARG2. |
446 __ save_LR_CR(R4_ARG2); | 446 __ save_LR_CR(R4_ARG2); |
447 __ push_frame_abi112(0, R0); | 447 __ push_frame_reg_args(0, R0); |
448 // Find exception handler. | 448 // Find exception handler. |
449 __ call_VM_leaf(CAST_FROM_FN_PTR(address, | 449 __ call_VM_leaf(CAST_FROM_FN_PTR(address, |
450 SharedRuntime::exception_handler_for_return_address), | 450 SharedRuntime::exception_handler_for_return_address), |
451 R16_thread, | 451 R16_thread, |
452 R4_ARG2); | 452 R4_ARG2); |
517 Register arg1 = noreg, Register arg2 = noreg) { | 517 Register arg1 = noreg, Register arg2 = noreg) { |
518 CodeBuffer code(name, 1024 DEBUG_ONLY(+ 512), 0); | 518 CodeBuffer code(name, 1024 DEBUG_ONLY(+ 512), 0); |
519 MacroAssembler* masm = new MacroAssembler(&code); | 519 MacroAssembler* masm = new MacroAssembler(&code); |
520 | 520 |
521 OopMapSet* oop_maps = new OopMapSet(); | 521 OopMapSet* oop_maps = new OopMapSet(); |
522 int frame_size_in_bytes = frame::abi_112_size; | 522 int frame_size_in_bytes = frame::abi_reg_args_size; |
523 OopMap* map = new OopMap(frame_size_in_bytes / sizeof(jint), 0); | 523 OopMap* map = new OopMap(frame_size_in_bytes / sizeof(jint), 0); |
524 | 524 |
525 StubCodeMark mark(this, "StubRoutines", "throw_exception"); | 525 StubCodeMark mark(this, "StubRoutines", "throw_exception"); |
526 | 526 |
527 address start = __ pc(); | 527 address start = __ pc(); |
528 | 528 |
529 __ save_LR_CR(R11_scratch1); | 529 __ save_LR_CR(R11_scratch1); |
530 | 530 |
531 // Push a frame. | 531 // Push a frame. |
532 __ push_frame_abi112(0, R11_scratch1); | 532 __ push_frame_reg_args(0, R11_scratch1); |
533 | 533 |
534 address frame_complete_pc = __ pc(); | 534 address frame_complete_pc = __ pc(); |
535 | 535 |
536 if (restore_saved_exception_pc) { | 536 if (restore_saved_exception_pc) { |
537 __ unimplemented("StubGenerator::throw_exception with restore_saved_exception_pc", 74); | 537 __ unimplemented("StubGenerator::throw_exception with restore_saved_exception_pc", 74); |
549 __ mr(R4_ARG2, arg1); | 549 __ mr(R4_ARG2, arg1); |
550 } | 550 } |
551 if (arg2 != noreg) { | 551 if (arg2 != noreg) { |
552 __ mr(R5_ARG3, arg2); | 552 __ mr(R5_ARG3, arg2); |
553 } | 553 } |
554 __ call_c(CAST_FROM_FN_PTR(FunctionDescriptor*, runtime_entry), | 554 #if defined(ABI_ELFv2) |
555 relocInfo::none); | 555 __ call_c(runtime_entry, relocInfo::none); |
556 #else | |
557 __ call_c(CAST_FROM_FN_PTR(FunctionDescriptor*, runtime_entry), relocInfo::none); | |
558 #endif | |
556 | 559 |
557 // Set an oopmap for the call site. | 560 // Set an oopmap for the call site. |
558 oop_maps->add_gc_map((int)(gc_map_pc - start), map); | 561 oop_maps->add_gc_map((int)(gc_map_pc - start), map); |
559 | 562 |
560 __ reset_last_Java_frame(); | 563 __ reset_last_Java_frame(); |
612 case BarrierSet::G1SATBCT: | 615 case BarrierSet::G1SATBCT: |
613 case BarrierSet::G1SATBCTLogging: | 616 case BarrierSet::G1SATBCTLogging: |
614 // With G1, don't generate the call if we statically know that the target in uninitialized | 617 // With G1, don't generate the call if we statically know that the target in uninitialized |
615 if (!dest_uninitialized) { | 618 if (!dest_uninitialized) { |
616 const int spill_slots = 4 * wordSize; | 619 const int spill_slots = 4 * wordSize; |
617 const int frame_size = frame::abi_112_size + spill_slots; | 620 const int frame_size = frame::abi_reg_args_size + spill_slots; |
618 Label filtered; | 621 Label filtered; |
619 | 622 |
620 // Is marking active? | 623 // Is marking active? |
621 if (in_bytes(PtrQueue::byte_width_of_active()) == 4) { | 624 if (in_bytes(PtrQueue::byte_width_of_active()) == 4) { |
622 __ lwz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active()), R16_thread); | 625 __ lwz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active()), R16_thread); |
626 } | 629 } |
627 __ cmpdi(CCR0, Rtmp1, 0); | 630 __ cmpdi(CCR0, Rtmp1, 0); |
628 __ beq(CCR0, filtered); | 631 __ beq(CCR0, filtered); |
629 | 632 |
630 __ save_LR_CR(R0); | 633 __ save_LR_CR(R0); |
631 __ push_frame_abi112(spill_slots, R0); | 634 __ push_frame_reg_args(spill_slots, R0); |
632 __ std(from, frame_size - 1 * wordSize, R1_SP); | 635 __ std(from, frame_size - 1 * wordSize, R1_SP); |
633 __ std(to, frame_size - 2 * wordSize, R1_SP); | 636 __ std(to, frame_size - 2 * wordSize, R1_SP); |
634 __ std(count, frame_size - 3 * wordSize, R1_SP); | 637 __ std(count, frame_size - 3 * wordSize, R1_SP); |
635 | 638 |
636 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), to, count); | 639 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), to, count); |
670 case BarrierSet::G1SATBCTLogging: | 673 case BarrierSet::G1SATBCTLogging: |
671 { | 674 { |
672 if (branchToEnd) { | 675 if (branchToEnd) { |
673 __ save_LR_CR(R0); | 676 __ save_LR_CR(R0); |
674 // We need this frame only to spill LR. | 677 // We need this frame only to spill LR. |
675 __ push_frame_abi112(0, R0); | 678 __ push_frame_reg_args(0, R0); |
676 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), addr, count); | 679 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), addr, count); |
677 __ pop_frame(); | 680 __ pop_frame(); |
678 __ restore_LR_CR(R0); | 681 __ restore_LR_CR(R0); |
679 } else { | 682 } else { |
680 // Tail call: fake call from stub caller by branching without linking. | 683 // Tail call: fake call from stub caller by branching without linking. |
740 // | 743 // |
741 address generate_zero_words_aligned8() { | 744 address generate_zero_words_aligned8() { |
742 StubCodeMark mark(this, "StubRoutines", "zero_words_aligned8"); | 745 StubCodeMark mark(this, "StubRoutines", "zero_words_aligned8"); |
743 | 746 |
744 // Implemented as in ClearArray. | 747 // Implemented as in ClearArray. |
745 address start = __ emit_fd(); | 748 address start = __ function_entry(); |
746 | 749 |
747 Register base_ptr_reg = R3_ARG1; // tohw (needs to be 8b aligned) | 750 Register base_ptr_reg = R3_ARG1; // tohw (needs to be 8b aligned) |
748 Register cnt_dwords_reg = R4_ARG2; // count (in dwords) | 751 Register cnt_dwords_reg = R4_ARG2; // count (in dwords) |
749 Register tmp1_reg = R5_ARG3; | 752 Register tmp1_reg = R5_ARG3; |
750 Register tmp2_reg = R6_ARG4; | 753 Register tmp2_reg = R6_ARG4; |
818 // UnknownError when an unsafe access gets a fault that could not be | 821 // UnknownError when an unsafe access gets a fault that could not be |
819 // reasonably prevented by the programmer. (Example: SIGBUS/OBJERR.) | 822 // reasonably prevented by the programmer. (Example: SIGBUS/OBJERR.) |
820 // | 823 // |
821 address generate_handler_for_unsafe_access() { | 824 address generate_handler_for_unsafe_access() { |
822 StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access"); | 825 StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access"); |
823 address start = __ emit_fd(); | 826 address start = __ function_entry(); |
824 __ unimplemented("StubRoutines::handler_for_unsafe_access", 93); | 827 __ unimplemented("StubRoutines::handler_for_unsafe_access", 93); |
825 return start; | 828 return start; |
826 } | 829 } |
827 | 830 |
828 #if !defined(PRODUCT) | 831 #if !defined(PRODUCT) |
859 // linux-ppc64 kernel before 2.6.6 doesn't set si_addr on some segfaults in 64bit mode | 862 // linux-ppc64 kernel before 2.6.6 doesn't set si_addr on some segfaults in 64bit mode |
860 // (cf. http://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.6), especially when we try | 863 // (cf. http://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.6), especially when we try |
861 // to read from the safepoint polling page. | 864 // to read from the safepoint polling page. |
862 address generate_load_from_poll() { | 865 address generate_load_from_poll() { |
863 StubCodeMark mark(this, "StubRoutines", "generate_load_from_poll"); | 866 StubCodeMark mark(this, "StubRoutines", "generate_load_from_poll"); |
864 address start = __ emit_fd(); | 867 address start = __ function_entry(); |
865 __ unimplemented("StubRoutines::verify_oop", 95); // TODO PPC port | 868 __ unimplemented("StubRoutines::verify_oop", 95); // TODO PPC port |
866 return start; | 869 return start; |
867 } | 870 } |
868 | 871 |
869 // -XX:+OptimizeFill : convert fill/copy loops into intrinsic | 872 // -XX:+OptimizeFill : convert fill/copy loops into intrinsic |
883 // value: R4_ARG2 | 886 // value: R4_ARG2 |
884 // count: R5_ARG3 treated as signed | 887 // count: R5_ARG3 treated as signed |
885 // | 888 // |
886 address generate_fill(BasicType t, bool aligned, const char* name) { | 889 address generate_fill(BasicType t, bool aligned, const char* name) { |
887 StubCodeMark mark(this, "StubRoutines", name); | 890 StubCodeMark mark(this, "StubRoutines", name); |
888 address start = __ emit_fd(); | 891 address start = __ function_entry(); |
889 | 892 |
890 const Register to = R3_ARG1; // source array address | 893 const Register to = R3_ARG1; // source array address |
891 const Register value = R4_ARG2; // fill value | 894 const Register value = R4_ARG2; // fill value |
892 const Register count = R5_ARG3; // elements count | 895 const Register count = R5_ARG3; // elements count |
893 const Register temp = R6_ARG4; // temp register | 896 const Register temp = R6_ARG4; // temp register |
1121 // to: R4_ARG2 | 1124 // to: R4_ARG2 |
1122 // count: R5_ARG3 treated as signed | 1125 // count: R5_ARG3 treated as signed |
1123 // | 1126 // |
1124 address generate_disjoint_byte_copy(bool aligned, const char * name) { | 1127 address generate_disjoint_byte_copy(bool aligned, const char * name) { |
1125 StubCodeMark mark(this, "StubRoutines", name); | 1128 StubCodeMark mark(this, "StubRoutines", name); |
1126 address start = __ emit_fd(); | 1129 address start = __ function_entry(); |
1127 | 1130 |
1128 Register tmp1 = R6_ARG4; | 1131 Register tmp1 = R6_ARG4; |
1129 Register tmp2 = R7_ARG5; | 1132 Register tmp2 = R7_ARG5; |
1130 Register tmp3 = R8_ARG6; | 1133 Register tmp3 = R8_ARG6; |
1131 Register tmp4 = R9_ARG7; | 1134 Register tmp4 = R9_ARG7; |
1252 // to: R4_ARG2 | 1255 // to: R4_ARG2 |
1253 // count: R5_ARG3 treated as signed | 1256 // count: R5_ARG3 treated as signed |
1254 // | 1257 // |
1255 address generate_conjoint_byte_copy(bool aligned, const char * name) { | 1258 address generate_conjoint_byte_copy(bool aligned, const char * name) { |
1256 StubCodeMark mark(this, "StubRoutines", name); | 1259 StubCodeMark mark(this, "StubRoutines", name); |
1257 address start = __ emit_fd(); | 1260 address start = __ function_entry(); |
1258 | 1261 |
1259 Register tmp1 = R6_ARG4; | 1262 Register tmp1 = R6_ARG4; |
1260 Register tmp2 = R7_ARG5; | 1263 Register tmp2 = R7_ARG5; |
1261 Register tmp3 = R8_ARG6; | 1264 Register tmp3 = R8_ARG6; |
1262 | 1265 |
1266 #if defined(ABI_ELFv2) | |
1267 address nooverlap_target = aligned ? | |
1268 StubRoutines::arrayof_jbyte_disjoint_arraycopy() : | |
1269 StubRoutines::jbyte_disjoint_arraycopy(); | |
1270 #else | |
1263 address nooverlap_target = aligned ? | 1271 address nooverlap_target = aligned ? |
1264 ((FunctionDescriptor*)StubRoutines::arrayof_jbyte_disjoint_arraycopy())->entry() : | 1272 ((FunctionDescriptor*)StubRoutines::arrayof_jbyte_disjoint_arraycopy())->entry() : |
1265 ((FunctionDescriptor*)StubRoutines::jbyte_disjoint_arraycopy())->entry(); | 1273 ((FunctionDescriptor*)StubRoutines::jbyte_disjoint_arraycopy())->entry(); |
1274 #endif | |
1266 | 1275 |
1267 array_overlap_test(nooverlap_target, 0); | 1276 array_overlap_test(nooverlap_target, 0); |
1268 // Do reverse copy. We assume the case of actual overlap is rare enough | 1277 // Do reverse copy. We assume the case of actual overlap is rare enough |
1269 // that we don't have to optimize it. | 1278 // that we don't have to optimize it. |
1270 Label l_1, l_2; | 1279 Label l_1, l_2; |
1343 Register tmp1 = R6_ARG4; | 1352 Register tmp1 = R6_ARG4; |
1344 Register tmp2 = R7_ARG5; | 1353 Register tmp2 = R7_ARG5; |
1345 Register tmp3 = R8_ARG6; | 1354 Register tmp3 = R8_ARG6; |
1346 Register tmp4 = R9_ARG7; | 1355 Register tmp4 = R9_ARG7; |
1347 | 1356 |
1348 address start = __ emit_fd(); | 1357 address start = __ function_entry(); |
1349 | 1358 |
1350 Label l_1, l_2, l_3, l_4, l_5, l_6, l_7, l_8; | 1359 Label l_1, l_2, l_3, l_4, l_5, l_6, l_7, l_8; |
1351 // don't try anything fancy if arrays don't have many elements | 1360 // don't try anything fancy if arrays don't have many elements |
1352 __ li(tmp3, 0); | 1361 __ li(tmp3, 0); |
1353 __ cmpwi(CCR0, R5_ARG3, 9); | 1362 __ cmpwi(CCR0, R5_ARG3, 9); |
1472 // to: R4_ARG2 | 1481 // to: R4_ARG2 |
1473 // count: R5_ARG3 treated as signed | 1482 // count: R5_ARG3 treated as signed |
1474 // | 1483 // |
1475 address generate_conjoint_short_copy(bool aligned, const char * name) { | 1484 address generate_conjoint_short_copy(bool aligned, const char * name) { |
1476 StubCodeMark mark(this, "StubRoutines", name); | 1485 StubCodeMark mark(this, "StubRoutines", name); |
1477 address start = __ emit_fd(); | 1486 address start = __ function_entry(); |
1478 | 1487 |
1479 Register tmp1 = R6_ARG4; | 1488 Register tmp1 = R6_ARG4; |
1480 Register tmp2 = R7_ARG5; | 1489 Register tmp2 = R7_ARG5; |
1481 Register tmp3 = R8_ARG6; | 1490 Register tmp3 = R8_ARG6; |
1482 | 1491 |
1492 #if defined(ABI_ELFv2) | |
1493 address nooverlap_target = aligned ? | |
1494 StubRoutines::arrayof_jshort_disjoint_arraycopy() : | |
1495 StubRoutines::jshort_disjoint_arraycopy(); | |
1496 #else | |
1483 address nooverlap_target = aligned ? | 1497 address nooverlap_target = aligned ? |
1484 ((FunctionDescriptor*)StubRoutines::arrayof_jshort_disjoint_arraycopy())->entry() : | 1498 ((FunctionDescriptor*)StubRoutines::arrayof_jshort_disjoint_arraycopy())->entry() : |
1485 ((FunctionDescriptor*)StubRoutines::jshort_disjoint_arraycopy())->entry(); | 1499 ((FunctionDescriptor*)StubRoutines::jshort_disjoint_arraycopy())->entry(); |
1500 #endif | |
1486 | 1501 |
1487 array_overlap_test(nooverlap_target, 1); | 1502 array_overlap_test(nooverlap_target, 1); |
1488 | 1503 |
1489 Label l_1, l_2; | 1504 Label l_1, l_2; |
1490 __ sldi(tmp1, R5_ARG3, 1); | 1505 __ sldi(tmp1, R5_ARG3, 1); |
1595 // to: R4_ARG2 | 1610 // to: R4_ARG2 |
1596 // count: R5_ARG3 treated as signed | 1611 // count: R5_ARG3 treated as signed |
1597 // | 1612 // |
1598 address generate_disjoint_int_copy(bool aligned, const char * name) { | 1613 address generate_disjoint_int_copy(bool aligned, const char * name) { |
1599 StubCodeMark mark(this, "StubRoutines", name); | 1614 StubCodeMark mark(this, "StubRoutines", name); |
1600 address start = __ emit_fd(); | 1615 address start = __ function_entry(); |
1601 generate_disjoint_int_copy_core(aligned); | 1616 generate_disjoint_int_copy_core(aligned); |
1602 __ blr(); | 1617 __ blr(); |
1603 return start; | 1618 return start; |
1604 } | 1619 } |
1605 | 1620 |
1679 // to: R4_ARG2 | 1694 // to: R4_ARG2 |
1680 // count: R5_ARG3 treated as signed | 1695 // count: R5_ARG3 treated as signed |
1681 // | 1696 // |
1682 address generate_conjoint_int_copy(bool aligned, const char * name) { | 1697 address generate_conjoint_int_copy(bool aligned, const char * name) { |
1683 StubCodeMark mark(this, "StubRoutines", name); | 1698 StubCodeMark mark(this, "StubRoutines", name); |
1684 address start = __ emit_fd(); | 1699 address start = __ function_entry(); |
1685 | 1700 |
1701 #if defined(ABI_ELFv2) | |
1702 address nooverlap_target = aligned ? | |
1703 StubRoutines::arrayof_jint_disjoint_arraycopy() : | |
1704 StubRoutines::jint_disjoint_arraycopy(); | |
1705 #else | |
1686 address nooverlap_target = aligned ? | 1706 address nooverlap_target = aligned ? |
1687 ((FunctionDescriptor*)StubRoutines::arrayof_jint_disjoint_arraycopy())->entry() : | 1707 ((FunctionDescriptor*)StubRoutines::arrayof_jint_disjoint_arraycopy())->entry() : |
1688 ((FunctionDescriptor*)StubRoutines::jint_disjoint_arraycopy())->entry(); | 1708 ((FunctionDescriptor*)StubRoutines::jint_disjoint_arraycopy())->entry(); |
1709 #endif | |
1689 | 1710 |
1690 array_overlap_test(nooverlap_target, 2); | 1711 array_overlap_test(nooverlap_target, 2); |
1691 | 1712 |
1692 generate_conjoint_int_copy_core(aligned); | 1713 generate_conjoint_int_copy_core(aligned); |
1693 | 1714 |
1765 // to: R4_ARG2 | 1786 // to: R4_ARG2 |
1766 // count: R5_ARG3 treated as signed | 1787 // count: R5_ARG3 treated as signed |
1767 // | 1788 // |
1768 address generate_disjoint_long_copy(bool aligned, const char * name) { | 1789 address generate_disjoint_long_copy(bool aligned, const char * name) { |
1769 StubCodeMark mark(this, "StubRoutines", name); | 1790 StubCodeMark mark(this, "StubRoutines", name); |
1770 address start = __ emit_fd(); | 1791 address start = __ function_entry(); |
1771 generate_disjoint_long_copy_core(aligned); | 1792 generate_disjoint_long_copy_core(aligned); |
1772 __ blr(); | 1793 __ blr(); |
1773 | 1794 |
1774 return start; | 1795 return start; |
1775 } | 1796 } |
1847 // to: R4_ARG2 | 1868 // to: R4_ARG2 |
1848 // count: R5_ARG3 treated as signed | 1869 // count: R5_ARG3 treated as signed |
1849 // | 1870 // |
1850 address generate_conjoint_long_copy(bool aligned, const char * name) { | 1871 address generate_conjoint_long_copy(bool aligned, const char * name) { |
1851 StubCodeMark mark(this, "StubRoutines", name); | 1872 StubCodeMark mark(this, "StubRoutines", name); |
1852 address start = __ emit_fd(); | 1873 address start = __ function_entry(); |
1853 | 1874 |
1875 #if defined(ABI_ELFv2) | |
1876 address nooverlap_target = aligned ? | |
1877 StubRoutines::arrayof_jlong_disjoint_arraycopy() : | |
1878 StubRoutines::jlong_disjoint_arraycopy(); | |
1879 #else | |
1854 address nooverlap_target = aligned ? | 1880 address nooverlap_target = aligned ? |
1855 ((FunctionDescriptor*)StubRoutines::arrayof_jlong_disjoint_arraycopy())->entry() : | 1881 ((FunctionDescriptor*)StubRoutines::arrayof_jlong_disjoint_arraycopy())->entry() : |
1856 ((FunctionDescriptor*)StubRoutines::jlong_disjoint_arraycopy())->entry(); | 1882 ((FunctionDescriptor*)StubRoutines::jlong_disjoint_arraycopy())->entry(); |
1883 #endif | |
1857 | 1884 |
1858 array_overlap_test(nooverlap_target, 3); | 1885 array_overlap_test(nooverlap_target, 3); |
1859 generate_conjoint_long_copy_core(aligned); | 1886 generate_conjoint_long_copy_core(aligned); |
1860 | 1887 |
1861 __ blr(); | 1888 __ blr(); |
1873 // dest_uninitialized: G1 support | 1900 // dest_uninitialized: G1 support |
1874 // | 1901 // |
1875 address generate_conjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) { | 1902 address generate_conjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) { |
1876 StubCodeMark mark(this, "StubRoutines", name); | 1903 StubCodeMark mark(this, "StubRoutines", name); |
1877 | 1904 |
1878 address start = __ emit_fd(); | 1905 address start = __ function_entry(); |
1879 | 1906 |
1907 #if defined(ABI_ELFv2) | |
1908 address nooverlap_target = aligned ? | |
1909 StubRoutines::arrayof_oop_disjoint_arraycopy() : | |
1910 StubRoutines::oop_disjoint_arraycopy(); | |
1911 #else | |
1880 address nooverlap_target = aligned ? | 1912 address nooverlap_target = aligned ? |
1881 ((FunctionDescriptor*)StubRoutines::arrayof_oop_disjoint_arraycopy())->entry() : | 1913 ((FunctionDescriptor*)StubRoutines::arrayof_oop_disjoint_arraycopy())->entry() : |
1882 ((FunctionDescriptor*)StubRoutines::oop_disjoint_arraycopy())->entry(); | 1914 ((FunctionDescriptor*)StubRoutines::oop_disjoint_arraycopy())->entry(); |
1915 #endif | |
1883 | 1916 |
1884 gen_write_ref_array_pre_barrier(R3_ARG1, R4_ARG2, R5_ARG3, dest_uninitialized, R9_ARG7); | 1917 gen_write_ref_array_pre_barrier(R3_ARG1, R4_ARG2, R5_ARG3, dest_uninitialized, R9_ARG7); |
1885 | 1918 |
1886 // Save arguments. | 1919 // Save arguments. |
1887 __ mr(R9_ARG7, R4_ARG2); | 1920 __ mr(R9_ARG7, R4_ARG2); |
1908 // count: R5_ARG3 treated as signed | 1941 // count: R5_ARG3 treated as signed |
1909 // dest_uninitialized: G1 support | 1942 // dest_uninitialized: G1 support |
1910 // | 1943 // |
1911 address generate_disjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) { | 1944 address generate_disjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) { |
1912 StubCodeMark mark(this, "StubRoutines", name); | 1945 StubCodeMark mark(this, "StubRoutines", name); |
1913 address start = __ emit_fd(); | 1946 address start = __ function_entry(); |
1914 | 1947 |
1915 gen_write_ref_array_pre_barrier(R3_ARG1, R4_ARG2, R5_ARG3, dest_uninitialized, R9_ARG7); | 1948 gen_write_ref_array_pre_barrier(R3_ARG1, R4_ARG2, R5_ARG3, dest_uninitialized, R9_ARG7); |
1916 | 1949 |
1917 // save some arguments, disjoint_long_copy_core destroys them. | 1950 // save some arguments, disjoint_long_copy_core destroys them. |
1918 // needed for post barrier | 1951 // needed for post barrier |
1989 // R3_RET = *adr or errValue | 2022 // R3_RET = *adr or errValue |
1990 | 2023 |
1991 StubCodeMark mark(this, "StubRoutines", name); | 2024 StubCodeMark mark(this, "StubRoutines", name); |
1992 | 2025 |
1993 // Entry point, pc or function descriptor. | 2026 // Entry point, pc or function descriptor. |
1994 *entry = __ emit_fd(); | 2027 *entry = __ function_entry(); |
1995 | 2028 |
1996 // Load *adr into R4_ARG2, may fault. | 2029 // Load *adr into R4_ARG2, may fault. |
1997 *fault_pc = __ pc(); | 2030 *fault_pc = __ pc(); |
1998 switch (size) { | 2031 switch (size) { |
1999 case 4: | 2032 case 4: |