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); |
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 |
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; |
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); |
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; |
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) { |
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 } |
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"); |