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

Side by Side Diff: src/arm64/lithium-gap-resolver-arm64.cc

Issue 208183002: ARM64: Use a double register to break cycle involving double values. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 9 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 24 matching lines...) Expand all
35 35
36 // We use the root register to spill a value while breaking a cycle in parallel 36 // We use the root register to spill a value while breaking a cycle in parallel
37 // moves. We don't need access to roots while resolving the move list and using 37 // moves. We don't need access to roots while resolving the move list and using
38 // the root register has two advantages: 38 // the root register has two advantages:
39 // - It is not in crankshaft allocatable registers list, so it can't interfere 39 // - It is not in crankshaft allocatable registers list, so it can't interfere
40 // with any of the moves we are resolving. 40 // with any of the moves we are resolving.
41 // - We don't need to push it on the stack, as we can reload it with its value 41 // - We don't need to push it on the stack, as we can reload it with its value
42 // once we have resolved a cycle. 42 // once we have resolved a cycle.
43 #define kSavedValue root 43 #define kSavedValue root
44 44
45 // We use the MacroAssembler floating-point scratch register to break a cycle
46 // involving double values as the MacroAssembler will not need it for the
47 // operations performed by the gap resolver.
48 #define kSavedDoubleValue fp_scratch
49
50
45 LGapResolver::LGapResolver(LCodeGen* owner) 51 LGapResolver::LGapResolver(LCodeGen* owner)
46 : cgen_(owner), moves_(32, owner->zone()), root_index_(0), in_cycle_(false), 52 : cgen_(owner), moves_(32, owner->zone()), root_index_(0), in_cycle_(false),
47 saved_destination_(NULL), need_to_restore_root_(false) { } 53 saved_destination_(NULL), need_to_restore_root_(false) { }
48 54
49 55
50 #define __ ACCESS_MASM(cgen_->masm()) 56 #define __ ACCESS_MASM(cgen_->masm())
51 57
52 void LGapResolver::Resolve(LParallelMove* parallel_move) { 58 void LGapResolver::Resolve(LParallelMove* parallel_move) {
53 ASSERT(moves_.is_empty()); 59 ASSERT(moves_.is_empty());
54 60
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 } 168 }
163 } 169 }
164 #endif 170 #endif
165 } 171 }
166 172
167 173
168 void LGapResolver::BreakCycle(int index) { 174 void LGapResolver::BreakCycle(int index) {
169 ASSERT(moves_[index].destination()->Equals(moves_[root_index_].source())); 175 ASSERT(moves_[index].destination()->Equals(moves_[root_index_].source()));
170 ASSERT(!in_cycle_); 176 ASSERT(!in_cycle_);
171 177
172 // We use a register which is not allocatable by crankshaft to break the cycle 178 // We use registers which are not allocatable by crankshaft to break the cycle
173 // to be sure it doesn't interfere with the moves we are resolving. 179 // to be sure they don't interfere with the moves we are resolving.
174 ASSERT(!kSavedValue.IsAllocatable()); 180 ASSERT(!kSavedValue.IsAllocatable());
175 need_to_restore_root_ = true; 181 ASSERT(!kSavedDoubleValue.IsAllocatable());
176 182
177 // We save in a register the source of that move and we remember its 183 // We save in a register the source of that move and we remember its
178 // destination. Then we mark this move as resolved so the cycle is 184 // destination. Then we mark this move as resolved so the cycle is
179 // broken and we can perform the other moves. 185 // broken and we can perform the other moves.
180 in_cycle_ = true; 186 in_cycle_ = true;
181 LOperand* source = moves_[index].source(); 187 LOperand* source = moves_[index].source();
182 saved_destination_ = moves_[index].destination(); 188 saved_destination_ = moves_[index].destination();
183 189
184 if (source->IsRegister()) { 190 if (source->IsRegister()) {
191 need_to_restore_root_ = true;
185 __ Mov(kSavedValue, cgen_->ToRegister(source)); 192 __ Mov(kSavedValue, cgen_->ToRegister(source));
186 } else if (source->IsStackSlot()) { 193 } else if (source->IsStackSlot()) {
194 need_to_restore_root_ = true;
187 __ Ldr(kSavedValue, cgen_->ToMemOperand(source)); 195 __ Ldr(kSavedValue, cgen_->ToMemOperand(source));
188 } else if (source->IsDoubleRegister()) { 196 } else if (source->IsDoubleRegister()) {
189 // TODO(all): We should use a double register to store the value to avoid 197 ASSERT(cgen_->masm()->FPTmpList()->IncludesAliasOf(kSavedDoubleValue));
190 // the penalty of the mov across register banks. We are going to reserve 198 cgen_->masm()->FPTmpList()->Remove(kSavedDoubleValue);
191 // d31 to hold 0.0 value. We could clobber this register while breaking the 199 __ Fmov(kSavedDoubleValue, cgen_->ToDoubleRegister(source));
192 // cycle and restore it after like we do with the root register.
193 // LGapResolver::RestoreValue() will need to be updated as well when we'll
194 // do that.
195 __ Fmov(kSavedValue, cgen_->ToDoubleRegister(source));
196 } else if (source->IsDoubleStackSlot()) { 200 } else if (source->IsDoubleStackSlot()) {
197 __ Ldr(kSavedValue, cgen_->ToMemOperand(source)); 201 ASSERT(cgen_->masm()->FPTmpList()->IncludesAliasOf(kSavedDoubleValue));
202 cgen_->masm()->FPTmpList()->Remove(kSavedDoubleValue);
203 __ Ldr(kSavedDoubleValue, cgen_->ToMemOperand(source));
198 } else { 204 } else {
199 UNREACHABLE(); 205 UNREACHABLE();
200 } 206 }
201 207
202 // Mark this move as resolved. 208 // Mark this move as resolved.
203 // This move will be actually performed by moving the saved value to this 209 // This move will be actually performed by moving the saved value to this
204 // move's destination in LGapResolver::RestoreValue(). 210 // move's destination in LGapResolver::RestoreValue().
205 moves_[index].Eliminate(); 211 moves_[index].Eliminate();
206 } 212 }
207 213
208 214
209 void LGapResolver::RestoreValue() { 215 void LGapResolver::RestoreValue() {
210 ASSERT(in_cycle_); 216 ASSERT(in_cycle_);
211 ASSERT(saved_destination_ != NULL); 217 ASSERT(saved_destination_ != NULL);
212 218
213 if (saved_destination_->IsRegister()) { 219 if (saved_destination_->IsRegister()) {
214 __ Mov(cgen_->ToRegister(saved_destination_), kSavedValue); 220 __ Mov(cgen_->ToRegister(saved_destination_), kSavedValue);
215 } else if (saved_destination_->IsStackSlot()) { 221 } else if (saved_destination_->IsStackSlot()) {
216 __ Str(kSavedValue, cgen_->ToMemOperand(saved_destination_)); 222 __ Str(kSavedValue, cgen_->ToMemOperand(saved_destination_));
217 } else if (saved_destination_->IsDoubleRegister()) { 223 } else if (saved_destination_->IsDoubleRegister()) {
218 __ Fmov(cgen_->ToDoubleRegister(saved_destination_), kSavedValue); 224 __ Fmov(cgen_->ToDoubleRegister(saved_destination_), kSavedDoubleValue);
225 cgen_->masm()->FPTmpList()->Combine(kSavedDoubleValue);
219 } else if (saved_destination_->IsDoubleStackSlot()) { 226 } else if (saved_destination_->IsDoubleStackSlot()) {
220 __ Str(kSavedValue, cgen_->ToMemOperand(saved_destination_)); 227 __ Str(kSavedDoubleValue, cgen_->ToMemOperand(saved_destination_));
228 cgen_->masm()->FPTmpList()->Combine(kSavedDoubleValue);
221 } else { 229 } else {
222 UNREACHABLE(); 230 UNREACHABLE();
223 } 231 }
224 232
225 in_cycle_ = false; 233 in_cycle_ = false;
226 saved_destination_ = NULL; 234 saved_destination_ = NULL;
227 } 235 }
228 236
229 237
230 void LGapResolver::EmitMove(int index) { 238 void LGapResolver::EmitMove(int index) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 LOperand* src = moves_[index].source(); 325 LOperand* src = moves_[index].source();
318 LOperand* dst = moves_[index].destination(); 326 LOperand* dst = moves_[index].destination();
319 327
320 ASSERT(src->IsStackSlot()); 328 ASSERT(src->IsStackSlot());
321 ASSERT(dst->IsStackSlot()); 329 ASSERT(dst->IsStackSlot());
322 __ Ldr(temp, cgen_->ToMemOperand(src)); 330 __ Ldr(temp, cgen_->ToMemOperand(src));
323 __ Str(temp, cgen_->ToMemOperand(dst)); 331 __ Str(temp, cgen_->ToMemOperand(dst));
324 } 332 }
325 333
326 } } // namespace v8::internal 334 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698