Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(515)

Side by Side Diff: runtime/vm/intermediate_language_ia32.cc

Issue 539153002: Port and integrate the irregexp engine from V8 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Squashed all irregexp CLs, addressed comments. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_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 "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 1198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 } 1209 }
1210 break; 1210 break;
1211 default: 1211 default:
1212 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); 1212 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1213 __ movl(result, element_address); 1213 __ movl(result, element_address);
1214 break; 1214 break;
1215 } 1215 }
1216 } 1216 }
1217 1217
1218 1218
1219 Representation LoadCodeUnitsInstr::representation() const {
1220 switch (class_id()) {
1221 case kOneByteStringCid:
1222 case kExternalOneByteStringCid:
1223 // TODO(jgruber): kUnboxedUint32 could be a better choice.
1224 return element_count() < 4 ? kTagged : kUnboxedMint;
1225 case kTwoByteStringCid:
1226 case kExternalTwoByteStringCid:
1227 return element_count() < 2 ? kTagged : kUnboxedMint;
1228 default:
1229 UNIMPLEMENTED();
1230 return kTagged;
1231 }
1232 }
1233
1234
1235 LocationSummary* LoadCodeUnitsInstr::MakeLocationSummary(Isolate* isolate,
1236 bool opt) const {
1237 const intptr_t kNumInputs = 2;
1238 const intptr_t kNumTemps = 0;
1239 LocationSummary* locs = new(isolate) LocationSummary(
1240 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1241 locs->set_in(0, Location::RequiresRegister());
1242 // The smi index is either untagged (element size == 1), or it is left smi
1243 // tagged (for all element sizes > 1).
1244 locs->set_in(1, (index_scale() == 1) ? Location::WritableRegister()
1245 : Location::RequiresRegister());
1246
1247 if (representation() == kUnboxedMint) {
1248 locs->set_out(0, Location::Pair(Location::RequiresRegister(),
1249 Location::RequiresRegister()));
1250 } else {
1251 ASSERT(representation() == kTagged);
1252 locs->set_out(0, Location::RequiresRegister());
1253 }
1254
1255 return locs;
1256 }
1257
1258
1259 void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1260 const Register array = locs()->in(0).reg();
1261 const Location index = locs()->in(1);
1262
1263 Address element_address = Assembler::ElementAddressForRegIndex(
1264 IsExternal(), class_id(), index_scale(), array, index.reg());
1265
1266 if ((index_scale() == 1)) {
1267 __ SmiUntag(index.reg());
1268 }
1269
1270 if (representation() == kUnboxedMint) {
1271 ASSERT(locs()->out(0).IsPairLocation());
1272 PairLocation* result_pair = locs()->out(0).AsPairLocation();
1273 Register result1 = result_pair->At(0).reg();
1274 Register result2 = result_pair->At(1).reg();
1275 switch (class_id()) {
1276 case kOneByteStringCid:
1277 case kExternalOneByteStringCid:
1278 ASSERT(element_count() == 4);
1279 __ movl(result1, element_address);
1280 __ xorl(result2, result2);
1281 break;
1282 case kTwoByteStringCid:
1283 case kExternalTwoByteStringCid:
1284 ASSERT(element_count() == 2);
1285 __ movl(result1, element_address);
1286 __ xorl(result2, result2);
1287 break;
1288 default:
1289 UNREACHABLE();
1290 }
1291 } else {
1292 ASSERT(representation() == kTagged);
1293 Register result = locs()->out(0).reg();
1294 switch (class_id()) {
1295 case kOneByteStringCid:
1296 case kExternalOneByteStringCid:
1297 switch (element_count()) {
1298 case 1: __ movzxb(result, element_address); break;
1299 case 2: __ movzxw(result, element_address); break;
1300 default: UNREACHABLE();
1301 }
1302 __ SmiTag(result);
1303 break;
1304 case kTwoByteStringCid:
1305 case kExternalTwoByteStringCid:
1306 switch (element_count()) {
1307 case 1: __ movzxw(result, element_address); break;
1308 default: UNREACHABLE();
1309 }
1310 __ SmiTag(result);
1311 break;
1312 default:
1313 UNREACHABLE();
1314 break;
1315 }
1316 }
1317 }
1318
1319
1219 Representation StoreIndexedInstr::RequiredInputRepresentation( 1320 Representation StoreIndexedInstr::RequiredInputRepresentation(
1220 intptr_t idx) const { 1321 intptr_t idx) const {
1221 // Array can be a Dart object or a pointer to external data. 1322 // Array can be a Dart object or a pointer to external data.
1222 if (idx == 0) return kNoRepresentation; // Flexible input representation. 1323 if (idx == 0) return kNoRepresentation; // Flexible input representation.
1223 if (idx == 1) return kTagged; // Index is a smi. 1324 if (idx == 1) return kTagged; // Index is a smi.
1224 ASSERT(idx == 2); 1325 ASSERT(idx == 2);
1225 switch (class_id_) { 1326 switch (class_id_) {
1226 case kArrayCid: 1327 case kArrayCid:
1227 case kOneByteStringCid: 1328 case kOneByteStringCid:
1228 case kTypedDataInt8ArrayCid: 1329 case kTypedDataInt8ArrayCid:
(...skipping 3446 matching lines...) Expand 10 before | Expand all | Expand 10 after
4675 __ movsd(Address(ESP, 0), locs()->in(0).fpu_reg()); 4776 __ movsd(Address(ESP, 0), locs()->in(0).fpu_reg());
4676 __ CallRuntime(TargetFunction(), InputCount()); 4777 __ CallRuntime(TargetFunction(), InputCount());
4677 __ fstpl(Address(ESP, 0)); 4778 __ fstpl(Address(ESP, 0));
4678 __ movsd(locs()->out(0).fpu_reg(), Address(ESP, 0)); 4779 __ movsd(locs()->out(0).fpu_reg(), Address(ESP, 0));
4679 // Restore ESP. 4780 // Restore ESP.
4680 __ movl(ESP, locs()->temp(0).reg()); 4781 __ movl(ESP, locs()->temp(0).reg());
4681 } 4782 }
4682 } 4783 }
4683 4784
4684 4785
4786 LocationSummary* CaseInsensitiveCompareUC16Instr::MakeLocationSummary(
4787 Isolate* isolate, bool opt) const {
4788 const intptr_t kNumTemps = 0;
4789 LocationSummary* summary = new(isolate) LocationSummary(
4790 isolate, InputCount(), kNumTemps, LocationSummary::kCall);
4791 summary->set_in(0, Location::RegisterLocation(EAX));
4792 summary->set_in(1, Location::RegisterLocation(ECX));
4793 summary->set_in(2, Location::RegisterLocation(EDX));
4794 summary->set_in(3, Location::RegisterLocation(EBX));
4795 summary->set_out(0, Location::RegisterLocation(EAX));
4796 return summary;
4797 }
4798
4799
4800 void CaseInsensitiveCompareUC16Instr::EmitNativeCode(
4801 FlowGraphCompiler* compiler) {
4802
4803 // Save ESP. EDI is chosen because it is callee saved so we do not need to
4804 // back it up before calling into the runtime.
4805 static const Register kSavedSPReg = EDI;
4806 __ movl(kSavedSPReg, ESP);
4807 __ ReserveAlignedFrameSpace(kWordSize * TargetFunction().argument_count());
4808
4809 __ movl(Address(ESP, + 0 * kWordSize), locs()->in(0).reg());
4810 __ movl(Address(ESP, + 1 * kWordSize), locs()->in(1).reg());
4811 __ movl(Address(ESP, + 2 * kWordSize), locs()->in(2).reg());
4812 __ movl(Address(ESP, + 3 * kWordSize), locs()->in(3).reg());
4813
4814 // Call the function.
4815 __ CallRuntime(TargetFunction(), TargetFunction().argument_count());
4816
4817 // Restore ESP.
4818 __ movl(ESP, kSavedSPReg);
4819 }
4820
4821
4685 LocationSummary* MathMinMaxInstr::MakeLocationSummary(Isolate* isolate, 4822 LocationSummary* MathMinMaxInstr::MakeLocationSummary(Isolate* isolate,
4686 bool opt) const { 4823 bool opt) const {
4687 if (result_cid() == kDoubleCid) { 4824 if (result_cid() == kDoubleCid) {
4688 const intptr_t kNumInputs = 2; 4825 const intptr_t kNumInputs = 2;
4689 const intptr_t kNumTemps = 1; 4826 const intptr_t kNumTemps = 1;
4690 LocationSummary* summary = new(isolate) LocationSummary( 4827 LocationSummary* summary = new(isolate) LocationSummary(
4691 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4828 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4692 summary->set_in(0, Location::RequiresFpuRegister()); 4829 summary->set_in(0, Location::RequiresFpuRegister());
4693 summary->set_in(1, Location::RequiresFpuRegister()); 4830 summary->set_in(1, Location::RequiresFpuRegister());
4694 // Reuse the left register so that code can be made shorter. 4831 // Reuse the left register so that code can be made shorter.
(...skipping 1822 matching lines...) Expand 10 before | Expand all | Expand 10 after
6517 } 6654 }
6518 6655
6519 // We can fall through if the successor is the next block in the list. 6656 // We can fall through if the successor is the next block in the list.
6520 // Otherwise, we need a jump. 6657 // Otherwise, we need a jump.
6521 if (!compiler->CanFallThroughTo(successor())) { 6658 if (!compiler->CanFallThroughTo(successor())) {
6522 __ jmp(compiler->GetJumpLabel(successor())); 6659 __ jmp(compiler->GetJumpLabel(successor()));
6523 } 6660 }
6524 } 6661 }
6525 6662
6526 6663
6664 LocationSummary* IndirectGotoInstr::MakeLocationSummary(Isolate* isolate,
6665 bool opt) const {
6666 const intptr_t kNumInputs = 1;
6667 const intptr_t kNumTemps = 1;
6668
6669 LocationSummary* locs = new(isolate) LocationSummary(
6670 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6671
6672 locs->set_in(0, Location::RequiresRegister());
6673 locs->set_temp(0, Location::RequiresRegister());
6674
6675 return locs;
6676 }
6677
6678
6679 void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6680 Register target_address_reg = locs()->temp_slot(0)->reg();
6681
6682 // Load from [current frame pointer] + kPcMarkerSlotFromFp.
6683 __ movl(target_address_reg, Address(EBP, kPcMarkerSlotFromFp * kWordSize));
6684
6685 // Add the offset.
6686 Register offset_reg = locs()->in(0).reg();
6687 __ SmiUntag(offset_reg);
6688 __ addl(target_address_reg, offset_reg);
6689
6690 // Jump to the absolute address.
6691 __ jmp(target_address_reg);
6692 }
6693
6694
6527 LocationSummary* StrictCompareInstr::MakeLocationSummary(Isolate* isolate, 6695 LocationSummary* StrictCompareInstr::MakeLocationSummary(Isolate* isolate,
6528 bool opt) const { 6696 bool opt) const {
6529 const intptr_t kNumInputs = 2; 6697 const intptr_t kNumInputs = 2;
6530 const intptr_t kNumTemps = 0; 6698 const intptr_t kNumTemps = 0;
6531 if (needs_number_check()) { 6699 if (needs_number_check()) {
6532 LocationSummary* locs = new(isolate) LocationSummary( 6700 LocationSummary* locs = new(isolate) LocationSummary(
6533 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); 6701 isolate, kNumInputs, kNumTemps, LocationSummary::kCall);
6534 locs->set_in(0, Location::RegisterLocation(EAX)); 6702 locs->set_in(0, Location::RegisterLocation(EAX));
6535 locs->set_in(1, Location::RegisterLocation(ECX)); 6703 locs->set_in(1, Location::RegisterLocation(ECX));
6536 locs->set_out(0, Location::RegisterLocation(EAX)); 6704 locs->set_out(0, Location::RegisterLocation(EAX));
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
6771 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6939 __ movl(EDX, Immediate(kInvalidObjectPointer));
6772 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6940 __ movl(EDX, Immediate(kInvalidObjectPointer));
6773 #endif 6941 #endif
6774 } 6942 }
6775 6943
6776 } // namespace dart 6944 } // namespace dart
6777 6945
6778 #undef __ 6946 #undef __
6779 6947
6780 #endif // defined TARGET_ARCH_IA32 6948 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698