blob: 7fd1189669876d042e15a4814b285ca9b7127dd5 [file]
// 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 represenations 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_