// Copyright (c) 2019, 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;

public class IRMetadata {

  private long first;
  private long second;

  public IRMetadata() {}

  private IRMetadata(long first, long second) {
    this.first = first;
    this.second = second;
  }

  public static IRMetadata unknown() {
    return new IRMetadata(0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL);
  }

  private boolean get(int bit) {
    if (bit < 64) {
      return isAnySetInFirst(1L << bit);
    } else {
      assert bit < 128;
      int adjusted = bit - 64;
      return isAnySetInSecond(1L << adjusted);
    }
  }

  private boolean isAnySetInFirst(long mask) {
    return (first & mask) != 0;
  }

  private boolean isAnySetInSecond(long mask) {
    return (second & mask) != 0;
  }

  private void set(int bit) {
    if (bit < 64) {
      first |= (1L << bit);
    } else {
      assert bit < 128;
      int adjusted = bit - 64;
      second |= (1L << adjusted);
    }
  }

  public void record(Instruction instruction) {
    set(instruction.opcode());
  }

  public void merge(IRMetadata metadata) {
    first |= metadata.first;
    second |= metadata.second;
  }

  public boolean mayHaveAdd() {
    return get(Opcodes.ADD);
  }

  public boolean mayHaveAnd() {
    return get(Opcodes.AND);
  }

  public boolean mayHaveArrayLength() {
    return get(Opcodes.ARRAY_LENGTH);
  }

  public boolean mayHaveCheckCast() {
    return get(Opcodes.CHECK_CAST);
  }

  public boolean mayHaveConstNumber() {
    return get(Opcodes.CONST_NUMBER);
  }

  public boolean mayHaveConstString() {
    return get(Opcodes.CONST_STRING);
  }

  public boolean mayHaveDebugPosition() {
    return get(Opcodes.DEBUG_POSITION);
  }

  public boolean mayHaveDexItemBasedConstString() {
    return get(Opcodes.DEX_ITEM_BASED_CONST_STRING);
  }

  public boolean mayHaveDiv() {
    return get(Opcodes.DIV);
  }

  public boolean mayHaveFieldGet() {
    return mayHaveInstanceGet() || mayHaveStaticGet();
  }

  public boolean mayHaveFieldInstruction() {
    assert Opcodes.INSTANCE_GET < 64;
    assert Opcodes.INSTANCE_PUT < 64;
    assert Opcodes.STATIC_GET < 64;
    assert Opcodes.STATIC_PUT < 64;
    long mask =
        (1L << Opcodes.INSTANCE_GET)
            | (1L << Opcodes.INSTANCE_PUT)
            | (1L << Opcodes.STATIC_GET)
            | (1L << Opcodes.STATIC_PUT);
    boolean result = isAnySetInFirst(mask);
    assert result
        == (mayHaveInstanceGet()
            || mayHaveInstancePut()
            || mayHaveStaticGet()
            || mayHaveStaticPut());
    return result;
  }

  public boolean mayHaveInitClass() {
    return get(Opcodes.INIT_CLASS);
  }

  public boolean mayHaveInstanceGet() {
    return get(Opcodes.INSTANCE_GET);
  }

  public boolean mayHaveInstancePut() {
    return get(Opcodes.INSTANCE_PUT);
  }

  public boolean mayHaveInstanceOf() {
    return get(Opcodes.INSTANCE_OF);
  }

  public boolean mayHaveIntSwitch() {
    return get(Opcodes.INT_SWITCH);
  }

  public boolean mayHaveInvokeDirect() {
    return get(Opcodes.INVOKE_DIRECT);
  }

  public boolean mayHaveInvokeInterface() {
    return get(Opcodes.INVOKE_INTERFACE);
  }

  @SuppressWarnings("ConstantConditions")
  public boolean mayHaveInvokeMethod() {
    assert Opcodes.INVOKE_DIRECT < 64;
    assert Opcodes.INVOKE_INTERFACE < 64;
    assert Opcodes.INVOKE_POLYMORPHIC < 64;
    assert Opcodes.INVOKE_STATIC < 64;
    assert Opcodes.INVOKE_SUPER < 64;
    assert Opcodes.INVOKE_VIRTUAL < 64;
    long mask =
        (1L << Opcodes.INVOKE_DIRECT)
            | (1L << Opcodes.INVOKE_INTERFACE)
            | (1L << Opcodes.INVOKE_POLYMORPHIC)
            | (1L << Opcodes.INVOKE_STATIC)
            | (1L << Opcodes.INVOKE_SUPER)
            | (1L << Opcodes.INVOKE_VIRTUAL);
    boolean result = isAnySetInFirst(mask);
    assert result
        == (mayHaveInvokeDirect()
            || mayHaveInvokeInterface()
            || mayHaveInvokePolymorphic()
            || mayHaveInvokeStatic()
            || mayHaveInvokeSuper()
            || mayHaveInvokeVirtual());
    return result;
  }

  @SuppressWarnings("ConstantConditions")
  public boolean mayHaveInvokeMethodWithReceiver() {
    assert Opcodes.INVOKE_DIRECT < 64;
    assert Opcodes.INVOKE_INTERFACE < 64;
    assert Opcodes.INVOKE_SUPER < 64;
    assert Opcodes.INVOKE_VIRTUAL < 64;
    long mask =
        (1L << Opcodes.INVOKE_DIRECT)
            | (1L << Opcodes.INVOKE_INTERFACE)
            | (1L << Opcodes.INVOKE_SUPER)
            | (1L << Opcodes.INVOKE_VIRTUAL);
    boolean result = isAnySetInFirst(mask);
    assert result
        == (mayHaveInvokeDirect()
            || mayHaveInvokeInterface()
            || mayHaveInvokeSuper()
            || mayHaveInvokeVirtual());
    return result;
  }

  public boolean mayHaveInvokePolymorphic() {
    return get(Opcodes.INVOKE_POLYMORPHIC);
  }

  public boolean mayHaveInvokeStatic() {
    return get(Opcodes.INVOKE_STATIC);
  }

  public boolean mayHaveInvokeSuper() {
    return get(Opcodes.INVOKE_SUPER);
  }

  public boolean mayHaveInvokeVirtual() {
    return get(Opcodes.INVOKE_VIRTUAL);
  }

  public boolean mayHaveMonitorInstruction() {
    return get(Opcodes.MONITOR);
  }

  public boolean mayHaveMul() {
    return get(Opcodes.MUL);
  }

  public boolean mayHaveNewInstance() {
    return get(Opcodes.NEW_INSTANCE);
  }

  public boolean mayHaveOr() {
    return get(Opcodes.OR);
  }

  public boolean mayHaveRem() {
    return get(Opcodes.REM);
  }

  public boolean mayHaveShl() {
    return get(Opcodes.SHL);
  }

  public boolean mayHaveShr() {
    return get(Opcodes.SHR);
  }

  public boolean mayHaveStaticGet() {
    return get(Opcodes.STATIC_GET);
  }

  public boolean mayHaveStaticPut() {
    return get(Opcodes.STATIC_PUT);
  }

  public boolean mayHaveStringSwitch() {
    return get(Opcodes.STRING_SWITCH);
  }

  public boolean mayHaveSub() {
    return get(Opcodes.SUB);
  }

  @SuppressWarnings("ConstantConditions")
  public boolean mayHaveSwitch() {
    assert Opcodes.INT_SWITCH < 64;
    assert Opcodes.STRING_SWITCH < 64;
    long mask = (1L << Opcodes.INT_SWITCH) | (1L << Opcodes.STRING_SWITCH);
    boolean result = isAnySetInFirst(mask);
    assert result == (mayHaveIntSwitch() || mayHaveStringSwitch());
    return result;
  }

  public boolean mayHaveUshr() {
    return get(Opcodes.USHR);
  }

  public boolean mayHaveXor() {
    return get(Opcodes.XOR);
  }

  public boolean mayHaveArithmeticOrLogicalBinop() {
    // ArithmeticBinop
    assert Opcodes.ADD < 64;
    assert Opcodes.DIV < 64;
    assert Opcodes.MUL < 64;
    assert Opcodes.REM < 64;
    assert Opcodes.SUB < 64;
    // LogicalBinop
    assert Opcodes.AND < 64;
    assert Opcodes.OR < 64;
    assert Opcodes.SHL < 64;
    assert Opcodes.SHR < 64;
    assert Opcodes.USHR >= 64;
    assert Opcodes.XOR >= 64;
    long mask =
        (1L << Opcodes.ADD)
            | (1L << Opcodes.DIV)
            | (1L << Opcodes.MUL)
            | (1L << Opcodes.REM)
            | (1L << Opcodes.SUB)
            | (1L << Opcodes.AND)
            | (1L << Opcodes.OR)
            | (1L << Opcodes.SHL)
            | (1L << Opcodes.SHR)
            | (1L << Opcodes.USHR)
            | (1L << Opcodes.XOR);
    long other = (1L << (Opcodes.USHR - 64)) | (1L << (Opcodes.XOR - 64));
    boolean result = isAnySetInFirst(mask) || isAnySetInSecond(other);
    assert result
        == (mayHaveAdd()
            || mayHaveDiv()
            || mayHaveMul()
            || mayHaveRem()
            || mayHaveSub()
            || mayHaveAnd()
            || mayHaveOr()
            || mayHaveShl()
            || mayHaveShr()
            || mayHaveUshr()
            || mayHaveXor());
    return result;
  }
}
