// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef MPACT_SIM_GENERIC_DECODE_CACHE_H_
#define MPACT_SIM_GENERIC_DECODE_CACHE_H_

#include <cstdint>

#include "mpact/sim/generic/decoder_interface.h"
#include "mpact/sim/generic/instruction.h"

// The purpose of the decode cache is to cache the "decoded" simulator internal
// represenations of target instructions so that the runtime cost of decoding
// an instruction can be amortized over many instruction executions. The decode
// cache is agnostic with respect to the type and format of the actual source
// instruction encoding.

namespace mpact {
namespace sim {
namespace generic {

// This structure contains properties used to configure the decode cache. The
// minimum number of cached instructions and the minimum possible pc increment.
// The actual size of the decode cache will be the smallest power of two that
// is greater or equal to the minimum number of entries. The decode cache is
// currently only direct mapped, but different organizations may be permitted
// in the future.
struct DecodeCacheProperties {
  // Actual size will be the power of two that is >= num_entries.
  uint32_t num_entries;
  // Minimum pc increment should be a power of two.
  uint32_t minimum_pc_increment;
};

// Instructions are decoded into an internal representation for the simulator.
// Because the decode process can be slow (at least there's no requirement that
// it be fast), the decoded internal representations are cached in a
// DecodeCache. The organization of the decode cache is specified by a
// DecodeCacheProperties struct which is passed in to the DecodeCache
// constructor.
//
// Instruction decode invalidation is supported, for the whole decode cache,
// an address range in the decode cache, or for a single instruction address.
// The instructions are reference counted, so while an instruction may be in
// the process of being executed, its internal representation will not be
// deleted until the execution completes with a DecRef.
class DecodeCache {
 private:
  // Constructed using static factory method.
  DecodeCache(const DecodeCacheProperties& props, DecoderInterface* decoder);

 public:
  DecodeCache() = delete;
  virtual ~DecodeCache();
  // The DecodeCache factory method takes the property struct and the interface
  // to a decoder that will supply an instruction internal representation for
  // a given address. If memory allocation fails it returns nullptr.
  static DecodeCache* Create(const DecodeCacheProperties& props,
                             DecoderInterface* decoder);
  // Returns the decoded instruction associated with the given address. If there
  // is not an instruction with that address in the decode cache, the decoder
  // will be called and the newly decoded instruction will be cached.
  Instruction* GetDecodedInstruction(uint64_t address);
  // Invalidation operations
  // These methods cases the removal from the cache of the instruction
  // internal represenations that match the address, address range [start, end),
  // or the entire cache. Each instruction that is removed from the cache is
  // DecRef'ed.
  void Invalidate(uint64_t address);
  void InvalidateRange(uint64_t start_address, uint64_t end_address);
  void InvalidateAll();

  // Accessors.
  int num_entries() const { return num_entries_; }
  uint64_t address_mask() const { return address_mask_; }
  int address_shift() const { return address_shift_; }
  int address_inc() const { return address_inc_; }

 private:
  DecoderInterface* decoder_;
  int num_entries_;
  int address_shift_;
  uint32_t address_inc_;
  uint64_t address_mask_;
  Instruction** instruction_cache_;
};

}  // namespace generic
}  // namespace sim
}  // namespace mpact

#endif  // MPACT_SIM_GENERIC_DECODE_CACHE_H_
