OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1215 // where base is -INFINITY or -0. | 1215 // where base is -INFINITY or -0. |
1216 | 1216 |
1217 // Add +0 to base. This has no effect other than turning -0 into +0. | 1217 // Add +0 to base. This has no effect other than turning -0 into +0. |
1218 __ Fmov(zero_double, 0.0); | 1218 __ Fmov(zero_double, 0.0); |
1219 __ Fadd(base_double, base_double, zero_double); | 1219 __ Fadd(base_double, base_double, zero_double); |
1220 // The operation -0+0 results in +0 in all cases except where the | 1220 // The operation -0+0 results in +0 in all cases except where the |
1221 // FPCR rounding mode is 'round towards minus infinity' (RM). The | 1221 // FPCR rounding mode is 'round towards minus infinity' (RM). The |
1222 // A64 simulator does not currently simulate FPCR (where the rounding | 1222 // A64 simulator does not currently simulate FPCR (where the rounding |
1223 // mode is set), so test the operation with some debug code. | 1223 // mode is set), so test the operation with some debug code. |
1224 if (masm->emit_debug_code()) { | 1224 if (masm->emit_debug_code()) { |
1225 Register temp = masm->Tmp1(); | 1225 UseScratchRegisterScope temps(masm); |
| 1226 Register temp = temps.AcquireX(); |
1226 // d5 zero_double The value +0.0 as a double. | 1227 // d5 zero_double The value +0.0 as a double. |
1227 __ Fneg(scratch0_double, zero_double); | 1228 __ Fneg(scratch0_double, zero_double); |
1228 // Verify that we correctly generated +0.0 and -0.0. | 1229 // Verify that we correctly generated +0.0 and -0.0. |
1229 // bits(+0.0) = 0x0000000000000000 | 1230 // bits(+0.0) = 0x0000000000000000 |
1230 // bits(-0.0) = 0x8000000000000000 | 1231 // bits(-0.0) = 0x8000000000000000 |
1231 __ Fmov(temp, zero_double); | 1232 __ Fmov(temp, zero_double); |
1232 __ CheckRegisterIsClear(temp, kCouldNotGenerateZero); | 1233 __ CheckRegisterIsClear(temp, kCouldNotGenerateZero); |
1233 __ Fmov(temp, scratch0_double); | 1234 __ Fmov(temp, scratch0_double); |
1234 __ Eor(temp, temp, kDSignMask); | 1235 __ Eor(temp, temp, kDSignMask); |
1235 __ CheckRegisterIsClear(temp, kCouldNotGenerateNegativeZero); | 1236 __ CheckRegisterIsClear(temp, kCouldNotGenerateNegativeZero); |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1493 | 1494 |
1494 // Store the return address on the stack, in the space previously allocated | 1495 // Store the return address on the stack, in the space previously allocated |
1495 // by EnterExitFrame. The return address is queried by | 1496 // by EnterExitFrame. The return address is queried by |
1496 // ExitFrame::GetStateForFramePointer. | 1497 // ExitFrame::GetStateForFramePointer. |
1497 Label return_location; | 1498 Label return_location; |
1498 __ Adr(x12, &return_location); | 1499 __ Adr(x12, &return_location); |
1499 __ Poke(x12, 0); | 1500 __ Poke(x12, 0); |
1500 if (__ emit_debug_code()) { | 1501 if (__ emit_debug_code()) { |
1501 // Verify that the slot below fp[kSPOffset]-8 points to the return location | 1502 // Verify that the slot below fp[kSPOffset]-8 points to the return location |
1502 // (currently in x12). | 1503 // (currently in x12). |
1503 Register temp = masm->Tmp1(); | 1504 UseScratchRegisterScope temps(masm); |
| 1505 Register temp = temps.AcquireX(); |
1504 __ Ldr(temp, MemOperand(fp, ExitFrameConstants::kSPOffset)); | 1506 __ Ldr(temp, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
1505 __ Ldr(temp, MemOperand(temp, -static_cast<int64_t>(kXRegSizeInBytes))); | 1507 __ Ldr(temp, MemOperand(temp, -static_cast<int64_t>(kXRegSizeInBytes))); |
1506 __ Cmp(temp, x12); | 1508 __ Cmp(temp, x12); |
1507 __ Check(eq, kReturnAddressNotFoundInFrame); | 1509 __ Check(eq, kReturnAddressNotFoundInFrame); |
1508 } | 1510 } |
1509 | 1511 |
1510 // Call the builtin. | 1512 // Call the builtin. |
1511 __ Blr(target); | 1513 __ Blr(target); |
1512 __ Bind(&return_location); | 1514 __ Bind(&return_location); |
1513 const Register& result = x0; | 1515 const Register& result = x0; |
(...skipping 3194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4708 value, | 4710 value, |
4709 1 << MemoryChunk::SCAN_ON_SCAVENGE, | 4711 1 << MemoryChunk::SCAN_ON_SCAVENGE, |
4710 &dont_need_remembered_set); | 4712 &dont_need_remembered_set); |
4711 | 4713 |
4712 // First notify the incremental marker if necessary, then update the | 4714 // First notify the incremental marker if necessary, then update the |
4713 // remembered set. | 4715 // remembered set. |
4714 CheckNeedsToInformIncrementalMarker( | 4716 CheckNeedsToInformIncrementalMarker( |
4715 masm, kUpdateRememberedSetOnNoNeedToInformIncrementalMarker, mode); | 4717 masm, kUpdateRememberedSetOnNoNeedToInformIncrementalMarker, mode); |
4716 InformIncrementalMarker(masm, mode); | 4718 InformIncrementalMarker(masm, mode); |
4717 regs_.Restore(masm); // Restore the extra scratch registers we used. | 4719 regs_.Restore(masm); // Restore the extra scratch registers we used. |
| 4720 |
| 4721 UseScratchRegisterScope temps(masm); |
4718 __ RememberedSetHelper(object_, | 4722 __ RememberedSetHelper(object_, |
4719 address_, | 4723 address_, |
4720 value_, | 4724 value_, // scratch1 |
| 4725 temps.AcquireX(), // scratch2 |
4721 save_fp_regs_mode_, | 4726 save_fp_regs_mode_, |
4722 MacroAssembler::kReturnAtEnd); | 4727 MacroAssembler::kReturnAtEnd); |
4723 | 4728 |
4724 __ Bind(&dont_need_remembered_set); | 4729 __ Bind(&dont_need_remembered_set); |
4725 } | 4730 } |
4726 | 4731 |
4727 CheckNeedsToInformIncrementalMarker( | 4732 CheckNeedsToInformIncrementalMarker( |
4728 masm, kReturnOnNoNeedToInformIncrementalMarker, mode); | 4733 masm, kReturnOnNoNeedToInformIncrementalMarker, mode); |
4729 InformIncrementalMarker(masm, mode); | 4734 InformIncrementalMarker(masm, mode); |
4730 regs_.Restore(masm); // Restore the extra scratch registers we used. | 4735 regs_.Restore(masm); // Restore the extra scratch registers we used. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4771 __ Subs(counter, counter, 1); | 4776 __ Subs(counter, counter, 1); |
4772 __ Str(counter, | 4777 __ Str(counter, |
4773 MemOperand(mem_chunk, MemoryChunk::kWriteBarrierCounterOffset)); | 4778 MemOperand(mem_chunk, MemoryChunk::kWriteBarrierCounterOffset)); |
4774 __ B(mi, &need_incremental); | 4779 __ B(mi, &need_incremental); |
4775 | 4780 |
4776 // If the object is not black we don't have to inform the incremental marker. | 4781 // If the object is not black we don't have to inform the incremental marker. |
4777 __ JumpIfBlack(regs_.object(), regs_.scratch0(), regs_.scratch1(), &on_black); | 4782 __ JumpIfBlack(regs_.object(), regs_.scratch0(), regs_.scratch1(), &on_black); |
4778 | 4783 |
4779 regs_.Restore(masm); // Restore the extra scratch registers we used. | 4784 regs_.Restore(masm); // Restore the extra scratch registers we used. |
4780 if (on_no_need == kUpdateRememberedSetOnNoNeedToInformIncrementalMarker) { | 4785 if (on_no_need == kUpdateRememberedSetOnNoNeedToInformIncrementalMarker) { |
| 4786 UseScratchRegisterScope temps(masm); |
4781 __ RememberedSetHelper(object_, | 4787 __ RememberedSetHelper(object_, |
4782 address_, | 4788 address_, |
4783 value_, | 4789 value_, // scratch1 |
| 4790 temps.AcquireX(), // scratch2 |
4784 save_fp_regs_mode_, | 4791 save_fp_regs_mode_, |
4785 MacroAssembler::kReturnAtEnd); | 4792 MacroAssembler::kReturnAtEnd); |
4786 } else { | 4793 } else { |
4787 __ Ret(); | 4794 __ Ret(); |
4788 } | 4795 } |
4789 | 4796 |
4790 __ Bind(&on_black); | 4797 __ Bind(&on_black); |
4791 // Get the value from the slot. | 4798 // Get the value from the slot. |
4792 Register value = regs_.scratch0(); | 4799 Register value = regs_.scratch0(); |
4793 __ Ldr(value, MemOperand(regs_.address())); | 4800 __ Ldr(value, MemOperand(regs_.address())); |
(...skipping 20 matching lines...) Expand all Loading... |
4814 __ EnsureNotWhite(value, | 4821 __ EnsureNotWhite(value, |
4815 regs_.scratch1(), // Scratch. | 4822 regs_.scratch1(), // Scratch. |
4816 regs_.object(), // Scratch. | 4823 regs_.object(), // Scratch. |
4817 regs_.address(), // Scratch. | 4824 regs_.address(), // Scratch. |
4818 regs_.scratch2(), // Scratch. | 4825 regs_.scratch2(), // Scratch. |
4819 &need_incremental_pop_scratch); | 4826 &need_incremental_pop_scratch); |
4820 __ Pop(regs_.object(), regs_.address()); | 4827 __ Pop(regs_.object(), regs_.address()); |
4821 | 4828 |
4822 regs_.Restore(masm); // Restore the extra scratch registers we used. | 4829 regs_.Restore(masm); // Restore the extra scratch registers we used. |
4823 if (on_no_need == kUpdateRememberedSetOnNoNeedToInformIncrementalMarker) { | 4830 if (on_no_need == kUpdateRememberedSetOnNoNeedToInformIncrementalMarker) { |
| 4831 UseScratchRegisterScope temps(masm); |
4824 __ RememberedSetHelper(object_, | 4832 __ RememberedSetHelper(object_, |
4825 address_, | 4833 address_, |
4826 value_, | 4834 value_, // scratch1 |
| 4835 temps.AcquireX(), // scratch2 |
4827 save_fp_regs_mode_, | 4836 save_fp_regs_mode_, |
4828 MacroAssembler::kReturnAtEnd); | 4837 MacroAssembler::kReturnAtEnd); |
4829 } else { | 4838 } else { |
4830 __ Ret(); | 4839 __ Ret(); |
4831 } | 4840 } |
4832 | 4841 |
4833 __ Bind(&need_incremental_pop_scratch); | 4842 __ Bind(&need_incremental_pop_scratch); |
4834 __ Pop(regs_.object(), regs_.address()); | 4843 __ Pop(regs_.object(), regs_.address()); |
4835 | 4844 |
4836 __ Bind(&need_incremental); | 4845 __ Bind(&need_incremental); |
(...skipping 10 matching lines...) Expand all Loading... |
4847 // Initially the stub is expected to be in STORE_BUFFER_ONLY mode, so 2 nops | 4856 // Initially the stub is expected to be in STORE_BUFFER_ONLY mode, so 2 nops |
4848 // are generated. | 4857 // are generated. |
4849 // See RecordWriteStub::Patch for details. | 4858 // See RecordWriteStub::Patch for details. |
4850 { | 4859 { |
4851 InstructionAccurateScope scope(masm, 2); | 4860 InstructionAccurateScope scope(masm, 2); |
4852 __ adr(xzr, &skip_to_incremental_noncompacting); | 4861 __ adr(xzr, &skip_to_incremental_noncompacting); |
4853 __ adr(xzr, &skip_to_incremental_compacting); | 4862 __ adr(xzr, &skip_to_incremental_compacting); |
4854 } | 4863 } |
4855 | 4864 |
4856 if (remembered_set_action_ == EMIT_REMEMBERED_SET) { | 4865 if (remembered_set_action_ == EMIT_REMEMBERED_SET) { |
| 4866 UseScratchRegisterScope temps(masm); |
4857 __ RememberedSetHelper(object_, | 4867 __ RememberedSetHelper(object_, |
4858 address_, | 4868 address_, |
4859 value_, | 4869 value_, // scratch1 |
| 4870 temps.AcquireX(), // scratch2 |
4860 save_fp_regs_mode_, | 4871 save_fp_regs_mode_, |
4861 MacroAssembler::kReturnAtEnd); | 4872 MacroAssembler::kReturnAtEnd); |
4862 } | 4873 } |
4863 __ Ret(); | 4874 __ Ret(); |
4864 | 4875 |
4865 __ Bind(&skip_to_incremental_noncompacting); | 4876 __ Bind(&skip_to_incremental_noncompacting); |
4866 GenerateIncremental(masm, INCREMENTAL); | 4877 GenerateIncremental(masm, INCREMENTAL); |
4867 | 4878 |
4868 __ Bind(&skip_to_incremental_compacting); | 4879 __ Bind(&skip_to_incremental_compacting); |
4869 GenerateIncremental(masm, INCREMENTAL_COMPACTION); | 4880 GenerateIncremental(masm, INCREMENTAL_COMPACTION); |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5081 __ Add(scratch2, scratch2, Operand( | 5092 __ Add(scratch2, scratch2, Operand( |
5082 NameDictionary::GetProbeOffset(i) << Name::kHashShift)); | 5093 NameDictionary::GetProbeOffset(i) << Name::kHashShift)); |
5083 } | 5094 } |
5084 __ And(scratch2, scratch1, Operand(scratch2, LSR, Name::kHashShift)); | 5095 __ And(scratch2, scratch1, Operand(scratch2, LSR, Name::kHashShift)); |
5085 | 5096 |
5086 // Scale the index by multiplying by the element size. | 5097 // Scale the index by multiplying by the element size. |
5087 ASSERT(NameDictionary::kEntrySize == 3); | 5098 ASSERT(NameDictionary::kEntrySize == 3); |
5088 __ Add(scratch2, scratch2, Operand(scratch2, LSL, 1)); | 5099 __ Add(scratch2, scratch2, Operand(scratch2, LSL, 1)); |
5089 | 5100 |
5090 // Check if the key is identical to the name. | 5101 // Check if the key is identical to the name. |
| 5102 UseScratchRegisterScope temps(masm); |
| 5103 Register scratch3 = temps.AcquireX(); |
5091 __ Add(scratch2, elements, Operand(scratch2, LSL, kPointerSizeLog2)); | 5104 __ Add(scratch2, elements, Operand(scratch2, LSL, kPointerSizeLog2)); |
5092 // TODO(jbramley): We need another scratch here, but some callers can't | 5105 __ Ldr(scratch3, FieldMemOperand(scratch2, kElementsStartOffset)); |
5093 // provide a scratch3 so we have to use Tmp1(). We should find a clean way | 5106 __ Cmp(name, scratch3); |
5094 // to make it unavailable to the MacroAssembler for a short time. | |
5095 __ Ldr(__ Tmp1(), FieldMemOperand(scratch2, kElementsStartOffset)); | |
5096 __ Cmp(name, __ Tmp1()); | |
5097 __ B(eq, done); | 5107 __ B(eq, done); |
5098 } | 5108 } |
5099 | 5109 |
5100 // The inlined probes didn't find the entry. | 5110 // The inlined probes didn't find the entry. |
5101 // Call the complete stub to scan the whole dictionary. | 5111 // Call the complete stub to scan the whole dictionary. |
5102 | 5112 |
5103 CPURegList spill_list(CPURegister::kRegister, kXRegSize, 0, 6); | 5113 CPURegList spill_list(CPURegister::kRegister, kXRegSize, 0, 6); |
5104 spill_list.Combine(lr); | 5114 spill_list.Combine(lr); |
5105 spill_list.Remove(scratch1); | 5115 spill_list.Remove(scratch1); |
5106 spill_list.Remove(scratch2); | 5116 spill_list.Remove(scratch2); |
(...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5799 MemOperand(fp, 6 * kPointerSize), | 5809 MemOperand(fp, 6 * kPointerSize), |
5800 NULL); | 5810 NULL); |
5801 } | 5811 } |
5802 | 5812 |
5803 | 5813 |
5804 #undef __ | 5814 #undef __ |
5805 | 5815 |
5806 } } // namespace v8::internal | 5816 } } // namespace v8::internal |
5807 | 5817 |
5808 #endif // V8_TARGET_ARCH_A64 | 5818 #endif // V8_TARGET_ARCH_A64 |
OLD | NEW |