OLD | NEW |
| (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 #if V8_TARGET_ARCH_ARM64 | |
6 | |
7 #include "src/arm64/delayed-masm-arm64.h" | |
8 #include "src/arm64/lithium-codegen-arm64.h" | |
9 | |
10 namespace v8 { | |
11 namespace internal { | |
12 | |
13 #define __ ACCESS_MASM(masm_) | |
14 | |
15 | |
16 void DelayedMasm::StackSlotMove(LOperand* src, LOperand* dst) { | |
17 DCHECK((src->IsStackSlot() && dst->IsStackSlot()) || | |
18 (src->IsDoubleStackSlot() && dst->IsDoubleStackSlot())); | |
19 MemOperand src_operand = cgen_->ToMemOperand(src); | |
20 MemOperand dst_operand = cgen_->ToMemOperand(dst); | |
21 if (pending_ == kStackSlotMove) { | |
22 DCHECK(pending_pc_ == masm_->pc_offset()); | |
23 UseScratchRegisterScope scope(masm_); | |
24 DoubleRegister temp1 = scope.AcquireD(); | |
25 DoubleRegister temp2 = scope.AcquireD(); | |
26 switch (MemOperand::AreConsistentForPair(pending_address_src_, | |
27 src_operand)) { | |
28 case MemOperand::kNotPair: | |
29 __ Ldr(temp1, pending_address_src_); | |
30 __ Ldr(temp2, src_operand); | |
31 break; | |
32 case MemOperand::kPairAB: | |
33 __ Ldp(temp1, temp2, pending_address_src_); | |
34 break; | |
35 case MemOperand::kPairBA: | |
36 __ Ldp(temp2, temp1, src_operand); | |
37 break; | |
38 } | |
39 switch (MemOperand::AreConsistentForPair(pending_address_dst_, | |
40 dst_operand)) { | |
41 case MemOperand::kNotPair: | |
42 __ Str(temp1, pending_address_dst_); | |
43 __ Str(temp2, dst_operand); | |
44 break; | |
45 case MemOperand::kPairAB: | |
46 __ Stp(temp1, temp2, pending_address_dst_); | |
47 break; | |
48 case MemOperand::kPairBA: | |
49 __ Stp(temp2, temp1, dst_operand); | |
50 break; | |
51 } | |
52 ResetPending(); | |
53 return; | |
54 } | |
55 | |
56 EmitPending(); | |
57 pending_ = kStackSlotMove; | |
58 pending_address_src_ = src_operand; | |
59 pending_address_dst_ = dst_operand; | |
60 #ifdef DEBUG | |
61 pending_pc_ = masm_->pc_offset(); | |
62 #endif | |
63 } | |
64 | |
65 | |
66 void DelayedMasm::StoreConstant(uint64_t value, const MemOperand& operand) { | |
67 DCHECK(!scratch_register_acquired_); | |
68 if ((pending_ == kStoreConstant) && (value == pending_value_)) { | |
69 MemOperand::PairResult result = | |
70 MemOperand::AreConsistentForPair(pending_address_dst_, operand); | |
71 if (result != MemOperand::kNotPair) { | |
72 const MemOperand& dst = | |
73 (result == MemOperand::kPairAB) ? | |
74 pending_address_dst_ : | |
75 operand; | |
76 DCHECK(pending_pc_ == masm_->pc_offset()); | |
77 if (pending_value_ == 0) { | |
78 __ Stp(xzr, xzr, dst); | |
79 } else { | |
80 SetSavedValue(pending_value_); | |
81 __ Stp(ScratchRegister(), ScratchRegister(), dst); | |
82 } | |
83 ResetPending(); | |
84 return; | |
85 } | |
86 } | |
87 | |
88 EmitPending(); | |
89 pending_ = kStoreConstant; | |
90 pending_address_dst_ = operand; | |
91 pending_value_ = value; | |
92 #ifdef DEBUG | |
93 pending_pc_ = masm_->pc_offset(); | |
94 #endif | |
95 } | |
96 | |
97 | |
98 void DelayedMasm::Load(const CPURegister& rd, const MemOperand& operand) { | |
99 if ((pending_ == kLoad) && | |
100 pending_register_.IsSameSizeAndType(rd)) { | |
101 switch (MemOperand::AreConsistentForPair(pending_address_src_, operand)) { | |
102 case MemOperand::kNotPair: | |
103 break; | |
104 case MemOperand::kPairAB: | |
105 DCHECK(pending_pc_ == masm_->pc_offset()); | |
106 DCHECK(!IsScratchRegister(pending_register_) || | |
107 scratch_register_acquired_); | |
108 DCHECK(!IsScratchRegister(rd) || scratch_register_acquired_); | |
109 __ Ldp(pending_register_, rd, pending_address_src_); | |
110 ResetPending(); | |
111 return; | |
112 case MemOperand::kPairBA: | |
113 DCHECK(pending_pc_ == masm_->pc_offset()); | |
114 DCHECK(!IsScratchRegister(pending_register_) || | |
115 scratch_register_acquired_); | |
116 DCHECK(!IsScratchRegister(rd) || scratch_register_acquired_); | |
117 __ Ldp(rd, pending_register_, operand); | |
118 ResetPending(); | |
119 return; | |
120 } | |
121 } | |
122 | |
123 EmitPending(); | |
124 pending_ = kLoad; | |
125 pending_register_ = rd; | |
126 pending_address_src_ = operand; | |
127 #ifdef DEBUG | |
128 pending_pc_ = masm_->pc_offset(); | |
129 #endif | |
130 } | |
131 | |
132 | |
133 void DelayedMasm::Store(const CPURegister& rd, const MemOperand& operand) { | |
134 if ((pending_ == kStore) && | |
135 pending_register_.IsSameSizeAndType(rd)) { | |
136 switch (MemOperand::AreConsistentForPair(pending_address_dst_, operand)) { | |
137 case MemOperand::kNotPair: | |
138 break; | |
139 case MemOperand::kPairAB: | |
140 DCHECK(pending_pc_ == masm_->pc_offset()); | |
141 __ Stp(pending_register_, rd, pending_address_dst_); | |
142 ResetPending(); | |
143 return; | |
144 case MemOperand::kPairBA: | |
145 DCHECK(pending_pc_ == masm_->pc_offset()); | |
146 __ Stp(rd, pending_register_, operand); | |
147 ResetPending(); | |
148 return; | |
149 } | |
150 } | |
151 | |
152 EmitPending(); | |
153 pending_ = kStore; | |
154 pending_register_ = rd; | |
155 pending_address_dst_ = operand; | |
156 #ifdef DEBUG | |
157 pending_pc_ = masm_->pc_offset(); | |
158 #endif | |
159 } | |
160 | |
161 | |
162 void DelayedMasm::EmitPending() { | |
163 DCHECK((pending_ == kNone) || (pending_pc_ == masm_->pc_offset())); | |
164 switch (pending_) { | |
165 case kNone: | |
166 return; | |
167 case kStoreConstant: | |
168 if (pending_value_ == 0) { | |
169 __ Str(xzr, pending_address_dst_); | |
170 } else { | |
171 SetSavedValue(pending_value_); | |
172 __ Str(ScratchRegister(), pending_address_dst_); | |
173 } | |
174 break; | |
175 case kLoad: | |
176 DCHECK(!IsScratchRegister(pending_register_) || | |
177 scratch_register_acquired_); | |
178 __ Ldr(pending_register_, pending_address_src_); | |
179 break; | |
180 case kStore: | |
181 __ Str(pending_register_, pending_address_dst_); | |
182 break; | |
183 case kStackSlotMove: { | |
184 UseScratchRegisterScope scope(masm_); | |
185 DoubleRegister temp = scope.AcquireD(); | |
186 __ Ldr(temp, pending_address_src_); | |
187 __ Str(temp, pending_address_dst_); | |
188 break; | |
189 } | |
190 } | |
191 ResetPending(); | |
192 } | |
193 | |
194 } // namespace internal | |
195 } // namespace v8 | |
196 | |
197 #endif // V8_TARGET_ARCH_ARM64 | |
OLD | NEW |