/*
 * 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/logging.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:
        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 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__
