| // 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_ |