/*
 * Copyright (c) 2010, 2012-2013, 2017-2018 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.
 *
 * Copyright (c) 2007-2008 The Florida State University
 * 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.
 */

#ifndef __ARCH_ARM_INSTS_PREDINST_HH__
#define __ARCH_ARM_INSTS_PREDINST_HH__

#include "arch/arm/insts/static_inst.hh"
#include "base/compiler.hh"
#include "base/logging.hh"
#include "base/trace.hh"

namespace gem5
{

namespace ArmISA
{
static inline uint32_t
rotate_imm(uint32_t immValue, uint32_t rotateValue)
{
    rotateValue &= 31;
    return rotateValue == 0 ? immValue :
        (immValue >> rotateValue) | (immValue << (32 - rotateValue));
}

static inline uint32_t
modified_imm(uint8_t ctrlImm, uint8_t dataImm)
{
    uint32_t bigData = dataImm;
    uint32_t bigCtrl = ctrlImm;
    if (bigCtrl < 4) {
        switch (bigCtrl) {
          case 0:
            return bigData;
          case 1:
            return bigData | (bigData << 16);
          case 2:
            return (bigData << 8) | (bigData << 24);
          case 3:
            return (bigData << 0) | (bigData << 8) |
                   (bigData << 16) | (bigData << 24);
        }
    }
    bigCtrl = (bigCtrl << 1) | ((bigData >> 7) & 0x1);
    bigData |= (1 << 7);
    return bigData << (32 - bigCtrl);
}

static inline uint64_t
simd_modified_imm(bool op, uint8_t cmode, uint8_t data, bool &immValid,
                  bool isAarch64 = false)
{
    uint64_t bigData = data;
    immValid = true;
    switch (cmode) {
      case 0x0:
      case 0x1:
        bigData = (bigData << 0) | (bigData << 32);
        break;
      case 0x2:
      case 0x3:
        bigData = (bigData << 8) | (bigData << 40);
        break;
      case 0x4:
      case 0x5:
        bigData = (bigData << 16) | (bigData << 48);
        break;
      case 0x6:
      case 0x7:
        bigData = (bigData << 24) | (bigData << 56);
        break;
      case 0x8:
      case 0x9:
        bigData = (bigData << 0) | (bigData << 16) |
                  (bigData << 32) | (bigData << 48);
        break;
      case 0xa:
      case 0xb:
        bigData = (bigData << 8) | (bigData << 24) |
                  (bigData << 40) | (bigData << 56);
        break;
      case 0xc:
        bigData = (0xffULL << 0) | (bigData << 8) |
                  (0xffULL << 32) | (bigData << 40);
        break;
      case 0xd:
        bigData = (0xffffULL << 0) | (bigData << 16) |
                  (0xffffULL << 32) | (bigData << 48);
        break;
      case 0xe:
        if (op) {
            bigData = 0;
            for (int i = 7; i >= 0; i--) {
                if (bits(data, i)) {
                    bigData |= (0xFFULL << (i * 8));
                }
            }
        } else {
            bigData = (bigData << 0)  | (bigData << 8)  |
                      (bigData << 16) | (bigData << 24) |
                      (bigData << 32) | (bigData << 40) |
                      (bigData << 48) | (bigData << 56);
        }
        break;
      case 0xf:
        {
            uint64_t bVal = 0;
            if (!op) {
                bVal = bits(bigData, 6) ? (0x1F) : (0x20);
                bigData = (bits(bigData, 5, 0) << 19) |
                          (bVal << 25) | (bits(bigData, 7) << 31);
                bigData |= (bigData << 32);
                break;
            } else if (isAarch64) {
                bVal = bits(bigData, 6) ? (0x0FF) : (0x100);
                bigData = (bits(bigData, 5, 0) << 48) |
                          (bVal << 54) | (bits(bigData, 7) << 63);
                break;
            }
        }
        [[fallthrough]];
      default:
        immValid = false;
        break;
    }
    return bigData;
}

/** Floating point data types. */
enum class FpDataType { Fp16, Fp32, Fp64 };

static inline uint64_t
vfp_modified_imm(uint8_t data, FpDataType dtype)
{
    uint64_t bigData = data;
    uint64_t repData;
    switch (dtype) {
      case FpDataType::Fp16:
        repData = bits(data, 6) ? 0x3 : 0;
        bigData = (bits(bigData, 5, 0) << 6) |
                  (repData << 12) | (bits(~bigData, 6) << 14) |
                  (bits(bigData, 7) << 15);
        break;
      case FpDataType::Fp32:
        repData = bits(data, 6) ? 0x1F : 0;
        bigData = (bits(bigData, 5, 0) << 19) |
                  (repData << 25) | (bits(~bigData, 6) << 30) |
                  (bits(bigData, 7) << 31);
        break;
      case FpDataType::Fp64:
        repData = bits(data, 6) ? 0xFF : 0;
        bigData = (bits(bigData, 5, 0) << 48) |
                  (repData << 54) | (bits(~bigData, 6) << 62) |
                  (bits(bigData, 7) << 63);
        break;
      default:
        panic("Unrecognized FP data type");
    }
    return bigData;
}

static inline FpDataType
decode_fp_data_type(uint8_t encoding)
{
    switch (encoding) {
      case 1: return FpDataType::Fp16;
      case 2: return FpDataType::Fp32;
      case 3: return FpDataType::Fp64;
      default:
        panic(
            "Invalid floating point data type in VFP/SIMD or SVE instruction");
    }
}

/**
 * Base class for predicated integer operations.
 */
class PredOp : public ArmStaticInst
{
  protected:

    ConditionCode condCode;

    /// Constructor
    PredOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
           ArmStaticInst(mnem, _machInst, __opClass)
    {
        if (machInst.aarch64)
            condCode = COND_UC;
        else if (machInst.itstateMask)
            condCode = (ConditionCode)(uint8_t)machInst.itstateCond;
        else
            condCode = (ConditionCode)(unsigned)machInst.condCode;
    }
};

/**
 * Base class for predicated immediate operations.
 */
class PredImmOp : public PredOp
{
    protected:

    uint32_t imm;
    uint32_t rotated_imm;
    uint32_t rotated_carry;
    uint32_t rotate;

    /// Constructor
    PredImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
              PredOp(mnem, _machInst, __opClass),
              imm(machInst.imm), rotated_imm(0), rotated_carry(0),
              rotate(machInst.rotate << 1)
    {
        rotated_imm = rotate_imm(imm, rotate);
        if (rotate != 0)
            rotated_carry = bits(rotated_imm, 31);
    }

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

/**
 * Base class for predicated integer operations.
 */
class PredIntOp : public PredOp
{
    protected:

    uint32_t shift_size;
    uint32_t shift;

    /// Constructor
    PredIntOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
              PredOp(mnem, _machInst, __opClass),
              shift_size(machInst.shiftSize), shift(machInst.shift)
    {
    }

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

class DataImmOp : public PredOp
{
  protected:
    IntRegIndex dest, op1;
    uint32_t imm;
    // Whether the carry flag should be modified if that's an option for
    // this instruction.
    bool rotC;

    DataImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
              IntRegIndex _dest, IntRegIndex _op1, uint32_t _imm, bool _rotC) :
        PredOp(mnem, _machInst, __opClass),
        dest(_dest), op1(_op1), imm(_imm), rotC(_rotC)
    {}

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

class DataRegOp : public PredOp
{
  protected:
    IntRegIndex dest, op1, op2;
    int32_t shiftAmt;
    ArmShiftType shiftType;

    DataRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
              IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
              int32_t _shiftAmt, ArmShiftType _shiftType) :
        PredOp(mnem, _machInst, __opClass),
        dest(_dest), op1(_op1), op2(_op2),
        shiftAmt(_shiftAmt), shiftType(_shiftType)
    {}

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

class DataRegRegOp : public PredOp
{
  protected:
    IntRegIndex dest, op1, op2, shift;
    ArmShiftType shiftType;

    DataRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
                 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
                 IntRegIndex _shift, ArmShiftType _shiftType) :
        PredOp(mnem, _machInst, __opClass),
        dest(_dest), op1(_op1), op2(_op2), shift(_shift),
        shiftType(_shiftType)
    {}

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

/**
 * Base class for predicated macro-operations.
 */
class PredMacroOp : public PredOp
{
    protected:

    uint32_t numMicroops;
    StaticInstPtr * microOps;

    /// Constructor
    PredMacroOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
                PredOp(mnem, _machInst, __opClass),
                numMicroops(0), microOps(nullptr)
    {
        // We rely on the subclasses of this object to handle the
        // initialization of the micro-operations, since they are
        // all of variable length
        flags[IsMacroop] = true;
    }

    ~PredMacroOp()
    {
        if (numMicroops)
            delete [] microOps;
    }

    StaticInstPtr
    fetchMicroop(MicroPC microPC) const override
    {
        assert(microPC < numMicroops);
        return microOps[microPC];
    }

    Fault
    execute(ExecContext *, Trace::InstRecord *) const override
    {
        panic("Execute method called when it shouldn't!");
    }

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

/**
 * Base class for predicated micro-operations.
 */
class PredMicroop : public PredOp
{
    /// Constructor
    PredMicroop(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
                PredOp(mnem, _machInst, __opClass)
    {
        flags[IsMicroop] = true;
    }

    void
    advancePC(PCState &pcState) const override
    {
        if (flags[IsLastMicroop])
            pcState.uEnd();
        else
            pcState.uAdvance();
    }
};

} // namespace ArmISA
} // namespace gem5

#endif //__ARCH_ARM_INSTS_PREDINST_HH__
