/*
 * 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.dx.dex.code;

import com.android.dx.rop.code.RegisterSpec;
import com.android.dx.rop.code.RegisterSpecList;
import com.android.dx.rop.code.SourcePosition;
import com.android.dx.util.AnnotatedOutput;
import com.android.dx.util.Hex;
import com.android.dx.util.TwoColumnOutput;

import java.util.BitSet;

/**
 * Base class for Dalvik instructions.
 */
public abstract class DalvInsn {
    /**
     * the actual output address of this instance, if known, or
     * {@code -1} if not
     */
    private int address;

    /** the opcode; one of the constants from {@link Dops} */
    private final Dop opcode;

    /** {@code non-null;} source position */
    private final SourcePosition position;

    /** {@code non-null;} list of register arguments */
    private final RegisterSpecList registers;

    /**
     * Makes a move instruction, appropriate and ideal for the given arguments.
     *
     * @param position {@code non-null;} source position information
     * @param dest {@code non-null;} destination register
     * @param src {@code non-null;} source register
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public static SimpleInsn makeMove(SourcePosition position,
            RegisterSpec dest, RegisterSpec src) {
        boolean category1 = dest.getCategory() == 1;
        boolean reference = dest.getType().isReference();
        int destReg = dest.getReg();
        int srcReg = src.getReg();
        Dop opcode;

        if ((srcReg | destReg) < 16) {
            opcode = reference ? Dops.MOVE_OBJECT :
                (category1 ? Dops.MOVE : Dops.MOVE_WIDE);
        } else if (destReg < 256) {
            opcode = reference ? Dops.MOVE_OBJECT_FROM16 :
                (category1 ? Dops.MOVE_FROM16 : Dops.MOVE_WIDE_FROM16);
        } else {
            opcode = reference ? Dops.MOVE_OBJECT_16 :
                (category1 ? Dops.MOVE_16 : Dops.MOVE_WIDE_16);
        }

        return new SimpleInsn(opcode, position,
                              RegisterSpecList.make(dest, src));
    }

    /**
     * Constructs an instance. The output address of this instance is initially
     * unknown ({@code -1}).
     *
     * <p><b>Note:</b> In the unlikely event that an instruction takes
     * absolutely no registers (e.g., a {@code nop} or a
     * no-argument no-result static method call), then the given
     * register list may be passed as {@link
     * RegisterSpecList#EMPTY}.</p>
     *
     * @param opcode the opcode; one of the constants from {@link Dops}
     * @param position {@code non-null;} source position
     * @param registers {@code non-null;} register list, including a
     * result register if appropriate (that is, registers may be either
     * ins and outs)
     */
    public DalvInsn(Dop opcode, SourcePosition position,
                    RegisterSpecList registers) {
        if (opcode == null) {
            throw new NullPointerException("opcode == null");
        }

        if (position == null) {
            throw new NullPointerException("position == null");
        }

        if (registers == null) {
            throw new NullPointerException("registers == null");
        }

        this.address = -1;
        this.opcode = opcode;
        this.position = position;
        this.registers = registers;
    }

    /** {@inheritDoc} */
    @Override
    public final String toString() {
        StringBuffer sb = new StringBuffer(100);

        sb.append(identifierString());
        sb.append(' ');
        sb.append(position);

        sb.append(": ");
        sb.append(opcode.getName());

        boolean needComma = false;
        if (registers.size() != 0) {
            sb.append(registers.toHuman(" ", ", ", null));
            needComma = true;
        }

        String extra = argString();
        if (extra != null) {
            if (needComma) {
                sb.append(',');
            }
            sb.append(' ');
            sb.append(extra);
        }

        return sb.toString();
    }

    /**
     * Gets whether the address of this instruction is known.
     *
     * @see #getAddress
     * @see #setAddress
     */
    public final boolean hasAddress() {
        return (address >= 0);
    }

    /**
     * Gets the output address of this instruction, if it is known. This throws
     * a {@code RuntimeException} if it has not yet been set.
     *
     * @see #setAddress
     *
     * @return {@code >= 0;} the output address
     */
    public final int getAddress() {
        if (address < 0) {
            throw new RuntimeException("address not yet known");
        }

        return address;
    }

    /**
     * Gets the opcode.
     *
     * @return {@code non-null;} the opcode
     */
    public final Dop getOpcode() {
        return opcode;
    }

    /**
     * Gets the source position.
     *
     * @return {@code non-null;} the source position
     */
    public final SourcePosition getPosition() {
        return position;
    }

    /**
     * Gets the register list for this instruction.
     *
     * @return {@code non-null;} the registers
     */
    public final RegisterSpecList getRegisters() {
        return registers;
    }

    /**
     * Returns whether this instance's opcode uses a result register.
     * This method is a convenient shorthand for
     * {@code getOpcode().hasResult()}.
     *
     * @return {@code true} iff this opcode uses a result register
     */
    public final boolean hasResult() {
        return opcode.hasResult();
    }

    /**
     * Gets the minimum distinct registers required for this instruction.
     * Uses the given BitSet to determine which registers require
     * replacement, and ignores registers that are already compatible.
     * This assumes that the result (if any) can share registers with the
     * sources (if any), that each source register is unique, and that
     * (to be explicit here) category-2 values take up two consecutive
     * registers.
     *
     * @param compatRegs {@code non-null;} set of compatible registers
     * @return {@code >= 0;} the minimum distinct register requirement
     */
    public final int getMinimumRegisterRequirement(BitSet compatRegs) {
        boolean hasResult = hasResult();
        int regSz = registers.size();
        int resultRequirement = 0;
        int sourceRequirement = 0;

        if (hasResult && !compatRegs.get(0)) {
            resultRequirement = registers.get(0).getCategory();
        }

        for (int i = hasResult ? 1 : 0; i < regSz; i++) {
            if (!compatRegs.get(i)) {
                sourceRequirement += registers.get(i).getCategory();
            }
        }

        return Math.max(sourceRequirement, resultRequirement);
    }

    /**
     * Gets the instruction that is equivalent to this one, except that
     * it uses sequential registers starting at {@code 0} (storing
     * the result, if any, in register {@code 0} as well).
     *
     * @return {@code non-null;} the replacement
     */
    public DalvInsn getLowRegVersion() {
        RegisterSpecList regs =
            registers.withExpandedRegisters(0, hasResult(), null);
        return withRegisters(regs);
    }

    /**
     * Gets the instruction prefix required, if any, to use in an expanded
     * version of this instance. Will not generate moves for registers
     * marked compatible to the format by the given BitSet.
     *
     * @see #expandedVersion
     *
     * @param compatRegs {@code non-null;} set of compatible registers
     * @return {@code null-ok;} the prefix, if any
     */
    public DalvInsn expandedPrefix(BitSet compatRegs) {
        RegisterSpecList regs = registers;
        boolean firstBit = compatRegs.get(0);

        if (hasResult()) compatRegs.set(0);

        regs = regs.subset(compatRegs);

        if (hasResult()) compatRegs.set(0, firstBit);

        if (regs.size() == 0) return null;

        return new HighRegisterPrefix(position, regs);
    }

    /**
     * Gets the instruction suffix required, if any, to use in an expanded
     * version of this instance. Will not generate a move for a register
     * marked compatible to the format by the given BitSet.
     *
     * @see #expandedVersion
     *
     * @param compatRegs {@code non-null;} set of compatible registers
     * @return {@code null-ok;} the suffix, if any
     */
    public DalvInsn expandedSuffix(BitSet compatRegs) {
        if (hasResult() && !compatRegs.get(0)) {
            RegisterSpec r = registers.get(0);
            return makeMove(position, r, r.withReg(0));
        } else {
            return null;
        }
    }

    /**
     * Gets the instruction that is equivalent to this one, except that
     * it replaces incompatible registers with sequential registers
     * starting at {@code 0} (storing the result, if any, in register
     * {@code 0} as well). The sequence of instructions from
     * {@link #expandedPrefix} and {@link #expandedSuffix} (if non-null)
     * surrounding the result of a call to this method are the expanded
     * transformation of this instance, and it is guaranteed that the
     * number of low registers used will be the number returned by
     * {@link #getMinimumRegisterRequirement}.
     *
     * @param compatRegs {@code non-null;} set of compatible registers
     * @return {@code non-null;} the replacement
     */
    public DalvInsn expandedVersion(BitSet compatRegs) {
        RegisterSpecList regs =
            registers.withExpandedRegisters(0, hasResult(), compatRegs);
        return withRegisters(regs);
    }

    /**
     * Gets the short identifier for this instruction. This is its
     * address, if assigned, or its identity hashcode if not.
     *
     * @return {@code non-null;} the identifier
     */
    public final String identifierString() {
        if (address != -1) {
            return String.format("%04x", address);
        }

        return Hex.u4(System.identityHashCode(this));
    }

    /**
     * Returns the string form of this instance suitable for inclusion in
     * a human-oriented listing dump. This method will return {@code null}
     * if this instance should not appear in a listing.
     *
     * @param prefix {@code non-null;} prefix before the address; each follow-on
     * line will be indented to match as well
     * @param width {@code >= 0;} the width of the output or {@code 0} for
     * unlimited width
     * @param noteIndices whether to include an explicit notation of
     * constant pool indices
     * @return {@code null-ok;} the string form or {@code null} if this
     * instance should not appear in a listing
     */
    public final String listingString(String prefix, int width,
            boolean noteIndices) {
        String insnPerSe = listingString0(noteIndices);

        if (insnPerSe == null) {
            return null;
        }

        String addr = prefix + identifierString() + ": ";
        int w1 = addr.length();
        int w2 = (width == 0) ? insnPerSe.length() : (width - w1);

        return TwoColumnOutput.toString(addr, w1, "", insnPerSe, w2);
    }

    /**
     * Sets the output address.
     *
     * @param address {@code >= 0;} the output address
     */
    public final void setAddress(int address) {
        if (address < 0) {
            throw new IllegalArgumentException("address < 0");
        }

        this.address = address;
    }

    /**
     * Gets the address immediately after this instance. This is only
     * calculable if this instance's address is known, and it is equal
     * to the address plus the length of the instruction format of this
     * instance's opcode.
     *
     * @return {@code >= 0;} the next address
     */
    public final int getNextAddress() {
        return getAddress() + codeSize();
    }

    /**
     * Gets the size of this instruction, in 16-bit code units.
     *
     * @return {@code >= 0;} the code size of this instruction
     */
    public abstract int codeSize();

    /**
     * Writes this instance to the given output. This method should
     * never annotate the output.
     *
     * @param out {@code non-null;} where to write to
     */
    public abstract void writeTo(AnnotatedOutput out);

    /**
     * Returns an instance that is just like this one, except that its
     * opcode is replaced by the one given, and its address is reset.
     *
     * @param opcode {@code non-null;} the new opcode
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public abstract DalvInsn withOpcode(Dop opcode);

    /**
     * Returns an instance that is just like this one, except that all
     * register references have been offset by the given delta, and its
     * address is reset.
     *
     * @param delta the amount to offset register references by
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public abstract DalvInsn withRegisterOffset(int delta);

    /**
     * Returns an instance that is just like this one, except that the
     * register list is replaced by the given one, and its address is
     * reset.
     *
     * @param registers {@code non-null;} new register list
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public abstract DalvInsn withRegisters(RegisterSpecList registers);

    /**
     * Gets the string form for any arguments to this instance. Subclasses
     * must override this.
     *
     * @return {@code null-ok;} the string version of any arguments or
     * {@code null} if there are none
     */
    protected abstract String argString();

    /**
     * Helper for {@link #listingString}, which returns the string
     * form of this instance suitable for inclusion in a
     * human-oriented listing dump, not including the instruction
     * address and without respect for any output formatting. This
     * method should return {@code null} if this instance should
     * not appear in a listing.
     *
     * @param noteIndices whether to include an explicit notation of
     * constant pool indices
     * @return {@code null-ok;} the listing string
     */
    protected abstract String listingString0(boolean noteIndices);
}
