/*
 * 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.
 *
 * Authors: Stephen Hines
 */
#ifndef __ARCH_ARM_INSTS_PREDINST_HH__
#define __ARCH_ARM_INSTS_PREDINST_HH__

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

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 |= (ULL(0xFF) << (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;
            }
        }
        M5_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:
        assert(0);
    }
    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 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 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 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 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 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 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
    {
        if (flags[IsLastMicroop])
            pcState.uEnd();
        else
            pcState.uAdvance();
    }
};
}

#endif //__ARCH_ARM_INSTS_PREDINST_HH__
