Mercurial > hg > graal-jvmci-8
comparison src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @ 2002:ac637b7220d1
6985015: C1 needs to support compressed oops
Summary: This change implements compressed oops for C1 for x64 and sparc. The changes are mostly on the codegen level, with a few exceptions when we do access things outside of the heap that are uncompressed from the IR. Compressed oops are now also enabled with tiered.
Reviewed-by: twisti, kvn, never, phh
author | iveresov |
---|---|
date | Tue, 30 Nov 2010 23:23:40 -0800 |
parents | f95d63e2154a |
children | 5ddfcf4b079e |
comparison
equal
deleted
inserted
replaced
1972:f95d63e2154a | 2002:ac637b7220d1 |
---|---|
98 if (src->is_double_cpu() || dst->is_double_cpu() || op1->patch_code() != lir_patch_none || | 98 if (src->is_double_cpu() || dst->is_double_cpu() || op1->patch_code() != lir_patch_none || |
99 ((src->is_double_fpu() || dst->is_double_fpu()) && op1->move_kind() != lir_move_normal)) { | 99 ((src->is_double_fpu() || dst->is_double_fpu()) && op1->move_kind() != lir_move_normal)) { |
100 return false; | 100 return false; |
101 } | 101 } |
102 | 102 |
103 if (UseCompressedOops) { | |
104 if (dst->is_address() && !dst->is_stack() && (dst->type() == T_OBJECT || dst->type() == T_ARRAY)) return false; | |
105 if (src->is_address() && !src->is_stack() && (src->type() == T_OBJECT || src->type() == T_ARRAY)) return false; | |
106 } | |
107 | |
103 if (dst->is_register()) { | 108 if (dst->is_register()) { |
104 if (src->is_address() && Assembler::is_simm13(src->as_address_ptr()->disp())) { | 109 if (src->is_address() && Assembler::is_simm13(src->as_address_ptr()->disp())) { |
105 return !PatchALot; | 110 return !PatchALot; |
106 } else if (src->is_single_stack()) { | 111 } else if (src->is_single_stack()) { |
107 return true; | 112 return true; |
251 | 256 |
252 int value_offset = java_lang_String:: value_offset_in_bytes(); // char array | 257 int value_offset = java_lang_String:: value_offset_in_bytes(); // char array |
253 int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position | 258 int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position |
254 int count_offset = java_lang_String:: count_offset_in_bytes(); | 259 int count_offset = java_lang_String:: count_offset_in_bytes(); |
255 | 260 |
256 __ ld_ptr(str0, value_offset, tmp0); | 261 __ load_heap_oop(str0, value_offset, tmp0); |
257 __ ld(str0, offset_offset, tmp2); | 262 __ ld(str0, offset_offset, tmp2); |
258 __ add(tmp0, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0); | 263 __ add(tmp0, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0); |
259 __ ld(str0, count_offset, str0); | 264 __ ld(str0, count_offset, str0); |
260 __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2); | 265 __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2); |
261 | 266 |
262 // str1 may be null | 267 // str1 may be null |
263 add_debug_info_for_null_check_here(info); | 268 add_debug_info_for_null_check_here(info); |
264 | 269 |
265 __ ld_ptr(str1, value_offset, tmp1); | 270 __ load_heap_oop(str1, value_offset, tmp1); |
266 __ add(tmp0, tmp2, tmp0); | 271 __ add(tmp0, tmp2, tmp0); |
267 | 272 |
268 __ ld(str1, offset_offset, tmp2); | 273 __ ld(str1, offset_offset, tmp2); |
269 __ add(tmp1, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1); | 274 __ add(tmp1, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1); |
270 __ ld(str1, count_offset, str1); | 275 __ ld(str1, count_offset, str1); |
764 } | 769 } |
765 | 770 |
766 | 771 |
767 void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) { | 772 void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) { |
768 add_debug_info_for_null_check_here(op->info()); | 773 add_debug_info_for_null_check_here(op->info()); |
769 __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_scratch); | 774 __ load_klass(O0, G3_scratch); |
770 if (__ is_simm13(op->vtable_offset())) { | 775 if (__ is_simm13(op->vtable_offset())) { |
771 __ ld_ptr(G3_scratch, op->vtable_offset(), G5_method); | 776 __ ld_ptr(G3_scratch, op->vtable_offset(), G5_method); |
772 } else { | 777 } else { |
773 // This will generate 2 instructions | 778 // This will generate 2 instructions |
774 __ set(op->vtable_offset(), G5_method); | 779 __ set(op->vtable_offset(), G5_method); |
778 __ ld_ptr(G5_method, methodOopDesc::from_compiled_offset(), G3_scratch); | 783 __ ld_ptr(G5_method, methodOopDesc::from_compiled_offset(), G3_scratch); |
779 __ callr(G3_scratch, G0); | 784 __ callr(G3_scratch, G0); |
780 // the peephole pass fills the delay slot | 785 // the peephole pass fills the delay slot |
781 } | 786 } |
782 | 787 |
783 | 788 int LIR_Assembler::store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool wide, bool unaligned) { |
784 // load with 32-bit displacement | |
785 int LIR_Assembler::load(Register s, int disp, Register d, BasicType ld_type, CodeEmitInfo *info) { | |
786 int load_offset = code_offset(); | |
787 if (Assembler::is_simm13(disp)) { | |
788 if (info != NULL) add_debug_info_for_null_check_here(info); | |
789 switch(ld_type) { | |
790 case T_BOOLEAN: // fall through | |
791 case T_BYTE : __ ldsb(s, disp, d); break; | |
792 case T_CHAR : __ lduh(s, disp, d); break; | |
793 case T_SHORT : __ ldsh(s, disp, d); break; | |
794 case T_INT : __ ld(s, disp, d); break; | |
795 case T_ADDRESS:// fall through | |
796 case T_ARRAY : // fall through | |
797 case T_OBJECT: __ ld_ptr(s, disp, d); break; | |
798 default : ShouldNotReachHere(); | |
799 } | |
800 } else { | |
801 __ set(disp, O7); | |
802 if (info != NULL) add_debug_info_for_null_check_here(info); | |
803 load_offset = code_offset(); | |
804 switch(ld_type) { | |
805 case T_BOOLEAN: // fall through | |
806 case T_BYTE : __ ldsb(s, O7, d); break; | |
807 case T_CHAR : __ lduh(s, O7, d); break; | |
808 case T_SHORT : __ ldsh(s, O7, d); break; | |
809 case T_INT : __ ld(s, O7, d); break; | |
810 case T_ADDRESS:// fall through | |
811 case T_ARRAY : // fall through | |
812 case T_OBJECT: __ ld_ptr(s, O7, d); break; | |
813 default : ShouldNotReachHere(); | |
814 } | |
815 } | |
816 if (ld_type == T_ARRAY || ld_type == T_OBJECT) __ verify_oop(d); | |
817 return load_offset; | |
818 } | |
819 | |
820 | |
821 // store with 32-bit displacement | |
822 void LIR_Assembler::store(Register value, Register base, int offset, BasicType type, CodeEmitInfo *info) { | |
823 if (Assembler::is_simm13(offset)) { | |
824 if (info != NULL) add_debug_info_for_null_check_here(info); | |
825 switch (type) { | |
826 case T_BOOLEAN: // fall through | |
827 case T_BYTE : __ stb(value, base, offset); break; | |
828 case T_CHAR : __ sth(value, base, offset); break; | |
829 case T_SHORT : __ sth(value, base, offset); break; | |
830 case T_INT : __ stw(value, base, offset); break; | |
831 case T_ADDRESS:// fall through | |
832 case T_ARRAY : // fall through | |
833 case T_OBJECT: __ st_ptr(value, base, offset); break; | |
834 default : ShouldNotReachHere(); | |
835 } | |
836 } else { | |
837 __ set(offset, O7); | |
838 if (info != NULL) add_debug_info_for_null_check_here(info); | |
839 switch (type) { | |
840 case T_BOOLEAN: // fall through | |
841 case T_BYTE : __ stb(value, base, O7); break; | |
842 case T_CHAR : __ sth(value, base, O7); break; | |
843 case T_SHORT : __ sth(value, base, O7); break; | |
844 case T_INT : __ stw(value, base, O7); break; | |
845 case T_ADDRESS:// fall through | |
846 case T_ARRAY : //fall through | |
847 case T_OBJECT: __ st_ptr(value, base, O7); break; | |
848 default : ShouldNotReachHere(); | |
849 } | |
850 } | |
851 // Note: Do the store before verification as the code might be patched! | |
852 if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(value); | |
853 } | |
854 | |
855 | |
856 // load float with 32-bit displacement | |
857 void LIR_Assembler::load(Register s, int disp, FloatRegister d, BasicType ld_type, CodeEmitInfo *info) { | |
858 FloatRegisterImpl::Width w; | |
859 switch(ld_type) { | |
860 case T_FLOAT : w = FloatRegisterImpl::S; break; | |
861 case T_DOUBLE: w = FloatRegisterImpl::D; break; | |
862 default : ShouldNotReachHere(); | |
863 } | |
864 | |
865 if (Assembler::is_simm13(disp)) { | |
866 if (info != NULL) add_debug_info_for_null_check_here(info); | |
867 if (disp % BytesPerLong != 0 && w == FloatRegisterImpl::D) { | |
868 __ ldf(FloatRegisterImpl::S, s, disp + BytesPerWord, d->successor()); | |
869 __ ldf(FloatRegisterImpl::S, s, disp , d); | |
870 } else { | |
871 __ ldf(w, s, disp, d); | |
872 } | |
873 } else { | |
874 __ set(disp, O7); | |
875 if (info != NULL) add_debug_info_for_null_check_here(info); | |
876 __ ldf(w, s, O7, d); | |
877 } | |
878 } | |
879 | |
880 | |
881 // store float with 32-bit displacement | |
882 void LIR_Assembler::store(FloatRegister value, Register base, int offset, BasicType type, CodeEmitInfo *info) { | |
883 FloatRegisterImpl::Width w; | |
884 switch(type) { | |
885 case T_FLOAT : w = FloatRegisterImpl::S; break; | |
886 case T_DOUBLE: w = FloatRegisterImpl::D; break; | |
887 default : ShouldNotReachHere(); | |
888 } | |
889 | |
890 if (Assembler::is_simm13(offset)) { | |
891 if (info != NULL) add_debug_info_for_null_check_here(info); | |
892 if (w == FloatRegisterImpl::D && offset % BytesPerLong != 0) { | |
893 __ stf(FloatRegisterImpl::S, value->successor(), base, offset + BytesPerWord); | |
894 __ stf(FloatRegisterImpl::S, value , base, offset); | |
895 } else { | |
896 __ stf(w, value, base, offset); | |
897 } | |
898 } else { | |
899 __ set(offset, O7); | |
900 if (info != NULL) add_debug_info_for_null_check_here(info); | |
901 __ stf(w, value, O7, base); | |
902 } | |
903 } | |
904 | |
905 | |
906 int LIR_Assembler::store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool unaligned) { | |
907 int store_offset; | 789 int store_offset; |
908 if (!Assembler::is_simm13(offset + (type == T_LONG) ? wordSize : 0)) { | 790 if (!Assembler::is_simm13(offset + (type == T_LONG) ? wordSize : 0)) { |
909 assert(!unaligned, "can't handle this"); | 791 assert(!unaligned, "can't handle this"); |
910 // for offsets larger than a simm13 we setup the offset in O7 | 792 // for offsets larger than a simm13 we setup the offset in O7 |
911 __ set(offset, O7); | 793 __ set(offset, O7); |
912 store_offset = store(from_reg, base, O7, type); | 794 store_offset = store(from_reg, base, O7, type, wide); |
913 } else { | 795 } else { |
914 if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(from_reg->as_register()); | 796 if (type == T_ARRAY || type == T_OBJECT) { |
797 __ verify_oop(from_reg->as_register()); | |
798 } | |
915 store_offset = code_offset(); | 799 store_offset = code_offset(); |
916 switch (type) { | 800 switch (type) { |
917 case T_BOOLEAN: // fall through | 801 case T_BOOLEAN: // fall through |
918 case T_BYTE : __ stb(from_reg->as_register(), base, offset); break; | 802 case T_BYTE : __ stb(from_reg->as_register(), base, offset); break; |
919 case T_CHAR : __ sth(from_reg->as_register(), base, offset); break; | 803 case T_CHAR : __ sth(from_reg->as_register(), base, offset); break; |
932 assert(Assembler::is_simm13(offset + 4), "must be"); | 816 assert(Assembler::is_simm13(offset + 4), "must be"); |
933 __ stw(from_reg->as_register_lo(), base, offset + lo_word_offset_in_bytes); | 817 __ stw(from_reg->as_register_lo(), base, offset + lo_word_offset_in_bytes); |
934 __ stw(from_reg->as_register_hi(), base, offset + hi_word_offset_in_bytes); | 818 __ stw(from_reg->as_register_hi(), base, offset + hi_word_offset_in_bytes); |
935 #endif | 819 #endif |
936 break; | 820 break; |
937 case T_ADDRESS:// fall through | 821 case T_ADDRESS: |
822 __ st_ptr(from_reg->as_register(), base, offset); | |
823 break; | |
938 case T_ARRAY : // fall through | 824 case T_ARRAY : // fall through |
939 case T_OBJECT: __ st_ptr(from_reg->as_register(), base, offset); break; | 825 case T_OBJECT: |
826 { | |
827 if (UseCompressedOops && !wide) { | |
828 __ encode_heap_oop(from_reg->as_register(), G3_scratch); | |
829 store_offset = code_offset(); | |
830 __ stw(G3_scratch, base, offset); | |
831 } else { | |
832 __ st_ptr(from_reg->as_register(), base, offset); | |
833 } | |
834 break; | |
835 } | |
836 | |
940 case T_FLOAT : __ stf(FloatRegisterImpl::S, from_reg->as_float_reg(), base, offset); break; | 837 case T_FLOAT : __ stf(FloatRegisterImpl::S, from_reg->as_float_reg(), base, offset); break; |
941 case T_DOUBLE: | 838 case T_DOUBLE: |
942 { | 839 { |
943 FloatRegister reg = from_reg->as_double_reg(); | 840 FloatRegister reg = from_reg->as_double_reg(); |
944 // split unaligned stores | 841 // split unaligned stores |
956 } | 853 } |
957 return store_offset; | 854 return store_offset; |
958 } | 855 } |
959 | 856 |
960 | 857 |
961 int LIR_Assembler::store(LIR_Opr from_reg, Register base, Register disp, BasicType type) { | 858 int LIR_Assembler::store(LIR_Opr from_reg, Register base, Register disp, BasicType type, bool wide) { |
962 if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(from_reg->as_register()); | 859 if (type == T_ARRAY || type == T_OBJECT) { |
860 __ verify_oop(from_reg->as_register()); | |
861 } | |
963 int store_offset = code_offset(); | 862 int store_offset = code_offset(); |
964 switch (type) { | 863 switch (type) { |
965 case T_BOOLEAN: // fall through | 864 case T_BOOLEAN: // fall through |
966 case T_BYTE : __ stb(from_reg->as_register(), base, disp); break; | 865 case T_BYTE : __ stb(from_reg->as_register(), base, disp); break; |
967 case T_CHAR : __ sth(from_reg->as_register(), base, disp); break; | 866 case T_CHAR : __ sth(from_reg->as_register(), base, disp); break; |
973 #else | 872 #else |
974 assert(from_reg->as_register_hi()->successor() == from_reg->as_register_lo(), "must match"); | 873 assert(from_reg->as_register_hi()->successor() == from_reg->as_register_lo(), "must match"); |
975 __ std(from_reg->as_register_hi(), base, disp); | 874 __ std(from_reg->as_register_hi(), base, disp); |
976 #endif | 875 #endif |
977 break; | 876 break; |
978 case T_ADDRESS:// fall through | 877 case T_ADDRESS: |
878 __ st_ptr(from_reg->as_register(), base, disp); | |
879 break; | |
979 case T_ARRAY : // fall through | 880 case T_ARRAY : // fall through |
980 case T_OBJECT: __ st_ptr(from_reg->as_register(), base, disp); break; | 881 case T_OBJECT: |
882 { | |
883 if (UseCompressedOops && !wide) { | |
884 __ encode_heap_oop(from_reg->as_register(), G3_scratch); | |
885 store_offset = code_offset(); | |
886 __ stw(G3_scratch, base, disp); | |
887 } else { | |
888 __ st_ptr(from_reg->as_register(), base, disp); | |
889 } | |
890 break; | |
891 } | |
981 case T_FLOAT : __ stf(FloatRegisterImpl::S, from_reg->as_float_reg(), base, disp); break; | 892 case T_FLOAT : __ stf(FloatRegisterImpl::S, from_reg->as_float_reg(), base, disp); break; |
982 case T_DOUBLE: __ stf(FloatRegisterImpl::D, from_reg->as_double_reg(), base, disp); break; | 893 case T_DOUBLE: __ stf(FloatRegisterImpl::D, from_reg->as_double_reg(), base, disp); break; |
983 default : ShouldNotReachHere(); | 894 default : ShouldNotReachHere(); |
984 } | 895 } |
985 return store_offset; | 896 return store_offset; |
986 } | 897 } |
987 | 898 |
988 | 899 |
989 int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool unaligned) { | 900 int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool wide, bool unaligned) { |
990 int load_offset; | 901 int load_offset; |
991 if (!Assembler::is_simm13(offset + (type == T_LONG) ? wordSize : 0)) { | 902 if (!Assembler::is_simm13(offset + (type == T_LONG) ? wordSize : 0)) { |
992 assert(base != O7, "destroying register"); | 903 assert(base != O7, "destroying register"); |
993 assert(!unaligned, "can't handle this"); | 904 assert(!unaligned, "can't handle this"); |
994 // for offsets larger than a simm13 we setup the offset in O7 | 905 // for offsets larger than a simm13 we setup the offset in O7 |
995 __ set(offset, O7); | 906 __ set(offset, O7); |
996 load_offset = load(base, O7, to_reg, type); | 907 load_offset = load(base, O7, to_reg, type, wide); |
997 } else { | 908 } else { |
998 load_offset = code_offset(); | 909 load_offset = code_offset(); |
999 switch(type) { | 910 switch(type) { |
1000 case T_BOOLEAN: // fall through | 911 case T_BOOLEAN: // fall through |
1001 case T_BYTE : __ ldsb(base, offset, to_reg->as_register()); break; | 912 case T_BYTE : __ ldsb(base, offset, to_reg->as_register()); break; |
1028 __ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_hi()); | 939 __ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_hi()); |
1029 } | 940 } |
1030 #endif | 941 #endif |
1031 } | 942 } |
1032 break; | 943 break; |
1033 case T_ADDRESS:// fall through | 944 case T_ADDRESS: __ ld_ptr(base, offset, to_reg->as_register()); break; |
1034 case T_ARRAY : // fall through | 945 case T_ARRAY : // fall through |
1035 case T_OBJECT: __ ld_ptr(base, offset, to_reg->as_register()); break; | 946 case T_OBJECT: |
947 { | |
948 if (UseCompressedOops && !wide) { | |
949 __ lduw(base, offset, to_reg->as_register()); | |
950 __ decode_heap_oop(to_reg->as_register()); | |
951 } else { | |
952 __ ld_ptr(base, offset, to_reg->as_register()); | |
953 } | |
954 break; | |
955 } | |
1036 case T_FLOAT: __ ldf(FloatRegisterImpl::S, base, offset, to_reg->as_float_reg()); break; | 956 case T_FLOAT: __ ldf(FloatRegisterImpl::S, base, offset, to_reg->as_float_reg()); break; |
1037 case T_DOUBLE: | 957 case T_DOUBLE: |
1038 { | 958 { |
1039 FloatRegister reg = to_reg->as_double_reg(); | 959 FloatRegister reg = to_reg->as_double_reg(); |
1040 // split unaligned loads | 960 // split unaligned loads |
1046 } | 966 } |
1047 break; | 967 break; |
1048 } | 968 } |
1049 default : ShouldNotReachHere(); | 969 default : ShouldNotReachHere(); |
1050 } | 970 } |
1051 if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(to_reg->as_register()); | 971 if (type == T_ARRAY || type == T_OBJECT) { |
972 __ verify_oop(to_reg->as_register()); | |
973 } | |
1052 } | 974 } |
1053 return load_offset; | 975 return load_offset; |
1054 } | 976 } |
1055 | 977 |
1056 | 978 |
1057 int LIR_Assembler::load(Register base, Register disp, LIR_Opr to_reg, BasicType type) { | 979 int LIR_Assembler::load(Register base, Register disp, LIR_Opr to_reg, BasicType type, bool wide) { |
1058 int load_offset = code_offset(); | 980 int load_offset = code_offset(); |
1059 switch(type) { | 981 switch(type) { |
1060 case T_BOOLEAN: // fall through | 982 case T_BOOLEAN: // fall through |
1061 case T_BYTE : __ ldsb(base, disp, to_reg->as_register()); break; | 983 case T_BYTE : __ ldsb(base, disp, to_reg->as_register()); break; |
1062 case T_CHAR : __ lduh(base, disp, to_reg->as_register()); break; | 984 case T_CHAR : __ lduh(base, disp, to_reg->as_register()); break; |
1063 case T_SHORT : __ ldsh(base, disp, to_reg->as_register()); break; | 985 case T_SHORT : __ ldsh(base, disp, to_reg->as_register()); break; |
1064 case T_INT : __ ld(base, disp, to_reg->as_register()); break; | 986 case T_INT : __ ld(base, disp, to_reg->as_register()); break; |
1065 case T_ADDRESS:// fall through | 987 case T_ADDRESS: __ ld_ptr(base, disp, to_reg->as_register()); break; |
1066 case T_ARRAY : // fall through | 988 case T_ARRAY : // fall through |
1067 case T_OBJECT: __ ld_ptr(base, disp, to_reg->as_register()); break; | 989 case T_OBJECT: |
990 { | |
991 if (UseCompressedOops && !wide) { | |
992 __ lduw(base, disp, to_reg->as_register()); | |
993 __ decode_heap_oop(to_reg->as_register()); | |
994 } else { | |
995 __ ld_ptr(base, disp, to_reg->as_register()); | |
996 } | |
997 break; | |
998 } | |
1068 case T_FLOAT: __ ldf(FloatRegisterImpl::S, base, disp, to_reg->as_float_reg()); break; | 999 case T_FLOAT: __ ldf(FloatRegisterImpl::S, base, disp, to_reg->as_float_reg()); break; |
1069 case T_DOUBLE: __ ldf(FloatRegisterImpl::D, base, disp, to_reg->as_double_reg()); break; | 1000 case T_DOUBLE: __ ldf(FloatRegisterImpl::D, base, disp, to_reg->as_double_reg()); break; |
1070 case T_LONG : | 1001 case T_LONG : |
1071 #ifdef _LP64 | 1002 #ifdef _LP64 |
1072 __ ldx(base, disp, to_reg->as_register_lo()); | 1003 __ ldx(base, disp, to_reg->as_register_lo()); |
1076 __ ldd(base, disp, to_reg->as_register_hi()); | 1007 __ ldd(base, disp, to_reg->as_register_hi()); |
1077 #endif | 1008 #endif |
1078 break; | 1009 break; |
1079 default : ShouldNotReachHere(); | 1010 default : ShouldNotReachHere(); |
1080 } | 1011 } |
1081 if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(to_reg->as_register()); | 1012 if (type == T_ARRAY || type == T_OBJECT) { |
1013 __ verify_oop(to_reg->as_register()); | |
1014 } | |
1082 return load_offset; | 1015 return load_offset; |
1083 } | 1016 } |
1084 | |
1085 | |
1086 // load/store with an Address | |
1087 void LIR_Assembler::load(const Address& a, Register d, BasicType ld_type, CodeEmitInfo *info, int offset) { | |
1088 load(a.base(), a.disp() + offset, d, ld_type, info); | |
1089 } | |
1090 | |
1091 | |
1092 void LIR_Assembler::store(Register value, const Address& dest, BasicType type, CodeEmitInfo *info, int offset) { | |
1093 store(value, dest.base(), dest.disp() + offset, type, info); | |
1094 } | |
1095 | |
1096 | |
1097 // loadf/storef with an Address | |
1098 void LIR_Assembler::load(const Address& a, FloatRegister d, BasicType ld_type, CodeEmitInfo *info, int offset) { | |
1099 load(a.base(), a.disp() + offset, d, ld_type, info); | |
1100 } | |
1101 | |
1102 | |
1103 void LIR_Assembler::store(FloatRegister value, const Address& dest, BasicType type, CodeEmitInfo *info, int offset) { | |
1104 store(value, dest.base(), dest.disp() + offset, type, info); | |
1105 } | |
1106 | |
1107 | |
1108 // load/store with an Address | |
1109 void LIR_Assembler::load(LIR_Address* a, Register d, BasicType ld_type, CodeEmitInfo *info) { | |
1110 load(as_Address(a), d, ld_type, info); | |
1111 } | |
1112 | |
1113 | |
1114 void LIR_Assembler::store(Register value, LIR_Address* dest, BasicType type, CodeEmitInfo *info) { | |
1115 store(value, as_Address(dest), type, info); | |
1116 } | |
1117 | |
1118 | |
1119 // loadf/storef with an Address | |
1120 void LIR_Assembler::load(LIR_Address* a, FloatRegister d, BasicType ld_type, CodeEmitInfo *info) { | |
1121 load(as_Address(a), d, ld_type, info); | |
1122 } | |
1123 | |
1124 | |
1125 void LIR_Assembler::store(FloatRegister value, LIR_Address* dest, BasicType type, CodeEmitInfo *info) { | |
1126 store(value, as_Address(dest), type, info); | |
1127 } | |
1128 | |
1129 | 1017 |
1130 void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) { | 1018 void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) { |
1131 LIR_Const* c = src->as_constant_ptr(); | 1019 LIR_Const* c = src->as_constant_ptr(); |
1132 switch (c->type()) { | 1020 switch (c->type()) { |
1133 case T_INT: | 1021 case T_INT: |
1134 case T_FLOAT: | 1022 case T_FLOAT: { |
1023 Register src_reg = O7; | |
1024 int value = c->as_jint_bits(); | |
1025 if (value == 0) { | |
1026 src_reg = G0; | |
1027 } else { | |
1028 __ set(value, O7); | |
1029 } | |
1030 Address addr = frame_map()->address_for_slot(dest->single_stack_ix()); | |
1031 __ stw(src_reg, addr.base(), addr.disp()); | |
1032 break; | |
1033 } | |
1135 case T_ADDRESS: { | 1034 case T_ADDRESS: { |
1136 Register src_reg = O7; | 1035 Register src_reg = O7; |
1137 int value = c->as_jint_bits(); | 1036 int value = c->as_jint_bits(); |
1138 if (value == 0) { | 1037 if (value == 0) { |
1139 src_reg = G0; | 1038 src_reg = G0; |
1140 } else { | 1039 } else { |
1141 __ set(value, O7); | 1040 __ set(value, O7); |
1142 } | 1041 } |
1143 Address addr = frame_map()->address_for_slot(dest->single_stack_ix()); | 1042 Address addr = frame_map()->address_for_slot(dest->single_stack_ix()); |
1144 __ stw(src_reg, addr.base(), addr.disp()); | 1043 __ st_ptr(src_reg, addr.base(), addr.disp()); |
1145 break; | 1044 break; |
1146 } | 1045 } |
1147 case T_OBJECT: { | 1046 case T_OBJECT: { |
1148 Register src_reg = O7; | 1047 Register src_reg = O7; |
1149 jobject2reg(c->as_jobject(), src_reg); | 1048 jobject2reg(c->as_jobject(), src_reg); |
1176 Unimplemented(); | 1075 Unimplemented(); |
1177 } | 1076 } |
1178 } | 1077 } |
1179 | 1078 |
1180 | 1079 |
1181 void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info ) { | 1080 void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) { |
1182 LIR_Const* c = src->as_constant_ptr(); | 1081 LIR_Const* c = src->as_constant_ptr(); |
1183 LIR_Address* addr = dest->as_address_ptr(); | 1082 LIR_Address* addr = dest->as_address_ptr(); |
1184 Register base = addr->base()->as_pointer_register(); | 1083 Register base = addr->base()->as_pointer_register(); |
1185 | 1084 int offset = -1; |
1186 if (info != NULL) { | 1085 |
1187 add_debug_info_for_null_check_here(info); | |
1188 } | |
1189 switch (c->type()) { | 1086 switch (c->type()) { |
1190 case T_INT: | 1087 case T_INT: |
1191 case T_FLOAT: | 1088 case T_FLOAT: |
1192 case T_ADDRESS: { | 1089 case T_ADDRESS: { |
1193 LIR_Opr tmp = FrameMap::O7_opr; | 1090 LIR_Opr tmp = FrameMap::O7_opr; |
1197 } else if (Assembler::is_simm13(value)) { | 1094 } else if (Assembler::is_simm13(value)) { |
1198 __ set(value, O7); | 1095 __ set(value, O7); |
1199 } | 1096 } |
1200 if (addr->index()->is_valid()) { | 1097 if (addr->index()->is_valid()) { |
1201 assert(addr->disp() == 0, "must be zero"); | 1098 assert(addr->disp() == 0, "must be zero"); |
1202 store(tmp, base, addr->index()->as_pointer_register(), type); | 1099 offset = store(tmp, base, addr->index()->as_pointer_register(), type, wide); |
1203 } else { | 1100 } else { |
1204 assert(Assembler::is_simm13(addr->disp()), "can't handle larger addresses"); | 1101 assert(Assembler::is_simm13(addr->disp()), "can't handle larger addresses"); |
1205 store(tmp, base, addr->disp(), type); | 1102 offset = store(tmp, base, addr->disp(), type, wide, false); |
1206 } | 1103 } |
1207 break; | 1104 break; |
1208 } | 1105 } |
1209 case T_LONG: | 1106 case T_LONG: |
1210 case T_DOUBLE: { | 1107 case T_DOUBLE: { |
1211 assert(!addr->index()->is_valid(), "can't handle reg reg address here"); | 1108 assert(!addr->index()->is_valid(), "can't handle reg reg address here"); |
1212 assert(Assembler::is_simm13(addr->disp()) && | 1109 assert(Assembler::is_simm13(addr->disp()) && |
1213 Assembler::is_simm13(addr->disp() + 4), "can't handle larger addresses"); | 1110 Assembler::is_simm13(addr->disp() + 4), "can't handle larger addresses"); |
1214 | 1111 |
1215 Register tmp = O7; | 1112 LIR_Opr tmp = FrameMap::O7_opr; |
1216 int value_lo = c->as_jint_lo_bits(); | 1113 int value_lo = c->as_jint_lo_bits(); |
1217 if (value_lo == 0) { | 1114 if (value_lo == 0) { |
1218 tmp = G0; | 1115 tmp = FrameMap::G0_opr; |
1219 } else { | 1116 } else { |
1220 __ set(value_lo, O7); | 1117 __ set(value_lo, O7); |
1221 } | 1118 } |
1222 store(tmp, base, addr->disp() + lo_word_offset_in_bytes, T_INT); | 1119 offset = store(tmp, base, addr->disp() + lo_word_offset_in_bytes, T_INT, wide, false); |
1223 int value_hi = c->as_jint_hi_bits(); | 1120 int value_hi = c->as_jint_hi_bits(); |
1224 if (value_hi == 0) { | 1121 if (value_hi == 0) { |
1225 tmp = G0; | 1122 tmp = FrameMap::G0_opr; |
1226 } else { | 1123 } else { |
1227 __ set(value_hi, O7); | 1124 __ set(value_hi, O7); |
1228 } | 1125 } |
1229 store(tmp, base, addr->disp() + hi_word_offset_in_bytes, T_INT); | 1126 offset = store(tmp, base, addr->disp() + hi_word_offset_in_bytes, T_INT, wide, false); |
1230 break; | 1127 break; |
1231 } | 1128 } |
1232 case T_OBJECT: { | 1129 case T_OBJECT: { |
1233 jobject obj = c->as_jobject(); | 1130 jobject obj = c->as_jobject(); |
1234 LIR_Opr tmp; | 1131 LIR_Opr tmp; |
1239 jobject2reg(c->as_jobject(), O7); | 1136 jobject2reg(c->as_jobject(), O7); |
1240 } | 1137 } |
1241 // handle either reg+reg or reg+disp address | 1138 // handle either reg+reg or reg+disp address |
1242 if (addr->index()->is_valid()) { | 1139 if (addr->index()->is_valid()) { |
1243 assert(addr->disp() == 0, "must be zero"); | 1140 assert(addr->disp() == 0, "must be zero"); |
1244 store(tmp, base, addr->index()->as_pointer_register(), type); | 1141 offset = store(tmp, base, addr->index()->as_pointer_register(), type, wide); |
1245 } else { | 1142 } else { |
1246 assert(Assembler::is_simm13(addr->disp()), "can't handle larger addresses"); | 1143 assert(Assembler::is_simm13(addr->disp()), "can't handle larger addresses"); |
1247 store(tmp, base, addr->disp(), type); | 1144 offset = store(tmp, base, addr->disp(), type, wide, false); |
1248 } | 1145 } |
1249 | 1146 |
1250 break; | 1147 break; |
1251 } | 1148 } |
1252 default: | 1149 default: |
1253 Unimplemented(); | 1150 Unimplemented(); |
1151 } | |
1152 if (info != NULL) { | |
1153 assert(offset != -1, "offset should've been set"); | |
1154 add_debug_info_for_null_check(offset, info); | |
1254 } | 1155 } |
1255 } | 1156 } |
1256 | 1157 |
1257 | 1158 |
1258 void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) { | 1159 void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) { |
1334 | 1235 |
1335 } else { | 1236 } else { |
1336 assert(to_reg->is_single_cpu(), "Must be a cpu register."); | 1237 assert(to_reg->is_single_cpu(), "Must be a cpu register."); |
1337 | 1238 |
1338 __ set(const_addrlit, O7); | 1239 __ set(const_addrlit, O7); |
1339 load(O7, 0, to_reg->as_register(), T_INT); | 1240 __ ld(O7, 0, to_reg->as_register()); |
1340 } | 1241 } |
1341 } | 1242 } |
1342 break; | 1243 break; |
1343 | 1244 |
1344 case T_DOUBLE: | 1245 case T_DOUBLE: |
1427 return Address(base.base(), base.disp() + lo_word_offset_in_bytes); | 1328 return Address(base.base(), base.disp() + lo_word_offset_in_bytes); |
1428 } | 1329 } |
1429 | 1330 |
1430 | 1331 |
1431 void LIR_Assembler::mem2reg(LIR_Opr src_opr, LIR_Opr dest, BasicType type, | 1332 void LIR_Assembler::mem2reg(LIR_Opr src_opr, LIR_Opr dest, BasicType type, |
1432 LIR_PatchCode patch_code, CodeEmitInfo* info, bool unaligned) { | 1333 LIR_PatchCode patch_code, CodeEmitInfo* info, bool wide, bool unaligned) { |
1433 | 1334 |
1434 LIR_Address* addr = src_opr->as_address_ptr(); | 1335 LIR_Address* addr = src_opr->as_address_ptr(); |
1435 LIR_Opr to_reg = dest; | 1336 LIR_Opr to_reg = dest; |
1436 | 1337 |
1437 Register src = addr->base()->as_pointer_register(); | 1338 Register src = addr->base()->as_pointer_register(); |
1473 // entered in increasing order. | 1374 // entered in increasing order. |
1474 int offset = code_offset(); | 1375 int offset = code_offset(); |
1475 | 1376 |
1476 assert(disp_reg != noreg || Assembler::is_simm13(disp_value), "should have set this up"); | 1377 assert(disp_reg != noreg || Assembler::is_simm13(disp_value), "should have set this up"); |
1477 if (disp_reg == noreg) { | 1378 if (disp_reg == noreg) { |
1478 offset = load(src, disp_value, to_reg, type, unaligned); | 1379 offset = load(src, disp_value, to_reg, type, wide, unaligned); |
1479 } else { | 1380 } else { |
1480 assert(!unaligned, "can't handle this"); | 1381 assert(!unaligned, "can't handle this"); |
1481 offset = load(src, disp_reg, to_reg, type); | 1382 offset = load(src, disp_reg, to_reg, type, wide); |
1482 } | 1383 } |
1483 | 1384 |
1484 if (patch != NULL) { | 1385 if (patch != NULL) { |
1485 patching_epilog(patch, patch_code, src, info); | 1386 patching_epilog(patch, patch_code, src, info); |
1486 } | 1387 } |
1487 | |
1488 if (info != NULL) add_debug_info_for_null_check(offset, info); | 1388 if (info != NULL) add_debug_info_for_null_check(offset, info); |
1489 } | 1389 } |
1490 | 1390 |
1491 | 1391 |
1492 void LIR_Assembler::prefetchr(LIR_Opr src) { | 1392 void LIR_Assembler::prefetchr(LIR_Opr src) { |
1516 } else if (src->is_double_word()) { | 1416 } else if (src->is_double_word()) { |
1517 addr = frame_map()->address_for_double_slot(src->double_stack_ix()); | 1417 addr = frame_map()->address_for_double_slot(src->double_stack_ix()); |
1518 } | 1418 } |
1519 | 1419 |
1520 bool unaligned = (addr.disp() - STACK_BIAS) % 8 != 0; | 1420 bool unaligned = (addr.disp() - STACK_BIAS) % 8 != 0; |
1521 load(addr.base(), addr.disp(), dest, dest->type(), unaligned); | 1421 load(addr.base(), addr.disp(), dest, dest->type(), true /*wide*/, unaligned); |
1522 } | 1422 } |
1523 | 1423 |
1524 | 1424 |
1525 void LIR_Assembler::reg2stack(LIR_Opr from_reg, LIR_Opr dest, BasicType type, bool pop_fpu_stack) { | 1425 void LIR_Assembler::reg2stack(LIR_Opr from_reg, LIR_Opr dest, BasicType type, bool pop_fpu_stack) { |
1526 Address addr; | 1426 Address addr; |
1528 addr = frame_map()->address_for_slot(dest->single_stack_ix()); | 1428 addr = frame_map()->address_for_slot(dest->single_stack_ix()); |
1529 } else if (dest->is_double_word()) { | 1429 } else if (dest->is_double_word()) { |
1530 addr = frame_map()->address_for_slot(dest->double_stack_ix()); | 1430 addr = frame_map()->address_for_slot(dest->double_stack_ix()); |
1531 } | 1431 } |
1532 bool unaligned = (addr.disp() - STACK_BIAS) % 8 != 0; | 1432 bool unaligned = (addr.disp() - STACK_BIAS) % 8 != 0; |
1533 store(from_reg, addr.base(), addr.disp(), from_reg->type(), unaligned); | 1433 store(from_reg, addr.base(), addr.disp(), from_reg->type(), true /*wide*/, unaligned); |
1534 } | 1434 } |
1535 | 1435 |
1536 | 1436 |
1537 void LIR_Assembler::reg2reg(LIR_Opr from_reg, LIR_Opr to_reg) { | 1437 void LIR_Assembler::reg2reg(LIR_Opr from_reg, LIR_Opr to_reg) { |
1538 if (from_reg->is_float_kind() && to_reg->is_float_kind()) { | 1438 if (from_reg->is_float_kind() && to_reg->is_float_kind()) { |
1576 } | 1476 } |
1577 | 1477 |
1578 | 1478 |
1579 void LIR_Assembler::reg2mem(LIR_Opr from_reg, LIR_Opr dest, BasicType type, | 1479 void LIR_Assembler::reg2mem(LIR_Opr from_reg, LIR_Opr dest, BasicType type, |
1580 LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, | 1480 LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, |
1581 bool unaligned) { | 1481 bool wide, bool unaligned) { |
1582 LIR_Address* addr = dest->as_address_ptr(); | 1482 LIR_Address* addr = dest->as_address_ptr(); |
1583 | 1483 |
1584 Register src = addr->base()->as_pointer_register(); | 1484 Register src = addr->base()->as_pointer_register(); |
1585 Register disp_reg = noreg; | 1485 Register disp_reg = noreg; |
1586 int disp_value = addr->disp(); | 1486 int disp_value = addr->disp(); |
1620 // entered in increasing order. | 1520 // entered in increasing order. |
1621 int offset; | 1521 int offset; |
1622 | 1522 |
1623 assert(disp_reg != noreg || Assembler::is_simm13(disp_value), "should have set this up"); | 1523 assert(disp_reg != noreg || Assembler::is_simm13(disp_value), "should have set this up"); |
1624 if (disp_reg == noreg) { | 1524 if (disp_reg == noreg) { |
1625 offset = store(from_reg, src, disp_value, type, unaligned); | 1525 offset = store(from_reg, src, disp_value, type, wide, unaligned); |
1626 } else { | 1526 } else { |
1627 assert(!unaligned, "can't handle this"); | 1527 assert(!unaligned, "can't handle this"); |
1628 offset = store(from_reg, src, disp_reg, type); | 1528 offset = store(from_reg, src, disp_reg, type, wide); |
1629 } | 1529 } |
1630 | 1530 |
1631 if (patch != NULL) { | 1531 if (patch != NULL) { |
1632 patching_epilog(patch, patch_code, src, info); | 1532 patching_epilog(patch, patch_code, src, info); |
1633 } | 1533 } |
2182 assert(default_type != NULL && default_type->is_array_klass(), "must be true at this point"); | 2082 assert(default_type != NULL && default_type->is_array_klass(), "must be true at this point"); |
2183 | 2083 |
2184 // make sure src and dst are non-null and load array length | 2084 // make sure src and dst are non-null and load array length |
2185 if (flags & LIR_OpArrayCopy::src_null_check) { | 2085 if (flags & LIR_OpArrayCopy::src_null_check) { |
2186 __ tst(src); | 2086 __ tst(src); |
2187 __ br(Assembler::equal, false, Assembler::pn, *stub->entry()); | 2087 __ brx(Assembler::equal, false, Assembler::pn, *stub->entry()); |
2188 __ delayed()->nop(); | 2088 __ delayed()->nop(); |
2189 } | 2089 } |
2190 | 2090 |
2191 if (flags & LIR_OpArrayCopy::dst_null_check) { | 2091 if (flags & LIR_OpArrayCopy::dst_null_check) { |
2192 __ tst(dst); | 2092 __ tst(dst); |
2193 __ br(Assembler::equal, false, Assembler::pn, *stub->entry()); | 2093 __ brx(Assembler::equal, false, Assembler::pn, *stub->entry()); |
2194 __ delayed()->nop(); | 2094 __ delayed()->nop(); |
2195 } | 2095 } |
2196 | 2096 |
2197 if (flags & LIR_OpArrayCopy::src_pos_positive_check) { | 2097 if (flags & LIR_OpArrayCopy::src_pos_positive_check) { |
2198 // test src_pos register | 2098 // test src_pos register |
2230 __ br(Assembler::carrySet, false, Assembler::pn, *stub->entry()); | 2130 __ br(Assembler::carrySet, false, Assembler::pn, *stub->entry()); |
2231 __ delayed()->nop(); | 2131 __ delayed()->nop(); |
2232 } | 2132 } |
2233 | 2133 |
2234 if (flags & LIR_OpArrayCopy::type_check) { | 2134 if (flags & LIR_OpArrayCopy::type_check) { |
2235 __ ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp); | 2135 if (UseCompressedOops) { |
2236 __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2); | 2136 // We don't need decode because we just need to compare |
2237 __ cmp(tmp, tmp2); | 2137 __ lduw(src, oopDesc::klass_offset_in_bytes(), tmp); |
2238 __ br(Assembler::notEqual, false, Assembler::pt, *stub->entry()); | 2138 __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2); |
2139 __ cmp(tmp, tmp2); | |
2140 __ br(Assembler::notEqual, false, Assembler::pt, *stub->entry()); | |
2141 } else { | |
2142 __ ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp); | |
2143 __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2); | |
2144 __ cmp(tmp, tmp2); | |
2145 __ brx(Assembler::notEqual, false, Assembler::pt, *stub->entry()); | |
2146 } | |
2239 __ delayed()->nop(); | 2147 __ delayed()->nop(); |
2240 } | 2148 } |
2241 | 2149 |
2242 #ifdef ASSERT | 2150 #ifdef ASSERT |
2243 if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) { | 2151 if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) { |
2248 // dst type is exactly the expected type and the src type is a | 2156 // dst type is exactly the expected type and the src type is a |
2249 // subtype which we can't check or src is the same array as dst | 2157 // subtype which we can't check or src is the same array as dst |
2250 // but not necessarily exactly of type default_type. | 2158 // but not necessarily exactly of type default_type. |
2251 Label known_ok, halt; | 2159 Label known_ok, halt; |
2252 jobject2reg(op->expected_type()->constant_encoding(), tmp); | 2160 jobject2reg(op->expected_type()->constant_encoding(), tmp); |
2253 __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2); | 2161 if (UseCompressedOops) { |
2254 if (basic_type != T_OBJECT) { | 2162 // tmp holds the default type. It currently comes uncompressed after the |
2255 __ cmp(tmp, tmp2); | 2163 // load of a constant, so encode it. |
2256 __ br(Assembler::notEqual, false, Assembler::pn, halt); | 2164 __ encode_heap_oop(tmp); |
2257 __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2); | 2165 // load the raw value of the dst klass, since we will be comparing |
2258 __ cmp(tmp, tmp2); | 2166 // uncompressed values directly. |
2259 __ br(Assembler::equal, false, Assembler::pn, known_ok); | 2167 __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2); |
2260 __ delayed()->nop(); | 2168 if (basic_type != T_OBJECT) { |
2169 __ cmp(tmp, tmp2); | |
2170 __ br(Assembler::notEqual, false, Assembler::pn, halt); | |
2171 // load the raw value of the src klass. | |
2172 __ delayed()->lduw(src, oopDesc::klass_offset_in_bytes(), tmp2); | |
2173 __ cmp(tmp, tmp2); | |
2174 __ br(Assembler::equal, false, Assembler::pn, known_ok); | |
2175 __ delayed()->nop(); | |
2176 } else { | |
2177 __ cmp(tmp, tmp2); | |
2178 __ br(Assembler::equal, false, Assembler::pn, known_ok); | |
2179 __ delayed()->cmp(src, dst); | |
2180 __ brx(Assembler::equal, false, Assembler::pn, known_ok); | |
2181 __ delayed()->nop(); | |
2182 } | |
2261 } else { | 2183 } else { |
2262 __ cmp(tmp, tmp2); | 2184 __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2); |
2263 __ br(Assembler::equal, false, Assembler::pn, known_ok); | 2185 if (basic_type != T_OBJECT) { |
2264 __ delayed()->cmp(src, dst); | 2186 __ cmp(tmp, tmp2); |
2265 __ br(Assembler::equal, false, Assembler::pn, known_ok); | 2187 __ brx(Assembler::notEqual, false, Assembler::pn, halt); |
2266 __ delayed()->nop(); | 2188 __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2); |
2189 __ cmp(tmp, tmp2); | |
2190 __ brx(Assembler::equal, false, Assembler::pn, known_ok); | |
2191 __ delayed()->nop(); | |
2192 } else { | |
2193 __ cmp(tmp, tmp2); | |
2194 __ brx(Assembler::equal, false, Assembler::pn, known_ok); | |
2195 __ delayed()->cmp(src, dst); | |
2196 __ brx(Assembler::equal, false, Assembler::pn, known_ok); | |
2197 __ delayed()->nop(); | |
2198 } | |
2267 } | 2199 } |
2268 __ bind(halt); | 2200 __ bind(halt); |
2269 __ stop("incorrect type information in arraycopy"); | 2201 __ stop("incorrect type information in arraycopy"); |
2270 __ bind(known_ok); | 2202 __ bind(known_ok); |
2271 } | 2203 } |
2469 // Didn't find receiver; find next empty slot and fill it in | 2401 // Didn't find receiver; find next empty slot and fill it in |
2470 for (i = 0; i < VirtualCallData::row_limit(); i++) { | 2402 for (i = 0; i < VirtualCallData::row_limit(); i++) { |
2471 Label next_test; | 2403 Label next_test; |
2472 Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) - | 2404 Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) - |
2473 mdo_offset_bias); | 2405 mdo_offset_bias); |
2474 load(recv_addr, tmp1, T_OBJECT); | 2406 __ ld_ptr(recv_addr, tmp1); |
2475 __ br_notnull(tmp1, false, Assembler::pt, next_test); | 2407 __ br_notnull(tmp1, false, Assembler::pt, next_test); |
2476 __ delayed()->nop(); | 2408 __ delayed()->nop(); |
2477 __ st_ptr(recv, recv_addr); | 2409 __ st_ptr(recv, recv_addr); |
2478 __ set(DataLayout::counter_increment, tmp1); | 2410 __ set(DataLayout::counter_increment, tmp1); |
2479 __ st_ptr(tmp1, mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) - | 2411 __ st_ptr(tmp1, mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) - |
2561 } | 2493 } |
2562 assert(obj != k_RInfo, "must be different"); | 2494 assert(obj != k_RInfo, "must be different"); |
2563 | 2495 |
2564 // get object class | 2496 // get object class |
2565 // not a safepoint as obj null check happens earlier | 2497 // not a safepoint as obj null check happens earlier |
2566 load(obj, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL); | 2498 __ load_klass(obj, klass_RInfo); |
2567 if (op->fast_check()) { | 2499 if (op->fast_check()) { |
2568 assert_different_registers(klass_RInfo, k_RInfo); | 2500 assert_different_registers(klass_RInfo, k_RInfo); |
2569 __ cmp(k_RInfo, klass_RInfo); | 2501 __ cmp(k_RInfo, klass_RInfo); |
2570 __ brx(Assembler::notEqual, false, Assembler::pt, *failure_target); | 2502 __ brx(Assembler::notEqual, false, Assembler::pt, *failure_target); |
2571 __ delayed()->nop(); | 2503 __ delayed()->nop(); |
2603 jobject2reg(md->constant_encoding(), mdo); | 2535 jobject2reg(md->constant_encoding(), mdo); |
2604 if (mdo_offset_bias > 0) { | 2536 if (mdo_offset_bias > 0) { |
2605 __ set(mdo_offset_bias, tmp1); | 2537 __ set(mdo_offset_bias, tmp1); |
2606 __ add(mdo, tmp1, mdo); | 2538 __ add(mdo, tmp1, mdo); |
2607 } | 2539 } |
2608 load(Address(obj, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT); | 2540 __ load_klass(obj, recv); |
2609 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, success); | 2541 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, success); |
2610 // Jump over the failure case | 2542 // Jump over the failure case |
2611 __ ba(false, *success); | 2543 __ ba(false, *success); |
2612 __ delayed()->nop(); | 2544 __ delayed()->nop(); |
2613 // Cast failure case | 2545 // Cast failure case |
2672 __ bind(not_null); | 2604 __ bind(not_null); |
2673 } else { | 2605 } else { |
2674 __ br_null(value, false, Assembler::pn, done); | 2606 __ br_null(value, false, Assembler::pn, done); |
2675 __ delayed()->nop(); | 2607 __ delayed()->nop(); |
2676 } | 2608 } |
2677 load(array, oopDesc::klass_offset_in_bytes(), k_RInfo, T_OBJECT, op->info_for_exception()); | 2609 add_debug_info_for_null_check_here(op->info_for_exception()); |
2678 load(value, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL); | 2610 __ load_klass(array, k_RInfo); |
2611 __ load_klass(value, klass_RInfo); | |
2679 | 2612 |
2680 // get instance klass | 2613 // get instance klass |
2681 load(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc), k_RInfo, T_OBJECT, NULL); | 2614 __ ld_ptr(Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)), k_RInfo); |
2682 // perform the fast part of the checking logic | 2615 // perform the fast part of the checking logic |
2683 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, success_target, failure_target, NULL); | 2616 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, success_target, failure_target, NULL); |
2684 | 2617 |
2685 // call out-of-line instance of __ check_klass_subtype_slow_path(...): | 2618 // call out-of-line instance of __ check_klass_subtype_slow_path(...): |
2686 assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup"); | 2619 assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup"); |
2698 jobject2reg(md->constant_encoding(), mdo); | 2631 jobject2reg(md->constant_encoding(), mdo); |
2699 if (mdo_offset_bias > 0) { | 2632 if (mdo_offset_bias > 0) { |
2700 __ set(mdo_offset_bias, tmp1); | 2633 __ set(mdo_offset_bias, tmp1); |
2701 __ add(mdo, tmp1, mdo); | 2634 __ add(mdo, tmp1, mdo); |
2702 } | 2635 } |
2703 load(Address(value, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT); | 2636 __ load_klass(value, recv); |
2704 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &done); | 2637 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &done); |
2705 __ ba(false, done); | 2638 __ ba(false, done); |
2706 __ delayed()->nop(); | 2639 __ delayed()->nop(); |
2707 // Cast failure case | 2640 // Cast failure case |
2708 __ bind(profile_cast_failure); | 2641 __ bind(profile_cast_failure); |
2779 Register new_value = op->new_value()->as_register(); | 2712 Register new_value = op->new_value()->as_register(); |
2780 Register t1 = op->tmp1()->as_register(); | 2713 Register t1 = op->tmp1()->as_register(); |
2781 Register t2 = op->tmp2()->as_register(); | 2714 Register t2 = op->tmp2()->as_register(); |
2782 __ mov(cmp_value, t1); | 2715 __ mov(cmp_value, t1); |
2783 __ mov(new_value, t2); | 2716 __ mov(new_value, t2); |
2784 #ifdef _LP64 | |
2785 if (op->code() == lir_cas_obj) { | 2717 if (op->code() == lir_cas_obj) { |
2786 __ casx(addr, t1, t2); | 2718 if (UseCompressedOops) { |
2787 } else | 2719 __ encode_heap_oop(t1); |
2788 #endif | 2720 __ encode_heap_oop(t2); |
2789 { | |
2790 __ cas(addr, t1, t2); | 2721 __ cas(addr, t1, t2); |
2791 } | 2722 } else { |
2723 __ casx(addr, t1, t2); | |
2724 } | |
2725 } else { | |
2726 __ cas(addr, t1, t2); | |
2727 } | |
2792 __ cmp(t1, t2); | 2728 __ cmp(t1, t2); |
2793 } else { | 2729 } else { |
2794 Unimplemented(); | 2730 Unimplemented(); |
2795 } | 2731 } |
2796 } | 2732 } |
2964 __ st_ptr(tmp1, data_addr); | 2900 __ st_ptr(tmp1, data_addr); |
2965 return; | 2901 return; |
2966 } | 2902 } |
2967 } | 2903 } |
2968 } else { | 2904 } else { |
2969 load(Address(recv, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT); | 2905 __ load_klass(recv, recv); |
2970 Label update_done; | 2906 Label update_done; |
2971 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &update_done); | 2907 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &update_done); |
2972 // Receiver did not match any saved receiver and there is no empty row for it. | 2908 // Receiver did not match any saved receiver and there is no empty row for it. |
2973 // Increment total counter to indicate polymorphic case. | 2909 // Increment total counter to indicate polymorphic case. |
2974 __ ld_ptr(counter_addr, tmp1); | 2910 __ ld_ptr(counter_addr, tmp1); |
3158 } | 3094 } |
3159 | 3095 |
3160 } else { | 3096 } else { |
3161 // use normal move for all other volatiles since they don't need | 3097 // use normal move for all other volatiles since they don't need |
3162 // special handling to remain atomic. | 3098 // special handling to remain atomic. |
3163 move_op(src, dest, type, lir_patch_none, info, false, false); | 3099 move_op(src, dest, type, lir_patch_none, info, false, false, false); |
3164 } | 3100 } |
3165 } | 3101 } |
3166 | 3102 |
3167 void LIR_Assembler::membar() { | 3103 void LIR_Assembler::membar() { |
3168 // only StoreLoad membars are ever explicitly needed on sparcs in TSO mode | 3104 // only StoreLoad membars are ever explicitly needed on sparcs in TSO mode |