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 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 | 149 |
150 // This move is no longer blocked. | 150 // This move is no longer blocked. |
151 EmitMove(index); | 151 EmitMove(index); |
152 } | 152 } |
153 | 153 |
154 | 154 |
155 void LGapResolver::Verify() { | 155 void LGapResolver::Verify() { |
156 TODO_UNIMPLEMENTED("LGapResolver::Verify"); | 156 TODO_UNIMPLEMENTED("LGapResolver::Verify"); |
157 } | 157 } |
158 | 158 |
| 159 |
159 void LGapResolver::BreakCycle(int index) { | 160 void LGapResolver::BreakCycle(int index) { |
160 ASSERT(moves_[index].destination()->Equals(moves_[root_index_].source())); | 161 ASSERT(moves_[index].destination()->Equals(moves_[root_index_].source())); |
161 ASSERT(!in_cycle_); | 162 ASSERT(!in_cycle_); |
162 | 163 |
163 // We use a register which is not allocatable by crankshaft to break the cycle | 164 // We use a register which is not allocatable by crankshaft to break the cycle |
164 // to be sure it doesn't interfere with the moves we are resolving. | 165 // to be sure it doesn't interfere with the moves we are resolving. |
165 ASSERT(!kSavedValue.IsAllocatable()); | 166 ASSERT(!kSavedValue.IsAllocatable()); |
166 need_to_restore_root_ = true; | 167 need_to_restore_root_ = true; |
167 | 168 |
168 // We save in a register the source of that move and we remember its | 169 // We save in a register the source of that move and we remember its |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 // combinations are possible. | 227 // combinations are possible. |
227 | 228 |
228 if (source->IsRegister()) { | 229 if (source->IsRegister()) { |
229 Register source_register = cgen_->ToRegister(source); | 230 Register source_register = cgen_->ToRegister(source); |
230 if (destination->IsRegister()) { | 231 if (destination->IsRegister()) { |
231 __ Mov(cgen_->ToRegister(destination), source_register); | 232 __ Mov(cgen_->ToRegister(destination), source_register); |
232 } else { | 233 } else { |
233 ASSERT(destination->IsStackSlot()); | 234 ASSERT(destination->IsStackSlot()); |
234 __ Str(source_register, cgen_->ToMemOperand(destination)); | 235 __ Str(source_register, cgen_->ToMemOperand(destination)); |
235 } | 236 } |
| 237 |
236 } else if (source->IsStackSlot()) { | 238 } else if (source->IsStackSlot()) { |
237 MemOperand source_operand = cgen_->ToMemOperand(source); | 239 MemOperand source_operand = cgen_->ToMemOperand(source); |
238 if (destination->IsRegister()) { | 240 if (destination->IsRegister()) { |
239 __ Ldr(cgen_->ToRegister(destination), source_operand); | 241 __ Ldr(cgen_->ToRegister(destination), source_operand); |
240 } else { | 242 } else { |
241 ASSERT(destination->IsStackSlot()); | 243 ASSERT(destination->IsStackSlot()); |
242 EmitStackSlotMove(index); | 244 EmitStackSlotMove(index); |
243 } | 245 } |
| 246 |
244 } else if (source->IsConstantOperand()) { | 247 } else if (source->IsConstantOperand()) { |
245 LConstantOperand* constant_source = LConstantOperand::cast(source); | 248 LConstantOperand* constant_source = LConstantOperand::cast(source); |
246 if (destination->IsRegister()) { | 249 if (destination->IsRegister()) { |
247 Register dst = cgen_->ToRegister(destination); | 250 Register dst = cgen_->ToRegister(destination); |
248 if (cgen_->IsSmi(constant_source)) { | 251 if (cgen_->IsSmi(constant_source)) { |
249 __ Mov(dst, Operand(cgen_->ToSmi(constant_source))); | 252 __ Mov(dst, Operand(cgen_->ToSmi(constant_source))); |
250 } else if (cgen_->IsInteger32Constant(constant_source)) { | 253 } else if (cgen_->IsInteger32Constant(constant_source)) { |
251 __ Mov(dst, cgen_->ToInteger32(constant_source)); | 254 __ Mov(dst, cgen_->ToInteger32(constant_source)); |
252 } else { | 255 } else { |
253 __ LoadObject(dst, cgen_->ToHandle(constant_source)); | 256 __ LoadObject(dst, cgen_->ToHandle(constant_source)); |
254 } | 257 } |
| 258 } else if (source->IsDoubleRegister()) { |
| 259 DoubleRegister result = cgen_->ToDoubleRegister(destination); |
| 260 __ Fmov(result, cgen_->ToDouble(constant_source)); |
255 } else { | 261 } else { |
256 ASSERT(destination->IsStackSlot()); | 262 ASSERT(destination->IsStackSlot()); |
257 ASSERT(!in_cycle_); // Constant moves happen after all cycles are gone. | 263 ASSERT(!in_cycle_); // Constant moves happen after all cycles are gone. |
258 need_to_restore_root_ = true; | 264 need_to_restore_root_ = true; |
259 if (cgen_->IsSmi(constant_source)) { | 265 if (cgen_->IsSmi(constant_source)) { |
260 __ Mov(kSavedValue, Operand(cgen_->ToSmi(constant_source))); | 266 __ Mov(kSavedValue, Operand(cgen_->ToSmi(constant_source))); |
261 } else if (cgen_->IsInteger32Constant(constant_source)) { | 267 } else if (cgen_->IsInteger32Constant(constant_source)) { |
262 __ Mov(kSavedValue, cgen_->ToInteger32(constant_source)); | 268 __ Mov(kSavedValue, cgen_->ToInteger32(constant_source)); |
263 } else { | 269 } else { |
264 __ LoadObject(kSavedValue, cgen_->ToHandle(constant_source)); | 270 __ LoadObject(kSavedValue, cgen_->ToHandle(constant_source)); |
265 } | 271 } |
266 __ Str(kSavedValue, cgen_->ToMemOperand(destination)); | 272 __ Str(kSavedValue, cgen_->ToMemOperand(destination)); |
267 } | 273 } |
| 274 |
268 } else if (source->IsDoubleRegister()) { | 275 } else if (source->IsDoubleRegister()) { |
269 DoubleRegister src = cgen_->ToDoubleRegister(source); | 276 DoubleRegister src = cgen_->ToDoubleRegister(source); |
270 if (destination->IsDoubleRegister()) { | 277 if (destination->IsDoubleRegister()) { |
271 __ Fmov(cgen_->ToDoubleRegister(destination), src); | 278 __ Fmov(cgen_->ToDoubleRegister(destination), src); |
272 } else { | 279 } else { |
273 ASSERT(destination->IsDoubleStackSlot()); | 280 ASSERT(destination->IsDoubleStackSlot()); |
274 __ Str(src, cgen_->ToMemOperand(destination)); | 281 __ Str(src, cgen_->ToMemOperand(destination)); |
275 } | 282 } |
| 283 |
276 } else if (source->IsDoubleStackSlot()) { | 284 } else if (source->IsDoubleStackSlot()) { |
277 MemOperand src = cgen_->ToMemOperand(source); | 285 MemOperand src = cgen_->ToMemOperand(source); |
278 if (destination->IsDoubleRegister()) { | 286 if (destination->IsDoubleRegister()) { |
279 __ Ldr(cgen_->ToDoubleRegister(destination), src); | 287 __ Ldr(cgen_->ToDoubleRegister(destination), src); |
280 } else { | 288 } else { |
281 // TODO(all): double stack slot to double stack slot move. | 289 // TODO(all): double stack slot to double stack slot move. |
282 UNIMPLEMENTED(); | 290 UNIMPLEMENTED(); |
283 } | 291 } |
| 292 |
284 } else { | 293 } else { |
285 UNREACHABLE(); | 294 UNREACHABLE(); |
286 } | 295 } |
287 | 296 |
288 // The move has been emitted, we can eliminate it. | 297 // The move has been emitted, we can eliminate it. |
289 moves_[index].Eliminate(); | 298 moves_[index].Eliminate(); |
290 } | 299 } |
291 | 300 |
292 | 301 |
293 void LGapResolver::EmitStackSlotMove(int index) { | 302 void LGapResolver::EmitStackSlotMove(int index) { |
294 // We need a temp register to perform a stack slot to stack slot move, and | 303 // We need a temp register to perform a stack slot to stack slot move, and |
295 // the register must not be involved in breaking cycles. | 304 // the register must not be involved in breaking cycles. |
296 | 305 |
297 // Use the Crankshaft double scratch register as the temporary. | 306 // Use the Crankshaft double scratch register as the temporary. |
298 DoubleRegister temp = crankshaft_fp_scratch; | 307 DoubleRegister temp = crankshaft_fp_scratch; |
299 | 308 |
300 LOperand* src = moves_[index].source(); | 309 LOperand* src = moves_[index].source(); |
301 LOperand* dst = moves_[index].destination(); | 310 LOperand* dst = moves_[index].destination(); |
302 | 311 |
303 ASSERT(src->IsStackSlot()); | 312 ASSERT(src->IsStackSlot()); |
304 ASSERT(dst->IsStackSlot()); | 313 ASSERT(dst->IsStackSlot()); |
305 __ Ldr(temp, cgen_->ToMemOperand(src)); | 314 __ Ldr(temp, cgen_->ToMemOperand(src)); |
306 __ Str(temp, cgen_->ToMemOperand(dst)); | 315 __ Str(temp, cgen_->ToMemOperand(dst)); |
307 } | 316 } |
308 | 317 |
309 } } // namespace v8::internal | 318 } } // namespace v8::internal |
OLD | NEW |