| 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 937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 948 Register result = locs()->out().reg(); | 948 Register result = locs()->out().reg(); |
| 949 __ movq(result, | 949 __ movq(result, |
| 950 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress()))); | 950 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress()))); |
| 951 __ movq(result, Address(result, | 951 __ movq(result, Address(result, |
| 952 char_code, | 952 char_code, |
| 953 TIMES_HALF_WORD_SIZE, // Char code is a smi. | 953 TIMES_HALF_WORD_SIZE, // Char code is a smi. |
| 954 Symbols::kNullCharCodeSymbolOffset * kWordSize)); | 954 Symbols::kNullCharCodeSymbolOffset * kWordSize)); |
| 955 } | 955 } |
| 956 | 956 |
| 957 | 957 |
| 958 intptr_t LoadIndexedInstr::ResultCid() const { |
| 959 switch (class_id_) { |
| 960 case kArrayCid: |
| 961 case kImmutableArrayCid: |
| 962 return kDynamicCid; |
| 963 case kFloat32ArrayCid : |
| 964 case kFloat64ArrayCid : |
| 965 return kDoubleCid; |
| 966 case kInt8ArrayCid: |
| 967 case kUint8ArrayCid: |
| 968 case kUint8ClampedArrayCid: |
| 969 case kExternalUint8ArrayCid: |
| 970 case kInt16ArrayCid: |
| 971 case kUint16ArrayCid: |
| 972 case kOneByteStringCid: |
| 973 case kTwoByteStringCid: |
| 974 case kInt32ArrayCid: |
| 975 case kUint32ArrayCid: |
| 976 return kSmiCid; |
| 977 |
| 978 default: |
| 979 UNIMPLEMENTED(); |
| 980 return kSmiCid; |
| 981 } |
| 982 } |
| 983 |
| 984 |
| 985 Representation LoadIndexedInstr::representation() const { |
| 986 switch (class_id_) { |
| 987 case kArrayCid: |
| 988 case kImmutableArrayCid: |
| 989 case kInt8ArrayCid: |
| 990 case kUint8ArrayCid: |
| 991 case kUint8ClampedArrayCid: |
| 992 case kExternalUint8ArrayCid: |
| 993 case kInt16ArrayCid: |
| 994 case kUint16ArrayCid: |
| 995 case kOneByteStringCid: |
| 996 case kTwoByteStringCid: |
| 997 case kInt32ArrayCid: |
| 998 case kUint32ArrayCid: |
| 999 return kTagged; |
| 1000 case kFloat32ArrayCid : |
| 1001 case kFloat64ArrayCid : |
| 1002 return kUnboxedDouble; |
| 1003 default: |
| 1004 UNIMPLEMENTED(); |
| 1005 return kTagged; |
| 1006 } |
| 1007 } |
| 1008 |
| 1009 |
| 958 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 1010 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
| 959 const intptr_t kNumInputs = 2; | 1011 const intptr_t kNumInputs = 2; |
| 960 const intptr_t kNumTemps = 0; | 1012 const intptr_t kNumTemps = 0; |
| 961 LocationSummary* locs = | 1013 LocationSummary* locs = |
| 962 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1014 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 963 locs->set_in(0, Location::RequiresRegister()); | 1015 locs->set_in(0, Location::RequiresRegister()); |
| 964 // The smi index is either untagged and tagged again at the end of the | 1016 // The smi index is either untagged and tagged again at the end of the |
| 965 // operation (element size == 1), or it is left smi tagged (for all element | 1017 // operation (element size == 1), or it is left smi tagged (for all element |
| 966 // sizes > 1). | 1018 // sizes > 1). |
| 967 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) | 1019 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1043 break; | 1095 break; |
| 1044 case kInt16ArrayCid: | 1096 case kInt16ArrayCid: |
| 1045 __ movsxw(result, element_address); | 1097 __ movsxw(result, element_address); |
| 1046 __ SmiTag(result); | 1098 __ SmiTag(result); |
| 1047 break; | 1099 break; |
| 1048 case kUint16ArrayCid: | 1100 case kUint16ArrayCid: |
| 1049 case kTwoByteStringCid: | 1101 case kTwoByteStringCid: |
| 1050 __ movzxw(result, element_address); | 1102 __ movzxw(result, element_address); |
| 1051 __ SmiTag(result); | 1103 __ SmiTag(result); |
| 1052 break; | 1104 break; |
| 1105 case kInt32ArrayCid: |
| 1106 __ movsxl(result, element_address); |
| 1107 __ SmiTag(result); |
| 1108 break; |
| 1109 case kUint32ArrayCid: |
| 1110 __ movl(result, element_address); |
| 1111 __ SmiTag(result); |
| 1112 break; |
| 1053 default: | 1113 default: |
| 1054 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); | 1114 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
| 1055 __ movq(result, element_address); | 1115 __ movq(result, element_address); |
| 1056 break; | 1116 break; |
| 1057 } | 1117 } |
| 1058 } | 1118 } |
| 1059 | 1119 |
| 1060 | 1120 |
| 1121 Representation StoreIndexedInstr::RequiredInputRepresentation( |
| 1122 intptr_t idx) const { |
| 1123 if ((idx == 0) || (idx == 1)) return kTagged; |
| 1124 ASSERT(idx == 2); |
| 1125 switch (class_id_) { |
| 1126 case kArrayCid: |
| 1127 case kInt8ArrayCid: |
| 1128 case kUint8ArrayCid: |
| 1129 case kUint8ClampedArrayCid: |
| 1130 case kInt16ArrayCid: |
| 1131 case kUint16ArrayCid: |
| 1132 case kInt32ArrayCid: |
| 1133 case kUint32ArrayCid: |
| 1134 return kTagged; |
| 1135 case kFloat32ArrayCid : |
| 1136 case kFloat64ArrayCid : |
| 1137 return kUnboxedDouble; |
| 1138 default: |
| 1139 UNIMPLEMENTED(); |
| 1140 return kTagged; |
| 1141 } |
| 1142 } |
| 1143 |
| 1144 |
| 1061 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1145 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
| 1062 const intptr_t kNumInputs = 3; | 1146 const intptr_t kNumInputs = 3; |
| 1063 const intptr_t kNumTemps = 0; | 1147 const intptr_t kNumTemps = 0; |
| 1064 LocationSummary* locs = | 1148 LocationSummary* locs = |
| 1065 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1149 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1066 // The smi index is either untagged and tagged again at the end of the | 1150 // The smi index is either untagged and tagged again at the end of the |
| 1067 // operation (element size == 1), or it is left smi tagged (for all element | 1151 // operation (element size == 1), or it is left smi tagged (for all element |
| 1068 // sizes > 1). | 1152 // sizes > 1). |
| 1069 locs->set_in(0, Location::RequiresRegister()); | 1153 locs->set_in(0, Location::RequiresRegister()); |
| 1070 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) | 1154 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
| 1071 ? Location::RegisterOrSmiConstant(index()) | 1155 ? Location::RegisterOrSmiConstant(index()) |
| 1072 : Location::RequiresRegister()); | 1156 : Location::RequiresRegister()); |
| 1073 switch (class_id()) { | 1157 switch (class_id()) { |
| 1074 case kArrayCid: | 1158 case kArrayCid: |
| 1075 locs->set_in(2, ShouldEmitStoreBarrier() | 1159 locs->set_in(2, ShouldEmitStoreBarrier() |
| 1076 ? Location::WritableRegister() | 1160 ? Location::WritableRegister() |
| 1077 : Location::RegisterOrConstant(value())); | 1161 : Location::RegisterOrConstant(value())); |
| 1078 break; | 1162 break; |
| 1079 case kInt8ArrayCid: | 1163 case kInt8ArrayCid: |
| 1080 case kUint8ArrayCid: | 1164 case kUint8ArrayCid: |
| 1081 case kUint8ClampedArrayCid: | 1165 case kUint8ClampedArrayCid: |
| 1082 // TODO(fschneider): Add location constraint for byte registers (RAX, | 1166 // TODO(fschneider): Add location constraint for byte registers (RAX, |
| 1083 // RBX, RCX, RDX) instead of using a fixed register. | 1167 // RBX, RCX, RDX) instead of using a fixed register. |
| 1084 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), RAX)); | 1168 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), RAX)); |
| 1085 break; | 1169 break; |
| 1086 case kInt16ArrayCid: | 1170 case kInt16ArrayCid: |
| 1087 case kUint16ArrayCid: | 1171 case kUint16ArrayCid: |
| 1172 case kInt32ArrayCid: |
| 1173 case kUint32ArrayCid: |
| 1088 // Writable register because the value must be untagged before storing. | 1174 // Writable register because the value must be untagged before storing. |
| 1089 locs->set_in(2, Location::WritableRegister()); | 1175 locs->set_in(2, Location::WritableRegister()); |
| 1090 break; | 1176 break; |
| 1091 case kFloat32ArrayCid: | 1177 case kFloat32ArrayCid: |
| 1092 // Need temp register for float-to-double conversion. | 1178 // Need temp register for float-to-double conversion. |
| 1093 locs->AddTemp(Location::RequiresFpuRegister()); | 1179 locs->AddTemp(Location::RequiresFpuRegister()); |
| 1094 // Fall through. | 1180 // Fall through. |
| 1095 case kFloat64ArrayCid: | 1181 case kFloat64ArrayCid: |
| 1096 // TODO(srdjan): Support Float64 constants. | 1182 // TODO(srdjan): Support Float64 constants. |
| 1097 locs->set_in(2, Location::RequiresFpuRegister()); | 1183 locs->set_in(2, Location::RequiresFpuRegister()); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1175 __ Bind(&store_value); | 1261 __ Bind(&store_value); |
| 1176 __ movb(element_address, RAX); | 1262 __ movb(element_address, RAX); |
| 1177 } | 1263 } |
| 1178 if (index.IsRegister()) { | 1264 if (index.IsRegister()) { |
| 1179 __ SmiTag(index.reg()); // Re-tag. | 1265 __ SmiTag(index.reg()); // Re-tag. |
| 1180 } | 1266 } |
| 1181 break; | 1267 break; |
| 1182 } | 1268 } |
| 1183 case kInt16ArrayCid: | 1269 case kInt16ArrayCid: |
| 1184 case kUint16ArrayCid: { | 1270 case kUint16ArrayCid: { |
| 1185 Register value = locs()->in(2).reg(); | 1271 Register value = locs()->in(2).reg(); |
| 1186 __ SmiUntag(value); | 1272 __ SmiUntag(value); |
| 1187 __ movw(element_address, value); | 1273 __ movw(element_address, value); |
| 1274 break; |
| 1275 } |
| 1276 case kInt32ArrayCid: |
| 1277 case kUint32ArrayCid: { |
| 1278 Register value = locs()->in(2).reg(); |
| 1279 __ SmiUntag(value); |
| 1280 __ movl(element_address, value); |
| 1188 break; | 1281 break; |
| 1189 } | 1282 } |
| 1190 case kFloat32ArrayCid: | 1283 case kFloat32ArrayCid: |
| 1191 // Convert to single precision. | 1284 // Convert to single precision. |
| 1192 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); | 1285 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); |
| 1193 // Store. | 1286 // Store. |
| 1194 __ movss(element_address, locs()->temp(0).fpu_reg()); | 1287 __ movss(element_address, locs()->temp(0).fpu_reg()); |
| 1195 break; | 1288 break; |
| 1196 case kFloat64ArrayCid: | 1289 case kFloat64ArrayCid: |
| 1197 __ movsd(element_address, locs()->in(2).fpu_reg()); | 1290 __ movsd(element_address, locs()->in(2).fpu_reg()); |
| 1198 break; | 1291 break; |
| 1199 default: | 1292 default: |
| (...skipping 1659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2859 PcDescriptors::kOther, | 2952 PcDescriptors::kOther, |
| 2860 locs()); | 2953 locs()); |
| 2861 __ Drop(2); // Discard type arguments and receiver. | 2954 __ Drop(2); // Discard type arguments and receiver. |
| 2862 } | 2955 } |
| 2863 | 2956 |
| 2864 } // namespace dart | 2957 } // namespace dart |
| 2865 | 2958 |
| 2866 #undef __ | 2959 #undef __ |
| 2867 | 2960 |
| 2868 #endif // defined TARGET_ARCH_X64 | 2961 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |