mirror of
https://github.com/TomHarte/CLK.git
synced 2024-07-08 15:29:09 +00:00
Seeks to switch to maintaining a bank of performers.
My thinking here is that for really simple processors there'll be 256 or less, meaning that they can be stored by simple uint8_t; for every other processor I can currently think of it'll likely be uint16_t. Either way, that's a much better outcome than using plain pointers, which on architectures I currently build for will always be 8 bytes. For the simple processors I can get eight times as much into the cache; for the others four times.
This commit is contained in:
parent
5f413a38df
commit
17c3a3eb4b
@ -9,16 +9,55 @@
|
|||||||
#ifndef CachingExecutor_hpp
|
#ifndef CachingExecutor_hpp
|
||||||
#define CachingExecutor_hpp
|
#define CachingExecutor_hpp
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
namespace InstructionSet {
|
namespace InstructionSet {
|
||||||
|
|
||||||
template <typename Executor, typename Action, typename AddressType, AddressType MaxAddress> class CachingExecutor {
|
/*!
|
||||||
|
Maps to the smallest of the following integers that can contain max_value:
|
||||||
|
|
||||||
|
* uint8_t;
|
||||||
|
* uint16_t;
|
||||||
|
* uint32_t; or
|
||||||
|
* uint64_t.
|
||||||
|
*/
|
||||||
|
template <uint64_t max_value> struct MinIntTypeValue {
|
||||||
|
using type =
|
||||||
|
std::conditional_t<
|
||||||
|
max_value <= std::numeric_limits<uint8_t>::max(), uint8_t,
|
||||||
|
std::conditional_t<
|
||||||
|
max_value <= std::numeric_limits<uint16_t>::max(), uint16_t,
|
||||||
|
std::conditional_t<
|
||||||
|
max_value <= std::numeric_limits<uint32_t>::max(), uint32_t,
|
||||||
|
uint64_t
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <
|
||||||
|
/// Indicates the Executor for this platform.
|
||||||
|
typename Executor,
|
||||||
|
/// Indicates the greatest value the program counter might take.
|
||||||
|
uint64_t max_address,
|
||||||
|
/// Indicates the maximum number of potential performers that will be provided.
|
||||||
|
uint64_t max_performer_count,
|
||||||
|
/// Indicates whether performers will acess their decoded instructions; if @c false then instructions are not retained.
|
||||||
|
bool keep_instruction_structs
|
||||||
|
> class CachingExecutor {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AddressType program_counter_;
|
using Performer = void (*)(Executor *);
|
||||||
|
std::array<Performer, max_performer_count> performers_;
|
||||||
|
typename MinIntTypeValue<max_address>::type program_counter_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Action actions_[100]; // TODO: just a test declaration; these actually need to be bucketed by page, etc.
|
typename MinIntTypeValue<max_performer_count>::type actions_[100];
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,11 +29,11 @@ struct Action {
|
|||||||
inline Action(Performer performer) noexcept : perform(performer) {}
|
inline Action(Performer performer) noexcept : perform(performer) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Executor: public CachingExecutor<Executor, Action, uint16_t, 0x2000> {
|
class Executor: public CachingExecutor<Executor, 0x2000, 256, false> {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend CachingExecutor<Executor, Action, uint16_t, 0x2000>;
|
friend CachingExecutor<Executor, 0x2000, 256, false>;
|
||||||
Action action_for(Instruction);
|
Action action_for(Instruction);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
Loading…
Reference in New Issue
Block a user