| Index: runtime/vm/flow_graph_allocator.cc
 | 
| diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
 | 
| index ac39023f54f2d00d58eef45012170d99899d9f49..1332661b9cc9e7f7cd36e3a79c4cabc40c67a820 100644
 | 
| --- a/runtime/vm/flow_graph_allocator.cc
 | 
| +++ b/runtime/vm/flow_graph_allocator.cc
 | 
| @@ -580,6 +580,24 @@ void FlowGraphAllocator::BuildLiveRanges() {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +static Location::Kind RegisterKindFromPolicy(Location loc) {
 | 
| +  if (loc.policy() == Location::kRequiresXmmRegister) {
 | 
| +    return Location::kXmmRegister;
 | 
| +  } else {
 | 
| +    return Location::kRegister;
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +
 | 
| +static Location::Kind RegisterKindForResult(Instruction* instr) {
 | 
| +  if (instr->representation() == kUnboxedDouble) {
 | 
| +    return Location::kXmmRegister;
 | 
| +  } else {
 | 
| +    return Location::kRegister;
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +
 | 
|  //
 | 
|  // When describing shape of live ranges in comments below we are going to use
 | 
|  // the following notation:
 | 
| @@ -700,8 +718,7 @@ void FlowGraphAllocator::ConnectIncomingPhiMoves(BlockEntryInstr* block) {
 | 
|        // complete.
 | 
|        AssignSafepoints(range);
 | 
|  
 | 
| -      // TODO(vegorov): unboxed double phis.
 | 
| -      CompleteRange(range, Location::kRegister);
 | 
| +      CompleteRange(range, RegisterKindForResult(phi));
 | 
|  
 | 
|        move_idx++;
 | 
|      }
 | 
| @@ -753,24 +770,6 @@ void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block,
 | 
|  }
 | 
|  
 | 
|  
 | 
| -static Location::Kind RegisterKindFromPolicy(Location loc) {
 | 
| -  if (loc.policy() == Location::kRequiresXmmRegister) {
 | 
| -    return Location::kXmmRegister;
 | 
| -  } else {
 | 
| -    return Location::kRegister;
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -
 | 
| -static Location::Kind RegisterKindForResult(Instruction* instr) {
 | 
| -  if (instr->representation() == kUnboxedDouble) {
 | 
| -    return Location::kXmmRegister;
 | 
| -  } else {
 | 
| -    return Location::kRegister;
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -
 | 
|  // Create and update live ranges corresponding to instruction's inputs,
 | 
|  // temporaries and output.
 | 
|  void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block,
 | 
| @@ -871,6 +870,14 @@ void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block,
 | 
|                      pos + 1);
 | 
|      }
 | 
|  
 | 
| +    for (intptr_t reg = 0; reg < kNumberOfXmmRegisters; reg++) {
 | 
| +      BlockLocation(
 | 
| +          Location::XmmRegisterLocation(static_cast<XmmRegister>(reg)),
 | 
| +          pos,
 | 
| +          pos + 1);
 | 
| +    }
 | 
| +
 | 
| +
 | 
|  #if defined(DEBUG)
 | 
|      // Verify that temps, inputs and output were specified as fixed
 | 
|      // locations.  Every register is blocked now so attempt to
 | 
| @@ -1188,7 +1195,8 @@ UsePosition* AllocationFinger::FirstRegisterUse(intptr_t after) {
 | 
|         use = use->next()) {
 | 
|      Location* loc = use->location_slot();
 | 
|      if (loc->IsUnallocated() &&
 | 
| -        (loc->policy() == Location::kRequiresRegister)) {
 | 
| +        ((loc->policy() == Location::kRequiresRegister) ||
 | 
| +        (loc->policy() == Location::kRequiresXmmRegister))) {
 | 
|        first_register_use_ = use;
 | 
|        return use;
 | 
|      }
 | 
| @@ -1434,9 +1442,15 @@ void FlowGraphAllocator::AllocateSpillSlotFor(LiveRange* range) {
 | 
|    if (register_kind_ == Location::kRegister) {
 | 
|      range->set_spill_slot(Location::StackSlot(idx));
 | 
|    } else {
 | 
| +    // Double spill slots are essentially one (x64) or two (ia32) normal
 | 
| +    // word size spill slots.  We use the index of the slot with the lowest
 | 
| +    // address as an index for the double spill slot. In terms of indexes
 | 
| +    // this relation is inverted: so we have to take the highest index.
 | 
| +    const intptr_t slot_idx =
 | 
| +        idx * kDoubleSpillSlotFactor + (kDoubleSpillSlotFactor - 1);
 | 
|      range->set_spill_slot(
 | 
|          Location::DoubleStackSlot(
 | 
| -            cpu_spill_slot_count_ + idx * kDoubleSpillSlotFactor));
 | 
| +            cpu_spill_slot_count_ + slot_idx));
 | 
|    }
 | 
|  
 | 
|    spilled_.Add(range);
 | 
| @@ -1674,7 +1688,7 @@ void FlowGraphAllocator::AssignNonFreeRegister(LiveRange* unallocated,
 | 
|      if (allocated->vreg() < 0) continue;  // Can't be evicted.
 | 
|      if (EvictIntersection(allocated, unallocated)) {
 | 
|        // If allocated was not spilled convert all pending uses.
 | 
| -      if (allocated->assigned_location().IsRegister()) {
 | 
| +      if (allocated->assigned_location().IsMachineRegister()) {
 | 
|          ASSERT(allocated->End() <= unallocated->Start());
 | 
|          ConvertAllUses(allocated);
 | 
|        }
 | 
| 
 |