530 // RuntimeStub.
531 address generate_throw_exception(const char* name, address runtime_entry, bool restore_saved_exception_pc,
532 Register arg1 = noreg, Register arg2 = noreg) {
533 CodeBuffer code(name, 1024 DEBUG_ONLY(+ 512), 0);
534 MacroAssembler* masm = new MacroAssembler(&code);
535
536 OopMapSet* oop_maps = new OopMapSet();
537 int frame_size_in_bytes = frame::abi_reg_args_size;
538 OopMap* map = new OopMap(frame_size_in_bytes / sizeof(jint), 0);
539
540 address start = __ pc();
541
542 __ save_LR_CR(R11_scratch1);
543
544 // Push a frame.
545 __ push_frame_reg_args(0, R11_scratch1);
546
547 address frame_complete_pc = __ pc();
548
549 if (restore_saved_exception_pc) {
550 __ unimplemented("StubGenerator::throw_exception with restore_saved_exception_pc", 74);
551 }
552
553 // Note that we always have a runtime stub frame on the top of
554 // stack by this point. Remember the offset of the instruction
555 // whose address will be moved to R11_scratch1.
556 address gc_map_pc = __ get_PC_trash_LR(R11_scratch1);
557
558 __ set_last_Java_frame(/*sp*/R1_SP, /*pc*/R11_scratch1);
559
560 __ mr(R3_ARG1, R16_thread);
561 if (arg1 != noreg) {
562 __ mr(R4_ARG2, arg1);
563 }
564 if (arg2 != noreg) {
565 __ mr(R5_ARG3, arg2);
566 }
567 #if defined(ABI_ELFv2)
568 __ call_c(runtime_entry, relocInfo::none);
569 #else
570 __ call_c(CAST_FROM_FN_PTR(FunctionDescriptor*, runtime_entry), relocInfo::none);
904 if (t == T_SHORT) {
905 Label L_fill_2;
906 __ bind(L_fill_elements);
907 __ andi_(temp, count, 1);
908 __ beq(CCR0, L_fill_2);
909 __ sth(value, 0, to);
910 __ addi(to, to, 2);
911 __ bind(L_fill_2);
912 __ andi_(temp, count, 2);
913 __ beq(CCR0, L_exit);
914 __ sth(value, 0, to);
915 __ sth(value, 2, to);
916 __ blr();
917 }
918 return start;
919 }
920
921 inline void assert_positive_int(Register count) {
922 #ifdef ASSERT
923 __ srdi_(R0, count, 31);
924 __ asm_assert_eq("missing zero extend", 0xAFFE);
925 #endif
926 }
927
928 // Generate overlap test for array copy stubs.
929 //
930 // Input:
931 // R3_ARG1 - from
932 // R4_ARG2 - to
933 // R5_ARG3 - element count
934 //
935 void array_overlap_test(address no_overlap_target, int log2_elem_size) {
936 Register tmp1 = R6_ARG4;
937 Register tmp2 = R7_ARG5;
938
939 assert_positive_int(R5_ARG3);
940
941 __ subf(tmp1, R3_ARG1, R4_ARG2); // distance in bytes
942 __ sldi(tmp2, R5_ARG3, log2_elem_size); // size in bytes
943 __ cmpld(CCR0, R3_ARG1, R4_ARG2); // Use unsigned comparison!
944 __ cmpld(CCR1, tmp1, tmp2);
2164 const Register R2_minus1 = R2;
2165
2166 //__ align(CodeEntryAlignment);
2167 StubCodeMark mark(this, "StubRoutines", name);
2168 address start = __ function_entry();
2169
2170 // Assert that int is 64 bit sign extended and arrays are not conjoint.
2171 #ifdef ASSERT
2172 {
2173 assert_positive_int(R5_ARG3);
2174 const Register tmp1 = R11_scratch1, tmp2 = R12_scratch2;
2175 Label no_overlap;
2176 __ subf(tmp1, R3_ARG1, R4_ARG2); // distance in bytes
2177 __ sldi(tmp2, R5_ARG3, LogBytesPerHeapOop); // size in bytes
2178 __ cmpld(CCR0, R3_ARG1, R4_ARG2); // Use unsigned comparison!
2179 __ cmpld(CCR1, tmp1, tmp2);
2180 __ crnand(CCR0, Assembler::less, CCR1, Assembler::less);
2181 // Overlaps if Src before dst and distance smaller than size.
2182 // Branch to forward copy routine otherwise.
2183 __ blt(CCR0, no_overlap);
2184 __ stop("overlap in checkcast_copy", 0x9543);
2185 __ bind(no_overlap);
2186 }
2187 #endif
2188
2189 DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_CHECKCAST;
2190 if (dest_uninitialized) {
2191 decorators |= IS_DEST_UNINITIALIZED;
2192 }
2193
2194 BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
2195 bs->arraycopy_prologue(_masm, decorators, T_OBJECT, R3_from, R4_to, R5_count, /* preserve: */ R6_ckoff, R7_ckval);
2196
2197 //inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, R12_tmp, R3_RET);
2198
2199 Label load_element, store_element, store_null, success, do_epilogue;
2200 __ or_(R9_remain, R5_count, R5_count); // Initialize loop index, and test it.
2201 __ li(R8_offset, 0); // Offset from start of arrays.
2202 __ li(R2_minus1, -1);
2203 __ bne(CCR0, load_element);
2204
|
530 // RuntimeStub.
531 address generate_throw_exception(const char* name, address runtime_entry, bool restore_saved_exception_pc,
532 Register arg1 = noreg, Register arg2 = noreg) {
533 CodeBuffer code(name, 1024 DEBUG_ONLY(+ 512), 0);
534 MacroAssembler* masm = new MacroAssembler(&code);
535
536 OopMapSet* oop_maps = new OopMapSet();
537 int frame_size_in_bytes = frame::abi_reg_args_size;
538 OopMap* map = new OopMap(frame_size_in_bytes / sizeof(jint), 0);
539
540 address start = __ pc();
541
542 __ save_LR_CR(R11_scratch1);
543
544 // Push a frame.
545 __ push_frame_reg_args(0, R11_scratch1);
546
547 address frame_complete_pc = __ pc();
548
549 if (restore_saved_exception_pc) {
550 __ unimplemented("StubGenerator::throw_exception with restore_saved_exception_pc");
551 }
552
553 // Note that we always have a runtime stub frame on the top of
554 // stack by this point. Remember the offset of the instruction
555 // whose address will be moved to R11_scratch1.
556 address gc_map_pc = __ get_PC_trash_LR(R11_scratch1);
557
558 __ set_last_Java_frame(/*sp*/R1_SP, /*pc*/R11_scratch1);
559
560 __ mr(R3_ARG1, R16_thread);
561 if (arg1 != noreg) {
562 __ mr(R4_ARG2, arg1);
563 }
564 if (arg2 != noreg) {
565 __ mr(R5_ARG3, arg2);
566 }
567 #if defined(ABI_ELFv2)
568 __ call_c(runtime_entry, relocInfo::none);
569 #else
570 __ call_c(CAST_FROM_FN_PTR(FunctionDescriptor*, runtime_entry), relocInfo::none);
904 if (t == T_SHORT) {
905 Label L_fill_2;
906 __ bind(L_fill_elements);
907 __ andi_(temp, count, 1);
908 __ beq(CCR0, L_fill_2);
909 __ sth(value, 0, to);
910 __ addi(to, to, 2);
911 __ bind(L_fill_2);
912 __ andi_(temp, count, 2);
913 __ beq(CCR0, L_exit);
914 __ sth(value, 0, to);
915 __ sth(value, 2, to);
916 __ blr();
917 }
918 return start;
919 }
920
921 inline void assert_positive_int(Register count) {
922 #ifdef ASSERT
923 __ srdi_(R0, count, 31);
924 __ asm_assert_eq("missing zero extend");
925 #endif
926 }
927
928 // Generate overlap test for array copy stubs.
929 //
930 // Input:
931 // R3_ARG1 - from
932 // R4_ARG2 - to
933 // R5_ARG3 - element count
934 //
935 void array_overlap_test(address no_overlap_target, int log2_elem_size) {
936 Register tmp1 = R6_ARG4;
937 Register tmp2 = R7_ARG5;
938
939 assert_positive_int(R5_ARG3);
940
941 __ subf(tmp1, R3_ARG1, R4_ARG2); // distance in bytes
942 __ sldi(tmp2, R5_ARG3, log2_elem_size); // size in bytes
943 __ cmpld(CCR0, R3_ARG1, R4_ARG2); // Use unsigned comparison!
944 __ cmpld(CCR1, tmp1, tmp2);
2164 const Register R2_minus1 = R2;
2165
2166 //__ align(CodeEntryAlignment);
2167 StubCodeMark mark(this, "StubRoutines", name);
2168 address start = __ function_entry();
2169
2170 // Assert that int is 64 bit sign extended and arrays are not conjoint.
2171 #ifdef ASSERT
2172 {
2173 assert_positive_int(R5_ARG3);
2174 const Register tmp1 = R11_scratch1, tmp2 = R12_scratch2;
2175 Label no_overlap;
2176 __ subf(tmp1, R3_ARG1, R4_ARG2); // distance in bytes
2177 __ sldi(tmp2, R5_ARG3, LogBytesPerHeapOop); // size in bytes
2178 __ cmpld(CCR0, R3_ARG1, R4_ARG2); // Use unsigned comparison!
2179 __ cmpld(CCR1, tmp1, tmp2);
2180 __ crnand(CCR0, Assembler::less, CCR1, Assembler::less);
2181 // Overlaps if Src before dst and distance smaller than size.
2182 // Branch to forward copy routine otherwise.
2183 __ blt(CCR0, no_overlap);
2184 __ stop("overlap in checkcast_copy");
2185 __ bind(no_overlap);
2186 }
2187 #endif
2188
2189 DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_CHECKCAST;
2190 if (dest_uninitialized) {
2191 decorators |= IS_DEST_UNINITIALIZED;
2192 }
2193
2194 BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
2195 bs->arraycopy_prologue(_masm, decorators, T_OBJECT, R3_from, R4_to, R5_count, /* preserve: */ R6_ckoff, R7_ckval);
2196
2197 //inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, R12_tmp, R3_RET);
2198
2199 Label load_element, store_element, store_null, success, do_epilogue;
2200 __ or_(R9_remain, R5_count, R5_count); // Initialize loop index, and test it.
2201 __ li(R8_offset, 0); // Offset from start of arrays.
2202 __ li(R2_minus1, -1);
2203 __ bne(CCR0, load_element);
2204
|