/*
 * 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.dexgen.rop.code;

import com.android.dexgen.rop.cst.CstInteger;
import com.android.dexgen.rop.type.Type;

/**
 * Implementation of {@link TranslationAdvice} which represents what
 * the dex format will be able to represent.
 */
public final class DexTranslationAdvice
        implements TranslationAdvice {
    /** {@code non-null;} standard instance of this class */
    public static final DexTranslationAdvice THE_ONE =
        new DexTranslationAdvice();

    /** debug advice for disabling invoke-range optimization */
    public static final DexTranslationAdvice NO_SOURCES_IN_ORDER =
        new DexTranslationAdvice(true);

    /**
     * The minimum source width, in register units, for an invoke
     * instruction that requires its sources to be in order and contiguous.
     */
    private static final int MIN_INVOKE_IN_ORDER = 6;

    /** when true: always returns false for requiresSourcesInOrder */
    private final boolean disableSourcesInOrder;

    /**
     * This class is not publicly instantiable. Use {@link #THE_ONE}.
     */
    private DexTranslationAdvice() {
        disableSourcesInOrder = false;
    }

    private DexTranslationAdvice(boolean disableInvokeRange) {
        this.disableSourcesInOrder = disableInvokeRange;
    }

    /** {@inheritDoc} */
    public boolean hasConstantOperation(Rop opcode,
            RegisterSpec sourceA, RegisterSpec sourceB) {
        if (sourceA.getType() != Type.INT) {
            return false;
        }

        if (! (sourceB.getTypeBearer() instanceof CstInteger)) {
            return false;
        }

        CstInteger cst = (CstInteger) sourceB.getTypeBearer();

        // TODO handle rsub
        switch (opcode.getOpcode()) {
            // These have 8 and 16 bit cst representations
            case RegOps.REM:
            case RegOps.ADD:
            case RegOps.MUL:
            case RegOps.DIV:
            case RegOps.AND:
            case RegOps.OR:
            case RegOps.XOR:
                return cst.fitsIn16Bits();
            // These only have 8 bit cst reps
            case RegOps.SHL:
            case RegOps.SHR:
            case RegOps.USHR:
                return cst.fitsIn8Bits();
            default:
                return false;
        }
    }

    /** {@inheritDoc} */
    public boolean requiresSourcesInOrder(Rop opcode,
            RegisterSpecList sources) {

        return !disableSourcesInOrder && opcode.isCallLike()
                && totalRopWidth(sources) >= MIN_INVOKE_IN_ORDER;
    }

    /**
     * Calculates the total rop width of the list of SSA registers
     *
     * @param sources {@code non-null;} list of SSA registers
     * @return {@code >= 0;} rop-form width in register units
     */
    private int totalRopWidth(RegisterSpecList sources) {
        int sz = sources.size();
        int total = 0;

        for (int i = 0; i < sz; i++) {
            total += sources.get(i).getCategory();
        }

        return total;
    }

    /** {@inheritDoc} */
    public int getMaxOptimalRegisterCount() {
        return 16;
    }
}
