Chromium Code Reviews| 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 |