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 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
730 } | 730 } |
731 } | 731 } |
732 | 732 |
733 | 733 |
734 // Abstracted stack operations. | 734 // Abstracted stack operations. |
735 | 735 |
736 | 736 |
737 void MacroAssembler::Push(const CPURegister& src0, const CPURegister& src1, | 737 void MacroAssembler::Push(const CPURegister& src0, const CPURegister& src1, |
738 const CPURegister& src2, const CPURegister& src3) { | 738 const CPURegister& src2, const CPURegister& src3) { |
739 ASSERT(AreSameSizeAndType(src0, src1, src2, src3)); | 739 ASSERT(AreSameSizeAndType(src0, src1, src2, src3)); |
740 ASSERT(src0.IsValid()); | |
741 | 740 |
742 int count = 1 + src1.IsValid() + src2.IsValid() + src3.IsValid(); | 741 int count = 1 + src1.IsValid() + src2.IsValid() + src3.IsValid(); |
743 int size = src0.SizeInBytes(); | 742 int size = src0.SizeInBytes(); |
744 | 743 |
745 PrepareForPush(count, size); | 744 PrepareForPush(count, size); |
746 PushHelper(count, size, src0, src1, src2, src3); | 745 PushHelper(count, size, src0, src1, src2, src3); |
747 } | 746 } |
748 | 747 |
749 | 748 |
749 void MacroAssembler::Push(const CPURegister& src0, const CPURegister& src1, | |
750 const CPURegister& src2, const CPURegister& src3, | |
751 const CPURegister& src4, const CPURegister& src5, | |
752 const CPURegister& src6, const CPURegister& src7) { | |
753 ASSERT(AreSameSizeAndType(src0, src1, src2, src3, src4, src5, src6, src7)); | |
754 | |
755 int count = 5 + src5.IsValid() + src6.IsValid() + src6.IsValid(); | |
756 int size = src0.SizeInBytes(); | |
757 | |
758 PrepareForPush(count, size); | |
759 PushHelper(4, size, src0, src1, src2, src3); | |
760 PushHelper(count - 4, size, src4, src5, src6, src7); | |
761 } | |
762 | |
763 | |
750 void MacroAssembler::Pop(const CPURegister& dst0, const CPURegister& dst1, | 764 void MacroAssembler::Pop(const CPURegister& dst0, const CPURegister& dst1, |
751 const CPURegister& dst2, const CPURegister& dst3) { | 765 const CPURegister& dst2, const CPURegister& dst3) { |
752 // It is not valid to pop into the same register more than once in one | 766 // It is not valid to pop into the same register more than once in one |
753 // instruction, not even into the zero register. | 767 // instruction, not even into the zero register. |
754 ASSERT(!AreAliased(dst0, dst1, dst2, dst3)); | 768 ASSERT(!AreAliased(dst0, dst1, dst2, dst3)); |
755 ASSERT(AreSameSizeAndType(dst0, dst1, dst2, dst3)); | 769 ASSERT(AreSameSizeAndType(dst0, dst1, dst2, dst3)); |
756 ASSERT(dst0.IsValid()); | 770 ASSERT(dst0.IsValid()); |
757 | 771 |
758 int count = 1 + dst1.IsValid() + dst2.IsValid() + dst3.IsValid(); | 772 int count = 1 + dst1.IsValid() + dst2.IsValid() + dst3.IsValid(); |
759 int size = dst0.SizeInBytes(); | 773 int size = dst0.SizeInBytes(); |
(...skipping 1656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2416 UNREACHABLE(); | 2430 UNREACHABLE(); |
2417 } | 2431 } |
2418 } | 2432 } |
2419 | 2433 |
2420 | 2434 |
2421 void MacroAssembler::CopyBytes(Register dst, | 2435 void MacroAssembler::CopyBytes(Register dst, |
2422 Register src, | 2436 Register src, |
2423 Register length, | 2437 Register length, |
2424 Register scratch, | 2438 Register scratch, |
2425 CopyHint hint) { | 2439 CopyHint hint) { |
2426 ASSERT(!AreAliased(src, dst, length, scratch)); | 2440 UseScratchRegisterScope temps(this); |
2441 Register tmp1 = temps.AcquireX(); | |
2442 Register tmp2 = temps.AcquireX(); | |
2443 ASSERT(!AreAliased(src, dst, length, scratch, tmp1, tmp2)); | |
2444 ASSERT(!AreAliased(src, dst, csp)); | |
2427 | 2445 |
2428 // TODO(all): Implement a faster copy function, and use hint to determine | |
2429 // which algorithm to use for copies. | |
2430 if (emit_debug_code()) { | 2446 if (emit_debug_code()) { |
2431 // Check copy length. | 2447 // Check copy length. |
2432 Cmp(length, 0); | 2448 Cmp(length, 0); |
2433 Assert(ge, kUnexpectedNegativeValue); | 2449 Assert(ge, kUnexpectedNegativeValue); |
2434 | 2450 |
2435 // Check src and dst buffers don't overlap. | 2451 // Check src and dst buffers don't overlap. |
2436 Add(scratch, src, length); // Calculate end of src buffer. | 2452 Add(scratch, src, length); // Calculate end of src buffer. |
2437 Cmp(scratch, dst); | 2453 Cmp(scratch, dst); |
2438 Add(scratch, dst, length); // Calculate end of dst buffer. | 2454 Add(scratch, dst, length); // Calculate end of dst buffer. |
2439 Ccmp(scratch, src, ZFlag, gt); | 2455 Ccmp(scratch, src, ZFlag, gt); |
2440 Assert(le, kCopyBuffersOverlap); | 2456 Assert(le, kCopyBuffersOverlap); |
2441 } | 2457 } |
2442 | 2458 |
2443 Label loop, done; | 2459 Label short_copy, short_loop, bulk_loop, done; |
2460 | |
2461 if ((hint == kCopyLong || hint == kCopyUnknown) && !FLAG_optimize_for_size) { | |
2462 Register bulk_length = scratch; | |
2463 int pair_size = 2 * kXRegSize; | |
2464 int pair_mask = pair_size - 1; | |
2465 | |
2466 Bics(bulk_length, length, pair_mask); | |
2467 Cbz(bulk_length, &short_copy); | |
ulan
2014/03/18 12:51:14
You probably wanted to use flags set by Bics.
Alexandre Rames
2014/03/18 13:35:24
Yes. Fixed that.
| |
2468 Bind(&bulk_loop); | |
2469 Sub(bulk_length, bulk_length, pair_size); | |
2470 Ldp(tmp1, tmp2, MemOperand(src, pair_size, PostIndex)); | |
2471 Stp(tmp1, tmp2, MemOperand(dst, pair_size, PostIndex)); | |
2472 Cbnz(bulk_length, &bulk_loop); | |
2473 | |
2474 And(length, length, pair_mask); | |
2475 } | |
2476 | |
2477 Bind(&short_copy); | |
2444 Cbz(length, &done); | 2478 Cbz(length, &done); |
2479 Bind(&short_loop); | |
2480 Sub(length, length, 1); | |
2481 Ldrb(tmp1, MemOperand(src, 1, PostIndex)); | |
2482 Strb(tmp1, MemOperand(dst, 1, PostIndex)); | |
2483 Cbnz(length, &short_loop); | |
2445 | 2484 |
2446 Bind(&loop); | 2485 |
2447 Sub(length, length, 1); | |
2448 Ldrb(scratch, MemOperand(src, 1, PostIndex)); | |
2449 Strb(scratch, MemOperand(dst, 1, PostIndex)); | |
2450 Cbnz(length, &loop); | |
2451 Bind(&done); | 2486 Bind(&done); |
2452 } | 2487 } |
2453 | 2488 |
2454 | 2489 |
2455 void MacroAssembler::FillFields(Register dst, | 2490 void MacroAssembler::FillFields(Register dst, |
2456 Register field_count, | 2491 Register field_count, |
2457 Register filler) { | 2492 Register filler) { |
2458 ASSERT(!dst.Is(csp)); | 2493 ASSERT(!dst.Is(csp)); |
2459 UseScratchRegisterScope temps(this); | 2494 UseScratchRegisterScope temps(this); |
2460 Register field_ptr = temps.AcquireX(); | 2495 Register field_ptr = temps.AcquireX(); |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2919 int offset = ExitFrameConstants::kLastExitFrameField; | 2954 int offset = ExitFrameConstants::kLastExitFrameField; |
2920 while (!saved_fp_regs.IsEmpty()) { | 2955 while (!saved_fp_regs.IsEmpty()) { |
2921 const CPURegister& dst0 = saved_fp_regs.PopHighestIndex(); | 2956 const CPURegister& dst0 = saved_fp_regs.PopHighestIndex(); |
2922 const CPURegister& dst1 = saved_fp_regs.PopHighestIndex(); | 2957 const CPURegister& dst1 = saved_fp_regs.PopHighestIndex(); |
2923 offset -= 2 * kDRegSize; | 2958 offset -= 2 * kDRegSize; |
2924 Ldp(dst1, dst0, MemOperand(fp, offset)); | 2959 Ldp(dst1, dst0, MemOperand(fp, offset)); |
2925 } | 2960 } |
2926 } | 2961 } |
2927 | 2962 |
2928 | 2963 |
2929 // TODO(jbramley): Check that we're handling the frame pointer correctly. | |
2930 void MacroAssembler::EnterExitFrame(bool save_doubles, | 2964 void MacroAssembler::EnterExitFrame(bool save_doubles, |
2931 const Register& scratch, | 2965 const Register& scratch, |
2932 int extra_space) { | 2966 int extra_space) { |
2933 ASSERT(jssp.Is(StackPointer())); | 2967 ASSERT(jssp.Is(StackPointer())); |
2934 | 2968 |
2935 // Set up the new stack frame. | 2969 // Set up the new stack frame. |
2936 Mov(scratch, Operand(CodeObject())); | 2970 Mov(scratch, Operand(CodeObject())); |
2937 Push(lr, fp); | 2971 Push(lr, fp); |
2938 Mov(fp, StackPointer()); | 2972 Mov(fp, StackPointer()); |
2939 Push(xzr, scratch); | 2973 Push(xzr, scratch); |
(...skipping 23 matching lines...) Expand all Loading... | |
2963 } | 2997 } |
2964 | 2998 |
2965 // Reserve space for the return address and for user requested memory. | 2999 // Reserve space for the return address and for user requested memory. |
2966 // We do this before aligning to make sure that we end up correctly | 3000 // We do this before aligning to make sure that we end up correctly |
2967 // aligned with the minimum of wasted space. | 3001 // aligned with the minimum of wasted space. |
2968 Claim(extra_space + 1, kXRegSize); | 3002 Claim(extra_space + 1, kXRegSize); |
2969 // fp[8]: CallerPC (lr) | 3003 // fp[8]: CallerPC (lr) |
2970 // fp -> fp[0]: CallerFP (old fp) | 3004 // fp -> fp[0]: CallerFP (old fp) |
2971 // fp[-8]: Space reserved for SPOffset. | 3005 // fp[-8]: Space reserved for SPOffset. |
2972 // fp[-16]: CodeObject() | 3006 // fp[-16]: CodeObject() |
2973 // jssp[-16 - fp_size]: Saved doubles (if save_doubles is true). | 3007 // fp[-16 - fp_size]: Saved doubles (if save_doubles is true). |
2974 // jssp[8]: Extra space reserved for caller (if extra_space != 0). | 3008 // jssp[8]: Extra space reserved for caller (if extra_space != 0). |
2975 // jssp -> jssp[0]: Space reserved for the return address. | 3009 // jssp -> jssp[0]: Space reserved for the return address. |
2976 | 3010 |
2977 // Align and synchronize the system stack pointer with jssp. | 3011 // Align and synchronize the system stack pointer with jssp. |
2978 AlignAndSetCSPForFrame(); | 3012 AlignAndSetCSPForFrame(); |
2979 ASSERT(csp.Is(StackPointer())); | 3013 ASSERT(csp.Is(StackPointer())); |
2980 | 3014 |
2981 // fp[8]: CallerPC (lr) | 3015 // fp[8]: CallerPC (lr) |
2982 // fp -> fp[0]: CallerFP (old fp) | 3016 // fp -> fp[0]: CallerFP (old fp) |
2983 // fp[-8]: Space reserved for SPOffset. | 3017 // fp[-8]: Space reserved for SPOffset. |
2984 // fp[-16]: CodeObject() | 3018 // fp[-16]: CodeObject() |
2985 // csp[...]: Saved doubles, if saved_doubles is true. | 3019 // fp[-16 - fp_size]: Saved doubles (if save_doubles is true). |
2986 // csp[8]: Memory reserved for the caller if extra_space != 0. | 3020 // csp[8]: Memory reserved for the caller if extra_space != 0. |
2987 // Alignment padding, if necessary. | 3021 // Alignment padding, if necessary. |
2988 // csp -> csp[0]: Space reserved for the return address. | 3022 // csp -> csp[0]: Space reserved for the return address. |
2989 | 3023 |
2990 // ExitFrame::GetStateForFramePointer expects to find the return address at | 3024 // ExitFrame::GetStateForFramePointer expects to find the return address at |
2991 // the memory address immediately below the pointer stored in SPOffset. | 3025 // the memory address immediately below the pointer stored in SPOffset. |
2992 // It is not safe to derive much else from SPOffset, because the size of the | 3026 // It is not safe to derive much else from SPOffset, because the size of the |
2993 // padding can vary. | 3027 // padding can vary. |
2994 Add(scratch, csp, kXRegSize); | 3028 Add(scratch, csp, kXRegSize); |
2995 Str(scratch, MemOperand(fp, ExitFrameConstants::kSPOffset)); | 3029 Str(scratch, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
(...skipping 2125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5121 } | 5155 } |
5122 } | 5156 } |
5123 | 5157 |
5124 | 5158 |
5125 #undef __ | 5159 #undef __ |
5126 | 5160 |
5127 | 5161 |
5128 } } // namespace v8::internal | 5162 } } // namespace v8::internal |
5129 | 5163 |
5130 #endif // V8_TARGET_ARCH_A64 | 5164 #endif // V8_TARGET_ARCH_A64 |
OLD | NEW |