/* Copyright (c) 2007-2008 The Florida State University
 * Copyright (c) 2009 The University of Edinburgh
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Timothy M. Jones
 */

#ifndef __ARCH_POWER_INSTS_BRANCH_HH__
#define __ARCH_POWER_INSTS_BRANCH_HH__

#include "arch/power/insts/static_inst.hh"

namespace PowerISA
{

/**
 * Base class for instructions whose disassembly is not purely a
 * function of the machine instruction (i.e., it depends on the
 * PC).  This class overrides the disassemble() method to check
 * the PC and symbol table values before re-using a cached
 * disassembly string.  This is necessary for branches and jumps,
 * where the disassembly string includes the target address (which
 * may depend on the PC and/or symbol table).
 */
class PCDependentDisassembly : public PowerStaticInst
{
  protected:
    /// Cached program counter from last disassembly
    mutable Addr cachedPC;
    /// Cached symbol table pointer from last disassembly
    mutable const SymbolTable *cachedSymtab;

    /// Constructor
    PCDependentDisassembly(const char *mnem, ExtMachInst _machInst,
                           OpClass __opClass)
        : PowerStaticInst(mnem, _machInst, __opClass),
          cachedPC(0), cachedSymtab(0)
    {
    }

    const std::string &
    disassemble(Addr pc, const SymbolTable *symtab) const;
};

/**
 * Base class for unconditional, PC-relative branches.
 */
class BranchPCRel : public PCDependentDisassembly
{
  protected:

    /// Displacement
    uint32_t disp;

    /// Constructor.
    BranchPCRel(const char *mnem, MachInst _machInst, OpClass __opClass)
        : PCDependentDisassembly(mnem, _machInst, __opClass),
          disp(machInst.li << 2)
    {
        // If bit 26 is 1 then sign extend
        if (disp & 0x2000000) {
            disp |= 0xfc000000;
        }
    }

    PowerISA::PCState branchTarget(const PowerISA::PCState &pc) const override;

    /// Explicitly import the otherwise hidden branchTarget
    using StaticInst::branchTarget;

    std::string generateDisassembly(
            Addr pc, const SymbolTable *symtab) const override;
};

/**
 * Base class for unconditional, non PC-relative branches.
 */
class BranchNonPCRel : public PCDependentDisassembly
{
  protected:

    /// Target address
    uint32_t targetAddr;

    /// Constructor.
    BranchNonPCRel(const char *mnem, MachInst _machInst, OpClass __opClass)
        : PCDependentDisassembly(mnem, _machInst, __opClass),
          targetAddr(machInst.li << 2)
    {
        // If bit 26 is 1 then sign extend
        if (targetAddr & 0x2000000) {
            targetAddr |= 0xfc000000;
        }
    }

    PowerISA::PCState branchTarget(const PowerISA::PCState &pc) const override;

    /// Explicitly import the otherwise hidden branchTarget
    using StaticInst::branchTarget;

    std::string generateDisassembly(
            Addr pc, const SymbolTable *symtab) const override;
};

/**
 * Base class for conditional branches.
 */
class BranchCond : public PCDependentDisassembly
{
  protected:

    /// Fields needed for conditions
    uint32_t bo;
    uint32_t bi;

    /// Constructor.
    BranchCond(const char *mnem, MachInst _machInst, OpClass __opClass)
        : PCDependentDisassembly(mnem, _machInst, __opClass),
          bo(machInst.bo),
          bi(machInst.bi)
    {
    }

    inline bool
    ctrOk(uint32_t& ctr) const
    {
        bool ctr_ok;
        if (bo & 4) {
            ctr_ok = true;
        } else {
            ctr--;
            if (ctr != 0) {
                ctr_ok = ((bo & 2) == 0);
            } else {
                ctr_ok = ((bo & 2) != 0);
            }
        }
        return ctr_ok;
    }

    inline bool
    condOk(uint32_t cr) const
    {
        bool cond_ok;
        if (bo & 16) {
            cond_ok = true;
        } else {
            cond_ok = (((cr >> (31 - bi)) & 1) == ((bo >> 3) & 1));
        }
        return cond_ok;
    }
};

/**
 * Base class for conditional, PC-relative branches.
 */
class BranchPCRelCond : public BranchCond
{
  protected:

    /// Displacement
    uint32_t disp;

    /// Constructor.
    BranchPCRelCond(const char *mnem, MachInst _machInst, OpClass __opClass)
        : BranchCond(mnem, _machInst, __opClass),
          disp(machInst.bd << 2)
    {
        // If bit 16 is 1 then sign extend
        if (disp & 0x8000) {
            disp |= 0xffff0000;
        }
    }

    PowerISA::PCState branchTarget(const PowerISA::PCState &pc) const override;

    /// Explicitly import the otherwise hidden branchTarget
    using StaticInst::branchTarget;

    std::string generateDisassembly(
            Addr pc, const SymbolTable *symtab) const override;
};

/**
 * Base class for conditional, non PC-relative branches.
 */
class BranchNonPCRelCond : public BranchCond
{
  protected:

    /// Target address
    uint32_t targetAddr;

    /// Constructor.
    BranchNonPCRelCond(const char *mnem, MachInst _machInst, OpClass __opClass)
        : BranchCond(mnem, _machInst, __opClass),
          targetAddr(machInst.bd << 2)
    {
        // If bit 16 is 1 then sign extend
        if (targetAddr & 0x8000) {
            targetAddr |= 0xffff0000;
        }
    }

    PowerISA::PCState branchTarget(const PowerISA::PCState &pc) const override;

    /// Explicitly import the otherwise hidden branchTarget
    using StaticInst::branchTarget;

    std::string generateDisassembly(
            Addr pc, const SymbolTable *symtab) const override;
};

/**
 * Base class for conditional, register-based branches
 */
class BranchRegCond : public BranchCond
{
  protected:

    /// Constructor.
    BranchRegCond(const char *mnem, MachInst _machInst, OpClass __opClass)
        : BranchCond(mnem, _machInst, __opClass)
    {
    }

    PowerISA::PCState branchTarget(ThreadContext *tc) const override;

    /// Explicitly import the otherwise hidden branchTarget
    using StaticInst::branchTarget;

    std::string generateDisassembly(
            Addr pc, const SymbolTable *symtab) const override;
};

} // namespace PowerISA

#endif //__ARCH_POWER_INSTS_BRANCH_HH__
