/*
 * 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.ssa;

import com.android.dx.rop.code.*;
import com.android.dx.util.ToHuman;

/**
 * An instruction in SSA form
 */
public abstract class SsaInsn implements ToHuman, Cloneable {
    /** {@code non-null;} the block that contains this instance */
    private final SsaBasicBlock block;

    /** {@code null-ok;} result register */
    private RegisterSpec result;

    /**
     * Constructs an instance.
     *
     * @param result {@code null-ok;} initial result register. May be changed.
     * @param block {@code non-null;} block containing this insn. Can
     * never change.
     */
    protected SsaInsn(RegisterSpec result, SsaBasicBlock block) {
        if (block == null) {
            throw new NullPointerException("block == null");
        }

        this.block = block;
        this.result = result;
    }

    /**
     * Makes a new SSA insn form a rop insn.
     *
     * @param insn {@code non-null;} rop insn
     * @param block {@code non-null;} owning block
     * @return {@code non-null;} an appropriately constructed instance
     */
    public static SsaInsn makeFromRop(Insn insn, SsaBasicBlock block) {
        return new NormalSsaInsn(insn, block);
    }

    /** {@inheritDoc} */
    @Override
    public SsaInsn clone() {
        try {
            return (SsaInsn)super.clone();
        } catch (CloneNotSupportedException ex) {
            throw new RuntimeException ("unexpected", ex);
        }
    }

    /**
     * Like {@link com.android.dx.rop.code.Insn getResult()}.
     *
     * @return result register
     */
    public RegisterSpec getResult() {
        return result;
    }

    /**
     * Set the result register.
     *
     * @param result {@code non-null;} the new result register
     */
    protected void setResult(RegisterSpec result) {
        if (result == null) {
            throw new NullPointerException("result == null");
        }

        this.result = result;
    }

    /**
     * Like {@link com.android.dx.rop.code.Insn getSources()}.
     *
     * @return {@code non-null;} sources list
     */
    abstract public RegisterSpecList getSources();

    /**
     * Gets the block to which this insn instance belongs.
     *
     * @return owning block
     */
    public SsaBasicBlock getBlock() {
        return block;
    }

    /**
     * Returns whether or not the specified reg is the result reg.
     *
     * @param reg register to test
     * @return true if there is a result and it is stored in the specified
     * register
     */
    public boolean isResultReg(int reg) {
        return result != null && result.getReg() == reg;
    }


    /**
     * Changes the result register if this insn has a result. This is used
     * during renaming.
     *
     * @param reg new result register
     */
    public void changeResultReg(int reg) {
        if (result != null) {
            result = result.withReg(reg);
        }
    }

    /**
     * Sets the local association for the result of this insn. This is
     * sometimes updated during the SsaRenamer process.
     *
     * @param local {@code null-ok;} new debug/local variable info
     */
    public final void setResultLocal(LocalItem local) {
        LocalItem oldItem = result.getLocalItem();

        if (local != oldItem && (local == null
                || !local.equals(result.getLocalItem()))) {
            result = RegisterSpec.makeLocalOptional(
                    result.getReg(), result.getType(), local);
        }
    }

    /**
     * Map registers after register allocation.
     *
     * @param mapper {@code non-null;} mapping from old to new registers
     */
    public final void mapRegisters(RegisterMapper mapper) {
        RegisterSpec oldResult = result;

        result = mapper.map(result);
        block.getParent().updateOneDefinition(this, oldResult);
        mapSourceRegisters(mapper);
    }

    /**
     * Maps only source registers.
     *
     * @param mapper new mapping
     */
    abstract public void mapSourceRegisters(RegisterMapper mapper);

    /**
     * Returns the Rop opcode for this insn, or null if this is a phi insn.
     *
     * TODO: Move this up into NormalSsaInsn.
     *
     * @return {@code null-ok;} Rop opcode if there is one.
     */
    abstract public Rop getOpcode();

    /**
     * Returns the original Rop insn for this insn, or null if this is
     * a phi insn.
     *
     * TODO: Move this up into NormalSsaInsn.
     *
     * @return {@code null-ok;} Rop insn if there is one.
     */
    abstract public Insn getOriginalRopInsn();

    /**
     * Gets the spec of a local variable assignment that occurs at this
     * instruction, or null if no local variable assignment occurs. This
     * may be the result register, or for {@code mark-local} insns
     * it may be the source.
     *
     * @see com.android.dx.rop.code.Insn#getLocalAssignment()
     *
     * @return {@code null-ok;} a local-associated register spec or null
     */
    public RegisterSpec getLocalAssignment() {
        if (result != null && result.getLocalItem() != null) {
            return result;
        }

        return null;
    }

    /**
     * Indicates whether the specified register is amongst the registers
     * used as sources for this instruction.
     *
     * @param reg the register in question
     * @return true if the reg is a source
     */
    public boolean isRegASource(int reg) {
        return null != getSources().specForRegister(reg);
    }

    /**
     * Transform back to ROP form.
     *
     * TODO: Move this up into NormalSsaInsn.
     *
     * @return {@code non-null;} a ROP representation of this instruction, with
     * updated registers.
     */
    public abstract Insn toRopInsn();

    /**
     * @return true if this is a PhiInsn or a normal move insn
     */
    public abstract boolean isPhiOrMove();

    /**
     * Returns true if this insn is considered to have a side effect beyond
     * that of assigning to the result reg.
     *
     * @return true if this insn is considered to have a side effect beyond
     * that of assigning to the result reg.
     */
    public abstract boolean hasSideEffect();

    /**
     * @return true if this is a move (but not a move-operand or
     * move-exception) instruction
     */
    public boolean isNormalMoveInsn() {
        return false;
    }

    /**
     * @return true if this is a move-exception instruction.
     * These instructions must immediately follow a preceeding invoke*
     */
    public boolean isMoveException() {
        return false;
    }

    /**
     * @return true if this instruction can throw.
     */
    abstract public boolean canThrow();

    /**
     * Accepts a visitor.
     *
     * @param v {@code non-null} the visitor
     */
    public abstract void accept(Visitor v);

    /**
     * Visitor interface for this class.
     */
    public static interface Visitor {
        /**
         * Any non-phi move instruction
         * @param insn {@code non-null;} the instruction to visit
         */
        public void visitMoveInsn(NormalSsaInsn insn);

        /**
         * Any phi insn
         * @param insn {@code non-null;} the instruction to visit
         */
        public void visitPhiInsn(PhiInsn insn);

        /**
         * Any insn that isn't a move or a phi (which is also a move).
         * @param insn {@code non-null;} the instruction to visit
         */
        public void visitNonMoveInsn(NormalSsaInsn insn);
    }
}
