285 |
285 |
286 Label L_ok_1, L_ok_2, L_ok_3, L_ok_4; |
286 Label L_ok_1, L_ok_2, L_ok_3, L_ok_4; |
287 BLOCK_COMMENT("verify_clean {"); |
287 BLOCK_COMMENT("verify_clean {"); |
288 // Magic numbers must check out: |
288 // Magic numbers must check out: |
289 __ set((int32_t) MAGIC_NUMBER_1, O7_temp); |
289 __ set((int32_t) MAGIC_NUMBER_1, O7_temp); |
290 __ cmp(O7_temp, L0_magic_number_1); |
290 __ cmp_and_br_short(O7_temp, L0_magic_number_1, Assembler::equal, Assembler::pt, L_ok_1); |
291 __ br(Assembler::equal, false, Assembler::pt, L_ok_1); |
|
292 __ delayed()->nop(); |
|
293 __ stop("damaged ricochet frame: MAGIC_NUMBER_1 not found"); |
291 __ stop("damaged ricochet frame: MAGIC_NUMBER_1 not found"); |
294 |
292 |
295 __ BIND(L_ok_1); |
293 __ BIND(L_ok_1); |
296 |
294 |
297 // Arguments pointer must look reasonable: |
295 // Arguments pointer must look reasonable: |
299 Register FP_temp = O5_temp; |
297 Register FP_temp = O5_temp; |
300 __ add(FP, STACK_BIAS, FP_temp); |
298 __ add(FP, STACK_BIAS, FP_temp); |
301 #else |
299 #else |
302 Register FP_temp = FP; |
300 Register FP_temp = FP; |
303 #endif |
301 #endif |
304 __ cmp(L4_saved_args_base, FP_temp); |
302 __ cmp_and_brx_short(L4_saved_args_base, FP_temp, Assembler::greaterEqualUnsigned, Assembler::pt, L_ok_2); |
305 __ br(Assembler::greaterEqualUnsigned, false, Assembler::pt, L_ok_2); |
|
306 __ delayed()->nop(); |
|
307 __ stop("damaged ricochet frame: L4 < FP"); |
303 __ stop("damaged ricochet frame: L4 < FP"); |
308 |
304 |
309 __ BIND(L_ok_2); |
305 __ BIND(L_ok_2); |
310 // Disable until we decide on it's fate |
306 // Disable until we decide on it's fate |
311 // __ sub(L4_saved_args_base, UNREASONABLE_STACK_MOVE * Interpreter::stackElementSize, O7_temp); |
307 // __ sub(L4_saved_args_base, UNREASONABLE_STACK_MOVE * Interpreter::stackElementSize, O7_temp); |
314 // __ delayed()->nop(); |
310 // __ delayed()->nop(); |
315 // __ stop("damaged ricochet frame: (L4 - UNREASONABLE_STACK_MOVE) > FP"); |
311 // __ stop("damaged ricochet frame: (L4 - UNREASONABLE_STACK_MOVE) > FP"); |
316 |
312 |
317 __ BIND(L_ok_3); |
313 __ BIND(L_ok_3); |
318 extract_conversion_dest_type(_masm, L5_conversion, O7_temp); |
314 extract_conversion_dest_type(_masm, L5_conversion, O7_temp); |
319 __ cmp(O7_temp, T_VOID); |
315 __ cmp_and_br_short(O7_temp, T_VOID, Assembler::equal, Assembler::pt, L_ok_4); |
320 __ br(Assembler::equal, false, Assembler::pt, L_ok_4); |
|
321 __ delayed()->nop(); |
|
322 extract_conversion_vminfo(_masm, L5_conversion, O5_temp); |
316 extract_conversion_vminfo(_masm, L5_conversion, O5_temp); |
323 __ ld_ptr(L4_saved_args_base, __ argument_offset(O5_temp, O5_temp), O7_temp); |
317 __ ld_ptr(L4_saved_args_base, __ argument_offset(O5_temp, O5_temp), O7_temp); |
324 assert(__ is_simm13(RETURN_VALUE_PLACEHOLDER), "must be simm13"); |
318 assert(__ is_simm13(RETURN_VALUE_PLACEHOLDER), "must be simm13"); |
325 __ cmp(O7_temp, (int32_t) RETURN_VALUE_PLACEHOLDER); |
319 __ cmp_and_brx_short(O7_temp, (int32_t) RETURN_VALUE_PLACEHOLDER, Assembler::equal, Assembler::pt, L_ok_4); |
326 __ brx(Assembler::equal, false, Assembler::pt, L_ok_4); |
|
327 __ delayed()->nop(); |
|
328 __ stop("damaged ricochet frame: RETURN_VALUE_PLACEHOLDER not found"); |
320 __ stop("damaged ricochet frame: RETURN_VALUE_PLACEHOLDER not found"); |
329 __ BIND(L_ok_4); |
321 __ BIND(L_ok_4); |
330 BLOCK_COMMENT("} verify_clean"); |
322 BLOCK_COMMENT("} verify_clean"); |
331 } |
323 } |
332 #endif //ASSERT |
324 #endif //ASSERT |
361 __ ldsw(G3_amh_conversion, stack_move_reg); |
353 __ ldsw(G3_amh_conversion, stack_move_reg); |
362 __ sra(stack_move_reg, CONV_STACK_MOVE_SHIFT, stack_move_reg); |
354 __ sra(stack_move_reg, CONV_STACK_MOVE_SHIFT, stack_move_reg); |
363 if (VerifyMethodHandles) { |
355 if (VerifyMethodHandles) { |
364 Label L_ok, L_bad; |
356 Label L_ok, L_bad; |
365 int32_t stack_move_limit = 0x0800; // extra-large |
357 int32_t stack_move_limit = 0x0800; // extra-large |
366 __ cmp(stack_move_reg, stack_move_limit); |
358 __ cmp_and_br_short(stack_move_reg, stack_move_limit, Assembler::greaterEqual, Assembler::pn, L_bad); |
367 __ br(Assembler::greaterEqual, false, Assembler::pn, L_bad); |
|
368 __ delayed()->nop(); |
|
369 __ cmp(stack_move_reg, -stack_move_limit); |
359 __ cmp(stack_move_reg, -stack_move_limit); |
370 __ br(Assembler::greater, false, Assembler::pt, L_ok); |
360 __ br(Assembler::greater, false, Assembler::pt, L_ok); |
371 __ delayed()->nop(); |
361 __ delayed()->nop(); |
372 __ BIND(L_bad); |
362 __ BIND(L_bad); |
373 __ stop("load_stack_move of garbage value"); |
363 __ stop("load_stack_move of garbage value"); |
399 |
389 |
400 void MethodHandles::verify_argslot(MacroAssembler* _masm, Register argslot_reg, Register temp_reg, const char* error_message) { |
390 void MethodHandles::verify_argslot(MacroAssembler* _masm, Register argslot_reg, Register temp_reg, const char* error_message) { |
401 // Verify that argslot lies within (Gargs, FP]. |
391 // Verify that argslot lies within (Gargs, FP]. |
402 Label L_ok, L_bad; |
392 Label L_ok, L_bad; |
403 BLOCK_COMMENT("verify_argslot {"); |
393 BLOCK_COMMENT("verify_argslot {"); |
|
394 __ cmp_and_brx_short(Gargs, argslot_reg, Assembler::greaterUnsigned, Assembler::pn, L_bad); |
404 __ add(FP, STACK_BIAS, temp_reg); // STACK_BIAS is zero on !_LP64 |
395 __ add(FP, STACK_BIAS, temp_reg); // STACK_BIAS is zero on !_LP64 |
405 __ cmp(argslot_reg, temp_reg); |
396 __ cmp_and_brx_short(argslot_reg, temp_reg, Assembler::lessEqualUnsigned, Assembler::pt, L_ok); |
406 __ brx(Assembler::greaterUnsigned, false, Assembler::pn, L_bad); |
|
407 __ delayed()->nop(); |
|
408 __ cmp(Gargs, argslot_reg); |
|
409 __ brx(Assembler::lessEqualUnsigned, false, Assembler::pt, L_ok); |
|
410 __ delayed()->nop(); |
|
411 __ BIND(L_bad); |
397 __ BIND(L_bad); |
412 __ stop(error_message); |
398 __ stop(error_message); |
413 __ BIND(L_ok); |
399 __ BIND(L_ok); |
414 BLOCK_COMMENT("} verify_argslot"); |
400 BLOCK_COMMENT("} verify_argslot"); |
415 } |
401 } |
432 arg_slots = temp_reg; |
418 arg_slots = temp_reg; |
433 } |
419 } |
434 } |
420 } |
435 __ add(arg_slot_base_reg, __ argument_offset(arg_slots, temp_reg), temp_reg); |
421 __ add(arg_slot_base_reg, __ argument_offset(arg_slots, temp_reg), temp_reg); |
436 __ add(FP, STACK_BIAS, temp2_reg); // STACK_BIAS is zero on !_LP64 |
422 __ add(FP, STACK_BIAS, temp2_reg); // STACK_BIAS is zero on !_LP64 |
437 __ cmp(temp_reg, temp2_reg); |
423 __ cmp_and_brx_short(temp_reg, temp2_reg, Assembler::greaterUnsigned, Assembler::pn, L_bad); |
438 __ brx(Assembler::greaterUnsigned, false, Assembler::pn, L_bad); |
|
439 __ delayed()->nop(); |
|
440 // Gargs points to the first word so adjust by BytesPerWord |
424 // Gargs points to the first word so adjust by BytesPerWord |
441 __ add(arg_slot_base_reg, BytesPerWord, temp_reg); |
425 __ add(arg_slot_base_reg, BytesPerWord, temp_reg); |
442 __ cmp(Gargs, temp_reg); |
426 __ cmp_and_brx_short(Gargs, temp_reg, Assembler::lessEqualUnsigned, Assembler::pt, L_ok); |
443 __ brx(Assembler::lessEqualUnsigned, false, Assembler::pt, L_ok); |
|
444 __ delayed()->nop(); |
|
445 __ BIND(L_bad); |
427 __ BIND(L_bad); |
446 __ stop(error_message); |
428 __ stop(error_message); |
447 __ BIND(L_ok); |
429 __ BIND(L_ok); |
448 BLOCK_COMMENT("} verify_argslots"); |
430 BLOCK_COMMENT("} verify_argslots"); |
449 } |
431 } |
500 klass_addr <= SystemDictionaryHandles::Long_klass().raw_value(), |
482 klass_addr <= SystemDictionaryHandles::Long_klass().raw_value(), |
501 "must be one of the SystemDictionaryHandles"); |
483 "must be one of the SystemDictionaryHandles"); |
502 Label L_ok, L_bad; |
484 Label L_ok, L_bad; |
503 BLOCK_COMMENT("verify_klass {"); |
485 BLOCK_COMMENT("verify_klass {"); |
504 __ verify_oop(obj_reg); |
486 __ verify_oop(obj_reg); |
505 __ br_null(obj_reg, false, Assembler::pn, L_bad); |
487 __ br_null_short(obj_reg, Assembler::pn, L_bad); |
506 __ delayed()->nop(); |
|
507 __ load_klass(obj_reg, temp_reg); |
488 __ load_klass(obj_reg, temp_reg); |
508 __ set(ExternalAddress(klass_addr), temp2_reg); |
489 __ set(ExternalAddress(klass_addr), temp2_reg); |
509 __ ld_ptr(Address(temp2_reg, 0), temp2_reg); |
490 __ ld_ptr(Address(temp2_reg, 0), temp2_reg); |
510 __ cmp(temp_reg, temp2_reg); |
491 __ cmp_and_brx_short(temp_reg, temp2_reg, Assembler::equal, Assembler::pt, L_ok); |
511 __ brx(Assembler::equal, false, Assembler::pt, L_ok); |
|
512 __ delayed()->nop(); |
|
513 intptr_t super_check_offset = klass->super_check_offset(); |
492 intptr_t super_check_offset = klass->super_check_offset(); |
514 __ ld_ptr(Address(temp_reg, super_check_offset), temp_reg); |
493 __ ld_ptr(Address(temp_reg, super_check_offset), temp_reg); |
515 __ set(ExternalAddress(klass_addr), temp2_reg); |
494 __ set(ExternalAddress(klass_addr), temp2_reg); |
516 __ ld_ptr(Address(temp2_reg, 0), temp2_reg); |
495 __ ld_ptr(Address(temp2_reg, 0), temp2_reg); |
517 __ cmp(temp_reg, temp2_reg); |
496 __ cmp_and_brx_short(temp_reg, temp2_reg, Assembler::equal, Assembler::pt, L_ok); |
518 __ brx(Assembler::equal, false, Assembler::pt, L_ok); |
|
519 __ delayed()->nop(); |
|
520 __ BIND(L_bad); |
497 __ BIND(L_bad); |
521 __ stop(error_message); |
498 __ stop(error_message); |
522 __ BIND(L_ok); |
499 __ BIND(L_ok); |
523 BLOCK_COMMENT("} verify_klass"); |
500 BLOCK_COMMENT("} verify_klass"); |
524 } |
501 } |
669 return offset; |
646 return offset; |
670 } else { |
647 } else { |
671 #ifdef ASSERT |
648 #ifdef ASSERT |
672 { |
649 { |
673 Label L_ok; |
650 Label L_ok; |
674 __ cmp(arg_slots.as_register(), 0); |
651 __ cmp_and_br_short(arg_slots.as_register(), 0, Assembler::greaterEqual, Assembler::pt, L_ok); |
675 __ br(Assembler::greaterEqual, false, Assembler::pt, L_ok); |
|
676 __ delayed()->nop(); |
|
677 __ stop("negative arg_slots"); |
652 __ stop("negative arg_slots"); |
678 __ bind(L_ok); |
653 __ bind(L_ok); |
679 } |
654 } |
680 #endif |
655 #endif |
681 __ sll_ptr(arg_slots.as_register(), LogBytesPerWord, temp_reg); |
656 __ sll_ptr(arg_slots.as_register(), LogBytesPerWord, temp_reg); |
746 __ BIND(loop); |
721 __ BIND(loop); |
747 // pull one word down each time through the loop |
722 // pull one word down each time through the loop |
748 __ ld_ptr( Address(temp_reg, 0 ), temp2_reg); |
723 __ ld_ptr( Address(temp_reg, 0 ), temp2_reg); |
749 __ st_ptr(temp2_reg, Address(temp_reg, offset) ); |
724 __ st_ptr(temp2_reg, Address(temp_reg, offset) ); |
750 __ add(temp_reg, wordSize, temp_reg); |
725 __ add(temp_reg, wordSize, temp_reg); |
751 __ cmp(temp_reg, argslot_reg); |
726 __ cmp_and_brx_short(temp_reg, argslot_reg, Assembler::lessUnsigned, Assembler::pt, loop); |
752 __ brx(Assembler::lessUnsigned, false, Assembler::pt, loop); |
|
753 __ delayed()->nop(); // FILLME |
|
754 } |
727 } |
755 |
728 |
756 // Now move the argslot down, to point to the opened-up space. |
729 // Now move the argslot down, to point to the opened-up space. |
757 __ add(argslot_reg, offset, argslot_reg); |
730 __ add(argslot_reg, offset, argslot_reg); |
758 BLOCK_COMMENT("} insert_arg_slots"); |
731 BLOCK_COMMENT("} insert_arg_slots"); |
795 __ BIND(L_loop); |
768 __ BIND(L_loop); |
796 // pull one word up each time through the loop |
769 // pull one word up each time through the loop |
797 __ ld_ptr( Address(temp_reg, 0 ), temp2_reg); |
770 __ ld_ptr( Address(temp_reg, 0 ), temp2_reg); |
798 __ st_ptr(temp2_reg, Address(temp_reg, offset) ); |
771 __ st_ptr(temp2_reg, Address(temp_reg, offset) ); |
799 __ sub(temp_reg, wordSize, temp_reg); |
772 __ sub(temp_reg, wordSize, temp_reg); |
800 __ cmp(temp_reg, Gargs); |
773 __ cmp_and_brx_short(temp_reg, Gargs, Assembler::greaterEqualUnsigned, Assembler::pt, L_loop); |
801 __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, L_loop); |
|
802 __ delayed()->nop(); // FILLME |
|
803 } |
774 } |
804 |
775 |
805 // And adjust the argslot address to point at the deletion point. |
776 // And adjust the argslot address to point at the deletion point. |
806 __ add(argslot_reg, offset, argslot_reg); |
777 __ add(argslot_reg, offset, argslot_reg); |
807 |
778 |
846 __ delayed()->nop(); |
817 __ delayed()->nop(); |
847 __ br(Assembler::less, false, Assembler::pn, L_break); |
818 __ br(Assembler::less, false, Assembler::pn, L_break); |
848 __ delayed()->nop(); |
819 __ delayed()->nop(); |
849 __ ld_ptr( Address(argslot_reg, 0), temp_reg); |
820 __ ld_ptr( Address(argslot_reg, 0), temp_reg); |
850 __ st_ptr(temp_reg, Address(Gargs, 0)); |
821 __ st_ptr(temp_reg, Address(Gargs, 0)); |
851 __ ba(false, L_break); |
822 __ ba_short(L_break); |
852 __ delayed()->nop(); // FILLME |
|
853 __ BIND(L_plural); |
823 __ BIND(L_plural); |
854 |
824 |
855 // Loop for 2 or more: |
825 // Loop for 2 or more: |
856 // top = &argslot[slot_count] |
826 // top = &argslot[slot_count] |
857 // while (top > argslot) *(--Gargs) = *(--top) |
827 // while (top > argslot) *(--Gargs) = *(--top) |
861 __ BIND(L_loop); |
831 __ BIND(L_loop); |
862 __ sub(top_reg, wordSize, top_reg); |
832 __ sub(top_reg, wordSize, top_reg); |
863 __ sub(Gargs, wordSize, Gargs ); |
833 __ sub(Gargs, wordSize, Gargs ); |
864 __ ld_ptr( Address(top_reg, 0), temp2_reg); |
834 __ ld_ptr( Address(top_reg, 0), temp2_reg); |
865 __ st_ptr(temp2_reg, Address(Gargs, 0)); |
835 __ st_ptr(temp2_reg, Address(Gargs, 0)); |
866 __ cmp(top_reg, argslot_reg); |
836 __ cmp_and_brx_short(top_reg, argslot_reg, Assembler::greaterUnsigned, Assembler::pt, L_loop); |
867 __ brx(Assembler::greaterUnsigned, false, Assembler::pt, L_loop); |
|
868 __ delayed()->nop(); // FILLME |
|
869 __ BIND(L_break); |
837 __ BIND(L_break); |
870 } |
838 } |
871 BLOCK_COMMENT("} push_arg_slots"); |
839 BLOCK_COMMENT("} push_arg_slots"); |
872 } |
840 } |
873 |
841 |
895 if (positive_distance_in_slots.is_register()) { |
863 if (positive_distance_in_slots.is_register()) { |
896 __ cmp(positive_distance_in_slots.as_register(), (int32_t) 0); |
864 __ cmp(positive_distance_in_slots.as_register(), (int32_t) 0); |
897 __ br(Assembler::lessEqual, false, Assembler::pn, L_bad); |
865 __ br(Assembler::lessEqual, false, Assembler::pn, L_bad); |
898 __ delayed()->nop(); |
866 __ delayed()->nop(); |
899 } |
867 } |
900 __ cmp(bottom_reg, top_reg); |
868 __ cmp_and_brx_short(bottom_reg, top_reg, Assembler::lessUnsigned, Assembler::pt, L_ok); |
901 __ brx(Assembler::lessUnsigned, false, Assembler::pt, L_ok); |
|
902 __ delayed()->nop(); |
|
903 __ BIND(L_bad); |
869 __ BIND(L_bad); |
904 __ stop("valid bounds (copy up)"); |
870 __ stop("valid bounds (copy up)"); |
905 __ BIND(L_ok); |
871 __ BIND(L_ok); |
906 } |
872 } |
907 #endif |
873 #endif |
908 __ cmp(bottom_reg, top_reg); |
874 __ cmp_and_brx_short(bottom_reg, top_reg, Assembler::greaterEqualUnsigned, Assembler::pn, L_break); |
909 __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pn, L_break); |
|
910 __ delayed()->nop(); |
|
911 // work top down to bottom, copying contiguous data upwards |
875 // work top down to bottom, copying contiguous data upwards |
912 // In pseudo-code: |
876 // In pseudo-code: |
913 // while (--top >= bottom) *(top + distance) = *(top + 0); |
877 // while (--top >= bottom) *(top + distance) = *(top + 0); |
914 RegisterOrConstant offset = __ argument_offset(positive_distance_in_slots, positive_distance_in_slots.register_or_noreg()); |
878 RegisterOrConstant offset = __ argument_offset(positive_distance_in_slots, positive_distance_in_slots.register_or_noreg()); |
915 __ BIND(L_loop); |
879 __ BIND(L_loop); |
916 __ sub(top_reg, wordSize, top_reg); |
880 __ sub(top_reg, wordSize, top_reg); |
917 __ ld_ptr( Address(top_reg, 0 ), temp2_reg); |
881 __ ld_ptr( Address(top_reg, 0 ), temp2_reg); |
918 __ st_ptr(temp2_reg, Address(top_reg, offset) ); |
882 __ st_ptr(temp2_reg, Address(top_reg, offset) ); |
919 __ cmp(top_reg, bottom_reg); |
883 __ cmp_and_brx_short(top_reg, bottom_reg, Assembler::greaterUnsigned, Assembler::pt, L_loop); |
920 __ brx(Assembler::greaterUnsigned, false, Assembler::pt, L_loop); |
|
921 __ delayed()->nop(); // FILLME |
|
922 assert(Interpreter::stackElementSize == wordSize, "else change loop"); |
884 assert(Interpreter::stackElementSize == wordSize, "else change loop"); |
923 __ BIND(L_break); |
885 __ BIND(L_break); |
924 BLOCK_COMMENT("} move_arg_slots_up"); |
886 BLOCK_COMMENT("} move_arg_slots_up"); |
925 } |
887 } |
926 |
888 |
949 if (negative_distance_in_slots.is_register()) { |
911 if (negative_distance_in_slots.is_register()) { |
950 __ cmp(negative_distance_in_slots.as_register(), (int32_t) 0); |
912 __ cmp(negative_distance_in_slots.as_register(), (int32_t) 0); |
951 __ br(Assembler::greaterEqual, false, Assembler::pn, L_bad); |
913 __ br(Assembler::greaterEqual, false, Assembler::pn, L_bad); |
952 __ delayed()->nop(); |
914 __ delayed()->nop(); |
953 } |
915 } |
954 __ cmp(bottom_reg, top_reg); |
916 __ cmp_and_brx_short(bottom_reg, top_reg, Assembler::lessUnsigned, Assembler::pt, L_ok); |
955 __ brx(Assembler::lessUnsigned, false, Assembler::pt, L_ok); |
|
956 __ delayed()->nop(); |
|
957 __ BIND(L_bad); |
917 __ BIND(L_bad); |
958 __ stop("valid bounds (copy down)"); |
918 __ stop("valid bounds (copy down)"); |
959 __ BIND(L_ok); |
919 __ BIND(L_ok); |
960 } |
920 } |
961 #endif |
921 #endif |
962 __ cmp(bottom_reg, top_reg); |
922 __ cmp_and_brx_short(bottom_reg, top_reg, Assembler::greaterEqualUnsigned, Assembler::pn, L_break); |
963 __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pn, L_break); |
|
964 __ delayed()->nop(); |
|
965 // work bottom up to top, copying contiguous data downwards |
923 // work bottom up to top, copying contiguous data downwards |
966 // In pseudo-code: |
924 // In pseudo-code: |
967 // while (bottom < top) *(bottom - distance) = *(bottom + 0), bottom++; |
925 // while (bottom < top) *(bottom - distance) = *(bottom + 0), bottom++; |
968 RegisterOrConstant offset = __ argument_offset(negative_distance_in_slots, negative_distance_in_slots.register_or_noreg()); |
926 RegisterOrConstant offset = __ argument_offset(negative_distance_in_slots, negative_distance_in_slots.register_or_noreg()); |
969 __ BIND(L_loop); |
927 __ BIND(L_loop); |
970 __ ld_ptr( Address(bottom_reg, 0 ), temp2_reg); |
928 __ ld_ptr( Address(bottom_reg, 0 ), temp2_reg); |
971 __ st_ptr(temp2_reg, Address(bottom_reg, offset) ); |
929 __ st_ptr(temp2_reg, Address(bottom_reg, offset) ); |
972 __ add(bottom_reg, wordSize, bottom_reg); |
930 __ add(bottom_reg, wordSize, bottom_reg); |
973 __ cmp(bottom_reg, top_reg); |
931 __ cmp_and_brx_short(bottom_reg, top_reg, Assembler::lessUnsigned, Assembler::pt, L_loop); |
974 __ brx(Assembler::lessUnsigned, false, Assembler::pt, L_loop); |
|
975 __ delayed()->nop(); // FILLME |
|
976 assert(Interpreter::stackElementSize == wordSize, "else change loop"); |
932 assert(Interpreter::stackElementSize == wordSize, "else change loop"); |
977 __ BIND(L_break); |
933 __ BIND(L_break); |
978 BLOCK_COMMENT("} move_arg_slots_down"); |
934 BLOCK_COMMENT("} move_arg_slots_down"); |
979 } |
935 } |
980 |
936 |
1327 __ load_heap_oop(G3_amh_argument, O1_klass); // This is a Class object! |
1283 __ load_heap_oop(G3_amh_argument, O1_klass); // This is a Class object! |
1328 load_klass_from_Class(_masm, O1_klass, O2_scratch, O3_scratch); |
1284 load_klass_from_Class(_masm, O1_klass, O2_scratch, O3_scratch); |
1329 |
1285 |
1330 Label L_done; |
1286 Label L_done; |
1331 __ ld_ptr(vmarg, O2_scratch); |
1287 __ ld_ptr(vmarg, O2_scratch); |
1332 __ tst(O2_scratch); |
1288 __ br_null_short(O2_scratch, Assembler::pn, L_done); // No cast if null. |
1333 __ brx(Assembler::zero, false, Assembler::pn, L_done); // No cast if null. |
|
1334 __ delayed()->nop(); |
|
1335 __ load_klass(O2_scratch, O2_scratch); |
1289 __ load_klass(O2_scratch, O2_scratch); |
1336 |
1290 |
1337 // Live at this point: |
1291 // Live at this point: |
1338 // - O0_argslot : argslot index in vmarg; may be required in the failing path |
1292 // - O0_argslot : argslot index in vmarg; may be required in the failing path |
1339 // - O1_klass : klass required by the target method |
1293 // - O1_klass : klass required by the target method |
1434 __ br(Assembler::zero, false, Assembler::pn, zero_extend); |
1388 __ br(Assembler::zero, false, Assembler::pn, zero_extend); |
1435 __ delayed()->nop(); |
1389 __ delayed()->nop(); |
1436 |
1390 |
1437 // this path is taken for int->byte, int->short |
1391 // this path is taken for int->byte, int->short |
1438 __ sra(O1_scratch, G5_vminfo, O1_scratch); |
1392 __ sra(O1_scratch, G5_vminfo, O1_scratch); |
1439 __ ba(false, done); |
1393 __ ba_short(done); |
1440 __ delayed()->nop(); |
|
1441 |
1394 |
1442 __ bind(zero_extend); |
1395 __ bind(zero_extend); |
1443 // this is taken for int->char |
1396 // this is taken for int->char |
1444 __ srl(O1_scratch, G5_vminfo, O1_scratch); |
1397 __ srl(O1_scratch, G5_vminfo, O1_scratch); |
1445 |
1398 |
1858 #ifdef ASSERT |
1811 #ifdef ASSERT |
1859 if (VerifyMethodHandles) { |
1812 if (VerifyMethodHandles) { |
1860 BLOCK_COMMENT("verify collect_count_constant {"); |
1813 BLOCK_COMMENT("verify collect_count_constant {"); |
1861 __ load_method_handle_vmslots(O3_scratch, G3_method_handle, O2_scratch); |
1814 __ load_method_handle_vmslots(O3_scratch, G3_method_handle, O2_scratch); |
1862 Label L_count_ok; |
1815 Label L_count_ok; |
1863 __ cmp(O3_scratch, collect_count_constant); |
1816 __ cmp_and_br_short(O3_scratch, collect_count_constant, Assembler::equal, Assembler::pt, L_count_ok); |
1864 __ br(Assembler::equal, false, Assembler::pt, L_count_ok); |
|
1865 __ delayed()->nop(); |
|
1866 __ stop("bad vminfo in AMH.conv"); |
1817 __ stop("bad vminfo in AMH.conv"); |
1867 __ BIND(L_count_ok); |
1818 __ BIND(L_count_ok); |
1868 BLOCK_COMMENT("} verify collect_count_constant"); |
1819 BLOCK_COMMENT("} verify collect_count_constant"); |
1869 } |
1820 } |
1870 #endif //ASSERT |
1821 #endif //ASSERT |
1907 #ifdef ASSERT |
1858 #ifdef ASSERT |
1908 if (VerifyMethodHandles && dest_slot_constant < 0) { |
1859 if (VerifyMethodHandles && dest_slot_constant < 0) { |
1909 BLOCK_COMMENT("verify dest_slot_constant {"); |
1860 BLOCK_COMMENT("verify dest_slot_constant {"); |
1910 extract_conversion_vminfo(_masm, RicochetFrame::L5_conversion, O3_scratch); |
1861 extract_conversion_vminfo(_masm, RicochetFrame::L5_conversion, O3_scratch); |
1911 Label L_vminfo_ok; |
1862 Label L_vminfo_ok; |
1912 __ cmp(O3_scratch, dest_slot_constant); |
1863 __ cmp_and_br_short(O3_scratch, dest_slot_constant, Assembler::equal, Assembler::pt, L_vminfo_ok); |
1913 __ br(Assembler::equal, false, Assembler::pt, L_vminfo_ok); |
|
1914 __ delayed()->nop(); |
|
1915 __ stop("bad vminfo in AMH.conv"); |
1864 __ stop("bad vminfo in AMH.conv"); |
1916 __ BIND(L_vminfo_ok); |
1865 __ BIND(L_vminfo_ok); |
1917 BLOCK_COMMENT("} verify dest_slot_constant"); |
1866 BLOCK_COMMENT("} verify dest_slot_constant"); |
1918 } |
1867 } |
1919 #endif //ASSERT |
1868 #endif //ASSERT |
1949 // (As it happens, all movements involve an argument list size change.) |
1898 // (As it happens, all movements involve an argument list size change.) |
1950 |
1899 |
1951 // If there are variable parameters, use dynamic checks to skip around the whole mess. |
1900 // If there are variable parameters, use dynamic checks to skip around the whole mess. |
1952 Label L_done; |
1901 Label L_done; |
1953 if (keep3_count.is_register()) { |
1902 if (keep3_count.is_register()) { |
1954 __ tst(keep3_count.as_register()); |
1903 __ cmp_and_br_short(keep3_count.as_register(), 0, Assembler::equal, Assembler::pn, L_done); |
1955 __ br(Assembler::zero, false, Assembler::pn, L_done); |
|
1956 __ delayed()->nop(); |
|
1957 } |
1904 } |
1958 if (close_count.is_register()) { |
1905 if (close_count.is_register()) { |
1959 __ cmp(close_count.as_register(), open_count); |
1906 __ cmp_and_br_short(close_count.as_register(), open_count, Assembler::equal, Assembler::pn, L_done); |
1960 __ br(Assembler::equal, false, Assembler::pn, L_done); |
|
1961 __ delayed()->nop(); |
|
1962 } |
1907 } |
1963 |
1908 |
1964 if (move_keep3 && fix_arg_base) { |
1909 if (move_keep3 && fix_arg_base) { |
1965 bool emit_move_down = false, emit_move_up = false, emit_guard = false; |
1910 bool emit_move_down = false, emit_move_up = false, emit_guard = false; |
1966 if (!close_count.is_constant()) { |
1911 if (!close_count.is_constant()) { |
2131 __ sll_ptr(O5_dest_type, LogBytesPerWord, O5_dest_type); |
2075 __ sll_ptr(O5_dest_type, LogBytesPerWord, O5_dest_type); |
2132 __ ld_ptr(O7_temp, O5_dest_type, O7_temp); |
2076 __ ld_ptr(O7_temp, O5_dest_type, O7_temp); |
2133 |
2077 |
2134 #ifdef ASSERT |
2078 #ifdef ASSERT |
2135 { Label L_ok; |
2079 { Label L_ok; |
2136 __ br_notnull(O7_temp, false, Assembler::pt, L_ok); |
2080 __ br_notnull_short(O7_temp, Assembler::pt, L_ok); |
2137 __ delayed()->nop(); |
|
2138 __ stop("bad method handle return"); |
2081 __ stop("bad method handle return"); |
2139 __ BIND(L_ok); |
2082 __ BIND(L_ok); |
2140 } |
2083 } |
2141 #endif //ASSERT |
2084 #endif //ASSERT |
2142 __ JMP(O7_temp, 0); |
2085 __ JMP(O7_temp, 0); |
2190 if (length_can_be_zero) { |
2133 if (length_can_be_zero) { |
2191 // handle the null pointer case, if zero is allowed |
2134 // handle the null pointer case, if zero is allowed |
2192 Label L_skip; |
2135 Label L_skip; |
2193 if (length_constant < 0) { |
2136 if (length_constant < 0) { |
2194 load_conversion_vminfo(_masm, G3_amh_conversion, O3_scratch); |
2137 load_conversion_vminfo(_masm, G3_amh_conversion, O3_scratch); |
2195 __ br_zero(Assembler::notZero, false, Assembler::pn, O3_scratch, L_skip); |
2138 __ cmp_zero_and_br(Assembler::notZero, O3_scratch, L_skip); |
2196 __ delayed()->nop(); |
2139 __ delayed()->nop(); // to avoid back-to-back cbcond instructions |
2197 } |
2140 } |
2198 __ br_null(O1_array, false, Assembler::pn, L_array_is_empty); |
2141 __ br_null_short(O1_array, Assembler::pn, L_array_is_empty); |
2199 __ delayed()->nop(); |
|
2200 __ BIND(L_skip); |
2142 __ BIND(L_skip); |
2201 } |
2143 } |
2202 __ null_check(O1_array, oopDesc::klass_offset_in_bytes()); |
2144 __ null_check(O1_array, oopDesc::klass_offset_in_bytes()); |
2203 __ load_klass(O1_array, O2_array_klass); |
2145 __ load_klass(O1_array, O2_array_klass); |
2204 |
2146 |
2208 load_klass_from_Class(_masm, O3_klass, O4_scratch, G5_scratch); |
2150 load_klass_from_Class(_masm, O3_klass, O4_scratch, G5_scratch); |
2209 |
2151 |
2210 Label L_ok_array_klass, L_bad_array_klass, L_bad_array_length; |
2152 Label L_ok_array_klass, L_bad_array_klass, L_bad_array_length; |
2211 __ check_klass_subtype(O2_array_klass, O3_klass, O4_scratch, G5_scratch, L_ok_array_klass); |
2153 __ check_klass_subtype(O2_array_klass, O3_klass, O4_scratch, G5_scratch, L_ok_array_klass); |
2212 // If we get here, the type check failed! |
2154 // If we get here, the type check failed! |
2213 __ ba(false, L_bad_array_klass); |
2155 __ ba_short(L_bad_array_klass); |
2214 __ delayed()->nop(); |
|
2215 __ BIND(L_ok_array_klass); |
2156 __ BIND(L_ok_array_klass); |
2216 |
2157 |
2217 // Check length. |
2158 // Check length. |
2218 if (length_constant >= 0) { |
2159 if (length_constant >= 0) { |
2219 __ ldsw(Address(O1_array, length_offset), O4_scratch); |
2160 __ ldsw(Address(O1_array, length_offset), O4_scratch); |
2245 __ delayed()->nop(); |
2186 __ delayed()->nop(); |
2246 // single argument case, with no array movement |
2187 // single argument case, with no array movement |
2247 __ BIND(L_array_is_empty); |
2188 __ BIND(L_array_is_empty); |
2248 remove_arg_slots(_masm, -stack_move_unit() * array_slots, |
2189 remove_arg_slots(_masm, -stack_move_unit() * array_slots, |
2249 O0_argslot, O1_scratch, O2_scratch, O3_scratch); |
2190 O0_argslot, O1_scratch, O2_scratch, O3_scratch); |
2250 __ ba(false, L_args_done); // no spreading to do |
2191 __ ba_short(L_args_done); // no spreading to do |
2251 __ delayed()->nop(); |
|
2252 __ BIND(L_insert_arg_space); |
2192 __ BIND(L_insert_arg_space); |
2253 // come here in the usual case, stack_move < 0 (2 or more spread arguments) |
2193 // come here in the usual case, stack_move < 0 (2 or more spread arguments) |
2254 // Live: O1_array, O2_argslot_limit, O3_stack_move |
2194 // Live: O1_array, O2_argslot_limit, O3_stack_move |
2255 insert_arg_slots(_masm, O3_stack_move, |
2195 insert_arg_slots(_masm, O3_stack_move, |
2256 O0_argslot, O4_scratch, G5_scratch, O1_scratch); |
2196 O0_argslot, O4_scratch, G5_scratch, O1_scratch); |
2287 __ add(O4_fill_ptr, -Interpreter::stackElementSize * elem_slots, O4_fill_ptr); |
2227 __ add(O4_fill_ptr, -Interpreter::stackElementSize * elem_slots, O4_fill_ptr); |
2288 move_typed_arg(_masm, elem_type, true, |
2228 move_typed_arg(_masm, elem_type, true, |
2289 Address(O1_source, 0), Address(O4_fill_ptr, 0), |
2229 Address(O1_source, 0), Address(O4_fill_ptr, 0), |
2290 O2_scratch); // must be an even register for !_LP64 long moves (uses O2/O3) |
2230 O2_scratch); // must be an even register for !_LP64 long moves (uses O2/O3) |
2291 __ add(O1_source, type2aelembytes(elem_type), O1_source); |
2231 __ add(O1_source, type2aelembytes(elem_type), O1_source); |
2292 __ cmp(O4_fill_ptr, O0_argslot); |
2232 __ cmp_and_brx_short(O4_fill_ptr, O0_argslot, Assembler::greaterUnsigned, Assembler::pt, L_loop); |
2293 __ brx(Assembler::greaterUnsigned, false, Assembler::pt, L_loop); |
|
2294 __ delayed()->nop(); // FILLME |
|
2295 } else if (length_constant == 0) { |
2233 } else if (length_constant == 0) { |
2296 // nothing to copy |
2234 // nothing to copy |
2297 } else { |
2235 } else { |
2298 int elem_offset = elem0_offset; |
2236 int elem_offset = elem0_offset; |
2299 int slot_offset = length_constant * Interpreter::stackElementSize; |
2237 int slot_offset = length_constant * Interpreter::stackElementSize; |