/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.jack.dx.dex.code.form;

import com.android.jack.dx.dex.code.DalvInsn;
import com.android.jack.dx.dex.code.InsnFormat;
import com.android.jack.dx.dex.code.SimpleInsn;
import com.android.jack.dx.rop.code.RegisterSpecList;
import com.android.jack.dx.util.AnnotatedOutput;

import java.util.BitSet;

/**
 * Instruction format {@code 32x}. See the instruction format spec
 * for details.
 */
public final class Form32x extends InsnFormat {
  /** {@code non-null;} unique instance of this class */
  public static final InsnFormat THE_ONE = new Form32x();

  /**
   * Constructs an instance. This class is not publicly
   * instantiable. Use {@link #THE_ONE}.
   */
  private Form32x() {
    // This space intentionally left blank.
  }

  /** {@inheritDoc} */
  @Override
  public String insnArgString(DalvInsn insn) {
    RegisterSpecList regs = insn.getRegisters();
    return regs.get(0).regString() + ", " + regs.get(1).regString();
  }

  /** {@inheritDoc} */
  @Override
  public String insnCommentString(DalvInsn insn, boolean noteIndices) {
    // This format has no comment.
    return "";
  }

  /** {@inheritDoc} */
  @Override
  public int codeSize() {
    return 3;
  }

  /** {@inheritDoc} */
  @Override
  public boolean isCompatible(DalvInsn insn) {
    RegisterSpecList regs = insn.getRegisters();
    return (insn instanceof SimpleInsn) && (regs.size() == 2)
        && unsignedFitsInShort(regs.get(0).getReg()) && unsignedFitsInShort(regs.get(1).getReg());
  }

  /** {@inheritDoc} */
  @Override
  public BitSet compatibleRegs(DalvInsn insn) {
    RegisterSpecList regs = insn.getRegisters();
    BitSet bits = new BitSet(2);

    bits.set(0, unsignedFitsInShort(regs.get(0).getReg()));
    bits.set(1, unsignedFitsInShort(regs.get(1).getReg()));
    return bits;
  }

  /** {@inheritDoc} */
  @Override
  public void writeTo(AnnotatedOutput out, DalvInsn insn) {
    RegisterSpecList regs = insn.getRegisters();

    write(out, opcodeUnit(insn, 0), (short) regs.get(0).getReg(), (short) regs.get(1).getReg());
  }
}
