/*
 * Copyright (C) 2008 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.
 */

/*
 * Dalvik instruction utility functions.
 */
#ifndef _LIBDEX_INSTRUTILS
#define _LIBDEX_INSTRUTILS

#include "DexFile.h"
#include "OpCode.h"

/*
 * Dalvik-defined instruction formats.
 *
 * (This defines InstructionFormat as an unsigned char to reduce the size
 * of the table.  This isn't necessary with some compilers, which use an
 * integer width appropriate for the number of enum values.)
 * 
 * If you add or delete a format, you have to change some or all of:
 *  - this enum
 *  - the switch inside dexDecodeInstruction() in InstrUtils.c
 *  - the switch inside dumpInstruction() in DexDump.c
 */
typedef unsigned char InstructionFormat;
enum InstructionFormat {
    kFmtUnknown = 0,
    kFmt10x,        // op
    kFmt12x,        // op vA, vB
    kFmt11n,        // op vA, #+B
    kFmt11x,        // op vAA
    kFmt10t,        // op +AA
    kFmt20bc,       // op AA, thing@BBBB
    kFmt20t,        // op +AAAA
    kFmt22x,        // op vAA, vBBBB
    kFmt21t,        // op vAA, +BBBB
    kFmt21s,        // op vAA, #+BBBB
    kFmt21h,        // op vAA, #+BBBB00000[00000000]
    kFmt21c,        // op vAA, thing@BBBB
    kFmt23x,        // op vAA, vBB, vCC
    kFmt22b,        // op vAA, vBB, #+CC
    kFmt22t,        // op vA, vB, +CCCC
    kFmt22s,        // op vA, vB, #+CCCC
    kFmt22c,        // op vA, vB, thing@CCCC
    kFmt22cs,       // [opt] op vA, vB, field offset CCCC
    kFmt32x,        // op vAAAA, vBBBB
    kFmt30t,        // op +AAAAAAAA
    kFmt31t,        // op vAA, +BBBBBBBB
    kFmt31i,        // op vAA, #+BBBBBBBB
    kFmt31c,        // op vAA, thing@BBBBBBBB
    kFmt35c,        // op {vC, vD, vE, vF, vG}, thing@BBBB (B: count, A: vG)
    kFmt35ms,       // [opt] invoke-virtual+super
    kFmt35fs,       // [opt] invoke-interface
    kFmt3rc,        // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB
    kFmt3rms,       // [opt] invoke-virtual+super/range
    kFmt3rfs,       // [opt] invoke-interface/range
    kFmt3inline,    // [opt] inline invoke
    kFmt51l,        // op vAA, #+BBBBBBBBBBBBBBBB
};

/*
 * Holds the contents of a decoded instruction.
 */
typedef struct DecodedInstruction {
    u4      vA;
    u4      vB;
    u8      vB_wide;        /* for kFmt51l */
    u4      vC;
    u4      arg[5];         /* vC/D/E/F/G in invoke or filled-new-array */
    OpCode  opCode;
} DecodedInstruction;

/*
 * Instruction width, a value in the range -3 to 5.
 */
typedef signed char InstructionWidth;

/*
 * Instruction flags, used by the verifier to determine where control
 * can flow to next.
 */
typedef unsigned char InstructionFlags;
enum InstructionFlags {
    kInstrCanBranch     = 1,        // conditional or unconditional branch
    kInstrCanContinue   = 1 << 1,   // flow can continue to next statement
    kInstrCanSwitch     = 1 << 2,   // switch statement
    kInstrCanThrow      = 1 << 3,   // could cause an exception to be thrown
    kInstrCanReturn     = 1 << 4,   // returns, no additional statements
    kInstrInvoke        = 1 << 5,   // a flavor of invoke
    kInstrUnconditional = 1 << 6,   // unconditional branch
    kInstrNoJit         = 1 << 7,   // don't jit trace containing this
};


/*
 * Allocate and populate a 256-element array with instruction widths.  A
 * width of zero means the entry does not exist.
 */
InstructionWidth* dexCreateInstrWidthTable(void);

/*
 * Returns the width of the specified instruction, or 0 if not defined.
 * Optimized instructions use negative values.
 */
DEX_INLINE int dexGetInstrWidth(const InstructionWidth* widths, OpCode opCode)
{
   // assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
    return widths[opCode];
}

/*
 * Return the width of the specified instruction, or 0 if not defined.
 */
DEX_INLINE int dexGetInstrWidthAbs(const InstructionWidth* widths,OpCode opCode)
{
    //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);

    int val = dexGetInstrWidth(widths, opCode);
    if (val < 0)
        val = -val;
    /* XXX - the no-compare trick may be a cycle slower on ARM */
    return val;
}

/*
 * Return the width of the specified instruction, or 0 if not defined.  Also
 * works for special OP_NOP entries, including switch statement data tables
 * and array data.
 */
int dexGetInstrOrTableWidthAbs(const InstructionWidth* widths, const u2* insns);


/*
 * Allocate and populate a 256-element array with instruction flags.
 */
InstructionFlags* dexCreateInstrFlagsTable(void);

/*
 * Returns the flags for the specified opcode.
 */
DEX_INLINE int dexGetInstrFlags(const InstructionFlags* flags, OpCode opCode)
{
    //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
    return flags[opCode];
}


/*
 * Allocate and populate a 256-element array with instruction formats.
 */
InstructionFormat* dexCreateInstrFormatTable(void);

/*
 * Return the instruction format for the specified opcode.
 */
DEX_INLINE InstructionFormat dexGetInstrFormat(const InstructionFormat* fmts,
    OpCode opCode)
{
    //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
    return fmts[opCode];
}

/*
 * Decode the instruction pointed to by "insns".
 */
void dexDecodeInstruction(const InstructionFormat* fmts, const u2* insns,
    DecodedInstruction* pDec);

#endif /*_LIBDEX_INSTRUTILS*/
