hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp
changeset 35232 76aed99c0ddd
parent 35166 23125410af16
parent 35156 a06b3d7455d6
child 35546 b75e269c0922
equal deleted inserted replaced
35231:e89989198037 35232:76aed99c0ddd
    46 #define BLOCK_COMMENT(str) // nothing
    46 #define BLOCK_COMMENT(str) // nothing
    47 #else
    47 #else
    48 #define BLOCK_COMMENT(str) __ block_comment(str)
    48 #define BLOCK_COMMENT(str) __ block_comment(str)
    49 #endif
    49 #endif
    50 
    50 
       
    51 #if defined(ABI_ELFv2)
       
    52 #define STUB_ENTRY(name) StubRoutines::name()
       
    53 #else
       
    54 #define STUB_ENTRY(name) ((FunctionDescriptor*)StubRoutines::name())->entry()
       
    55 #endif
       
    56 
    51 class StubGenerator: public StubCodeGenerator {
    57 class StubGenerator: public StubCodeGenerator {
    52  private:
    58  private:
    53 
    59 
    54   // Call stubs are used to call Java from C
    60   // Call stubs are used to call Java from C
    55   //
    61   //
   250       //      F1      [C_FRAME]
   256       //      F1      [C_FRAME]
   251       //              ...
   257       //              ...
   252       //
   258       //
   253 
   259 
   254       // global toc register
   260       // global toc register
   255       __ load_const(R29, MacroAssembler::global_toc(), R11_scratch1);
   261       __ load_const_optimized(R29_TOC, MacroAssembler::global_toc(), R11_scratch1);
   256 
       
   257       // Remember the senderSP so we interpreter can pop c2i arguments off of the stack
   262       // Remember the senderSP so we interpreter can pop c2i arguments off of the stack
   258       // when called via a c2i.
   263       // when called via a c2i.
   259 
   264 
   260       // Pass initial_caller_sp to framemanager.
   265       // Pass initial_caller_sp to framemanager.
   261       __ mr(R21_tmp1, R1_SP);
   266       __ mr(R21_tmp1, R1_SP);
   610   //     tmp      - scratch register
   615   //     tmp      - scratch register
   611   //
   616   //
   612   //  Kills:
   617   //  Kills:
   613   //     nothing
   618   //     nothing
   614   //
   619   //
   615   void gen_write_ref_array_pre_barrier(Register from, Register to, Register count, bool dest_uninitialized, Register Rtmp1) {
   620   void gen_write_ref_array_pre_barrier(Register from, Register to, Register count, bool dest_uninitialized, Register Rtmp1,
       
   621                                        Register preserve1 = noreg, Register preserve2 = noreg) {
   616     BarrierSet* const bs = Universe::heap()->barrier_set();
   622     BarrierSet* const bs = Universe::heap()->barrier_set();
   617     switch (bs->kind()) {
   623     switch (bs->kind()) {
   618       case BarrierSet::G1SATBCTLogging:
   624       case BarrierSet::G1SATBCTLogging:
   619         // With G1, don't generate the call if we statically know that the target in uninitialized
   625         // With G1, don't generate the call if we statically know that the target in uninitialized
   620         if (!dest_uninitialized) {
   626         if (!dest_uninitialized) {
   621           const int spill_slots = 4 * wordSize;
   627           int spill_slots = 3;
   622           const int frame_size  = frame::abi_reg_args_size + spill_slots;
   628           if (preserve1 != noreg) { spill_slots++; }
       
   629           if (preserve2 != noreg) { spill_slots++; }
       
   630           const int frame_size = align_size_up(frame::abi_reg_args_size + spill_slots * BytesPerWord, frame::alignment_in_bytes);
   623           Label filtered;
   631           Label filtered;
   624 
   632 
   625           // Is marking active?
   633           // Is marking active?
   626           if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
   634           if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
   627             __ lwz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread);
   635             __ lwz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread);
   631           }
   639           }
   632           __ cmpdi(CCR0, Rtmp1, 0);
   640           __ cmpdi(CCR0, Rtmp1, 0);
   633           __ beq(CCR0, filtered);
   641           __ beq(CCR0, filtered);
   634 
   642 
   635           __ save_LR_CR(R0);
   643           __ save_LR_CR(R0);
   636           __ push_frame_reg_args(spill_slots, R0);
   644           __ push_frame(frame_size, R0);
   637           __ std(from,  frame_size - 1 * wordSize, R1_SP);
   645           int slot_nr = 0;
   638           __ std(to,    frame_size - 2 * wordSize, R1_SP);
   646           __ std(from,  frame_size - (++slot_nr) * wordSize, R1_SP);
   639           __ std(count, frame_size - 3 * wordSize, R1_SP);
   647           __ std(to,    frame_size - (++slot_nr) * wordSize, R1_SP);
       
   648           __ std(count, frame_size - (++slot_nr) * wordSize, R1_SP);
       
   649           if (preserve1 != noreg) { __ std(preserve1, frame_size - (++slot_nr) * wordSize, R1_SP); }
       
   650           if (preserve2 != noreg) { __ std(preserve2, frame_size - (++slot_nr) * wordSize, R1_SP); }
   640 
   651 
   641           __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), to, count);
   652           __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), to, count);
   642 
   653 
   643           __ ld(from,  frame_size - 1 * wordSize, R1_SP);
   654           slot_nr = 0;
   644           __ ld(to,    frame_size - 2 * wordSize, R1_SP);
   655           __ ld(from,  frame_size - (++slot_nr) * wordSize, R1_SP);
   645           __ ld(count, frame_size - 3 * wordSize, R1_SP);
   656           __ ld(to,    frame_size - (++slot_nr) * wordSize, R1_SP);
   646           __ pop_frame();
   657           __ ld(count, frame_size - (++slot_nr) * wordSize, R1_SP);
       
   658           if (preserve1 != noreg) { __ ld(preserve1, frame_size - (++slot_nr) * wordSize, R1_SP); }
       
   659           if (preserve2 != noreg) { __ ld(preserve2, frame_size - (++slot_nr) * wordSize, R1_SP); }
       
   660           __ addi(R1_SP, R1_SP, frame_size); // pop_frame()
   647           __ restore_LR_CR(R0);
   661           __ restore_LR_CR(R0);
   648 
   662 
   649           __ bind(filtered);
   663           __ bind(filtered);
   650         }
   664         }
   651         break;
   665         break;
   665   //     count    - register containing element count
   679   //     count    - register containing element count
   666   //     tmp      - scratch register
   680   //     tmp      - scratch register
   667   //
   681   //
   668   //  The input registers and R0 are overwritten.
   682   //  The input registers and R0 are overwritten.
   669   //
   683   //
   670   void gen_write_ref_array_post_barrier(Register addr, Register count, Register tmp, bool branchToEnd) {
   684   void gen_write_ref_array_post_barrier(Register addr, Register count, Register tmp, Register preserve = noreg) {
   671     BarrierSet* const bs = Universe::heap()->barrier_set();
   685     BarrierSet* const bs = Universe::heap()->barrier_set();
   672 
   686 
   673     switch (bs->kind()) {
   687     switch (bs->kind()) {
   674       case BarrierSet::G1SATBCTLogging:
   688       case BarrierSet::G1SATBCTLogging:
   675         {
   689         {
   676           if (branchToEnd) {
   690           int spill_slots = (preserve != noreg) ? 1 : 0;
   677             __ save_LR_CR(R0);
   691           const int frame_size = align_size_up(frame::abi_reg_args_size + spill_slots * BytesPerWord, frame::alignment_in_bytes);
   678             // We need this frame only to spill LR.
   692 
   679             __ push_frame_reg_args(0, R0);
   693           __ save_LR_CR(R0);
   680             __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), addr, count);
   694           __ push_frame(frame_size, R0);
   681             __ pop_frame();
   695           if (preserve != noreg) { __ std(preserve, frame_size - 1 * wordSize, R1_SP); }
   682             __ restore_LR_CR(R0);
   696           __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), addr, count);
   683           } else {
   697           if (preserve != noreg) { __ ld(preserve, frame_size - 1 * wordSize, R1_SP); }
   684             // Tail call: fake call from stub caller by branching without linking.
   698           __ addi(R1_SP, R1_SP, frame_size); // pop_frame();
   685             address entry_point = (address)CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post);
   699           __ restore_LR_CR(R0);
   686             __ mr_if_needed(R3_ARG1, addr);
       
   687             __ mr_if_needed(R4_ARG2, count);
       
   688             __ load_const(R11, entry_point, R0);
       
   689             __ call_c_and_return_to_caller(R11);
       
   690           }
       
   691         }
   700         }
   692         break;
   701         break;
   693       case BarrierSet::CardTableForRS:
   702       case BarrierSet::CardTableForRS:
   694       case BarrierSet::CardTableExtension:
   703       case BarrierSet::CardTableExtension:
   695         {
   704         {
   720           __ bind(Lstore_loop);
   729           __ bind(Lstore_loop);
   721           __ stbx(R0, tmp, addr);
   730           __ stbx(R0, tmp, addr);
   722           __ addi(addr, addr, 1);
   731           __ addi(addr, addr, 1);
   723           __ bdnz(Lstore_loop);
   732           __ bdnz(Lstore_loop);
   724           __ bind(Lskip_loop);
   733           __ bind(Lskip_loop);
   725 
       
   726           if (!branchToEnd) __ blr();
       
   727         }
   734         }
   728       break;
   735       break;
   729       case BarrierSet::ModRef:
   736       case BarrierSet::ModRef:
   730         if (!branchToEnd) __ blr();
       
   731         break;
   737         break;
   732       default:
   738       default:
   733         ShouldNotReachHere();
   739         ShouldNotReachHere();
   734     }
   740     }
   735   }
   741   }
   754     Register tmp2_reg       = R6_ARG4;
   760     Register tmp2_reg       = R6_ARG4;
   755     Register zero_reg       = R7_ARG5;
   761     Register zero_reg       = R7_ARG5;
   756 
   762 
   757     // Procedure for large arrays (uses data cache block zero instruction).
   763     // Procedure for large arrays (uses data cache block zero instruction).
   758     Label dwloop, fast, fastloop, restloop, lastdword, done;
   764     Label dwloop, fast, fastloop, restloop, lastdword, done;
   759     int cl_size=VM_Version::get_cache_line_size(), cl_dwords=cl_size>>3, cl_dwordaddr_bits=exact_log2(cl_dwords);
   765     int cl_size = VM_Version::L1_data_cache_line_size();
   760     int min_dcbz=2; // Needs to be positive, apply dcbz only to at least min_dcbz cache lines.
   766     int cl_dwords = cl_size >> 3;
       
   767     int cl_dwordaddr_bits = exact_log2(cl_dwords);
       
   768     int min_dcbz = 2; // Needs to be positive, apply dcbz only to at least min_dcbz cache lines.
   761 
   769 
   762     // Clear up to 128byte boundary if long enough, dword_cnt=(16-(base>>3))%16.
   770     // Clear up to 128byte boundary if long enough, dword_cnt=(16-(base>>3))%16.
   763     __ dcbtst(base_ptr_reg);                    // Indicate write access to first cache line ...
   771     __ dcbtst(base_ptr_reg);                    // Indicate write access to first cache line ...
   764     __ andi(tmp2_reg, cnt_dwords_reg, 1);       // to check if number of dwords is even.
   772     __ andi(tmp2_reg, cnt_dwords_reg, 1);       // to check if number of dwords is even.
   765     __ srdi_(tmp1_reg, cnt_dwords_reg, 1);      // number of double dwords
   773     __ srdi_(tmp1_reg, cnt_dwords_reg, 1);      // number of double dwords
  1072   //
  1080   //
  1073   void array_overlap_test(address no_overlap_target, int log2_elem_size) {
  1081   void array_overlap_test(address no_overlap_target, int log2_elem_size) {
  1074     Register tmp1 = R6_ARG4;
  1082     Register tmp1 = R6_ARG4;
  1075     Register tmp2 = R7_ARG5;
  1083     Register tmp2 = R7_ARG5;
  1076 
  1084 
  1077     Label l_overlap;
       
  1078 #ifdef ASSERT
  1085 #ifdef ASSERT
  1079     __ srdi_(tmp2, R5_ARG3, 31);
  1086     __ srdi_(tmp2, R5_ARG3, 31);
  1080     __ asm_assert_eq("missing zero extend", 0xAFFE);
  1087     __ asm_assert_eq("missing zero extend", 0xAFFE);
  1081 #endif
  1088 #endif
  1082 
  1089 
  1083     __ subf(tmp1, R3_ARG1, R4_ARG2); // distance in bytes
  1090     __ subf(tmp1, R3_ARG1, R4_ARG2); // distance in bytes
  1084     __ sldi(tmp2, R5_ARG3, log2_elem_size); // size in bytes
  1091     __ sldi(tmp2, R5_ARG3, log2_elem_size); // size in bytes
  1085     __ cmpld(CCR0, R3_ARG1, R4_ARG2); // Use unsigned comparison!
  1092     __ cmpld(CCR0, R3_ARG1, R4_ARG2); // Use unsigned comparison!
  1086     __ cmpld(CCR1, tmp1, tmp2);
  1093     __ cmpld(CCR1, tmp1, tmp2);
  1087     __ crand(CCR0, Assembler::less, CCR1, Assembler::less);
  1094     __ crnand(CCR0, Assembler::less, CCR1, Assembler::less);
  1088     __ blt(CCR0, l_overlap); // Src before dst and distance smaller than size.
  1095     // Overlaps if Src before dst and distance smaller than size.
  1089 
  1096     // Branch to forward copy routine otherwise (within range of 32kB).
  1090     // need to copy forwards
  1097     __ bc(Assembler::bcondCRbiIs1, Assembler::bi0(CCR0, Assembler::less), no_overlap_target);
  1091     if (__ is_within_range_of_b(no_overlap_target, __ pc())) {
  1098 
  1092       __ b(no_overlap_target);
       
  1093     } else {
       
  1094       __ load_const(tmp1, no_overlap_target, tmp2);
       
  1095       __ mtctr(tmp1);
       
  1096       __ bctr();
       
  1097     }
       
  1098 
       
  1099     __ bind(l_overlap);
       
  1100     // need to copy backwards
  1099     // need to copy backwards
  1101   }
  1100   }
  1102 
  1101 
  1103   // The guideline in the implementations of generate_disjoint_xxx_copy
  1102   // The guideline in the implementations of generate_disjoint_xxx_copy
  1104   // (xxx=byte,short,int,long,oop) is to copy as many elements as possible with
  1103   // (xxx=byte,short,int,long,oop) is to copy as many elements as possible with
  1239       __ stbu(tmp2, 1, R4_ARG2);
  1238       __ stbu(tmp2, 1, R4_ARG2);
  1240       __ bdnz(l_5);
  1239       __ bdnz(l_5);
  1241     }
  1240     }
  1242 
  1241 
  1243     __ bind(l_4);
  1242     __ bind(l_4);
       
  1243     __ li(R3_RET, 0); // return 0
  1244     __ blr();
  1244     __ blr();
  1245 
  1245 
  1246     return start;
  1246     return start;
  1247   }
  1247   }
  1248 
  1248 
  1260 
  1260 
  1261     Register tmp1 = R6_ARG4;
  1261     Register tmp1 = R6_ARG4;
  1262     Register tmp2 = R7_ARG5;
  1262     Register tmp2 = R7_ARG5;
  1263     Register tmp3 = R8_ARG6;
  1263     Register tmp3 = R8_ARG6;
  1264 
  1264 
  1265 #if defined(ABI_ELFv2)
       
  1266     address nooverlap_target = aligned ?
  1265     address nooverlap_target = aligned ?
  1267       StubRoutines::arrayof_jbyte_disjoint_arraycopy() :
  1266       STUB_ENTRY(arrayof_jbyte_disjoint_arraycopy) :
  1268       StubRoutines::jbyte_disjoint_arraycopy();
  1267       STUB_ENTRY(jbyte_disjoint_arraycopy);
  1269 #else
       
  1270     address nooverlap_target = aligned ?
       
  1271       ((FunctionDescriptor*)StubRoutines::arrayof_jbyte_disjoint_arraycopy())->entry() :
       
  1272       ((FunctionDescriptor*)StubRoutines::jbyte_disjoint_arraycopy())->entry();
       
  1273 #endif
       
  1274 
  1268 
  1275     array_overlap_test(nooverlap_target, 0);
  1269     array_overlap_test(nooverlap_target, 0);
  1276     // Do reverse copy. We assume the case of actual overlap is rare enough
  1270     // Do reverse copy. We assume the case of actual overlap is rare enough
  1277     // that we don't have to optimize it.
  1271     // that we don't have to optimize it.
  1278     Label l_1, l_2;
  1272     Label l_1, l_2;
  1283     __ bind(l_2);
  1277     __ bind(l_2);
  1284     __ addic_(R5_ARG3, R5_ARG3, -1);
  1278     __ addic_(R5_ARG3, R5_ARG3, -1);
  1285     __ lbzx(tmp1, R3_ARG1, R5_ARG3);
  1279     __ lbzx(tmp1, R3_ARG1, R5_ARG3);
  1286     __ bge(CCR0, l_1);
  1280     __ bge(CCR0, l_1);
  1287 
  1281 
       
  1282     __ li(R3_RET, 0); // return 0
  1288     __ blr();
  1283     __ blr();
  1289 
  1284 
  1290     return start;
  1285     return start;
  1291   }
  1286   }
  1292 
  1287 
  1465       __ lhzu(tmp2, 2, R3_ARG1);
  1460       __ lhzu(tmp2, 2, R3_ARG1);
  1466       __ sthu(tmp2, 2, R4_ARG2);
  1461       __ sthu(tmp2, 2, R4_ARG2);
  1467       __ bdnz(l_5);
  1462       __ bdnz(l_5);
  1468     }
  1463     }
  1469     __ bind(l_4);
  1464     __ bind(l_4);
       
  1465     __ li(R3_RET, 0); // return 0
  1470     __ blr();
  1466     __ blr();
  1471 
  1467 
  1472     return start;
  1468     return start;
  1473   }
  1469   }
  1474 
  1470 
  1486 
  1482 
  1487     Register tmp1 = R6_ARG4;
  1483     Register tmp1 = R6_ARG4;
  1488     Register tmp2 = R7_ARG5;
  1484     Register tmp2 = R7_ARG5;
  1489     Register tmp3 = R8_ARG6;
  1485     Register tmp3 = R8_ARG6;
  1490 
  1486 
  1491 #if defined(ABI_ELFv2)
       
  1492     address nooverlap_target = aligned ?
  1487     address nooverlap_target = aligned ?
  1493         StubRoutines::arrayof_jshort_disjoint_arraycopy() :
  1488       STUB_ENTRY(arrayof_jshort_disjoint_arraycopy) :
  1494         StubRoutines::jshort_disjoint_arraycopy();
  1489       STUB_ENTRY(jshort_disjoint_arraycopy);
  1495 #else
       
  1496     address nooverlap_target = aligned ?
       
  1497         ((FunctionDescriptor*)StubRoutines::arrayof_jshort_disjoint_arraycopy())->entry() :
       
  1498         ((FunctionDescriptor*)StubRoutines::jshort_disjoint_arraycopy())->entry();
       
  1499 #endif
       
  1500 
  1490 
  1501     array_overlap_test(nooverlap_target, 1);
  1491     array_overlap_test(nooverlap_target, 1);
  1502 
  1492 
  1503     Label l_1, l_2;
  1493     Label l_1, l_2;
  1504     __ sldi(tmp1, R5_ARG3, 1);
  1494     __ sldi(tmp1, R5_ARG3, 1);
  1508     __ bind(l_2);
  1498     __ bind(l_2);
  1509     __ addic_(tmp1, tmp1, -2);
  1499     __ addic_(tmp1, tmp1, -2);
  1510     __ lhzx(tmp2, R3_ARG1, tmp1);
  1500     __ lhzx(tmp2, R3_ARG1, tmp1);
  1511     __ bge(CCR0, l_1);
  1501     __ bge(CCR0, l_1);
  1512 
  1502 
       
  1503     __ li(R3_RET, 0); // return 0
  1513     __ blr();
  1504     __ blr();
  1514 
  1505 
  1515     return start;
  1506     return start;
  1516   }
  1507   }
  1517 
  1508 
  1611   //
  1602   //
  1612   address generate_disjoint_int_copy(bool aligned, const char * name) {
  1603   address generate_disjoint_int_copy(bool aligned, const char * name) {
  1613     StubCodeMark mark(this, "StubRoutines", name);
  1604     StubCodeMark mark(this, "StubRoutines", name);
  1614     address start = __ function_entry();
  1605     address start = __ function_entry();
  1615     generate_disjoint_int_copy_core(aligned);
  1606     generate_disjoint_int_copy_core(aligned);
       
  1607     __ li(R3_RET, 0); // return 0
  1616     __ blr();
  1608     __ blr();
  1617     return start;
  1609     return start;
  1618   }
  1610   }
  1619 
  1611 
  1620   // Generate core code for conjoint int copy (and oop copy on
  1612   // Generate core code for conjoint int copy (and oop copy on
  1695   //
  1687   //
  1696   address generate_conjoint_int_copy(bool aligned, const char * name) {
  1688   address generate_conjoint_int_copy(bool aligned, const char * name) {
  1697     StubCodeMark mark(this, "StubRoutines", name);
  1689     StubCodeMark mark(this, "StubRoutines", name);
  1698     address start = __ function_entry();
  1690     address start = __ function_entry();
  1699 
  1691 
  1700 #if defined(ABI_ELFv2)
       
  1701     address nooverlap_target = aligned ?
  1692     address nooverlap_target = aligned ?
  1702       StubRoutines::arrayof_jint_disjoint_arraycopy() :
  1693       STUB_ENTRY(arrayof_jint_disjoint_arraycopy) :
  1703       StubRoutines::jint_disjoint_arraycopy();
  1694       STUB_ENTRY(jint_disjoint_arraycopy);
  1704 #else
       
  1705     address nooverlap_target = aligned ?
       
  1706       ((FunctionDescriptor*)StubRoutines::arrayof_jint_disjoint_arraycopy())->entry() :
       
  1707       ((FunctionDescriptor*)StubRoutines::jint_disjoint_arraycopy())->entry();
       
  1708 #endif
       
  1709 
  1695 
  1710     array_overlap_test(nooverlap_target, 2);
  1696     array_overlap_test(nooverlap_target, 2);
  1711 
  1697 
  1712     generate_conjoint_int_copy_core(aligned);
  1698     generate_conjoint_int_copy_core(aligned);
  1713 
  1699 
       
  1700     __ li(R3_RET, 0); // return 0
  1714     __ blr();
  1701     __ blr();
  1715 
  1702 
  1716     return start;
  1703     return start;
  1717   }
  1704   }
  1718 
  1705 
  1787   //
  1774   //
  1788   address generate_disjoint_long_copy(bool aligned, const char * name) {
  1775   address generate_disjoint_long_copy(bool aligned, const char * name) {
  1789     StubCodeMark mark(this, "StubRoutines", name);
  1776     StubCodeMark mark(this, "StubRoutines", name);
  1790     address start = __ function_entry();
  1777     address start = __ function_entry();
  1791     generate_disjoint_long_copy_core(aligned);
  1778     generate_disjoint_long_copy_core(aligned);
       
  1779     __ li(R3_RET, 0); // return 0
  1792     __ blr();
  1780     __ blr();
  1793 
  1781 
  1794     return start;
  1782     return start;
  1795   }
  1783   }
  1796 
  1784 
  1869   //
  1857   //
  1870   address generate_conjoint_long_copy(bool aligned, const char * name) {
  1858   address generate_conjoint_long_copy(bool aligned, const char * name) {
  1871     StubCodeMark mark(this, "StubRoutines", name);
  1859     StubCodeMark mark(this, "StubRoutines", name);
  1872     address start = __ function_entry();
  1860     address start = __ function_entry();
  1873 
  1861 
  1874 #if defined(ABI_ELFv2)
       
  1875     address nooverlap_target = aligned ?
  1862     address nooverlap_target = aligned ?
  1876       StubRoutines::arrayof_jlong_disjoint_arraycopy() :
  1863       STUB_ENTRY(arrayof_jlong_disjoint_arraycopy) :
  1877       StubRoutines::jlong_disjoint_arraycopy();
  1864       STUB_ENTRY(jlong_disjoint_arraycopy);
  1878 #else
       
  1879     address nooverlap_target = aligned ?
       
  1880       ((FunctionDescriptor*)StubRoutines::arrayof_jlong_disjoint_arraycopy())->entry() :
       
  1881       ((FunctionDescriptor*)StubRoutines::jlong_disjoint_arraycopy())->entry();
       
  1882 #endif
       
  1883 
  1865 
  1884     array_overlap_test(nooverlap_target, 3);
  1866     array_overlap_test(nooverlap_target, 3);
  1885     generate_conjoint_long_copy_core(aligned);
  1867     generate_conjoint_long_copy_core(aligned);
  1886 
  1868 
       
  1869     __ li(R3_RET, 0); // return 0
  1887     __ blr();
  1870     __ blr();
  1888 
  1871 
  1889     return start;
  1872     return start;
  1890   }
  1873   }
  1891 
  1874 
  1901   address generate_conjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) {
  1884   address generate_conjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) {
  1902     StubCodeMark mark(this, "StubRoutines", name);
  1885     StubCodeMark mark(this, "StubRoutines", name);
  1903 
  1886 
  1904     address start = __ function_entry();
  1887     address start = __ function_entry();
  1905 
  1888 
  1906 #if defined(ABI_ELFv2)
       
  1907     address nooverlap_target = aligned ?
  1889     address nooverlap_target = aligned ?
  1908       StubRoutines::arrayof_oop_disjoint_arraycopy() :
  1890       STUB_ENTRY(arrayof_oop_disjoint_arraycopy) :
  1909       StubRoutines::oop_disjoint_arraycopy();
  1891       STUB_ENTRY(oop_disjoint_arraycopy);
  1910 #else
       
  1911     address nooverlap_target = aligned ?
       
  1912       ((FunctionDescriptor*)StubRoutines::arrayof_oop_disjoint_arraycopy())->entry() :
       
  1913       ((FunctionDescriptor*)StubRoutines::oop_disjoint_arraycopy())->entry();
       
  1914 #endif
       
  1915 
  1892 
  1916     gen_write_ref_array_pre_barrier(R3_ARG1, R4_ARG2, R5_ARG3, dest_uninitialized, R9_ARG7);
  1893     gen_write_ref_array_pre_barrier(R3_ARG1, R4_ARG2, R5_ARG3, dest_uninitialized, R9_ARG7);
  1917 
  1894 
  1918     // Save arguments.
  1895     // Save arguments.
  1919     __ mr(R9_ARG7, R4_ARG2);
  1896     __ mr(R9_ARG7, R4_ARG2);
  1925     } else {
  1902     } else {
  1926       array_overlap_test(nooverlap_target, 3);
  1903       array_overlap_test(nooverlap_target, 3);
  1927       generate_conjoint_long_copy_core(aligned);
  1904       generate_conjoint_long_copy_core(aligned);
  1928     }
  1905     }
  1929 
  1906 
  1930     gen_write_ref_array_post_barrier(R9_ARG7, R10_ARG8, R11_scratch1, /*branchToEnd*/ false);
  1907     gen_write_ref_array_post_barrier(R9_ARG7, R10_ARG8, R11_scratch1);
       
  1908     __ li(R3_RET, 0); // return 0
       
  1909     __ blr();
  1931     return start;
  1910     return start;
  1932   }
  1911   }
  1933 
  1912 
  1934   // Generate stub for disjoint oop copy.  If "aligned" is true, the
  1913   // Generate stub for disjoint oop copy.  If "aligned" is true, the
  1935   // "from" and "to" addresses are assumed to be heapword aligned.
  1914   // "from" and "to" addresses are assumed to be heapword aligned.
  1955       generate_disjoint_int_copy_core(aligned);
  1934       generate_disjoint_int_copy_core(aligned);
  1956     } else {
  1935     } else {
  1957       generate_disjoint_long_copy_core(aligned);
  1936       generate_disjoint_long_copy_core(aligned);
  1958     }
  1937     }
  1959 
  1938 
  1960     gen_write_ref_array_post_barrier(R9_ARG7, R10_ARG8, R11_scratch1, /*branchToEnd*/ false);
  1939     gen_write_ref_array_post_barrier(R9_ARG7, R10_ARG8, R11_scratch1);
       
  1940     __ li(R3_RET, 0); // return 0
       
  1941     __ blr();
  1961 
  1942 
  1962     return start;
  1943     return start;
  1963   }
  1944   }
       
  1945 
       
  1946 
       
  1947   // Helper for generating a dynamic type check.
       
  1948   // Smashes only the given temp registers.
       
  1949   void generate_type_check(Register sub_klass,
       
  1950                            Register super_check_offset,
       
  1951                            Register super_klass,
       
  1952                            Register temp,
       
  1953                            Label& L_success) {
       
  1954     assert_different_registers(sub_klass, super_check_offset, super_klass);
       
  1955 
       
  1956     BLOCK_COMMENT("type_check:");
       
  1957 
       
  1958     Label L_miss;
       
  1959 
       
  1960     __ check_klass_subtype_fast_path(sub_klass, super_klass, temp, R0, &L_success, &L_miss, NULL,
       
  1961                                      super_check_offset);
       
  1962     __ check_klass_subtype_slow_path(sub_klass, super_klass, temp, R0, &L_success, NULL);
       
  1963 
       
  1964     // Fall through on failure!
       
  1965     __ bind(L_miss);
       
  1966   }
       
  1967 
       
  1968 
       
  1969   //  Generate stub for checked oop copy.
       
  1970   //
       
  1971   // Arguments for generated stub:
       
  1972   //      from:  R3
       
  1973   //      to:    R4
       
  1974   //      count: R5 treated as signed
       
  1975   //      ckoff: R6 (super_check_offset)
       
  1976   //      ckval: R7 (super_klass)
       
  1977   //      ret:   R3 zero for success; (-1^K) where K is partial transfer count
       
  1978   //
       
  1979   address generate_checkcast_copy(const char *name, bool dest_uninitialized) {
       
  1980 
       
  1981     const Register R3_from   = R3_ARG1;      // source array address
       
  1982     const Register R4_to     = R4_ARG2;      // destination array address
       
  1983     const Register R5_count  = R5_ARG3;      // elements count
       
  1984     const Register R6_ckoff  = R6_ARG4;      // super_check_offset
       
  1985     const Register R7_ckval  = R7_ARG5;      // super_klass
       
  1986 
       
  1987     const Register R8_offset = R8_ARG6;      // loop var, with stride wordSize
       
  1988     const Register R9_remain = R9_ARG7;      // loop var, with stride -1
       
  1989     const Register R10_oop   = R10_ARG8;     // actual oop copied
       
  1990     const Register R11_klass = R11_scratch1; // oop._klass
       
  1991     const Register R12_tmp   = R12_scratch2;
       
  1992 
       
  1993     const Register R2_minus1 = R2;
       
  1994 
       
  1995     //__ align(CodeEntryAlignment);
       
  1996     StubCodeMark mark(this, "StubRoutines", name);
       
  1997     address start = __ function_entry();
       
  1998 
       
  1999     // TODO: Assert that int is 64 bit sign extended and arrays are not conjoint.
       
  2000 
       
  2001     gen_write_ref_array_pre_barrier(R3_from, R4_to, R5_count, dest_uninitialized, R12_tmp, /* preserve: */ R6_ckoff, R7_ckval);
       
  2002 
       
  2003     //inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, R12_tmp, R3_RET);
       
  2004 
       
  2005     Label load_element, store_element, store_null, success, do_card_marks;
       
  2006     __ or_(R9_remain, R5_count, R5_count); // Initialize loop index, and test it.
       
  2007     __ li(R8_offset, 0);                   // Offset from start of arrays.
       
  2008     __ li(R2_minus1, -1);
       
  2009     __ bne(CCR0, load_element);
       
  2010 
       
  2011     // Empty array: Nothing to do.
       
  2012     __ li(R3_RET, 0);           // Return 0 on (trivial) success.
       
  2013     __ blr();
       
  2014 
       
  2015     // ======== begin loop ========
       
  2016     // (Entry is load_element.)
       
  2017     __ align(OptoLoopAlignment);
       
  2018     __ bind(store_element);
       
  2019     if (UseCompressedOops) {
       
  2020       __ encode_heap_oop_not_null(R10_oop);
       
  2021       __ bind(store_null);
       
  2022       __ stw(R10_oop, R8_offset, R4_to);
       
  2023     } else {
       
  2024       __ bind(store_null);
       
  2025       __ std(R10_oop, R8_offset, R4_to);
       
  2026     }
       
  2027 
       
  2028     __ addi(R8_offset, R8_offset, heapOopSize);   // Step to next offset.
       
  2029     __ add_(R9_remain, R2_minus1, R9_remain);     // Decrement the count.
       
  2030     __ beq(CCR0, success);
       
  2031 
       
  2032     // ======== loop entry is here ========
       
  2033     __ bind(load_element);
       
  2034     __ load_heap_oop(R10_oop, R8_offset, R3_from, &store_null);  // Load the oop.
       
  2035 
       
  2036     __ load_klass(R11_klass, R10_oop); // Query the object klass.
       
  2037 
       
  2038     generate_type_check(R11_klass, R6_ckoff, R7_ckval, R12_tmp,
       
  2039                         // Branch to this on success:
       
  2040                         store_element);
       
  2041     // ======== end loop ========
       
  2042 
       
  2043     // It was a real error; we must depend on the caller to finish the job.
       
  2044     // Register R9_remain has number of *remaining* oops, R5_count number of *total* oops.
       
  2045     // Emit GC store barriers for the oops we have copied (R5_count minus R9_remain),
       
  2046     // and report their number to the caller.
       
  2047     __ subf_(R5_count, R9_remain, R5_count);
       
  2048     __ nand(R3_RET, R5_count, R5_count);   // report (-1^K) to caller
       
  2049     __ bne(CCR0, do_card_marks);
       
  2050     __ blr();
       
  2051 
       
  2052     __ bind(success);
       
  2053     __ li(R3_RET, 0);
       
  2054 
       
  2055     __ bind(do_card_marks);
       
  2056     // Store check on R4_to[0..R5_count-1].
       
  2057     gen_write_ref_array_post_barrier(R4_to, R5_count, R12_tmp, /* preserve: */ R3_RET);
       
  2058     __ blr();
       
  2059     return start;
       
  2060   }
       
  2061 
       
  2062 
       
  2063   //  Generate 'unsafe' array copy stub.
       
  2064   //  Though just as safe as the other stubs, it takes an unscaled
       
  2065   //  size_t argument instead of an element count.
       
  2066   //
       
  2067   // Arguments for generated stub:
       
  2068   //      from:  R3
       
  2069   //      to:    R4
       
  2070   //      count: R5 byte count, treated as ssize_t, can be zero
       
  2071   //
       
  2072   // Examines the alignment of the operands and dispatches
       
  2073   // to a long, int, short, or byte copy loop.
       
  2074   //
       
  2075   address generate_unsafe_copy(const char* name,
       
  2076                                address byte_copy_entry,
       
  2077                                address short_copy_entry,
       
  2078                                address int_copy_entry,
       
  2079                                address long_copy_entry) {
       
  2080 
       
  2081     const Register R3_from   = R3_ARG1;      // source array address
       
  2082     const Register R4_to     = R4_ARG2;      // destination array address
       
  2083     const Register R5_count  = R5_ARG3;      // elements count (as long on PPC64)
       
  2084 
       
  2085     const Register R6_bits   = R6_ARG4;      // test copy of low bits
       
  2086     const Register R7_tmp    = R7_ARG5;
       
  2087 
       
  2088     //__ align(CodeEntryAlignment);
       
  2089     StubCodeMark mark(this, "StubRoutines", name);
       
  2090     address start = __ function_entry();
       
  2091 
       
  2092     // Bump this on entry, not on exit:
       
  2093     //inc_counter_np(SharedRuntime::_unsafe_array_copy_ctr, R6_bits, R7_tmp);
       
  2094 
       
  2095     Label short_copy, int_copy, long_copy;
       
  2096 
       
  2097     __ orr(R6_bits, R3_from, R4_to);
       
  2098     __ orr(R6_bits, R6_bits, R5_count);
       
  2099     __ andi_(R0, R6_bits, (BytesPerLong-1));
       
  2100     __ beq(CCR0, long_copy);
       
  2101 
       
  2102     __ andi_(R0, R6_bits, (BytesPerInt-1));
       
  2103     __ beq(CCR0, int_copy);
       
  2104 
       
  2105     __ andi_(R0, R6_bits, (BytesPerShort-1));
       
  2106     __ beq(CCR0, short_copy);
       
  2107 
       
  2108     // byte_copy:
       
  2109     __ b(byte_copy_entry);
       
  2110 
       
  2111     __ bind(short_copy);
       
  2112     __ srwi(R5_count, R5_count, LogBytesPerShort);
       
  2113     __ b(short_copy_entry);
       
  2114 
       
  2115     __ bind(int_copy);
       
  2116     __ srwi(R5_count, R5_count, LogBytesPerInt);
       
  2117     __ b(int_copy_entry);
       
  2118 
       
  2119     __ bind(long_copy);
       
  2120     __ srwi(R5_count, R5_count, LogBytesPerLong);
       
  2121     __ b(long_copy_entry);
       
  2122 
       
  2123     return start;
       
  2124   }
       
  2125 
       
  2126 
       
  2127   // Perform range checks on the proposed arraycopy.
       
  2128   // Kills the two temps, but nothing else.
       
  2129   // Also, clean the sign bits of src_pos and dst_pos.
       
  2130   void arraycopy_range_checks(Register src,     // source array oop
       
  2131                               Register src_pos, // source position
       
  2132                               Register dst,     // destination array oop
       
  2133                               Register dst_pos, // destination position
       
  2134                               Register length,  // length of copy
       
  2135                               Register temp1, Register temp2,
       
  2136                               Label& L_failed) {
       
  2137     BLOCK_COMMENT("arraycopy_range_checks:");
       
  2138 
       
  2139     const Register array_length = temp1;  // scratch
       
  2140     const Register end_pos      = temp2;  // scratch
       
  2141 
       
  2142     //  if (src_pos + length > arrayOop(src)->length() ) FAIL;
       
  2143     __ lwa(array_length, arrayOopDesc::length_offset_in_bytes(), src);
       
  2144     __ add(end_pos, src_pos, length);  // src_pos + length
       
  2145     __ cmpd(CCR0, end_pos, array_length);
       
  2146     __ bgt(CCR0, L_failed);
       
  2147 
       
  2148     //  if (dst_pos + length > arrayOop(dst)->length() ) FAIL;
       
  2149     __ lwa(array_length, arrayOopDesc::length_offset_in_bytes(), dst);
       
  2150     __ add(end_pos, dst_pos, length);  // src_pos + length
       
  2151     __ cmpd(CCR0, end_pos, array_length);
       
  2152     __ bgt(CCR0, L_failed);
       
  2153 
       
  2154     BLOCK_COMMENT("arraycopy_range_checks done");
       
  2155   }
       
  2156 
       
  2157 
       
  2158   //
       
  2159   //  Generate generic array copy stubs
       
  2160   //
       
  2161   //  Input:
       
  2162   //    R3    -  src oop
       
  2163   //    R4    -  src_pos
       
  2164   //    R5    -  dst oop
       
  2165   //    R6    -  dst_pos
       
  2166   //    R7    -  element count
       
  2167   //
       
  2168   //  Output:
       
  2169   //    R3 ==  0  -  success
       
  2170   //    R3 == -1  -  need to call System.arraycopy
       
  2171   //
       
  2172   address generate_generic_copy(const char *name,
       
  2173                                 address entry_jbyte_arraycopy,
       
  2174                                 address entry_jshort_arraycopy,
       
  2175                                 address entry_jint_arraycopy,
       
  2176                                 address entry_oop_arraycopy,
       
  2177                                 address entry_disjoint_oop_arraycopy,
       
  2178                                 address entry_jlong_arraycopy,
       
  2179                                 address entry_checkcast_arraycopy) {
       
  2180     Label L_failed, L_objArray;
       
  2181 
       
  2182     // Input registers
       
  2183     const Register src       = R3_ARG1;  // source array oop
       
  2184     const Register src_pos   = R4_ARG2;  // source position
       
  2185     const Register dst       = R5_ARG3;  // destination array oop
       
  2186     const Register dst_pos   = R6_ARG4;  // destination position
       
  2187     const Register length    = R7_ARG5;  // elements count
       
  2188 
       
  2189     // registers used as temp
       
  2190     const Register src_klass = R8_ARG6;  // source array klass
       
  2191     const Register dst_klass = R9_ARG7;  // destination array klass
       
  2192     const Register lh        = R10_ARG8; // layout handler
       
  2193     const Register temp      = R2;
       
  2194 
       
  2195     //__ align(CodeEntryAlignment);
       
  2196     StubCodeMark mark(this, "StubRoutines", name);
       
  2197     address start = __ function_entry();
       
  2198 
       
  2199     // Bump this on entry, not on exit:
       
  2200     //inc_counter_np(SharedRuntime::_generic_array_copy_ctr, lh, temp);
       
  2201 
       
  2202     // In principle, the int arguments could be dirty.
       
  2203 
       
  2204     //-----------------------------------------------------------------------
       
  2205     // Assembler stubs will be used for this call to arraycopy
       
  2206     // if the following conditions are met:
       
  2207     //
       
  2208     // (1) src and dst must not be null.
       
  2209     // (2) src_pos must not be negative.
       
  2210     // (3) dst_pos must not be negative.
       
  2211     // (4) length  must not be negative.
       
  2212     // (5) src klass and dst klass should be the same and not NULL.
       
  2213     // (6) src and dst should be arrays.
       
  2214     // (7) src_pos + length must not exceed length of src.
       
  2215     // (8) dst_pos + length must not exceed length of dst.
       
  2216     BLOCK_COMMENT("arraycopy initial argument checks");
       
  2217 
       
  2218     __ cmpdi(CCR1, src, 0);      // if (src == NULL) return -1;
       
  2219     __ extsw_(src_pos, src_pos); // if (src_pos < 0) return -1;
       
  2220     __ cmpdi(CCR5, dst, 0);      // if (dst == NULL) return -1;
       
  2221     __ cror(CCR1, Assembler::equal, CCR0, Assembler::less);
       
  2222     __ extsw_(dst_pos, dst_pos); // if (src_pos < 0) return -1;
       
  2223     __ cror(CCR5, Assembler::equal, CCR0, Assembler::less);
       
  2224     __ extsw_(length, length);   // if (length < 0) return -1;
       
  2225     __ cror(CCR1, Assembler::equal, CCR5, Assembler::equal);
       
  2226     __ cror(CCR1, Assembler::equal, CCR0, Assembler::less);
       
  2227     __ beq(CCR1, L_failed);
       
  2228 
       
  2229     BLOCK_COMMENT("arraycopy argument klass checks");
       
  2230     __ load_klass(src_klass, src);
       
  2231     __ load_klass(dst_klass, dst);
       
  2232 
       
  2233     // Load layout helper
       
  2234     //
       
  2235     //  |array_tag|     | header_size | element_type |     |log2_element_size|
       
  2236     // 32        30    24            16              8     2                 0
       
  2237     //
       
  2238     //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
       
  2239     //
       
  2240 
       
  2241     int lh_offset = in_bytes(Klass::layout_helper_offset());
       
  2242 
       
  2243     // Load 32-bits signed value. Use br() instruction with it to check icc.
       
  2244     __ lwz(lh, lh_offset, src_klass);
       
  2245 
       
  2246     // Handle objArrays completely differently...
       
  2247     jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
       
  2248     __ load_const_optimized(temp, objArray_lh, R0);
       
  2249     __ cmpw(CCR0, lh, temp);
       
  2250     __ beq(CCR0, L_objArray);
       
  2251 
       
  2252     __ cmpd(CCR5, src_klass, dst_klass);          // if (src->klass() != dst->klass()) return -1;
       
  2253     __ cmpwi(CCR6, lh, Klass::_lh_neutral_value); // if (!src->is_Array()) return -1;
       
  2254 
       
  2255     __ crnand(CCR5, Assembler::equal, CCR6, Assembler::less);
       
  2256     __ beq(CCR5, L_failed);
       
  2257 
       
  2258     // At this point, it is known to be a typeArray (array_tag 0x3).
       
  2259 #ifdef ASSERT
       
  2260     { Label L;
       
  2261       jint lh_prim_tag_in_place = (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift);
       
  2262       __ load_const_optimized(temp, lh_prim_tag_in_place, R0);
       
  2263       __ cmpw(CCR0, lh, temp);
       
  2264       __ bge(CCR0, L);
       
  2265       __ stop("must be a primitive array");
       
  2266       __ bind(L);
       
  2267     }
       
  2268 #endif
       
  2269 
       
  2270     arraycopy_range_checks(src, src_pos, dst, dst_pos, length,
       
  2271                            temp, dst_klass, L_failed);
       
  2272 
       
  2273     // TypeArrayKlass
       
  2274     //
       
  2275     // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
       
  2276     // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
       
  2277     //
       
  2278 
       
  2279     const Register offset = dst_klass;    // array offset
       
  2280     const Register elsize = src_klass;    // log2 element size
       
  2281 
       
  2282     __ rldicl(offset, lh, 64 - Klass::_lh_header_size_shift, 64 - exact_log2(Klass::_lh_header_size_mask + 1));
       
  2283     __ andi(elsize, lh, Klass::_lh_log2_element_size_mask);
       
  2284     __ add(src, offset, src);       // src array offset
       
  2285     __ add(dst, offset, dst);       // dst array offset
       
  2286 
       
  2287     // Next registers should be set before the jump to corresponding stub.
       
  2288     const Register from     = R3_ARG1;  // source array address
       
  2289     const Register to       = R4_ARG2;  // destination array address
       
  2290     const Register count    = R5_ARG3;  // elements count
       
  2291 
       
  2292     // 'from', 'to', 'count' registers should be set in this order
       
  2293     // since they are the same as 'src', 'src_pos', 'dst'.
       
  2294 
       
  2295     BLOCK_COMMENT("scale indexes to element size");
       
  2296     __ sld(src_pos, src_pos, elsize);
       
  2297     __ sld(dst_pos, dst_pos, elsize);
       
  2298     __ add(from, src_pos, src);  // src_addr
       
  2299     __ add(to, dst_pos, dst);    // dst_addr
       
  2300     __ mr(count, length);        // length
       
  2301 
       
  2302     BLOCK_COMMENT("choose copy loop based on element size");
       
  2303     // Using conditional branches with range 32kB.
       
  2304     const int bo = Assembler::bcondCRbiIs1, bi = Assembler::bi0(CCR0, Assembler::equal);
       
  2305     __ cmpwi(CCR0, elsize, 0);
       
  2306     __ bc(bo, bi, entry_jbyte_arraycopy);
       
  2307     __ cmpwi(CCR0, elsize, LogBytesPerShort);
       
  2308     __ bc(bo, bi, entry_jshort_arraycopy);
       
  2309     __ cmpwi(CCR0, elsize, LogBytesPerInt);
       
  2310     __ bc(bo, bi, entry_jint_arraycopy);
       
  2311 #ifdef ASSERT
       
  2312     { Label L;
       
  2313       __ cmpwi(CCR0, elsize, LogBytesPerLong);
       
  2314       __ beq(CCR0, L);
       
  2315       __ stop("must be long copy, but elsize is wrong");
       
  2316       __ bind(L);
       
  2317     }
       
  2318 #endif
       
  2319     __ b(entry_jlong_arraycopy);
       
  2320 
       
  2321     // ObjArrayKlass
       
  2322   __ bind(L_objArray);
       
  2323     // live at this point:  src_klass, dst_klass, src[_pos], dst[_pos], length
       
  2324 
       
  2325     Label L_disjoint_plain_copy, L_checkcast_copy;
       
  2326     //  test array classes for subtyping
       
  2327     __ cmpd(CCR0, src_klass, dst_klass);         // usual case is exact equality
       
  2328     __ bne(CCR0, L_checkcast_copy);
       
  2329 
       
  2330     // Identically typed arrays can be copied without element-wise checks.
       
  2331     arraycopy_range_checks(src, src_pos, dst, dst_pos, length,
       
  2332                            temp, lh, L_failed);
       
  2333 
       
  2334     __ addi(src, src, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); //src offset
       
  2335     __ addi(dst, dst, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); //dst offset
       
  2336     __ sldi(src_pos, src_pos, LogBytesPerHeapOop);
       
  2337     __ sldi(dst_pos, dst_pos, LogBytesPerHeapOop);
       
  2338     __ add(from, src_pos, src);  // src_addr
       
  2339     __ add(to, dst_pos, dst);    // dst_addr
       
  2340     __ mr(count, length);        // length
       
  2341     __ b(entry_oop_arraycopy);
       
  2342 
       
  2343   __ bind(L_checkcast_copy);
       
  2344     // live at this point:  src_klass, dst_klass
       
  2345     {
       
  2346       // Before looking at dst.length, make sure dst is also an objArray.
       
  2347       __ lwz(temp, lh_offset, dst_klass);
       
  2348       __ cmpw(CCR0, lh, temp);
       
  2349       __ bne(CCR0, L_failed);
       
  2350 
       
  2351       // It is safe to examine both src.length and dst.length.
       
  2352       arraycopy_range_checks(src, src_pos, dst, dst_pos, length,
       
  2353                              temp, lh, L_failed);
       
  2354 
       
  2355       // Marshal the base address arguments now, freeing registers.
       
  2356       __ addi(src, src, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); //src offset
       
  2357       __ addi(dst, dst, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); //dst offset
       
  2358       __ sldi(src_pos, src_pos, LogBytesPerHeapOop);
       
  2359       __ sldi(dst_pos, dst_pos, LogBytesPerHeapOop);
       
  2360       __ add(from, src_pos, src);  // src_addr
       
  2361       __ add(to, dst_pos, dst);    // dst_addr
       
  2362       __ mr(count, length);        // length
       
  2363 
       
  2364       Register sco_temp = R6_ARG4;             // This register is free now.
       
  2365       assert_different_registers(from, to, count, sco_temp,
       
  2366                                  dst_klass, src_klass);
       
  2367 
       
  2368       // Generate the type check.
       
  2369       int sco_offset = in_bytes(Klass::super_check_offset_offset());
       
  2370       __ lwz(sco_temp, sco_offset, dst_klass);
       
  2371       generate_type_check(src_klass, sco_temp, dst_klass,
       
  2372                           temp, L_disjoint_plain_copy);
       
  2373 
       
  2374       // Fetch destination element klass from the ObjArrayKlass header.
       
  2375       int ek_offset = in_bytes(ObjArrayKlass::element_klass_offset());
       
  2376 
       
  2377       // The checkcast_copy loop needs two extra arguments:
       
  2378       __ ld(R7_ARG5, ek_offset, dst_klass);   // dest elem klass
       
  2379       __ lwz(R6_ARG4, sco_offset, R7_ARG5);   // sco of elem klass
       
  2380       __ b(entry_checkcast_arraycopy);
       
  2381     }
       
  2382 
       
  2383     __ bind(L_disjoint_plain_copy);
       
  2384     __ b(entry_disjoint_oop_arraycopy);
       
  2385 
       
  2386   __ bind(L_failed);
       
  2387     __ li(R3_RET, -1); // return -1
       
  2388     __ blr();
       
  2389     return start;
       
  2390   }
       
  2391 
  1964 
  2392 
  1965   void generate_arraycopy_stubs() {
  2393   void generate_arraycopy_stubs() {
  1966     // Note: the disjoint stubs must be generated first, some of
  2394     // Note: the disjoint stubs must be generated first, some of
  1967     // the conjoint stubs use them.
  2395     // the conjoint stubs use them.
  1968 
  2396 
  1995     StubRoutines::_arrayof_jshort_arraycopy     = generate_conjoint_short_copy(true, "arrayof_jshort_arraycopy");
  2423     StubRoutines::_arrayof_jshort_arraycopy     = generate_conjoint_short_copy(true, "arrayof_jshort_arraycopy");
  1996     StubRoutines::_arrayof_jint_arraycopy       = generate_conjoint_int_copy(true, "arrayof_jint_arraycopy");
  2424     StubRoutines::_arrayof_jint_arraycopy       = generate_conjoint_int_copy(true, "arrayof_jint_arraycopy");
  1997     StubRoutines::_arrayof_jlong_arraycopy      = generate_conjoint_long_copy(true, "arrayof_jlong_arraycopy");
  2425     StubRoutines::_arrayof_jlong_arraycopy      = generate_conjoint_long_copy(true, "arrayof_jlong_arraycopy");
  1998     StubRoutines::_arrayof_oop_arraycopy        = generate_conjoint_oop_copy(true, "arrayof_oop_arraycopy", false);
  2426     StubRoutines::_arrayof_oop_arraycopy        = generate_conjoint_oop_copy(true, "arrayof_oop_arraycopy", false);
  1999     StubRoutines::_arrayof_oop_arraycopy_uninit = generate_conjoint_oop_copy(true, "arrayof_oop_arraycopy", true);
  2427     StubRoutines::_arrayof_oop_arraycopy_uninit = generate_conjoint_oop_copy(true, "arrayof_oop_arraycopy", true);
       
  2428 
       
  2429     // special/generic versions
       
  2430     StubRoutines::_checkcast_arraycopy        = generate_checkcast_copy("checkcast_arraycopy", false);
       
  2431     StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy("checkcast_arraycopy_uninit", true);
       
  2432 
       
  2433     StubRoutines::_unsafe_arraycopy  = generate_unsafe_copy("unsafe_arraycopy",
       
  2434                                                             STUB_ENTRY(jbyte_arraycopy),
       
  2435                                                             STUB_ENTRY(jshort_arraycopy),
       
  2436                                                             STUB_ENTRY(jint_arraycopy),
       
  2437                                                             STUB_ENTRY(jlong_arraycopy));
       
  2438     StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy",
       
  2439                                                              STUB_ENTRY(jbyte_arraycopy),
       
  2440                                                              STUB_ENTRY(jshort_arraycopy),
       
  2441                                                              STUB_ENTRY(jint_arraycopy),
       
  2442                                                              STUB_ENTRY(oop_arraycopy),
       
  2443                                                              STUB_ENTRY(oop_disjoint_arraycopy),
       
  2444                                                              STUB_ENTRY(jlong_arraycopy),
       
  2445                                                              STUB_ENTRY(checkcast_arraycopy));
  2000 
  2446 
  2001     // fill routines
  2447     // fill routines
  2002     StubRoutines::_jbyte_fill          = generate_fill(T_BYTE,  false, "jbyte_fill");
  2448     StubRoutines::_jbyte_fill          = generate_fill(T_BYTE,  false, "jbyte_fill");
  2003     StubRoutines::_jshort_fill         = generate_fill(T_SHORT, false, "jshort_fill");
  2449     StubRoutines::_jshort_fill         = generate_fill(T_SHORT, false, "jshort_fill");
  2004     StubRoutines::_jint_fill           = generate_fill(T_INT,   false, "jint_fill");
  2450     StubRoutines::_jint_fill           = generate_fill(T_INT,   false, "jint_fill");
  2226 #ifdef COMPILER2
  2672 #ifdef COMPILER2
  2227     if (UseMultiplyToLenIntrinsic) {
  2673     if (UseMultiplyToLenIntrinsic) {
  2228       StubRoutines::_multiplyToLen = generate_multiplyToLen();
  2674       StubRoutines::_multiplyToLen = generate_multiplyToLen();
  2229     }
  2675     }
  2230 #endif
  2676 #endif
       
  2677 
       
  2678     if (UseMontgomeryMultiplyIntrinsic) {
       
  2679       StubRoutines::_montgomeryMultiply
       
  2680         = CAST_FROM_FN_PTR(address, SharedRuntime::montgomery_multiply);
       
  2681     }
       
  2682     if (UseMontgomerySquareIntrinsic) {
       
  2683       StubRoutines::_montgomerySquare
       
  2684         = CAST_FROM_FN_PTR(address, SharedRuntime::montgomery_square);
       
  2685     }
  2231   }
  2686   }
  2232 
  2687 
  2233  public:
  2688  public:
  2234   StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) {
  2689   StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) {
  2235     // replace the standard masm with a special one:
  2690     // replace the standard masm with a special one: