OLD | NEW |
1 | 1 |
2 // Copyright 2012 the V8 project authors. All rights reserved. | 2 // Copyright 2012 the V8 project authors. All rights reserved. |
3 // Use of this source code is governed by a BSD-style license that can be | 3 // Use of this source code is governed by a BSD-style license that can be |
4 // found in the LICENSE file. | 4 // found in the LICENSE file. |
5 | 5 |
6 #include <limits.h> // For LONG_MIN, LONG_MAX. | 6 #include <limits.h> // For LONG_MIN, LONG_MAX. |
7 | 7 |
8 #if V8_TARGET_ARCH_MIPS | 8 #if V8_TARGET_ARCH_MIPS |
9 | 9 |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 SmiUntag(scratch); | 492 SmiUntag(scratch); |
493 | 493 |
494 // Xor original key with a seed. | 494 // Xor original key with a seed. |
495 xor_(reg0, reg0, scratch); | 495 xor_(reg0, reg0, scratch); |
496 | 496 |
497 // Compute the hash code from the untagged key. This must be kept in sync | 497 // Compute the hash code from the untagged key. This must be kept in sync |
498 // with ComputeIntegerHash in utils.h. | 498 // with ComputeIntegerHash in utils.h. |
499 // | 499 // |
500 // hash = ~hash + (hash << 15); | 500 // hash = ~hash + (hash << 15); |
501 nor(scratch, reg0, zero_reg); | 501 nor(scratch, reg0, zero_reg); |
502 sll(at, reg0, 15); | 502 Lsa(reg0, scratch, reg0, 15); |
503 addu(reg0, scratch, at); | |
504 | 503 |
505 // hash = hash ^ (hash >> 12); | 504 // hash = hash ^ (hash >> 12); |
506 srl(at, reg0, 12); | 505 srl(at, reg0, 12); |
507 xor_(reg0, reg0, at); | 506 xor_(reg0, reg0, at); |
508 | 507 |
509 // hash = hash + (hash << 2); | 508 // hash = hash + (hash << 2); |
510 sll(at, reg0, 2); | 509 Lsa(reg0, reg0, reg0, 2); |
511 addu(reg0, reg0, at); | |
512 | 510 |
513 // hash = hash ^ (hash >> 4); | 511 // hash = hash ^ (hash >> 4); |
514 srl(at, reg0, 4); | 512 srl(at, reg0, 4); |
515 xor_(reg0, reg0, at); | 513 xor_(reg0, reg0, at); |
516 | 514 |
517 // hash = hash * 2057; | 515 // hash = hash * 2057; |
518 sll(scratch, reg0, 11); | 516 sll(scratch, reg0, 11); |
519 sll(at, reg0, 3); | 517 Lsa(reg0, reg0, reg0, 3); |
520 addu(reg0, reg0, at); | |
521 addu(reg0, reg0, scratch); | 518 addu(reg0, reg0, scratch); |
522 | 519 |
523 // hash = hash ^ (hash >> 16); | 520 // hash = hash ^ (hash >> 16); |
524 srl(at, reg0, 16); | 521 srl(at, reg0, 16); |
525 xor_(reg0, reg0, at); | 522 xor_(reg0, reg0, at); |
526 And(reg0, reg0, Operand(0x3fffffff)); | 523 And(reg0, reg0, Operand(0x3fffffff)); |
527 } | 524 } |
528 | 525 |
529 | 526 |
530 void MacroAssembler::LoadFromNumberDictionary(Label* miss, | 527 void MacroAssembler::LoadFromNumberDictionary(Label* miss, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 // Use reg2 for index calculations and keep the hash intact in reg0. | 567 // Use reg2 for index calculations and keep the hash intact in reg0. |
571 mov(reg2, reg0); | 568 mov(reg2, reg0); |
572 // Compute the masked index: (hash + i + i * i) & mask. | 569 // Compute the masked index: (hash + i + i * i) & mask. |
573 if (i > 0) { | 570 if (i > 0) { |
574 Addu(reg2, reg2, Operand(SeededNumberDictionary::GetProbeOffset(i))); | 571 Addu(reg2, reg2, Operand(SeededNumberDictionary::GetProbeOffset(i))); |
575 } | 572 } |
576 and_(reg2, reg2, reg1); | 573 and_(reg2, reg2, reg1); |
577 | 574 |
578 // Scale the index by multiplying by the element size. | 575 // Scale the index by multiplying by the element size. |
579 DCHECK(SeededNumberDictionary::kEntrySize == 3); | 576 DCHECK(SeededNumberDictionary::kEntrySize == 3); |
580 sll(at, reg2, 1); // 2x. | 577 Lsa(reg2, reg2, reg2, 1); // reg2 = reg2 * 3. |
581 addu(reg2, reg2, at); // reg2 = reg2 * 3. | |
582 | 578 |
583 // Check if the key is identical to the name. | 579 // Check if the key is identical to the name. |
584 sll(at, reg2, kPointerSizeLog2); | 580 Lsa(reg2, elements, reg2, kPointerSizeLog2); |
585 addu(reg2, elements, at); | |
586 | 581 |
587 lw(at, FieldMemOperand(reg2, SeededNumberDictionary::kElementsStartOffset)); | 582 lw(at, FieldMemOperand(reg2, SeededNumberDictionary::kElementsStartOffset)); |
588 if (i != kNumberDictionaryProbes - 1) { | 583 if (i != kNumberDictionaryProbes - 1) { |
589 Branch(&done, eq, key, Operand(at)); | 584 Branch(&done, eq, key, Operand(at)); |
590 } else { | 585 } else { |
591 Branch(miss, ne, key, Operand(at)); | 586 Branch(miss, ne, key, Operand(at)); |
592 } | 587 } |
593 } | 588 } |
594 | 589 |
595 bind(&done); | 590 bind(&done); |
(...skipping 2809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3405 li(result_end, Operand(isolate()->factory()->one_pointer_filler_map())); | 3400 li(result_end, Operand(isolate()->factory()->one_pointer_filler_map())); |
3406 sw(result_end, MemOperand(result)); | 3401 sw(result_end, MemOperand(result)); |
3407 Addu(result, result, Operand(kDoubleSize / 2)); | 3402 Addu(result, result, Operand(kDoubleSize / 2)); |
3408 bind(&aligned); | 3403 bind(&aligned); |
3409 } | 3404 } |
3410 | 3405 |
3411 // Calculate new top and bail out if new space is exhausted. Use result | 3406 // Calculate new top and bail out if new space is exhausted. Use result |
3412 // to calculate the new top. Object size may be in words so a shift is | 3407 // to calculate the new top. Object size may be in words so a shift is |
3413 // required to get the number of bytes. | 3408 // required to get the number of bytes. |
3414 if ((flags & SIZE_IN_WORDS) != 0) { | 3409 if ((flags & SIZE_IN_WORDS) != 0) { |
3415 sll(result_end, object_size, kPointerSizeLog2); | 3410 Lsa(result_end, result, object_size, kPointerSizeLog2); |
3416 Addu(result_end, result, result_end); | |
3417 } else { | 3411 } else { |
3418 Addu(result_end, result, Operand(object_size)); | 3412 Addu(result_end, result, Operand(object_size)); |
3419 } | 3413 } |
3420 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit)); | 3414 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit)); |
3421 | 3415 |
3422 // Update allocation top. result temporarily holds the new top. | 3416 // Update allocation top. result temporarily holds the new top. |
3423 if (emit_debug_code()) { | 3417 if (emit_debug_code()) { |
3424 And(alloc_limit, result_end, Operand(kObjectAlignmentMask)); | 3418 And(alloc_limit, result_end, Operand(kObjectAlignmentMask)); |
3425 Check(eq, kUnalignedAllocationInNewSpace, alloc_limit, Operand(zero_reg)); | 3419 Check(eq, kUnalignedAllocationInNewSpace, alloc_limit, Operand(zero_reg)); |
3426 } | 3420 } |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3768 | 3762 |
3769 // Check for nan: all NaN values have a value greater (signed) than 0x7ff00000 | 3763 // Check for nan: all NaN values have a value greater (signed) than 0x7ff00000 |
3770 // in the exponent. | 3764 // in the exponent. |
3771 li(scratch1, Operand(kHoleNanUpper32 & HeapNumber::kExponentMask)); | 3765 li(scratch1, Operand(kHoleNanUpper32 & HeapNumber::kExponentMask)); |
3772 lw(exponent_reg, FieldMemOperand(value_reg, HeapNumber::kExponentOffset)); | 3766 lw(exponent_reg, FieldMemOperand(value_reg, HeapNumber::kExponentOffset)); |
3773 Branch(&maybe_nan, ge, exponent_reg, Operand(scratch1)); | 3767 Branch(&maybe_nan, ge, exponent_reg, Operand(scratch1)); |
3774 | 3768 |
3775 lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset)); | 3769 lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset)); |
3776 | 3770 |
3777 bind(&have_double_value); | 3771 bind(&have_double_value); |
3778 sll(scratch1, key_reg, kDoubleSizeLog2 - kSmiTagSize); | 3772 Lsa(scratch1, elements_reg, key_reg, kDoubleSizeLog2 - kSmiTagSize); |
3779 Addu(scratch1, scratch1, elements_reg); | |
3780 sw(mantissa_reg, | 3773 sw(mantissa_reg, |
3781 FieldMemOperand(scratch1, FixedDoubleArray::kHeaderSize - elements_offset | 3774 FieldMemOperand(scratch1, FixedDoubleArray::kHeaderSize - elements_offset |
3782 + kHoleNanLower32Offset)); | 3775 + kHoleNanLower32Offset)); |
3783 sw(exponent_reg, | 3776 sw(exponent_reg, |
3784 FieldMemOperand(scratch1, FixedDoubleArray::kHeaderSize - elements_offset | 3777 FieldMemOperand(scratch1, FixedDoubleArray::kHeaderSize - elements_offset |
3785 + kHoleNanUpper32Offset)); | 3778 + kHoleNanUpper32Offset)); |
3786 jmp(&done); | 3779 jmp(&done); |
3787 | 3780 |
3788 bind(&maybe_nan); | 3781 bind(&maybe_nan); |
3789 // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise | 3782 // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise |
3790 // it's an Infinity, and the non-NaN code path applies. | 3783 // it's an Infinity, and the non-NaN code path applies. |
3791 Branch(&is_nan, gt, exponent_reg, Operand(scratch1)); | 3784 Branch(&is_nan, gt, exponent_reg, Operand(scratch1)); |
3792 lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset)); | 3785 lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset)); |
3793 Branch(&have_double_value, eq, mantissa_reg, Operand(zero_reg)); | 3786 Branch(&have_double_value, eq, mantissa_reg, Operand(zero_reg)); |
3794 bind(&is_nan); | 3787 bind(&is_nan); |
3795 // Load canonical NaN for storing into the double array. | 3788 // Load canonical NaN for storing into the double array. |
3796 LoadRoot(at, Heap::kNanValueRootIndex); | 3789 LoadRoot(at, Heap::kNanValueRootIndex); |
3797 lw(mantissa_reg, FieldMemOperand(at, HeapNumber::kMantissaOffset)); | 3790 lw(mantissa_reg, FieldMemOperand(at, HeapNumber::kMantissaOffset)); |
3798 lw(exponent_reg, FieldMemOperand(at, HeapNumber::kExponentOffset)); | 3791 lw(exponent_reg, FieldMemOperand(at, HeapNumber::kExponentOffset)); |
3799 jmp(&have_double_value); | 3792 jmp(&have_double_value); |
3800 | 3793 |
3801 bind(&smi_value); | 3794 bind(&smi_value); |
3802 Addu(scratch1, elements_reg, | 3795 Addu(scratch1, elements_reg, |
3803 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag - | 3796 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag - |
3804 elements_offset)); | 3797 elements_offset)); |
3805 sll(scratch2, key_reg, kDoubleSizeLog2 - kSmiTagSize); | 3798 Lsa(scratch1, scratch1, key_reg, kDoubleSizeLog2 - kSmiTagSize); |
3806 Addu(scratch1, scratch1, scratch2); | |
3807 // scratch1 is now effective address of the double element | 3799 // scratch1 is now effective address of the double element |
3808 | 3800 |
3809 Register untagged_value = scratch2; | 3801 Register untagged_value = scratch2; |
3810 SmiUntag(untagged_value, value_reg); | 3802 SmiUntag(untagged_value, value_reg); |
3811 mtc1(untagged_value, f2); | 3803 mtc1(untagged_value, f2); |
3812 cvt_d_w(f0, f2); | 3804 cvt_d_w(f0, f2); |
3813 sdc1(f0, MemOperand(scratch1, 0)); | 3805 sdc1(f0, MemOperand(scratch1, 0)); |
3814 bind(&done); | 3806 bind(&done); |
3815 } | 3807 } |
3816 | 3808 |
(...skipping 1121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4938 | 4930 |
4939 // Pop the arguments, restore registers, and return. | 4931 // Pop the arguments, restore registers, and return. |
4940 mov(sp, fp); // Respect ABI stack constraint. | 4932 mov(sp, fp); // Respect ABI stack constraint. |
4941 lw(fp, MemOperand(sp, ExitFrameConstants::kCallerFPOffset)); | 4933 lw(fp, MemOperand(sp, ExitFrameConstants::kCallerFPOffset)); |
4942 lw(ra, MemOperand(sp, ExitFrameConstants::kCallerPCOffset)); | 4934 lw(ra, MemOperand(sp, ExitFrameConstants::kCallerPCOffset)); |
4943 | 4935 |
4944 if (argument_count.is_valid()) { | 4936 if (argument_count.is_valid()) { |
4945 if (argument_count_is_length) { | 4937 if (argument_count_is_length) { |
4946 addu(sp, sp, argument_count); | 4938 addu(sp, sp, argument_count); |
4947 } else { | 4939 } else { |
4948 sll(t8, argument_count, kPointerSizeLog2); | 4940 Lsa(sp, sp, argument_count, kPointerSizeLog2, t8); |
4949 addu(sp, sp, t8); | |
4950 } | 4941 } |
4951 } | 4942 } |
4952 | 4943 |
4953 if (do_return) { | 4944 if (do_return) { |
4954 Ret(USE_DELAY_SLOT); | 4945 Ret(USE_DELAY_SLOT); |
4955 // If returning, the instruction in the delay slot will be the addiu below. | 4946 // If returning, the instruction in the delay slot will be the addiu below. |
4956 } | 4947 } |
4957 addiu(sp, sp, 8); | 4948 addiu(sp, sp, 8); |
4958 } | 4949 } |
4959 | 4950 |
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5466 | 5457 |
5467 | 5458 |
5468 void MacroAssembler::GetMarkBits(Register addr_reg, | 5459 void MacroAssembler::GetMarkBits(Register addr_reg, |
5469 Register bitmap_reg, | 5460 Register bitmap_reg, |
5470 Register mask_reg) { | 5461 Register mask_reg) { |
5471 DCHECK(!AreAliased(addr_reg, bitmap_reg, mask_reg, no_reg)); | 5462 DCHECK(!AreAliased(addr_reg, bitmap_reg, mask_reg, no_reg)); |
5472 And(bitmap_reg, addr_reg, Operand(~Page::kPageAlignmentMask)); | 5463 And(bitmap_reg, addr_reg, Operand(~Page::kPageAlignmentMask)); |
5473 Ext(mask_reg, addr_reg, kPointerSizeLog2, Bitmap::kBitsPerCellLog2); | 5464 Ext(mask_reg, addr_reg, kPointerSizeLog2, Bitmap::kBitsPerCellLog2); |
5474 const int kLowBits = kPointerSizeLog2 + Bitmap::kBitsPerCellLog2; | 5465 const int kLowBits = kPointerSizeLog2 + Bitmap::kBitsPerCellLog2; |
5475 Ext(t8, addr_reg, kLowBits, kPageSizeBits - kLowBits); | 5466 Ext(t8, addr_reg, kLowBits, kPageSizeBits - kLowBits); |
5476 sll(t8, t8, kPointerSizeLog2); | 5467 Lsa(bitmap_reg, bitmap_reg, t8, kPointerSizeLog2, t8); |
5477 Addu(bitmap_reg, bitmap_reg, t8); | |
5478 li(t8, Operand(1)); | 5468 li(t8, Operand(1)); |
5479 sllv(mask_reg, t8, mask_reg); | 5469 sllv(mask_reg, t8, mask_reg); |
5480 } | 5470 } |
5481 | 5471 |
5482 | 5472 |
5483 void MacroAssembler::JumpIfWhite(Register value, Register bitmap_scratch, | 5473 void MacroAssembler::JumpIfWhite(Register value, Register bitmap_scratch, |
5484 Register mask_scratch, Register load_scratch, | 5474 Register mask_scratch, Register load_scratch, |
5485 Label* value_is_white) { | 5475 Label* value_is_white) { |
5486 DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, t8)); | 5476 DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, t8)); |
5487 GetMarkBits(value, bitmap_scratch, mask_scratch); | 5477 GetMarkBits(value, bitmap_scratch, mask_scratch); |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5788 if (mag.shift > 0) sra(result, result, mag.shift); | 5778 if (mag.shift > 0) sra(result, result, mag.shift); |
5789 srl(at, dividend, 31); | 5779 srl(at, dividend, 31); |
5790 Addu(result, result, Operand(at)); | 5780 Addu(result, result, Operand(at)); |
5791 } | 5781 } |
5792 | 5782 |
5793 | 5783 |
5794 } // namespace internal | 5784 } // namespace internal |
5795 } // namespace v8 | 5785 } // namespace v8 |
5796 | 5786 |
5797 #endif // V8_TARGET_ARCH_MIPS | 5787 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |