8866db4c9479178c8eaec96de2fbfcfc6b312f6d
[platform/upstream/v8.git] / src / arm64 / lithium-gap-resolver-arm64.h
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_ARM64_LITHIUM_GAP_RESOLVER_ARM64_H_
6 #define V8_ARM64_LITHIUM_GAP_RESOLVER_ARM64_H_
7
8 #include "src/arm64/delayed-masm-arm64.h"
9 #include "src/lithium.h"
10
11 namespace v8 {
12 namespace internal {
13
14 class LCodeGen;
15 class LGapResolver;
16
17 class DelayedGapMasm : public DelayedMasm {
18  public:
19   DelayedGapMasm(LCodeGen* owner, MacroAssembler* masm)
20     : DelayedMasm(owner, masm, root) {
21     // We use the root register as an extra scratch register.
22     // The root register has two advantages:
23     //  - It is not in crankshaft allocatable registers list, so it can't
24     //    interfere with the allocatable registers.
25     //  - We don't need to push it on the stack, as we can reload it with its
26     //    value once we have finish.
27   }
28   void EndDelayedUse();
29 };
30
31
32 class LGapResolver BASE_EMBEDDED {
33  public:
34   explicit LGapResolver(LCodeGen* owner);
35
36   // Resolve a set of parallel moves, emitting assembler instructions.
37   void Resolve(LParallelMove* parallel_move);
38
39  private:
40   // Build the initial list of moves.
41   void BuildInitialMoveList(LParallelMove* parallel_move);
42
43   // Perform the move at the moves_ index in question (possibly requiring
44   // other moves to satisfy dependencies).
45   void PerformMove(int index);
46
47   // If a cycle is found in the series of moves, save the blocking value to
48   // a scratch register.  The cycle must be found by hitting the root of the
49   // depth-first search.
50   void BreakCycle(int index);
51
52   // After a cycle has been resolved, restore the value from the scratch
53   // register to its proper destination.
54   void RestoreValue();
55
56   // Emit a move and remove it from the move graph.
57   void EmitMove(int index);
58
59   // Emit a move from one stack slot to another.
60   void EmitStackSlotMove(int index) {
61     masm_.StackSlotMove(moves_[index].source(), moves_[index].destination());
62   }
63
64   // Verify the move list before performing moves.
65   void Verify();
66
67   // Registers used to solve cycles.
68   const Register& SavedValueRegister() {
69     DCHECK(!masm_.ScratchRegister().IsAllocatable());
70     return masm_.ScratchRegister();
71   }
72   // The scratch register is used to break cycles and to store constant.
73   // These two methods switch from one mode to the other.
74   void AcquireSavedValueRegister() { masm_.AcquireScratchRegister(); }
75   void ReleaseSavedValueRegister() { masm_.ReleaseScratchRegister(); }
76   const FPRegister& SavedFPValueRegister() {
77     // We use the Crankshaft floating-point scratch register to break a cycle
78     // involving double values as the MacroAssembler will not need it for the
79     // operations performed by the gap resolver.
80     DCHECK(!crankshaft_fp_scratch.IsAllocatable());
81     return crankshaft_fp_scratch;
82   }
83
84   LCodeGen* cgen_;
85   DelayedGapMasm masm_;
86
87   // List of moves not yet resolved.
88   ZoneList<LMoveOperands> moves_;
89
90   int root_index_;
91   bool in_cycle_;
92   LOperand* saved_destination_;
93 };
94
95 } }  // namespace v8::internal
96
97 #endif  // V8_ARM64_LITHIUM_GAP_RESOLVER_ARM64_H_