OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_X87 | 5 #if V8_TARGET_ARCH_X87 |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 Register map) { | 694 Register map) { |
695 mov(map, FieldOperand(heap_object, HeapObject::kMapOffset)); | 695 mov(map, FieldOperand(heap_object, HeapObject::kMapOffset)); |
696 CmpInstanceType(map, type); | 696 CmpInstanceType(map, type); |
697 } | 697 } |
698 | 698 |
699 | 699 |
700 void MacroAssembler::CmpInstanceType(Register map, InstanceType type) { | 700 void MacroAssembler::CmpInstanceType(Register map, InstanceType type) { |
701 cmpb(FieldOperand(map, Map::kInstanceTypeOffset), Immediate(type)); | 701 cmpb(FieldOperand(map, Map::kInstanceTypeOffset), Immediate(type)); |
702 } | 702 } |
703 | 703 |
704 | |
705 void MacroAssembler::CheckFastElements(Register map, | |
706 Label* fail, | |
707 Label::Distance distance) { | |
708 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | |
709 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | |
710 STATIC_ASSERT(FAST_ELEMENTS == 2); | |
711 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); | |
712 cmpb(FieldOperand(map, Map::kBitField2Offset), | |
713 Immediate(Map::kMaximumBitField2FastHoleyElementValue)); | |
714 j(above, fail, distance); | |
715 } | |
716 | |
717 | |
718 void MacroAssembler::CheckFastObjectElements(Register map, | 704 void MacroAssembler::CheckFastObjectElements(Register map, |
719 Label* fail, | 705 Label* fail, |
720 Label::Distance distance) { | 706 Label::Distance distance) { |
721 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | 707 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); |
722 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | 708 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
723 STATIC_ASSERT(FAST_ELEMENTS == 2); | 709 STATIC_ASSERT(FAST_ELEMENTS == 2); |
724 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); | 710 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); |
725 cmpb(FieldOperand(map, Map::kBitField2Offset), | 711 cmpb(FieldOperand(map, Map::kBitField2Offset), |
726 Immediate(Map::kMaximumBitField2FastHoleySmiElementValue)); | 712 Immediate(Map::kMaximumBitField2FastHoleySmiElementValue)); |
727 j(below_equal, fail, distance); | 713 j(below_equal, fail, distance); |
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1348 xor_(r0, scratch); | 1334 xor_(r0, scratch); |
1349 // hash = hash * 2057; | 1335 // hash = hash * 2057; |
1350 imul(r0, r0, 2057); | 1336 imul(r0, r0, 2057); |
1351 // hash = hash ^ (hash >> 16); | 1337 // hash = hash ^ (hash >> 16); |
1352 mov(scratch, r0); | 1338 mov(scratch, r0); |
1353 shr(scratch, 16); | 1339 shr(scratch, 16); |
1354 xor_(r0, scratch); | 1340 xor_(r0, scratch); |
1355 and_(r0, 0x3fffffff); | 1341 and_(r0, 0x3fffffff); |
1356 } | 1342 } |
1357 | 1343 |
1358 | |
1359 | |
1360 void MacroAssembler::LoadFromNumberDictionary(Label* miss, | |
1361 Register elements, | |
1362 Register key, | |
1363 Register r0, | |
1364 Register r1, | |
1365 Register r2, | |
1366 Register result) { | |
1367 // Register use: | |
1368 // | |
1369 // elements - holds the slow-case elements of the receiver and is unchanged. | |
1370 // | |
1371 // key - holds the smi key on entry and is unchanged. | |
1372 // | |
1373 // Scratch registers: | |
1374 // | |
1375 // r0 - holds the untagged key on entry and holds the hash once computed. | |
1376 // | |
1377 // r1 - used to hold the capacity mask of the dictionary | |
1378 // | |
1379 // r2 - used for the index into the dictionary. | |
1380 // | |
1381 // result - holds the result on exit if the load succeeds and we fall through. | |
1382 | |
1383 Label done; | |
1384 | |
1385 GetNumberHash(r0, r1); | |
1386 | |
1387 // Compute capacity mask. | |
1388 mov(r1, FieldOperand(elements, SeededNumberDictionary::kCapacityOffset)); | |
1389 shr(r1, kSmiTagSize); // convert smi to int | |
1390 dec(r1); | |
1391 | |
1392 // Generate an unrolled loop that performs a few probes before giving up. | |
1393 for (int i = 0; i < kNumberDictionaryProbes; i++) { | |
1394 // Use r2 for index calculations and keep the hash intact in r0. | |
1395 mov(r2, r0); | |
1396 // Compute the masked index: (hash + i + i * i) & mask. | |
1397 if (i > 0) { | |
1398 add(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i))); | |
1399 } | |
1400 and_(r2, r1); | |
1401 | |
1402 // Scale the index by multiplying by the entry size. | |
1403 DCHECK(SeededNumberDictionary::kEntrySize == 3); | |
1404 lea(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3 | |
1405 | |
1406 // Check if the key matches. | |
1407 cmp(key, FieldOperand(elements, | |
1408 r2, | |
1409 times_pointer_size, | |
1410 SeededNumberDictionary::kElementsStartOffset)); | |
1411 if (i != (kNumberDictionaryProbes - 1)) { | |
1412 j(equal, &done); | |
1413 } else { | |
1414 j(not_equal, miss); | |
1415 } | |
1416 } | |
1417 | |
1418 bind(&done); | |
1419 // Check that the value is a field property. | |
1420 const int kDetailsOffset = | |
1421 SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize; | |
1422 DCHECK_EQ(DATA, 0); | |
1423 test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), | |
1424 Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize)); | |
1425 j(not_zero, miss); | |
1426 | |
1427 // Get the value at the masked, scaled index. | |
1428 const int kValueOffset = | |
1429 SeededNumberDictionary::kElementsStartOffset + kPointerSize; | |
1430 mov(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); | |
1431 } | |
1432 | |
1433 | |
1434 void MacroAssembler::LoadAllocationTopHelper(Register result, | 1344 void MacroAssembler::LoadAllocationTopHelper(Register result, |
1435 Register scratch, | 1345 Register scratch, |
1436 AllocationFlags flags) { | 1346 AllocationFlags flags) { |
1437 ExternalReference allocation_top = | 1347 ExternalReference allocation_top = |
1438 AllocationUtils::GetAllocationTopReference(isolate(), flags); | 1348 AllocationUtils::GetAllocationTopReference(isolate(), flags); |
1439 | 1349 |
1440 // Just return if allocation top is already known. | 1350 // Just return if allocation top is already known. |
1441 if ((flags & RESULT_CONTAINS_TOP) != 0) { | 1351 if ((flags & RESULT_CONTAINS_TOP) != 0) { |
1442 // No use of scratch if allocation top is provided. | 1352 // No use of scratch if allocation top is provided. |
1443 DCHECK(scratch.is(no_reg)); | 1353 DCHECK(scratch.is(no_reg)); |
(...skipping 1860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3304 mov(eax, dividend); | 3214 mov(eax, dividend); |
3305 shr(eax, 31); | 3215 shr(eax, 31); |
3306 add(edx, eax); | 3216 add(edx, eax); |
3307 } | 3217 } |
3308 | 3218 |
3309 | 3219 |
3310 } // namespace internal | 3220 } // namespace internal |
3311 } // namespace v8 | 3221 } // namespace v8 |
3312 | 3222 |
3313 #endif // V8_TARGET_ARCH_X87 | 3223 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |