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 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1047 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function()))); | 1047 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function()))); |
1048 __ movl(EDX, Immediate(NativeArguments::ComputeArgcTag(function()))); | 1048 __ movl(EDX, Immediate(NativeArguments::ComputeArgcTag(function()))); |
1049 compiler->GenerateCall(token_pos(), | 1049 compiler->GenerateCall(token_pos(), |
1050 &StubCode::CallNativeCFunctionLabel(), | 1050 &StubCode::CallNativeCFunctionLabel(), |
1051 PcDescriptors::kOther, | 1051 PcDescriptors::kOther, |
1052 locs()); | 1052 locs()); |
1053 __ popl(result); | 1053 __ popl(result); |
1054 } | 1054 } |
1055 | 1055 |
1056 | 1056 |
1057 static bool CanBeImmediateIndex(Value* index) { | 1057 static bool CanBeImmediateIndex(Value* index, intptr_t cid) { |
1058 if (!index->definition()->IsConstant()) return false; | 1058 if (!index->definition()->IsConstant()) return false; |
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 int64_t disp = smi_const.AsInt64Value() * kWordSize + sizeof(RawArray); | 1062 const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid); |
| 1063 const intptr_t data_offset = FlowGraphCompiler::DataOffsetFor(cid); |
| 1064 const int64_t disp = smi_const.AsInt64Value() * scale + data_offset; |
1063 return Utils::IsInt(32, disp); | 1065 return Utils::IsInt(32, disp); |
1064 } | 1066 } |
1065 | 1067 |
1066 | 1068 |
1067 LocationSummary* StringCharCodeAtInstr::MakeLocationSummary() const { | 1069 LocationSummary* StringCharCodeAtInstr::MakeLocationSummary() const { |
1068 const intptr_t kNumInputs = 2; | 1070 const intptr_t kNumInputs = 2; |
1069 const intptr_t kNumTemps = 0; | 1071 const intptr_t kNumTemps = 0; |
1070 LocationSummary* locs = | 1072 LocationSummary* locs = |
1071 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1073 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1072 locs->set_in(0, Location::RequiresRegister()); | 1074 locs->set_in(0, Location::RequiresRegister()); |
1073 // TODO(fschneider): Allow immediate operands for the index. | 1075 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
1074 locs->set_in(1, Location::RequiresRegister()); | 1076 ? Location::RegisterOrSmiConstant(index()) |
| 1077 : Location::RequiresRegister()); |
1075 locs->set_out(Location::RequiresRegister()); | 1078 locs->set_out(Location::RequiresRegister()); |
1076 return locs; | 1079 return locs; |
1077 } | 1080 } |
1078 | 1081 |
1079 | 1082 |
1080 void StringCharCodeAtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1083 void StringCharCodeAtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1081 Register str = locs()->in(0).reg(); | 1084 Register str = locs()->in(0).reg(); |
1082 Register index = locs()->in(1).reg(); | 1085 Location index = locs()->in(1); |
1083 Register result = locs()->out().reg(); | 1086 Register result = locs()->out().reg(); |
1084 | 1087 |
1085 ASSERT((class_id() == kOneByteStringCid) || | 1088 ASSERT((class_id() == kOneByteStringCid) || |
1086 (class_id() == kTwoByteStringCid)); | 1089 (class_id() == kTwoByteStringCid)); |
| 1090 |
| 1091 FieldAddress element_address = index.IsRegister() ? |
| 1092 FlowGraphCompiler::ElementAddressForRegIndex( |
| 1093 class_id(), str, index.reg()) : |
| 1094 FlowGraphCompiler::ElementAddressForIntIndex( |
| 1095 class_id(), str, Smi::Cast(index.constant()).Value()); |
| 1096 |
1087 if (class_id() == kOneByteStringCid) { | 1097 if (class_id() == kOneByteStringCid) { |
1088 __ SmiUntag(index); | 1098 if (index.IsRegister()) { |
1089 __ movzxb(result, FieldAddress(str, | 1099 __ SmiUntag(index.reg()); |
1090 index, | 1100 } |
1091 TIMES_1, | 1101 __ movzxb(result, element_address); |
1092 OneByteString::data_offset())); | 1102 if (index.IsRegister()) { |
1093 __ SmiTag(index); // Retag index. | 1103 __ SmiTag(index.reg()); // Retag index. |
| 1104 } |
1094 __ SmiTag(result); | 1105 __ SmiTag(result); |
1095 } else { | 1106 } else { |
1096 // Don't untag smi-index and use TIMES_1 for two byte strings. | 1107 // Don't untag smi-index and use TIMES_1 for two byte strings. |
1097 __ movzxw(result, FieldAddress(str, | 1108 __ movzxw(result, element_address); |
1098 index, | |
1099 TIMES_1, | |
1100 TwoByteString::data_offset())); | |
1101 __ SmiTag(result); | 1109 __ SmiTag(result); |
1102 } | 1110 } |
1103 } | 1111 } |
1104 | 1112 |
1105 | 1113 |
1106 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { | 1114 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { |
1107 const intptr_t kNumInputs = 1; | 1115 const intptr_t kNumInputs = 1; |
1108 const intptr_t kNumTemps = 0; | 1116 const intptr_t kNumTemps = 0; |
1109 LocationSummary* locs = | 1117 LocationSummary* locs = |
1110 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1118 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
(...skipping 15 matching lines...) Expand all Loading... |
1126 Symbols::kNullCharCodeSymbolOffset * kWordSize)); | 1134 Symbols::kNullCharCodeSymbolOffset * kWordSize)); |
1127 } | 1135 } |
1128 | 1136 |
1129 | 1137 |
1130 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 1138 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
1131 const intptr_t kNumInputs = 2; | 1139 const intptr_t kNumInputs = 2; |
1132 const intptr_t kNumTemps = 0; | 1140 const intptr_t kNumTemps = 0; |
1133 LocationSummary* locs = | 1141 LocationSummary* locs = |
1134 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1142 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1135 locs->set_in(0, Location::RequiresRegister()); | 1143 locs->set_in(0, Location::RequiresRegister()); |
1136 locs->set_in(1, CanBeImmediateIndex(index()) | 1144 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
1137 ? Location::RegisterOrConstant(index()) | 1145 ? Location::RegisterOrSmiConstant(index()) |
1138 : Location::RequiresRegister()); | 1146 : Location::RequiresRegister()); |
1139 if (representation() == kUnboxedDouble) { | 1147 if (representation() == kUnboxedDouble) { |
1140 locs->set_out(Location::RequiresXmmRegister()); | 1148 locs->set_out(Location::RequiresXmmRegister()); |
1141 } else { | 1149 } else { |
1142 locs->set_out(Location::RequiresRegister()); | 1150 locs->set_out(Location::RequiresRegister()); |
1143 } | 1151 } |
1144 return locs; | 1152 return locs; |
1145 } | 1153 } |
1146 | 1154 |
1147 | 1155 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1207 __ movl(result, element_address); | 1215 __ movl(result, element_address); |
1208 } | 1216 } |
1209 | 1217 |
1210 | 1218 |
1211 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1219 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
1212 const intptr_t kNumInputs = 3; | 1220 const intptr_t kNumInputs = 3; |
1213 const intptr_t kNumTemps = 0; | 1221 const intptr_t kNumTemps = 0; |
1214 LocationSummary* locs = | 1222 LocationSummary* locs = |
1215 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1223 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1216 locs->set_in(0, Location::RequiresRegister()); | 1224 locs->set_in(0, Location::RequiresRegister()); |
1217 locs->set_in(1, CanBeImmediateIndex(index()) | 1225 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
1218 ? Location::RegisterOrConstant(index()) | 1226 ? Location::RegisterOrSmiConstant(index()) |
1219 : Location::RequiresRegister()); | 1227 : Location::RequiresRegister()); |
1220 switch (class_id()) { | 1228 switch (class_id()) { |
1221 case kArrayCid: | 1229 case kArrayCid: |
1222 locs->set_in(2, ShouldEmitStoreBarrier() | 1230 locs->set_in(2, ShouldEmitStoreBarrier() |
1223 ? Location::WritableRegister() | 1231 ? Location::WritableRegister() |
1224 : Location::RegisterOrConstant(value())); | 1232 : Location::RegisterOrConstant(value())); |
1225 break; | 1233 break; |
1226 case kUint8ArrayCid: | 1234 case kUint8ArrayCid: |
1227 // TODO(fschneider): Add location constraint for byte registers (EAX, | 1235 // TODO(fschneider): Add location constraint for byte registers (EAX, |
1228 // EBX, ECX, EDX) instead of using a fixed register. | 1236 // EBX, ECX, EDX) instead of using a fixed register. |
(...skipping 1623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2852 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. | 2860 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. |
2853 __ pxor(value, XMM0); | 2861 __ pxor(value, XMM0); |
2854 } | 2862 } |
2855 | 2863 |
2856 | 2864 |
2857 } // namespace dart | 2865 } // namespace dart |
2858 | 2866 |
2859 #undef __ | 2867 #undef __ |
2860 | 2868 |
2861 #endif // defined TARGET_ARCH_X64 | 2869 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |