/*
 * Copyright (c) 2019-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 with limited Dictionary
 * support (FPC-D) cache compressor, as described in "Opportunistic
 * Compression for Direct-Mapped DRAM Caches", by Alameldeen et al.
 *
 * It is a pattern compressor that can only have 2 dictionary entries, and
 * as such the pattern encodings are specialized to inform to which entry it
 * refers. These entries are replaced in a FIFO manner.
 */

#ifndef __MEM_CACHE_COMPRESSORS_FPCD_HH__
#define __MEM_CACHE_COMPRESSORS_FPCD_HH__

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

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

struct FPCDParams;

namespace Compressor {

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

    /** Number of bits in a FPCD pattern prefix. */
    static constexpr int prefixSize = 4;

    /** Index of the previous dictionary entry. */
    static constexpr int previousIndex = 1;

    /** Index of the penultimate dictionary entry. */
    static constexpr int penultimateIndex = 0;

    // Declaration of all possible patterns, from lowest to highest sizes.
    // Penultimate is prioritized over previous to reduce the ripple effect
    // of propagating values during decompression
    class PatternZZZZ;
    class PatternFFFF;
    class PatternMMMMPenultimate;
    class PatternMMMMPrevious;
    class PatternZZZX;
    class PatternXZZZ;
    class PatternRRRR;
    class PatternMMMXPenultimate;
    class PatternMMMXPrevious;
    class PatternZZXX;
    class PatternZXZX;
    class PatternFFXX;
    class PatternXXZZ;
    class PatternMMXXPenultimate;
    class PatternMMXXPrevious;
    class PatternXXXX;

    /**
     * The patterns proposed in the paper. Each letter represents a byte:
     * Z is a null byte, M is a dictionary match, X is a new value, R is
     * a repeated value.
     * These are used as indexes to reference the pattern data. If a new
     * pattern is added, it must be done before NUM_PATTERNS.
     */
    typedef enum {
        ZZZZ, FFFF, MMMMPenultimate, MMMMPrevious, ZZZX, XZZZ, RRRR,
        MMMXPenultimate, MMMXPrevious, ZZXX, ZXZX, FFXX, XXZZ,
        MMXXPenultimate, MMXXPrevious, XXXX, NUM_PATTERNS
    } PatternNumber;

    /**
     * Convenience factory declaration. The templates must be organized by
     * size, with the smallest first, and "no-match" last.
     */
    using PatternFactory =
        Factory<PatternZZZZ, PatternFFFF, PatternMMMMPrevious,
                PatternMMMMPenultimate, PatternZZZX, PatternXZZZ,
                PatternRRRR, PatternMMMXPrevious, PatternMMMXPenultimate,
                PatternZZXX, PatternZXZX, PatternFFXX, PatternXXZZ,
                PatternMMXXPrevious, PatternMMXXPenultimate, PatternXXXX>;

    uint64_t getNumPatterns() const override { return NUM_PATTERNS; }

    std::string
    getName(int number) const override
    {
        static std::map<PatternNumber, std::string> pattern_names = {
            {ZZZZ, "ZZZZ"}, {FFFF, "FFFF"},
            {MMMMPenultimate, "MMMMPenultimate"},
            {MMMMPrevious, "MMMMPrevious"}, {ZZZX, "ZZZX"},
            {XZZZ, "XZZZ"}, {RRRR, "RRRR"},
            {MMMXPenultimate, "MMMXPenultimate"},
            {MMMXPrevious, "MMMXPrevious"},
            {ZZXX, "ZZXX"},
            {ZXZX, "ZXZX"}, {FFXX, "FFXX"}, {XXZZ, "XXZZ"},
            {MMXXPenultimate, "MMXXPenultimate"},
            {MMXXPrevious, "MMXXPrevious"}, {XXXX, "XXXX"}
        };

        return pattern_names[(PatternNumber)number];
    };

    std::unique_ptr<Pattern>
    getPattern(const DictionaryEntry& bytes, const DictionaryEntry& dict_bytes,
        const int match_location) const override
    {
        return PatternFactory::getPattern(bytes, dict_bytes, match_location);
    }

    void addToDictionary(DictionaryEntry data) override;

    std::unique_ptr<Base::CompressionData> compress(
        const std::vector<Base::Chunk>& chunks,
        Cycles& comp_lat, Cycles& decomp_lat) override;

  public:
    typedef FPCDParams Params;
    FPCD(const Params *p);
    ~FPCD() = default;
};

class FPCD::PatternZZZZ : public MaskedValuePattern<0, 0xFFFFFFFF>
{
  public:
    PatternZZZZ(const DictionaryEntry bytes, const int match_location)
        : MaskedValuePattern<0, 0xFFFFFFFF>(ZZZZ, 0x0, prefixSize,
          match_location, bytes, true)
    {
    }
};

class FPCD::PatternFFFF : public MaskedValuePattern<0xFFFFFFFF, 0xFFFFFFFF>
{
  public:
    PatternFFFF(const DictionaryEntry bytes, const int match_location)
        : MaskedValuePattern<0xFFFFFFFF, 0xFFFFFFFF>(FFFF, 0x1,
          prefixSize, match_location, bytes, true)
    {
    }
};

class FPCD::PatternMMMMPrevious
    : public LocatedMaskedPattern<0xFFFFFFFF, previousIndex>
{
  public:
    PatternMMMMPrevious(const DictionaryEntry bytes,
        const int match_location)
        : LocatedMaskedPattern<0xFFFFFFFF, previousIndex>(MMMMPrevious,
          0x2, prefixSize, match_location, bytes)
    {
    }
};

class FPCD::PatternMMMMPenultimate
    : public LocatedMaskedPattern<0xFFFFFFFF, penultimateIndex>
{
  public:
    PatternMMMMPenultimate(const DictionaryEntry bytes,
        const int match_location)
        : LocatedMaskedPattern<0xFFFFFFFF, penultimateIndex>(
          MMMMPenultimate, 0x3, prefixSize, match_location, bytes)
    {
    }
};

class FPCD::PatternZZZX : public MaskedValuePattern<0, 0xFFFFFF00>
{
  public:
    PatternZZZX(const DictionaryEntry bytes, const int match_location)
        : MaskedValuePattern<0, 0xFFFFFF00>(ZZZX, 0x4, prefixSize,
          match_location, bytes, true)
    {
    }
};

class FPCD::PatternXZZZ : public MaskedValuePattern<0, 0x00FFFFFF>
{
  public:
    PatternXZZZ(const DictionaryEntry bytes, const int match_location)
        : MaskedValuePattern<0, 0x00FFFFFF>(XZZZ, 0x5, prefixSize,
          match_location, bytes, true)
    {
    }
};

class FPCD::PatternRRRR : public RepeatedValuePattern<uint8_t>
{
  public:
    PatternRRRR(const DictionaryEntry bytes, const int match_location)
        : RepeatedValuePattern<uint8_t>(RRRR, 0x6, prefixSize,
          match_location, bytes, true)
    {
    }
};

class FPCD::PatternMMMXPrevious
    : public LocatedMaskedPattern<0xFFFFFF00, previousIndex>
{
  public:
    PatternMMMXPrevious(const DictionaryEntry bytes,
        const int match_location)
        : LocatedMaskedPattern<0xFFFFFF00, previousIndex>(MMMXPrevious,
          0x7, prefixSize, match_location, bytes)
    {
    }
};

class FPCD::PatternMMMXPenultimate
    : public LocatedMaskedPattern<0xFFFFFF00, penultimateIndex>
{
  public:
    PatternMMMXPenultimate(const DictionaryEntry bytes,
        const int match_location)
        : LocatedMaskedPattern<0xFFFFFF00, penultimateIndex>(
          MMMXPenultimate, 0x8, prefixSize, match_location, bytes)
    {
    }
};

class FPCD::PatternZZXX : public MaskedValuePattern<0, 0xFFFF0000>
{
  public:
    PatternZZXX(const DictionaryEntry bytes, const int match_location)
        : MaskedValuePattern<0, 0xFFFF0000>(ZZXX, 0x9, prefixSize,
          match_location, bytes, true)
    {
    }
};

class FPCD::PatternZXZX : public MaskedValuePattern<0, 0xFF00FF00>
{
  public:
    PatternZXZX(const DictionaryEntry bytes, const int match_location)
        : MaskedValuePattern<0, 0xFF00FF00>(ZXZX, 0xA, prefixSize,
          match_location, bytes, true)
    {
    }
};

class FPCD::PatternFFXX : public MaskedValuePattern<0xFFFFFFFF, 0xFFFF0000>
{
  public:
    PatternFFXX(const DictionaryEntry bytes, const int match_location)
        : MaskedValuePattern<0xFFFFFFFF, 0xFFFF0000>(FFXX, 0xB,
          prefixSize, match_location, bytes, true)
    {
    }
};

class FPCD::PatternXXZZ : public MaskedValuePattern<0, 0x0000FFFF>
{
  public:
    PatternXXZZ(const DictionaryEntry bytes, const int match_location)
        : MaskedValuePattern<0, 0x0000FFFF>(XXZZ, 0xC, prefixSize,
          match_location, bytes, true)
    {
    }
};

class FPCD::PatternMMXXPrevious
    : public LocatedMaskedPattern<0xFFFF0000, previousIndex>
{
  public:
    PatternMMXXPrevious(const DictionaryEntry bytes,
        const int match_location)
        : LocatedMaskedPattern<0xFFFF0000, previousIndex>(MMXXPrevious,
          0xD, prefixSize, match_location, bytes)
    {
    }
};

class FPCD::PatternMMXXPenultimate
    : public LocatedMaskedPattern<0xFFFF0000, penultimateIndex>
{
  public:
    PatternMMXXPenultimate(const DictionaryEntry bytes,
        const int match_location)
        : LocatedMaskedPattern<0xFFFF0000, penultimateIndex>(
          MMXXPenultimate, 0xE, prefixSize, match_location, bytes)
    {
    }
};

class FPCD::PatternXXXX : public UncompressedPattern
{
  public:
    PatternXXXX(const DictionaryEntry bytes, const int match_location)
        : UncompressedPattern(XXXX, 0xF, prefixSize, match_location,
          bytes)
    {
    }
};

} // namespace Compressor

#endif //__MEM_CACHE_COMPRESSORS_FPCD_HH__
