148 #ifdef ASSERT |
148 #ifdef ASSERT |
149 // make sure we have no pending exceptions |
149 // make sure we have no pending exceptions |
150 { const Register t = G3_scratch; |
150 { const Register t = G3_scratch; |
151 Label L; |
151 Label L; |
152 __ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), t); |
152 __ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), t); |
153 __ br_null(t, false, Assembler::pt, L); |
153 __ br_null_short(t, Assembler::pt, L); |
154 __ delayed()->nop(); |
|
155 __ stop("StubRoutines::call_stub: entered with pending exception"); |
154 __ stop("StubRoutines::call_stub: entered with pending exception"); |
156 __ bind(L); |
155 __ bind(L); |
157 } |
156 } |
158 #endif |
157 #endif |
159 |
158 |
205 |
204 |
206 // test if any parameters & setup of Lentry_args |
205 // test if any parameters & setup of Lentry_args |
207 Label exit; |
206 Label exit; |
208 __ ld_ptr(parameter_size.as_in().as_address(), cnt); // parameter counter |
207 __ ld_ptr(parameter_size.as_in().as_address(), cnt); // parameter counter |
209 __ add( FP, STACK_BIAS, dst ); |
208 __ add( FP, STACK_BIAS, dst ); |
210 __ tst(cnt); |
209 __ cmp_zero_and_br(Assembler::zero, cnt, exit); |
211 __ br(Assembler::zero, false, Assembler::pn, exit); |
|
212 __ delayed()->sub(dst, BytesPerWord, dst); // setup Lentry_args |
210 __ delayed()->sub(dst, BytesPerWord, dst); // setup Lentry_args |
213 |
211 |
214 // copy parameters if any |
212 // copy parameters if any |
215 Label loop; |
213 Label loop; |
216 __ BIND(loop); |
214 __ BIND(loop); |
280 __ BIND(exit); |
278 __ BIND(exit); |
281 __ ret(); |
279 __ ret(); |
282 __ delayed()->restore(); |
280 __ delayed()->restore(); |
283 |
281 |
284 __ BIND(is_object); |
282 __ BIND(is_object); |
285 __ ba(false, exit); |
283 __ ba(exit); |
286 __ delayed()->st_ptr(O0, addr, G0); |
284 __ delayed()->st_ptr(O0, addr, G0); |
287 |
285 |
288 __ BIND(is_float); |
286 __ BIND(is_float); |
289 __ ba(false, exit); |
287 __ ba(exit); |
290 __ delayed()->stf(FloatRegisterImpl::S, F0, addr, G0); |
288 __ delayed()->stf(FloatRegisterImpl::S, F0, addr, G0); |
291 |
289 |
292 __ BIND(is_double); |
290 __ BIND(is_double); |
293 __ ba(false, exit); |
291 __ ba(exit); |
294 __ delayed()->stf(FloatRegisterImpl::D, F0, addr, G0); |
292 __ delayed()->stf(FloatRegisterImpl::D, F0, addr, G0); |
295 |
293 |
296 __ BIND(is_long); |
294 __ BIND(is_long); |
297 #ifdef _LP64 |
295 #ifdef _LP64 |
298 __ ba(false, exit); |
296 __ ba(exit); |
299 __ delayed()->st_long(O0, addr, G0); // store entire long |
297 __ delayed()->st_long(O0, addr, G0); // store entire long |
300 #else |
298 #else |
301 #if defined(COMPILER2) |
299 #if defined(COMPILER2) |
302 // All return values are where we want them, except for Longs. C2 returns |
300 // All return values are where we want them, except for Longs. C2 returns |
303 // longs in G1 in the 32-bit build whereas the interpreter wants them in O0/O1. |
301 // longs in G1 in the 32-bit build whereas the interpreter wants them in O0/O1. |
305 // build we simply always use G1. |
303 // build we simply always use G1. |
306 // Note: I tried to make c2 return longs in O0/O1 and G1 so we wouldn't have to |
304 // Note: I tried to make c2 return longs in O0/O1 and G1 so we wouldn't have to |
307 // do this here. Unfortunately if we did a rethrow we'd see an machepilog node |
305 // do this here. Unfortunately if we did a rethrow we'd see an machepilog node |
308 // first which would move g1 -> O0/O1 and destroy the exception we were throwing. |
306 // first which would move g1 -> O0/O1 and destroy the exception we were throwing. |
309 |
307 |
310 __ ba(false, exit); |
308 __ ba(exit); |
311 __ delayed()->stx(G1, addr, G0); // store entire long |
309 __ delayed()->stx(G1, addr, G0); // store entire long |
312 #else |
310 #else |
313 __ st(O1, addr, BytesPerInt); |
311 __ st(O1, addr, BytesPerInt); |
314 __ ba(false, exit); |
312 __ ba(exit); |
315 __ delayed()->st(O0, addr, G0); |
313 __ delayed()->st(O0, addr, G0); |
316 #endif /* COMPILER2 */ |
314 #endif /* COMPILER2 */ |
317 #endif /* _LP64 */ |
315 #endif /* _LP64 */ |
318 } |
316 } |
319 return start; |
317 return start; |
380 |
378 |
381 #ifdef ASSERT |
379 #ifdef ASSERT |
382 // make sure that this code is only executed if there is a pending exception |
380 // make sure that this code is only executed if there is a pending exception |
383 { Label L; |
381 { Label L; |
384 __ ld_ptr(exception_addr, Gtemp); |
382 __ ld_ptr(exception_addr, Gtemp); |
385 __ br_notnull(Gtemp, false, Assembler::pt, L); |
383 __ br_notnull_short(Gtemp, Assembler::pt, L); |
386 __ delayed()->nop(); |
|
387 __ stop("StubRoutines::forward exception: no pending exception (1)"); |
384 __ stop("StubRoutines::forward exception: no pending exception (1)"); |
388 __ bind(L); |
385 __ bind(L); |
389 } |
386 } |
390 #endif |
387 #endif |
391 |
388 |
404 __ add(O7, frame::pc_return_offset, Oissuing_pc); // save the issuing PC |
401 __ add(O7, frame::pc_return_offset, Oissuing_pc); // save the issuing PC |
405 |
402 |
406 #ifdef ASSERT |
403 #ifdef ASSERT |
407 // make sure exception is set |
404 // make sure exception is set |
408 { Label L; |
405 { Label L; |
409 __ br_notnull(Oexception, false, Assembler::pt, L); |
406 __ br_notnull_short(Oexception, Assembler::pt, L); |
410 __ delayed()->nop(); |
|
411 __ stop("StubRoutines::forward exception: no pending exception (2)"); |
407 __ stop("StubRoutines::forward exception: no pending exception (2)"); |
412 __ bind(L); |
408 __ bind(L); |
413 } |
409 } |
414 #endif |
410 #endif |
415 // jump to exception handler |
411 // jump to exception handler |
499 Label L; |
495 Label L; |
500 |
496 |
501 Address exception_addr(G2_thread, Thread::pending_exception_offset()); |
497 Address exception_addr(G2_thread, Thread::pending_exception_offset()); |
502 Register scratch_reg = Gtemp; |
498 Register scratch_reg = Gtemp; |
503 __ ld_ptr(exception_addr, scratch_reg); |
499 __ ld_ptr(exception_addr, scratch_reg); |
504 __ br_notnull(scratch_reg, false, Assembler::pt, L); |
500 __ br_notnull_short(scratch_reg, Assembler::pt, L); |
505 __ delayed()->nop(); |
|
506 __ should_not_reach_here(); |
501 __ should_not_reach_here(); |
507 __ bind(L); |
502 __ bind(L); |
508 #endif // ASSERT |
503 #endif // ASSERT |
509 BLOCK_COMMENT("call forward_exception_entry"); |
504 BLOCK_COMMENT("call forward_exception_entry"); |
510 __ call(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type); |
505 __ call(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type); |
612 __ set(StubRoutines::Sparc::locked, lock_reg); |
607 __ set(StubRoutines::Sparc::locked, lock_reg); |
613 // Initialize yield counter |
608 // Initialize yield counter |
614 __ mov(G0,yield_reg); |
609 __ mov(G0,yield_reg); |
615 |
610 |
616 __ BIND(retry); |
611 __ BIND(retry); |
617 __ cmp(yield_reg, V8AtomicOperationUnderLockSpinCount); |
612 __ cmp_and_br_short(yield_reg, V8AtomicOperationUnderLockSpinCount, Assembler::less, Assembler::pt, dontyield); |
618 __ br(Assembler::less, false, Assembler::pt, dontyield); |
|
619 __ delayed()->nop(); |
|
620 |
613 |
621 // This code can only be called from inside the VM, this |
614 // This code can only be called from inside the VM, this |
622 // stub is only invoked from Atomic::add(). We do not |
615 // stub is only invoked from Atomic::add(). We do not |
623 // want to use call_VM, because _last_java_sp and such |
616 // want to use call_VM, because _last_java_sp and such |
624 // must already be set. |
617 // must already be set. |
674 __ mov(O0, O3); // scratch copy of exchange value |
667 __ mov(O0, O3); // scratch copy of exchange value |
675 __ ld(O1, 0, O2); // observe the previous value |
668 __ ld(O1, 0, O2); // observe the previous value |
676 // try to replace O2 with O3 |
669 // try to replace O2 with O3 |
677 __ cas_under_lock(O1, O2, O3, |
670 __ cas_under_lock(O1, O2, O3, |
678 (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr(),false); |
671 (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr(),false); |
679 __ cmp(O2, O3); |
672 __ cmp_and_br_short(O2, O3, Assembler::notEqual, Assembler::pn, retry); |
680 __ br(Assembler::notEqual, false, Assembler::pn, retry); |
|
681 __ delayed()->nop(); |
|
682 |
673 |
683 __ retl(false); |
674 __ retl(false); |
684 __ delayed()->mov(O2, O0); // report previous value to caller |
675 __ delayed()->mov(O2, O0); // report previous value to caller |
685 |
676 |
686 } else { |
677 } else { |
796 if (VM_Version::v9_instructions_work()) { |
787 if (VM_Version::v9_instructions_work()) { |
797 Label(retry); |
788 Label(retry); |
798 __ BIND(retry); |
789 __ BIND(retry); |
799 |
790 |
800 __ lduw(O1, 0, O2); |
791 __ lduw(O1, 0, O2); |
801 __ add(O0, O2, O3); |
792 __ add(O0, O2, O3); |
802 __ cas(O1, O2, O3); |
793 __ cas(O1, O2, O3); |
803 __ cmp( O2, O3); |
794 __ cmp_and_br_short(O2, O3, Assembler::notEqual, Assembler::pn, retry); |
804 __ br(Assembler::notEqual, false, Assembler::pn, retry); |
|
805 __ delayed()->nop(); |
|
806 __ retl(false); |
795 __ retl(false); |
807 __ delayed()->add(O0, O2, O0); // note that cas made O2==O3 |
796 __ delayed()->add(O0, O2, O0); // note that cas made O2==O3 |
808 } else { |
797 } else { |
809 const Register& lock_reg = O2; |
798 const Register& lock_reg = O2; |
810 const Register& lock_ptr_reg = O3; |
799 const Register& lock_ptr_reg = O3; |
1368 generate_disjoint_long_copy_core(aligned); |
1357 generate_disjoint_long_copy_core(aligned); |
1369 __ mov(G4, count); // Restore count |
1358 __ mov(G4, count); // Restore count |
1370 |
1359 |
1371 // copy tailing bytes |
1360 // copy tailing bytes |
1372 __ BIND(L_copy_byte); |
1361 __ BIND(L_copy_byte); |
1373 __ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit); |
1362 __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit); |
1374 __ delayed()->nop(); |
|
1375 __ align(OptoLoopAlignment); |
1363 __ align(OptoLoopAlignment); |
1376 __ BIND(L_copy_byte_loop); |
1364 __ BIND(L_copy_byte_loop); |
1377 __ ldub(from, offset, O3); |
1365 __ ldub(from, offset, O3); |
1378 __ deccc(count); |
1366 __ deccc(count); |
1379 __ stb(O3, to, offset); |
1367 __ stb(O3, to, offset); |
1480 __ delayed()->stx(O4, end_to, 0); |
1468 __ delayed()->stx(O4, end_to, 0); |
1481 __ inc(count, 16); |
1469 __ inc(count, 16); |
1482 |
1470 |
1483 // copy 1 element (2 bytes) at a time |
1471 // copy 1 element (2 bytes) at a time |
1484 __ BIND(L_copy_byte); |
1472 __ BIND(L_copy_byte); |
1485 __ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit); |
1473 __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit); |
1486 __ delayed()->nop(); |
|
1487 __ align(OptoLoopAlignment); |
1474 __ align(OptoLoopAlignment); |
1488 __ BIND(L_copy_byte_loop); |
1475 __ BIND(L_copy_byte_loop); |
1489 __ dec(end_from); |
1476 __ dec(end_from); |
1490 __ dec(end_to); |
1477 __ dec(end_to); |
1491 __ ldub(end_from, 0, O4); |
1478 __ ldub(end_from, 0, O4); |
1598 generate_disjoint_long_copy_core(aligned); |
1585 generate_disjoint_long_copy_core(aligned); |
1599 __ mov(G4, count); // restore |
1586 __ mov(G4, count); // restore |
1600 |
1587 |
1601 // copy 1 element at a time |
1588 // copy 1 element at a time |
1602 __ BIND(L_copy_2_bytes); |
1589 __ BIND(L_copy_2_bytes); |
1603 __ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit); |
1590 __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit); |
1604 __ delayed()->nop(); |
|
1605 __ align(OptoLoopAlignment); |
1591 __ align(OptoLoopAlignment); |
1606 __ BIND(L_copy_2_bytes_loop); |
1592 __ BIND(L_copy_2_bytes_loop); |
1607 __ lduh(from, offset, O3); |
1593 __ lduh(from, offset, O3); |
1608 __ deccc(count); |
1594 __ deccc(count); |
1609 __ sth(O3, to, offset); |
1595 __ sth(O3, to, offset); |
1944 __ delayed()->stx(O4, end_to, 0); |
1930 __ delayed()->stx(O4, end_to, 0); |
1945 __ inc(count, 8); |
1931 __ inc(count, 8); |
1946 |
1932 |
1947 // copy 1 element (2 bytes) at a time |
1933 // copy 1 element (2 bytes) at a time |
1948 __ BIND(L_copy_2_bytes); |
1934 __ BIND(L_copy_2_bytes); |
1949 __ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit); |
1935 __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit); |
1950 __ delayed()->nop(); |
|
1951 __ BIND(L_copy_2_bytes_loop); |
1936 __ BIND(L_copy_2_bytes_loop); |
1952 __ dec(end_from, 2); |
1937 __ dec(end_from, 2); |
1953 __ dec(end_to, 2); |
1938 __ dec(end_to, 2); |
1954 __ lduh(end_from, 0, O4); |
1939 __ lduh(end_from, 0, O4); |
1955 __ deccc(count); |
1940 __ deccc(count); |
2058 generate_disjoint_long_copy_core(aligned); |
2043 generate_disjoint_long_copy_core(aligned); |
2059 __ mov(G4, count); // Restore |
2044 __ mov(G4, count); // Restore |
2060 |
2045 |
2061 // copy 1 element at a time |
2046 // copy 1 element at a time |
2062 __ BIND(L_copy_4_bytes); |
2047 __ BIND(L_copy_4_bytes); |
2063 __ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit); |
2048 __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit); |
2064 __ delayed()->nop(); |
|
2065 __ BIND(L_copy_4_bytes_loop); |
2049 __ BIND(L_copy_4_bytes_loop); |
2066 __ ld(from, offset, O3); |
2050 __ ld(from, offset, O3); |
2067 __ deccc(count); |
2051 __ deccc(count); |
2068 __ st(O3, to, offset); |
2052 __ st(O3, to, offset); |
2069 __ brx(Assembler::notZero, false, Assembler::pt, L_copy_4_bytes_loop); |
2053 __ brx(Assembler::notZero, false, Assembler::pt, L_copy_4_bytes_loop); |
2191 __ delayed()->stx(O4, end_to, 0); |
2175 __ delayed()->stx(O4, end_to, 0); |
2192 __ inc(count, 4); |
2176 __ inc(count, 4); |
2193 |
2177 |
2194 // copy 1 element (4 bytes) at a time |
2178 // copy 1 element (4 bytes) at a time |
2195 __ BIND(L_copy_4_bytes); |
2179 __ BIND(L_copy_4_bytes); |
2196 __ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit); |
2180 __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit); |
2197 __ delayed()->nop(); |
|
2198 __ BIND(L_copy_4_bytes_loop); |
2181 __ BIND(L_copy_4_bytes_loop); |
2199 __ dec(end_from, 4); |
2182 __ dec(end_from, 4); |
2200 __ dec(end_to, 4); |
2183 __ dec(end_to, 4); |
2201 __ ld(end_from, 0, O4); |
2184 __ ld(end_from, 0, O4); |
2202 __ deccc(count); |
2185 __ deccc(count); |
2574 __ save_frame(0); |
2557 __ save_frame(0); |
2575 __ check_klass_subtype_slow_path(sub_klass->after_save(), |
2558 __ check_klass_subtype_slow_path(sub_klass->after_save(), |
2576 super_klass->after_save(), |
2559 super_klass->after_save(), |
2577 L0, L1, L2, L4, |
2560 L0, L1, L2, L4, |
2578 NULL, &L_pop_to_miss); |
2561 NULL, &L_pop_to_miss); |
2579 __ ba(false, L_success); |
2562 __ ba(L_success); |
2580 __ delayed()->restore(); |
2563 __ delayed()->restore(); |
2581 |
2564 |
2582 __ bind(L_pop_to_miss); |
2565 __ bind(L_pop_to_miss); |
2583 __ restore(); |
2566 __ restore(); |
2584 |
2567 |
2671 __ delayed()->set(0, O0); // return -1 on success |
2654 __ delayed()->set(0, O0); // return -1 on success |
2672 |
2655 |
2673 // ======== loop entry is here ======== |
2656 // ======== loop entry is here ======== |
2674 __ BIND(load_element); |
2657 __ BIND(load_element); |
2675 __ load_heap_oop(O0_from, O5_offset, G3_oop); // load the oop |
2658 __ load_heap_oop(O0_from, O5_offset, G3_oop); // load the oop |
2676 __ br_null(G3_oop, true, Assembler::pt, store_element); |
2659 __ br_null_short(G3_oop, Assembler::pt, store_element); |
2677 __ delayed()->nop(); |
|
2678 |
2660 |
2679 __ load_klass(G3_oop, G4_klass); // query the object klass |
2661 __ load_klass(G3_oop, G4_klass); // query the object klass |
2680 |
2662 |
2681 generate_type_check(G4_klass, O3_ckoff, O4_ckval, G5_super, |
2663 generate_type_check(G4_klass, O3_ckoff, O4_ckval, G5_super, |
2682 // branch to this on success: |
2664 // branch to this on success: |
2894 |
2876 |
2895 #ifdef ASSERT |
2877 #ifdef ASSERT |
2896 // assert(src->klass() != NULL); |
2878 // assert(src->klass() != NULL); |
2897 BLOCK_COMMENT("assert klasses not null"); |
2879 BLOCK_COMMENT("assert klasses not null"); |
2898 { Label L_a, L_b; |
2880 { Label L_a, L_b; |
2899 __ br_notnull(G3_src_klass, false, Assembler::pt, L_b); // it is broken if klass is NULL |
2881 __ br_notnull_short(G3_src_klass, Assembler::pt, L_b); // it is broken if klass is NULL |
2900 __ delayed()->nop(); |
|
2901 __ bind(L_a); |
2882 __ bind(L_a); |
2902 __ stop("broken null klass"); |
2883 __ stop("broken null klass"); |
2903 __ bind(L_b); |
2884 __ bind(L_b); |
2904 __ load_klass(dst, G4_dst_klass); |
2885 __ load_klass(dst, G4_dst_klass); |
2905 __ br_null(G4_dst_klass, false, Assembler::pn, L_a); // this would be broken also |
2886 __ br_null(G4_dst_klass, false, Assembler::pn, L_a); // this would be broken also |
2935 } else { |
2916 } else { |
2936 __ delayed()->ld_ptr(dst, oopDesc::klass_offset_in_bytes(), G4_dst_klass); |
2917 __ delayed()->ld_ptr(dst, oopDesc::klass_offset_in_bytes(), G4_dst_klass); |
2937 } |
2918 } |
2938 |
2919 |
2939 // if (src->klass() != dst->klass()) return -1; |
2920 // if (src->klass() != dst->klass()) return -1; |
2940 __ cmp(G3_src_klass, G4_dst_klass); |
2921 __ cmp_and_brx_short(G3_src_klass, G4_dst_klass, Assembler::notEqual, Assembler::pn, L_failed); |
2941 __ brx(Assembler::notEqual, false, Assembler::pn, L_failed); |
|
2942 __ delayed()->nop(); |
|
2943 |
2922 |
2944 // if (!src->is_Array()) return -1; |
2923 // if (!src->is_Array()) return -1; |
2945 __ cmp(G5_lh, Klass::_lh_neutral_value); // < 0 |
2924 __ cmp(G5_lh, Klass::_lh_neutral_value); // < 0 |
2946 __ br(Assembler::greaterEqual, false, Assembler::pn, L_failed); |
2925 __ br(Assembler::greaterEqual, false, Assembler::pn, L_failed); |
2947 |
2926 |
3005 __ cmp(G3_elsize, LogBytesPerInt); |
2984 __ cmp(G3_elsize, LogBytesPerInt); |
3006 __ br(Assembler::equal, true, Assembler::pt, entry_jint_arraycopy); |
2985 __ br(Assembler::equal, true, Assembler::pt, entry_jint_arraycopy); |
3007 __ delayed()->signx(length, count); // length |
2986 __ delayed()->signx(length, count); // length |
3008 #ifdef ASSERT |
2987 #ifdef ASSERT |
3009 { Label L; |
2988 { Label L; |
3010 __ cmp(G3_elsize, LogBytesPerLong); |
2989 __ cmp_and_br_short(G3_elsize, LogBytesPerLong, Assembler::equal, Assembler::pt, L); |
3011 __ br(Assembler::equal, false, Assembler::pt, L); |
|
3012 __ delayed()->nop(); |
|
3013 __ stop("must be long copy, but elsize is wrong"); |
2990 __ stop("must be long copy, but elsize is wrong"); |
3014 __ bind(L); |
2991 __ bind(L); |
3015 } |
2992 } |
3016 #endif |
2993 #endif |
3017 __ br(Assembler::always, false, Assembler::pt, entry_jlong_arraycopy); |
2994 __ br(Assembler::always, false, Assembler::pt, entry_jlong_arraycopy); |