// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.regalloc;

import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.Instruction;
import java.util.Map;
import java.util.Set;

// Register moves used by the spilling register allocator. These are used both for spill and
// for phi moves and they are moves between actual registers represented by their register number.
public class RegisterMove implements Comparable<RegisterMove> {

  final TypeElement type;
  final int dst;
  final int src;
  final Instruction definition;

  public RegisterMove(int dst, int src, TypeElement type) {
    this.dst = dst;
    this.src = src;
    this.definition = null;
    this.type = type;
  }

  public RegisterMove(int dst, TypeElement type, Instruction definition) {
    assert definition.isOutConstant();
    this.dst = dst;
    this.src = LiveIntervals.NO_REGISTER;
    this.definition = definition;
    this.type = type;
  }

  private boolean writes(int register) {
    if (type.isWidePrimitive() && (dst + 1) == register) {
      return true;
    }
    return dst == register;
  }

  public boolean isBlocked(Set<RegisterMove> moveSet, Map<Integer, Integer> valueMap) {
    for (RegisterMove move : moveSet) {
      if (move.src == LiveIntervals.NO_REGISTER) {
        continue;
      }
      if (move != this) {
        if (writes(valueMap.get(move.src))) {
          return true;
        }
        if (move.type.isWidePrimitive()) {
          if (writes(valueMap.get(move.src) + 1)) {
            return true;
          }
        }
      }
    }
    return false;
  }

  @Override
  public int hashCode() {
    return src + dst * 3 + type.hashCode() * 5 + (definition == null ? 0 : definition.hashCode());
  }

  @Override
  public boolean equals(Object other) {
    if (!(other instanceof RegisterMove)) {
      return false;
    }
    RegisterMove o = (RegisterMove) other;
    return o.src == src && o.dst == dst && o.type == type && o.definition == definition;
  }

  @Override
  public int compareTo(RegisterMove o) {
    int srcDiff = src - o.src;
    if (srcDiff != 0) {
      return srcDiff;
    }
    int dstDiff = dst - o.dst;
    if (dstDiff != 0) {
      return dstDiff;
    }
    if (type.isPrimitiveType() != o.type.isPrimitiveType()) {
      return Boolean.compare(type.isPrimitiveType(), o.type.isPrimitiveType());
    }
    if (type.isWidePrimitive() != o.type.isWidePrimitive()) {
      return Boolean.compare(type.isWidePrimitive(), o.type.isWidePrimitive());
    }
    if (type.isReferenceType() != o.type.isReferenceType()) {
      return Boolean.compare(type.isReferenceType(), o.type.isReferenceType());
    }
    if (definition == null) {
      if (o.definition != null) {
        return -1;
      }
      return 0;
    }
    if (o.definition == null) {
      return 1;
    }
    return definition.getNumber() - o.definition.getNumber();
  }
}
