1856 // in debug mode and the type isn't required when we know the exact type |
1856 // in debug mode and the type isn't required when we know the exact type |
1857 // also check that the type is an array type. |
1857 // also check that the type is an array type. |
1858 if (op->expected_type() == NULL) { |
1858 if (op->expected_type() == NULL) { |
1859 assert(src->is_nonvolatile() && src_pos->is_nonvolatile() && dst->is_nonvolatile() && dst_pos->is_nonvolatile() && |
1859 assert(src->is_nonvolatile() && src_pos->is_nonvolatile() && dst->is_nonvolatile() && dst_pos->is_nonvolatile() && |
1860 length->is_nonvolatile(), "must preserve"); |
1860 length->is_nonvolatile(), "must preserve"); |
|
1861 address copyfunc_addr = StubRoutines::generic_arraycopy(); |
|
1862 assert(copyfunc_addr != NULL, "generic arraycopy stub required"); |
|
1863 |
1861 // 3 parms are int. Convert to long. |
1864 // 3 parms are int. Convert to long. |
1862 __ mr(R3_ARG1, src); |
1865 __ mr(R3_ARG1, src); |
1863 __ extsw(R4_ARG2, src_pos); |
1866 __ extsw(R4_ARG2, src_pos); |
1864 __ mr(R5_ARG3, dst); |
1867 __ mr(R5_ARG3, dst); |
1865 __ extsw(R6_ARG4, dst_pos); |
1868 __ extsw(R6_ARG4, dst_pos); |
1866 __ extsw(R7_ARG5, length); |
1869 __ extsw(R7_ARG5, length); |
1867 address copyfunc_addr = StubRoutines::generic_arraycopy(); |
1870 |
1868 |
|
1869 if (copyfunc_addr == NULL) { // Use C version if stub was not generated. |
|
1870 address entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy); |
|
1871 __ call_c_with_frame_resize(entry, frame_resize); |
|
1872 } else { |
|
1873 #ifndef PRODUCT |
1871 #ifndef PRODUCT |
1874 if (PrintC1Statistics) { |
1872 if (PrintC1Statistics) { |
1875 address counter = (address)&Runtime1::_generic_arraycopystub_cnt; |
1873 address counter = (address)&Runtime1::_generic_arraycopystub_cnt; |
1876 int simm16_offs = __ load_const_optimized(tmp, counter, tmp2, true); |
1874 int simm16_offs = __ load_const_optimized(tmp, counter, tmp2, true); |
1877 __ lwz(R11_scratch1, simm16_offs, tmp); |
1875 __ lwz(R11_scratch1, simm16_offs, tmp); |
1878 __ addi(R11_scratch1, R11_scratch1, 1); |
1876 __ addi(R11_scratch1, R11_scratch1, 1); |
1879 __ stw(R11_scratch1, simm16_offs, tmp); |
1877 __ stw(R11_scratch1, simm16_offs, tmp); |
1880 } |
1878 } |
1881 #endif |
1879 #endif |
1882 __ call_c_with_frame_resize(copyfunc_addr, /*stub does not need resized frame*/ 0); |
1880 __ call_c_with_frame_resize(copyfunc_addr, /*stub does not need resized frame*/ 0); |
1883 |
1881 |
1884 __ nand(tmp, R3_RET, R3_RET); |
1882 __ nand(tmp, R3_RET, R3_RET); |
1885 __ subf(length, tmp, length); |
1883 __ subf(length, tmp, length); |
1886 __ add(src_pos, tmp, src_pos); |
1884 __ add(src_pos, tmp, src_pos); |
1887 __ add(dst_pos, tmp, dst_pos); |
1885 __ add(dst_pos, tmp, dst_pos); |
1888 } |
|
1889 |
1886 |
1890 __ cmpwi(CCR0, R3_RET, 0); |
1887 __ cmpwi(CCR0, R3_RET, 0); |
1891 __ bc_far_optimized(Assembler::bcondCRbiIs1, __ bi0(CCR0, Assembler::less), *stub->entry()); |
1888 __ bc_far_optimized(Assembler::bcondCRbiIs1, __ bi0(CCR0, Assembler::less), *stub->entry()); |
1892 __ bind(*stub->continuation()); |
1889 __ bind(*stub->continuation()); |
1893 return; |
1890 return; |