/*
 * Copyright (c) 2018-2020 Inria
 * 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.
 */

/** @file
 * Definition of the Frequent Pattern Compression cache compressor, as
 * described in "Frequent Pattern Compression: A Significance-Based
 * Compression Scheme for L2 Caches".
 */

#ifndef __MEM_CACHE_COMPRESSORS_FPC_HH__
#define __MEM_CACHE_COMPRESSORS_FPC_HH__

#include <cstdint>
#include <map>
#include <memory>
#include <string>
#include <type_traits>
#include <vector>

#include "base/bitfield.hh"
#include "base/types.hh"
#include "mem/cache/compressors/dictionary_compressor.hh"

namespace gem5
{

struct FPCParams;

GEM5_DEPRECATED_NAMESPACE(Compressor, compression);
namespace compression
{

class FPC : public DictionaryCompressor<uint32_t>
{
  private:
    using DictionaryEntry = DictionaryCompressor<uint32_t>::DictionaryEntry;

    /**
     * Compression data for FPC. It contains a list of the patterns
     * encountered while parsing the cache line.
     */
    class FPCCompData;

    // Declaration of all possible patterns
    class ZeroRun;
    class SignExtended4Bits;
    class SignExtended1Byte;
    class SignExtendedHalfword;
    class ZeroPaddedHalfword;
    class SignExtendedTwoHalfwords;
    class RepBytes;
    class Uncompressed;

    /**
     * The possible patterns. If a new pattern is added, it must be done
     * before NUM_PATTERNS.
     */
    typedef enum
    {
        ZERO_RUN, SIGN_EXTENDED_4_BITS, SIGN_EXTENDED_1_BYTE,
        SIGN_EXTENDED_HALFWORD, ZERO_PADDED_HALFWORD,
        SIGN_EXTENDED_TWO_HALFWORDS, REP_BYTES, UNCOMPRESSED,
        NUM_PATTERNS
    } PatternNumber;

    /**
     * Number of bits of the zero run size bitfield. If the size of the
     * zero run reaches the maximum value, it is split into ZERO_RUN entries.
     */
    const int zeroRunSizeBits;

    uint64_t getNumPatterns() const override { return NUM_PATTERNS; }

    std::string
    getName(int number) const override
    {
        static std::map<int, std::string> patternNames = {
            {ZERO_RUN, "ZERO_RUN"},
            {SIGN_EXTENDED_4_BITS, "SignExtended4Bits"},
            {SIGN_EXTENDED_1_BYTE, "SignExtended1Byte"},
            {SIGN_EXTENDED_HALFWORD, "SignExtendedHalfword"},
            {ZERO_PADDED_HALFWORD, "ZeroPaddedHalfword"},
            {SIGN_EXTENDED_TWO_HALFWORDS, "SignExtendedTwoHalfwords"},
            {REP_BYTES, "RepBytes"},
            {UNCOMPRESSED, "Uncompressed"}
        };

        return patternNames[number];
    };

    std::unique_ptr<Pattern> getPattern(
        const DictionaryEntry& bytes,
        const DictionaryEntry& dict_bytes,
        const int match_location) const override
    {
        using PatternFactory = Factory<ZeroRun, SignExtended4Bits,
            SignExtended1Byte, SignExtendedHalfword, ZeroPaddedHalfword,
            SignExtendedTwoHalfwords, RepBytes, Uncompressed>;
        return PatternFactory::getPattern(bytes, dict_bytes, match_location);
    }

    void addToDictionary(const DictionaryEntry data) override;

    std::unique_ptr<DictionaryCompressor::CompData>
    instantiateDictionaryCompData() const override;

  public:
    typedef FPCParams Params;
    FPC(const Params &p);
    ~FPC() = default;
};

class FPC::FPCCompData : public DictionaryCompressor<uint32_t>::CompData
{
  protected:
    /**
     * Number of bits of the zero run size bitfield. If the size of the
     * zero run reaches the maximum value, it is split into ZERO_RUN entries.
     */
    const int zeroRunSizeBits;

  public:
    FPCCompData(int zeroRunSizeBits);
    ~FPCCompData() = default;

    void addEntry(std::unique_ptr<Pattern> pattern) override;
};

// Pattern implementations

class FPC::ZeroRun : public MaskedValuePattern<0, 0xFFFFFFFF>
{
  private:
    /** Run length so far. */
    int _runLength;

    /**
     * A zero run consists of a main ZeroRun pattern, which has a meaningful
     * real size (i.e., different from zero), and X-1 fake (i.e., they are
     * zero-sized, and don't exist in a real implementation) patterns, with X
     * being the size of the zero run.
     */
    int _realSize;

  public:
    ZeroRun(const DictionaryEntry bytes, const int match_location)
      : MaskedValuePattern<0, 0xFFFFFFFF>(ZERO_RUN, ZERO_RUN, 3, -1, bytes,
            false),
        _runLength(0), _realSize(0)
    {
    }

    std::size_t
    getSizeBits() const override
    {
        return _realSize;
    }

    /**
     * Get the number of zeros in the run so far.
     *
     * @return The number of zeros in this run.
     */
    int getRunLength() const { return _runLength; }

    /**
     * Set the number of zeros in the run so far.
     *
     * @param The number of zeros in this run.
     */
    void setRunLength(int length) { _runLength = length; }

    /**
     * When the real size is set it means that we are adding the main zero
     * run pattern. When that happens, the metadata length must also be taken
     * into account for the size calculation.
     *
     * @param size Number of bits used to represent the number of zeros in the
     *             run.
     */
    void setRealSize(int size) { _realSize = length + size; }
};

class FPC::SignExtended4Bits : public SignExtendedPattern<4>
{
  public:
    SignExtended4Bits(const DictionaryEntry bytes, const int match_location)
      : SignExtendedPattern<4>(SIGN_EXTENDED_4_BITS, SIGN_EXTENDED_4_BITS, 3,
        bytes)
    {
    }
};

class FPC::SignExtended1Byte : public SignExtendedPattern<8>
{
  public:
    SignExtended1Byte(const DictionaryEntry bytes, const int match_location)
      : SignExtendedPattern<8>(SIGN_EXTENDED_1_BYTE, SIGN_EXTENDED_1_BYTE, 3,
        bytes)
    {
    }
};

class FPC::SignExtendedHalfword : public SignExtendedPattern<16>
{
  public:
    SignExtendedHalfword(const DictionaryEntry bytes, const int match_location)
      : SignExtendedPattern<16>(SIGN_EXTENDED_HALFWORD, SIGN_EXTENDED_HALFWORD,
        3, bytes)
    {
    }
};

class FPC::ZeroPaddedHalfword : public MaskedValuePattern<0, 0x0000FFFF>
{
  public:
    ZeroPaddedHalfword(const DictionaryEntry bytes, const int match_location)
      : MaskedValuePattern<0, 0x0000FFFF>(ZERO_PADDED_HALFWORD,
        ZERO_PADDED_HALFWORD, 3, -1, bytes, false)
    {
    }
};

class FPC::SignExtendedTwoHalfwords : public Pattern
{
  private:
    /** These are the bytes that are extended to form the two halfwords. */
    const int8_t extendedBytes[2];

  public:
    SignExtendedTwoHalfwords(const DictionaryEntry bytes,
        const int match_location)
      : Pattern(SIGN_EXTENDED_TWO_HALFWORDS, SIGN_EXTENDED_TWO_HALFWORDS, 3,
            16, -1, false),
        extendedBytes{int8_t(fromDictionaryEntry(bytes) & mask(8)),
            int8_t((fromDictionaryEntry(bytes) >> 16) & mask(8))}
    {
    }

    static bool
    isPattern(const DictionaryEntry& bytes,
        const DictionaryEntry& dict_bytes, const int match_location)
    {
        const uint32_t data = fromDictionaryEntry(bytes);
        const int16_t halfwords[2] = {
            int16_t(data & mask(16)),
            int16_t((data >> 16) & mask(16))
        };
        return (halfwords[0] == (uint16_t)szext<8>(halfwords[0])) &&
            (halfwords[1] == (uint16_t)szext<8>(halfwords[1]));
    }

    DictionaryEntry
    decompress(const DictionaryEntry dict_bytes) const override
    {
        uint16_t halfwords[2] = {
            (uint16_t)szext<8>(extendedBytes[0]),
            (uint16_t)szext<8>(extendedBytes[1])
        };
        return toDictionaryEntry((halfwords[1] << 16) | halfwords[0]);
    }
};

class FPC::RepBytes : public RepeatedValuePattern<uint8_t>
{
  public:
    RepBytes(const DictionaryEntry bytes, const int match_location)
      : RepeatedValuePattern<uint8_t>(REP_BYTES, REP_BYTES, 3, -1, bytes,
        false)
    {
    }
};

class FPC::Uncompressed : public UncompressedPattern
{
  public:
    Uncompressed(const DictionaryEntry bytes, const int match_location)
      : UncompressedPattern(UNCOMPRESSED, UNCOMPRESSED, 3, -1, bytes)
    {
    }
};

} // namespace compression
} // namespace gem5

#endif //__MEM_CACHE_COMPRESSORS_FPC_HH__
