// -*- mode:c++ -*-

// Copyright (c) 2010, 2014 ARM Limited
// All rights reserved
//
// The license below extends only to copyright in the software and shall
// not be construed as granting a license to any other intellectual
// property including but not limited to intellectual property relating
// to a hardware implementation of the functionality of the software
// licensed hereunder.  You may use the software subject to the license
// terms below provided that you ensure that this notice is replicated
// unmodified and in its entirety in all distributions of the software,
// modified or unmodified, in source code or in binary form.
//
// 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.

def template BranchImmCondDeclare {{
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, int32_t _imm,
                   ConditionCode _condCode);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
    ArmISA::PCState branchTarget(
            const ArmISA::PCState &branchPC) const override;

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

def template BranchImmCondConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst, int32_t _imm,
                                   ConditionCode _condCode) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _imm, _condCode)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
            flags[IsCondControl] = true;
        } else {
            flags[IsUncondControl] = true;
        }
    }
}};

def template BranchRegCondDeclare {{
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, IntRegIndex _op1,
                   ConditionCode _condCode);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template BranchRegCondConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst, IntRegIndex _op1,
                                   ConditionCode _condCode) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _op1, _condCode)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
            flags[IsCondControl] = true;
        } else {
            flags[IsUncondControl] = true;
        }
        if (%(is_ras_pop)s)
            flags[IsReturn] = true;
    }
}};

def template BranchTableDeclare {{
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, IntRegIndex _op1, IntRegIndex _op2);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
    Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
    Fault completeAcc(PacketPtr, ExecContext *,
                      Trace::InstRecord *) const override;
};
}};

def template BranchRegRegConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
                                   IntRegIndex _op1, IntRegIndex _op2) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _op1, _op2)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
            flags[IsCondControl] = true;
        } else {
            flags[IsUncondControl] = true;
        }
    }
}};

def template BranchImmRegDeclare {{
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, int32_t imm, IntRegIndex _op1);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
    ArmISA::PCState branchTarget(
            const ArmISA::PCState &branchPC) const override;

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

// Only used by CBNZ, CBZ which is conditional based on
// a register value even though the instruction is always unconditional.
def template BranchImmRegConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst, int32_t _imm,
                                   IntRegIndex _op1) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _imm, _op1)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        flags[IsCondControl] = true;
    }
}};

def template BranchTarget {{

    ArmISA::PCState
    %(class_name)s::branchTarget(const ArmISA::PCState &branchPC) const
    {
        %(op_decl)s;
        %(op_rd)s;

        ArmISA::PCState pcs = branchPC;
        %(brTgtCode)s
        pcs.advance();
        return pcs;
    }
}};


