| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 1020 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1031 | 1031 |
| 1032 | 1032 |
| 1033 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1033 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1034 Register array = locs()->in(0).reg(); | 1034 Register array = locs()->in(0).reg(); |
| 1035 Location index = locs()->in(1); | 1035 Location index = locs()->in(1); |
| 1036 | 1036 |
| 1037 if (class_id() == kExternalUint8ArrayCid) { | 1037 if (class_id() == kExternalUint8ArrayCid) { |
| 1038 Register result = locs()->out().reg(); | 1038 Register result = locs()->out().reg(); |
| 1039 Address element_address = index.IsRegister() | 1039 Address element_address = index.IsRegister() |
| 1040 ? FlowGraphCompiler::ExternalElementAddressForRegIndex( | 1040 ? FlowGraphCompiler::ExternalElementAddressForRegIndex( |
| 1041 class_id(), result, index.reg()) | 1041 class_id(), index_scale(), result, index.reg()) |
| 1042 : FlowGraphCompiler::ExternalElementAddressForIntIndex( | 1042 : FlowGraphCompiler::ExternalElementAddressForIntIndex( |
| 1043 class_id(), result, Smi::Cast(index.constant()).Value()); | 1043 class_id(), index_scale(), result, |
| 1044 Smi::Cast(index.constant()).Value()); |
| 1045 ASSERT(index_scale() == 1); |
| 1044 if (index.IsRegister()) { | 1046 if (index.IsRegister()) { |
| 1045 __ SmiUntag(index.reg()); | 1047 __ SmiUntag(index.reg()); |
| 1046 } | 1048 } |
| 1047 __ movq(result, | 1049 __ movq(result, |
| 1048 FieldAddress(array, ExternalUint8Array::data_offset())); | 1050 FieldAddress(array, ExternalUint8Array::data_offset())); |
| 1049 __ movzxb(result, element_address); | 1051 __ movzxb(result, element_address); |
| 1050 __ SmiTag(result); | 1052 __ SmiTag(result); |
| 1051 if (index.IsRegister()) { | 1053 if (index.IsRegister()) { |
| 1052 __ SmiTag(index.reg()); // Re-tag. | 1054 __ SmiTag(index.reg()); // Re-tag. |
| 1053 } | 1055 } |
| 1054 return; | 1056 return; |
| 1055 } | 1057 } |
| 1056 | 1058 |
| 1057 FieldAddress element_address = index.IsRegister() ? | 1059 FieldAddress element_address = index.IsRegister() |
| 1058 FlowGraphCompiler::ElementAddressForRegIndex( | 1060 ? FlowGraphCompiler::ElementAddressForRegIndex( |
| 1059 class_id(), array, index.reg()) : | 1061 class_id(), index_scale(), array, index.reg()) |
| 1060 FlowGraphCompiler::ElementAddressForIntIndex( | 1062 : FlowGraphCompiler::ElementAddressForIntIndex( |
| 1061 class_id(), array, Smi::Cast(index.constant()).Value()); | 1063 class_id(), index_scale(), array, |
| 1064 Smi::Cast(index.constant()).Value()); |
| 1062 | 1065 |
| 1063 if (representation() == kUnboxedDouble) { | 1066 if (representation() == kUnboxedDouble) { |
| 1067 if (index_scale() == 1 && index.IsRegister()) { |
| 1068 __ SmiUntag(index.reg()); |
| 1069 } |
| 1070 |
| 1064 XmmRegister result = locs()->out().fpu_reg(); | 1071 XmmRegister result = locs()->out().fpu_reg(); |
| 1065 if (class_id() == kFloat32ArrayCid) { | 1072 if (class_id() == kFloat32ArrayCid) { |
| 1066 // Load single precision float. | 1073 // Load single precision float. |
| 1067 __ movss(result, element_address); | 1074 __ movss(result, element_address); |
| 1068 // Promote to double. | 1075 // Promote to double. |
| 1069 __ cvtss2sd(result, locs()->out().fpu_reg()); | 1076 __ cvtss2sd(result, locs()->out().fpu_reg()); |
| 1070 } else { | 1077 } else { |
| 1071 ASSERT(class_id() == kFloat64ArrayCid); | 1078 ASSERT(class_id() == kFloat64ArrayCid); |
| 1072 __ movsd(result, element_address); | 1079 __ movsd(result, element_address); |
| 1073 } | 1080 } |
| 1081 |
| 1082 if (index_scale() == 1 && index.IsRegister()) { |
| 1083 __ SmiTag(index.reg()); // Re-tag. |
| 1084 } |
| 1074 return; | 1085 return; |
| 1075 } | 1086 } |
| 1076 | 1087 |
| 1088 if (index_scale() == 1 && index.IsRegister()) { |
| 1089 __ SmiUntag(index.reg()); |
| 1090 } |
| 1077 Register result = locs()->out().reg(); | 1091 Register result = locs()->out().reg(); |
| 1078 switch (class_id()) { | 1092 switch (class_id()) { |
| 1079 case kInt8ArrayCid: | 1093 case kInt8ArrayCid: |
| 1080 case kUint8ArrayCid: | 1094 case kUint8ArrayCid: |
| 1081 case kUint8ClampedArrayCid: | 1095 case kUint8ClampedArrayCid: |
| 1082 case kOneByteStringCid: | 1096 case kOneByteStringCid: |
| 1083 if (index.IsRegister()) { | |
| 1084 __ SmiUntag(index.reg()); | |
| 1085 } | |
| 1086 if (class_id() == kInt8ArrayCid) { | 1097 if (class_id() == kInt8ArrayCid) { |
| 1087 __ movsxb(result, element_address); | 1098 __ movsxb(result, element_address); |
| 1088 } else { | 1099 } else { |
| 1089 __ movzxb(result, element_address); | 1100 __ movzxb(result, element_address); |
| 1090 } | 1101 } |
| 1091 __ SmiTag(result); | 1102 __ SmiTag(result); |
| 1092 if (index.IsRegister()) { | |
| 1093 __ SmiTag(index.reg()); // Re-tag. | |
| 1094 } | |
| 1095 break; | 1103 break; |
| 1096 case kInt16ArrayCid: | 1104 case kInt16ArrayCid: |
| 1097 __ movsxw(result, element_address); | 1105 __ movsxw(result, element_address); |
| 1098 __ SmiTag(result); | 1106 __ SmiTag(result); |
| 1099 break; | 1107 break; |
| 1100 case kUint16ArrayCid: | 1108 case kUint16ArrayCid: |
| 1101 case kTwoByteStringCid: | 1109 case kTwoByteStringCid: |
| 1102 __ movzxw(result, element_address); | 1110 __ movzxw(result, element_address); |
| 1103 __ SmiTag(result); | 1111 __ SmiTag(result); |
| 1104 break; | 1112 break; |
| 1105 case kInt32ArrayCid: | 1113 case kInt32ArrayCid: |
| 1106 __ movsxl(result, element_address); | 1114 __ movsxl(result, element_address); |
| 1107 __ SmiTag(result); | 1115 __ SmiTag(result); |
| 1108 break; | 1116 break; |
| 1109 case kUint32ArrayCid: | 1117 case kUint32ArrayCid: |
| 1110 __ movl(result, element_address); | 1118 __ movl(result, element_address); |
| 1111 __ SmiTag(result); | 1119 __ SmiTag(result); |
| 1112 break; | 1120 break; |
| 1113 default: | 1121 default: |
| 1114 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); | 1122 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
| 1115 __ movq(result, element_address); | 1123 __ movq(result, element_address); |
| 1116 break; | 1124 break; |
| 1117 } | 1125 } |
| 1126 if (index_scale() == 1 && index.IsRegister()) { |
| 1127 __ SmiTag(index.reg()); // Re-tag. |
| 1128 } |
| 1118 } | 1129 } |
| 1119 | 1130 |
| 1120 | 1131 |
| 1121 Representation StoreIndexedInstr::RequiredInputRepresentation( | 1132 Representation StoreIndexedInstr::RequiredInputRepresentation( |
| 1122 intptr_t idx) const { | 1133 intptr_t idx) const { |
| 1123 if ((idx == 0) || (idx == 1)) return kTagged; | 1134 if ((idx == 0) || (idx == 1)) return kTagged; |
| 1124 ASSERT(idx == 2); | 1135 ASSERT(idx == 2); |
| 1125 switch (class_id_) { | 1136 switch (class_id_) { |
| 1126 case kArrayCid: | 1137 case kArrayCid: |
| 1127 case kInt8ArrayCid: | 1138 case kInt8ArrayCid: |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1187 return NULL; | 1198 return NULL; |
| 1188 } | 1199 } |
| 1189 return locs; | 1200 return locs; |
| 1190 } | 1201 } |
| 1191 | 1202 |
| 1192 | 1203 |
| 1193 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1204 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1194 Register array = locs()->in(0).reg(); | 1205 Register array = locs()->in(0).reg(); |
| 1195 Location index = locs()->in(1); | 1206 Location index = locs()->in(1); |
| 1196 | 1207 |
| 1197 FieldAddress element_address = index.IsRegister() ? | 1208 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(class_id()); |
| 1198 FlowGraphCompiler::ElementAddressForRegIndex( | 1209 |
| 1199 class_id(), array, index.reg()) : | 1210 FieldAddress element_address = index.IsRegister() |
| 1200 FlowGraphCompiler::ElementAddressForIntIndex( | 1211 ? FlowGraphCompiler::ElementAddressForRegIndex( |
| 1201 class_id(), array, Smi::Cast(index.constant()).Value()); | 1212 class_id(), index_scale, array, index.reg()) |
| 1213 : FlowGraphCompiler::ElementAddressForIntIndex( |
| 1214 class_id(), index_scale, array, |
| 1215 Smi::Cast(index.constant()).Value()); |
| 1202 | 1216 |
| 1203 switch (class_id()) { | 1217 switch (class_id()) { |
| 1204 case kArrayCid: | 1218 case kArrayCid: |
| 1205 if (ShouldEmitStoreBarrier()) { | 1219 if (ShouldEmitStoreBarrier()) { |
| 1206 Register value = locs()->in(2).reg(); | 1220 Register value = locs()->in(2).reg(); |
| 1207 __ StoreIntoObject(array, element_address, value); | 1221 __ StoreIntoObject(array, element_address, value); |
| 1208 } else if (locs()->in(2).IsConstant()) { | 1222 } else if (locs()->in(2).IsConstant()) { |
| 1209 const Object& constant = locs()->in(2).constant(); | 1223 const Object& constant = locs()->in(2).constant(); |
| 1210 __ StoreObject(element_address, constant); | 1224 __ StoreObject(element_address, constant); |
| 1211 } else { | 1225 } else { |
| (...skipping 1814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3026 PcDescriptors::kOther, | 3040 PcDescriptors::kOther, |
| 3027 locs()); | 3041 locs()); |
| 3028 __ Drop(2); // Discard type arguments and receiver. | 3042 __ Drop(2); // Discard type arguments and receiver. |
| 3029 } | 3043 } |
| 3030 | 3044 |
| 3031 } // namespace dart | 3045 } // namespace dart |
| 3032 | 3046 |
| 3033 #undef __ | 3047 #undef __ |
| 3034 | 3048 |
| 3035 #endif // defined TARGET_ARCH_X64 | 3049 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |