Mercurial > hg > truffle
comparison src/cpu/sparc/vm/methodHandles_sparc.cpp @ 3839:3d42f82cd811
7063628: Use cbcond on T4
Summary: Add new short branch instruction to Hotspot sparc assembler.
Reviewed-by: never, twisti, jrose
author | kvn |
---|---|
date | Thu, 21 Jul 2011 11:25:07 -0700 |
parents | 341a57af9b0a |
children | a19c671188cb |
comparison
equal
deleted
inserted
replaced
3838:6a991dcb52bb | 3839:3d42f82cd811 |
---|---|
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()) { |
1997 O4_scratch, G5_scratch); | 1942 O4_scratch, G5_scratch); |
1998 } | 1943 } |
1999 } | 1944 } |
2000 | 1945 |
2001 if (emit_guard) { | 1946 if (emit_guard) { |
2002 __ ba(false, L_done); // assumes emit_move_up is true also | 1947 __ ba_short(L_done); // assumes emit_move_up is true also |
2003 __ delayed()->nop(); | |
2004 __ BIND(L_move_up); | 1948 __ BIND(L_move_up); |
2005 } | 1949 } |
2006 | 1950 |
2007 if (emit_move_up) { | 1951 if (emit_move_up) { |
2008 // Move arguments up if |+dest+| < |-collect-| | 1952 // Move arguments up if |+dest+| < |-collect-| |
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; |