// Copyright (c) 2016, 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.code;

import com.android.tools.r8.cf.code.CfArithmeticBinop;
import com.android.tools.r8.code.AddIntLit16;
import com.android.tools.r8.code.AddIntLit8;
import com.android.tools.r8.code.RsubInt;
import com.android.tools.r8.code.RsubIntLit8;
import com.android.tools.r8.code.SubDouble;
import com.android.tools.r8.code.SubDouble2Addr;
import com.android.tools.r8.code.SubFloat;
import com.android.tools.r8.code.SubFloat2Addr;
import com.android.tools.r8.code.SubInt;
import com.android.tools.r8.code.SubInt2Addr;
import com.android.tools.r8.code.SubLong;
import com.android.tools.r8.code.SubLong2Addr;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.ir.conversion.DexBuilder;

public class Sub extends ArithmeticBinop {

  public Sub(NumericType type, Value dest, Value left, Value right) {
    super(type, dest, left, right);
  }

  @Override
  public boolean isCommutative() {
    return false;
  }

  @Override
  public com.android.tools.r8.code.Instruction CreateInt(int dest, int left, int right) {
    return new SubInt(dest, left, right);
  }

  @Override
  public com.android.tools.r8.code.Instruction CreateLong(int dest, int left, int right) {
    return new SubLong(dest, left, right);
  }

  @Override
  public com.android.tools.r8.code.Instruction CreateFloat(int dest, int left, int right) {
    return new SubFloat(dest, left, right);
  }

  @Override
  public com.android.tools.r8.code.Instruction CreateDouble(int dest, int left, int right) {
    return new SubDouble(dest, left, right);
  }

  @Override
  public com.android.tools.r8.code.Instruction CreateInt2Addr(int left, int right) {
    return new SubInt2Addr(left, right);
  }

  @Override
  public com.android.tools.r8.code.Instruction CreateLong2Addr(int left, int right) {
    return new SubLong2Addr(left, right);
  }

  @Override
  public com.android.tools.r8.code.Instruction CreateFloat2Addr(int left, int right) {
    return new SubFloat2Addr(left, right);
  }

  @Override
  public com.android.tools.r8.code.Instruction CreateDouble2Addr(int left, int right) {
    return new SubDouble2Addr(left, right);
  }

  @Override
  public com.android.tools.r8.code.Instruction CreateIntLit8(int dest, int left, int constant) {
    // The sub instructions with constants are rsub, and is handled below.
    throw new Unreachable("Unsupported instruction SubIntLit8");
  }

  @Override
  public com.android.tools.r8.code.Instruction CreateIntLit16(int dest, int left, int constant) {
    // The sub instructions with constants are rsub, and is handled below.
    throw new Unreachable("Unsupported instruction SubIntLit16");
  }

  @Override
  public boolean identicalNonValueNonPositionParts(Instruction other) {
    return other.isSub() && other.asSub().type == type;
  }

  @Override
  int foldIntegers(int left, int right) {
    return left - right;
  }

  @Override
  long foldLongs(long left, long right) {
    return left - right;
  }

  @Override
  float foldFloat(float left, float right) {
    return left - right;
  }

  @Override
  double foldDouble(double left, double right) {
    return left - right;
  }

  boolean negativeFitsInDexInstruction(Value value) {
    return type == NumericType.INT &&
        value.isConstant() &&
        value.getConstInstruction().asConstNumber().negativeIs16Bit();
  }

  // This is overridden to give the correct value when adding the negative constant.
  @Override
  int maxInOutValueRegisterSize() {
    if (!needsValueInRegister(leftValue())) {
      assert fitsInDexInstruction(leftValue());
      ConstNumber left = leftValue().getConstInstruction().asConstNumber();
      return left.is8Bit() ? Constants.U8BIT_MAX : Constants.U4BIT_MAX;
    } else if (!needsValueInRegister(rightValue())) {
      assert negativeFitsInDexInstruction(rightValue());
      ConstNumber right = rightValue().getConstInstruction().asConstNumber();
      return right.negativeIs8Bit() ? Constants.U8BIT_MAX : Constants.U4BIT_MAX;
    }
    return Constants.U8BIT_MAX;
  }

  @Override
  public boolean needsValueInRegister(Value value) {
    if (leftValue() == rightValue()) {
      // We cannot distinguish the the two values, so both must end up in registers no matter what.
      return true;
    }
    if (value == leftValue()) {
      // If the left value fits in the dex instruction no register is needed for that (rsub
      // instruction).
      return !fitsInDexInstruction(value);
    } else {
      assert value == rightValue();
      // If the negative right value fits in the dex instruction no register is needed for that (add
      // instruction with the negative value), unless the left is taking that place.
      return !negativeFitsInDexInstruction(value) || fitsInDexInstruction(leftValue());
    }
  }

  @Override
  public void buildDex(DexBuilder builder) {
    // Handle two address and non-int case through the generic arithmetic binop.
    if (isTwoAddr(builder.getRegisterAllocator()) || type != NumericType.INT) {
      super.buildDex(builder);
      return;
    }

    com.android.tools.r8.code.Instruction instruction = null;
    if (!needsValueInRegister(leftValue())) {
      // Sub instructions with small left constant is emitted as rsub.
      assert fitsInDexInstruction(leftValue());
      ConstNumber left = leftValue().getConstInstruction().asConstNumber();
      int right = builder.allocatedRegister(rightValue(), getNumber());
      int dest = builder.allocatedRegister(outValue, getNumber());
      if (left.is8Bit()) {
        instruction = new RsubIntLit8(dest, right, left.getIntValue());
      } else {
        assert left.is16Bit();
        instruction = new RsubInt(dest, right, left.getIntValue());
      }
    } else if (!needsValueInRegister(rightValue())) {
      // Sub instructions with small right constant are emitted as add of the negative constant.
      assert negativeFitsInDexInstruction(rightValue());
      int dest = builder.allocatedRegister(outValue, getNumber());
      assert needsValueInRegister(leftValue());
      int left = builder.allocatedRegister(leftValue(), getNumber());
      ConstNumber right = rightValue().getConstInstruction().asConstNumber();
      if (right.negativeIs8Bit()) {
        instruction = new AddIntLit8(dest, left, -right.getIntValue());
      } else {
        assert right.negativeIs16Bit();
        instruction = new AddIntLit16(dest, left, -right.getIntValue());
      }
    } else {
      assert type == NumericType.INT;
      int left = builder.allocatedRegister(leftValue(), getNumber());
      int right = builder.allocatedRegister(rightValue(), getNumber());
      int dest = builder.allocatedRegister(outValue, getNumber());
      instruction = CreateInt(dest, left, right);
    }
    builder.add(this, instruction);
  }

  @Override
  public boolean isSub() {
    return true;
  }

  @Override
  public Sub asSub() {
    return this;
  }

  @Override
  CfArithmeticBinop.Opcode getCfOpcode() {
    return CfArithmeticBinop.Opcode.Sub;
  }
}
