| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1059 const Object& constant = index->definition()->AsConstant()->value(); | 1059 const Object& constant = index->definition()->AsConstant()->value(); |
| 1060 if (!constant.IsSmi()) return false; | 1060 if (!constant.IsSmi()) return false; |
| 1061 const Smi& smi_const = Smi::Cast(constant); | 1061 const Smi& smi_const = Smi::Cast(constant); |
| 1062 const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid); | 1062 const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid); |
| 1063 const intptr_t data_offset = FlowGraphCompiler::DataOffsetFor(cid); | 1063 const intptr_t data_offset = FlowGraphCompiler::DataOffsetFor(cid); |
| 1064 const int64_t disp = smi_const.AsInt64Value() * scale + data_offset; | 1064 const int64_t disp = smi_const.AsInt64Value() * scale + data_offset; |
| 1065 return Utils::IsInt(32, disp); | 1065 return Utils::IsInt(32, disp); |
| 1066 } | 1066 } |
| 1067 | 1067 |
| 1068 | 1068 |
| 1069 LocationSummary* StringCharCodeAtInstr::MakeLocationSummary() const { | |
| 1070 const intptr_t kNumInputs = 2; | |
| 1071 const intptr_t kNumTemps = 0; | |
| 1072 LocationSummary* locs = | |
| 1073 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 1074 locs->set_in(0, Location::RequiresRegister()); | |
| 1075 // The smi index is either untagged and tagged again at the end of the | |
| 1076 // operation (element size == 1), or it is left smi tagged (for all element | |
| 1077 // sizes > 1). | |
| 1078 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) | |
| 1079 ? Location::RegisterOrSmiConstant(index()) | |
| 1080 : Location::RequiresRegister()); | |
| 1081 locs->set_out(Location::RequiresRegister()); | |
| 1082 return locs; | |
| 1083 } | |
| 1084 | |
| 1085 | |
| 1086 void StringCharCodeAtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 1087 Register str = locs()->in(0).reg(); | |
| 1088 Location index = locs()->in(1); | |
| 1089 Register result = locs()->out().reg(); | |
| 1090 | |
| 1091 ASSERT((class_id() == kOneByteStringCid) || | |
| 1092 (class_id() == kTwoByteStringCid)); | |
| 1093 | |
| 1094 FieldAddress element_address = index.IsRegister() ? | |
| 1095 FlowGraphCompiler::ElementAddressForRegIndex( | |
| 1096 class_id(), str, index.reg()) : | |
| 1097 FlowGraphCompiler::ElementAddressForIntIndex( | |
| 1098 class_id(), str, Smi::Cast(index.constant()).Value()); | |
| 1099 | |
| 1100 if (class_id() == kOneByteStringCid) { | |
| 1101 if (index.IsRegister()) { | |
| 1102 __ SmiUntag(index.reg()); | |
| 1103 } | |
| 1104 __ movzxb(result, element_address); | |
| 1105 if (index.IsRegister()) { | |
| 1106 __ SmiTag(index.reg()); // Retag index. | |
| 1107 } | |
| 1108 __ SmiTag(result); | |
| 1109 } else { | |
| 1110 // Don't untag smi-index and use TIMES_1 for two byte strings. | |
| 1111 __ movzxw(result, element_address); | |
| 1112 __ SmiTag(result); | |
| 1113 } | |
| 1114 } | |
| 1115 | |
| 1116 | |
| 1117 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { | 1069 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { |
| 1118 const intptr_t kNumInputs = 1; | 1070 const intptr_t kNumInputs = 1; |
| 1119 const intptr_t kNumTemps = 0; | 1071 const intptr_t kNumTemps = 0; |
| 1120 LocationSummary* locs = | 1072 LocationSummary* locs = |
| 1121 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1073 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1122 // TODO(fschneider): Allow immediate operands for the char code. | 1074 // TODO(fschneider): Allow immediate operands for the char code. |
| 1123 locs->set_in(0, Location::RequiresRegister()); | 1075 locs->set_in(0, Location::RequiresRegister()); |
| 1124 locs->set_out(Location::RequiresRegister()); | 1076 locs->set_out(Location::RequiresRegister()); |
| 1125 return locs; | 1077 return locs; |
| 1126 } | 1078 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1203 __ movsd(result, element_address); | 1155 __ movsd(result, element_address); |
| 1204 } | 1156 } |
| 1205 return; | 1157 return; |
| 1206 } | 1158 } |
| 1207 | 1159 |
| 1208 Register result = locs()->out().reg(); | 1160 Register result = locs()->out().reg(); |
| 1209 switch (class_id()) { | 1161 switch (class_id()) { |
| 1210 case kInt8ArrayCid: | 1162 case kInt8ArrayCid: |
| 1211 case kUint8ArrayCid: | 1163 case kUint8ArrayCid: |
| 1212 case kUint8ClampedArrayCid: | 1164 case kUint8ClampedArrayCid: |
| 1165 case kOneByteStringCid: |
| 1213 if (index.IsRegister()) { | 1166 if (index.IsRegister()) { |
| 1214 __ SmiUntag(index.reg()); | 1167 __ SmiUntag(index.reg()); |
| 1215 } | 1168 } |
| 1216 if (class_id() == kInt8ArrayCid) { | 1169 if (class_id() == kInt8ArrayCid) { |
| 1217 __ movsxb(result, element_address); | 1170 __ movsxb(result, element_address); |
| 1218 } else { | 1171 } else { |
| 1219 __ movzxb(result, element_address); | 1172 __ movzxb(result, element_address); |
| 1220 } | 1173 } |
| 1221 __ SmiTag(result); | 1174 __ SmiTag(result); |
| 1222 if (index.IsRegister()) { | 1175 if (index.IsRegister()) { |
| 1223 __ SmiTag(index.reg()); // Re-tag. | 1176 __ SmiTag(index.reg()); // Re-tag. |
| 1224 } | 1177 } |
| 1225 break; | 1178 break; |
| 1226 case kInt16ArrayCid: | 1179 case kInt16ArrayCid: |
| 1227 __ movsxw(result, element_address); | 1180 __ movsxw(result, element_address); |
| 1228 __ SmiTag(result); | 1181 __ SmiTag(result); |
| 1229 break; | 1182 break; |
| 1230 case kUint16ArrayCid: | 1183 case kUint16ArrayCid: |
| 1184 case kTwoByteStringCid: |
| 1231 __ movzxw(result, element_address); | 1185 __ movzxw(result, element_address); |
| 1232 __ SmiTag(result); | 1186 __ SmiTag(result); |
| 1233 break; | 1187 break; |
| 1234 default: | 1188 default: |
| 1235 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); | 1189 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
| 1236 __ movl(result, element_address); | 1190 __ movl(result, element_address); |
| 1237 break; | 1191 break; |
| 1238 } | 1192 } |
| 1239 } | 1193 } |
| 1240 | 1194 |
| (...skipping 1695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2936 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. | 2890 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. |
| 2937 __ pxor(value, XMM0); | 2891 __ pxor(value, XMM0); |
| 2938 } | 2892 } |
| 2939 | 2893 |
| 2940 | 2894 |
| 2941 } // namespace dart | 2895 } // namespace dart |
| 2942 | 2896 |
| 2943 #undef __ | 2897 #undef __ |
| 2944 | 2898 |
| 2945 #endif // defined TARGET_ARCH_X64 | 2899 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |