Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Side by Side Diff: src/arm64/delayed-masm-arm64.h

Issue 268673003: ARM64: Optimize generated code for gaps (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: use new includes norm Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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_DELAYED_MASM_ARM64_H_
6 #define V8_ARM64_DELAYED_MASM_ARM64_H_
7
8 #include "src/lithium.h"
9
10 namespace v8 {
11 namespace internal {
12
13 class LCodeGen;
14
15 // This class delays the generation of some instructions. This way, we have a
16 // chance to merge two instructions in one (with load/store pair).
17 // Each instruction must either:
18 // - merge with the pending instruction and generate just one instruction.
19 // - emit the pending instruction and then generate the instruction (or set the
20 // pending instruction).
21 class DelayedMasm BASE_EMBEDDED {
22 public:
23 explicit DelayedMasm(LCodeGen* owner, MacroAssembler* masm)
24 : cgen_(owner), masm_(masm), need_to_restore_root_(false), pending_(kNone),
25 saved_value_(0) {
26 #ifdef DEBUG
27 pending_register_ = no_reg;
28 pending_value_ = 0;
29 pending_pc_ = 0;
30 #endif
31 }
32 ~DelayedMasm() {
33 ASSERT(!need_to_restore_root_);
34 ASSERT(!pending());
35 }
36 inline void EndDelayedUse();
37
38 // We use the root register as an extra scratch register.
39 // The root register has two advantages:
40 // - It is not in crankshaft allocatable registers list, so it can't
41 // interfere with the allocatable registers.
42 // - We don't need to push it on the stack, as we can reload it with its
43 // value once we have finish.
44 const Register& ScratchRegister() {
45 need_to_restore_root_ = true;
ulan 2014/06/04 09:28:19 I think the root register and its management belon
vincent.belliard 2014/06/09 10:31:15 The scratch register is now defined by the caller
46 return root;
47 }
48 bool IsScratchRegister(const CPURegister& reg) {
49 return reg.Is(root);
50 }
51 bool pending() { return pending_ != kNone; }
52
53 // Extra layer over the macro-assembler instructions (which emits the
54 // potential pending instruction).
55 inline void Mov(const Register& rd,
56 const Operand& operand,
57 DiscardMoveMode discard_mode = kDontDiscardForSameWReg);
58 inline void Fmov(FPRegister fd, FPRegister fn);
59 inline void Fmov(FPRegister fd, double imm);
60 inline void LoadObject(Register result, Handle<Object> object);
61 // Instructions which try to merge which the pending instructions.
62 void StackSlotMove(LOperand* src, LOperand* dst);
63 void StoreConstant(uint64_t value, const MemOperand& operand);
64 void Load(const CPURegister& rd, const MemOperand& operand);
65 void Store(const CPURegister& rd, const MemOperand& operand);
66 // Emit the potential pending instruction.
67 void EmitPending();
68 // Reset the pending state.
69 void ResetPending() {
70 pending_ = kNone;
71 #ifdef DEBUG
72 pending_register_ = no_reg;
73 MemOperand tmp;
74 pending_address_src_ = tmp;
75 pending_address_dst_ = tmp;
76 pending_value_ = 0;
77 pending_pc_ = 0;
78 #endif
79 }
80
81 private:
82 // Set the saved value and load the ScratchRegister with it.
83 void SetSavedValue(uint64_t saved_value) {
84 ASSERT(saved_value != 0);
85 if (saved_value_ != saved_value) {
86 masm_->Mov(ScratchRegister(), saved_value);
87 saved_value_ = saved_value;
88 }
89 }
90 // Reset the saved value (i.e. the value of ScratchRegister is no longer
91 // known).
92 void ResetSavedValue() {
93 saved_value_ = 0;
94 }
95
96 LCodeGen* cgen_;
97 MacroAssembler* masm_;
98
99 // We use the root register as a scratch in a few places. When that happens,
100 // this flag is set to indicate that it needs to be restored.
101 bool need_to_restore_root_;
102
103 // Sometimes we store or load two values in two contiguous stack slots.
104 // In this case, we try to use the ldp/stp instructions to reduce code size.
105 // To be able to do that, instead of generating directly the instructions,
106 // we register with the following fields that an instruction needs to be
107 // generated. Then with the next instruction, if the instruction is
108 // consistent with the pending one for stp/ldp we generate ldp/stp. Else,
109 // if they are not consistent, we generate the pending instruction and we
110 // register the new instruction (which becomes pending).
111
112 // Enumeration of instructions which can be pending.
113 enum Pending {
114 kNone,
115 kStoreConstant,
116 kLoad, kStore,
117 kStackSlotMove
118 };
119 // The pending instruction.
120 Pending pending_;
121 // For kLoad, kStore: register which must be loaded/stored.
122 CPURegister pending_register_;
123 // For kLoad, kStackSlotMove: address of the load.
124 MemOperand pending_address_src_;
125 // For kStoreConstant, kStore, kStackSlotMove: address of the store.
126 MemOperand pending_address_dst_;
127 // For kStoreConstant: value to be stored.
128 uint64_t pending_value_;
129 // Value held into the ScratchRegister (root register) if
130 // the saved_value_ is not 0 (for 0, we use xzr).
131 uint64_t saved_value_;
132 #ifdef DEBUG
133 // Address where the pending instruction must be generated. It's only used to
134 // check that nothing else has been generated since we set the pending
135 // instruction.
136 int pending_pc_;
137 #endif
138 };
139
140 } } // namespace v8::internal
141
142 #endif // V8_ARM64_DELAYED_MASM_ARM64_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698